[pypy-svn] pypy jit-longlong: LLONG_EQ.

arigo commits-noreply at bitbucket.org
Sun Jan 9 22:57:08 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: jit-longlong
Changeset: r40543:007034e4ad2c
Date: 2011-01-09 21:58 +0100
http://bitbucket.org/pypy/pypy/changeset/007034e4ad2c/

Log:	LLONG_EQ.

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
@@ -552,8 +552,9 @@
     PAND_xx = xmminsn('\x66', rex_nw, '\x0F\xDB', register(1, 8), register(2), '\xC0')
     POR_xx  = xmminsn('\x66', rex_nw, '\x0F\xEB', register(1, 8), register(2), '\xC0')
     PXOR_xx = xmminsn('\x66', rex_nw, '\x0F\xEF', register(1, 8), register(2), '\xC0')
-    # PSLLQ
     PUNPCKLDQ_xx = xmminsn('\x66', rex_nw, '\x0F\x62', register(1, 8), register(2), '\xC0')
+    PMOVMSKB_rx = xmminsn('\x66', rex_w, '\x0F\xD7', register(1, 8), register(2), '\xC0')
+    PCMPEQD_xx = xmminsn('\x66', rex_nw, '\x0F\x76', register(1, 8), register(2), '\xC0')
 
     # ------------------------------------------------------------
 

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
@@ -1148,6 +1148,20 @@
                 self.mc.MOVD_xr(loc3.value, loc2.value)
             self.mc.PUNPCKLDQ_xx(resloc.value, loc3.value)
 
+    def genop_llong_eq(self, op, arglocs, resloc):
+        loc1, loc2, locxtmp, loctmp = arglocs
+        self.mc.MOVSD_xx(locxtmp.value, loc1.value)
+        self.mc.PCMPEQD_xx(locxtmp.value, loc2.value)
+        self.mc.PMOVMSKB_rx(loctmp.value, locxtmp.value)
+        # Now the lower 8 bits of resloc contain 0x00, 0x0F, 0xF0 or 0xFF
+        # depending on the result of the comparison of each of the two
+        # double-words of loc1 and loc2.  The higher 8 bits contain random
+        # results.  We want to map 0xFF to 1, and 0x00, 0x0F and 0xF0 to 0.
+        self.mc.MOV_rr(resloc.value, loctmp.value)
+        self.mc.SHR_ri(loctmp.value, 4)
+        self.mc.AND_ri(resloc.value, 1)
+        self.mc.AND_rr(resloc.value, loctmp.value)
+
     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
@@ -631,8 +631,8 @@
         self.Perform(op, [loc0], loc1)
         self.rm.possibly_free_var(op.getarg(0))
 
-    def _consider_llong_binop_rr(self, op):
-        # must force both arguments into registers, because we don't
+    def _consider_llong_binop_xx(self, op):
+        # must force both arguments into xmm registers, because we don't
         # know if they will be suitably aligned
         args = [op.getarg(1), op.getarg(2)]
         loc1 = self.xrm.make_sure_var_in_reg(args[1], imm_fine=False)
@@ -640,6 +640,22 @@
         self.PerformLLong(op, [loc0, loc1], loc0)
         self.xrm.possibly_free_vars(args)
 
+    def _consider_llong_cmp_xx(self, op):
+        # must force both arguments into xmm registers, because we don't
+        # know if they will be suitably aligned
+        args = [op.getarg(1), op.getarg(2)]
+        loc1 = self.xrm.make_sure_var_in_reg(args[0], imm_fine=False)
+        loc2 = self.xrm.make_sure_var_in_reg(args[1], args, imm_fine=False)
+        tmpxvar = TempBox()
+        loc3 = self.xrm.force_allocate_reg(tmpxvar, args)
+        self.xrm.possibly_free_var(tmpxvar)
+        tmpvar = TempBox()
+        loc4 = self.rm.force_allocate_reg(tmpvar)
+        loc0 = self.rm.force_allocate_reg(op.result, [tmpvar])
+        self.rm.possibly_free_var(tmpvar)
+        self.PerformLLong(op, [loc1, loc2, loc3, loc4], 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))
@@ -746,13 +762,15 @@
                                     EffectInfo.OS_LLONG_AND,
                                     EffectInfo.OS_LLONG_OR,
                                     EffectInfo.OS_LLONG_XOR):
-                    return self._consider_llong_binop_rr(op)
+                    return self._consider_llong_binop_xx(op)
                 if oopspecindex == EffectInfo.OS_LLONG_TO_INT:
                     return self._consider_llong_to_int(op)
                 if oopspecindex == EffectInfo.OS_LLONG_FROM_INT:
                     return self._consider_llong_from_int(op)
                 if oopspecindex == EffectInfo.OS_LLONG_FROM_TWO_INTS:
                     return self._consider_llong_from_two_ints(op)
+                if oopspecindex == EffectInfo.OS_LLONG_EQ:
+                    return self._consider_llong_cmp_xx(op)
         #
         self._consider_call(op)
 


More information about the Pypy-commit mailing list