[pypy-commit] pypy ppc-jit-backend: merge

hager noreply at buildbot.pypy.org
Tue Nov 15 12:59:16 CET 2011


Author: hager <sven.hager at uni-duesseldorf.de>
Branch: ppc-jit-backend
Changeset: r49435:2a816abcb981
Date: 2011-11-15 12:58 +0100
http://bitbucket.org/pypy/pypy/changeset/2a816abcb981/

Log:	merge

diff --git a/pypy/jit/backend/ppc/ppcgen/opassembler.py b/pypy/jit/backend/ppc/ppcgen/opassembler.py
--- a/pypy/jit/backend/ppc/ppcgen/opassembler.py
+++ b/pypy/jit/backend/ppc/ppcgen/opassembler.py
@@ -364,18 +364,19 @@
             self.mc.ld(res.value, base_loc.value, ofs.value)
 
     def emit_setarrayitem_gc(self, op, arglocs, regalloc):
-        value_loc, base_loc, ofs_loc, scale, ofs = arglocs
+        value_loc, base_loc, ofs_loc, scale, ofs, scratch_reg = arglocs
         if scale.value > 0:
-            scale_loc = r.r0
-            self.mc.load_imm(r.r0, scale.value)
+            scale_loc = scratch_reg
             if IS_PPC_32:
-                self.mc.slw(r.r0.value, ofs_loc.value, r.r0.value)
+                self.mc.slwi(scale_loc.value, ofs_loc.value, scale.value)
             else:
-                self.mc.sld(r.r0.value, ofs_loc.value, r.r0.value)
+                self.mc.sldi(scale_loc.value, ofs_loc.value, scale.value)
         else:
             scale_loc = ofs_loc
 
+        # add the base offset
         if ofs.value > 0:
+            assert scale_loc is not r.r0
             self.mc.addi(r.r0.value, scale_loc.value, ofs.value)
             scale_loc = r.r0
 
@@ -393,17 +394,19 @@
     emit_setarrayitem_raw = emit_setarrayitem_gc
 
     def emit_getarrayitem_gc(self, op, arglocs, regalloc):
-        res, base_loc, ofs_loc, scale, ofs = arglocs
+        res, base_loc, ofs_loc, scale, ofs, scratch_reg = arglocs
         if scale.value > 0:
-            scale_loc = r.r0
-            self.mc.load_imm(r.r0, scale.value)
+            scale_loc = scratch_reg
             if IS_PPC_32:
-                self.mc.slw(r.r0.value, ofs_loc.value, scale.value)
+                self.mc.slwi(scale_loc.value, ofs_loc.value, scale.value)
             else:
-                self.mc.sld(r.r0.value, ofs_loc.value, scale.value)
+                self.mc.sldi(scale_loc.value, ofs_loc.value, scale.value)
         else:
             scale_loc = ofs_loc
+
+        # add the base offset
         if ofs.value > 0:
+            assert scale_loc is not r.r0
             self.mc.addi(r.r0.value, scale_loc.value, ofs.value)
             scale_loc = r.r0
 
diff --git a/pypy/jit/backend/ppc/ppcgen/regalloc.py b/pypy/jit/backend/ppc/ppcgen/regalloc.py
--- a/pypy/jit/backend/ppc/ppcgen/regalloc.py
+++ b/pypy/jit/backend/ppc/ppcgen/regalloc.py
@@ -86,6 +86,16 @@
             assert isinstance(c, ConstPtr)
             return locations.ImmLocation(rffi.cast(lltype.Signed, c.value))
 
+    def allocate_scratch_reg(self, type=INT, selected_reg=None, forbidden_vars=None):
+        """Allocate a scratch register, possibly spilling a managed register.
+        This register is freed after emitting the current operation and can not
+        be spilled"""
+        box = TempBox()
+        reg = self.force_allocate_reg(box,
+                            selected_reg=selected_reg,
+                            forbidden_vars=forbidden_vars)
+        return reg, box
+
 class PPCFrameManager(FrameManager):
     def __init__(self):
         FrameManager.__init__(self)
@@ -170,6 +180,12 @@
         return self.rm.force_allocate_reg(var, forbidden_vars, selected_reg,
                 need_lower_byte)
 
+    def allocate_scratch_reg(self, type=INT, forbidden_vars=[], selected_reg=None):
+        assert type == INT # XXX extend this once floats are supported
+        return self.rm.allocate_scratch_reg(type=type,
+                        forbidden_vars=forbidden_vars,
+                        selected_reg=selected_reg)
+
     def _check_invariants(self):
         self.rm._check_invariants()
 
@@ -450,23 +466,32 @@
         #XXX check if imm would be fine here
         value_loc, value_box = self._ensure_value_is_boxed(b2, boxes)
         boxes.append(value_box)
+        if scale > 0:
+            tmp, box = self.allocate_scratch_reg(forbidden_vars=boxes)
+            boxes.append(box)
+        else:
+            tmp = None
         self.possibly_free_vars(boxes)
-        return [value_loc, base_loc, ofs_loc, imm(scale), imm(ofs)]
+        return [value_loc, base_loc, ofs_loc, imm(scale), imm(ofs), tmp]
 
         prepare_setarrayitem_raw = prepare_setarrayitem_gc
 
     def prepare_getarrayitem_gc(self, op):
         a0, a1 = boxes = list(op.getarglist())
         _, scale, ofs, _, ptr = self._unpack_arraydescr(op.getdescr())
-
         base_loc, base_box  = self._ensure_value_is_boxed(a0, boxes)
         boxes.append(base_box)
         ofs_loc, ofs_box = self._ensure_value_is_boxed(a1, boxes)
         boxes.append(ofs_box)
+        if scale > 0:
+            tmp, box = self.allocate_scratch_reg(forbidden_vars=boxes)
+            boxes.append(box)
+        else:
+            tmp = None
         self.possibly_free_vars(boxes)
         res = self.force_allocate_reg(op.result)
         self.possibly_free_var(op.result)
-        return [res, base_loc, ofs_loc, imm(scale), imm(ofs)]
+        return [res, base_loc, ofs_loc, imm(scale), imm(ofs), tmp]
 
     prepare_getarrayitem_raw = prepare_getarrayitem_gc
     prepare_getarrayitem_gc_pure = prepare_getarrayitem_gc
diff --git a/pypy/jit/backend/ppc/ppcgen/test/test_register_manager.py b/pypy/jit/backend/ppc/ppcgen/test/test_register_manager.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/ppc/ppcgen/test/test_register_manager.py
@@ -0,0 +1,8 @@
+from pypy.jit.backend.ppc.ppcgen import regalloc, register
+
+class TestPPCRegisterManager(object):
+    def test_allocate_scratch_register(self):
+        rm = regalloc.PPCRegisterManager({})
+        reg, box = rm.allocate_scratch_reg()
+        assert reg in register.MANAGED_REGS
+        assert rm.stays_alive(box) == False


More information about the pypy-commit mailing list