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

arigo at codespeak.net arigo at codespeak.net
Fri Sep 24 15:39:38 CEST 2010


Author: arigo
Date: Fri Sep 24 15:39:37 2010
New Revision: 77343

Modified:
   pypy/trunk/pypy/jit/backend/x86/regloc.py
   pypy/trunk/pypy/jit/backend/x86/test/test_regloc.py
Log:
Test and fix for rare cases that use unsupported 64-bit immediates.


Modified: pypy/trunk/pypy/jit/backend/x86/regloc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/regloc.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/regloc.py	Fri Sep 24 15:39:37 2010
@@ -137,6 +137,12 @@
                 self._location_code = 'a'
                 self.loc_a = (base_loc.value, scaled_loc.value, scale, static_offset)
 
+    def __repr__(self):
+        dict = {'j': 'value', 'a': 'loc_a', 'm': 'loc_m', 'a':'loc_a'}
+        attr = dict.get(self._location_code, '?')
+        info = getattr(self, attr, '?')
+        return '<AddressLoc %r: %s>' % (self._location_code, info)
+
     def location_code(self):
         return self._location_code
 
@@ -159,6 +165,9 @@
         self.value = address
         self.const_id = const_id
 
+    def __repr__(self):
+        return '<ConstFloatLoc(%s, %s)>' % (self.value, self.const_id)
+
     def _getregkey(self):
         # XXX: 1000 is kind of magic: We just don't want to be confused
         # with any registers
@@ -248,6 +257,14 @@
                                 methname = name + "_" + possible_code1 + "m"
                                 _rx86_getattr(self, methname)(val1, reg_offset)
                             else:
+                                if possible_code1 == 'm' and not rx86.fits_in_32bits(val1[1]):
+                                    val1 = self._fix_static_offset_64_m(val1)
+                                if possible_code2 == 'm' and not rx86.fits_in_32bits(val2[1]):
+                                    val2 = self._fix_static_offset_64_m(val2)
+                                if possible_code1 == 'a' and not rx86.fits_in_32bits(val1[3]):
+                                    val1 = self._fix_static_offset_64_a(val1)
+                                if possible_code2 == 'a' and not rx86.fits_in_32bits(val2[3]):
+                                    val2 = self._fix_static_offset_64_a(val2)
                                 methname = name + "_" + possible_code1 + possible_code2
                                 _rx86_getattr(self, methname)(val1, val2)
 
@@ -317,6 +334,34 @@
         self.MOV_ri(X86_64_SCRATCH_REG.value, addr)
         return (X86_64_SCRATCH_REG.value, 0)
 
+    def _fix_static_offset_64_m(self, (basereg, static_offset)):
+        # For cases where an AddressLoc has the location_code 'm', but
+        # where the static offset does not fit in 32-bits.  We have to fall
+        # back to the X86_64_SCRATCH_REG.  It is even more annoying because
+        # we want to keep using the mode 'm'.  These are all possibly rare
+        # cases; don't try to reuse a past value of the scratch register at
+        # all.
+        self._scratch_register_known = False
+        self.MOV_ri(X86_64_SCRATCH_REG.value, static_offset)
+        self.LEA_ra(X86_64_SCRATCH_REG.value,
+                    (basereg, X86_64_SCRATCH_REG.value, 0, 0))
+        return (X86_64_SCRATCH_REG.value, 0)
+
+    def _fix_static_offset_64_a(self, (basereg, scalereg,
+                                       scale, static_offset)):
+        # For cases where an AddressLoc has the location_code 'a', but
+        # where the static offset does not fit in 32-bits.  We have to fall
+        # back to the X86_64_SCRATCH_REG.  In one case it is even more
+        # annoying.  These are all possibly rare cases; don't try to reuse a
+        # past value of the scratch register at all.
+        self._scratch_register_known = False
+        self.MOV_ri(X86_64_SCRATCH_REG.value, static_offset)
+        #
+        if basereg != rx86.NO_BASE_REGISTER:
+            self.LEA_ra(X86_64_SCRATCH_REG.value,
+                        (basereg, X86_64_SCRATCH_REG.value, 0, 0))
+        return (X86_64_SCRATCH_REG.value, scalereg, scale, 0)
+
     def begin_reuse_scratch_register(self):
         # Flag the beginning of a block where it is okay to reuse the value
         # of the scratch register. In theory we shouldn't have to do this if

Modified: pypy/trunk/pypy/jit/backend/x86/test/test_regloc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/test/test_regloc.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/test/test_regloc.py	Fri Sep 24 15:39:37 2010
@@ -58,82 +58,91 @@
     expected_ofs = pos_addr - (neg_addr+5)
     assert s.getvalue() == '\xE9' + struct.pack("<i", expected_ofs)
 
-def test_reuse_scratch_register():
-    if not IS_X86_64:
-        py.test.skip()
-
-    base_addr = 0xFEDCBA9876543210
-    cb = LocationCodeBuilder64()
-    cb.begin_reuse_scratch_register()
-    cb.MOV(ecx, heap(base_addr))
-    cb.MOV(ecx, heap(base_addr + 8))
-    cb.end_reuse_scratch_register()
-
-    expected_instructions = (
-            # mov r11, 0xFEDCBA9876543210
-            '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE' +
-            # mov rcx, [r11]
-            '\x49\x8B\x0B' +
-            # mov rcx, [r11+8]
-            '\x49\x8B\x4B\x08'
-    )
-    assert cb.getvalue() == expected_instructions
-
-def test_64bit_address_1():
-    base_addr = 0xFEDCBA9876543210
-    cb = LocationCodeBuilder64()
-    cb.CMP(ecx, AddressLoc(ImmedLoc(0), ImmedLoc(0), 0, base_addr))
-    #
-    expected_instructions = (
-            # mov r11, 0xFEDCBA9876543210
-            '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
-            # cmp rcx, [r11]
-            '\x49\x3B\x0B'
-    )
-    assert cb.getvalue() == expected_instructions
-
-def test_64bit_address_2():
-    base_addr = 0xFEDCBA9876543210
-    cb = LocationCodeBuilder64()
-    cb.MOV(ecx, AddressLoc(ImmedLoc(0), edx, 3, base_addr))
-    #
-    expected_instructions = (
-            # mov r11, 0xFEDCBA9876543210
-            '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
-            # mov rcx, [r11+8*rdx]
-            '\x49\x8B\x0C\xD3'
-    )
-    assert cb.getvalue() == expected_instructions
-
-def test_64bit_address_3():
-    base_addr = 0xFEDCBA9876543210
-    cb = LocationCodeBuilder64()
-    cb.MOV(ecx, AddressLoc(edx, ImmedLoc(0), 0, base_addr))
-    #
-    expected_instructions = (
-            # mov r11, 0xFEDCBA9876543210
-            '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
-            # mov rcx, [rdx+r11]
-            '\x4A\x8B\x0C\x1A'
-    )
-    assert cb.getvalue() == expected_instructions
-
-def test_64bit_address_4():
-    base_addr = 0xFEDCBA9876543210
-    cb = LocationCodeBuilder64()
-    cb.begin_reuse_scratch_register()
-    assert cb._reuse_scratch_register is True
-    assert cb._scratch_register_known is False
-    cb.MOV(ecx, AddressLoc(edx, esi, 2, base_addr))
-    assert cb._reuse_scratch_register is True
-    assert cb._scratch_register_known is False
-    #
-    expected_instructions = (
-            # mov r11, 0xFEDCBA9876543210
-            '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
-            # lea r11, [rdx+r11]
-            '\x4E\x8D\x1C\x1A'
-            # mov rcx, [r11+4*rsi]
-            '\x49\x8B\x0C\xB3'
-    )
-    assert cb.getvalue() == expected_instructions
+
+class Test64Bits:
+
+    def setup_class(cls):
+        if not IS_X86_64:
+            py.test.skip()
+
+    def test_reuse_scratch_register(self):
+        base_addr = 0xFEDCBA9876543210
+        cb = LocationCodeBuilder64()
+        cb.begin_reuse_scratch_register()
+        cb.MOV(ecx, heap(base_addr))
+        cb.MOV(ecx, heap(base_addr + 8))
+        cb.end_reuse_scratch_register()
+
+        expected_instructions = (
+                # mov r11, 0xFEDCBA9876543210
+                '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE' +
+                # mov rcx, [r11]
+                '\x49\x8B\x0B' +
+                # mov rcx, [r11+8]
+                '\x49\x8B\x4B\x08'
+        )
+        assert cb.getvalue() == expected_instructions
+
+    def test_64bit_address_1(self):
+        base_addr = 0xFEDCBA9876543210
+        cb = LocationCodeBuilder64()
+        cb.CMP(ecx, AddressLoc(ImmedLoc(0), ImmedLoc(0), 0, base_addr))
+        #
+        expected_instructions = (
+                # mov r11, 0xFEDCBA9876543210
+                '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
+                # cmp rcx, [r11]
+                '\x49\x3B\x0B'
+        )
+        assert cb.getvalue() == expected_instructions
+
+    def test_64bit_address_2(self):
+        base_addr = 0xFEDCBA9876543210
+        cb = LocationCodeBuilder64()
+        cb.MOV(ecx, AddressLoc(ImmedLoc(0), edx, 3, base_addr))
+        #
+        expected_instructions = (
+                # mov r11, 0xFEDCBA9876543210
+                '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
+                # mov rcx, [r11+8*rdx]
+                '\x49\x8B\x0C\xD3'
+        )
+        assert cb.getvalue() == expected_instructions
+
+    def test_64bit_address_3(self):
+        base_addr = 0xFEDCBA9876543210
+        cb = LocationCodeBuilder64()
+        cb.MOV(ecx, AddressLoc(edx, ImmedLoc(0), 0, base_addr))
+        #
+        # sub-efficient instruction generated in that particular case:
+        # the LEA is not really needed, but it's useful because we can
+        # keep the same mode 'm' for generating the final instruction
+        expected_instructions = (
+                # mov r11, 0xFEDCBA9876543210
+                '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
+                # lea r11, [rdx+r11]
+                '\x4E\x8D\x1C\x1A'
+                # mov rcx, [r11]
+                '\x49\x8B\x0B'
+        )
+        assert cb.getvalue() == expected_instructions
+
+    def test_64bit_address_4(self):
+        base_addr = 0xFEDCBA9876543210
+        cb = LocationCodeBuilder64()
+        cb.begin_reuse_scratch_register()
+        assert cb._reuse_scratch_register is True
+        assert cb._scratch_register_known is False
+        cb.MOV(ecx, AddressLoc(edx, esi, 2, base_addr))
+        assert cb._reuse_scratch_register is True
+        assert cb._scratch_register_known is False
+        #
+        expected_instructions = (
+                # mov r11, 0xFEDCBA9876543210
+                '\x49\xBB\x10\x32\x54\x76\x98\xBA\xDC\xFE'
+                # lea r11, [rdx+r11]
+                '\x4E\x8D\x1C\x1A'
+                # mov rcx, [r11+4*rsi]
+                '\x49\x8B\x0C\xB3'
+        )
+        assert cb.getvalue() == expected_instructions



More information about the Pypy-commit mailing list