[pypy-commit] pypy s390x-backend: added more assembler functions (branching, loading, ...) and added first small test that assembles a real assembler block and executes it

plan_rich noreply at buildbot.pypy.org
Mon Oct 19 05:07:37 EDT 2015


Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r80334:7dae60560404
Date: 2015-10-19 11:07 +0200
http://bitbucket.org/pypy/pypy/changeset/7dae60560404/

Log:	added more assembler functions (branching, loading, ...) and added
	first small test that assembles a real assembler block and executes
	it

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
@@ -1,8 +1,65 @@
 from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler
+from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
+from rpython.jit.backend.zarch import registers as reg
+from rpython.jit.backend.zarch import locations as loc
+from rpython.jit.backend.zarch.codebuilder import InstrBuilder
 from rpython.jit.metainterp.resoperation import rop
+from rpython.rlib.objectmodel import we_are_translated, specialize, compute_unique_id
 
 class AssemblerZARCH(BaseAssembler):
 
+    def __init__(self, cpu, translate_support_code=False):
+        BaseAssembler.__init__(self, cpu, translate_support_code)
+        self.mc = None
+        self.pending_guards = None
+        self.current_clt = None
+        self._regalloc = None
+        self.datablockwrapper = None
+        self.propagate_exception_path = 0
+        self.stack_check_slowpath = 0
+        self.loop_run_counters = []
+        self.gcrootmap_retaddr_forced = 0
+
+    def setup(self, looptoken):
+        BaseAssembler.setup(self, looptoken)
+        assert self.memcpy_addr != 0, 'setup_once() not called?'
+        if we_are_translated():
+            self.debug = False
+        self.current_clt = looptoken.compiled_loop_token
+        self.mc = InstrBuilder()
+        self.pending_guards = []
+        #assert self.datablockwrapper is None --- but obscure case
+        # possible, e.g. getting MemoryError and continuing
+        allblocks = self.get_asmmemmgr_blocks(looptoken)
+        self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr,
+                                                        allblocks)
+        self.mc.datablockwrapper = self.datablockwrapper
+        self.target_tokens_currently_compiling = {}
+        self.frame_depth_to_patch = []
+
+    def teardown(self):
+        self.current_clt = None
+        self._regalloc = None
+        self.mc = None
+        self.pending_guards = None
+
+    def get_asmmemmgr_blocks(self, looptoken):
+        clt = looptoken.compiled_loop_token
+        if clt.asmmemmgr_blocks is None:
+            clt.asmmemmgr_blocks = []
+        return clt.asmmemmgr_blocks
+
+    def gen_func_prolog(self):
+        self.mc.STMG(reg.r0, reg.r15, loc.addr(reg.sp, -160))
+        #self.mc.LAY(reg.r15, loc.addr(reg.sp, -160))
+
+    def gen_func_epilog(self):
+        self.mc.LMG(reg.r0, reg.r15, loc.addr(reg.sp, -160))
+        self.jmpto(reg.r14)
+
+    def jmpto(self, register):
+        self.mc.BCR_rr(0xf, register.value)
+
     def _build_failure_recovery(self, exc, withfloats=False):
         pass # TODO
 
diff --git a/rpython/jit/backend/zarch/codebuilder.py b/rpython/jit/backend/zarch/codebuilder.py
--- a/rpython/jit/backend/zarch/codebuilder.py
+++ b/rpython/jit/backend/zarch/codebuilder.py
@@ -1,7 +1,9 @@
 from rpython.jit.backend.zarch import conditions as cond
 from rpython.jit.backend.zarch import registers as reg
+from rpython.jit.backend.zarch import locations as loc
 from rpython.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin
 from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib.unroll import unrolling_iterable
 from rpython.rtyper.lltypesystem import lltype, rffi, llmemory
 from rpython.tool.udir import udir
 from rpython.jit.backend.detect_cpu import autodetect
@@ -40,9 +42,10 @@
         uX     - immediate X bits (unsigend)
         bd     - base displacement (12 bit)
         bdl    - base displacement long (20 bit)
-        ibd    - index base displacement
-        l4bd    - length base displacement (4 bit)
-        l8bd    - length base displacement (8 bit)
+        bid    - index base displacement
+        bidl   - index base displacement (20 bit)
+        l4bd   - length base displacement (4 bit)
+        l8bd   - length base displacement (8 bit)
 
         note that a suffix 'l' means long, and a prefix length
         """
@@ -105,7 +108,7 @@
     return encode_rr
 
 def build_rx(mnemonic, (opcode,)):
-    @builder.arguments('r/m,ibd')
+    @builder.arguments('r/m,bid')
     def encode_rx(self, reg_or_mask, idxbasedisp):
         self.writechar(opcode)
         index = idxbasedisp.index
@@ -119,7 +122,7 @@
     return encode_rx
 
 def build_rxy(mnemonic, (opcode1,opcode2)):
-    @builder.arguments('r/m,ibdl')
+    @builder.arguments('r/m,bidl')
     def encode_rxy(self, reg_or_mask, idxbasedisp):
         self.writechar(opcode1)
         index = idxbasedisp.index
@@ -199,7 +202,7 @@
     return encode_ssc
 
 def build_ssd(mnemonic, (opcode,)):
-    @builder.arguments('ibd,bd,r')
+    @builder.arguments('bid,bd,r')
     def encode_ssd(self, index_base_disp, base_disp, reg):
         self.writechar(opcode)
         byte = (index_base_disp.index & 0xf) << 4 | reg & 0xf
@@ -273,26 +276,51 @@
     'AG':      (build_rxy,   ['\xE3','\x08']),
     'AGF':     (build_rxy,   ['\xE3','\x18']),
     'AHI':     (build_ri,    ['\xA7','\x0A']),
+    #
+    'BRASL':   (build_ril,   ['\xC0','\x05']),
+    'BXH':     (build_rs,    ['\x86']),
+    'BXHG':    (build_rsy,   ['\xEB','\x44']),
+    'BRXH':    (build_rsi,   ['\x84']),
+    'BRXLG':   (build_rie,   ['\xEC','\x45']),
+    'BCR':     (build_rr,    ['\x07']),
+    #
     'NI':      (build_si,    ['\x94']),
     'NIY':     (build_siy,   ['\xEB','\x54']),
     'NC':      (build_ssa,   ['\xD4']),
     'AP':      (build_ssb,   ['\xFA']),
     'SRP':     (build_ssc,   ['\xF0']),
     'MVCK':    (build_ssd,   ['\xD9']),
+
+    'LAY':     (build_rxy,   ['\xE3','\x71']),
     'LMD':     (build_sse,   ['\xEF']),
+    'LMG':     (build_rsy,   ['\xEB','\x04']),
+    'LGHI':    (build_ri,    ['\xA7','\x09']),
+
     'PKA':     (build_ssf,   ['\xE9']),
-    'BRASL':   (build_ril,   ['\xC0','\x05']),
-    'BXH':     (build_rs,    ['\x86']),
-    'BXHG':    (build_rsy,   ['\xEB','\x44']),
-    'BRXH':    (build_rsi,   ['\x84']),
-    'BRXLG':   (build_rie,   ['\xEC','\x45']),
+    'STMG':    (build_rsy,   ['\xEB','\x24']),
 }
 
+def build_unpack_func(mnemonic, func):
+    def function(self, *args):
+        newargs = [None] * len(args)
+        for i,arg in enumerate(unrolling_iterable(func._arguments_)):
+            if arg == 'r' or arg == 'r/m':
+                newargs[i] = args[i].value
+            elif arg.startswith('i') or arg.startswith('u'):
+                newargs[i] = args[i].value
+            else:
+                newargs[i] = args[i]
+        return func(self, *newargs)
+    function.__name__ = mnemonic
+    return function
+
 def build_instr_codes(clazz):
     for mnemonic, (builder, args) in _mnemonic_codes.items():
         func = builder(mnemonic, args)
-        name = mnemonic + "_" + builder.__name__.split("_")[1]
+        instrtype = builder.__name__.split("_")[1]
+        name = mnemonic + "_" + instrtype
         setattr(clazz, name, func)
+        setattr(clazz, mnemonic, build_unpack_func(mnemonic, func))
 
 class AbstractZARCHBuilder(object):
     def write_i32(self, word):
@@ -300,13 +328,13 @@
         self.writechar(chr((word >> 16) & 0xFF))
         self.writechar(chr((word >> 8) & 0xFF))
         self.writechar(chr(word & 0xFF))
+
     def write_i16(self, word):
         self.writechar(chr((word >> 8) & 0xFF))
         self.writechar(chr(word & 0xFF))
 
 build_instr_codes(AbstractZARCHBuilder)
 
-
 class InstrBuilder(BlockBuilderMixin, AbstractZARCHBuilder):
 
     def __init__(self):
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
@@ -167,9 +167,23 @@
     def as_key(self):            # a word >= 1000, and < 1000 + size of SP frame
         return self.value + 1000
 
+class AddressLocation(AssemblerLocation):
+    _immutable_ = True
+
+    def __init__(self, basereg, indexreg, displace):
+        self.base = basereg.value
+        self.displace = displace
+        self.index = -1
+        if indexreg:
+            self.index = indexreg.value
+
+def addr(basereg, displace, indexreg=None):
+    return AddressLocation(basereg, indexreg, displace)
 
 def imm(i):
     return ImmLocation(i)
 
 def get_fp_offset(base_ofs, position):
     return base_ofs + WORD * (position + JITFRAME_FIXED_SIZE)
+
+
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
@@ -9,5 +9,8 @@
 [r0,r1,r2,r3,r4,r5,r6,r7,r8,
  r9,r10,r11,r12,r13,r14,r15] = registers
 
+sp = r15
+raddr = r14
+
 [f0,f1,f2,f3,f4,f5,f6,f7,f8,
  f9,f10,f11,f12,f13,f14,f15] = fpregisters
diff --git a/rpython/jit/backend/zarch/test/support.py b/rpython/jit/backend/zarch/test/support.py
--- a/rpython/jit/backend/zarch/test/support.py
+++ b/rpython/jit/backend/zarch/test/support.py
@@ -1,4 +1,9 @@
+from rpython.rtyper.lltypesystem import lltype, rffi
 
-
-def run_asm():
-    pass
+def run_asm(asm):
+    BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed)
+    addr = asm.mc.materialize(asm.cpu, [], None)
+    assert addr % 8 == 0
+    func = rffi.cast(lltype.Ptr(BOOTSTRAP_TP), addr)
+    asm.mc._dump_trace(addr, 'test.asm')
+    return func()
diff --git a/rpython/jit/backend/zarch/test/test_assembler.py b/rpython/jit/backend/zarch/test/test_assembler.py
--- a/rpython/jit/backend/zarch/test/test_assembler.py
+++ b/rpython/jit/backend/zarch/test/test_assembler.py
@@ -1,5 +1,5 @@
-from rpython.jit.backend.zarch import conditions as c
-from rpython.jit.backend.zarch import registers as r
+from rpython.jit.backend.zarch import conditions as con
+from rpython.jit.backend.zarch import registers as reg
 from rpython.jit.backend.zarch.assembler import AssemblerZARCH
 from rpython.jit.backend.zarch.locations import imm
 from rpython.jit.backend.zarch.test.support import run_asm
@@ -34,3 +34,15 @@
         from rpython.jit.backend.zarch import assembler
         assert assembler.asm_operations[i] \
             is AssemblerZARCH.emit_op_int_add.im_func
+
+    def test_load_small_int_to_reg(self):
+        self.a.mc.LGHI(reg.r2, imm(123))
+        self.a.jmpto(reg.r14)
+        assert run_asm(self.a) == 123
+
+    #def test_load_small_int_to_reg_func(self):
+    #    self.a.gen_func_prolog()
+    #    self.a.mc.LGHI(r.r2, imm(123))
+    #    self.a.gen_func_epilog()
+    #    assert run_asm(self.a) == 123
+
diff --git a/rpython/jit/backend/zarch/test/test_auto_encoding.py b/rpython/jit/backend/zarch/test/test_auto_encoding.py
--- a/rpython/jit/backend/zarch/test/test_auto_encoding.py
+++ b/rpython/jit/backend/zarch/test/test_auto_encoding.py
@@ -140,8 +140,8 @@
     'u64':  test_range(64),
     'bd':   build_fake(FakeBaseDisplace,4,12),
     'bdl':  build_fake(FakeBaseDisplace,4,19),
-    'ibd':  build_fake(FakeIndexBaseDisplace,4,4,12),
-    'ibdl': build_fake(FakeIndexBaseDisplace,4,4,(20,True)),
+    'bid':  build_fake(FakeIndexBaseDisplace,4,4,12),
+    'bidl': build_fake(FakeIndexBaseDisplace,4,4,(20,True)),
     'l8bd': build_fake(FakeLengthBaseDisplace,8,4,12),
     'l4bd': build_fake(FakeLengthBaseDisplace,4,4,12),
 }


More information about the pypy-commit mailing list