[pypy-svn] r40701 - in pypy/dist/pypy/jit/codegen: i386 test

arigo at codespeak.net arigo at codespeak.net
Sun Mar 18 15:13:26 CET 2007


Author: arigo
Date: Sun Mar 18 15:13:23 2007
New Revision: 40701

Modified:
   pypy/dist/pypy/jit/codegen/i386/operation.py
   pypy/dist/pypy/jit/codegen/test/operation_tests.py
Log:
More operation tests.  Comment out the div- and mod-correction code in the 386 backend.


Modified: pypy/dist/pypy/jit/codegen/i386/operation.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/operation.py	(original)
+++ pypy/dist/pypy/jit/codegen/i386/operation.py	Sun Mar 18 15:13:23 2007
@@ -281,7 +281,12 @@
                 mc.CDQ()
 
         op2 = allocator.grab_operand(self.y)
-        self.generate2(allocator, op2)
+        try:
+            self.generate2(allocator, op2)
+        except FailedToImplement:
+            tmp = allocator.create_scratch_reg(op2)
+            self.generate2(allocator, tmp)
+            allocator.end_clobber(tmp)
 
         allocator.end_clobber(eax)
         allocator.end_clobber(edx)
@@ -290,102 +295,107 @@
         # the target register should still be free, see clobber2()
         allocator.create_exactly_at(self, self.reg_containing_result)
 
-class OpIntFloorDiv(MulOrDivOp):
-    opname = 'int_floordiv'
-    input_is_64bits = True
-    reg_containing_result = eax
-    unsigned = False
-
-    def generate2(self, allocator, op2):
-        # from the PPC backend which has the same problem:
-        # 
-        #   grumble, the powerpc handles division when the signs of x
-        #   and y differ the other way to how cpython wants it.  this
-        #   crawling horror is a branch-free way of computing the right
-        #   remainder in all cases.  it's probably not optimal.
-        #
-        #   we need to adjust the result iff the remainder is non-zero
-        #   and the signs of x and y differ.  in the standard-ish PPC
-        #   way, we compute boolean values as either all-bits-0 or
-        #   all-bits-1 and "and" them together, resulting in either
-        #   adding 0 or -1 as needed in the final step.
-        #
-        #                 Python    i386
-        #    20/3    =     6, 2     6, 2
-        # (-20)/3    =    -7, 1    -6,-2      # operand signs differ
-        #    20/(-3) =    -7,-1    -6, 2      # operand signs differ
-        # (-20)/(-3) =     6,-2     6,-2
-        #
-        tmp = allocator.create_scratch_reg()
-        mc = allocator.mc
-        if isinstance(op2, IMM32):
-            # if op2 is an immediate, we do an initial adjustment of operand 1
-            # so that we get directly the correct answer
-            if op2.value >= 0:
-                # if op1 is negative, subtract (op2-1)
-                mc.MOV(tmp, edx)       # -1 if op1 is negative, 0 otherwise
-                mc.AND(tmp, imm(op2.value-1))
-                mc.SUB(eax, tmp)
-                mc.SBB(edx, imm8(0))
-            else:
-                # if op1 is positive (or null), add (|op2|-1)
-                mc.MOV(tmp, edx)
-                mc.NOT(tmp)            # -1 if op1 is positive, 0 otherwise
-                mc.AND(tmp, imm(-op2.value-1))
-                mc.ADD(eax, tmp)
-                mc.ADC(edx, imm8(0))
-            mc.MOV(tmp, op2)
-            mc.IDIV(tmp)
-        else:
-            # subtract 1 to the result if the operand signs differ and
-            # the remainder is not zero
-            mc.MOV(tmp, eax)
-            mc.IDIV(op2)
-            mc.XOR(tmp, op2)
-            mc.SAR(tmp, imm8(31)) # -1 if signs differ, 0 otherwise
-            mc.AND(tmp, edx)      # nonnull if signs differ and edx != 0
-            mc.CMP(tmp, imm8(1))  # no carry flag iff signs differ and edx != 0
-            mc.ADC(eax, imm8(-1)) # subtract 1 iff no carry flag
-        allocator.end_clobber(tmp)
-
-class OpIntMod(MulOrDivOp):
-    opname = 'int_mod'
-    input_is_64bits = True
-    reg_containing_result = edx
-    unsigned = False
-
-    def generate2(self, allocator, op2):
-        #                 Python    i386
-        #    20/3    =     6, 2     6, 2
-        # (-20)/3    =    -7, 1    -6,-2      # operand signs differ
-        #    20/(-3) =    -7,-1    -6, 2      # operand signs differ
-        # (-20)/(-3) =     6,-2     6,-2
-        #
-        tmp = allocator.create_scratch_reg()
-        mc = allocator.mc
-        if isinstance(op2, IMM32):
-            mc.MOV(tmp, op2)
-            mc.IDIV(tmp)
-            # adjustment needed:
-            #   if op2 > 0: if the result is negative, add op2 to it
-            #   if op2 < 0: if the result is > 0, subtract |op2| from it
-            mc.MOV(tmp, edx)
-            if op2.value < 0:
-                mc.NEG(tmp)
-            mc.SAR(tmp, imm8(31))
-            mc.AND(tmp, imm(op2.value))
-            mc.ADD(edx, tmp)
-        else:
-            # if the operand signs differ and the remainder is not zero,
-            # add operand2 to the result
-            mc.MOV(tmp, eax)
-            mc.IDIV(op2)
-            mc.XOR(tmp, op2)
-            mc.SAR(tmp, imm8(31)) # -1 if signs differ, 0 otherwise
-            mc.AND(tmp, edx)      # nonnull if signs differ and edx != 0
-            mc.CMOVNZ(tmp, op2)   # == op2  if signs differ and edx != 0
-            mc.ADD(edx, tmp)
-        allocator.end_clobber(tmp)
+## __________ logic for Python-like division and modulo _________
+##
+## (disabled for now, as int_floordiv and int_mod have CPU-like
+## semantics at the moment)
+
+##class OpIntFloorDiv(MulOrDivOp):
+##    opname = 'int_floordiv'
+##    input_is_64bits = True
+##    reg_containing_result = eax
+##    unsigned = False
+
+##    def generate2(self, allocator, op2):
+##        # from the PPC backend which has the same problem:
+##        # 
+##        #   grumble, the powerpc handles division when the signs of x
+##        #   and y differ the other way to how cpython wants it.  this
+##        #   crawling horror is a branch-free way of computing the right
+##        #   remainder in all cases.  it's probably not optimal.
+##        #
+##        #   we need to adjust the result iff the remainder is non-zero
+##        #   and the signs of x and y differ.  in the standard-ish PPC
+##        #   way, we compute boolean values as either all-bits-0 or
+##        #   all-bits-1 and "and" them together, resulting in either
+##        #   adding 0 or -1 as needed in the final step.
+##        #
+##        #                 Python    i386
+##        #    20/3    =     6, 2     6, 2
+##        # (-20)/3    =    -7, 1    -6,-2      # operand signs differ
+##        #    20/(-3) =    -7,-1    -6, 2      # operand signs differ
+##        # (-20)/(-3) =     6,-2     6,-2
+##        #
+##        tmp = allocator.create_scratch_reg()
+##        mc = allocator.mc
+##        if isinstance(op2, IMM32):      XXX
+##            # if op2 is an immediate, we do an initial adjustment of operand 1
+##            # so that we get directly the correct answer
+##            if op2.value >= 0:
+##                # if op1 is negative, subtract (op2-1)
+##                mc.MOV(tmp, edx)       # -1 if op1 is negative, 0 otherwise
+##                mc.AND(tmp, imm(op2.value-1))
+##                mc.SUB(eax, tmp)
+##                mc.SBB(edx, imm8(0))
+##            else:
+##                # if op1 is positive (or null), add (|op2|-1)
+##                mc.MOV(tmp, edx)
+##                mc.NOT(tmp)            # -1 if op1 is positive, 0 otherwise
+##                mc.AND(tmp, imm(-op2.value-1))
+##                mc.ADD(eax, tmp)
+##                mc.ADC(edx, imm8(0))
+##            mc.MOV(tmp, op2)
+##            mc.IDIV(tmp)
+##        else:
+##            # subtract 1 to the result if the operand signs differ and
+##            # the remainder is not zero
+##            mc.MOV(tmp, eax)
+##            mc.IDIV(op2)
+##            mc.XOR(tmp, op2)
+##            mc.SAR(tmp, imm8(31)) # -1 if signs differ, 0 otherwise
+##            mc.AND(tmp, edx)      # nonnull if signs differ and edx != 0
+##            mc.CMP(tmp, imm8(1))  # no carry flag iff signs differ and edx != 0
+##            mc.ADC(eax, imm8(-1)) # subtract 1 iff no carry flag
+##        allocator.end_clobber(tmp)
+
+##class OpIntMod(MulOrDivOp):
+##    opname = 'int_mod'
+##    input_is_64bits = True
+##    reg_containing_result = edx
+##    unsigned = False
+
+##    def generate2(self, allocator, op2):
+##        #                 Python    i386
+##        #    20/3    =     6, 2     6, 2
+##        # (-20)/3    =    -7, 1    -6,-2      # operand signs differ
+##        #    20/(-3) =    -7,-1    -6, 2      # operand signs differ
+##        # (-20)/(-3) =     6,-2     6,-2
+##        #
+##        tmp = allocator.create_scratch_reg()
+##        mc = allocator.mc
+##        if isinstance(op2, IMM32):   XXX
+##            mc.MOV(tmp, op2)
+##            mc.IDIV(tmp)
+##            # adjustment needed:
+##            #   if op2 > 0: if the result is negative, add op2 to it
+##            #   if op2 < 0: if the result is > 0, subtract |op2| from it
+##            mc.MOV(tmp, edx)
+##            if op2.value < 0:
+##                mc.NEG(tmp)
+##            mc.SAR(tmp, imm8(31))
+##            mc.AND(tmp, imm(op2.value))
+##            mc.ADD(edx, tmp)
+##        else:
+##            # if the operand signs differ and the remainder is not zero,
+##            # add operand2 to the result
+##            mc.MOV(tmp, eax)
+##            mc.IDIV(op2)
+##            mc.XOR(tmp, op2)
+##            mc.SAR(tmp, imm8(31)) # -1 if signs differ, 0 otherwise
+##            mc.AND(tmp, edx)      # nonnull if signs differ and edx != 0
+##            mc.CMOVNZ(tmp, op2)   # == op2  if signs differ and edx != 0
+##            mc.ADD(edx, tmp)
+##        allocator.end_clobber(tmp)
 
 class OpUIntMul(MulOrDivOp):
     opname = 'uint_mul'
@@ -411,6 +421,22 @@
     def generate2(self, allocator, op2):
         allocator.mc.DIV(op2)
 
+class OpIntFloorDiv(MulOrDivOp):
+    opname = 'int_floordiv'
+    input_is_64bits = True
+    reg_containing_result = eax
+    unsigned = False
+    def generate2(self, allocator, op2):
+        allocator.mc.IDIV(op2)
+
+class OpIntMod(MulOrDivOp):
+    opname = 'int_mod'
+    input_is_64bits = True
+    reg_containing_result = edx
+    unsigned = False
+    def generate2(self, allocator, op2):
+        allocator.mc.IDIV(op2)
+
 class OpShift(Op2):
     side_effects = False
     countmax31 = False

Modified: pypy/dist/pypy/jit/codegen/test/operation_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/operation_tests.py	(original)
+++ pypy/dist/pypy/jit/codegen/test/operation_tests.py	Sun Mar 18 15:13:23 2007
@@ -339,6 +339,11 @@
                 for operand1 in range(-33, 34):
                     res = fp(operand1)
                     assert res == eval(op, {'x': operand1, 'y': constant})
+                fp = self.rgen(fn, [r_uint], r_uint)
+                for operand1 in range(-33, 34):
+                    res = r_uint(fp(r_uint(operand1)))
+                    assert res == eval(op, {'x': r_uint(operand1),
+                                            'y': r_uint(constant)})
 
     def test_constants_in_divmod(self):
         for op in ['x // y', 'x % y']:
@@ -348,6 +353,11 @@
                 for operand1 in range(-32, 33):
                     res = fp(operand1)
                     assert res == eval(op, {'x': operand1, 'y': constant})
+                fp = self.rgen(fn, [r_uint], r_uint)
+                for operand1 in range(-32, 33):
+                    res = r_uint(fp(r_uint(operand1)))
+                    assert res == eval(op, {'x': r_uint(operand1),
+                                            'y': r_uint(constant)})
 
     def test_ptr_comparison(self):
         S = lltype.GcStruct('S')



More information about the Pypy-commit mailing list