[pypy-svn] r59165 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test

witulski at codespeak.net witulski at codespeak.net
Fri Oct 17 10:10:35 CEST 2008


Author: witulski
Date: Fri Oct 17 10:10:33 2008
New Revision: 59165

Modified:
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py
Log:
Added MOV(Stack, Register) + test to enable Stackreuse



Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py	Fri Oct 17 10:10:33 2008
@@ -50,6 +50,17 @@
                 rexB, modrm1 = self.get_register_bits(arg1.location.reg)
             elif isinstance(arg1.location, Register8):
                 modrm1 = self.get_register_bits_8Bit(arg1.location.reg)
+            # special case: Stack and Register exchanged
+            elif isinstance(arg1.location, Stack64) and isinstance(arg2.location, Register64):
+                rexB, modrm1 = self.get_register_bits(arg2.location.reg)
+                self.write_rex_byte(rexW, rexB, rexX, rexR) 
+                self.write(opcode)
+                # exchanged mod1,mod2, dont know why :)
+                self.write_modRM_byte(mod, modrm1, modrm2)
+                # no scale(has no effect on rsp), no index, base = rsp
+                self.write_SIB(0, 4, 4) 
+                self.writeImm32(arg1.location.offset) 
+                return quadreg_instr 
             
         # exchange the two arguments (modrm2/modrm1)
         if isinstance(arg2,Immediate32):
@@ -202,7 +213,8 @@
     _MOV_QWREG_IMM32 = make_two_operand_instr(   1,    0,    0, None, "\xC7", 3, None, 0)
     _MOV_QWREG_QWREG = make_two_operand_instr(   1, None,    0, None, "\x89", 3, None, None)
     _MOV_QWREG_IMM64 = make_two_operand_instr_with_alternate_encoding(1,0,0,None,"B8",None,None)
-    _MOV_QWREG_STACK = make_two_operand_instr(   1,    0,    0, None, "\x8B", 2, None, 4)#4 =RSP    
+    _MOV_QWREG_STACK = make_two_operand_instr(   1,    0,    0, None, "\x8B", 2, None, 4)#4 =RSP
+    _MOV_STACK_QWREG = make_two_operand_instr(   1,    0,    0, None, "\x89", 2, None, 4)    
         
     _IDIV_QWREG      = make_one_operand_instr(   1,    0,    0, None, "\xF7", 3, None, 7)
     

Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py	Fri Oct 17 10:10:33 2008
@@ -106,6 +106,7 @@
         self.known_gv = [] # contains the live genvars (used for spilling and allocation)
         for reg in used_registers:
             del self.freeregisters[reg.location.reg]
+        self.free_stack_pos = {}
                
     def _open(self):
         pass
@@ -304,15 +305,14 @@
         self._open()
         gv_return = self.allocate_register("rax")
         # if there unused genVars on the stack
-        # pop them away
-        while not self.stackdepth == 0:
-            self.mc.POP(gv_return)
-            self.stackdepth = self.stackdepth -1
+        # throw them away
+        if not self.stackdepth == 0:
+            self.mc.ADD(IntVar(Register64("rsp")), Immediate32(self.stackdepth*8))
         if not gv_returnvar == None:#check void return      
             self.mc.MOV(gv_return, gv_returnvar)
         self.mc.RET()
         self._close()
-        assert self.stackdepth == 0
+        #assert self.stackdepth == 0
         
     # FIXME: uses 32bit displ 
     # TODO: return also stackdepth or pop! 
@@ -439,8 +439,14 @@
         if gv_to_spill.location.throw_away:
             return gv_to_spill
         else:
+            #search for free stack position
+            for i in range(self.stackdepth):
+                if i in self.free_stack_pos.keys():
+                    pass
+                    # TODO: move gv_to_spill, stack(i)
             self.stackdepth = self.stackdepth +1 
-            self.mc.PUSH(gv_to_spill)    
+            self.mc.PUSH(gv_to_spill) 
+            self.free_stack_pos[self.stackdepth] = None # remember as used   
             new_gv = IntVar(Register64(gv_to_spill.location.reg))
             gv_to_spill.location = Stack64(self.stackdepth)         
             return new_gv
@@ -451,6 +457,7 @@
         gv_new = self.allocate_register(None, dont_alloc)
         if a_spilled_gv.location.offset ==  self.stackdepth:
             self.mc.POP(gv_new)
+            del self.free_stack_pos[self.stackdepth]
             self.stackdepth = self.stackdepth -1
             assert self.stackdepth >= 0 
             a_spilled_gv.location = Register64(gv_new.location.reg)
@@ -463,8 +470,7 @@
         # else access the memory
         # FIXME: if this genVar becomes the top of stack it will never be pushed
             self.mc.MOV(gv_new, IntVar(Stack64(8*(self.stackdepth-a_spilled_gv.location.offset))))#8=scale
-            #print "debug:",self.stackdepth
-            #print a_spilled_gv.location.offset
+            del self.free_stack_pos[a_spilled_gv.location.offset]
             a_spilled_gv.location = Register64(gv_new.location.reg)
             self.known_gv.remove(gv_new) 
             return a_spilled_gv

Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py	Fri Oct 17 10:10:33 2008
@@ -11,6 +11,22 @@
 def skip(self):
     py.test.skip("not implemented yet")
     
+    
+# pushes/pos some values and than uses a mem access to access the stack
+def make_mem_func2(rgenop):
+    sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed], lltype.Signed))
+    builder, gv_mem_func, [gv_x] = rgenop.newgraph(sigtoken, "mem_op")
+    builder.start_writing()
+    builder.genop1("int_push", gv_x)  
+    builder.genop1("int_push", gv_x)
+    builder.mc.MOV(gv_x,  rgenop.genconst(42))
+    builder.mc.MOV(IntVar(Stack64(8)), gv_x)
+    builder.genop1("int_pop",  gv_x)
+    builder.genop1("int_pop",  gv_x)
+    builder.finish_and_return(sigtoken, gv_x)
+    builder.end()
+    return gv_mem_func
+
 # pushes/pos some values and than uses a mem access to access the stack
 def make_mem_func(rgenop):
     sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed))
@@ -509,6 +525,13 @@
         result = fnptr(-1,2)
         assert result == 5
         
+    def test_memory_access2(self):
+        mem_func = make_mem_func2(self.RGenOp())
+        fnptr = self.cast(mem_func,1)
+        result = fnptr(0)
+        assert result == 42
+
+        
 #    def test_invert(self):
 #        inv_function = make_one_op_instr(self.RGenOp(),"int_invert")
 #        fnptr = self.cast(inv_function,1)



More information about the Pypy-commit mailing list