[pypy-commit] pypy int-tag-untag-as-operations: (arigo, cfbolz): implement int_tag, int_tag_ovf and int_untag in the x86 backend

cfbolz noreply at buildbot.pypy.org
Mon Oct 24 12:41:57 CEST 2011


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: int-tag-untag-as-operations
Changeset: r48370:30319db8738f
Date: 2011-10-24 12:41 +0200
http://bitbucket.org/pypy/pypy/changeset/30319db8738f/

Log:	(arigo, cfbolz): implement int_tag, int_tag_ovf and int_untag in the
	x86 backend

diff --git a/pypy/jit/backend/test/test_random.py b/pypy/jit/backend/test/test_random.py
--- a/pypy/jit/backend/test/test_random.py
+++ b/pypy/jit/backend/test/test_random.py
@@ -293,6 +293,9 @@
 class BinaryOvfOperation(AbstractOvfOperation, BinaryOperation):
     pass
 
+class UnaryOvfOperation(AbstractOvfOperation, UnaryOperation):
+    pass
+
 class AbstractFloatOperation(AbstractOperation):
     def filter(self, builder):
         if not builder.cpu.supports_floats:
@@ -421,6 +424,8 @@
 
 for _op in [rop.INT_NEG,
             rop.INT_INVERT,
+            rop.INT_TAG,
+            rop.INT_UNTAG,
             ]:
     OPERATIONS.append(UnaryOperation(_op))
 
@@ -433,6 +438,7 @@
             rop.INT_MUL_OVF,
             ]:
     OPERATIONS.append(BinaryOvfOperation(_op))
+OPERATIONS.append(UnaryOvfOperation(rop.INT_TAG_OVF))
 
 for _op in [rop.FLOAT_ADD,
             rop.FLOAT_SUB,
diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -1311,7 +1311,19 @@
     genop_guard_float_eq = _cmpop_guard_float("E", "E", "NE","NE")
     genop_guard_float_gt = _cmpop_guard_float("A", "B", "BE","AE")
     genop_guard_float_ge = _cmpop_guard_float("AE","BE", "B", "A")
-    
+
+
+    def genop_int_tag(self, op, arglocs, resloc):
+        loc, = arglocs
+        assert isinstance(loc, RegLoc)
+        assert isinstance(resloc, RegLoc)
+        # res = loc + (loc << 0) + 1
+        self.mc.LEA_ra(resloc.value, (loc.value, loc.value, 0, 1))
+
+    def genop_int_untag(self, op, arglocs, resloc):
+        loc, = arglocs
+        self.mc.SAR(loc, imm1)
+
     def genop_math_sqrt(self, op, arglocs, resloc):
         self.mc.SQRTSD(arglocs[0], resloc)
 
@@ -1730,6 +1742,11 @@
         self.genop_int_mul(op, arglocs, result_loc)
         return self._gen_guard_overflow(guard_op, guard_token)
 
+    def genop_guard_int_tag_ovf(self, op, guard_op, guard_token, arglocs, result_loc):
+        self.mc.STC()
+        self.mc.ADC(arglocs[0], arglocs[0])
+        return self._gen_guard_overflow(guard_op, guard_token)
+
     def genop_guard_guard_false(self, ign_1, guard_op, guard_token, locs, ign_2):
         loc = locs[0]
         self.mc.TEST(loc, loc)
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -579,11 +579,22 @@
     consider_int_sub_ovf = _consider_binop_with_guard
     consider_int_add_ovf = _consider_binop_with_guard
 
+    def consider_int_tag_ovf(self, op, guard_op):
+        loc = self.rm.force_result_in_reg(op.result, op.getarg(0))
+        self.perform_with_guard(op, guard_op, [loc], loc)
+
+    def consider_int_tag(self, op):
+        loc = self.rm.make_sure_var_in_reg(op.getarg(0))
+        self.rm.possibly_free_vars_for_op(op)
+        res = self.rm.force_allocate_reg(op.result)
+        self.Perform(op, [loc], res)
+
     def consider_int_neg(self, op):
         res = self.rm.force_result_in_reg(op.result, op.getarg(0))
         self.Perform(op, [res], res)
 
     consider_int_invert = consider_int_neg
+    consider_int_untag = consider_int_neg
 
     def consider_int_lshift(self, op):
         if isinstance(op.getarg(1), Const):
diff --git a/pypy/jit/backend/x86/regloc.py b/pypy/jit/backend/x86/regloc.py
--- a/pypy/jit/backend/x86/regloc.py
+++ b/pypy/jit/backend/x86/regloc.py
@@ -487,6 +487,7 @@
     BTS = _binaryop('BTS')
 
     ADD = _binaryop('ADD')
+    ADC = _binaryop('ADC')
     SUB = _binaryop('SUB')
     IMUL = _binaryop('IMUL')
     NEG = _unaryop('NEG')
diff --git a/pypy/jit/backend/x86/rx86.py b/pypy/jit/backend/x86/rx86.py
--- a/pypy/jit/backend/x86/rx86.py
+++ b/pypy/jit/backend/x86/rx86.py
@@ -470,6 +470,7 @@
     # ------------------------------ Arithmetic ------------------------------
 
     ADD_ri,ADD_rr,ADD_rb,_,_,ADD_rm,ADD_rj,_,_ = common_modes(0)
+    ADC_ri,ADC_rr,ADC_rb,_,_,ADC_rm,ADC_rj,_,_ = common_modes(2)
     OR_ri, OR_rr, OR_rb, _,_,OR_rm, OR_rj, _,_ = common_modes(1)
     AND_ri,AND_rr,AND_rb,_,_,AND_rm,AND_rj,_,_ = common_modes(4)
     SUB_ri,SUB_rr,SUB_rb,_,_,SUB_rm,SUB_rj,SUB_ji8,SUB_mi8 = common_modes(5)
@@ -577,6 +578,8 @@
     FSTPL_b = insn('\xDD', orbyte(3<<3), stack_bp(1)) # rffi.DOUBLE ('as' wants L??)
     FSTPS_s = insn('\xD9', orbyte(3<<3), stack_sp(1)) # lltype.SingleFloat
 
+    STC = insn('\xF9')
+
     # ------------------------------ Random mess -----------------------
     RDTSC = insn('\x0F\x31')
 
diff --git a/pypy/jit/backend/x86/test/test_regalloc.py b/pypy/jit/backend/x86/test/test_regalloc.py
--- a/pypy/jit/backend/x86/test/test_regalloc.py
+++ b/pypy/jit/backend/x86/test/test_regalloc.py
@@ -660,3 +660,27 @@
         self.run(loop)
         assert self.getint(0) == 29
 
+    def test_int_untag(self):
+        ops = '''
+        [i0]
+        i1 = int_untag(i0)
+        finish(i1)
+        '''
+        self.interpret(ops, [1129])
+        assert self.getint(0) == 564
+        self.interpret(ops, [-1129])
+        assert self.getint(0) == -565
+
+    def test_int_tag(self):
+        ops = '''
+        [i0]
+        i1 = int_tag(i0)
+        i2 = int_tag(i0)
+        finish(i1, i2)
+        '''
+        self.interpret(ops, [1129])
+        assert self.getint(0) == 1129 * 2 + 1
+        assert self.getint(1) == 1129 * 2 + 1
+        self.interpret(ops, [-1129])
+        assert self.getint(0) == -1129 * 2 + 1
+        assert self.getint(1) == -1129 * 2 + 1
diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py
--- a/pypy/jit/metainterp/blackhole.py
+++ b/pypy/jit/metainterp/blackhole.py
@@ -452,7 +452,7 @@
         return a >> 1
     @arguments("i", returns="i")
     def bhimpl_int_tag(a):
-        return (a << 1) + 1
+        return intmask(a << 1) + 1 # mostly there for test_random
     @arguments("i", returns="i")
     def bhimpl_int_tag_ovf(a):
         return ovfcheck(a << 1) + 1
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -3435,10 +3435,7 @@
             return sa
         res = self.meta_interp(f, [16])
         assert res == f(16)
-        
-
-
-class TestLLtype(BaseLLtypeTests, LLJitMixin):
+
     def test_tagged(self):
         from pypy.rlib.objectmodel import UnboxedValue
         class Base(object):
@@ -3523,3 +3520,8 @@
         assert x == -42
         x = self.interp_operations(f, [1000, 1], taggedpointers=True)
         assert x == 999
+
+
+
+class TestLLtype(BaseLLtypeTests, LLJitMixin):
+    pass # should be empty


More information about the pypy-commit mailing list