[pypy-svn] pypy default: Fix for the test. It's a bit roundabout and inefficient, but on

arigo commits-noreply at bitbucket.org
Mon Mar 14 22:05:01 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r42649:87ddbaa99b34
Date: 2011-03-14 16:57 -0400
http://bitbucket.org/pypy/pypy/changeset/87ddbaa99b34/

Log:	Fix for the test. It's a bit roundabout and inefficient, but on the
	other hand it looks like a rare case anyway, otherwise we would have
	found the bug much earlier.

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
@@ -69,3 +69,41 @@
         assembler.regalloc_mov(src, tmpreg)
         src = tmpreg
     assembler.regalloc_mov(src, dst)
+
+def remap_frame_layout_mixed(assembler,
+                             src_locations1, dst_locations1, tmpreg1,
+                             src_locations2, dst_locations2, tmpreg2):
+    # find and push the xmm stack locations from src_locations2 that
+    # are going to be overwritten by dst_locations1
+    from pypy.jit.backend.x86.arch import WORD
+    extrapushes = []
+    dst_keys = {}
+    for loc in dst_locations1:
+        dst_keys[loc._getregkey()] = None
+    src_locations2red = []
+    dst_locations2red = []
+    for i in range(len(src_locations2)):
+        loc    = src_locations2[i]
+        dstloc = dst_locations2[i]
+        if isinstance(loc, StackLoc):
+            key = loc._getregkey()
+            if (key in dst_keys or (loc.width > WORD and
+                                    (key + WORD) in dst_keys)):
+                assembler.regalloc_push(loc)
+                extrapushes.append(dstloc)
+                continue
+        src_locations2red.append(loc)
+        dst_locations2red.append(dstloc)
+    src_locations2 = src_locations2red
+    dst_locations2 = dst_locations2red
+    #
+    # remap the integer and pointer registers and stack locations
+    remap_frame_layout(assembler, src_locations1, dst_locations1, tmpreg1)
+    #
+    # remap the xmm registers and stack locations
+    remap_frame_layout(assembler, src_locations2, dst_locations2, tmpreg2)
+    #
+    # finally, pop the extra xmm stack locations
+    while len(extrapushes) > 0:
+        loc = extrapushes.pop()
+        assembler.regalloc_pop(loc)

diff --git a/pypy/jit/backend/x86/test/test_jump.py b/pypy/jit/backend/x86/test/test_jump.py
--- a/pypy/jit/backend/x86/test/test_jump.py
+++ b/pypy/jit/backend/x86/test/test_jump.py
@@ -2,6 +2,7 @@
 from pypy.jit.backend.x86.regloc import *
 from pypy.jit.backend.x86.regalloc import X86FrameManager
 from pypy.jit.backend.x86.jump import remap_frame_layout
+from pypy.jit.backend.x86.jump import remap_frame_layout_mixed
 from pypy.jit.metainterp.history import INT
 
 frame_pos = X86FrameManager.frame_pos
@@ -144,6 +145,64 @@
                              ('mov', ebx, s12),
                              ('pop', ebx)]
 
+def test_mixed():
+    assembler = MockAssembler()
+    s23 = frame_pos(2, FLOAT)     # non-conflicting locations
+    s4  = frame_pos(4, INT)
+    remap_frame_layout_mixed(assembler, [ebx], [s4], 'tmp',
+                                        [s23], [xmm5], 'xmmtmp')
+    assert assembler.ops == [('mov', ebx, s4),
+                             ('mov', s23, xmm5)]
+    #
+    if IS_X86_32:
+        assembler = MockAssembler()
+        s23 = frame_pos(2, FLOAT)  # gets stored in pos 2 and 3, with value==3
+        s3  = frame_pos(3, INT)
+        remap_frame_layout_mixed(assembler, [ebx], [s3], 'tmp',
+                                            [s23], [xmm5], 'xmmtmp')
+        assert assembler.ops == [('push', s23),
+                                 ('mov', ebx, s3),
+                                 ('pop', xmm5)]
+    #
+    assembler = MockAssembler()
+    s23 = frame_pos(2, FLOAT)
+    s2  = frame_pos(2, INT)
+    remap_frame_layout_mixed(assembler, [ebx], [s2], 'tmp',
+                                        [s23], [xmm5], 'xmmtmp')
+    assert assembler.ops == [('push', s23),
+                             ('mov', ebx, s2),
+                             ('pop', xmm5)]
+    #
+    assembler = MockAssembler()
+    s4  = frame_pos(4, INT)
+    s45 = frame_pos(4, FLOAT)
+    s1  = frame_pos(1, INT)
+    remap_frame_layout_mixed(assembler, [s4], [s1], edi,
+                                        [s23], [s45], xmm3)
+    assert assembler.ops == [('mov', s4, edi),
+                             ('mov', edi, s1),
+                             ('mov', s23, xmm3),
+                             ('mov', xmm3, s45)]
+    #
+    assembler = MockAssembler()
+    s4  = frame_pos(4, INT)
+    s45 = frame_pos(4, FLOAT)
+    remap_frame_layout_mixed(assembler, [s4], [s2], edi,
+                                        [s23], [s45], xmm3)
+    assert assembler.ops == [('push', s23),
+                             ('mov', s4, edi),
+                             ('mov', edi, s2),
+                             ('pop', s45)]
+    #
+    if IS_X86_32:
+        assembler = MockAssembler()
+        remap_frame_layout_mixed(assembler, [s4], [s3], edi,
+                                 [s23], [s45], xmm3)
+        assert assembler.ops == [('push', s23),
+                                 ('mov', s4, edi),
+                                 ('mov', edi, s3),
+                                 ('pop', s45)]
+
 def test_random_mixed():
     assembler = MockAssembler()
     registers1 = [eax, ebx, ecx]
@@ -212,18 +271,16 @@
                 assert isinstance(loc, ImmedLoc)
         return regs1, regs2, stack
     #
-    for i in range(1000):
+    for i in range(500):
         seen = {}
+        src_locations2 = [pick2() for i in range(4)]
+        dst_locations2 = pick_dst(pick2, 4, seen)
         src_locations1 = [pick1c() for i in range(5)]
         dst_locations1 = pick_dst(pick1, 5, seen)
-        src_locations2 = [pick2() for i in range(4)]
-        dst_locations2 = pick_dst(pick2, 4, seen)
         assembler = MockAssembler()
-        #remap_frame_layout_mixed(assembler,
-        #                         src_locations1, dst_locations1, edi,
-        #                         src_locations2, dst_locations2, xmm7)
-        remap_frame_layout(assembler, src_locations1, dst_locations1, edi)
-        remap_frame_layout(assembler, src_locations2, dst_locations2, xmm7)
+        remap_frame_layout_mixed(assembler,
+                                 src_locations1, dst_locations1, edi,
+                                 src_locations2, dst_locations2, xmm7)
         #
         regs1, regs2, stack = get_state(src_locations1 +
                                         src_locations2)

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
@@ -11,7 +11,7 @@
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rlib import rgc
 from pypy.jit.backend.llsupport import symbolic
-from pypy.jit.backend.x86.jump import remap_frame_layout
+from pypy.jit.backend.x86.jump import remap_frame_layout_mixed
 from pypy.jit.codewriter import heaptracker, longlong
 from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.metainterp.resoperation import rop
@@ -1172,16 +1172,17 @@
         xmmtmploc = self.xrm.force_allocate_reg(box1, selected_reg=xmmtmp)
         # Part about non-floats
         # XXX we don't need a copy, we only just the original list
-        src_locations = [self.loc(op.getarg(i)) for i in range(op.numargs()) 
+        src_locations1 = [self.loc(op.getarg(i)) for i in range(op.numargs()) 
                          if op.getarg(i).type != FLOAT]
         assert tmploc not in nonfloatlocs
-        dst_locations = [loc for loc in nonfloatlocs if loc is not None]
-        remap_frame_layout(assembler, src_locations, dst_locations, tmploc)
+        dst_locations1 = [loc for loc in nonfloatlocs if loc is not None]
         # Part about floats
-        src_locations = [self.loc(op.getarg(i)) for i in range(op.numargs()) 
+        src_locations2 = [self.loc(op.getarg(i)) for i in range(op.numargs()) 
                          if op.getarg(i).type == FLOAT]
-        dst_locations = [loc for loc in floatlocs if loc is not None]
-        remap_frame_layout(assembler, src_locations, dst_locations, xmmtmp)
+        dst_locations2 = [loc for loc in floatlocs if loc is not None]
+        remap_frame_layout_mixed(assembler,
+                                 src_locations1, dst_locations1, tmploc,
+                                 src_locations2, dst_locations2, xmmtmp)
         self.rm.possibly_free_var(box)
         self.xrm.possibly_free_var(box1)
         self.possibly_free_vars_for_op(op)


More information about the Pypy-commit mailing list