[pypy-commit] pypy align_float_cast: add passing test for unaligned GcStruct (gcc pads the struct)

mattip noreply at buildbot.pypy.org
Sun Feb 16 01:04:24 CET 2014


Author: Matti Picus <matti.picus at gmail.com>
Branch: align_float_cast
Changeset: r69167:ea72b35e2a10
Date: 2014-02-16 02:02 +0200
http://bitbucket.org/pypy/pypy/changeset/ea72b35e2a10/

Log:	add passing test for unaligned GcStruct (gcc pads the struct)

diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py
--- a/rpython/jit/backend/arm/runner.py
+++ b/rpython/jit/backend/arm/runner.py
@@ -121,14 +121,14 @@
     def bh_raw_load_f(self, struct, offset, descr):
         ll_p = rffi.cast(rffi.CCHARP, struct)
         ll_p_offset = rffi.ptradd(ll_p, offset)
-	if rffi.cast(lltype.Signed, ll_p_offset) & 3:
+        if rffi.cast(lltype.Signed, ll_p_offset) & 3:
             with lltype.scoped_alloc(rffi.CArray(longlong.FLOATSTORAGE), 1) as s_array:
-		rffi.c_memcpy(rffi.cast(rffi.VOIDP, s_array),
+                rffi.c_memcpy(rffi.cast(rffi.VOIDP, s_array),
                               rffi.cast(rffi.VOIDP, ll_p_offset),
                               rffi.sizeof(rffi.DOUBLE))
-        	ll_p = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE),
+                ll_p = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE),
                          s_array)
-		return ll_p[0]
+        return ll_p[0]
         ll_p = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE),
                          ll_p_offset)
         return ll_p[0]
diff --git a/rpython/rlib/rawstorage.py b/rpython/rlib/rawstorage.py
--- a/rpython/rlib/rawstorage.py
+++ b/rpython/rlib/rawstorage.py
@@ -23,7 +23,12 @@
 def raw_storage_getitem(TP, storage, index):
     "NOT_RPYTHON"
     ptr = rffi.ptradd(storage, index)
-    # TODO Check that pointer is aligned for TP
+    if TP is lltype.Float and rffi.cast(lltype.Signed, ptr) & 3:
+        with lltype.scoped_alloc(rffi.CArray(TP), 1) as s_array:
+            rffi.c_memcpy(rffi.cast(rffi.VOIDP, s_array),
+                          rffi.cast(rffi.VOIDP, ptr),
+                          rffi.sizeof(TP))
+            return rffi.cast(rffi.CArrayPtr(TP), s_array)[0]
     return rffi.cast(rffi.CArrayPtr(TP), ptr)[0]
 
 def raw_storage_setitem(storage, index, item):
@@ -43,12 +48,11 @@
         return lltype_to_annotation(s_TP.const)
 
     def specialize_call(self, hop):
-        # emit code that will 'automatically' copy memory if unaligned
         assert hop.args_r[1].lowleveltype == RAW_STORAGE_PTR
         v_storage = hop.inputarg(hop.args_r[1], arg=1)
         v_index   = hop.inputarg(lltype.Signed, arg=2)
         hop.exception_cannot_occur()
-        v_addr = hop.genop('cast_ptr_to_adr', [v_storage],
+        v_addr = hop.genop('casst_ptr_to_adr', [v_storage],
                            resulttype=llmemory.Address)
         return hop.genop('raw_load', [v_addr, v_index],
                          resulttype=hop.r_result.lowleveltype)
diff --git a/rpython/rlib/test/test_rawstorage.py b/rpython/rlib/test/test_rawstorage.py
--- a/rpython/rlib/test/test_rawstorage.py
+++ b/rpython/rlib/test/test_rawstorage.py
@@ -8,8 +8,11 @@
     r = alloc_raw_storage(15)
     raw_storage_setitem(r, 3, 1<<30)
     res = raw_storage_getitem(lltype.Signed, r, 3)
+    assert res == 1<<30
+    raw_storage_setitem(r, 3, 3.14)
+    res = raw_storage_getitem(lltype.Float, r, 3)
+    assert res == 3.14
     free_raw_storage(r)
-    assert res == 1<<30
 
 class TestRawStorage(BaseRtypingTest):
     def test_storage_int(self):
@@ -21,3 +24,12 @@
             return res
         x = self.interpret(f, [1<<30])
         assert x == 1 << 30
+    def test_storage_float(self):
+        def f(v):
+            r = alloc_raw_storage(24)
+            raw_storage_setitem(r, 3, v)
+            res = raw_storage_getitem(lltype.Float, r, 3)
+            free_raw_storage(r)
+            return res
+        x = self.interpret(f, [3.14])
+        assert x == 3.14
diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py
--- a/rpython/translator/c/funcgen.py
+++ b/rpython/translator/c/funcgen.py
@@ -703,8 +703,6 @@
         res = (
           "%(result)s = ((%(typename)s) (((char *)%(addr)s) + %(offset)s))[0];"
           % locals())
-        if 'float' in res or 'double' in res:
-            xxx
         return res    
 
     def OP_CAST_PRIMITIVE(self, op):
diff --git a/rpython/translator/c/test/test_lladdresses.py b/rpython/translator/c/test/test_lladdresses.py
--- a/rpython/translator/c/test/test_lladdresses.py
+++ b/rpython/translator/c/test/test_lladdresses.py
@@ -51,6 +51,29 @@
     res = fc(42.42)
     assert res == f(42.42)
 
+def test_memory_float_unaligned():
+    S = lltype.GcStruct("S", ('c0', lltype.Char), ("x", lltype.Float), ('c1', lltype.Char), ("y", lltype.Float))
+    offset = FieldOffset(S, 'x')
+    offset_c0 = FieldOffset(S, 'c0')
+    offsety = FieldOffset(S, 'y')
+    def f(value):
+        s = lltype.malloc(S)
+        s.c0 = 'a'
+        s.x = 123.2
+        a = cast_ptr_to_adr(s)
+        b = a + offset
+        assert s.c0 == 'a'
+        assert b.float[0] == 123.2
+        b.float[0] += 234.1
+        (a + offsety).float[0] = value
+        assert s.x == 234.1 + 123.2
+        assert s.y == value
+        return s.x + value
+    fc = compile(f, [float])
+    res = fc(42.42)
+    assert res == f(42.42)
+
+
 def test_offset_inside_fixed_array():
     S = lltype.FixedSizeArray(lltype.Signed, 10)
     offset = FieldOffset(S, 'item4')


More information about the pypy-commit mailing list