[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