[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