[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