Author: Armin Rigo <[email protected]>
Branch: stm
Changeset: r47853:aae602a1eca9
Date: 2011-10-07 13:30 +0200
http://bitbucket.org/pypy/pypy/changeset/aae602a1eca9/
Log: Support for 'double'.
diff --git a/pypy/translator/stm/funcgen.py b/pypy/translator/stm/funcgen.py
--- a/pypy/translator/stm/funcgen.py
+++ b/pypy/translator/stm/funcgen.py
@@ -19,7 +19,9 @@
fieldsize = rffi.sizeof(T)
if fieldsize >= size_of_voidp:
assert 1 # xxx assert somehow that the field is aligned
- if fieldsize == size_of_voidp:
+ if T == lltype.Float:
+ funcname = 'stm_read_double'
+ elif fieldsize == size_of_voidp:
funcname = 'stm_read_word'
elif fieldsize == 8: # 32-bit only: read a 64-bit field
funcname = 'stm_read_doubleword'
@@ -53,7 +55,10 @@
fieldsize = rffi.sizeof(T)
if fieldsize >= size_of_voidp:
assert 1 # xxx assert somehow that the field is aligned
- if fieldsize == size_of_voidp:
+ if T == lltype.Float:
+ funcname = 'stm_write_double'
+ newtype = 'double'
+ elif fieldsize == size_of_voidp:
funcname = 'stm_write_word'
newtype = 'long'
elif fieldsize == 8: # 32-bit only: read a 64-bit field
diff --git a/pypy/translator/stm/rstm.py b/pypy/translator/stm/rstm.py
--- a/pypy/translator/stm/rstm.py
+++ b/pypy/translator/stm/rstm.py
@@ -5,6 +5,7 @@
from pypy.annotation import model as annmodel
from pypy.objspace.flow.model import Constant
from pypy.rlib.rarithmetic import r_uint, r_ulonglong
+from pypy.rlib import longlong2float
size_of_voidp = rffi.sizeof(rffi.VOIDP)
assert size_of_voidp & (size_of_voidp - 1) == 0
@@ -31,6 +32,8 @@
res = (r_ulonglong(res1) << 32) | res0
else:
raise NotImplementedError(fieldsize)
+ if FIELD == lltype.Float:
+ return longlong2float.longlong2float(rffi.cast(rffi.LONGLONG, res))
else:
assert misalignment + fieldsize <= size_of_voidp
res = _rffi_stm.stm_read_word(p)
@@ -49,6 +52,8 @@
p = rffi.cast(_rffi_stm.SignedP, p - misalignment)
if fieldsize >= size_of_voidp:
assert misalignment == 0
+ if FIELD == lltype.Float:
+ newvalue = longlong2float.float2longlong(newvalue)
if fieldsize == size_of_voidp:
_rffi_stm.stm_write_word(p, rffi.cast(lltype.Signed, newvalue))
elif fieldsize == 8: # 32-bit only: write a 64-bit field
diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c
--- a/pypy/translator/stm/src_stm/et.c
+++ b/pypy/translator/stm/src_stm/et.c
@@ -788,3 +788,27 @@
stm_write_word(addr, (long)val);
stm_write_word(addr + 1, (long)(val >> 32));
}
+
+double stm_read_double(long *addr)
+{
+ long long x;
+ double dd;
+ if (sizeof(double) > sizeof(long))
+ x = stm_read_doubleword(addr); /* 32 bits */
+ else
+ x = stm_read_word(addr); /* 64 bits */
+ assert(sizeof(double) == 8 && sizeof(long long) == 8);
+ memcpy(&dd, &x, 8);
+ return dd;
+}
+
+void stm_write_double(long *addr, double val)
+{
+ long long ll;
+ assert(sizeof(double) == 8 && sizeof(long long) == 8);
+ memcpy(&ll, &val, 8);
+ if (sizeof(double) > sizeof(long))
+ stm_write_doubleword(addr, ll); /* 32 bits */
+ else
+ stm_write_word(addr, ll); /* 64 bits */
+}
diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h
--- a/pypy/translator/stm/src_stm/et.h
+++ b/pypy/translator/stm/src_stm/et.h
@@ -35,6 +35,8 @@
void stm_write_partial_word(int fieldsize, char *base, long offset, long nval);
+double stm_read_double(long *addr);
+void stm_write_double(long *addr, double val);
long long stm_read_doubleword(long *addr);
void stm_write_doubleword(long *addr, long long val);
diff --git a/pypy/translator/stm/test/test_rstm.py
b/pypy/translator/stm/test/test_rstm.py
--- a/pypy/translator/stm/test/test_rstm.py
+++ b/pypy/translator/stm/test/test_rstm.py
@@ -7,9 +7,12 @@
A = lltype.Struct('A', ('x', lltype.Signed), ('y', lltype.Signed),
('c1', lltype.Char), ('c2', lltype.Char),
- ('c3', lltype.Char), ('l', lltype.SignedLongLong))
+ ('c3', lltype.Char), ('l', lltype.SignedLongLong),
+ ('f', lltype.Float))
rll1 = r_longlong(-10000000000003)
rll2 = r_longlong(-300400500600700)
+rf1 = -12.38976129
+rf2 = 52.1029
def callback1(a):
a = rffi.cast(lltype.Ptr(A), a)
@@ -18,11 +21,13 @@
assert a.c2 == '\\'
assert a.c3 == '!'
assert a.l == rll1
+ assert a.f == rf1
assert stm_getfield(a, 'x') == -611
assert stm_getfield(a, 'c2') == '\\'
assert stm_getfield(a, 'c1') == '/'
assert stm_getfield(a, 'c3') == '!'
assert stm_getfield(a, 'l') == rll1
+ assert stm_getfield(a, 'f') == rf1
p = lltype.direct_fieldptr(a, 'x')
p = rffi.cast(SignedP, p)
stm_write_word(p, 42 * a.y)
@@ -41,6 +46,7 @@
a.c3 = '!'
a.y = 0
a.l = rll1
+ a.f = rf1
descriptor_init()
perform_transaction(llhelper(CALLBACK, callback1),
rffi.cast(rffi.VOIDP, a))
@@ -50,6 +56,7 @@
assert a.c2 == '\\'
assert a.c3 == '!'
assert a.l == rll1
+ assert a.f == rf1
lltype.free(a, flavor='raw')
def callback2(a):
@@ -59,26 +66,31 @@
assert a.c2 == '*'
assert a.c3 == '#'
assert a.l == rll1
+ assert a.f == rf1
assert stm_getfield(a, 'x') == -611
assert stm_getfield(a, 'c1') == '&'
assert stm_getfield(a, 'c2') == '*'
assert stm_getfield(a, 'c3') == '#'
assert stm_getfield(a, 'l') == rll1
+ assert stm_getfield(a, 'f') == rf1
stm_setfield(a, 'x', 42 * a.y)
stm_setfield(a, 'c1', '(')
stm_setfield(a, 'c2', '?')
stm_setfield(a, 'c3', ')')
stm_setfield(a, 'l', rll2)
+ stm_setfield(a, 'f', rf2)
assert stm_getfield(a, 'x') == 42 * a.y
assert stm_getfield(a, 'c1') == '('
assert stm_getfield(a, 'c2') == '?'
assert stm_getfield(a, 'c3') == ')'
assert stm_getfield(a, 'l') == rll2
+ assert stm_getfield(a, 'f') == rf2
assert a.x == -611 # xxx still the old value when reading non-transact.
assert a.c1 == '&'
assert a.c2 == '*'
assert a.c3 == '#'
assert a.l == rll1
+ assert a.f == rf1
if a.y < 10:
a.y += 1 # non-transactionally
abort_and_retry()
@@ -92,6 +104,7 @@
a.c3 = '#'
a.y = 0
a.l = rll1
+ a.f = rf1
descriptor_init()
perform_transaction(llhelper(CALLBACK, callback2),
rffi.cast(rffi.VOIDP, a))
@@ -101,6 +114,7 @@
assert a.c2 == '?'
assert a.c3 == ')'
assert a.l == rll2
+ assert a.f == rf2
lltype.free(a, flavor='raw')
# ____________________________________________________________
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit