Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r74794:4634aad50952
Date: 2014-12-03 11:29 +0100
http://bitbucket.org/pypy/pypy/changeset/4634aad50952/

Log:    Add INT_SIGNEXT to test_random, and found out another corner case on
        32-bit only.

diff --git a/rpython/jit/backend/test/test_random.py 
b/rpython/jit/backend/test/test_random.py
--- a/rpython/jit/backend/test/test_random.py
+++ b/rpython/jit/backend/test/test_random.py
@@ -321,6 +321,14 @@
         else:
             self.put(builder, [ConstFloat(r.random_float_storage())])
 
+class SignExtOperation(AbstractOperation):
+    def produce_into(self, builder, r):
+        sizes = [1, 2]
+        if sys.maxint > (1 << 32):
+            sizes.append(4)
+        self.put(builder, [r.choice(builder.intvars),
+                           ConstInt(r.choice(sizes))])
+
 class BinaryOperation(AbstractOperation):
     def __init__(self, opnum, and_mask=-1, or_mask=0, boolres=False):
         AbstractOperation.__init__(self, opnum, boolres=boolres)
@@ -509,6 +517,7 @@
 OPERATIONS.append(UnaryOperation(rop.INT_IS_TRUE, boolres=True))
 OPERATIONS.append(UnaryOperation(rop.INT_IS_ZERO, boolres=True))
 OPERATIONS.append(ConstUnaryOperation(rop.SAME_AS, boolres='sometimes'))
+OPERATIONS.append(SignExtOperation(rop.INT_SIGNEXT))
 
 for _op in [rop.INT_ADD_OVF,
             rop.INT_SUB_OVF,
diff --git a/rpython/jit/backend/x86/assembler.py 
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -1147,9 +1147,20 @@
     def genop_int_signext(self, op, arglocs, resloc):
         argloc, numbytesloc = arglocs
         assert isinstance(numbytesloc, ImmedLoc)
+        assert isinstance(resloc, RegLoc)
         if numbytesloc.value == 1:
             if isinstance(argloc, RegLoc):
-                argloc = argloc.lowest8bits()
+                if WORD == 4 and argloc.value >= 4:
+                    # meh, can't read the lowest byte of esi or edi on 32-bit
+                    if resloc.value < 4:
+                        self.mc.MOV(resloc, argloc)
+                        argloc = resloc
+                    else:
+                        tmploc = RawEspLoc(0, INT)
+                        self.mc.MOV(tmploc, argloc)
+                        argloc = tmploc
+                if isinstance(argloc, RegLoc):
+                    argloc = argloc.lowest8bits()
             self.mc.MOVSX8(resloc, argloc)
         elif numbytesloc.value == 2:
             self.mc.MOVSX16(resloc, argloc)
diff --git a/rpython/jit/backend/x86/regloc.py 
b/rpython/jit/backend/x86/regloc.py
--- a/rpython/jit/backend/x86/regloc.py
+++ b/rpython/jit/backend/x86/regloc.py
@@ -151,6 +151,8 @@
 
     def lowest8bits(self):
         assert not self.is_xmm
+        if WORD == 4:
+            assert 0 <= self.value < 4
         return RegLoc(rx86.low_byte(self.value), False)
 
     def higher8bits(self):
diff --git a/rpython/jit/backend/x86/rx86.py b/rpython/jit/backend/x86/rx86.py
--- a/rpython/jit/backend/x86/rx86.py
+++ b/rpython/jit/backend/x86/rx86.py
@@ -33,8 +33,9 @@
     xmmnames = ['xmm%d' % i for i in range(16)]
 
 def low_byte(reg):
-    # XXX: On 32-bit, this only works for 0 <= reg < 4
-    # Maybe we should check this?
+    # On 32-bit, this only works for 0 <= reg < 4.  The caller checks that.
+    # On 64-bit, it works for any register, but the assembler instruction
+    # must include a REX prefix (possibly with no modifier flags).
     return reg | BYTE_REG_FLAG
 
 def high_byte(reg):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to