[pypy-commit] pypy arm-backend-2: fix an error when setting and reading float fields from an object with a large offset

bivab noreply at buildbot.pypy.org
Tue Oct 25 11:07:54 CEST 2011


Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r48418:0dc87b084c4a
Date: 2011-10-24 14:59 +0200
http://bitbucket.org/pypy/pypy/changeset/0dc87b084c4a/

Log:	fix an error when setting and reading float fields from an object
	with a large offset

diff --git a/pypy/jit/backend/arm/opassembler.py b/pypy/jit/backend/arm/opassembler.py
--- a/pypy/jit/backend/arm/opassembler.py
+++ b/pypy/jit/backend/arm/opassembler.py
@@ -505,10 +505,15 @@
         value_loc, base_loc, ofs, size = arglocs
         if size.value == 8:
             assert value_loc.is_vfp_reg()
+            # vstr only supports imm offsets
+            # so if the ofset is too large we add it to the base and use an
+            # offset of 0
             if ofs.is_reg():
+                self.mc.ADD_rr(r.ip.value, base_loc.value, ofs.value)
                 base_loc = r.ip
                 ofs = imm(0)
-                self.mc.ADD_rr(r.ip.value, base_loc.value, ofs.value)
+            else:
+                assert ofs.value % 4 == 0
             self.mc.VSTR(value_loc.value, base_loc.value, ofs.value)
         elif size.value == 4:
             if ofs.is_imm():
@@ -535,10 +540,15 @@
         base_loc, ofs, res, size = arglocs
         if size.value == 8:
             assert res.is_vfp_reg()
+            # vldr only supports imm offsets
+            # so if the ofset is too large we add it to the base and use an
+            # offset of 0
             if ofs.is_reg():
+                self.mc.ADD_rr(r.ip.value, base_loc.value, ofs.value)
                 base_loc = r.ip
                 ofs = imm(0)
-                self.mc.ADD_rr(r.ip.value, base_loc.value, ofs.value)
+            else:
+                assert ofs.value % 4 == 0
             self.mc.VLDR(res.value, base_loc.value, ofs.value)
         elif size.value == 4:
             if ofs.is_imm():
diff --git a/pypy/jit/backend/arm/test/test_runner.py b/pypy/jit/backend/arm/test/test_runner.py
--- a/pypy/jit/backend/arm/test/test_runner.py
+++ b/pypy/jit/backend/arm/test/test_runner.py
@@ -1,6 +1,8 @@
 import py
 from pypy.jit.backend.arm.runner import ArmCPU
-from pypy.jit.backend.test.runner_test import LLtypeBackendTest
+from pypy.jit.backend.test.runner_test import LLtypeBackendTest, \
+                                                boxfloat, \
+                                                constfloat
 from pypy.jit.backend.arm.test.support import skip_unless_arm
 from pypy.jit.metainterp.history import (AbstractFailDescr,
                                          AbstractDescr,
@@ -12,7 +14,7 @@
                                          ConstObj, BoxFloat, ConstFloat)
 from pypy.jit.metainterp.resoperation import ResOperation, rop
 from pypy.jit.tool.oparser import parse
-from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.lltypesystem import lltype, llmemory, rclass
 from pypy.rpython.annlowlevel import llhelper
 from pypy.jit.codewriter.effectinfo import EffectInfo
 
@@ -117,3 +119,69 @@
 
     def test_cond_call_gc_wb_array_card_marking_fast_path(self):
         py.test.skip('ignore this fast path for now')
+
+    SFloat = lltype.GcForwardReference()
+    SFloat.become(lltype.GcStruct('SFloat', ('parent', rclass.OBJECT),
+          ('v1', lltype.Signed), ('v2', lltype.Signed),
+          ('v3', lltype.Signed), ('v4', lltype.Signed),
+          ('v5', lltype.Signed), ('v6', lltype.Signed),
+          ('v7', lltype.Signed), ('v8', lltype.Signed),
+          ('v9', lltype.Signed), ('v10', lltype.Signed),
+          ('v11', lltype.Signed), ('v12', lltype.Signed),
+          ('v13', lltype.Signed), ('v14', lltype.Signed),
+          ('v15', lltype.Signed), ('v16', lltype.Signed),
+          ('v17', lltype.Signed), ('v18', lltype.Signed),
+          ('v19', lltype.Signed), ('v20', lltype.Signed),
+
+          ('w1', lltype.Signed), ('w2', lltype.Signed),
+          ('w3', lltype.Signed), ('w4', lltype.Signed),
+          ('w5', lltype.Signed), ('w6', lltype.Signed),
+          ('w7', lltype.Signed), ('w8', lltype.Signed),
+          ('w9', lltype.Signed), ('w10', lltype.Signed),
+          ('w11', lltype.Signed), ('w12', lltype.Signed),
+          ('w13', lltype.Signed), ('w14', lltype.Signed),
+          ('w15', lltype.Signed), ('w16', lltype.Signed),
+          ('w17', lltype.Signed), ('w18', lltype.Signed),
+          ('w19', lltype.Signed), ('w20', lltype.Signed),
+
+          ('x1', lltype.Signed), ('x2', lltype.Signed),
+          ('x3', lltype.Signed), ('x4', lltype.Signed),
+          ('x5', lltype.Signed), ('x6', lltype.Signed),
+          ('x7', lltype.Signed), ('x8', lltype.Signed),
+          ('x9', lltype.Signed), ('x10', lltype.Signed),
+          ('x11', lltype.Signed), ('x12', lltype.Signed),
+          ('x13', lltype.Signed), ('x14', lltype.Signed),
+          ('x15', lltype.Signed), ('x16', lltype.Signed),
+          ('x17', lltype.Signed), ('x18', lltype.Signed),
+          ('x19', lltype.Signed), ('x20', lltype.Signed),
+
+          ('y1', lltype.Signed), ('y2', lltype.Signed),
+          ('y3', lltype.Signed), ('y4', lltype.Signed),
+          ('y5', lltype.Signed), ('y6', lltype.Signed),
+          ('y7', lltype.Signed), ('y8', lltype.Signed),
+          ('y9', lltype.Signed), ('y10', lltype.Signed),
+          ('y11', lltype.Signed), ('y12', lltype.Signed),
+          ('y13', lltype.Signed), ('y14', lltype.Signed),
+          ('y15', lltype.Signed), ('y16', lltype.Signed),
+          ('y17', lltype.Signed), ('y18', lltype.Signed),
+          ('y19', lltype.Signed), ('y20', lltype.Signed),
+          ('float', lltype.Float)))
+
+    T = lltype.GcStruct('T', ('parent', SFloat),
+                             ('next', lltype.Ptr(SFloat)))
+    def test_float_field(self):
+        if not self.cpu.supports_floats:
+            py.test.skip('requires floats')
+        floatdescr = self.cpu.fielddescrof(self.SFloat, 'float')
+        t_box, T_box = self.alloc_instance(self.T)
+        self.execute_operation(rop.SETFIELD_GC, [t_box, boxfloat(3.4)],
+                               'void', descr=floatdescr)
+        res = self.execute_operation(rop.GETFIELD_GC, [t_box],
+                                     'float', descr=floatdescr)
+        assert res.getfloat() == 3.4
+        #
+        self.execute_operation(rop.SETFIELD_GC, [t_box, constfloat(-3.6)],
+                               'void', descr=floatdescr)
+        res = self.execute_operation(rop.GETFIELD_GC, [t_box],
+                                     'float', descr=floatdescr)
+        assert res.getfloat() == -3.6


More information about the pypy-commit mailing list