[pypy-svn] r76291 - in pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86: . test
jcreigh at codespeak.net
jcreigh at codespeak.net
Tue Jul 20 16:42:50 CEST 2010
Author: jcreigh
Date: Tue Jul 20 16:42:49 2010
New Revision: 76291
Modified:
pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/assembler.py
pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/regloc.py
pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/test/test_assembler.py
Log:
try to be a bit safer about scratch register use
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/assembler.py Tue Jul 20 16:42:49 2010
@@ -92,8 +92,19 @@
def make_new_mc(self):
new_mc = self._instantiate_mc()
debug_print('[new machine code block at', new_mc.tell(), ']')
+
+ if IS_X86_64:
+ # The scratch register is sometimes used as a temporary
+ # register, but the JMP below might clobber it. Rather than risk
+ # subtle bugs, we preserve the scratch register across the jump.
+ self._mc.PUSH_r(X86_64_SCRATCH_REG.value)
+
self._mc.JMP(imm(new_mc.tell()))
+ if IS_X86_64:
+ # Restore scratch reg
+ new_mc.POP_r(X86_64_SCRATCH_REG.value)
+
if self.function_name is not None:
self.end_function(done=False)
self.start_pos = new_mc.get_relative_pos()
@@ -492,7 +503,6 @@
for i in range(len(get_from_stack)):
loc, is_xmm = get_from_stack[i]
- self.mc.ensure_bytes_available(32)
if is_xmm:
self.mc.MOVSD_xb(X86_64_XMM_SCRATCH_REG.value, (2 + i) * WORD)
self.mc.MOVSD(loc, X86_64_XMM_SCRATCH_REG)
@@ -650,9 +660,6 @@
tmp2 = result_loc.higher8bits()
elif IS_X86_64:
tmp2 = X86_64_SCRATCH_REG.lowest8bits()
- # We can't do a jump in the middle below, because that could
- # clobber the scratch register
- self.mc.ensure_bytes_available(32)
self.mc.SET_ir(rx86.Conditions[cond], tmp1.value)
if is_ne:
@@ -771,7 +778,6 @@
self.mc.MOVSD(X86_64_XMM_SCRATCH_REG, loc)
self.mc.MOVSD_sx(i*WORD, X86_64_XMM_SCRATCH_REG.value)
else:
- self.mc.ensure_bytes_available(32)
self.mc.MOV(X86_64_SCRATCH_REG, loc)
self.mc.MOV_sr(i*WORD, X86_64_SCRATCH_REG.value)
else:
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/regloc.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/regloc.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/regloc.py Tue Jul 20 16:42:49 2010
@@ -157,12 +157,11 @@
# mov rax, [r11]
#
# NB: You can use the scratch register as a temporary register in
-# assembly.py, but great care must be taken when doing so. A call to a
-# method in LocationCodeBuilder could clobber the scratch register when
-# certain location types are passed in. In additional, if a new MC is
-# allocated, and it happens to be more than 32-bits away, the JMP to it
-# will also clobber the scratch register.
+# assembler.py, but care must be taken when doing so. A call to a method in
+# LocationCodeBuilder could clobber the scratch register when certain
+# location types are passed in.
X86_64_SCRATCH_REG = r11
+
# XXX: a GPR scratch register is definitely needed, but we could probably do
# without an xmm scratch reg.
X86_64_XMM_SCRATCH_REG = xmm15
@@ -187,6 +186,15 @@
def INSN(self, loc1, loc2):
code1 = loc1.location_code()
code2 = loc2.location_code()
+
+ # You can pass in the scratch register as a location, but you
+ # must be careful not to combine it with location types that
+ # might need to use the scratch register themselves.
+ if loc2 is X86_64_SCRATCH_REG:
+ assert code1 not in ('j', 'i')
+ if loc1 is X86_64_SCRATCH_REG:
+ assert code2 not in ('j', 'i')
+
for possible_code1 in unrolling_location_codes:
if code1 == possible_code1:
for possible_code2 in unrolling_location_codes:
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/test/test_assembler.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/test/test_assembler.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/test/test_assembler.py Tue Jul 20 16:42:49 2010
@@ -30,6 +30,10 @@
self.content.append(("JMP", args))
def done(self):
pass
+ def PUSH_r(self, reg):
+ pass
+ def POP_r(self, reg):
+ pass
class FakeAssembler:
def write_pending_failure_recoveries(self):
More information about the Pypy-commit
mailing list