Author: Richard Plangger <[email protected]>
Branch: s390x-backend
Changeset: r81683:4d6c20801028
Date: 2016-01-12 12:26 +0100
http://bitbucket.org/pypy/pypy/changeset/4d6c20801028/
Log: translation issues mostly and added functions and missing
implementations. zrpy_releasegil translates
diff --git a/rpython/jit/backend/zarch/assembler.py
b/rpython/jit/backend/zarch/assembler.py
--- a/rpython/jit/backend/zarch/assembler.py
+++ b/rpython/jit/backend/zarch/assembler.py
@@ -22,8 +22,7 @@
from rpython.jit.metainterp.resoperation import rop
from rpython.rlib.debug import (debug_print, debug_start, debug_stop,
have_debug_prints)
-from rpython.jit.metainterp.history import (INT, REF, FLOAT,
- TargetToken)
+from rpython.jit.metainterp.history import (INT, REF, FLOAT, TargetToken)
from rpython.rlib.rarithmetic import r_uint
from rpython.rlib.objectmodel import we_are_translated, specialize,
compute_unique_id
from rpython.rlib import rgc
@@ -515,7 +514,7 @@
# registers).
mc = InstrBuilder()
#
- mc._push_core_regs_to_jitframe([r.r14]) # store the link on the jit
frame
+ self._push_core_regs_to_jitframe(mc, [r.r14]) # store the link on the
jit frame
# Do the call
mc.push_std_frame()
mc.LGR(r.r2, r.SP)
@@ -530,7 +529,7 @@
# else we have an exception
mc.cmp_op(r.SCRATCH, l.imm(0), imm=True)
#
- mc._pop_core_regs_from_jitframe([r.r14]) # restore the link on the jit
frame
+ self._pop_core_regs_from_jitframe(mc, [r.r14]) # restore the link on
the jit frame
# So we return to our caller, conditionally if "EQ"
mc.BCR(c.EQ, r.r14)
#
@@ -556,13 +555,14 @@
assert check_imm_value(diff)
mc = self.mc
- mc.load_imm(r.SCRATCH2, endaddr) # li r0, endaddr
- mc.branch_absolute(self.stack_check_slowpath)
- mc.load(r.SCRATCH, r.SCRATCH2, 0) # lg r1, [end]
- mc.load(r.SCRATCH2, r.SCRATCH2, diff)# lg r0, [length]
- mc.SGR(r.SCRATCH, r.SP) # sub r1, SP
- mc.cmp_op(r.SCRATCH, r.SCRATCH2, signed=False)
- mc.bgtctrl()
+ mc.load_imm(r.SCRATCH, endaddr) # li r0, endaddr
+ mc.load(r.SCRATCH2, r.SCRATCH, 0) # lg r1, [end]
+ mc.load(r.SCRATCH, r.SCRATCH, diff)# lg r0, [length]
+ mc.SGR(r.SCRATCH2, r.SP) # sub r1, SP
+ mc.load_imm(r.r14, self.stack_check_slowpath)
+ off = l.imm(mc.CLGRJ_byte_count + mc.BASR_byte_count)
+ mc.CLGRJ(r.SCRATCH2, r.SCRATCH, c.GT, off)
+ mc.BASR(r.r14, r.r14)
def _check_frame_depth(self, mc, gcmap):
""" check if the frame is of enough depth to follow this bridge.
@@ -731,6 +731,7 @@
def fixup_target_tokens(self, rawstart):
for targettoken in self.target_tokens_currently_compiling:
+ assert isinstance(targettoken, TargetToken)
targettoken._ll_loop_code += rawstart
self.target_tokens_currently_compiling = None
@@ -813,6 +814,21 @@
ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap')
mc.STG(r.SCRATCH, l.addr(ofs, r.SPP))
+ def break_long_loop(self):
+ # If the loop is too long, the guards in it will jump forward
+ # more than 32 KB. We use an approximate hack to know if we
+ # should break the loop here with an unconditional "b" that
+ # jumps over the target code.
+ jmp_pos = self.mc.currpos()
+ self.mc.reserve_cond_jump()
+
+ self.write_pending_failure_recoveries()
+
+ currpos = self.mc.currpos()
+ pmc = OverwritingBuilder(self.mc, jmp_pos, 1)
+ pmc.BRCL(c.ANY, l.imm(currpos - jmp_pos))
+ pmc.overwrite()
+
def _assemble(self, regalloc, inputargs, operations):
self._regalloc = regalloc
self.guard_success_cc = c.cond_none
@@ -883,7 +899,7 @@
elif prev_loc.is_in_pool():
# move immediate value to fp register
if loc.is_fp_reg():
- self.LD(loc, prev_loc)
+ self.mc.LD(loc, prev_loc)
return
# move immediate value to memory
elif loc.is_stack():
@@ -1263,7 +1279,7 @@
if check_imm_value(size):
mc.AGHI(r.RSZ, l.imm(size))
else:
- mc.load_imm(r.SCRATCH2, l.imm(size))
+ mc.load_imm(r.SCRATCH2, size)
mc.AGR(r.RSZ, r.SCRATCH2)
mc.load(r.SCRATCH2, r.r1, diff) # load nursery_top
diff --git a/rpython/jit/backend/zarch/callbuilder.py
b/rpython/jit/backend/zarch/callbuilder.py
--- a/rpython/jit/backend/zarch/callbuilder.py
+++ b/rpython/jit/backend/zarch/callbuilder.py
@@ -126,8 +126,8 @@
if gcrootmap.is_shadow_stack and self.is_call_release_gil:
# in this mode, RSHADOWOLD happens to contain the shadowstack
# top at this point, so reuse it instead of loading it again
- xxx
- ssreg = self.RSHADOWOLD
+ # RSHADOWOLD is moved to the scratch reg just before restoring
r8
+ ssreg = r.SCRATCH
self.asm._reload_frame_if_necessary(self.mc, shadowstack_reg=ssreg)
def emit_raw_call(self):
@@ -200,7 +200,8 @@
self.mc.trap() # boehm: patched with a BEQ: jump if r12 is
zero
self.mc.write('\x00'*4) # shadowstack: patched with BNE instead
- if self.asm.cpu.gc_ll_descr.gcrootmap:
+ gcrootmap = self.asm.cpu.gc_ll_descr.gcrootmap
+ if gcrootmap:
# When doing a call_release_gil with shadowstack, there
# is the risk that the 'rpy_fastgil' was free but the
# current shadowstack can be the one of a different
@@ -219,7 +220,7 @@
self.mc.STG(r.r12, l.addr(0,RFASTGILPTR))
pmc = OverwritingBuilder(self.mc, bne_location, 1)
- pmc.BCRL(c.NE, self.mc.currpos() - bne_location)
+ pmc.BRCL(c.NE, l.imm(self.mc.currpos() - bne_location))
pmc.overwrite()
#
# Yes, we need to call the reacqgil() function.
@@ -246,6 +247,9 @@
pmc.overwrite()
# restore the values that might have been overwritten
+ if gcrootmap:
+ if gcrootmap.is_shadow_stack and self.is_call_release_gil:
+ self.mc.LGR(r.SCRATCH, RSHADOWOLD)
self.mc.LMG(r.r8, r.r13, l.addr(-7*WORD, r.SP))
diff --git a/rpython/jit/backend/zarch/conditions.py
b/rpython/jit/backend/zarch/conditions.py
--- a/rpython/jit/backend/zarch/conditions.py
+++ b/rpython/jit/backend/zarch/conditions.py
@@ -2,6 +2,7 @@
from rpython.rlib.objectmodel import specialize
class ConditionLocation(loc.ImmLocation):
+ _immutable_ = True
def __repr__(self):
s = ""
if self.value & 0x10 != 0:
diff --git a/rpython/jit/backend/zarch/instruction_builder.py
b/rpython/jit/backend/zarch/instruction_builder.py
--- a/rpython/jit/backend/zarch/instruction_builder.py
+++ b/rpython/jit/backend/zarch/instruction_builder.py
@@ -464,27 +464,48 @@
e = unpack_arg(a, at)
f = unpack_arg(b, bt)
return func(self, e, f)
+ def function2_last_default(self, a):
+ e = unpack_arg(a, at)
+ return func(self, e, 0)
def function3(self, a, b, c):
e = unpack_arg(a, at)
f = unpack_arg(b, bt)
g = unpack_arg(c, ct)
return func(self, e, f, g)
+ def function3_last_default(self, a, b):
+ e = unpack_arg(a, at)
+ f = unpack_arg(b, bt)
+ return func(self, e, f, 0)
def function4(self, a, b, c, d):
e = unpack_arg(a, at)
f = unpack_arg(b, bt)
g = unpack_arg(c, ct)
h = unpack_arg(d, dt)
return func(self, e, f, g, h)
+ def function4_last_default(self, a, b, c):
+ e = unpack_arg(a, at)
+ f = unpack_arg(b, bt)
+ g = unpack_arg(c, ct)
+ return func(self, e, f, g, 0)
if len(argtypes) == 0:
function = function0
elif len(argtypes) == 1:
function = function1
elif len(argtypes) == 2:
function = function2
+ if argtypes[1] == '-':
+ # e.g. SPM/IPM
+ function = function2_last_default
elif len(argtypes) == 3:
function = function3
+ if argtypes[2] == '-':
+ # e.g. FIEBR or CGEBR ignore the last element
+ function = function3_last_default
elif len(argtypes) == 4:
function = function4
+ if argtypes[3] == '-':
+ # e.g. FIEBR or CGEBR ignore the last element
+ function = function4_last_default
else:
assert 0, "implement function for argtypes %s" % (argtypes,)
function.__name__ = mnemonic
diff --git a/rpython/jit/backend/zarch/opassembler.py
b/rpython/jit/backend/zarch/opassembler.py
--- a/rpython/jit/backend/zarch/opassembler.py
+++ b/rpython/jit/backend/zarch/opassembler.py
@@ -251,6 +251,25 @@
emit_call_f = _genop_call
emit_call_n = _genop_call
+ def _emit_threadlocalref_get(self, op, arglocs, regalloc):
+ [resloc] = arglocs
+ offset = op.getarg(1).getint() # getarg(0) == 'threadlocalref_get'
+ calldescr = op.getdescr()
+ size = calldescr.get_result_size()
+ sign = calldescr.is_result_signed()
+ #
+ # This loads the stack location THREADLOCAL_OFS into a
+ # register, and then read the word at the given offset.
+ # It is only supported if 'translate_support_code' is
+ # true; otherwise, the execute_token() was done with a
+ # dummy value for the stack location THREADLOCAL_OFS
+ #
+ assert self.cpu.translate_support_code
+ assert resloc.is_reg()
+ assert check_imm_value(offset)
+ self.mc.LG(resloc, l.addr(THREADLOCAL_ADDR_OFFSET, r.SP))
+ self._memory_read(resloc, l.addr(offset, resloc), size, sign)
+
def _emit_math_sqrt(self, op, arglocs, regalloc):
l0, res = arglocs
self.mc.SQDBR(res, l0)
@@ -641,10 +660,9 @@
self._read_typeid(r.SCRATCH2, loc_ptr)
assert 0 <= expected_typeid <= 0x7fffffff # 4 bytes are always enough
if expected_typeid > 0xffff: # if 2 bytes are not enough
- self.mc.subis(r.SCRATCH2.value, r.SCRATCH2.value,
- expected_typeid >> 16)
+ self.mc.AGHI(r.SCRATCH2, l.imm(-(expected_typeid >> 16)))
expected_typeid = expected_typeid & 0xffff
- self.mc.cmp_op(0, r.SCRATCH2.value, expected_typeid,
+ self.mc.cmp_op(r.SCRATCH2, l.imm(expected_typeid),
imm=True, signed=False)
def emit_guard_gc_type(self, op, arglocs, regalloc):
@@ -1026,8 +1044,8 @@
def _call_assembler_check_descr(self, value, tmploc):
ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
self.mc.LG(r.SCRATCH, l.addr(ofs, r.r2))
- if check_imm(value):
- self.mc.cmp_op(r.SCRATCH, value, imm=True)
+ if check_imm_value(value):
+ self.mc.cmp_op(r.SCRATCH, l.imm(value), imm=True)
else:
self.mc.load_imm(r.SCRATCH2, value)
self.mc.cmp_op(r.SCRATCH, r.SCRATCH2, imm=False)
diff --git a/rpython/jit/backend/zarch/pool.py
b/rpython/jit/backend/zarch/pool.py
--- a/rpython/jit/backend/zarch/pool.py
+++ b/rpython/jit/backend/zarch/pool.py
@@ -4,6 +4,7 @@
TargetToken)
from rpython.rlib.objectmodel import we_are_translated
from rpython.jit.metainterp.resoperation import rop
+from rpython.jit.metainterp.history import Const
from rpython.rtyper.lltypesystem import lltype, rffi, llmemory
from rpython.jit.backend.zarch.arch import (WORD,
RECOVERY_GCMAP_POOL_OFFSET, RECOVERY_TARGET_POOL_OFFSET)
@@ -168,16 +169,14 @@
print('pool: %s at offset: %d' % (val, offset))
if val.is_constant():
if val.type == FLOAT:
- self.overwrite_64(mc, offset, float2longlong(val.value))
+ self.overwrite_64(mc, offset,
float2longlong(val.getfloat()))
elif val.type == INT:
- i64 = rffi.cast(lltype.Signed, val.value)
+ i64 = rffi.cast(lltype.Signed, val.getint())
self.overwrite_64(mc, offset, i64)
else:
assert val.type == REF
- i64 = rffi.cast(lltype.Signed, val.value)
+ i64 = rffi.cast(lltype.Signed, val.getref_base())
self.overwrite_64(mc, offset, i64)
- else:
- pass
for guard_token in pending_guard_tokens:
descr = guard_token.faildescr
diff --git a/rpython/jit/backend/zarch/regalloc.py
b/rpython/jit/backend/zarch/regalloc.py
--- a/rpython/jit/backend/zarch/regalloc.py
+++ b/rpython/jit/backend/zarch/regalloc.py
@@ -163,8 +163,6 @@
self._check_type(var)
prev_loc = self.loc(var, must_exist=must_exist)
var2 = TempVar()
- if prev_loc is self.frame_reg:
- return prev_loc
if bind_first:
loc, loc2 = self.force_allocate_reg_pair(bindvar, var2,
self.temp_boxes)
else:
@@ -437,7 +435,7 @@
return r.SPP
else:
# else, return a regular register (not SPP).
- if self.rm.reg_bindings.get(var, None) != None:
+ if self.rm.reg_bindings.get(var, None) is not None:
return self.rm.loc(var, must_exist=True)
return self.rm.force_allocate_reg(var)
diff --git a/rpython/jit/backend/zarch/test/test_zrpy_releasegil.py
b/rpython/jit/backend/zarch/test/test_zrpy_releasegil.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/zarch/test/test_zrpy_releasegil.py
@@ -0,0 +1,5 @@
+from rpython.jit.backend.llsupport.test.zrpy_releasegil_test import
ReleaseGILTests
+
+
+class TestShadowStack(ReleaseGILTests):
+ gcrootfinder = "shadowstack"
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit