[pypy-svn] r69870 - in pypy/trunk/pypy/jit/backend/x86: . test

arigo at codespeak.net arigo at codespeak.net
Thu Dec 3 16:05:50 CET 2009


Author: arigo
Date: Thu Dec  3 16:05:49 2009
New Revision: 69870

Modified:
   pypy/trunk/pypy/jit/backend/x86/assembler.py
   pypy/trunk/pypy/jit/backend/x86/regalloc.py
   pypy/trunk/pypy/jit/backend/x86/ri386setup.py
   pypy/trunk/pypy/jit/backend/x86/test/test_ztranslation.py
Log:
Kill the hacks to get the constants for neg and abs.  Enhance a test
to shows why such hacks are not working when translated.  Replace
them with a proper 16-bytes-aligned buffer, only in assembler.py,
not in regalloc.py.


Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/assembler.py	Thu Dec  3 16:05:49 2009
@@ -90,6 +90,8 @@
         self.fail_boxes_ptr = NonmovableGrowableArrayGCREF()
         self.fail_boxes_float = NonmovableGrowableArrayFloat()
         self.fail_ebp = 0
+        self.loc_float_const_neg = None
+        self.loc_float_const_abs = None
         self.setup_failure_recovery()
 
     def leave_jitted_hook(self):
@@ -130,6 +132,26 @@
                 self._build_failure_recovery(False, withfloats=True)
                 self._build_failure_recovery(True, withfloats=True)
                 codebuf.ensure_sse2_floats()
+                self._build_float_constants()
+
+    def _build_float_constants(self):
+        # 11 words: 8 words for the data, and up to 3 words for alignment
+        addr = lltype.malloc(rffi.CArray(lltype.Signed), 11, flavor='raw')
+        if not we_are_translated():
+            self._keepalive_malloced_float_consts = addr
+        float_constants = rffi.cast(lltype.Signed, addr)
+        float_constants = (float_constants + 15) & ~15    # align to 16 bytes
+        addr = rffi.cast(rffi.CArrayPtr(lltype.Signed), float_constants)
+        addr[0] = 0                # \
+        addr[1] = -2147483648      # / for neg
+        addr[2] = 0                #
+        addr[3] = 0                #
+        addr[4] = -1               # \
+        addr[5] = 2147483647       # / for abs
+        addr[6] = 0                #
+        addr[7] = 0                #
+        self.loc_float_const_neg = heap64(float_constants)
+        self.loc_float_const_abs = heap64(float_constants + 16)
 
     def assemble_loop(self, inputargs, operations, looptoken):
         """adds the following attributes to looptoken:
@@ -445,15 +467,13 @@
     genop_guard_uint_le = _cmpop_guard("BE", "AE", "A", "B")
     genop_guard_uint_ge = _cmpop_guard("AE", "BE", "B", "A")
 
-    # for now all chars are being considered ints, although we should make
-    # a difference at some point
-    xxx_genop_char_eq = genop_int_eq
-
     def genop_float_neg(self, op, arglocs, resloc):
-        self.mc.XORPD(arglocs[0], arglocs[1])
+        # Following what gcc does: res = x ^ 0x8000000000000000
+        self.mc.XORPD(arglocs[0], self.loc_float_const_neg)
 
     def genop_float_abs(self, op, arglocs, resloc):
-        self.mc.ANDPD(arglocs[0], arglocs[1])
+        # Following what gcc does: res = x & 0x7FFFFFFFFFFFFFFF
+        self.mc.ANDPD(arglocs[0], self.loc_float_const_abs)
 
     def genop_float_is_true(self, op, arglocs, resloc):
         loc0, loc1 = arglocs

Modified: pypy/trunk/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/regalloc.py	Thu Dec  3 16:05:49 2009
@@ -54,15 +54,6 @@
 
 BASE_CONSTANT_SIZE = 1000
 
-# cheat cheat cheat....
-#  why not -0.0? People tell me it's platform-dependent
-#  nan is not portable
-import struct
-NEG_ZERO, = struct.unpack('d', struct.pack('ll', 0, -2147483648))
-NAN, = struct.unpack('d', struct.pack('ll', -1, 2147483647))
-# XXX These are actually masks for float_neg and float_abs.
-# They should not be converted to 'double' and given
-# names that reflect their float value.
 
 class X86XMMRegisterManager(RegisterManager):
 
@@ -80,9 +71,7 @@
         RegisterManager.__init__(self, longevity, stack_manager=stack_manager,
                                  assembler=assembler)
         self.constant_arrays = [self.new_const_array()]
-        self.constant_arrays[-1][0] = NEG_ZERO
-        self.constant_arrays[-1][1] = NAN
-        self.constant_array_counter = 2
+        self.constant_array_counter = 0
 
     def convert_to_imm(self, c):
         if self.constant_array_counter >= BASE_CONSTANT_SIZE:
@@ -564,28 +553,13 @@
     consider_float_ge = _consider_float_cmp
 
     def consider_float_neg(self, op, ignored):
-        # Following what gcc does...
-        # XXX we can ignore having constant in a reg, but we need
-        #     to be careful with 128-bit alignment
         loc0 = self.xrm.force_result_in_reg(op.result, op.args[0])
-        constloc = self.xrm.get_addr_of_const_float(0, 0)
-        tmpbox = TempBox()
-        loc1 = self.xrm.force_allocate_reg(tmpbox, op.args)
-        self.assembler.regalloc_mov(constloc, loc1)
-        self.Perform(op, [loc0, loc1], loc0)
-        self.xrm.possibly_free_var(tmpbox)
+        self.Perform(op, [loc0], loc0)
         self.xrm.possibly_free_var(op.args[0])
 
     def consider_float_abs(self, op, ignored):
-        # XXX we can ignore having constant in a reg, but we need
-        #     to be careful with 128-bit alignment
         loc0 = self.xrm.force_result_in_reg(op.result, op.args[0])
-        constloc = self.xrm.get_addr_of_const_float(0, 1)
-        tmpbox = TempBox()
-        loc1 = self.xrm.force_allocate_reg(tmpbox, op.args)
-        self.assembler.regalloc_mov(constloc, loc1)
-        self.Perform(op, [loc0, loc1], loc0)
-        self.xrm.possibly_free_var(tmpbox)
+        self.Perform(op, [loc0], loc0)
         self.xrm.possibly_free_var(op.args[0])
 
     def consider_float_is_true(self, op, ignored):

Modified: pypy/trunk/pypy/jit/backend/x86/ri386setup.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/ri386setup.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/ri386setup.py	Thu Dec  3 16:05:49 2009
@@ -541,13 +541,11 @@
 UCOMISD = Instruction()
 UCOMISD.mode2(XMMREG, MODRM64, ['\x66\x0F\x2E', register(1, 8), modrm(2)])
 
-XORPD = Instruction()
-XORPD.mode2(XMMREG, XMMREG, ['\x66\x0f\x57', register(1, 8), register(2),
-                            '\xC0'])
+XORPD = Instruction()  # warning: a memory argument must be aligned to 16 bytes
+XORPD.mode2(XMMREG, MODRM64, ['\x66\x0f\x57', register(1, 8), modrm(2)])
 
-ANDPD = Instruction()
-ANDPD.mode2(XMMREG, XMMREG, ['\x66\x0F\x54', register(1, 8), register(2),
-                             '\xC0'])
+ANDPD = Instruction()  # warning: a memory argument must be aligned to 16 bytes
+ANDPD.mode2(XMMREG, MODRM64, ['\x66\x0F\x54', register(1, 8), modrm(2)])
 
 CVTTSD2SI = Instruction()
 CVTTSD2SI.mode2(REG, XMMREG, ['\xF2\x0F\x2C', register(1, 8), register(2),

Modified: pypy/trunk/pypy/jit/backend/x86/test/test_ztranslation.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/test/test_ztranslation.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/test/test_ztranslation.py	Thu Dec  3 16:05:49 2009
@@ -22,6 +22,7 @@
         # - set_param interface
         # - profiler
         # - full optimizer
+        # - floats neg and abs
 
         class Frame(object):
             _virtualizable2_ = ['i']
@@ -29,9 +30,14 @@
             def __init__(self, i):
                 self.i = i
 
-        jitdriver = JitDriver(greens = [], reds = ['frame', 'total'],
+        @dont_look_inside
+        def myabs(x):
+            return abs(x)
+
+        jitdriver = JitDriver(greens = [],
+                              reds = ['frame', 'total', 'j'],
                               virtualizables = ['frame'])
-        def f(i):
+        def f(i, j):
             for param in unroll_parameters:
                 defl = PARAMETERS[param]
                 jitdriver.set_param(param, defl)
@@ -40,15 +46,20 @@
             total = 0
             frame = Frame(i)
             while frame.i > 3:
-                jitdriver.can_enter_jit(frame=frame, total=total)
-                jitdriver.jit_merge_point(frame=frame, total=total)
+                jitdriver.can_enter_jit(frame=frame, total=total, j=j)
+                jitdriver.jit_merge_point(frame=frame, total=total, j=j)
                 total += frame.i
                 if frame.i >= 20:
                     frame.i -= 2
                 frame.i -= 1
+                j *= -0.712
+                if j + (-j):    raise ValueError
+                k = myabs(j)
+                if k - abs(j):  raise ValueError
+                if k - abs(-j): raise ValueError
             return total * 10
-        res = self.meta_interp(f, [40])
-        assert res == f(40)
+        res = self.meta_interp(f, [40, -49])
+        assert res == f(40, -49)
 
     def test_external_exception_handling_translates(self):
         jitdriver = JitDriver(greens = [], reds = ['n', 'total'])



More information about the Pypy-commit mailing list