[pypy-commit] pypy stm: Single floats.
arigo
noreply at buildbot.pypy.org
Fri Oct 7 14:58:18 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: stm
Changeset: r47854:2e13d3c1cb12
Date: 2011-10-07 14:55 +0200
http://bitbucket.org/pypy/pypy/changeset/2e13d3c1cb12/
Log: Single floats.
diff --git a/pypy/translator/stm/_rffi_stm.py b/pypy/translator/stm/_rffi_stm.py
--- a/pypy/translator/stm/_rffi_stm.py
+++ b/pypy/translator/stm/_rffi_stm.py
@@ -24,7 +24,7 @@
descriptor_init = llexternal('stm_descriptor_init', [], lltype.Void)
descriptor_done = llexternal('stm_descriptor_done', [], lltype.Void)
-begin_transaction = llexternal('stm_begin_transaction_inline',[], lltype.Void)
+begin_transaction = llexternal('STM_begin_transaction',[], lltype.Void)
commit_transaction = llexternal('stm_commit_transaction', [], lltype.Signed)
stm_read_word = llexternal('stm_read_word', [SignedP], lltype.Signed)
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
@@ -17,10 +17,12 @@
#
assert T is not lltype.Void # XXX
fieldsize = rffi.sizeof(T)
- if fieldsize >= size_of_voidp:
+ if fieldsize >= size_of_voidp or T == lltype.SingleFloat:
assert 1 # xxx assert somehow that the field is aligned
if T == lltype.Float:
funcname = 'stm_read_double'
+ elif T == lltype.SingleFloat:
+ funcname = 'stm_read_float'
elif fieldsize == size_of_voidp:
funcname = 'stm_read_word'
elif fieldsize == 8: # 32-bit only: read a 64-bit field
@@ -36,7 +38,7 @@
# assume that the object is aligned, and any possible misalignment
# comes from the field offset, so that it can be resolved at
# compile-time (by using C macros)
- return '%s = stm_read_partial_word(%s, %s, offsetof(%s, %s));' % (
+ return '%s = STM_read_partial_word(%s, %s, offsetof(%s, %s));' % (
newvalue, cfieldtypename, basename,
cdecl(funcgen.db.gettype(STRUCT), ''),
structdef.c_struct_field_name(fieldname))
@@ -53,11 +55,14 @@
#
assert T is not lltype.Void # XXX
fieldsize = rffi.sizeof(T)
- if fieldsize >= size_of_voidp:
+ if fieldsize >= size_of_voidp or T == lltype.SingleFloat:
assert 1 # xxx assert somehow that the field is aligned
if T == lltype.Float:
funcname = 'stm_write_double'
newtype = 'double'
+ elif T == lltype.SingleFloat:
+ funcname = 'stm_write_float'
+ newtype = 'float'
elif fieldsize == size_of_voidp:
funcname = 'stm_write_word'
newtype = 'long'
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
@@ -38,6 +38,8 @@
assert misalignment + fieldsize <= size_of_voidp
res = _rffi_stm.stm_read_word(p)
res = res >> (misalignment * 8)
+ if FIELD == lltype.SingleFloat:
+ return longlong2float.uint2singlefloat(rffi.cast(rffi.UINT, res))
return rffi.cast(FIELD, res)
def stm_setfield(structptr, fieldname, newvalue):
@@ -50,6 +52,8 @@
fieldsize = rffi.sizeof(FIELD)
#print 'setfield %x size %d:' % (p, fieldsize),
p = rffi.cast(_rffi_stm.SignedP, p - misalignment)
+ if FIELD == lltype.SingleFloat:
+ newvalue = longlong2float.singlefloat2uint(newvalue)
if fieldsize >= size_of_voidp:
assert misalignment == 0
if FIELD == lltype.Float:
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
@@ -588,7 +588,7 @@
void* stm_perform_transaction(void*(*callback)(void*), void *arg)
{
void *result;
- stm_begin_transaction_inline();
+ STM_begin_transaction();
result = callback(arg);
stm_commit_transaction();
return result;
@@ -763,13 +763,14 @@
}
// XXX little-endian only!
-void stm_write_partial_word(int fieldsize, char *base, long offset, long nval)
+void stm_write_partial_word(int fieldsize, char *base, long offset,
+ unsigned long nval)
{
long *p = (long*)(base + (offset & ~(sizeof(void*)-1)));
int misalignment = offset & (sizeof(void*)-1);
long val = nval << (misalignment * 8);
long word = stm_read_word(p);
- long mask = ((1 << (fieldsize * 8)) - 1) << (misalignment * 8);
+ long mask = ((1L << (fieldsize * 8)) - 1) << (misalignment * 8);
val = (val & mask) | (word & ~mask);
stm_write_word(p, val);
}
@@ -812,3 +813,34 @@
else
stm_write_word(addr, ll); /* 64 bits */
}
+
+float stm_read_float(long *addr)
+{
+ unsigned int x;
+ float ff;
+ if (sizeof(float) == sizeof(long))
+ x = stm_read_word(addr); /* 32 bits */
+ else if (((long)(char*)addr) & 7) {
+ addr = (long *)(((char *)addr) - 4);
+ x = (unsigned int)(stm_read_word(addr) >> 32); /* 64 bits, unaligned */
+ }
+ else
+ x = (unsigned int)stm_read_word(addr); /* 64 bits, aligned */
+ assert(sizeof(float) == 4 && sizeof(unsigned int) == 4);
+ memcpy(&ff, &x, 4);
+ return ff;
+}
+
+void stm_write_float(long *addr, float val)
+{
+ unsigned int ii;
+ assert(sizeof(float) == 4 && sizeof(unsigned int) == 4);
+ memcpy(&ii, &val, 4);
+ if (sizeof(float) == sizeof(long))
+ stm_write_word(addr, ii); /* 32 bits */
+ else if (((long)(char*)addr) & 7)
+ stm_write_partial_word(4, (((char *)addr) - 4),
+ 4, ii); /* 64 bits, unaligned */
+ else
+ stm_write_partial_word(4, (char *)addr, 0, ii); /* 64 bits, aligned */
+}
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
@@ -22,21 +22,24 @@
void stm_begin_inevitable_transaction(void);
void stm_abort_and_retry(void);
-#define stm_begin_transaction_inline() ; \
+#define STM_begin_transaction() ; \
jmp_buf _jmpbuf; \
setjmp(_jmpbuf); \
stm_begin_transaction(&_jmpbuf)
// XXX little-endian only!
-#define stm_read_partial_word(T, base, offset) \
+#define STM_read_partial_word(T, base, offset) \
(T)(stm_read_word( \
(long*)(((char*)(base)) + ((offset) & ~(sizeof(void*)-1)))) \
>> (8 * ((offset) & (sizeof(void*)-1))))
-void stm_write_partial_word(int fieldsize, char *base, long offset, long nval);
+void stm_write_partial_word(int fieldsize, char *base, long offset,
+ unsigned long nval);
double stm_read_double(long *addr);
void stm_write_double(long *addr, double val);
+float stm_read_float(long *addr);
+void stm_write_float(long *addr, float 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
@@ -2,17 +2,22 @@
from pypy.translator.stm._rffi_stm import *
from pypy.translator.stm.rstm import *
from pypy.rpython.annlowlevel import llhelper
-from pypy.rlib.rarithmetic import r_longlong
+from pypy.rlib.rarithmetic import r_longlong, r_singlefloat
A = lltype.Struct('A', ('x', lltype.Signed), ('y', lltype.Signed),
('c1', lltype.Char), ('c2', lltype.Char),
('c3', lltype.Char), ('l', lltype.SignedLongLong),
- ('f', lltype.Float))
+ ('f', lltype.Float), ('sa', lltype.SingleFloat),
+ ('sb', lltype.SingleFloat))
rll1 = r_longlong(-10000000000003)
rll2 = r_longlong(-300400500600700)
rf1 = -12.38976129
rf2 = 52.1029
+rs1a = r_singlefloat(-0.598127)
+rs2a = r_singlefloat(0.017634)
+rs1b = r_singlefloat(40.121)
+rs2b = r_singlefloat(-9e9)
def callback1(a):
a = rffi.cast(lltype.Ptr(A), a)
@@ -22,12 +27,16 @@
assert a.c3 == '!'
assert a.l == rll1
assert a.f == rf1
+ assert float(a.sa) == float(rs1a)
+ assert float(a.sb) == float(rs1b)
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
+ assert float(stm_getfield(a, 'sa')) == float(rs1a)
+ assert float(stm_getfield(a, 'sb')) == float(rs1b)
p = lltype.direct_fieldptr(a, 'x')
p = rffi.cast(SignedP, p)
stm_write_word(p, 42 * a.y)
@@ -47,6 +56,8 @@
a.y = 0
a.l = rll1
a.f = rf1
+ a.sa = rs1a
+ a.sb = rs1b
descriptor_init()
perform_transaction(llhelper(CALLBACK, callback1),
rffi.cast(rffi.VOIDP, a))
@@ -57,6 +68,8 @@
assert a.c3 == '!'
assert a.l == rll1
assert a.f == rf1
+ assert float(a.sa) == float(rs1a)
+ assert float(a.sb) == float(rs1b)
lltype.free(a, flavor='raw')
def callback2(a):
@@ -67,30 +80,40 @@
assert a.c3 == '#'
assert a.l == rll1
assert a.f == rf1
+ assert float(a.sa) == float(rs1a)
+ assert float(a.sb) == float(rs1b)
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
+ assert float(stm_getfield(a, 'sa')) == float(rs1a)
+ assert float(stm_getfield(a, 'sb')) == float(rs1b)
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)
+ stm_setfield(a, 'sa', rs2a)
+ stm_setfield(a, 'sb', rs2b)
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 float(stm_getfield(a, 'sa')) == float(rs2a)
+ assert float(stm_getfield(a, 'sb')) == float(rs2b)
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
+ assert float(a.sa) == float(rs1a)
+ assert float(a.sb) == float(rs1b)
if a.y < 10:
a.y += 1 # non-transactionally
abort_and_retry()
@@ -105,6 +128,8 @@
a.y = 0
a.l = rll1
a.f = rf1
+ a.sa = rs1a
+ a.sb = rs1b
descriptor_init()
perform_transaction(llhelper(CALLBACK, callback2),
rffi.cast(rffi.VOIDP, a))
@@ -115,6 +140,8 @@
assert a.c3 == ')'
assert a.l == rll2
assert a.f == rf2
+ assert float(a.sa) == float(rs2a)
+ assert float(a.sb) == float(rs2b)
lltype.free(a, flavor='raw')
# ____________________________________________________________
More information about the pypy-commit
mailing list