[pypy-commit] pypy s390x-backend: wrong operation (SG instead of STG) lead to substraction instead of 64bit store, test_exception is now passing!
plan_rich
pypy.commits at gmail.com
Wed Dec 30 10:32:05 EST 2015
Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r81501:79c8712b54e0
Date: 2015-12-30 16:31 +0100
http://bitbucket.org/pypy/pypy/changeset/79c8712b54e0/
Log: wrong operation (SG instead of STG) lead to substraction instead of
64bit store, test_exception is now passing!
diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -65,7 +65,6 @@
def execute_operations(self, inputargs, operations, result_type):
looptoken = JitCellToken()
self.cpu.compile_loop(inputargs, operations, looptoken)
- #import pdb; pdb.set_trace()
args = []
for box in inputargs:
if box.type == 'i':
@@ -4980,7 +4979,6 @@
def test_increment_debug_counter(self):
foo = lltype.malloc(rffi.CArray(lltype.Signed), 1, flavor='raw')
foo[0] = 1789200
- print "addr" , hex(rffi.cast(lltype.Signed, foo))
self.execute_operation(rop.INCREMENT_DEBUG_COUNTER,
[ConstInt(rffi.cast(lltype.Signed, foo))],
'void')
@@ -5006,12 +5004,11 @@
addr = llmemory.cast_ptr_to_adr(a)
a_int = heaptracker.adr2int(addr)
a_ref = lltype.cast_opaque_ptr(llmemory.GCREF, a)
- for (start, length) in [(0,100), (49, 49), (1, 98),
+ for (start, length) in [(0, 100), (49, 49), (1, 98),
(15, 9), (10, 10), (47, 0),
(0, 4)]:
for cls1 in [ConstInt, InputArgInt]:
for cls2 in [ConstInt, InputArgInt]:
- print 'ptr:', hex(rffi.cast(lltype.Signed, a_ref))
print 'a_int:', a_int
print 'of:', OF
print 'start:', cls1.__name__, start
@@ -5049,10 +5046,6 @@
scalebox = ConstInt(arraydescr.itemsize)
inputargs, oplist = self._get_operation_list(ops,'void')
- # XXX
- print("input:", inputargs)
- for op in oplist:
- print(op)
self.execute_operations(inputargs, oplist, 'void')
assert len(a) == 100
for i in range(100):
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
@@ -295,9 +295,9 @@
# f) store the address of the new jitframe in the shadowstack
# c) set the gcmap field to 0 in the new jitframe
# g) restore registers and return
+ mc = InstrBuilder()
+ self.mc = mc
return
- mc = PPCBuilder()
- self.mc = mc
# signature of this _frame_realloc_slowpath function:
# * on entry, r0 is the new size
@@ -305,13 +305,13 @@
# * no managed register must be modified
ofs2 = self.cpu.get_ofs_of_frame_field('jf_gcmap')
- mc.store(r.r2.value, r.SPP.value, ofs2)
+ mc.STG(r.r2, l.addr(ofs2, r.SPP))
self._push_core_regs_to_jitframe(mc)
self._push_fp_regs_to_jitframe(mc)
# Save away the LR inside r30
- mc.mflr(r.RCS1.value)
+ #mc.mflr(r.RCS1.value)
# First argument is SPP (= r31), which is the jitframe
mc.mr(r.r3.value, r.SPP.value)
@@ -493,6 +493,7 @@
ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr)
#mc.LG(r.r2, l.addr(ofs, r.SPP))
patch_pos = mc.currpos()
+ self.mc.trap()
#mc.TRAP2() # placeholder for cmpdi(0, r2, ...)
#mc.TRAP2() # placeholder for bge
#mc.TRAP2() # placeholder for li(r0, ...)
@@ -664,8 +665,8 @@
# if self.propagate_exception_path == 0 (tests), this may jump to 0
# and segfaults. too bad. the alternative is to continue anyway
# with r2==0, but that will segfault too.
+ self.mc.load_imm(r.RETURN, self.propagate_exception_path)
self.mc.cmp_op(r.r2, l.imm(0), imm=True)
- self.mc.load_imm(r.RETURN, self.propagate_exception_path)
self.mc.BCR(c.EQ, r.RETURN)
def regalloc_push(self, loc, already_pushed):
@@ -843,6 +844,7 @@
for traps_pos, jmp_target in self.frame_depth_to_patch:
pmc = OverwritingBuilder(self.mc, traps_pos, 3)
# three traps, so exactly three instructions to patch here
+ xxx
#pmc.cmpdi(0, r.r2.value, frame_depth) # 1
#pmc.bc(7, 0, jmp_target - (traps_pos + 4)) # 2 "bge+"
#pmc.li(r.r0.value, frame_depth) # 3
@@ -1111,6 +1113,158 @@
ptr = rffi.cast(lltype.Signed, gcmap)
mc.load_imm(reg, ptr)
+ def malloc_cond_varsize_frame(self, nursery_free_adr, nursery_top_adr,
+ sizeloc, gcmap):
+ xxx
+ diff = nursery_top_adr - nursery_free_adr
+ assert _check_imm_arg(diff)
+ mc = self.mc
+ mc.load_imm(r.r2, nursery_free_adr)
+
+ if sizeloc is r.RES:
+ mc.mr(r.RSZ.value, r.RES.value)
+ sizeloc = r.RSZ
+
+ mc.load(r.RES.value, r.r2.value, 0) # load nursery_free
+ mc.load(r.SCRATCH.value, r.r2.value, diff) # load nursery_top
+
+ mc.add(r.RSZ.value, r.RES.value, sizeloc.value)
+
+ mc.cmp_op(0, r.RSZ.value, r.SCRATCH.value, signed=False)
+
+ fast_jmp_pos = mc.currpos()
+ mc.trap() # conditional jump, patched later
+
+ # new value of nursery_free_adr in RSZ and the adr of the new object
+ # in RES.
+ self.load_gcmap(mc, r.r2, gcmap)
+ mc.bl_abs(self.malloc_slowpath)
+
+ offset = mc.currpos() - fast_jmp_pos
+ pmc = OverwritingBuilder(mc, fast_jmp_pos, 1)
+ pmc.bc(7, 1, offset) # jump if LE (not GT), predicted to be true
+ pmc.overwrite()
+
+ mc.store(r.RSZ.value, r.r2.value, 0) # store into nursery_free
+
+ def malloc_cond_varsize(self, kind, nursery_free_adr, nursery_top_adr,
+ lengthloc, itemsize, maxlength, gcmap,
+ arraydescr):
+ xxx
+ from rpython.jit.backend.llsupport.descr import ArrayDescr
+ assert isinstance(arraydescr, ArrayDescr)
+
+ # lengthloc is the length of the array, which we must not modify!
+ assert lengthloc is not r.RES and lengthloc is not r.RSZ
+ assert lengthloc.is_reg()
+
+ if maxlength > 2**16-1:
+ maxlength = 2**16-1 # makes things easier
+ mc = self.mc
+ mc.cmp_op(0, lengthloc.value, maxlength, imm=True, signed=False)
+
+ jmp_adr0 = mc.currpos()
+ mc.trap() # conditional jump, patched later
+
+ # ------------------------------------------------------------
+ # block of code for the case: the length is <= maxlength
+
+ diff = nursery_top_adr - nursery_free_adr
+ assert _check_imm_arg(diff)
+ mc.load_imm(r.r2, nursery_free_adr)
+
+ varsizeloc = self._multiply_by_constant(lengthloc, itemsize,
+ r.RSZ)
+ # varsizeloc is either RSZ here, or equal to lengthloc if
+ # itemsize == 1. It is the size of the variable part of the
+ # array, in bytes.
+
+ mc.load(r.RES.value, r.r2.value, 0) # load nursery_free
+ mc.load(r.SCRATCH.value, r.r2.value, diff) # load nursery_top
+
+ assert arraydescr.basesize >= self.gc_minimal_size_in_nursery
+ constsize = arraydescr.basesize + self.gc_size_of_header
+ force_realignment = (itemsize % WORD) != 0
+ if force_realignment:
+ constsize += WORD - 1
+ mc.addi(r.RSZ.value, varsizeloc.value, constsize)
+ if force_realignment:
+ # "& ~(WORD-1)"
+ bit_limit = 60 if WORD == 8 else 61
+ mc.rldicr(r.RSZ.value, r.RSZ.value, 0, bit_limit)
+
+ mc.add(r.RSZ.value, r.RES.value, r.RSZ.value)
+ # now RSZ contains the total size in bytes, rounded up to a multiple
+ # of WORD, plus nursery_free_adr
+
+ mc.cmp_op(0, r.RSZ.value, r.SCRATCH.value, signed=False)
+
+ jmp_adr1 = mc.currpos()
+ mc.trap() # conditional jump, patched later
+
+ # ------------------------------------------------------------
+ # block of code for two cases: either the length is > maxlength
+ # (jump from jmp_adr0), or the length is small enough but there
+ # is not enough space in the nursery (fall-through)
+ #
+ offset = mc.currpos() - jmp_adr0
+ pmc = OverwritingBuilder(mc, jmp_adr0, 1)
+ pmc.bgt(offset) # jump if GT
+ pmc.overwrite()
+ #
+ # save the gcmap
+ self.load_gcmap(mc, r.r2, gcmap)
+ #
+ # load the function to call into CTR
+ if kind == rewrite.FLAG_ARRAY:
+ addr = self.malloc_slowpath_varsize
+ elif kind == rewrite.FLAG_STR:
+ addr = self.malloc_slowpath_str
+ elif kind == rewrite.FLAG_UNICODE:
+ addr = self.malloc_slowpath_unicode
+ else:
+ raise AssertionError(kind)
+ mc.load_imm(r.SCRATCH, addr)
+ mc.mtctr(r.SCRATCH.value)
+ #
+ # load the argument(s)
+ if kind == rewrite.FLAG_ARRAY:
+ mc.mr(r.RSZ.value, lengthloc.value)
+ mc.load_imm(r.RES, itemsize)
+ mc.load_imm(r.SCRATCH, arraydescr.tid)
+ else:
+ mc.mr(r.RES.value, lengthloc.value)
+ #
+ # call!
+ mc.bctrl()
+
+ jmp_location = mc.currpos()
+ mc.trap() # jump forward, patched later
+
+ # ------------------------------------------------------------
+ # block of code for the common case: the length is <= maxlength
+ # and there is enough space in the nursery
+
+ offset = mc.currpos() - jmp_adr1
+ pmc = OverwritingBuilder(mc, jmp_adr1, 1)
+ pmc.ble(offset) # jump if LE
+ pmc.overwrite()
+ #
+ # write down the tid, but only in this case (not in other cases
+ # where r.RES is the result of the CALL)
+ mc.load_imm(r.SCRATCH, arraydescr.tid)
+ mc.store(r.SCRATCH.value, r.RES.value, 0)
+ # while we're at it, this line is not needed if we've done the CALL
+ mc.store(r.RSZ.value, r.r2.value, 0) # store into nursery_free
+
+ # ------------------------------------------------------------
+
+ offset = mc.currpos() - jmp_location
+ pmc = OverwritingBuilder(mc, jmp_location, 1)
+ pmc.b(offset) # jump always
+ pmc.overwrite()
+
+
def notimplemented_op(asm, op, arglocs, regalloc):
print "[ZARCH/asm] %s not implemented" % op.getopname()
raise NotImplementedError(op)
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
@@ -746,8 +746,8 @@
if resloc:
mc.load(resloc, r.SCRATCH, 0)
mc.LGHI(r.SCRATCH2, l.imm(0))
- mc.SG(r.SCRATCH2, l.addr(0, r.SCRATCH))
- mc.SG(r.SCRATCH2, l.addr(diff, r.SCRATCH))
+ mc.STG(r.SCRATCH2, l.addr(0, r.SCRATCH))
+ mc.STG(r.SCRATCH2, l.addr(diff, r.SCRATCH))
def emit_save_exc_class(self, op, arglocs, regalloc):
[resloc] = arglocs
More information about the pypy-commit
mailing list