[pypy-commit] pypy arm-longlong: Fix for the strange interleaving possible with a mixture of d and s

arigo noreply at buildbot.pypy.org
Sun Aug 31 21:15:25 CEST 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: arm-longlong
Changeset: r73250:3463d820c160
Date: 2014-08-31 21:14 +0200
http://bitbucket.org/pypy/pypy/changeset/3463d820c160/

Log:	Fix for the strange interleaving possible with a mixture of d and s
	registers

diff --git a/rpython/jit/backend/arm/callbuilder.py b/rpython/jit/backend/arm/callbuilder.py
--- a/rpython/jit/backend/arm/callbuilder.py
+++ b/rpython/jit/backend/arm/callbuilder.py
@@ -276,29 +276,22 @@
 
     def get_next_vfp(self, tp):
         assert tp in 'fS'
-        if self.next_arg_vfp == -1:
-            return None
-        if tp == 'S':
+        if tp == 'f':
+            # 64bit double
+            i = max(self.next_arg_vfp, (self.next_arg_svfp + 1) >> 1)
+            if i >= len(r.vfp_argument_regs):
+                return None
+            self.next_arg_vfp = i + 1
+            return r.vfp_argument_regs[i]
+        else:
+            # 32bit float
             i = self.next_arg_svfp
-            next_vfp = (i >> 1) + 1
-            if not (i + 1) & 1: # i is even
-                self.next_arg_vfp = max(self.next_arg_vfp, next_vfp)
-                self.next_arg_svfp = self.next_arg_vfp << 1
-            else:
-                self.next_arg_svfp += 1
-                self.next_arg_vfp = next_vfp
-            lst = r.svfp_argument_regs
-        else: # 64bit double
-            i = self.next_arg_vfp
-            self.next_arg_vfp += 1
-            if self.next_arg_svfp >> 1 == i:
-                self.next_arg_svfp = self.next_arg_vfp << 1
-            lst = r.vfp_argument_regs
-        try:
-            return lst[i]
-        except IndexError:
-            self.next_arg_vfp = self.next_arg_svfp = -1
-            return None
+            if not (i & 1):     # if i is even
+                i = max(i, self.next_arg_vfp << 1)
+            if i >= len(r.svfp_argument_regs):
+                return None
+            self.next_arg_svfp = i + 1
+            return r.svfp_argument_regs[i]
 
     def prepare_arguments(self):
         non_float_locs = []
diff --git a/rpython/jit/backend/arm/test/test_callbuilder.py b/rpython/jit/backend/arm/test/test_callbuilder.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/arm/test/test_callbuilder.py
@@ -0,0 +1,34 @@
+from rpython.jit.backend.arm.callbuilder import HardFloatCallBuilder
+from rpython.jit.backend.arm import registers as r
+
+
+
+def test_hf_vfp_registers_all_singlefloat():
+    hf = HardFloatCallBuilder.__new__(HardFloatCallBuilder)
+    got = [hf.get_next_vfp('S') for i in range(18)]
+    assert got == [r.s0, r.s1, r.s2, r.s3, r.s4, r.s5, r.s6, r.s7,
+                   r.s8, r.s9, r.s10, r.s11, r.s12, r.s13, r.s14, r.s15,
+                   None, None]
+
+def test_hf_vfp_registers_all_doublefloat():
+    hf = HardFloatCallBuilder.__new__(HardFloatCallBuilder)
+    got = [hf.get_next_vfp('f') for i in range(10)]
+    assert got == [r.d0, r.d1, r.d2, r.d3, r.d4, r.d5, r.d6, r.d7,
+                   None, None]
+
+def test_hf_vfp_registers_mixture():
+    hf = HardFloatCallBuilder.__new__(HardFloatCallBuilder)
+    got = [hf.get_next_vfp('S'), hf.get_next_vfp('f'),
+           hf.get_next_vfp('S'), hf.get_next_vfp('f'),
+           hf.get_next_vfp('S'), hf.get_next_vfp('f'),
+           hf.get_next_vfp('S'), hf.get_next_vfp('f'),
+           hf.get_next_vfp('S'), hf.get_next_vfp('f'),
+           hf.get_next_vfp('S'), hf.get_next_vfp('f'),
+           hf.get_next_vfp('S'), hf.get_next_vfp('f')]
+    assert got == [r.s0,  r.d1,
+                   r.s1,  r.d2,
+                   r.s6,  r.d4,
+                   r.s7,  r.d5,
+                   r.s12, r.d7,
+                   r.s13, None,
+                   None,  None]


More information about the pypy-commit mailing list