[pypy-commit] pypy default: implement and use ldm/stm to store several registers to the jitframe

bivab noreply at buildbot.pypy.org
Wed May 1 23:31:52 CEST 2013


Author: David Schneider <david.schneider at picle.org>
Branch: 
Changeset: r63792:e2231ee466f7
Date: 2013-05-01 21:52 +0200
http://bitbucket.org/pypy/pypy/changeset/e2231ee466f7/

Log:	implement and use ldm/stm to store several registers to the jitframe

diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py
--- a/rpython/jit/backend/arm/assembler.py
+++ b/rpython/jit/backend/arm/assembler.py
@@ -360,11 +360,9 @@
             regs = CoreRegisterManager.save_around_call_regs
         else:
             regs = CoreRegisterManager.all_regs
-        # XXX use STMDB ops here
-        for i, gpr in enumerate(regs):
-            if gpr in ignored_regs:
-                continue
-            self.store_reg(mc, gpr, r.fp, base_ofs + i * WORD)
+        mc.ADD_ri(r.ip.value, r.fp.value, base_ofs)
+        mc.STM(r.ip.value, [reg.value for reg in regs
+                                    if reg not in ignored_regs])
         if withfloats:
             if callee_only:
                 regs = VFPRegisterManager.save_around_call_regs
@@ -385,12 +383,9 @@
             regs = CoreRegisterManager.save_around_call_regs
         else:
             regs = CoreRegisterManager.all_regs
-        # XXX use LDMDB ops here
-        for i, gpr in enumerate(regs):
-            if gpr in ignored_regs:
-                continue
-            ofs = i * WORD + base_ofs
-            self.load_reg(mc, gpr, r.fp, ofs)
+        mc.ADD_ri(r.ip.value, r.fp.value, base_ofs)
+        mc.LDM(r.ip.value, [reg.value for reg in regs
+                                    if reg not in ignored_regs])
         if withfloats:
             # Pop all XMM regs
             if callee_only:
diff --git a/rpython/jit/backend/arm/codebuilder.py b/rpython/jit/backend/arm/codebuilder.py
--- a/rpython/jit/backend/arm/codebuilder.py
+++ b/rpython/jit/backend/arm/codebuilder.py
@@ -49,6 +49,26 @@
             instr = self._encode_reg_list(cond << 28 | 0x92D << 16, regs)
         self.write32(instr)
 
+    def STM(self, base, regs, write_back=False, cond=cond.AL):
+        assert len(regs) > 0
+        instr = (cond << 28
+                | 0x11 << 23
+                | (1 if write_back else 0) << 21
+                | (base & 0xF) << 16)
+        instr = self._encode_reg_list(instr, regs)
+        self.write32(instr)
+
+    def LDM(self, base, regs, write_back=False, cond=cond.AL):
+        assert len(regs) > 0
+        instr = (cond << 28
+                | 0x11 << 23
+                | (1 if write_back else 0) << 21
+                | 1 << 20
+                | (base & 0xF) << 16)
+        instr = self._encode_reg_list(instr, regs)
+        self.write32(instr)
+
+
     def VPUSH(self, regs, cond=cond.AL):
         nregs = len(regs)
         assert nregs > 0 and nregs <= 16
diff --git a/rpython/jit/backend/arm/test/test_instr_codebuilder.py b/rpython/jit/backend/arm/test/test_instr_codebuilder.py
--- a/rpython/jit/backend/arm/test/test_instr_codebuilder.py
+++ b/rpython/jit/backend/arm/test/test_instr_codebuilder.py
@@ -139,6 +139,14 @@
     def test_push_raises_sp(self):
         assert py.test.raises(AssertionError, 'self.cb.PUSH([r.sp.value])')
 
+    def test_stm(self):
+        self.cb.STM(r.fp.value, [reg.value for reg in r.caller_resp], cond=conditions.AL)
+        self.assert_equal('STM fp, {r0, r1, r2, r3}')
+
+    def test_ldm(self):
+        self.cb.LDM(r.fp.value, [reg.value for reg in r.caller_resp], cond=conditions.AL)
+        self.assert_equal('LDM fp, {r0, r1, r2, r3}')
+
     def test_pop(self):
         self.cb.POP([reg.value for reg in r.caller_resp], cond=conditions.AL)
         self.assert_equal('POP {r0, r1, r2, r3}')


More information about the pypy-commit mailing list