[pypy-commit] pypy stm: long long support.
arigo
noreply at buildbot.pypy.org
Fri Oct 7 14:58:16 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: stm
Changeset: r47852:959f6f983474
Date: 2011-10-07 13:14 +0200
http://bitbucket.org/pypy/pypy/changeset/959f6f983474/
Log: long long support.
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,12 +19,17 @@
fieldsize = rffi.sizeof(T)
if fieldsize >= size_of_voidp:
assert 1 # xxx assert somehow that the field is aligned
- assert fieldsize == size_of_voidp # XXX
+ if fieldsize == size_of_voidp:
+ funcname = 'stm_read_word'
+ elif fieldsize == 8: # 32-bit only: read a 64-bit field
+ funcname = 'stm_read_doubleword'
+ else:
+ raise NotImplementedError(fieldsize)
expr = structdef.ptr_access_expr(basename,
fieldname,
baseexpr_is_const)
- return '%s = (%s)stm_read_word((long*)&%s);' % (
- newvalue, cfieldtypename, expr)
+ return '%s = (%s)%s((long*)&%s);' % (
+ newvalue, cfieldtypename, funcname, expr)
else:
# assume that the object is aligned, and any possible misalignment
# comes from the field offset, so that it can be resolved at
@@ -48,12 +53,19 @@
fieldsize = rffi.sizeof(T)
if fieldsize >= size_of_voidp:
assert 1 # xxx assert somehow that the field is aligned
- assert fieldsize == size_of_voidp # XXX
+ if fieldsize == size_of_voidp:
+ funcname = 'stm_write_word'
+ newtype = 'long'
+ elif fieldsize == 8: # 32-bit only: read a 64-bit field
+ funcname = 'stm_write_doubleword'
+ newtype = 'long long'
+ else:
+ raise NotImplementedError(fieldsize)
expr = structdef.ptr_access_expr(basename,
fieldname,
baseexpr_is_const)
- return 'stm_write_word((long*)&%s, (long)%s);' % (
- expr, newvalue)
+ return '%s((long*)&%s, (%s)%s);' % (
+ funcname, expr, newtype, newvalue)
else:
cfieldtypename = cdecl(fieldtypename, '')
return ('stm_write_partial_word(sizeof(%s), (char*)%s, '
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
@@ -4,6 +4,7 @@
from pypy.translator.stm import _rffi_stm
from pypy.annotation import model as annmodel
from pypy.objspace.flow.model import Constant
+from pypy.rlib.rarithmetic import r_uint, r_ulonglong
size_of_voidp = rffi.sizeof(rffi.VOIDP)
assert size_of_voidp & (size_of_voidp - 1) == 0
@@ -22,8 +23,14 @@
p = rffi.cast(_rffi_stm.SignedP, p - misalignment)
if fieldsize >= size_of_voidp:
assert misalignment == 0
- assert fieldsize == size_of_voidp # XXX
- res = _rffi_stm.stm_read_word(p)
+ if fieldsize == size_of_voidp:
+ res = _rffi_stm.stm_read_word(p)
+ elif fieldsize == 8: # 32-bit only: read a 64-bit field
+ res0 = r_uint(_rffi_stm.stm_read_word(p))
+ res1 = r_uint(_rffi_stm.stm_read_word(rffi.ptradd(p, 1)))
+ res = (r_ulonglong(res1) << 32) | res0
+ else:
+ raise NotImplementedError(fieldsize)
else:
assert misalignment + fieldsize <= size_of_voidp
res = _rffi_stm.stm_read_word(p)
@@ -42,8 +49,15 @@
p = rffi.cast(_rffi_stm.SignedP, p - misalignment)
if fieldsize >= size_of_voidp:
assert misalignment == 0
- assert fieldsize == size_of_voidp # XXX
- _rffi_stm.stm_write_word(p, rffi.cast(lltype.Signed, 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
+ _rffi_stm.stm_write_word(p, rffi.cast(lltype.Signed, newvalue))
+ p = rffi.ptradd(p, 1)
+ newvalue = rffi.cast(lltype.SignedLongLong, newvalue) >> 32
+ _rffi_stm.stm_write_word(p, rffi.cast(lltype.Signed, newvalue))
+ else:
+ raise NotImplementedError(fieldsize)
#print 'ok'
else:
# bah, must read the complete word in order to modify only a part
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
@@ -773,3 +773,18 @@
val = (val & mask) | (word & ~mask);
stm_write_word(p, val);
}
+
+long long stm_read_doubleword(long *addr)
+{
+ /* 32-bit only */
+ unsigned long res0 = (unsigned long)stm_read_word(addr);
+ unsigned long res1 = (unsigned long)stm_read_word(addr + 1);
+ return (((unsigned long long)res1) << 32) | res0;
+}
+
+void stm_write_doubleword(long *addr, long long val)
+{
+ /* 32-bit only */
+ stm_write_word(addr, (long)val);
+ stm_write_word(addr + 1, (long)(val >> 32));
+}
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,5 +35,8 @@
void stm_write_partial_word(int fieldsize, char *base, long offset, long nval);
+long long stm_read_doubleword(long *addr);
+void stm_write_doubleword(long *addr, long long val);
+
#endif /* _ET_H */
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,11 +2,14 @@
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
A = lltype.Struct('A', ('x', lltype.Signed), ('y', lltype.Signed),
('c1', lltype.Char), ('c2', lltype.Char),
- ('c3', lltype.Char))
+ ('c3', lltype.Char), ('l', lltype.SignedLongLong))
+rll1 = r_longlong(-10000000000003)
+rll2 = r_longlong(-300400500600700)
def callback1(a):
a = rffi.cast(lltype.Ptr(A), a)
@@ -14,10 +17,12 @@
assert a.c1 == '/'
assert a.c2 == '\\'
assert a.c3 == '!'
+ assert a.l == rll1
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
p = lltype.direct_fieldptr(a, 'x')
p = rffi.cast(SignedP, p)
stm_write_word(p, 42 * a.y)
@@ -35,6 +40,7 @@
a.c2 = '\\'
a.c3 = '!'
a.y = 0
+ a.l = rll1
descriptor_init()
perform_transaction(llhelper(CALLBACK, callback1),
rffi.cast(rffi.VOIDP, a))
@@ -43,6 +49,7 @@
assert a.c1 == '/'
assert a.c2 == '\\'
assert a.c3 == '!'
+ assert a.l == rll1
lltype.free(a, flavor='raw')
def callback2(a):
@@ -51,22 +58,27 @@
assert a.c1 == '&'
assert a.c2 == '*'
assert a.c3 == '#'
+ assert a.l == rll1
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
stm_setfield(a, 'x', 42 * a.y)
stm_setfield(a, 'c1', '(')
stm_setfield(a, 'c2', '?')
stm_setfield(a, 'c3', ')')
+ stm_setfield(a, 'l', rll2)
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 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
if a.y < 10:
a.y += 1 # non-transactionally
abort_and_retry()
@@ -79,6 +91,7 @@
a.c2 = '*'
a.c3 = '#'
a.y = 0
+ a.l = rll1
descriptor_init()
perform_transaction(llhelper(CALLBACK, callback2),
rffi.cast(rffi.VOIDP, a))
@@ -87,6 +100,7 @@
assert a.c1 == '('
assert a.c2 == '?'
assert a.c3 == ')'
+ assert a.l == rll2
lltype.free(a, flavor='raw')
# ____________________________________________________________
More information about the pypy-commit
mailing list