[pypy-commit] pypy s390x-backend: added assertion to pool, rewrote assembler of int_mul_ovf

plan_rich pypy.commits at gmail.com
Wed Jan 13 09:58:52 EST 2016


Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r81741:ee366b2e8bfb
Date: 2016-01-13 15:57 +0100
http://bitbucket.org/pypy/pypy/changeset/ee366b2e8bfb/

Log:	added assertion to pool, rewrote assembler of int_mul_ovf

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
@@ -182,6 +182,7 @@
 
     def __init__(self, offset, isfloat=False):
         AddressLocation.__init__(self, None, None, offset, None)
+        assert offset >= 0
         self.base = 13
         self.isfloat = isfloat
         if 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
@@ -52,60 +52,113 @@
         elif l1.is_imm():
             self.mc.LGFI(r.SCRATCH, l1)
             l1 = r.SCRATCH
+        else:
+            # we are not allowed to modify l1 if it is not a scratch
+            # register, thus copy it here!
+            self.mc.LGR(r.SCRATCH, l1)
+            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.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+mc.BRC_byte_count))
-        mc.CGIJ(l1, l.imm(0), c.GE, l.imm(mc.CGIJ_byte_count*2+mc.BRC_byte_count + bc_one_signed))
-        mc.BRC(c.ANY, l.imm(mc.BRC_byte_count + mc.CGIJ_byte_count)) # right is negative 
-        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
+        jmp_lq_lt_0 = mc.get_relative_pos()
+        mc.reserve_cond_jump() # CGIJ lq < 0 +-----------+
+        jmp_l1_ge_0 = mc.get_relative_pos() #            |
+        mc.reserve_cond_jump() # CGIJ l1 >= 0 -----------|-> (both same sign)
+        jmp_lq_pos_l1_neg = mc.get_relative_pos() #      |
+        mc.reserve_cond_jump(short=True) #  BCR any -----|-> (xor negative)
+        jmp_l1_neg_lq_neg = mc.get_relative_pos() #      |
+        mc.reserve_cond_jump() # <-----------------------+
+                               # CGIJ l1 < 0 -> (both same_sign)
+        # (xor negative)
+        label_xor_neg = mc.get_relative_pos()
+        mc.LPGR(lq, lq)
+        mc.LPGR(l1, l1)
+        mc.MLGR(lr, l1)
+        mc.LG(r.SCRATCH, l.pool(self.pool.constant_64_sign_bit))
+        # is the value greater than 2**63 ? then an overflow occured
+        jmp_xor_lq_overflow = mc.get_relative_pos()
+        mc.reserve_cond_jump() # CLGRJ lq > 0x8000 ... 00 -> (label_overflow)
+        jmp_xor_lr_overflow = mc.get_relative_pos()
+        mc.reserve_cond_jump() # CLGIJ lr > 0 -> (label_overflow)
+        mc.LCGR(lq, lq) # complement the value
+        mc.SPM(r.SCRATCH) # 0x80 ... 00 clears the condition code and program mask
+        jmp_no_overflow_xor_neg = mc.get_relative_pos()
+        mc.reserve_cond_jump(short=True)
+
+        # both are positive/negative
+        label_both_same_sign = mc.get_relative_pos()
         mc.LPGR(lq, lq)
         mc.LPGR(l1, l1)
         mc.MLGR(lr, l1)
         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
+        jmp_lq_overflow = mc.get_relative_pos()
+        mc.reserve_cond_jump() # CLGRJ lq > 0x7fff ... ff -> (label_overflow)
+        jmp_lr_overflow = mc.get_relative_pos()
+        mc.reserve_cond_jump() # CLGIJ lr > 0 -> (label_overflow)
+        jmp_neither_lqlr_overflow = mc.get_relative_pos()
+        mc.reserve_cond_jump(short=True) # BRC any -> (label_end)
 
-        # both are positive
-        mc.LPGR(lq, lq)
-        mc.LPGR(l1, l1)
-        mc.MLGR(lr, l1)
-        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)
+        label_overflow = mc.get_relative_pos()
+        mc.XGR(r.SCRATCH, r.SCRATCH)
         # set bit 34 & 35 -> indicates overflow
         mc.OILH(r.SCRATCH, l.imm(0x3000)) # sets OF
         mc.SPM(r.SCRATCH)
 
         # no overflow happended
+        label_end = mc.get_relative_pos()
+
+        # patch patch patch!!!
+
+        # jmp_lq_lt_0
+        pos = jmp_lq_lt_0
+        omc = OverwritingBuilder(self.mc, pos, 1)
+        omc.CGIJ(lq, l.imm(0), c.LT, l.imm(jmp_l1_neg_lq_neg - pos))
+        omc.overwrite()
+        # jmp_l1_ge_0
+        pos = jmp_l1_ge_0
+        omc = OverwritingBuilder(self.mc, pos, 1)
+        omc.CGIJ(l1, l.imm(0), c.GE, l.imm(label_both_same_sign - pos))
+        omc.overwrite()
+        # jmp_lq_pos_l1_neg
+        pos = jmp_lq_pos_l1_neg
+        omc = OverwritingBuilder(self.mc, pos, 1)
+        omc.BRC(c.ANY, l.imm(label_xor_neg - pos))
+        omc.overwrite()
+        # jmp_l1_neg_lq_neg
+        pos = jmp_l1_neg_lq_neg
+        omc = OverwritingBuilder(self.mc, pos, 1)
+        omc.CGIJ(l1, l.imm(0), c.LT, l.imm(label_both_same_sign - pos))
+        omc.overwrite()
+
+        # patch jmp_xor_lq_overflow
+        pos = jmp_xor_lq_overflow
+        omc = OverwritingBuilder(self.mc, pos, 1)
+        omc.CLGRJ(lq, r.SCRATCH, c.GT, l.imm(label_overflow - pos))
+        omc.overwrite()
+        # patch jmp_xor_lr_overflow
+        pos = jmp_xor_lr_overflow
+        omc = OverwritingBuilder(self.mc, pos, 1)
+        omc.CLGIJ(lr, l.imm(0), c.GT, l.imm(label_overflow - pos))
+        omc.overwrite()
+        # patch jmp_no_overflow_xor_neg
+        omc = OverwritingBuilder(self.mc, jmp_no_overflow_xor_neg, 1)
+        omc.BRC(c.ANY, l.imm(label_end - jmp_no_overflow_xor_neg))
+        omc.overwrite()
+        # patch jmp_lq_overflow
+        omc = OverwritingBuilder(self.mc, jmp_lq_overflow, 1)
+        omc.CLGRJ(lq, r.SCRATCH, c.GT, l.imm(label_overflow - jmp_lq_overflow))
+        omc.overwrite()
+        # patch jmp_lr_overflow
+        omc = OverwritingBuilder(self.mc, jmp_lr_overflow, 1)
+        omc.CLGIJ(lr, l.imm(0), c.GT, l.imm(label_overflow - jmp_lr_overflow))
+        omc.overwrite()
+        # patch jmp_neither_lqlr_overflow
+        omc = OverwritingBuilder(self.mc, jmp_neither_lqlr_overflow, 1)
+        omc.BRC(c.ANY, l.imm(label_end - jmp_neither_lqlr_overflow))
+        omc.overwrite()
 
     emit_int_floordiv = gen_emit_pool_or_rr_evenodd('DSG','DSGR')
     emit_uint_floordiv = gen_emit_pool_or_rr_evenodd('DLG','DLGR')


More information about the pypy-commit mailing list