[pypy-svn] r37364 - in pypy/dist/pypy/jit/codegen/i386: . test

arigo at codespeak.net arigo at codespeak.net
Thu Jan 25 23:53:23 CET 2007


Author: arigo
Date: Thu Jan 25 23:53:21 2007
New Revision: 37364

Modified:
   pypy/dist/pypy/jit/codegen/i386/regalloc.py
   pypy/dist/pypy/jit/codegen/i386/rgenop.py
   pypy/dist/pypy/jit/codegen/i386/ri386.py
   pypy/dist/pypy/jit/codegen/i386/test/test_rgenop.py
Log:
write_frame_place() works.


Modified: pypy/dist/pypy/jit/codegen/i386/regalloc.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/regalloc.py	(original)
+++ pypy/dist/pypy/jit/codegen/i386/regalloc.py	Thu Jan 25 23:53:21 2007
@@ -125,7 +125,15 @@
                 else:
                     self.add_final_move(v, operand, make_copy=v.is_const)
             else:
-                if loc in force_loc2operand or operand in force_operand2loc:
+                # we need to make of copy of this var if we have conflicting
+                # requirements about where it should go:
+                #  * its location is forced to another operand
+                #  * the operand is assigned to another location
+                #  * it should be in the stack, but it is not
+                if (loc in force_loc2operand or operand in force_operand2loc or
+                    (loc < self.num_stack_locs and not (
+                                 isinstance(operand, MODRM)
+                                 and operand.is_relative_to_ebp()))):
                     if at_start:
                         self.initial_moves.append((loc, operand))
                     else:
@@ -260,3 +268,7 @@
     def get_offset(self):
         assert self.offset != 0     # otherwise, RegAllocator bug
         return self.offset
+
+
+class Place(StorageInStack):
+    pass

Modified: pypy/dist/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/i386/rgenop.py	Thu Jan 25 23:53:21 2007
@@ -5,7 +5,7 @@
 from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
 from pypy.jit.codegen.i386.codebuf import CodeBlockOverflow
 from pypy.jit.codegen.i386.operation import *
-from pypy.jit.codegen.i386.regalloc import RegAllocator, StorageInStack
+from pypy.jit.codegen.i386.regalloc import RegAllocator, StorageInStack, Place
 from pypy.jit.codegen import conftest
 from pypy.rpython.annlowlevel import llhelper
 
@@ -58,6 +58,15 @@
         return lltype.cast_primitive(T, value)
 
 @specialize.arg(0)
+def cast_whatever_to_int(T, value):
+    if isinstance(T, lltype.Ptr):
+        return lltype.cast_ptr_to_int(value)
+    elif T is llmemory.Address:
+        return llmemory.cast_adr_to_int(value)
+    else:
+        return lltype.cast_primitive(lltype.Signed, value)
+
+ at specialize.arg(0)
 def cast_adr_to_whatever(T, addr):
     if T is llmemory.Address:
         return addr
@@ -177,7 +186,18 @@
     else:
         from ctypes import cast, c_void_p, c_int, POINTER
         p = cast(c_void_p(addr), POINTER(c_int))
-        return p.contents.value
+        return p[0]
+
+def poke_word_into(addr, value):
+    # now the Very Obscure Bit: when translated, 'addr' is an
+    # address.  When not, it's an integer.  It just happens to
+    # make the test pass, but that's probably going to change.
+    if we_are_translated():
+        addr.signed[0] = value
+    else:
+        from ctypes import cast, c_void_p, c_int, POINTER
+        p = cast(c_void_p(addr), POINTER(c_int))
+        p[0] = value
 
 # ____________________________________________________________
 
@@ -452,10 +472,19 @@
         return result
 
     def alloc_frame_place(self, kind, gv_initial_value):
-        raise NotImplementedError
+        if self.force_in_stack is None:
+            self.force_in_stack = []
+        v = OpSameAs(gv_initial_value)
+        self.operations.append(v)
+        place = Place()
+        place.stackvar = v
+        self.force_in_stack.append((v, place))
+        return place
 
     def genop_absorb_place(self, kind, place):
-        raise NotImplementedError
+        v = place.stackvar
+        place.stackvar = None  # break reference to potentially lots of memory
+        return v
 
 
 class Label(GenLabel):
@@ -717,7 +746,9 @@
     @staticmethod
     @specialize.arg(0)
     def write_frame_place(T, base, place, value):
-        raise NotImplementedError
+        # XXX assumes sizeof(T) == WORD
+        value = cast_whatever_to_int(T, value)
+        poke_word_into(base + place.get_offset(), value)
 
 global_rgenop = RI386GenOp()
 RI386GenOp.constPrebuiltGlobal = global_rgenop.genconst

Modified: pypy/dist/pypy/jit/codegen/i386/ri386.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/ri386.py	(original)
+++ pypy/dist/pypy/jit/codegen/i386/ri386.py	Thu Jan 25 23:53:21 2007
@@ -124,6 +124,14 @@
         else:
             return unpack(offset)
 
+    def is_relative_to_ebp(self):
+        try:
+            self.ofs_relative_to_ebp()
+        except ValueError:
+            return False
+        else:
+            return True
+
     def involves_ecx(self):
         # very custom: is ecx present in this mod/rm?
         mod = self.byte & 0xC0

Modified: pypy/dist/pypy/jit/codegen/i386/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/test/test_rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/i386/test/test_rgenop.py	Thu Jan 25 23:53:21 2007
@@ -50,8 +50,3 @@
         fnptr = self.cast(gv_callable, 3)
         res = fnptr(21, -21, 0)
         assert res == 42
-
-    #def test_read_frame_var_direct(self):   py.test.skip("in-progress")
-    #def test_read_frame_var_compile(self):  py.test.skip("in-progress")
-    def test_write_frame_place_direct(self):  py.test.skip("in-progress")
-    def test_write_frame_place_compile(self): py.test.skip("in-progress")



More information about the Pypy-commit mailing list