[pypy-commit] pypy numpy-record-dtypes: implement byteswap with the hope of being rpython

fijal noreply at buildbot.pypy.org
Tue Feb 7 10:13:48 CET 2012


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-record-dtypes
Changeset: r52157:e88c9ea41096
Date: 2012-02-07 11:13 +0200
http://bitbucket.org/pypy/pypy/changeset/e88c9ea41096/

Log:	implement byteswap with the hope of being rpython

diff --git a/pypy/rlib/rarithmetic.py b/pypy/rlib/rarithmetic.py
--- a/pypy/rlib/rarithmetic.py
+++ b/pypy/rlib/rarithmetic.py
@@ -513,3 +513,31 @@
     if not objectmodel.we_are_translated():
         assert n <= p
     return llop.int_between(lltype.Bool, n, m, p)
+
+ at objectmodel.specialize.argtype(0)
+def byteswap(arg):
+    """ Convert little->big endian and the opposite
+    """
+    from pypy.rpython.lltypesystem import lltype, rffi
+    
+    T = lltype.typeOf(arg)
+    if T != rffi.LONGLONG and T != rffi.ULONGLONG and T != rffi.UINT:
+        arg = rffi.cast(lltype.Signed, arg)
+        # XXX we cannot do arithmetics on small ints
+    if rffi.sizeof(T) == 1:
+        res = arg
+    elif rffi.sizeof(T) == 2:
+        a, b = arg & 0xFF, arg & 0xFF00
+        res = (a << 8) | (b >> 8)
+    elif rffi.sizeof(T) == 4:
+        a, b, c, d = arg & 0xFF, arg & 0xFF00, arg & 0xFF0000, arg & 0xFF000000
+        res = (a << 24) | (b << 8) | (c >> 8) | (d >> 24)
+    elif rffi.sizeof(T) == 8:
+        a, b, c, d = arg & 0xFF, arg & 0xFF00, arg & 0xFF0000, arg & 0xFF000000
+        e, f, g, h = (arg & (0xFF << 32), arg & (0xFF << 40),
+                      arg & (0xFF << 48), arg & (0xFF << 56))
+        res = ((a << 56) | (b << 40) | (c << 24) | (d << 8) | (e >> 8) |
+               (f >> 24) | (g >> 40) | (h >> 56))
+    else:
+        assert False # unreachable code
+    return rffi.cast(T, res)
diff --git a/pypy/rlib/test/test_rarithmetic.py b/pypy/rlib/test/test_rarithmetic.py
--- a/pypy/rlib/test/test_rarithmetic.py
+++ b/pypy/rlib/test/test_rarithmetic.py
@@ -374,3 +374,9 @@
     assert not int_between(1, 2, 2)
     assert not int_between(1, 1, 1)
 
+def test_byteswap():
+    from pypy.rpython.lltypesystem import rffi
+    
+    assert byteswap(rffi.cast(rffi.USHORT, 0x0102)) == 0x0201
+    assert byteswap(rffi.cast(rffi.INT, 0x01020304)) == 0x04030201
+    assert byteswap(rffi.cast(rffi.ULONGLONG, 0x0102030405060708L)) == 0x0807060504030201L


More information about the pypy-commit mailing list