[pypy-commit] pypy s390x-backend: immediate encoding with base register displacement (SI)

plan_rich noreply at buildbot.pypy.org
Thu Oct 15 08:32:45 EDT 2015


Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r80234:235a94b23040
Date: 2015-10-15 14:33 +0200
http://bitbucket.org/pypy/pypy/changeset/235a94b23040/

Log:	immediate encoding with base register displacement (SI)

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
@@ -5,6 +5,7 @@
 from rpython.rtyper.lltypesystem import lltype, rffi, llmemory
 from rpython.tool.udir import udir
 from rpython.jit.backend.detect_cpu import autodetect
+from rpython.rtyper.lltypesystem.rbuilder import always_inline
 
 clear_cache = rffi.llexternal(
     "__clear_cache",
@@ -26,6 +27,14 @@
 class Operand(object):
     pass
 
+ at always_inline
+def encode_base_displace(mc, base_displace):
+    displace = base_displace.displace # & 0x3ff
+    base = base_displace.base & 0xf
+    byte = (displace >> 8 & 0xf) | base << 4
+    mc.writechar(chr(byte))
+    mc.writechar(chr(displace & 0xff))
+
 def build_rr(mnemonic, (opcode,)):
     def encode_rr(self, reg1, reg2):
         self.writechar(opcode)
@@ -72,25 +81,34 @@
     return encode_rxy
 
 def build_ri(mnemonic, (opcode,halfopcode)):
-    def encode_ri(self, reg_or_mask, imm):
+    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(imm >> 8 & 0xff))
-        self.writechar(chr(imm & 0xff))
+        self.writechar(chr(imm16 >> 8 & 0xff))
+        self.writechar(chr(imm16 & 0xff))
     return encode_ri
 
+def build_si(mnemonic, (opcode,)):
+    def encode_si(self, base_displace, uimm8):
+        self.writechar(opcode)
+        self.writechar(chr(uimm8))
+        encode_base_displace(self, base_displace)
+    return encode_si
+
+_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']),
+    'NI':      (build_si,    ['\x94']),
+}
+
 def build_instr_codes(clazz):
-    _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']),
-    }
 
     for mnemonic, (builder, args) in _mnemonic_codes.items():
         func = builder(mnemonic, args)
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
@@ -5,6 +5,7 @@
 from rpython.rlib.rarithmetic import intmask
 from rpython.tool.udir import udir
 import itertools
+import re
 
 INPUTNAME = 'checkfile_%s.s'
 FILENAME = 'checkfile_%s.o'
@@ -28,7 +29,7 @@
                 return    # ignore the extra character '\x40'
             print self.op
             post = self.expected[self.index+1:self.index+1+15]
-            generated = "\x09from codebuilder.py: " + hexdump(self.expected[self.instrindex:self.index] + "!" + char + "!" + post)+"..."
+            generated = "\x09from codebuilder.py: " + hexdump(self.expected[self.instrindex:self.index] + char )+"..."
             print generated
             expected = "\x09from         gnu as: " + hexdump(self.expected[self.instrindex:self.index+15])+"..."
             print expected
@@ -75,8 +76,24 @@
         base = self.base
         return "{disp}(%r{index},%r{base})".format(**locals())
 
+class FakeBaseDisplace(object):
+    def __init__(self, base, disp):
+        self.base = base
+        self.displace = disp
+
+    def __str__(self):
+        disp = self.displace
+        base = self.base
+        return "{disp}(%r{base})".format(**locals())
+
+def build_base_disp(base_bits, displace_bits):
+    possibilities = itertools.product(range(base_bits), range(displace_bits))
+    results = []
+    for (base,disp) in possibilities:
+        results.append(FakeBaseDisplace(base,disp))
+    return results
+
 def build_idx_base_disp(index_bits, base_bits, displace_bits):
-
     possibilities = itertools.product(range(index_bits), range(base_bits),
                                       range(displace_bits))
     results = []
@@ -91,6 +108,7 @@
     REGNAMES = ['%%r%d' % i for i in REGS]
     accept_unnecessary_prefix = None
     methname = '?'
+    BASE_DISPLACE = build_base_disp(8,12)
     INDEX_BASE_DISPLACE = build_idx_base_disp(8,8,12)
     INDEX_BASE_DISPLACE_LONG = build_idx_base_disp(8,8,20)
 
@@ -121,8 +139,24 @@
                     for ofs in self.stack_bp_tests(1)
                 ]
 
+    def imm_tests(self, name, modes, index):
+        from rpython.jit.backend.zarch.codebuilder import AbstractZARCHBuilder
+        import inspect
+        mode = modes[index]
+        assert mode == 'i'
+        func = getattr(AbstractZARCHBuilder, name)
+        args = inspect.getargspec(func).args
+        # 1 off, self is first arg
+        match = re.compile("(u?imm\d+)").match(args[index+1])
+        assert match
+        return getattr(self, match.group(1) + "_tests")()
+
+    def uimm16_tests(self):
+        v = ([0,1,65535] +
+             [random.randrange(0,65535) for i in range(COUNT1)])
+        return v
     def imm16_tests(self):
-        v = ([-128,-1,0,1,127] +
+        v = ([-32768,-1,0,1,32767] +
              [random.randrange(-32768, 32767) for i in range(COUNT1)])
         return v
 
@@ -130,6 +164,10 @@
         v = ([-128,-1,0,1,127] +
              [random.randrange(-127, 127) for i in range(COUNT1)])
         return v
+    def uimm8_tests(self):
+        v = ([0,1,255] +
+             [random.randrange(0,255) for i in range(COUNT1)])
+        return v
 
     def imm32_tests(self):
         v = ([-0x80000000, 0x7FFFFFFF, 128, 256, -129, -255] +
@@ -147,6 +185,7 @@
     def get_mapping_asm_to_str(self):
         return {
             'r': self.assembler_operand_reg,
+            's': lambda x: str(x),
             'x': lambda x: str(x),
             'y': lambda x: str(x),
             'i': lambda x: str(x)
@@ -216,17 +255,17 @@
 
     def make_all_tests(self, methname, modes, args=[]):
         tests = {
-            'r': self.REGS,
-            'x': self.INDEX_BASE_DISPLACE,
-            'y': self.INDEX_BASE_DISPLACE_LONG,
-            'i': self.imm16_tests(),
+            'r': lambda i: self.REGS,
+            'x': lambda i: self.INDEX_BASE_DISPLACE,
+            'y': lambda i: self.INDEX_BASE_DISPLACE_LONG,
+            'i': lambda i: self.imm_tests(methname, modes, i),
+            's': lambda i: self.BASE_DISPLACE,
         }
         combinations = []
-        for m in modes:
-            if tests[m] is not None:
-                elems = tests[m]
-                random.shuffle(elems)
-                combinations.append(elems)
+        for i,m in enumerate(modes):
+            elems = tests[m](i)
+            random.shuffle(elems)
+            combinations.append(elems)
         results = []
         for args in itertools.product(*combinations):
             results.append(args)


More information about the pypy-commit mailing list