[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