Author: Richard Plangger <planri...@gmail.com>
Branch: s390x-backend
Changeset: r80655:7e4f29d5c048
Date: 2015-11-13 10:18 +0100
http://bitbucket.org/pypy/pypy/changeset/7e4f29d5c048/

Log:    completed implementation for int_is_true, int_is_zero. added
        flush_cc method and fixed the LARL problem (test suite provided
        wrong number to gnu asm)

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
@@ -357,6 +357,26 @@
             targettoken._ll_loop_code += rawstart
         self.target_tokens_currently_compiling = None
 
+    def flush_cc(self, condition, result_loc):
+        # After emitting an instruction that leaves a boolean result in
+        # a condition code (cc), call this.  In the common case, result_loc
+        # will be set to 'fp' by the regalloc, which in this case means
+        # "propagate it between this operation and the next guard by keeping
+        # it in the cc".  In the uncommon case, result_loc is another
+        # register, and we emit a load from the cc into this register.
+        assert self.guard_success_cc == c.cond_none
+        if result_loc is r.SPP:
+            self.guard_success_cc = condition
+        else:
+            # sadly we cannot use LOCGHI
+            # it is included in some extension that seem to be NOT installed
+            # by default.
+            self.mc.LGHI(r.SCRATCH, l.imm(1))
+            self.mc.LOCGR(result_loc, r.SCRATCH, condition)
+            self.mc.LGHI(r.SCRATCH, l.imm(0))
+            self.mc.LOCGR(result_loc, r.SCRATCH, c.negate(condition))
+
+
     def _assemble(self, regalloc, inputargs, operations):
         self._regalloc = regalloc
         self.guard_success_cc = c.cond_none
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
@@ -133,13 +133,13 @@
 
 def build_rre(mnemonic, (opcode1,opcode2), argtypes='r,r'):
     @builder.arguments(argtypes)
-    def encode_rr(self, reg1, reg2):
+    def encode_rre(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
+    return encode_rre
 
 def build_rx(mnemonic, (opcode,)):
     @builder.arguments('r/m,bid')
@@ -277,14 +277,24 @@
         encode_base_displace(self, base_displace)
     return encode_rs
 
-def build_rsy(mnemonic, (opcode1,opcode2)):
+@always_inline
+def _encode_rsy(self, opcode1, opcode2, 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)
+
+def build_rsy_a(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 encode_rsy(self, reg1, reg3, base_displace):
+        _encode_rsy(self, opcode1, opcode2, reg1, reg3, base_displace)
+    return encode_rsy
+
+def build_rsy_b(mnemonic, (opcode1,opcode2)):
+    @builder.arguments('r,bdl,r')
+    def encode_rsy(self, reg1, base_displace, reg3):
+        _encode_rsy(self, opcode1, opcode2, reg1, reg3, base_displace)
+    return encode_rsy
 
 def build_rsi(mnemonic, (opcode,)):
     br = is_branch_relative(mnemonic)
@@ -298,10 +308,10 @@
         self.write_i16(imm16 & BIT_MASK_16)
     return encode_ri
 
-def build_rie(mnemonic, (opcode1,opcode2)):
+def build_rie_e(mnemonic, (opcode1,opcode2)):
     br = is_branch_relative(mnemonic)
     @builder.arguments('r,r,i16')
-    def encode_ri(self, reg1, reg2, imm16):
+    def encode_rie_e(self, reg1, reg2, imm16):
         self.writechar(opcode1)
         byte = (reg1 & BIT_MASK_4) << 4 | (reg2 & BIT_MASK_4)
         self.writechar(chr(byte))
@@ -310,18 +320,45 @@
         self.write_i16(imm16 & BIT_MASK_16)
         self.writechar(chr(0x0))
         self.writechar(opcode2)
-    return encode_ri
+    return encode_rie_e
 
-def build_rrf(mnemonic, (opcode1,opcode2), argtypes):
+def build_rie_a(mnemonic, (opcode1,opcode2)):
+    br = is_branch_relative(mnemonic)
+    @builder.arguments('r,i16,r/m')
+    def encode_rie_a(self, reg1, imm16, mask):
+        self.writechar(opcode1)
+        byte = (reg1 & BIT_MASK_4) << 4 | (mask & 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_rie_a
+
+build_rie_g = build_rie_a
+
+@always_inline
+def _encode_rrf(self, opcode1, opcode2, r1, r2, rm3, rm4):
+    self.writechar(opcode1)
+    self.writechar(opcode2)
+    byte = (rm3 & BIT_MASK_4) << 4 | (rm4 & BIT_MASK_4)
+    self.writechar(chr(byte))
+    byte = (r1 & BIT_MASK_4) << 4 | (r2 & BIT_MASK_4)
+    self.writechar(chr(byte))
+
+def build_rrf_c(mnemonic, (opcode1,opcode2), argtypes='r,r,r/m,-'):
     @builder.arguments(argtypes)
-    def encode_rrf(self, r1, rm3, r2, rm4):
-        self.writechar(opcode1)
-        self.writechar(opcode2)
-        byte = (rm3 & BIT_MASK_4) << 4 | (rm4 & BIT_MASK_4)
-        self.writechar(chr(byte))
-        byte = (r1 & BIT_MASK_4) << 4 | (r2 & BIT_MASK_4)
-        self.writechar(chr(byte))
-    return encode_rrf
+    def encode_rrf_b(self, r1, r2, rm3, rm4):
+        _encode_rrf(self, opcode1, opcode2, r1, r2, rm3, rm4)
+    return encode_rrf_b
+
+def build_rrf_e(mnemonic, (opcode1,opcode2), argtypes):
+    @builder.arguments(argtypes)
+    def encode_rrf_e(self, r1, rm3, r2, rm4):
+        _encode_rrf(self, opcode1, opcode2, r1, r2, rm3, rm4)
+    return encode_rrf_e
+build_rrf_b = build_rrf_e
 
 def build_rxe(mnemonic, (opcode1,opcode2), argtypes):
     @builder.arguments(argtypes)
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
@@ -27,15 +27,15 @@
     # div/mod
     'DSGR':    ('rre',   ['\xB9','\x0D'], 'eo,r'),
     'DSG':     ('rxy',   ['\xE3','\x0D'], 'eo,bidl'),
-    'DLGR':    ('rre',   ['\xB9','\x97'], 'eo,r'),
+    'DLGR':    ('rre',   ['\xB9','\x87'], 'eo,r'),
     'DLG':     ('rxy',   ['\xE3','\x87'], 'eo,bidl'),
     # there is no immidiate divide
 
     # shifting
-    'SRAG':    ('rsy',   ['\xEB','\x0A']),
-    'SLAG':    ('rsy',   ['\xEB','\x0B']),
-    'SRLG':    ('rsy',   ['\xEB','\x0C']),
-    'SLLG':    ('rsy',   ['\xEB','\x0D']),
+    'SRAG':    ('rsy_a',   ['\xEB','\x0A']),
+    'SLAG':    ('rsy_a',   ['\xEB','\x0B']),
+    'SRLG':    ('rsy_a',   ['\xEB','\x0C']),
+    'SLLG':    ('rsy_a',   ['\xEB','\x0D']),
 
     # invert & negative & absolute
     'LPGR':    ('rre',   ['\xB9','\x00']),
@@ -59,7 +59,7 @@
     'CLGR':    ('rre',    ['\xB9','\x21']),
     'CLG':     ('rxy',    ['\xE3','\x21']),
     'CGHI':    ('ri',     ['\xA7','\x0F']),
-    'CGFI':    ('ril',    ['\xC2','\x0E']),
+    'CGFI':    ('ril',    ['\xC2','\x0C']),
 }
 
 logic_mnemonic_codes = {
@@ -111,7 +111,7 @@
 
     # load memory
     'LMD':     ('sse',   ['\xEF']),
-    'LMG':     ('rsy',   ['\xEB','\x04']),
+    'LMG':     ('rsy_a',   ['\xEB','\x04']),
     'LHI':     ('ri',    ['\xA7','\x08']),
     'LGHI':    ('ri',    ['\xA7','\x09']),
     'LR':      ('rr',    ['\x18']),
@@ -119,8 +119,12 @@
     'LG':      ('rxy',   ['\xE3','\x04']),
     'LARL':    ('ril',   ['\xC0','\x00'], 'r/m,h32'),
 
+    # load on condition
+    'LOCGR':  ('rrf_c',    ['\xB9','\xE2']),
+    'LOCG':   ('rsy_b',    ['\xEB','\xE2']),
+
     # store memory
-    'STMG':    ('rsy',   ['\xEB','\x24']),
+    'STMG':    ('rsy_a',   ['\xEB','\x24']),
     'ST':      ('rx',    ['\x50']),
     'STG':     ('rxy',   ['\xE3','\x24']),
     'STY':     ('rxy',   ['\xE3','\x50']),
@@ -155,12 +159,12 @@
 }
 
 floatingpoint_mnemonic_codes = {
-    'FIEBR':   ('rrf',   ['\xB3','\x57'], 'r,u4,r,-'),
-    'FIDBR':   ('rrf',   ['\xB3','\x5F'], 'r,u4,r,-'),
+    'FIEBR':   ('rrf_e',   ['\xB3','\x57'], 'r,u4,r,-'),
+    'FIDBR':   ('rrf_e',   ['\xB3','\x5F'], 'r,u4,r,-'),
 
     # convert to fixed
-    'CGEBR':   ('rrf',   ['\xB3','\xA8'], 'r,u4,r,-'),
-    'CGDBR':   ('rrf',   ['\xB3','\xA9'], 'r,u4,r,-'),
+    'CGEBR':   ('rrf_e',   ['\xB3','\xA8'], 'r,u4,r,-'),
+    'CGDBR':   ('rrf_e',   ['\xB3','\xA9'], 'r,u4,r,-'),
 
     # convert from fixed
     'CEGBR':   ('rre',   ['\xB3','\xA4']),
@@ -190,8 +194,8 @@
     'DDB':     ('rxe',   ['\xED','\x1D'], 'r,bidl,-'),
     
     # DIVIDE (+mod)
-    'DIEBR':     ('rrf',   ['\xB3','\x53'], 'r,r,r,m'),
-    'DIDBR':     ('rrf',   ['\xB3','\x5B'], 'r,r,r,m'),
+    'DIEBR':     ('rrf_b',   ['\xB3','\x53'], 'r,r,r,m'),
+    'DIDBR':     ('rrf_b',   ['\xB3','\x5B'], 'r,r,r,m'),
 
     # COMPARISON
     'CEBR':    ('rre',   ['\xB3','\x09']),
@@ -204,9 +208,9 @@
 all_mnemonic_codes = {
     #
     'BXH':     ('rs',    ['\x86']),
-    'BXHG':    ('rsy',   ['\xEB','\x44']),
+    'BXHG':    ('rsy_a',   ['\xEB','\x44']),
     'BRXH':    ('rsi',   ['\x84']),
-    'BRXLG':   ('rie',   ['\xEC','\x45']),
+    'BRXLG':   ('rie_e',   ['\xEC','\x45']),
     #
     'NI':      ('si',    ['\x94']),
     'NIY':     ('siy',   ['\xEB','\x54']),
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
@@ -6,21 +6,6 @@
 import rpython.jit.backend.zarch.locations as l
 from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
 
-def flush_cc(asm, condition, result_loc):
-    # After emitting an instruction that leaves a boolean result in
-    # a condition code (cc), call this.  In the common case, result_loc
-    # will be set to 'fp' by the regalloc, which in this case means
-    # "propagate it between this operation and the next guard by keeping
-    # it in the cc".  In the uncommon case, result_loc is another
-    # register, and we emit a load from the cc into this register.
-    assert asm.guard_success_cc == c.cond_none
-    if result_loc is r.SPP:
-        asm.guard_success_cc = condition
-    else:
-        xxx
-        #asm.mc.MOV_ri(result_loc.value, 1, condition)
-        #asm.mc.MOV_ri(result_loc.value, 0, c.get_opposite_of(condition))
-
 class IntOpAssembler(object):
     _mixin_ = True
 
@@ -101,12 +86,12 @@
     def emit_int_is_zero(self, op, arglocs, regalloc):
         l0 = arglocs[0]
         self.mc.CGHI(l0, l.imm(0))
-        flush_cc(self, l0, c.EQ)
+        self.flush_cc(c.EQ, l0)
 
     def emit_int_is_true(self, op, arglocs, regalloc):
         l0 = arglocs[0]
         self.mc.CGHI(l0, l.imm(0))
-        flush_cc(self, l0, c.NE)
+        self.flush_cc(c.NE, l0)
 
 
     emit_int_and = gen_emit_rr_or_rpool("NGR", "NG")
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
@@ -115,7 +115,7 @@
 def range_of_halfword_bits(bits, signed=True, count=24):
     elems = range_of_bits(bits, signed, count)
     for i,e in enumerate(elems):
-        elems[i] = (e // 2) >> 1
+        elems[i] = e >> 1
     return elems
 
 def build_fake(clazz, *arg_bits):
@@ -177,6 +177,7 @@
             'eo': (lambda num: REGNAMES[num]),
             'r/m': (lambda num: REGNAMES[num]),
             'f': (lambda num: FP_REGNAMES[num]),
+            'h32': (lambda num: str(num << 1)),
         }
         arg_types = self.get_func_arg_types(methodname)
         for mode, args in zip(arg_types, arguments):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to