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

Reply via email to