[pypy-svn] r53357 - pypy/branch/jit-hotpath/pypy/jit/codegen/ia32

fijal at codespeak.net fijal at codespeak.net
Fri Apr 4 21:42:31 CEST 2008


Author: fijal
Date: Fri Apr  4 21:42:29 2008
New Revision: 53357

Modified:
   pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/rgenop.py
Log:
start of refactoring of get/set arrayitem. test for floats fails, but thats
not very surprising


Modified: pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/rgenop.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/rgenop.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/rgenop.py	Fri Apr  4 21:42:29 2008
@@ -66,6 +66,9 @@
     def operand(self, builder):
         raise NotImplementedError
 
+    def movetonewaddr(self, builder, arg):
+        raise NotImplementedError
+
     def __repr__(self):
         return self.token + 'var@%d' % (self.stackpos,)
 
@@ -82,6 +85,11 @@
     def newvar(self, builder):
         return builder.returnintvar(self.operand(builder))
 
+    def movetonewaddr(self, builder, arg):
+        dstop = builder.itemaddr(arg)
+        builder.mc.MOV(eax, self.operand(builder))
+        builder.mc.MOV(dstop, eax)
+
 class AddressVar(IntVar):
     ll_type = llmemory.Address
     token = 'a'
@@ -95,6 +103,11 @@
     def newvar(self, builder):
         return builder.returnboolvar(self.operand(builder))
 
+    def movetonewaddr(self, builder, arg):
+        dstop = builder.itemaddr(arg)
+        builder.mc.MOV(eax, self.operand(builder))
+        builder.mc.MOV(destop, al)
+
     ll_type = lltype.Bool
     token = 'b'
     SIZE = 1
@@ -107,6 +120,14 @@
         raise NotImplementedError("This requires moving around float mem")
         return builder.returnfloatvar(self.operand(builder))
 
+    def movetonewaddr(self, builder, arg):
+        dstop1 = builder.itemaddr(arg)
+        dstop2 = builder.itemaddr(arg, WORD)
+        builder.mc.MOV(eax, builder.stack_access(self.stackpos))
+        builder.mc.MOV(dstop1, eax)
+        builder.mc.MOV(eax, builder.stack_access(self.stackpos - 1))
+        builder.mc.MOV(dstop2, eax)
+
     ll_type = lltype.Float
     token = 'f'
     SIZE = 2
@@ -185,6 +206,9 @@
         except TypeError:   # from Symbolics
             return "const=%r" % (self.value,)
 
+    def movetonewaddr(self, builder, addr):
+        raise NotImplementedError
+
     def repr(self):
         return "const=$%s" % (self.value,)
 
@@ -194,6 +218,10 @@
     def newvar(self, builder):
         return builder.returnintvar(self.operand(builder))
 
+    def movetonewaddr(self, builder, arg):
+        dstop = builder.itemaddr(arg)
+        builder.mc.MOV(dstop, self.operand(builder))
+
 class FloatConst(Const):
     SIZE = 2
     # XXX hack for annotator
@@ -208,11 +236,23 @@
         self.rawbuf[0] = floatval
 
     def newvar(self, builder):
-        return builder.newfloatfrommem(self.rawbuf)
+        return builder.newfloatfrommem(None, None, 0,
+            rffi.cast(rffi.INT, self.rawbuf))
 
     def operand(self, builder):
         return heap64(rffi.cast(rffi.INT, self.rawbuf))
 
+    def movetonewaddr(self, builder, arg):
+        dstop1 = builder.itemaddr(arg)
+        dstop2 = builder.itemaddr(arg, WORD)
+        builder.mc.MOV(dstop1, imm(rffi.cast(rffi.INTP, self.rawbuf)[0]))
+        builder.mc.MOV(dstop2, imm(rffi.cast(rffi.INTP, self.rawbuf)[1]))
+
+    def repr(self):
+        return "const=$%s" % (self.rawbuf[0],)
+
+    __repr__ = repr
+
 class BoolConst(Const):
     SIZE = 1
 
@@ -222,13 +262,17 @@
     def newvar(self, builder):
         return builder.returnboolvar(self.operand(builder))
 
+    def movetonewaddr(self, builder, arg):
+        dstop = builder.itemaddr(arg)
+        builder.mc.MOV(dstop, self.operand(builder))
+
 ##class FnPtrConst(IntConst):
 ##    def __init__(self, value, mc):
 ##        self.value = value
 ##        self.mc = mc    # to keep it alive
 
 
-class AddrConst(GenConst):
+class AddrConst(IntConst):
     SIZE = 1
 
     def __init__(self, addr):
@@ -240,10 +284,6 @@
     def newvar(self, builder):
         return builder.returnintvar(self.operand(builder))
 
-    def nonimmoperand(self, builder, tmpregister):
-        builder.mc.MOV(tmpregister, self.operand(builder))
-        return tmpregister
-
     @specialize.arg(1)
     def revealconst(self, T):
         if T is llmemory.Address:
@@ -533,38 +573,49 @@
         self.mc.LEA(eax, mem(edx, offset))
         return self.returnintvar(eax)
 
-    def itemaddr(self, base, arraytoken, gv_index):
-        # uses ecx
+    def _compute_itemaddr(self, arg, addoffset=0):
+        base, arraytoken, gv_index = arg
         lengthoffset, startoffset, itemoffset = arraytoken
-        if itemoffset == 1:
-            memSIBx = memSIB8
-        else:
-            memSIBx = memSIB
         if isinstance(gv_index, IntConst):
             startoffset += itemoffset * gv_index.value
-            op = memSIBx(base, None, 0, startoffset)
+            return (base, None, 0, startoffset + addoffset)
         elif itemoffset in SIZE2SHIFT:
             self.mc.MOV(ecx, gv_index.operand(self))
-            op = memSIBx(base, ecx, SIZE2SHIFT[itemoffset], startoffset)
+            return (base, ecx, SIZE2SHIFT[itemoffset], startoffset +
+                    addoffset)
         else:
             self.mc.IMUL(ecx, gv_index.operand(self), imm(itemoffset))
-            op = memSIBx(base, ecx, 0, startoffset)
-        return op
+            return (base, ecx, 0, startoffset + addoffset)
+        
+    def itemaddr(self, arg, addoffset=0):
+        # uses ecx
+        base, arraytoken, gv_index = arg
+        lengthoffset, startoffset, itemoffset = arraytoken
+        if itemoffset == 1:
+            memSIBx = memSIB8
+        else:
+            memSIBx = memSIB
+        base, reg, shift, ofs = self._compute_itemaddr(arg, addoffset)
+        return memSIBx(base, reg, shift, ofs)
 
     def genop_getarrayitem(self, arraytoken, gv_ptr, gv_index):
         self.mc.MOV(edx, gv_ptr.operand(self))
-        op = self.itemaddr(edx, arraytoken, gv_index)
         _, _, itemsize = arraytoken
-        if itemsize != WORD:
-            if itemsize > 2:
-                raise NotImplementedError("itemsize != 1,2,4")
+        if itemsize > WORD:
+            # XXX assert not different type than float, probably
+            #     need to sneak one in arraytoken
+            base, reg, shift, ofs = self._compute_itemaddr((edx, arraytoken,
+                                                            gv_index))
+            return self.newfloatfrommem(base, reg, shift, ofs)
+        op = self.itemaddr((edx, arraytoken, gv_index))
+        if itemsize < WORD:
             self.mc.MOVZX(eax, op)
             op = eax
         return self.returnintvar(op)
 
     def genop_getarraysubstruct(self, arraytoken, gv_ptr, gv_index):
         self.mc.MOV(edx, gv_ptr.operand(self))
-        op = self.itemaddr(edx, arraytoken, gv_index)
+        op = self.itemaddr((edx, arraytoken, gv_index))
         self.mc.LEA(eax, op)
         return self.returnintvar(eax)
 
@@ -574,19 +625,23 @@
         return self.returnintvar(mem(edx, lengthoffset))
 
     def genop_setarrayitem(self, arraytoken, gv_ptr, gv_index, gv_value):
-        self.mc.MOV(eax, gv_value.operand(self))
-        self.mc.MOV(edx, gv_ptr.operand(self))
-        destop = self.itemaddr(edx, arraytoken, gv_index)
         _, _, itemsize = arraytoken
-        if itemsize != WORD:
-            if itemsize == 1:
-                self.mc.MOV(destop, al)
-                return
-            elif itemsize == 2:
-                self.mc.o16()    # followed by the MOV below
-            else:
-                raise NotImplementedError("setarrayitme for fieldsize != 1,2,4")
-        self.mc.MOV(destop, eax)
+        self.mc.MOV(edx, gv_ptr.operand(self))
+        destaddr = self.itemaddr((edx, arraytoken, gv_index))
+        gv_value.movetonewaddr(self, (edx, arraytoken, gv_index))
+        #if itemsize <= WORD:
+        #    self.mc.MOV(eax, gv_value.operand(self))
+        #    if itemsize != WORD:
+        #        if itemsize == 1:
+        #            self.mc.MOV(destop, al)
+        #            return
+        #        elif itemsize == 2:
+        #            self.mc.o16()    # followed by the MOV below
+        #        else:
+        #            raise NotImplementedError("setarrayitme for fieldsize == 3")
+        #    self.mc.MOV(destop, eax)
+        #else:    
+        #    self.move_bigger_value(destop, gv_value, itemsize)
 
     def genop_malloc_fixedsize(self, size):
         # XXX boehm only, no atomic/non atomic distinction for now
@@ -597,7 +652,7 @@
     def genop_malloc_varsize(self, varsizealloctoken, gv_size):
         # XXX boehm only, no atomic/non atomic distinction for now
         # XXX no overflow checking for now
-        op_size = self.itemaddr(None, varsizealloctoken, gv_size)
+        op_size = self.itemaddr((None, varsizealloctoken, gv_size))
         self.mc.LEA(edx, op_size)
         self.push(edx)
         self.mc.CALL(rel32(gc_malloc_fnaddr()))
@@ -745,12 +800,10 @@
             raise NotImplementedError("Return float var not on fp stack")
         return res
 
-    def newfloatfrommem(self, rawbuf):
-        # XXX obscure pointer arithmetics on ints. Think how do to it
-        #     better
+    def newfloatfrommem(self, base, reg, shift, ofs):
         res = FloatVar(self.stackdepth + 1)
-        self.mc.PUSH(heap(rffi.cast(rffi.INT, rawbuf)))
-        self.mc.PUSH(heap(rffi.cast(rffi.INT, rawbuf) + WORD))
+        self.mc.PUSH(memSIB(base, reg, shift, ofs))
+        self.mc.PUSH(memSIB(base, reg, shift, ofs + WORD))
         self.stackdepth += 2
         return res
 
@@ -1145,7 +1198,7 @@
 # ____________________________________________________________
 
 def _remap_bigger_values(args_gv, arg_positions):
-    """ This function cheates and changes all FloatVars into double
+    """ This function cheats and changes all FloatVars into double
     IntVars. This might be probably optimized in some way in order
     to provide greater performance, but should be enough for now
     """
@@ -1159,11 +1212,16 @@
             res_positions.append(pos)
         else:
             assert gv.SIZE == 2
-            assert isinstance(gv, FloatVar)
-            res_gv.append(IntVar(gv.stackpos))
-            res_gv.append(IntVar(gv.stackpos - 1))
+            if isinstance(gv, FloatVar):
+                res_gv.append(IntVar(gv.stackpos))
+                res_gv.append(IntVar(gv.stackpos - 1))
+            else:
+                assert isinstance(gv, FloatConst)
+                buf = rffi.cast(rffi.INTP, gv.rawbuf)
+                res_gv.append(IntConst(buf[0]))
+                res_gv.append(IntConst(buf[1]))
             res_positions.append(pos)
-            res_positions.append(pos - 1)
+            res_positions.append(pos - 1)    
     # no repeats please
     if not objectmodel.we_are_translated():
         assert sorted(dict.fromkeys(res_positions).keys()) == sorted(res_positions)
@@ -1468,9 +1526,9 @@
                     arrayfield_offset+items_offset,
                     item_size)
 
-    @staticmethod
+    @classmethod
     @specialize.memo()    
-    def arrayToken(A):
+    def arrayToken(cls, A):
         return (llmemory.ArrayLengthOffset(A),
                 llmemory.ArrayItemsOffset(A),
                 llmemory.ItemOffset(A.OF))



More information about the Pypy-commit mailing list