[pypy-commit] pypy s390x-backend: split up the code builder into several files, branch relative shifts a zero value on the LSB before calculating the address, this case is now correctly handled

plan_rich noreply at buildbot.pypy.org
Tue Oct 20 04:55:08 EDT 2015


Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r80348:e505fe63db6c
Date: 2015-10-20 10:55 +0200
http://bitbucket.org/pypy/pypy/changeset/e505fe63db6c/

Log:	split up the code builder into several files, branch relative shifts
	a zero value on the LSB before calculating the address, this case is
	now correctly handled

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,6 +1,7 @@
 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.zarch.instruction_builder import build_instr_codes
 from rpython.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin
 from rpython.rlib.objectmodel import we_are_translated
 from rpython.rlib.unroll import unrolling_iterable
@@ -29,305 +30,6 @@
 class Operand(object):
     pass
 
-class builder(object):
-    """ NOT_RPYTHON """
-    @staticmethod
-    def arguments(args_str):
-        """ NOT_RPYTHON """
-        """
-        Available names:
-        r      - register
-        r/m    - register or mask
-        iX     - immediate X bits (signed)
-        uX     - immediate X bits (unsigend)
-        bd     - base displacement (12 bit)
-        bdl    - base displacement long (20 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
-        """
-        def impl(func):
-            func._arguments_ = args_str.split(',')
-            return func
-        return impl
-
-BIT_MASK_4 =  0xF
-BIT_MASK_12 = 0xFFF
-BIT_MASK_16 = 0xFFFF
-BIT_MASK_20 = 0xFFFFF
-BIT_MASK_32 = 0xFFFFFFFF
-
- at always_inline
-def encode_base_displace(mc, base_displace):
-    """
-        +---------------------------------+
-        | ... | base | length[0:11] | ... |
-        +---------------------------------+
-    """
-    displace = base_displace.displace
-    base = base_displace.base & 0xf
-    byte = (displace >> 8 & 0xf) | base << 4
-    mc.writechar(chr(byte))
-    mc.writechar(chr(displace & 0xff))
-
- at always_inline
-def encode_base_displace_long(mc, basedisp):
-    """
-        +-------------------------------------------------+
-        | ... | base | length[0:11] | length[12:20] | ... |
-        +-------------------------------------------------+
-    """
-    displace = basedisp.displace & 0xfffff
-    base = basedisp.base & 0xf
-    byte = displace >> 8 & 0xf | base << 4
-    mc.writechar(chr(byte))
-    mc.writechar(chr(displace & 0xff))
-    byte = displace >> 12 & 0xff
-    mc.writechar(chr(byte))
-
-def build_rr(mnemonic, (opcode,)):
-    @builder.arguments('r,r')
-    def encode_rr(self, reg1, reg2):
-        self.writechar(opcode)
-        operands = ((reg1 & 0x0f) << 4) | (reg2 & 0xf)
-        self.writechar(chr(operands))
-    return encode_rr
-
-def build_rre(mnemonic, (opcode1,opcode2)):
-    @builder.arguments('r,r')
-    def encode_rr(self, reg1, reg2):
-        self.writechar(opcode1)
-        self.writechar(opcode2)
-        self.writechar('\x00')
-        operands = ((reg1 & 0x0f) << 4) | (reg2 & 0xf)
-        self.writechar(chr(operands))
-    return encode_rr
-
-def build_rx(mnemonic, (opcode,)):
-    @builder.arguments('r/m,bid')
-    def encode_rx(self, reg_or_mask, idxbasedisp):
-        self.writechar(opcode)
-        index = idxbasedisp.index
-        byte = (reg_or_mask & 0x0f) << 4 | index & 0xf
-        self.writechar(chr(byte))
-        displace = idxbasedisp.displace & BIT_MASK_12
-        base = idxbasedisp.base & 0xf
-        byte = displace >> 8 & 0xf | base << 4
-        self.writechar(chr(byte))
-        self.writechar(chr(displace & 0xff))
-    return encode_rx
-
-def build_rxy(mnemonic, (opcode1,opcode2)):
-    @builder.arguments('r/m,bidl')
-    def encode_rxy(self, reg_or_mask, idxbasedisp):
-        self.writechar(opcode1)
-        index = idxbasedisp.index
-        byte = (reg_or_mask & 0x0f) << 4 | index & 0xf
-        self.writechar(chr(byte))
-        encode_base_displace_long(self, idxbasedisp)
-        self.writechar(opcode2)
-    return encode_rxy
-
-def build_ri(mnemonic, (opcode,halfopcode)):
-    @builder.arguments('r/m,i16')
-    def encode_ri(self, reg_or_mask, imm16):
-        self.writechar(opcode)
-        byte = (reg_or_mask & 0xf) << 4 | (ord(halfopcode) & 0xf)
-        self.writechar(chr(byte))
-        self.writechar(chr(imm16 >> 8 & 0xff))
-        self.writechar(chr(imm16 & 0xff))
-    return encode_ri
-
-def build_ril(mnemonic, (opcode,halfopcode)):
-    @builder.arguments('r/m,i32')
-    def encode_ri(self, reg_or_mask, imm32):
-        self.writechar(opcode)
-        byte = (reg_or_mask & 0xf) << 4 | (ord(halfopcode) & 0xf)
-        self.writechar(chr(byte))
-        # half word boundary, addressing bytes
-        self.write_i32(imm32 >> 1 & BIT_MASK_32)
-    return encode_ri
-
-
-def build_si(mnemonic, (opcode,)):
-    @builder.arguments('bd,u8')
-    def encode_si(self, base_displace, uimm8):
-        self.writechar(opcode)
-        self.writechar(chr(uimm8))
-        encode_base_displace(self, base_displace)
-    return encode_si
-
-def build_siy(mnemonic, (opcode1,opcode2)):
-    @builder.arguments('bd,u8')
-    def encode_siy(self, base_displace, uimm8):
-        self.writechar(opcode1)
-        self.writechar(chr(uimm8))
-        encode_base_displace(self, base_displace)
-        displace = base_displace.displace
-        self.writechar(chr(displace >> 12 & 0xff))
-        self.writechar(opcode2)
-    return encode_siy
-
-def build_ssa(mnemonic, (opcode1,)):
-    @builder.arguments('l8bd,bd')
-    def encode_ssa(self, len_base_disp, base_displace):
-        self.writechar(opcode1)
-        self.writechar(chr(len_base_disp.length & 0xff))
-        encode_base_displace(self, len_base_disp)
-        encode_base_displace(self, base_displace)
-    return encode_ssa
-
-def build_ssb(mnemonic, (opcode1,)):
-    @builder.arguments('l8bd,l8bd')
-    def encode_ssb(self, len_base_disp1, len_base_disp2):
-        self.writechar(opcode1)
-        byte = (len_base_disp1.length & 0xf) << 4 | len_base_disp2.length & 0xf
-        self.writechar(chr(byte))
-        encode_base_displace(self, len_base_disp1)
-        encode_base_displace(self, len_base_disp2)
-    return encode_ssb
-
-def build_ssc(mnemonic, (opcode1,)):
-    @builder.arguments('l4bd,bd,u4')
-    def encode_ssc(self, len_base_disp, base_disp, uimm4):
-        self.writechar(opcode1)
-        byte = (len_base_disp.length & 0xf) << 4 | uimm4 & 0xf
-        self.writechar(chr(byte))
-        encode_base_displace(self, len_base_disp)
-        encode_base_displace(self, base_disp)
-    return encode_ssc
-
-def build_ssd(mnemonic, (opcode,)):
-    @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
-        self.writechar(chr(byte))
-        encode_base_displace(self, index_base_disp)
-        encode_base_displace(self, base_disp)
-    return encode_ssd
-
-def build_sse(mnemonic, (opcode,)):
-    @builder.arguments('r,r,bd,bd')
-    def encode_sse(self, reg1, reg3, base_disp2, base_disp4):
-        self.writechar(opcode)
-        byte = (reg1 & BIT_MASK_4) << 4 | reg3 & BIT_MASK_4
-        self.writechar(chr(byte))
-        encode_base_displace(self, base_disp2)
-        encode_base_displace(self, base_disp4)
-    return encode_sse
-
-def build_ssf(mnemonic, (opcode,)):
-    @builder.arguments('bd,l8bd')
-    def encode_ssf(self, base_disp, len_base_disp):
-        self.writechar(opcode)
-        self.writechar(chr(len_base_disp.length & 0xff))
-        encode_base_displace(self, base_disp)
-        encode_base_displace(self, len_base_disp)
-    return encode_ssf
-
-def build_rs(mnemonic, (opcode,)):
-    @builder.arguments('r,r,bd')
-    def encode_rs(self, reg1, reg3, base_displace):
-        self.writechar(opcode)
-        self.writechar(chr((reg1 & BIT_MASK_4) << 4 | reg3 & BIT_MASK_4))
-        encode_base_displace(self, base_displace)
-    return encode_rs
-
-def build_rsy(mnemonic, (opcode1,opcode2)):
-    @builder.arguments('r,r,bdl')
-    def encode_ssa(self, reg1, reg3, base_displace):
-        self.writechar(opcode1)
-        self.writechar(chr((reg1 & BIT_MASK_4) << 4 | reg3 & BIT_MASK_4))
-        encode_base_displace_long(self, base_displace)
-        self.writechar(opcode2)
-    return encode_ssa
-
-def build_rsi(mnemonic, (opcode,)):
-    @builder.arguments('r,r,i16')
-    def encode_ri(self, reg1, reg2, imm16):
-        self.writechar(opcode)
-        byte = (reg1 & BIT_MASK_4) << 4 | (reg2 & BIT_MASK_4)
-        self.writechar(chr(byte))
-        self.write_i16(imm16 >> 1 & BIT_MASK_16)
-    return encode_ri
-
-def build_rie(mnemonic, (opcode1,opcode2)):
-    @builder.arguments('r,r,i16')
-    def encode_ri(self, reg1, reg2, imm16):
-        self.writechar(opcode1)
-        byte = (reg1 & BIT_MASK_4) << 4 | (reg2 & BIT_MASK_4)
-        self.writechar(chr(byte))
-        self.write_i16(imm16 >> 1 & BIT_MASK_16)
-        self.writechar(chr(0x0))
-        self.writechar(opcode2)
-    return encode_ri
-
-_mnemonic_codes = {
-    'AR':      (build_rr,    ['\x1A']),
-    'AGR':     (build_rre,   ['\xB9','\x08']),
-    'AGFR':    (build_rre,   ['\xB9','\x18']),
-    'A':       (build_rx,    ['\x5A']),
-    'AY':      (build_rxy,   ['\xE3','\x5A']),
-    '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']),
-    'BC':      (build_rx,    ['\x47']),
-    'BRC':     (build_ri,    ['\xA7','\x04']),
-    'BRCL':    (build_ril,   ['\xC0','\x04']),
-    #
-    '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']),
-    'LR':      (build_rr,    ['\x18']),
-    'LGR':     (build_rre,   ['\xB9','\x04']),
-
-    'PKA':     (build_ssf,   ['\xE9']),
-    'STMG':    (build_rsy,   ['\xEB','\x24']),
-    'SR':      (build_rr,    ['\x1B']),
-    'SGR':     (build_rre,   ['\xB9','\x09']),
-}
-
-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)
-        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):
         self.writechar(chr((word >> 24) & 0xFF))
@@ -386,4 +88,4 @@
 
 # Used to build the MachineCodeBlockWrapper
 all_instructions = sorted([name for cls in _classes for name in cls.__dict__ \
-                          if name.split('_')[0].isupper()])
+                          if name.split('_')[0].isupper() and '_' in name])
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
@@ -0,0 +1,278 @@
+from rpython.jit.backend.zarch.instructions import (all_mnemonic_codes,
+        arith_mnemic_codes, branch_mnemoic_codes)
+from rpython.rtyper.lltypesystem.rbuilder import always_inline
+
+
+class builder(object):
+    """ NOT_RPYTHON """
+    @staticmethod
+    def arguments(args_str):
+        """ NOT_RPYTHON """
+        """
+        Available names:
+        r      - register
+        r/m    - register or mask
+        iX     - immediate X bits (signed)
+        uX     - immediate X bits (unsigend)
+        bd     - base displacement (12 bit)
+        bdl    - base displacement long (20 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
+        """
+        def impl(func):
+            func._arguments_ = args_str.split(',')
+            return func
+        return impl
+
+BIT_MASK_4 =  0xF
+BIT_MASK_12 = 0xFFF
+BIT_MASK_16 = 0xFFFF
+BIT_MASK_20 = 0xFFFFF
+BIT_MASK_32 = 0xFFFFFFFF
+
+ at always_inline
+def encode_base_displace(mc, base_displace):
+    """
+        +---------------------------------+
+        | ... | base | length[0:11] | ... |
+        +---------------------------------+
+    """
+    displace = base_displace.displace
+    base = base_displace.base & 0xf
+    byte = (displace >> 8 & 0xf) | base << 4
+    mc.writechar(chr(byte))
+    mc.writechar(chr(displace & 0xff))
+
+ at always_inline
+def encode_base_displace_long(mc, basedisp):
+    """
+        +-------------------------------------------------+
+        | ... | base | length[0:11] | length[12:20] | ... |
+        +-------------------------------------------------+
+    """
+    displace = basedisp.displace & 0xfffff
+    base = basedisp.base & 0xf
+    byte = displace >> 8 & 0xf | base << 4
+    mc.writechar(chr(byte))
+    mc.writechar(chr(displace & 0xff))
+    byte = displace >> 12 & 0xff
+    mc.writechar(chr(byte))
+
+def build_rr(mnemonic, (opcode,)):
+    @builder.arguments('r,r')
+    def encode_rr(self, reg1, reg2):
+        self.writechar(opcode)
+        operands = ((reg1 & 0x0f) << 4) | (reg2 & 0xf)
+        self.writechar(chr(operands))
+    return encode_rr
+
+def build_rre(mnemonic, (opcode1,opcode2)):
+    @builder.arguments('r,r')
+    def encode_rr(self, reg1, reg2):
+        self.writechar(opcode1)
+        self.writechar(opcode2)
+        self.writechar('\x00')
+        operands = ((reg1 & 0x0f) << 4) | (reg2 & 0xf)
+        self.writechar(chr(operands))
+    return encode_rr
+
+def build_rx(mnemonic, (opcode,)):
+    @builder.arguments('r/m,bid')
+    def encode_rx(self, reg_or_mask, idxbasedisp):
+        self.writechar(opcode)
+        index = idxbasedisp.index
+        byte = (reg_or_mask & 0x0f) << 4 | index & 0xf
+        self.writechar(chr(byte))
+        displace = idxbasedisp.displace & BIT_MASK_12
+        base = idxbasedisp.base & 0xf
+        byte = displace >> 8 & 0xf | base << 4
+        self.writechar(chr(byte))
+        self.writechar(chr(displace & 0xff))
+    return encode_rx
+
+def build_rxy(mnemonic, (opcode1,opcode2)):
+    @builder.arguments('r/m,bidl')
+    def encode_rxy(self, reg_or_mask, idxbasedisp):
+        self.writechar(opcode1)
+        index = idxbasedisp.index
+        byte = (reg_or_mask & 0x0f) << 4 | index & 0xf
+        self.writechar(chr(byte))
+        encode_base_displace_long(self, idxbasedisp)
+        self.writechar(opcode2)
+    return encode_rxy
+
+def build_ri(mnemonic, (opcode,halfopcode)):
+    br = is_branch_relative(mnemonic)
+    @builder.arguments('r/m,i16')
+    def encode_ri(self, reg_or_mask, imm16):
+        self.writechar(opcode)
+        byte = (reg_or_mask & 0xf) << 4 | (ord(halfopcode) & 0xf)
+        self.writechar(chr(byte))
+        if br:
+            imm16 = imm16 >> 1
+        self.writechar(chr(imm16 >> 8 & 0xff))
+        self.writechar(chr(imm16 & 0xff))
+    return encode_ri
+
+def build_ril(mnemonic, (opcode,halfopcode)):
+    br = is_branch_relative(mnemonic)
+    @builder.arguments('r/m,i32')
+    def encode_ri(self, reg_or_mask, imm32):
+        self.writechar(opcode)
+        byte = (reg_or_mask & 0xf) << 4 | (ord(halfopcode) & 0xf)
+        self.writechar(chr(byte))
+        if br:
+            imm32 = imm32 >> 1
+        # half word boundary, addressing bytes
+        self.write_i32(imm32 & BIT_MASK_32)
+    return encode_ri
+
+
+def build_si(mnemonic, (opcode,)):
+    @builder.arguments('bd,u8')
+    def encode_si(self, base_displace, uimm8):
+        self.writechar(opcode)
+        self.writechar(chr(uimm8))
+        encode_base_displace(self, base_displace)
+    return encode_si
+
+def build_siy(mnemonic, (opcode1,opcode2)):
+    @builder.arguments('bd,u8')
+    def encode_siy(self, base_displace, uimm8):
+        self.writechar(opcode1)
+        self.writechar(chr(uimm8))
+        encode_base_displace(self, base_displace)
+        displace = base_displace.displace
+        self.writechar(chr(displace >> 12 & 0xff))
+        self.writechar(opcode2)
+    return encode_siy
+
+def build_ssa(mnemonic, (opcode1,)):
+    @builder.arguments('l8bd,bd')
+    def encode_ssa(self, len_base_disp, base_displace):
+        self.writechar(opcode1)
+        self.writechar(chr(len_base_disp.length & 0xff))
+        encode_base_displace(self, len_base_disp)
+        encode_base_displace(self, base_displace)
+    return encode_ssa
+
+def build_ssb(mnemonic, (opcode1,)):
+    @builder.arguments('l8bd,l8bd')
+    def encode_ssb(self, len_base_disp1, len_base_disp2):
+        self.writechar(opcode1)
+        byte = (len_base_disp1.length & 0xf) << 4 | len_base_disp2.length & 0xf
+        self.writechar(chr(byte))
+        encode_base_displace(self, len_base_disp1)
+        encode_base_displace(self, len_base_disp2)
+    return encode_ssb
+
+def build_ssc(mnemonic, (opcode1,)):
+    @builder.arguments('l4bd,bd,u4')
+    def encode_ssc(self, len_base_disp, base_disp, uimm4):
+        self.writechar(opcode1)
+        byte = (len_base_disp.length & 0xf) << 4 | uimm4 & 0xf
+        self.writechar(chr(byte))
+        encode_base_displace(self, len_base_disp)
+        encode_base_displace(self, base_disp)
+    return encode_ssc
+
+def build_ssd(mnemonic, (opcode,)):
+    @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
+        self.writechar(chr(byte))
+        encode_base_displace(self, index_base_disp)
+        encode_base_displace(self, base_disp)
+    return encode_ssd
+
+def build_sse(mnemonic, (opcode,)):
+    @builder.arguments('r,r,bd,bd')
+    def encode_sse(self, reg1, reg3, base_disp2, base_disp4):
+        self.writechar(opcode)
+        byte = (reg1 & BIT_MASK_4) << 4 | reg3 & BIT_MASK_4
+        self.writechar(chr(byte))
+        encode_base_displace(self, base_disp2)
+        encode_base_displace(self, base_disp4)
+    return encode_sse
+
+def build_ssf(mnemonic, (opcode,)):
+    @builder.arguments('bd,l8bd')
+    def encode_ssf(self, base_disp, len_base_disp):
+        self.writechar(opcode)
+        self.writechar(chr(len_base_disp.length & 0xff))
+        encode_base_displace(self, base_disp)
+        encode_base_displace(self, len_base_disp)
+    return encode_ssf
+
+def build_rs(mnemonic, (opcode,)):
+    @builder.arguments('r,r,bd')
+    def encode_rs(self, reg1, reg3, base_displace):
+        self.writechar(opcode)
+        self.writechar(chr((reg1 & BIT_MASK_4) << 4 | reg3 & BIT_MASK_4))
+        encode_base_displace(self, base_displace)
+    return encode_rs
+
+def build_rsy(mnemonic, (opcode1,opcode2)):
+    @builder.arguments('r,r,bdl')
+    def encode_ssa(self, reg1, reg3, base_displace):
+        self.writechar(opcode1)
+        self.writechar(chr((reg1 & BIT_MASK_4) << 4 | reg3 & BIT_MASK_4))
+        encode_base_displace_long(self, base_displace)
+        self.writechar(opcode2)
+    return encode_ssa
+
+def build_rsi(mnemonic, (opcode,)):
+    br = is_branch_relative(mnemonic)
+    @builder.arguments('r,r,i16')
+    def encode_ri(self, reg1, reg2, imm16):
+        self.writechar(opcode)
+        byte = (reg1 & BIT_MASK_4) << 4 | (reg2 & BIT_MASK_4)
+        self.writechar(chr(byte))
+        if br:
+            imm16 = imm16 >> 1
+        self.write_i16(imm16 & BIT_MASK_16)
+    return encode_ri
+
+def build_rie(mnemonic, (opcode1,opcode2)):
+    br = is_branch_relative(mnemonic)
+    @builder.arguments('r,r,i16')
+    def encode_ri(self, reg1, reg2, imm16):
+        self.writechar(opcode1)
+        byte = (reg1 & BIT_MASK_4) << 4 | (reg2 & BIT_MASK_4)
+        self.writechar(chr(byte))
+        if br:
+            imm16 = imm16 >> 1
+        self.write_i16(imm16 & BIT_MASK_16)
+        self.writechar(chr(0x0))
+        self.writechar(opcode2)
+    return encode_ri
+
+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 is_branch_relative(name):
+    return name.startswith('BR')
+
+def build_instr_codes(clazz):
+    for mnemonic, (instrtype, args) in all_mnemonic_codes.items():
+        builder = globals()['build_' + instrtype]
+        func = builder(mnemonic, args)
+        name = mnemonic + "_" + instrtype
+        setattr(clazz, name, func)
+        setattr(clazz, mnemonic, build_unpack_func(mnemonic, func))
diff --git a/rpython/jit/backend/zarch/instructions.py b/rpython/jit/backend/zarch/instructions.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/zarch/instructions.py
@@ -0,0 +1,49 @@
+
+branch_mnemoic_codes = {
+    'BRASL':   ('ril',   ['\xC0','\x05']),
+    'BCR':     ('rr',    ['\x07']),
+    'BC':      ('rx',    ['\x47']),
+    'BRC':     ('ri',    ['\xA7','\x04']),
+    'BRCL':    ('ril',   ['\xC0','\x04']),
+}
+
+arith_mnemic_codes = {
+    'AR':      ('rr',    ['\x1A']),
+    'AGR':     ('rre',   ['\xB9','\x08']),
+    'AGFR':    ('rre',   ['\xB9','\x18']),
+    'A':       ('rx',    ['\x5A']),
+    'SR':      ('rr',    ['\x1B']),
+    'SGR':     ('rre',   ['\xB9','\x09']),
+}
+
+all_mnemonic_codes = {
+    'AY':      ('rxy',   ['\xE3','\x5A']),
+    'AG':      ('rxy',   ['\xE3','\x08']),
+    'AGF':     ('rxy',   ['\xE3','\x18']),
+    'AHI':     ('ri',    ['\xA7','\x0A']),
+    #
+    'BXH':     ('rs',    ['\x86']),
+    'BXHG':    ('rsy',   ['\xEB','\x44']),
+    'BRXH':    ('rsi',   ['\x84']),
+    'BRXLG':   ('rie',   ['\xEC','\x45']),
+    #
+    'NI':      ('si',    ['\x94']),
+    'NIY':     ('siy',   ['\xEB','\x54']),
+    'NC':      ('ssa',   ['\xD4']),
+    'AP':      ('ssb',   ['\xFA']),
+    'SRP':     ('ssc',   ['\xF0']),
+    'MVCK':    ('ssd',   ['\xD9']),
+
+    'LAY':     ('rxy',   ['\xE3','\x71']),
+    'LMD':     ('sse',   ['\xEF']),
+    'LMG':     ('rsy',   ['\xEB','\x04']),
+    'LGHI':    ('ri',    ['\xA7','\x09']),
+    'LR':      ('rr',    ['\x18']),
+    'LGR':     ('rre',   ['\xB9','\x04']),
+
+    'PKA':     ('ssf',   ['\xE9']),
+    'STMG':    ('rsy',   ['\xEB','\x24']),
+}
+all_mnemonic_codes.update(arith_mnemic_codes)
+all_mnemonic_codes.update(branch_mnemoic_codes)
+
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
@@ -68,7 +68,7 @@
         L1 = self.a.mc.get_relative_pos()
         self.a.mc.SGR(reg.r3, reg.r4)
         LJ = self.a.mc.get_relative_pos()
-        self.a.mc.BRCL(loc.imm(0x2), loc.imm(L1-LJ))
+        self.a.mc.BRCL(con.GT, loc.imm(L1-LJ))
         self.a.mc.LGR(reg.r2, reg.r3)
         self.a.jmpto(reg.r14)
         assert run_asm(self.a) == 0
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
@@ -102,7 +102,7 @@
 
     __repr__ = __str__
 
-def test_range(bits, signed=False, count=24):
+def range_of_bits(bits, signed=False, count=24):
     if isinstance(bits, tuple):
         bits, signed = bits
     if signed:
@@ -113,7 +113,7 @@
     return [0,1,maximum-1] + [random.randrange(0,maximum) for i in range(count)]
 
 def build_fake(clazz, *arg_bits):
-    possibilities = itertools.product(*[test_range(b) for b in arg_bits])
+    possibilities = itertools.product(*[range_of_bits(b) for b in arg_bits])
     results = []
     i = 0
     for args in possibilities:
@@ -128,16 +128,16 @@
 TEST_CASE_GENERATE = {
     'r':    REGS,
     'r/m':  REGS,
-    'i4':   test_range(4, signed=True),
-    'i8':   test_range(8, signed=True),
-    'i16':  test_range(16, signed=True),
-    'i32':  test_range(32, signed=True),
-    'i64':  test_range(64, signed=True),
-    'u4':   test_range(4),
-    'u8':   test_range(8),
-    'u16':  test_range(16),
-    'u32':  test_range(32),
-    'u64':  test_range(64),
+    'i4':   range_of_bits(4, signed=True),
+    'i8':   range_of_bits(8, signed=True),
+    'i16':  range_of_bits(16, signed=True),
+    'i32':  range_of_bits(32, signed=True),
+    'i64':  range_of_bits(64, signed=True),
+    'u4':   range_of_bits(4),
+    'u8':   range_of_bits(8),
+    'u16':  range_of_bits(16),
+    'u32':  range_of_bits(32),
+    'u64':  range_of_bits(64),
     'bd':   build_fake(FakeBaseDisplace,4,12),
     'bdl':  build_fake(FakeBaseDisplace,4,19),
     'bid':  build_fake(FakeIndexBaseDisplace,4,4,12),
@@ -154,7 +154,6 @@
 
     def get_func_arg_types(self, methodname):
         from rpython.jit.backend.zarch.codebuilder import AbstractZARCHBuilder
-        import inspect
         func = getattr(AbstractZARCHBuilder, methodname)
         return func._arguments_
 


More information about the pypy-commit mailing list