Author: Richard Plangger <planri...@gmail.com>
Branch: s390x-backend
Changeset: r80466:85a292e8a0ad
Date: 2015-10-27 11:20 +0100
http://bitbucket.org/pypy/pypy/changeset/85a292e8a0ad/

Log:    adapted some arch details, added failure recovery, finish resop
        (partly)

diff --git a/rpython/jit/backend/zarch/arch.py 
b/rpython/jit/backend/zarch/arch.py
--- a/rpython/jit/backend/zarch/arch.py
+++ b/rpython/jit/backend/zarch/arch.py
@@ -1,4 +1,20 @@
+WORD = 8
 
-WORD = 4
+#
+#                                                 OFFSET
+#     +------------------------------+            0
+#     |  gpr save are (int+float)    |
+#     +------------------------------+            8
+#     |  local vars                  |
+#     +------------------------------+            0
+#     |                              |
+#     +------------------------------+
+#     |                              |
+#     +------------------------------+ <- SP      0         (r15)
+#
 
-JITFRAME_FIXED_SIZE = 48
+GPR_STACK_SAVE_IN_BYTES = 120
+STD_FRAME_SIZE_IN_BYTES = 140
+THREADLOCAL_ADDR_OFFSET = 8
+
+assert STD_FRAME_SIZE_IN_BYTES % 2 == 0
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
@@ -6,12 +6,16 @@
 from rpython.jit.backend.zarch import registers as r
 from rpython.jit.backend.zarch import locations as loc
 from rpython.jit.backend.zarch.codebuilder import InstrBuilder
-from rpython.jit.backend.zarch.arch import (WORD, JITFRAME_FIXED_SIZE)
+from rpython.jit.backend.zarch.registers import JITFRAME_FIXED_SIZE
+from rpython.jit.backend.zarch.arch import (WORD,
+        STD_FRAME_SIZE_IN_BYTES, GPR_STACK_SAVE_IN_BYTES,
+        THREADLOCAL_ADDR_OFFSET)
 from rpython.jit.backend.zarch.opassembler import IntOpAssembler
 from rpython.jit.backend.zarch.regalloc import Regalloc
 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)
 from rpython.rlib.rarithmetic import r_uint
 from rpython.rlib.objectmodel import we_are_translated, specialize, 
compute_unique_id
 from rpython.rlib import rgc
@@ -30,6 +34,7 @@
         self.stack_check_slowpath = 0
         self.loop_run_counters = []
         self.gcrootmap_retaddr_forced = 0
+        self.failure_recovery_code = [0, 0, 0, 0]
 
     def setup(self, looptoken):
         BaseAssembler.setup(self, looptoken)
@@ -62,12 +67,14 @@
         return clt.asmmemmgr_blocks
 
     def gen_func_prolog(self):
+        """ NOT_RPYTHON """
         STACK_FRAME_SIZE = 40
-        self.mc.STMG(r.r11, r.r15, loc.addr(-STACK_FRAME_SIZE, r.sp))
+        self.mc.STMG(r.r11, r.r15, loc.addr(-STACK_FRAME_SIZE, r.SP))
         self.mc.AHI(r.sp, loc.imm(-STACK_FRAME_SIZE))
 
     def gen_func_epilog(self):
-        self.mc.LMG(r.r11, r.r15, loc.addr(0, r.SPP))
+        """ NOT_RPYTHON """
+        self.mc.LMG(r.r11, r.r15, loc.addr(0, r.SP))
         self.jmpto(r.r14)
 
     def jmpto(self, register):
@@ -76,7 +83,42 @@
         self.mc.BCR_rr(0xf, register.value)
 
     def _build_failure_recovery(self, exc, withfloats=False):
-        pass # TODO
+        mc = InstrBuilder()
+        self.mc = mc
+        # fill in the jf_descr and jf_gcmap fields of the frame according
+        # to which failure we are resuming from.  These are set before
+        # this function is called (see generate_quick_failure()).
+        ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
+        ofs2 = self.cpu.get_ofs_of_frame_field('jf_gcmap')
+        mc.STG(r.r2, loc.addr(ofs, r.SPP))
+        mc.STG(r.r3, loc.addr(ofs2, r.SPP))
+
+        self._push_core_regs_to_jitframe(mc)
+        if withfloats:
+            self._push_fp_regs_to_jitframe(mc)
+
+        if exc:
+            pass # TODO
+            #xxx
+            ## We might have an exception pending.
+            #mc.load_imm(r.r2, self.cpu.pos_exc_value())
+            ## Copy it into 'jf_guard_exc'
+            #offset = self.cpu.get_ofs_of_frame_field('jf_guard_exc')
+            #mc.load(r.r0.value, r.r2.value, 0)
+            #mc.store(r.r0.value, r.SPP.value, offset)
+            ## Zero out the exception fields
+            #diff = self.cpu.pos_exception() - self.cpu.pos_exc_value()
+            #assert _check_imm_arg(diff)
+            #mc.li(r.r0.value, 0)
+            #mc.store(r.r0.value, r.r2.value, 0)
+            #mc.store(r.r0.value, r.r2.value, diff)
+
+        # now we return from the complete frame, which starts from
+        # _call_header_with_stack_check().  The _call_footer below does it.
+        self._call_footer()
+        rawstart = mc.materialize(self.cpu, [])
+        self.failure_recovery_code[exc + 2 * withfloats] = rawstart
+        self.mc = None
 
     def _build_wb_slowpath(self, withcards, withfloats=False, for_frame=False):
         pass # TODO
@@ -106,7 +148,23 @@
         pass # TODO
 
     def _call_header_with_stack_check(self):
-        pass # TODO
+        self._call_header()
+        if self.stack_check_slowpath == 0:
+            pass            # not translated
+        else:
+            endaddr, lengthaddr, _ = self.cpu.insert_stack_check()
+            diff = lengthaddr - endaddr
+            assert _check_imm_arg(diff)
+
+            mc = self.mc
+            mc.load_imm(r.SCRATCH, self.stack_check_slowpath)
+            mc.load_imm(r.SCRATCH2, endaddr)                 # li r2, endaddr
+            mc.mtctr(r.SCRATCH.value)
+            mc.load(r.SCRATCH.value, r.SCRATCH2.value, 0)    # ld r0, [end]
+            mc.load(r.SCRATCH2.value, r.SCRATCH2.value, diff)# ld r2, [length]
+            mc.subf(r.SCRATCH.value, r.SP.value, r.SCRATCH.value)  # sub r0, SP
+            mc.cmp_op(0, r.SCRATCH.value, r.SCRATCH2.value, signed=False)
+            mc.bgtctrl()
 
     @rgc.no_release_gil
     def assemble_loop(self, jd_id, unique_id, logger, loopname, inputargs,
@@ -322,7 +380,48 @@
                 clt.invalidate_positions.append((rawstart + relpos,
                                                  relative_target))
 
+    def _call_header(self):
+        # Reserve space for a function descriptor, 3 words
+        #self.mc.write64(0)
+        #self.mc.write64(0)
+        #self.mc.write64(0)
 
+        # Build a new stackframe of size STD_FRAME_SIZE_IN_BYTES
+        self.mc.STMG(r.r6, r.r15, loc.addr(-GPR_STACK_SAVE_IN_BYTES, r.SP))
+        self.mc.AGHI(r.SP, loc.imm(-STD_FRAME_SIZE_IN_BYTES))
+
+        # save r4, the second argument, to THREADLOCAL_ADDR_OFFSET
+        self.mc.STG(r.r3, loc.addr(THREADLOCAL_ADDR_OFFSET, r.SP))
+
+        # move the first argument to SPP: the jitframe object
+        self.mc.LGR(r.SPP, r.r2)
+
+        gcrootmap = self.cpu.gc_ll_descr.gcrootmap
+        if gcrootmap and gcrootmap.is_shadow_stack:
+            self._call_header_shadowstack(gcrootmap)
+
+    def _call_footer(self):
+        # the return value is the jitframe
+        self.mc.LGR(r.r2, r.SPP)
+
+        gcrootmap = self.cpu.gc_ll_descr.gcrootmap
+        if gcrootmap and gcrootmap.is_shadow_stack:
+            self._call_footer_shadowstack(gcrootmap)
+
+        # restore registers r6-r15
+        upoffset = STD_FRAME_SIZE_IN_BYTES-GPR_STACK_SAVE_IN_BYTES
+        self.mc.LMG(r.r6, r.r15, loc.addr(upoffset, r.SP))
+        self.jmpto(r.r14)
+
+    def _push_core_regs_to_jitframe(self, mc, includes=r.MANAGED_REGS):
+        base_ofs = self.cpu.get_baseofs_of_frame_field()
+        assert len(includes) == 16
+        mc.STMG(r.r0, r.r15, loc.addr(base_ofs, r.SPP))
+
+    def _push_fp_regs_to_jitframe(self, mc, includes=r.MANAGED_FP_REGS):
+        base_ofs = self.cpu.get_baseofs_of_frame_field()
+        assert len(includes) == 16
+        mc.LMG(r.r0, r.r15, loc.addr(base_ofs, r.SPP))
 
     # ________________________________________
     # ASSEMBLER EMISSION
@@ -331,7 +430,52 @@
         pass # TODO
 
     def emit_finish(self, op, arglocs, regalloc):
-        pass # TODO
+        base_ofs = self.cpu.get_baseofs_of_frame_field()
+        if len(arglocs) > 1:
+            [return_val, fail_descr_loc] = arglocs
+            if op.getarg(0).type == FLOAT:
+                raise NotImplementedError
+                #self.mc.stfd(return_val, loc.addr(base_ofs, r.SPP))
+            else:
+                self.mc.STG(return_val, loc.addr(base_ofs, r.SPP))
+        else:
+            [fail_descr_loc] = arglocs
+
+        ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
+        ofs2 = self.cpu.get_ofs_of_frame_field('jf_gcmap')
+
+        # gcmap logic here:
+        arglist = op.getarglist()
+        if arglist and arglist[0].type == REF:
+            if self._finish_gcmap:
+                # we're returning with a guard_not_forced_2, and
+                # additionally we need to say that the result contains
+                # a reference too:
+                self._finish_gcmap[0] |= r_uint(1)
+                gcmap = self._finish_gcmap
+            else:
+                gcmap = self.gcmap_for_finish
+        elif self._finish_gcmap:
+            # we're returning with a guard_not_forced_2
+            gcmap = self._finish_gcmap
+        else:
+            gcmap = lltype.nullptr(jitframe.GCMAP)
+        # TODO self.load_gcmap(self.mc, r.r2, gcmap)
+
+        assert fail_descr_loc.getint() <= 2**12-1
+        self.mc.LGHI(r.r5, fail_descr_loc)
+        self.mc.STG(r.r5, loc.addr(ofs, r.SPP))
+        self.mc.XGR(r.r2, r.r2)
+        self.mc.STG(r.r2, loc.addr(ofs2, r.SPP))
+
+        # exit function
+        self._call_footer()
+
+    def load_gcmap(self, mc, reg, gcmap):
+        # load the current gcmap into register 'reg'
+        ptr = rffi.cast(lltype.Signed, gcmap)
+        #mc.LGHI(mc.pool
+        #mc.load_imm(reg, ptr)
 
 def notimplemented_op(asm, op, arglocs, regalloc):
     print "[ZARCH/asm] %s not implemented" % op.getopname()
diff --git a/rpython/jit/backend/zarch/instructions.py 
b/rpython/jit/backend/zarch/instructions.py
--- a/rpython/jit/backend/zarch/instructions.py
+++ b/rpython/jit/backend/zarch/instructions.py
@@ -73,15 +73,23 @@
     # load memory
     'LMD':     ('sse',   ['\xEF']),
     'LMG':     ('rsy',   ['\xEB','\x04']),
+    'LHI':     ('ri',    ['\xA7','\x08']),
     'LGHI':    ('ri',    ['\xA7','\x09']),
     'LR':      ('rr',    ['\x18']),
     'LGR':     ('rre',   ['\xB9','\x04']),
     'LG':      ('rxy',   ['\xE3','\x04']),
 
+    # store memory
+    'STMG':    ('rsy',   ['\xEB','\x24']),
+    'ST':      ('rx',    ['\x50']),
+    'STG':     ('rxy',   ['\xE3','\x24']),
+    'STY':     ('rxy',   ['\xE3','\x50']),
+
     # store float
     'STE':     ('rx',    ['\x70']),
     'STD':     ('rx',    ['\x60']),
 
+
     # load binary float
     # E -> short (32bit),
     # D -> long (64bit),
@@ -166,7 +174,6 @@
     'MVCK':    ('ssd',   ['\xD9']),
 
     'PKA':     ('ssf',   ['\xE9']),
-    'STMG':    ('rsy',   ['\xEB','\x24']),
 
     'SVC':     ('i',     ['\x0A']),
 }
diff --git a/rpython/jit/backend/zarch/locations.py 
b/rpython/jit/backend/zarch/locations.py
--- a/rpython/jit/backend/zarch/locations.py
+++ b/rpython/jit/backend/zarch/locations.py
@@ -1,5 +1,5 @@
 from rpython.jit.metainterp.history import INT, FLOAT
-from rpython.jit.backend.zarch.arch import WORD, JITFRAME_FIXED_SIZE
+from rpython.jit.backend.zarch.arch import WORD
 
 class AssemblerLocation(object):
     _immutable_ = True
@@ -190,6 +190,7 @@
     return ImmLocation(i)
 
 def get_fp_offset(base_ofs, position):
+    from rpython.jit.backend.zarch.registers import JITFRAME_FIXED_SIZE
     return base_ofs + WORD * (position + JITFRAME_FIXED_SIZE)
 
 
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
@@ -465,7 +465,17 @@
     prepare_int_add = regallochelp._prepare_binary_arith
 
     def prepare_finish(self, op):
-        return []
+        descr = op.getdescr()
+        fail_descr = cast_instance_to_gcref(descr)
+        # we know it does not move, but well
+        rgc._make_sure_does_not_move(fail_descr)
+        fail_descr = rffi.cast(lltype.Signed, fail_descr)
+        if op.numargs() > 0:
+            loc = self.ensure_reg(op.getarg(0))
+            locs = [loc, imm(fail_descr)]
+        else:
+            locs = [imm(fail_descr)]
+        return locs
 
 def notimplemented(self, op):
     msg = '[S390X/regalloc] %s not implemented\n' % op.getopname()
diff --git a/rpython/jit/backend/zarch/registers.py 
b/rpython/jit/backend/zarch/registers.py
--- a/rpython/jit/backend/zarch/registers.py
+++ b/rpython/jit/backend/zarch/registers.py
@@ -1,5 +1,3 @@
-
-
 from rpython.jit.backend.zarch.locations import FloatRegisterLocation
 from rpython.jit.backend.zarch.locations import RegisterLocation
 
@@ -9,13 +7,28 @@
 [r0,r1,r2,r3,r4,r5,r6,r7,r8,
  r9,r10,r11,r12,r13,r14,r15] = registers
 
-MANAGED_REGS = [r0,r1,r2,r3,r4]
-VOLATILES = [r0,r1,r2,r3,r4]
-SPP = r15
+MANAGED_REGS = registers 
+VOLATILES = [r6,r7,r8,r9,r10,r11,r12,r13,r14,r15]
+SP = r15
 RETURN = r14
+POOL = r13
+SPP = r11
 
 [f0,f1,f2,f3,f4,f5,f6,f7,f8,
  f9,f10,f11,f12,f13,f14,f15] = fpregisters
 
 MANAGED_FP_REGS = fpregisters
 VOLATILES_FLOAT = []
+
+# The JITFRAME_FIXED_SIZE is measured in words, and should be the
+# number of registers that need to be saved into the jitframe when
+# failing a guard, for example.
+ALL_REG_INDEXES = {}
+for _r in MANAGED_REGS:
+    ALL_REG_INDEXES[_r] = len(ALL_REG_INDEXES)
+for _r in MANAGED_FP_REGS:
+    ALL_REG_INDEXES[_r] = len(ALL_REG_INDEXES) + 1
+    #       we leave a never-used hole for f0  ^^^  in the jitframe
+    #       to simplify store_info_on_descr(), which assumes that the
+    #       register number N is at offset N after the non-fp regs
+JITFRAME_FIXED_SIZE = len(ALL_REG_INDEXES) + 1
diff --git a/rpython/jit/backend/zarch/test/test_runner.py 
b/rpython/jit/backend/zarch/test/test_runner.py
--- a/rpython/jit/backend/zarch/test/test_runner.py
+++ b/rpython/jit/backend/zarch/test/test_runner.py
@@ -15,7 +15,7 @@
 class FakeStats(object):
     pass
 
-class TestPPC(LLtypeBackendTest):
+class TestZARCH(LLtypeBackendTest):
     # for the individual tests see
     # ====> ../../test/runner_test.py
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to