[pypy-commit] pypy s390x-backend: mul overflow implemented (thx arigato), added test cases stressing the border of overflow 64 bit overflow

plan_rich noreply at buildbot.pypy.org
Tue Nov 17 02:55:51 EST 2015


Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r80721:889bc2492655
Date: 2015-11-17 08:56 +0100
http://bitbucket.org/pypy/pypy/changeset/889bc2492655/

Log:	mul overflow implemented (thx arigato), added test cases stressing
	the border of overflow 64 bit overflow

diff --git a/rpython/jit/backend/zarch/conditions.py b/rpython/jit/backend/zarch/conditions.py
--- a/rpython/jit/backend/zarch/conditions.py
+++ b/rpython/jit/backend/zarch/conditions.py
@@ -1,13 +1,6 @@
 from rpython.jit.backend.zarch import locations as loc
 from rpython.rlib.objectmodel import specialize
 
-# CGIJ for instance has another mask encoding prefixed with J
-J_EQ = loc.imm(0x1)
-J_LT = loc.imm(0x2)
-J_LE = loc.imm(0x2 | 0x1)
-J_GT = loc.imm(0x4)
-J_GE = loc.imm(0x4 | 0x1)
-
 # normal branch instructions
 EQ = loc.imm(0x8)
 LT = loc.imm(0x4)
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
@@ -338,9 +338,9 @@
 
 build_rie_g = build_rie_a
 
-def build_rie_c(mnemonic, (opcode1,opcode2)):
+def build_rie_c(mnemonic, (opcode1,opcode2), argtypes='r,i8,r/m,i16'):
     br = is_branch_relative(mnemonic)
-    @builder.arguments('r,i8,r/m,i16')
+    @builder.arguments(argtypes)
     def encode_rie_c(self, reg1, imm8, mask, imm16):
         self.writechar(opcode1)
         byte = (reg1 & BIT_MASK_4) << 4 | (mask & BIT_MASK_4)
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
@@ -61,7 +61,8 @@
     'CLG':     ('rxy',    ['\xE3','\x21']),
     'CGHI':    ('ri',     ['\xA7','\x0F']),
     'CGFI':    ('ril',    ['\xC2','\x0C']),
-    'CGIJ':    ('rie_c',  ['\xEC','\x7E']),
+    'CGIJ':    ('rie_c',  ['\xEC','\x7C']),
+    'CLGIJ':   ('rie_c',  ['\xEC','\x7D'], 'r,u8,r/m,i16'),
 }
 
 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
@@ -18,45 +18,47 @@
     def emit_int_mul_ovf(self, op, arglocs, regalloc):
         lr, lq, l1 = arglocs
         if l1.is_in_pool():
-            self.mc.LTGR(r.SCRATCH, l1)
+            self.mc.LG(r.SCRATCH, l1)
             l1 = r.SCRATCH
         elif l1.is_imm():
             self.mc.LGFI(r.SCRATCH, l1)
             l1 = r.SCRATCH
 
         mc = self.mc
-        bc_one_signed = mc.CGIJ_byte_count + \
-                         mc.LPGR_byte_count * 2 + \
-                         mc.MLGR_byte_count + \
-                         mc.XG_byte_count + \
-                         mc.CGIJ_byte_count * 2 + \
-                         mc.BRC_byte_count
-        bc_none_signed = mc.MLGR_byte_count + mc.CGIJ_byte_count * 2 + mc.BRC_byte_count
+        bc_one_signed = mc.LPGR_byte_count * 2 + \
+                        mc.MLGR_byte_count + \
+                        mc.XG_byte_count + \
+                        mc.CLGIJ_byte_count * 2 + \
+                        mc.BRC_byte_count
+        bc_none_signed = mc.MLGR_byte_count + mc.CGIJ_byte_count * 2 + mc.BRC_byte_count + mc.LPGR_byte_count * 2
         bc_set_overflow = mc.IPM_byte_count + mc.OIHL_byte_count + mc.SPM_byte_count
 
         # check left neg
-        mc.CGIJ(lq, l.imm(0), c.J_LT, l.imm(mc.CGIJ_byte_count*2))
-        mc.CGIJ(l1, l.imm(0), c.J_GE, l.imm(bc_one_signed))
+        mc.CGIJ(lq, l.imm(0), c.LT, l.imm(mc.CGIJ_byte_count*2))
+        mc.CGIJ(l1, l.imm(0), c.GE, l.imm(mc.CGIJ_byte_count*2 + bc_one_signed))
+        mc.CGIJ(l1, l.imm(0), c.LT, l.imm(mc.CGIJ_byte_count + bc_one_signed)) # jump if both are negative
         # left or right is negative
         mc.LPGR(lq, lq)
         mc.LPGR(l1, l1)
         mc.MLGR(lr, l1)
-        off = mc.CGIJ_byte_count * 2 + mc.XG_byte_count + mc.BRC_byte_count + bc_none_signed
-        mc.CGIJ(lr, l.imm(0), c.J_LT, l.imm(off)) # jump to overflow
-        mc.CGIJ(lq, l.imm(0), c.J_LT, l.imm(off - mc.CGIJ_byte_count)) # jump to over overflow
-        mc.XG(lq, l.pool(self.pool.constant_64_sign_bit))
+        off = mc.CLGIJ_byte_count * 2 + mc.XG_byte_count + mc.BRC_byte_count + bc_none_signed
+        mc.CLGIJ(lr, l.imm(0), c.GT, l.imm(off)) # jump to overflow
+        mc.CGIJ(lq, l.imm(0), c.LT, l.imm(off - mc.CGIJ_byte_count)) # jump to over overflow
+        mc.XG(lq, l.pool(self.pool.constant_64_sign_bit)) # only one is negative, set the sign bit!
         mc.BRC(c.ANY, l.imm(mc.BRC_byte_count + bc_set_overflow + bc_none_signed)) # no overflow happened
 
         # both are positive
+        mc.LPGR(lq, lq)
+        mc.LPGR(l1, l1)
         mc.MLGR(lr, l1)
         mc.CGIJ(lq, l.imm(0), c.LT, l.imm(mc.CGIJ_byte_count * 2 + mc.BRC_byte_count)) # jump to over overflow
-        mc.CGIJ(lr, l.imm(0), c.GT, l.imm(mc.CGIJ_byte_count + mc.BRC_byte_count)) # jump to overflow
+        mc.CLGIJ(lr, l.imm(0), c.GT, l.imm(mc.CGIJ_byte_count + mc.BRC_byte_count)) # jump to overflow
         mc.BRC(c.ANY, l.imm(mc.BRC_byte_count + bc_set_overflow)) # no overflow happened
 
         # set overflow!
+        mc.XGR(r.SCRATCH, r.SCRATCH)
         mc.IPM(r.SCRATCH)
-        mc.XGR(r.SCRATCH, r.SCRATCH)
-        mc.OILH(r.SCRATCH, l.imm(0xf000)) # sets OF
+        mc.OILH(r.SCRATCH, l.imm(0x3000)) # sets OF
         mc.SPM(r.SCRATCH)
 
         # no overflow happended
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
@@ -79,11 +79,20 @@
           (-2**63,  'i1 = int_sub_ovf(i0, 1)',0,'guard_overflow'),
 
           (-2**63,  'i1 = int_mul_ovf(i0, 2)',1,'guard_no_overflow'),
-          #(-2**15,  'i1 = int_mul_ovf(i0, 2)',0,'guard_no_overflow'),
-          #(-2**63,  'i1 = int_mul_ovf(i0, 0)',0,'guard_no_overflow'),
-          #(-2**15,  'i1 = int_mul_ovf(i0, 2)',1,'guard_overflow'),
-          #(-2**63,  'i1 = int_mul_ovf(i0, 2)',0,'guard_overflow'),
-          #(-2**63,  'i1 = int_mul_ovf(i0, 0)',1,'guard_overflow'),
+          (-2**63,  'i1 = int_mul_ovf(i0, -2)',1,'guard_no_overflow'),
+          (-2**15,  'i1 = int_mul_ovf(i0, 2)',0,'guard_no_overflow'),
+          (-2**63,  'i1 = int_mul_ovf(i0, 0)',0,'guard_no_overflow'),
+          (-2**63,  'i1 = int_mul_ovf(i0, 2)',0,'guard_overflow'),
+          (-2**63,  'i1 = int_mul_ovf(i0, -2)',0,'guard_overflow'),
+          (-2**63,  'i1 = int_mul_ovf(i0, 0)',1,'guard_overflow'),
+          # positive!
+          (2**63-1,  'i1 = int_mul_ovf(i0, 33)',1,'guard_no_overflow'),
+          (2**63-1,  'i1 = int_mul_ovf(i0, -2)',1,'guard_no_overflow'),
+          (2**15,  'i1 = int_mul_ovf(i0, 2)',0,'guard_no_overflow'),
+          (2**63-1,  'i1 = int_mul_ovf(i0, 0)',0,'guard_no_overflow'),
+          (2**63-1,  'i1 = int_mul_ovf(i0, 99)',0,'guard_overflow'),
+          (2**63-1,  'i1 = int_mul_ovf(i0, 3323881828381)',0,'guard_overflow'),
+          (2**63-1,  'i1 = int_mul_ovf(i0, 0)',1,'guard_overflow'),
         ])
     def test_int_arithmetic_overflow(self, value, opcode, result, guard):
         # result == 1 means branch has been taken of the guard
@@ -97,6 +106,7 @@
         loop = parse(code, namespace={"faildescr": BasicFinalDescr(1)})
         looptoken = JitCellToken()
         self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+        #import pdb; pdb.set_trace()
         deadframe = self.cpu.execute_token(looptoken, value)
         fail = self.cpu.get_latest_descr(deadframe)
         res = self.cpu.get_int_value(deadframe, 0)


More information about the pypy-commit mailing list