[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