[pypy-svn] pypy jit-longlong: OS_LLONG_TO_INT, implemented with MOVD.

arigo commits-noreply at bitbucket.org
Sun Jan 9 11:11:12 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: jit-longlong
Changeset: r40499:0d982c914303
Date: 2011-01-08 18:52 +0100
http://bitbucket.org/pypy/pypy/changeset/0d982c914303/

Log:	OS_LLONG_TO_INT, implemented with MOVD.

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
@@ -545,8 +545,13 @@
     CVTTSD2SI_rx = xmminsn('\xF2', rex_w, '\x0F\x2C', register(1, 8), register(2), '\xC0')
     CVTTSD2SI_rb = xmminsn('\xF2', rex_w, '\x0F\x2C', register(1, 8), stack_bp(2))
 
+    MOVD_rx = xmminsn('\x66', rex_w, '\x0F\x7E', register(2, 8), register(1), '\xC0')
     PADDQ_xx = xmminsn('\x66', rex_nw, '\x0F\xD4', register(1, 8), register(2), '\xC0')
     PSUBQ_xx = xmminsn('\x66', rex_nw, '\x0F\xFB', register(1, 8), register(2), '\xC0')
+    # PAND
+    # POR
+    # PSLLQ
+    # PXOR
 
     # ------------------------------------------------------------
 

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
@@ -986,8 +986,6 @@
     genop_float_sub = _binaryop('SUBSD')
     genop_float_mul = _binaryop('MULSD', True)
     genop_float_truediv = _binaryop('DIVSD')
-    genop_llong_add = _binaryop("PADDQ", True)
-    genop_llong_sub = _binaryop("PSUBQ", True)
 
     genop_int_lt = _cmpop("L", "G")
     genop_int_le = _cmpop("LE", "GE")
@@ -1101,6 +1099,20 @@
         self.mc.XOR_rr(edx.value, edx.value)
         self.mc.DIV_r(ecx.value)
 
+    genop_llong_add = _binaryop("PADDQ", True)
+    genop_llong_sub = _binaryop("PSUBQ", True)
+
+    def genop_llong_to_int(self, op, arglocs, resloc):
+        loc = arglocs[0]
+        assert isinstance(resloc, RegLoc)
+        if isinstance(loc, RegLoc):
+            self.mc.MOVD_rx(resloc.value, loc.value)
+        elif isinstance(loc, StackLoc):
+            self.mc.MOV_rb(resloc.value, loc.value)
+        else:
+            not_implemented("llong_to_int: %s" % (loc,))
+
+
     def genop_new_with_vtable(self, op, arglocs, result_loc):
         assert result_loc is eax
         loc_vtable = arglocs[-1]

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
@@ -630,7 +630,7 @@
         self.Perform(op, [loc0], loc1)
         self.rm.possibly_free_var(op.getarg(0))
 
-    def _consider_llong_binop(self, op):
+    def _consider_llong_binop_rr(self, op):
         # must force both arguments into registers, because we don't
         # know if they will be suitably aligned
         args = [op.getarg(1), op.getarg(2)]
@@ -639,6 +639,13 @@
         self.PerformLLong(op, [loc0, loc1], loc0)
         self.xrm.possibly_free_vars(args)
 
+    def _consider_llong_to_int(self, op):
+        # accept an argument in a xmm register or in the stack
+        loc1 = self.xrm.loc(op.getarg(1))
+        loc0 = self.rm.force_allocate_reg(op.result)
+        self.PerformLLong(op, [loc1], loc0)
+        self.xrm.possibly_free_var(op.getarg(1))
+
     def _call(self, op, arglocs, force_store=[], guard_not_forced_op=None):
         save_all_regs = guard_not_forced_op is not None
         self.rm.before_call(force_store, save_all_regs=save_all_regs)
@@ -675,7 +682,9 @@
             oopspecindex = effectinfo.oopspecindex
             if oopspecindex in (EffectInfo.OS_LLONG_ADD,
                                 EffectInfo.OS_LLONG_SUB):
-                return self._consider_llong_binop(op)
+                return self._consider_llong_binop_rr(op)
+            if oopspecindex == EffectInfo.OS_LLONG_TO_INT:
+                return self._consider_llong_to_int(op)
         #
         self._consider_call(op)
 

diff --git a/pypy/jit/metainterp/test/test_longlong.py b/pypy/jit/metainterp/test/test_longlong.py
--- a/pypy/jit/metainterp/test/test_longlong.py
+++ b/pypy/jit/metainterp/test/test_longlong.py
@@ -186,6 +186,15 @@
                                      supports_longlong=True)
         assert res == intmask(2147483647 + 21474)
 
+    def test_truncate(self):
+        def f(n):
+            m = r_longlong(n) << 20
+            return r_uint(m)
+        res = self.interp_operations(f, [0x01234567])
+        assert res == 0x56700000
+        res = self.interp_operations(f, [0x56789ABC])
+        assert intmask(res) == intmask(0xABC00000)
+
 
 class TestLLtype(LongLongTests, LLJitMixin):
     pass


More information about the Pypy-commit mailing list