[pypy-commit] pypy arm-backend-2: test and refactor regalloc_pop

bivab noreply at buildbot.pypy.org
Fri Sep 30 12:00:24 CEST 2011


Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r47711:3fba66f3639e
Date: 2011-09-29 17:08 +0200
http://bitbucket.org/pypy/pypy/changeset/3fba66f3639e/

Log:	test and refactor regalloc_pop

diff --git a/pypy/jit/backend/arm/assembler.py b/pypy/jit/backend/arm/assembler.py
--- a/pypy/jit/backend/arm/assembler.py
+++ b/pypy/jit/backend/arm/assembler.py
@@ -867,8 +867,6 @@
         if loc.is_reg():
             new_loc = loc
         elif loc.is_stack():
-            # we use LR here, because the consequent move to the stack uses the
-            # IP register
             self.mc.PUSH([r.lr.value], cond=cond)
             new_loc = r.lr
         self.mc.gen_load_int(new_loc.value, prev_loc.value, cond=cond)
@@ -883,12 +881,16 @@
             self.mc.MOV_rr(loc.value, prev_loc.value, cond=cond)
         elif loc.is_stack() and loc.type != FLOAT:
             # spill a core register
+            if prev_loc is r.ip:
+                temp = r.lr
+            else:
+                temp = r.ip
             offset = ConstInt(loc.position*WORD)
             if not _check_imm_arg(offset, size=0xFFF):
-                self.mc.PUSH([r.ip.value], cond=cond)
-                self.mc.gen_load_int(r.ip.value, -offset.value, cond=cond)
-                self.mc.STR_rr(prev_loc.value, r.fp.value, r.ip.value, cond=cond)
-                self.mc.POP([r.ip.value], cond=cond)
+                self.mc.PUSH([temp.value], cond=cond)
+                self.mc.gen_load_int(temp.value, -offset.value, cond=cond)
+                self.mc.STR_rr(prev_loc.value, r.fp.value, temp.value, cond=cond)
+                self.mc.POP([temp.value], cond=cond)
             else:
                 self.mc.STR_ri(prev_loc.value, r.fp.value, imm=-1*offset.value, cond=cond)
         else:
@@ -1024,12 +1026,9 @@
     def regalloc_push(self, loc, cond=c.AL):
         """Pushes the value stored in loc to the stack
         Can trash the current value of the IP register when pushing a stack
-        lock"""
+        loc"""
 
         if loc.is_stack():
-            # XXX maybe push ip here to avoid trashing it and restore ip and
-            # the loc in regalloc pop. Also regalloc mov would not exclude
-            # stack -> lr, which is not a big issue anyway
             if loc.type != FLOAT:
                 scratch_reg = r.ip
             else:
@@ -1049,7 +1048,9 @@
         else:
             raise AssertionError('Trying to push an invalid location')
 
-    def regalloc_pop(self, loc):
+    def regalloc_pop(self, loc, cond=c.AL):
+        """Pops the value on top of the stack to loc Can trash the current
+        value of the IP register when popping to a stack loc"""
         if loc.is_stack():
             if loc.type != FLOAT:
                 scratch_reg = r.ip
@@ -1058,11 +1059,11 @@
             self.regalloc_pop(scratch_reg)
             self.regalloc_mov(scratch_reg, loc)
         elif loc.is_reg():
-            self.mc.POP([loc.value])
+            self.mc.POP([loc.value], cond=cond)
         elif loc.is_vfp_reg():
-            self.mc.VPOP([loc.value])
+            self.mc.VPOP([loc.value], cond=cond)
         else:
-            assert 0, 'ffuu'
+            raise AssertionError('Trying to pop to an invalid location')
 
     def leave_jitted_hook(self):
         ptrs = self.fail_boxes_ptr.ar
diff --git a/pypy/jit/backend/arm/test/test_regalloc_mov.py b/pypy/jit/backend/arm/test/test_regalloc_mov.py
--- a/pypy/jit/backend/arm/test/test_regalloc_mov.py
+++ b/pypy/jit/backend/arm/test/test_regalloc_mov.py
@@ -410,3 +410,62 @@
             mi('VPUSH', [vfp_ip.value], cond=AL),
         ]
         self.push(sf, e)
+
+class TestRegallocPop(BaseMovTest):
+    def pop(self, loc, e):
+        self.asm.regalloc_pop(loc)
+        self.validate(e)
+
+    def test_pop_reg(self):
+        r1 = r(1)
+        e = [mi('POP', [r1.value], cond=AL)]
+        self.pop(r1, e)
+
+    def test_pop_vfp_reg(self):
+        vr1 = vfp(1)
+        e = [mi('VPOP', [vr1.value], cond=AL)]
+        self.pop(vr1, e)
+
+    def test_pop_stackloc(self):
+        s = stack(12)
+        e = [
+            mi('POP', [ip.value], cond=AL),
+            mi('STR_ri', ip.value, fp.value, imm=-48, cond=AL)]
+        self.pop(s, e)
+
+    def test_pop_big_stackloc(self):
+        s = stack(1200)
+        e = [
+            mi('POP', [ip.value], cond=AL),
+            mi('PUSH', [lr.value], cond=AL),
+            mi('gen_load_int', lr.value, -1200*4, cond=AL),
+            mi('STR_rr', ip.value, fp.value, lr.value, cond=AL),
+            mi('POP', [lr.value], cond=AL)
+            ]
+        self.pop(s, e)
+
+    def test_pop_float_stackloc(self):
+        s = stack_float(12)
+        e = [
+            mi('VPOP', [vfp_ip.value], cond=AL),
+            mi('PUSH', [ip.value], cond=AL),
+            mi('SUB_ri', ip.value, fp.value, 48, cond=AL),
+            mi('VSTR', vfp_ip.value, ip.value, cond=AL),
+            mi('POP', [ip.value], cond=AL)]
+        self.pop(s, e)
+
+    def test_pop_big_float_stackloc(self):
+        s = stack_float(1200)
+        e = [
+            mi('VPOP', [vfp_ip.value], cond=AL),
+            mi('PUSH', [ip.value], cond=AL),
+            mi('gen_load_int', ip.value, 4800, cond=AL),
+            mi('SUB_rr', ip.value, fp.value, ip.value, cond=AL),
+            mi('VSTR', vfp_ip.value, ip.value, cond=AL),
+            mi('POP', [ip.value], cond=AL)]
+        self.pop(s, e)
+
+    def test_unsupported(self):
+        py.test.raises(AssertionError, 'self.asm.regalloc_pop(imm(1))')
+        py.test.raises(AssertionError, 'self.asm.regalloc_pop(imm_float(1))')
+


More information about the pypy-commit mailing list