[pypy-commit] pypy s390x-backend: added regalloc/assembler for int_neg, int_invert

plan_rich noreply at buildbot.pypy.org
Thu Nov 12 13:54:23 EST 2015


Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r80650:54d56775dc1e
Date: 2015-11-12 19:54 +0100
http://bitbucket.org/pypy/pypy/changeset/54d56775dc1e/

Log:	added regalloc/assembler for int_neg, int_invert

diff --git a/rpython/jit/backend/zarch/helper/regalloc.py b/rpython/jit/backend/zarch/helper/regalloc.py
--- a/rpython/jit/backend/zarch/helper/regalloc.py
+++ b/rpython/jit/backend/zarch/helper/regalloc.py
@@ -118,9 +118,9 @@
     self.free_op_vars()
     return [l0, l1]
 
-def prepare_unary(self, op):
+def prepare_unary_op(self, op):
     a0 = op.getarg(0)
-    assert not a0.is_imm()
+    assert not isinstance(a0, ConstInt)
     l0 = self.ensure_reg(a0)
     self.force_result_in_reg(op, a0)
     self.free_op_vars()
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
@@ -40,6 +40,7 @@
     # invert & negative & absolute
     'LPGR':    ('rre',   ['\xB9','\x00']),
     'LNGR':    ('rre',   ['\xB9','\x01']),
+    'LCGR':    ('rre',   ['\xB9','\x03']),
 
 
 
@@ -58,6 +59,7 @@
     'CLGR':    ('rre',    ['\xB9','\x21']),
     'CLG':     ('rxy',    ['\xE3','\x21']),
     'CGHI':    ('ri',     ['\xA7','\x0F']),
+    'CGFI':    ('ril',    ['\xC2','\x0E']),
 }
 
 logic_mnemonic_codes = {
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
@@ -3,8 +3,24 @@
 from rpython.jit.backend.zarch.codebuilder import ZARCHGuardToken
 import rpython.jit.backend.zarch.conditions as c
 import rpython.jit.backend.zarch.registers as r
+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
 
@@ -73,6 +89,26 @@
         else:
             self.mc.SGR(l0, l1)
 
+    def emit_int_invert(self, op, arglocs, regalloc):
+        l0 = arglocs[0]
+        assert not l0.is_imm()
+        self.mc.XG(l0, l.pool(self.pool.constant_64_ones))
+
+    def emit_int_neg(self, op, arglocs, regalloc):
+        l0 = arglocs[0]
+        self.mc.LNGR(l0, l0)
+
+    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)
+
+    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)
+
+
     emit_int_and = gen_emit_rr_or_rpool("NGR", "NG")
     emit_int_or  = gen_emit_rr_or_rpool("OGR", "OG")
     emit_int_xor = gen_emit_rr_or_rpool("XGR", "XG")
diff --git a/rpython/jit/backend/zarch/pool.py b/rpython/jit/backend/zarch/pool.py
--- a/rpython/jit/backend/zarch/pool.py
+++ b/rpython/jit/backend/zarch/pool.py
@@ -15,6 +15,8 @@
         self.label_offset = 0
         self.label_count = 0
         self.offset_map = {}
+        self.constant_64_zeros = -1
+        self.constant_64_ones = -1
 
     def ensure_can_hold_constants(self, asm, op):
         if op.is_guard():
@@ -34,6 +36,8 @@
             if descr not in asm.target_tokens_currently_compiling:
                 # this is a 'long' jump instead of a relative jump
                 self.offset_map[descr] = self.size
+        elif op.getopnum() == rop.INT_INVERT:
+            self.constant_64_ones = 1 # we need constant ones!!!
         for arg in op.getarglist():
             if arg.is_constant():
                 self.offset_map[arg] = self.size
@@ -71,13 +75,23 @@
         self.pool_start = asm.mc.get_relative_pos()
         for op in operations:
             self.ensure_can_hold_constants(asm, op)
-        if self.size == 0:
+        if self.size == 0 and written != 0:
             # no pool needed!
             return
         assert self.size % 2 == 0
         #if self.size % 2 == 1:
         #    self.size += 1
         asm.mc.write('\xFF' * self.size)
+        written = 0
+        if self.constant_64_ones:
+            asm.mc.write('\xFF' * 8)
+            self.constant_64_ones = self.size
+            written += 8
+        if self.constant_64_zeros:
+            asm.mc.write('\x00' * 8)
+            self.constant_64_zeros = self.size
+            written += 8
+        self.size += written
         print "pool with %d quad words" % (self.size // 8)
 
     def overwrite_64(self, mc, index, value):
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
@@ -42,6 +42,16 @@
           (-1,'i1 = int_lshift(i0, 1)', -2),
           (-2**35,'i1 = int_lshift(i0, 1)', (-2**35)*2),
           (2**64-1,'i1 = uint_rshift(i0, 2)', (2**64-1)//4),
+          (-1,'i1 = int_neg(i0)', -1),
+          (1,'i1 = int_neg(i0)', -1),
+          (2**63-1,'i1 = int_neg(i0)', -(2**63-1)),
+          (1,'i1 = int_invert(i0)', ~1),
+          (15,'i1 = int_invert(i0)', ~15),
+          (-1,'i1 = int_invert(i0)', ~(-1)),
+          (0,'i1 = int_is_zero(i0)', 1),
+          (50,'i1 = int_is_zero(i0)', 0),
+          (-1,'i1 = int_is_true(i0)', 1),
+          (0,'i1 = int_is_true(i0)', 0),
         ])
     def test_int_arithmetic_and_logic(self, value, opcode, result):
         loop = parse("""


More information about the pypy-commit mailing list