[pypy-commit] pypy default: Fix, as shown by test_zll_stress.

arigo noreply at buildbot.pypy.org
Wed Dec 14 12:35:05 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r50498:0fe404e7740d
Date: 2011-12-14 12:17 +0100
http://bitbucket.org/pypy/pypy/changeset/0fe404e7740d/

Log:	Fix, as shown by test_zll_stress.

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
@@ -38,6 +38,7 @@
 from pypy.jit.backend.x86.jump import remap_frame_layout
 from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.codewriter import longlong
+from pypy.rlib.rarithmetic import intmask
 
 # darwin requires the stack to be 16 bytes aligned on calls. Same for gcc 4.5.0,
 # better safe than sorry
@@ -855,6 +856,18 @@
         else:
             self.mc.POP(loc)
 
+    def regalloc_immedmem2mem(self, from_loc, to_loc):
+        # move a ConstFloatLoc directly to a StackLoc, as two MOVs
+        # (even on x86-64, because the immediates are encoded as 32 bits)
+        assert isinstance(from_loc, ConstFloatLoc)
+        assert isinstance(to_loc,   StackLoc)
+        low_part  = rffi.cast(rffi.CArrayPtr(rffi.INT), from_loc.value)[0]
+        high_part = rffi.cast(rffi.CArrayPtr(rffi.INT), from_loc.value)[1]
+        low_part  = intmask(low_part)
+        high_part = intmask(high_part)
+        self.mc.MOV_bi(to_loc.value,     low_part)
+        self.mc.MOV_bi(to_loc.value + 4, high_part)
+
     def regalloc_perform(self, op, arglocs, resloc):
         genop_list[op.getopnum()](self, op, arglocs, resloc)
 
diff --git a/pypy/jit/backend/x86/jump.py b/pypy/jit/backend/x86/jump.py
--- a/pypy/jit/backend/x86/jump.py
+++ b/pypy/jit/backend/x86/jump.py
@@ -1,6 +1,6 @@
 import sys
 from pypy.tool.pairtype import extendabletype
-from pypy.jit.backend.x86.regloc import ImmedLoc, StackLoc
+from pypy.jit.backend.x86.regloc import ImmediateAssemblerLocation, StackLoc
 
 def remap_frame_layout(assembler, src_locations, dst_locations, tmpreg):
     pending_dests = len(dst_locations)
@@ -12,7 +12,7 @@
         srccount[key] = 0
     for i in range(len(dst_locations)):
         src = src_locations[i]
-        if isinstance(src, ImmedLoc):
+        if isinstance(src, ImmediateAssemblerLocation):
             continue
         key = src._getregkey()
         if key in srccount:
@@ -31,7 +31,7 @@
                 srccount[key] = -1       # means "it's done"
                 pending_dests -= 1
                 src = src_locations[i]
-                if not isinstance(src, ImmedLoc):
+                if not isinstance(src, ImmediateAssemblerLocation):
                     key = src._getregkey()
                     if key in srccount:
                         srccount[key] -= 1
@@ -66,6 +66,9 @@
 
 def _move(assembler, src, dst, tmpreg):
     if dst.is_memory_reference() and src.is_memory_reference():
+        if isinstance(src, ImmediateAssemblerLocation):
+            assembler.regalloc_immedmem2mem(src, dst)
+            return
         if tmpreg is None:
             assembler.regalloc_push(src)
             assembler.regalloc_pop(dst)
diff --git a/pypy/jit/backend/x86/regloc.py b/pypy/jit/backend/x86/regloc.py
--- a/pypy/jit/backend/x86/regloc.py
+++ b/pypy/jit/backend/x86/regloc.py
@@ -44,6 +44,10 @@
     _location_code = 'b'
 
     def __init__(self, position, ebp_offset, num_words, type):
+        # _getregkey() returns self.value; the value returned must not
+        # conflict with RegLoc._getregkey().  It doesn't a bit by chance,
+        # so let it fail the following assert if it no longer does.
+        assert not (0 <= ebp_offset < 8 + 8 * IS_X86_64)
         self.position = position
         self.value = ebp_offset
         self.width = num_words * WORD
@@ -91,7 +95,10 @@
         else:
             return eax
 
-class ImmedLoc(AssemblerLocation):
+class ImmediateAssemblerLocation(AssemblerLocation):
+    _immutable_ = True
+
+class ImmedLoc(ImmediateAssemblerLocation):
     _immutable_ = True
     width = WORD
     _location_code = 'i'
@@ -179,7 +186,7 @@
             raise AssertionError(self._location_code)
         return result
 
-class ConstFloatLoc(AssemblerLocation):
+class ConstFloatLoc(ImmediateAssemblerLocation):
     # XXX: We have to use this class instead of just AddressLoc because
     # we want a width of 8  (... I think.  Check this!)
     _immutable_ = True
@@ -193,7 +200,7 @@
         return '<ConstFloatLoc @%s>' % (self.value,)
 
 if IS_X86_32:
-    class FloatImmedLoc(AssemblerLocation):
+    class FloatImmedLoc(ImmediateAssemblerLocation):
         # This stands for an immediate float.  It cannot be directly used in
         # any assembler instruction.  Instead, it is meant to be decomposed
         # in two 32-bit halves.  On 64-bit, FloatImmedLoc() is a function


More information about the pypy-commit mailing list