[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