Commits

David Schneider committed 9e6a292

implement and use VSTM and VLDM for loading and storing several floating point regs

Comments (0)

Files changed (3)

rpython/jit/backend/arm/assembler.py

                 regs = VFPRegisterManager.save_around_call_regs
             else:
                 regs = VFPRegisterManager.all_regs
-            for i, vfpr in enumerate(regs):
-                if vfpr in ignored_regs:
-                    continue
-                ofs = len(CoreRegisterManager.all_regs) * WORD
-                ofs += i * DOUBLE_WORD + base_ofs
-                self.store_reg(mc, vfpr, r.fp, ofs)
+            ofs = len(CoreRegisterManager.all_regs) * WORD
+            mc.ADD_ri(r.ip.value, r.ip.value, ofs)
+            mc.VSTM(r.ip.value, [vfpr.value for vfpr in regs
+                                    if vfpr not in ignored_regs])
 
     def _pop_all_regs_from_jitframe(self, mc, ignored_regs, withfloats,
                                  callee_only=False):
                 regs = VFPRegisterManager.save_around_call_regs
             else:
                 regs = VFPRegisterManager.all_regs
-            for i, vfpr in enumerate(regs):
-                if vfpr in ignored_regs:
-                    continue
-                ofs = len(CoreRegisterManager.all_regs) * WORD
-                ofs += i * DOUBLE_WORD + base_ofs
-                self.load_reg(mc, vfpr, r.fp, ofs)
+            ofs = len(CoreRegisterManager.all_regs) * WORD
+            mc.ADD_ri(r.ip.value, r.ip.value, ofs)
+            mc.VLDM(r.ip.value, [vfpr.value for vfpr in regs
+                                    if vfpr not in ignored_regs])
 
     def _build_failure_recovery(self, exc, withfloats=False):
         mc = InstrBuilder(self.cpu.cpuinfo.arch_version)

rpython/jit/backend/arm/codebuilder.py

         instr = self._encode_reg_list(instr, regs)
         self.write32(instr)
 
+    def VSTM(self, base, regs, write_back=False, cond=cond.AL):
+        # encoding T1
+        P = 0
+        U = 1
+        nregs = len(regs)
+        assert nregs > 0 and nregs <= 16
+        freg = regs[0]
+        D = (freg & 0x10) >> 4
+        Dd = (freg & 0xF)
+        nregs *= 2
+        instr = (cond << 28
+                | 3 << 26
+                | P << 24
+                | U << 23
+                | D << 22
+                | (1 if write_back else 0) << 21
+                | (base & 0xF) << 16
+                | Dd << 12
+                | 0xB << 8
+                | nregs)
+        self.write32(instr)
+
+    def VLDM(self, base, regs, write_back=False, cond=cond.AL):
+        # encoding T1
+        P = 0
+        U = 1
+        nregs = len(regs)
+        assert nregs > 0 and nregs <= 16
+        freg = regs[0]
+        D = (freg & 0x10) >> 4
+        Dd = (freg & 0xF)
+        nregs *= 2
+        instr = (cond << 28
+                | 3 << 26
+                | P << 24
+                | U << 23
+                | D << 22
+                | (1 if write_back else 0) << 21
+                | 1 << 20
+                | (base & 0xF) << 16
+                | Dd << 12
+                | 0xB << 8
+                | nregs)
+        self.write32(instr)
 
     def VPUSH(self, regs, cond=cond.AL):
         nregs = len(regs)

rpython/jit/backend/arm/test/test_instr_codebuilder.py

         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_vstm(self):
+        self.cb.VSTM(r.fp.value, [reg.value for reg in r.caller_vfp_resp], cond=conditions.AL)
+        self.assert_equal('VSTM fp, {d0, d1, d2, d3, d4, d5, d6, d7}')
+
+    def test_vldm(self):
+        self.cb.VLDM(r.fp.value, [reg.value for reg in r.caller_vfp_resp], cond=conditions.AL)
+        self.assert_equal('VLDM fp, {d0, d1, d2, d3, d4, d5, d6, d7}')
+
     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}')