Author: Richard Plangger <planri...@gmail.com>
Branch: s390x-backend
Changeset: r80732:173b585af649
Date: 2015-11-17 20:00 +0100
http://bitbucket.org/pypy/pypy/changeset/173b585af649/

Log:    ironed out the bug in mul overflow, test runner is now passing two
        ovf tests!

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
@@ -643,17 +643,21 @@
             gcmap = self._finish_gcmap
         else:
             gcmap = lltype.nullptr(jitframe.GCMAP)
-        #self.pool.load_gcmap(self.mc, r.r2, gcmap)
+        self.load_gcmap(self.mc, r.r2, gcmap)
 
-        assert fail_descr_loc.getint() <= 2**12-1
-        self.mc.LGHI(r.r5, fail_descr_loc)
-        self.mc.STG(r.r5, l.addr(ofs, r.SPP))
-        self.mc.XGR(r.r2, r.r2) # TODO
+        assert fail_descr_loc.getint() <= 2**32-1
+        self.mc.LGFI(r.r3, fail_descr_loc)
+        self.mc.STG(r.r3, l.addr(ofs, r.SPP))
         self.mc.STG(r.r2, l.addr(ofs2, r.SPP))
 
         # exit function
         self._call_footer()
 
+    def load_gcmap(self, mc, reg, gcmap):
+        # load the current gcmap into register 'reg'
+        ptr = rffi.cast(lltype.Signed, gcmap)
+        mc.load_imm(reg, ptr)
+
 def notimplemented_op(asm, op, arglocs, regalloc):
     print "[ZARCH/asm] %s not implemented" % op.getopname()
     raise NotImplementedError(op)
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
@@ -146,6 +146,14 @@
                     self.CGR(a, b)
 
 
+    def load_imm(self, dest_reg, word):
+        if word <= 32767 and word >= -32768:
+            self.LGHI(dest_reg, l.imm(word))
+        elif word <= 2**31-1 and word >= -2**31:
+            self.LGFI(dest_reg, l.imm(word))
+        else:
+            xxx
+
 _classes = (AbstractZARCHBuilder,)
 
 # Used to build the MachineCodeBlockWrapper
diff --git a/rpython/jit/backend/zarch/helper/assembler.py 
b/rpython/jit/backend/zarch/helper/assembler.py
--- a/rpython/jit/backend/zarch/helper/assembler.py
+++ b/rpython/jit/backend/zarch/helper/assembler.py
@@ -71,8 +71,6 @@
 def gen_emit_shift(func):
     def f(self, op, arglocs, regalloc):
         l0, l1 = arglocs
-        if not l1.is_imm() or l1.is_in_pool():
-            assert 0, "shift imm must NOT reside in pool!"
         getattr(self.mc, func)(l0, l0, l1)
     return f
 
@@ -111,7 +109,7 @@
         assert lr.is_even()
         assert lq.is_odd()
         if l1.is_in_pool():
-            self.mc.DSG(lr, l1)
+            getattr(self.mc,pool_func)(lr, l1)
         else:
-            self.mc.DSGR(lr, l1)
+            getattr(self.mc,rr_func)(lr, l1)
     return emit
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
@@ -100,7 +100,6 @@
     a0 = op.getarg(0)
     a1 = op.getarg(1)
     assert isinstance(a1, ConstInt)
-    l1 = self.ensure_reg(a1)
     assert check_imm20(a1)
     l0 = self.ensure_reg(a0)
     # note that the shift value is stored
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,6 +338,21 @@
 
 build_rie_g = build_rie_a
 
+def build_rie_b(mnemonic, (opcode1,opcode2)):
+    br = is_branch_relative(mnemonic)
+    @builder.arguments('r,r,r/m,i16')
+    def encode_rie_b(self, reg1, reg2, mask, 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)
+        byte = (mask & BIT_MASK_4) << 4
+        self.writechar(chr(byte))
+        self.writechar(opcode2)
+    return encode_rie_b
+
 def build_rie_c(mnemonic, (opcode1,opcode2), argtypes='r,i8,r/m,i16'):
     br = is_branch_relative(mnemonic)
     @builder.arguments(argtypes)
@@ -395,6 +410,19 @@
         self.writechar(opcode2)
     return encode_rxe
 
+def build_ris(mnemonic, (opcode1,opcode2), argtypes='r,i8,r/m,bd'):
+    br = is_branch_relative(mnemonic)
+    @builder.arguments(argtypes)
+    def encode_rie_c(self, reg1, imm8, mask, basedisp):
+        self.writechar(opcode1)
+        byte = (reg1 & BIT_MASK_4) << 4 | (mask & BIT_MASK_4)
+        self.writechar(chr(byte))
+        #
+        encode_base_displace(self, basedisp)
+        self.writechar(chr(imm8 & 0xff))
+        self.writechar(opcode2)
+    return encode_rie_c
+
 def build_unpack_func(mnemonic, func):
     def function(self, *args):
         newargs = [None] * len(func._arguments_)
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
@@ -43,8 +43,6 @@
     'LNGR':    ('rre',   ['\xB9','\x01']),
     'LCGR':    ('rre',   ['\xB9','\x03']),
 
-
-
     # div
 
     'AY':      ('rxy',   ['\xE3','\x5A']),
@@ -63,6 +61,9 @@
     'CGFI':    ('ril',    ['\xC2','\x0C']),
     'CGIJ':    ('rie_c',  ['\xEC','\x7C']),
     'CLGIJ':   ('rie_c',  ['\xEC','\x7D'], 'r,u8,r/m,i16'),
+    'CGIB':    ('ris',    ['\xEC','\xFC']),
+    'CGRJ':    ('rie_b',  ['\xEC','\x64']),
+    'CLGRJ':   ('rie_b',  ['\xEC','\x65']),
 }
 
 logic_mnemonic_codes = {
diff --git a/rpython/jit/backend/zarch/locations.py 
b/rpython/jit/backend/zarch/locations.py
--- a/rpython/jit/backend/zarch/locations.py
+++ b/rpython/jit/backend/zarch/locations.py
@@ -204,10 +204,10 @@
         return True
 
     def is_imm(self):
-        return True
+        return False
 
     def is_imm_float(self):
-        return self.isfloat
+        return False
 
     def is_float(self):
         return self.isfloat
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
@@ -25,13 +25,22 @@
             l1 = r.SCRATCH
 
         mc = self.mc
+        bc_one_decision = mc.CLGRJ_byte_count +\
+                          mc.CLGIJ_byte_count + \
+                          mc.LCGR_byte_count + \
+                          mc.BRC_byte_count + \
+                          mc.SPM_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
+                        mc.LG_byte_count + \
+                        bc_one_decision
+        bc_none_signed = mc.LPGR_byte_count * 2 + \
+                         mc.MLGR_byte_count + \
+                         mc.LG_byte_count + \
+                         mc.CLGRJ_byte_count + \
+                         mc.CLGIJ_byte_count + \
+                         mc.BRC_byte_count
+        bc_set_overflow = mc.OIHL_byte_count + mc.SPM_byte_count
 
         # check left neg
         mc.CGIJ(lq, l.imm(0), c.LT, l.imm(mc.CGIJ_byte_count*2))
@@ -41,22 +50,27 @@
         mc.LPGR(lq, lq)
         mc.LPGR(l1, l1)
         mc.MLGR(lr, l1)
-        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.LG(r.SCRATCH, l.pool(self.pool.constant_max_64_positive))
+        # is the value greater than 2**63 ? then an overflow occured
+        mc.CLGRJ(lq, r.SCRATCH, c.GT, l.imm(bc_one_decision + bc_none_signed)) 
# jump to over overflow
+        mc.CLGIJ(lr, l.imm(0), c.GT, l.imm(bc_one_decision - 
mc.CLGRJ_byte_count + bc_none_signed)) # jump to overflow
+        mc.LCGR(lq, lq)
+        mc.SPM(r.SCRATCH) # 0x80 ... 00 clears the condition code and program 
mask
         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.CLGIJ(lr, l.imm(0), c.GT, l.imm(mc.CGIJ_byte_count + 
mc.BRC_byte_count)) # jump to overflow
+        off = mc.CLGRJ_byte_count + mc.CLGIJ_byte_count + \
+              mc.BRC_byte_count
+        mc.LG(r.SCRATCH, l.pool(self.pool.constant_64_ones))
+        mc.CLGRJ(lq, r.SCRATCH, c.GT, l.imm(off)) # jump to over overflow
+        mc.CLGIJ(lr, l.imm(0), c.GT, l.imm(off - mc.CLGRJ_byte_count)) # jump 
to overflow
         mc.BRC(c.ANY, l.imm(mc.BRC_byte_count + bc_set_overflow)) # no 
overflow happened
 
         # set overflow!
-        mc.IPM(r.SCRATCH)
+        #mc.IPM(r.SCRATCH)
         # set bit 34 & 35 -> indicates overflow
         mc.OILH(r.SCRATCH, l.imm(0x3000)) # sets OF
         mc.SPM(r.SCRATCH)
@@ -67,7 +81,27 @@
     emit_uint_floordiv = gen_emit_pool_or_rr_evenodd('DLG','DLGR')
     # NOTE division sets one register with the modulo value, thus
     # the regalloc ensures the right register survives.
-    emit_int_mod = gen_emit_pool_or_rr_evenodd('DSG','DSGR')
+    #emit_int_mod = gen_emit_pool_or_rr_evenodd('DSG','DSGR')
+    def emit_int_mod(self, op, arglocs, regalloc):
+        lr, lq, l1 = arglocs # lr == remainer, lq == quotient
+        # when entering the function lr contains the dividend
+        # after this operation either lr or lq is used further
+        assert l1.is_in_pool() or not l1.is_imm() , "imm divider not supported"
+        # remainer is always a even register r0, r2, ... , r14
+        assert lr.is_even()
+        assert lq.is_odd()
+        if l1.is_in_pool():
+            self.mc.DSG(lr, l1)
+            # python behavior?
+            #off = self.mc.CGIJ_byte_count+self.mc.AG_byte_count
+            #self.mc.CGIJ(lr, l.imm(0), c.GE, l.imm(off))
+            #self.mc.AG(lr, l1)
+        else:
+            self.mc.DSGR(lr, l1)
+            # python behavior?
+            #off = self.mc.CGIJ_byte_count+self.mc.AGR_byte_count
+            #self.mc.CGIJ(lr, l.imm(0), c.GE, l.imm(off))
+            #self.mc.AGR(lr, l1)
 
     def emit_int_invert(self, op, arglocs, regalloc):
         l0 = arglocs[0]
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
@@ -18,8 +18,10 @@
         self.constant_64_zeros = -1
         self.constant_64_ones = -1
         self.constant_64_sign_bit = -1
+        self.constant_max_64_positive = -1
 
     def ensure_can_hold_constants(self, asm, op):
+        opnum = op.getopnum()
         if op.is_guard():
             # 1x gcmap pointer
             # 1x target address
@@ -41,6 +43,10 @@
             self.constant_64_ones = 1 # we need constant ones!!!
         elif op.getopnum() == rop.INT_MUL_OVF:
             self.constant_64_sign_bit = 1
+            self.constant_max_64_positive = 1
+        elif opnum == rop.INT_RSHIFT or opnum == rop.INT_LSHIFT or \
+             opnum == rop.UINT_RSHIFT:
+            return
         for arg in op.getarglist():
             if arg.is_constant():
                 self.offset_map[arg] = self.size
@@ -58,6 +64,10 @@
         self.label_offset = 0
         self.size = 0
         self.offset_map.clear()
+        self.constant_64_zeros = -1
+        self.constant_64_ones = -1
+        self.constant_64_sign_bit = -1
+        self.constant_max_64_positive -1
 
     def pre_assemble(self, asm, operations, bridge=False):
         self.reset()
@@ -84,20 +94,24 @@
         assert self.size % 2 == 0
         #if self.size % 2 == 1:
         #    self.size += 1
-        asm.mc.write('\xFF' * self.size)
+        asm.mc.write('\x00' * self.size)
         written = 0
-        if self.constant_64_ones:
+        if self.constant_64_ones != -1:
             asm.mc.write('\xFF' * 8)
             self.constant_64_ones = self.size
             written += 8
-        if self.constant_64_zeros:
+        if self.constant_64_zeros != -1:
             asm.mc.write('\x00' * 8)
             self.constant_64_zeros = self.size
             written += 8
-        if self.constant_64_sign_bit:
-            asm.mc.write('\x80' + '\x00' * 7)
+        if self.constant_64_sign_bit != -1:
+            asm.mc.write('\x80' + ('\x00' * 7))
             self.constant_64_sign_bit = self.size
             written += 8
+        if self.constant_max_64_positive != -1:
+            asm.mc.write('\x7F' + ('\xFF' * 7))
+            self.constant_max_64_positive = self.size
+            written += 8
         self.size += written
         print "pool with %d quad words" % (self.size // 8)
 
diff --git a/rpython/jit/backend/zarch/registers.py 
b/rpython/jit/backend/zarch/registers.py
--- a/rpython/jit/backend/zarch/registers.py
+++ b/rpython/jit/backend/zarch/registers.py
@@ -7,7 +7,7 @@
 [r0,r1,r2,r3,r4,r5,r6,r7,r8,
  r9,r10,r11,r12,r13,r14,r15] = registers
 
-MANAGED_REGS = [r0,r1,r4,r5,r6,r7,r8,r9,r10,r12]
+MANAGED_REGS = [r0,r1,r4,r5,r6,r7,r8,r9,r10,r12] # keep this list sorted (asc)!
 VOLATILES = [r6,r7,r8,r9,r10,r12]
 SP = r15
 RETURN = r14
diff --git a/rpython/jit/backend/zarch/test/test_int.py 
b/rpython/jit/backend/zarch/test/test_int.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/zarch/test/test_int.py
@@ -0,0 +1,192 @@
+from rpython.jit.backend.test.runner_test import LLtypeBackendTest
+from rpython.jit.backend.zarch.runner import CPU_S390_64
+from rpython.jit.tool.oparser import parse
+from rpython.jit.metainterp.history import (AbstractFailDescr,
+                                            AbstractDescr,
+                                            BasicFailDescr, BasicFinalDescr,
+                                            JitCellToken, TargetToken,
+                                            ConstInt, ConstPtr,
+                                            Const, ConstFloat)
+from rpython.jit.metainterp.resoperation import InputArgInt, InputArgFloat
+from rpython.rtyper.lltypesystem import lltype
+from rpython.jit.metainterp.resoperation import ResOperation, rop
+import py
+
+class FakeStats(object):
+    pass
+
+class TestIntResOpZARCH(object):
+    cpu = CPU_S390_64(rtyper=None, stats=FakeStats())
+    cpu.setup_once()
+
+    @py.test.mark.parametrize('value,opcode,result',
+        [ (30,'i1 = int_mul(i0, 2)',60),
+          (30,'i1 = int_floordiv(i0, 2)',15),
+          (2**31,'i1 = int_floordiv(i0, 15)',2**31//15),
+          (0,'i1 = int_floordiv(i0, 1)', 0),
+          (1,'i1 = int_floordiv(i0, 1)', 1),
+          (0,'i1 = uint_floordiv(i0, 1)', 0),
+          (1,'i1 = uint_floordiv(i0, 1)', 1),
+          (30,'i1 = int_mod(i0, 2)', 0),
+          (1,'i1 = int_mod(i0, 2)', 1),
+          (1,'i1 = int_lshift(i0, 4)', 16),
+          (1,'i1 = int_lshift(i0, 0)', 1),
+          (4,'i1 = int_rshift(i0, 0)', 4),
+          (4,'i1 = int_rshift(i0, 1)', 2),
+          (-1,'i1 = int_rshift(i0, 0)', -1),
+          (-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("""
+        [i0]
+        {opcode}
+        finish(i1, descr=faildescr)
+        """.format(opcode=opcode),namespace={"faildescr": BasicFinalDescr(1)})
+        looptoken = JitCellToken()
+        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+        deadframe = self.cpu.execute_token(looptoken, value)
+        fail = self.cpu.get_latest_descr(deadframe)
+        res = self.cpu.get_int_value(deadframe, 0)
+        assert res == result
+        assert fail.identifier == 1 
+
+    @py.test.mark.parametrize('value,opcode,result,guard',
+        [ (2**63-1,'i1 = int_add_ovf(i0, 1)',1,'guard_no_overflow'),
+          (2**63-2,'i1 = int_add_ovf(i0, 1)',0,'guard_no_overflow'),
+          (2**63-2,'i1 = int_add_ovf(i0, 1)',1,'guard_overflow'),
+          (2**63-1,'i1 = int_add_ovf(i0, 1)',0,'guard_overflow'),
+
+          (-2**63,  'i1 = int_sub_ovf(i0, 1)',1,'guard_no_overflow'),
+          (-2**63+1,'i1 = int_sub_ovf(i0, 1)',0,'guard_no_overflow'),
+          (-2**63+1,'i1 = int_sub_ovf(i0, 1)',1,'guard_overflow'),
+          (-2**63,  'i1 = int_sub_ovf(i0, 1)',0,'guard_overflow'),
+
+          (-2**63,  'i1 = int_mul_ovf(i0, 2)',1,'guard_no_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
+        code = """
+        [i0]
+        {opcode}
+        {guard}() [i0]
+        i2 = int_xor(i1,i1)
+        finish(i2, descr=faildescr)
+        """.format(opcode=opcode,guard=guard)
+        loop = parse(code, namespace={"faildescr": BasicFinalDescr(1)})
+        looptoken = JitCellToken()
+        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+        deadframe = self.cpu.execute_token(looptoken, value)
+        fail = self.cpu.get_latest_descr(deadframe)
+        res = self.cpu.get_int_value(deadframe, 0)
+        if result == 1:
+            assert res == value
+        else:
+            assert res == 0
+
+    def test_double_evenodd_pair(self):
+        code = """
+        [i0]
+        i1 = int_floordiv(i0, 2)
+        i2 = int_floordiv(i0, 3)
+        i3 = int_floordiv(i0, 4)
+        i4 = int_floordiv(i0, 5)
+        i5 = int_floordiv(i0, 6)
+        i6 = int_floordiv(i0, 7)
+        i7 = int_floordiv(i0, 8)
+        i8 = int_le(i1, 0)
+        guard_true(i8) [i1,i2,i3,i4,i5,i6,i7]
+        finish(i0, descr=faildescr)
+        """
+        # the guard forces 3 spills because after 4 divisions
+        # all even slots of the managed registers are full
+        loop = parse(code, namespace={'faildescr': BasicFinalDescr(1)})
+        looptoken = JitCellToken()
+        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+        deadframe = self.cpu.execute_token(looptoken, 100)
+        fail = self.cpu.get_latest_descr(deadframe)
+        for i in range(2,9):
+            assert self.cpu.get_int_value(deadframe, i-2) == 100//i
+
+
+
+    @py.test.mark.parametrize('value', [2,3,15,2**16])
+    def test_evenodd_pair_extensive(self, value):
+        instrs = []
+        failargs = []
+        values = []
+        j = 0
+        mapping = (('int_floordiv',lambda x,y: x // y),
+                   ('int_mod', lambda x,y: x % y),
+                   ('int_mul_ovf', lambda x,y: x * y))
+        for i in range(20):
+            name, func = mapping[j]
+            instrs.append("i{d} = {i}(i0, {d})".format(d=i+1, i=name))
+            values.append((name, func(value, i+1)))
+            failargs.append("i" + str(i+1))
+            j += 1
+            if j >= len(mapping):
+                j = 0
+        code = """
+        [i0]
+        {instrs}
+        i99 = int_add(i0, 1)
+        i100 = int_eq(i0,i99)
+        guard_true(i100) [{failargs}] # will always fail!!
+        finish(i0, descr=faildescr)
+        """.format(instrs=('\n' +' '*8).join(instrs), 
failargs=','.join(failargs))
+        # the guard forces 3 spills because after 4 divisions
+        # all even slots of the managed registers are full
+        loop = parse(code, namespace={'faildescr': BasicFinalDescr(1)})
+        looptoken = JitCellToken()
+        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+        deadframe = self.cpu.execute_token(looptoken, value)
+        fail = self.cpu.get_latest_descr(deadframe)
+        for i,(name, v) in enumerate(values):
+            assert self.cpu.get_int_value(deadframe, i) == v
+
+    @py.test.mark.parametrize('v1,v2', [
+        (-32,3), (-32,4), (-32,1), (-32,199),
+        (16236612,3), (-1201203,4), (-123101010023,1231), (-0,199),
+    ])
+    def test_int_mul_no_overflow(self, v1, v2):
+        try:
+            result = v1*v2
+        except OverflowError:
+            py.test.skip("this test is not made to check the overflow!")
+        code = """
+        [i0]
+        i1 = int_mul_ovf(i0,{v})
+        finish(i1, descr=faildescr)
+        """.format(v=v2)
+        loop = parse(code, namespace={"faildescr": BasicFinalDescr(1)})
+        looptoken = JitCellToken()
+        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+        deadframe = self.cpu.execute_token(looptoken, v1)
+        fail = self.cpu.get_latest_descr(deadframe)
+        assert self.cpu.get_int_value(deadframe, 0) == result
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
@@ -23,176 +23,3 @@
         cpu = CPU_S390_64(rtyper=None, stats=FakeStats())
         cpu.setup_once()
         return cpu
-
-    @py.test.mark.parametrize('value,opcode,result',
-        [ (30,'i1 = int_mul(i0, 2)',60),
-          (30,'i1 = int_floordiv(i0, 2)',15),
-          (2**31,'i1 = int_floordiv(i0, 15)',2**31//15),
-          (0,'i1 = int_floordiv(i0, 1)', 0),
-          (1,'i1 = int_floordiv(i0, 1)', 1),
-          (0,'i1 = uint_floordiv(i0, 1)', 0),
-          (1,'i1 = uint_floordiv(i0, 1)', 1),
-          (30,'i1 = int_mod(i0, 2)', 0),
-          (1,'i1 = int_mod(i0, 2)', 1),
-          (1,'i1 = int_lshift(i0, 4)', 16),
-          (1,'i1 = int_lshift(i0, 0)', 1),
-          (4,'i1 = int_rshift(i0, 0)', 4),
-          (4,'i1 = int_rshift(i0, 1)', 2),
-          (-1,'i1 = int_rshift(i0, 0)', -1),
-          (-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("""
-        [i0]
-        {opcode}
-        finish(i1, descr=faildescr)
-        """.format(opcode=opcode),namespace={"faildescr": BasicFinalDescr(1)})
-        looptoken = JitCellToken()
-        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
-        deadframe = self.cpu.execute_token(looptoken, value)
-        fail = self.cpu.get_latest_descr(deadframe)
-        res = self.cpu.get_int_value(deadframe, 0)
-        assert res == result
-        assert fail.identifier == 1 
-
-    @py.test.mark.parametrize('value,opcode,result,guard',
-        [ (2**63-1,'i1 = int_add_ovf(i0, 1)',1,'guard_no_overflow'),
-          (2**63-2,'i1 = int_add_ovf(i0, 1)',0,'guard_no_overflow'),
-          (2**63-2,'i1 = int_add_ovf(i0, 1)',1,'guard_overflow'),
-          (2**63-1,'i1 = int_add_ovf(i0, 1)',0,'guard_overflow'),
-
-          (-2**63,  'i1 = int_sub_ovf(i0, 1)',1,'guard_no_overflow'),
-          (-2**63+1,'i1 = int_sub_ovf(i0, 1)',0,'guard_no_overflow'),
-          (-2**63+1,'i1 = int_sub_ovf(i0, 1)',1,'guard_overflow'),
-          (-2**63,  'i1 = int_sub_ovf(i0, 1)',0,'guard_overflow'),
-
-          (-2**63,  'i1 = int_mul_ovf(i0, 2)',1,'guard_no_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
-        code = """
-        [i0]
-        {opcode}
-        {guard}() [i0]
-        i2 = int_xor(i1,i1)
-        finish(i2, descr=faildescr)
-        """.format(opcode=opcode,guard=guard)
-        loop = parse(code, namespace={"faildescr": BasicFinalDescr(1)})
-        looptoken = JitCellToken()
-        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
-        deadframe = self.cpu.execute_token(looptoken, value)
-        fail = self.cpu.get_latest_descr(deadframe)
-        res = self.cpu.get_int_value(deadframe, 0)
-        if result == 1:
-            assert res == value
-        else:
-            assert res == 0
-
-    def test_double_evenodd_pair(self):
-        code = """
-        [i0]
-        i1 = int_floordiv(i0, 2)
-        i2 = int_floordiv(i0, 3)
-        i3 = int_floordiv(i0, 4)
-        i4 = int_floordiv(i0, 5)
-        i5 = int_floordiv(i0, 6)
-        i6 = int_floordiv(i0, 7)
-        i7 = int_floordiv(i0, 8)
-        i8 = int_le(i1, 0)
-        guard_true(i8) [i1,i2,i3,i4,i5,i6,i7]
-        finish(i0, descr=faildescr)
-        """
-        # the guard forces 3 spills because after 4 divisions
-        # all even slots of the managed registers are full
-        loop = parse(code, namespace={'faildescr': BasicFinalDescr(1)})
-        looptoken = JitCellToken()
-        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
-        deadframe = self.cpu.execute_token(looptoken, 100)
-        fail = self.cpu.get_latest_descr(deadframe)
-        for i in range(2,9):
-            assert self.cpu.get_int_value(deadframe, i-2) == 100//i
-
-
-
-    @py.test.mark.parametrize('value', [2,3,15,2**16,-2**5])
-    def test_double_evenodd_pair_extensive(self, value):
-        instrs = []
-        failargs = []
-        values = []
-        j = 0
-        mapping = (('int_floordiv',lambda x,y: x // y),
-                   ('int_mod', lambda x,y: x % y),
-                   ('int_mul_ovf', lambda x,y: x * y))
-        for i in range(20):
-            name, func = mapping[j]
-            instrs.append("i{d} = {i}(i0, {d})".format(d=i+1, i=name))
-            values.append((name, func(value, i+1)))
-            failargs.append("i" + str(i+1))
-            j += 1
-            if j >= len(mapping):
-                j = 0
-        code = """
-        [i0]
-        {instrs}
-        i99 = int_add(i0, 1)
-        i100 = int_eq(i0,i99)
-        guard_true(i100) [{failargs}] # will always fail!!
-        finish(i0, descr=faildescr)
-        """.format(instrs=('\n' +' '*8).join(instrs), 
failargs=','.join(failargs))
-        # the guard forces 3 spills because after 4 divisions
-        # all even slots of the managed registers are full
-        loop = parse(code, namespace={'faildescr': BasicFinalDescr(1)})
-        looptoken = JitCellToken()
-        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
-        deadframe = self.cpu.execute_token(looptoken, value)
-        fail = self.cpu.get_latest_descr(deadframe)
-        for i,(name, v) in enumerate(values):
-            assert self.cpu.get_int_value(deadframe, i) == v
-
-    @py.test.mark.parametrize('v1,v2', [
-        (-32,3),
-    ])
-    def test_int_mul_no_overflow(self, v1, v2):
-        try:
-            result = v1*v2
-        except OverflowError:
-            py.test.skip("this test is not made to check the overflow!")
-        code = """
-        [i0]
-        i1 = int_mul_ovf(i0,{v})
-        finish(i1, descr=faildescr)
-        """.format(v=v2)
-        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, v1)
-        fail = self.cpu.get_latest_descr(deadframe)
-        assert self.cpu.get_int_value(deadframe, 0) == result
-
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to