[pypy-commit] pypy r15-for-exception: Complete pypy.rlib.register.

arigo noreply at buildbot.pypy.org
Sat Jul 9 11:17:26 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: r15-for-exception
Changeset: r45431:871dc1fecff3
Date: 2011-07-08 19:48 +0200
http://bitbucket.org/pypy/pypy/changeset/871dc1fecff3/

Log:	Complete pypy.rlib.register.

diff --git a/pypy/translator/register.py b/pypy/rlib/register.py
rename from pypy/translator/register.py
rename to pypy/rlib/register.py
--- a/pypy/translator/register.py
+++ b/pypy/rlib/register.py
@@ -15,21 +15,50 @@
 
 # For now, only for x86-64.  Tries to use the register r15.
 eci = ExternalCompilationInfo(
-    post_include_bits=['register void* pypy_reg asm("r15");'],
+    post_include_bits=['register void* pypy_r15 asm("r15");\n'
+                       '#define PYPY_GET_R15() pypy_r15\n'
+                       '#define PYPY_SET_R15(x) (pypy_r15 = x)\n'
+                       ],
     )
 
 _test_eci = eci.merge(ExternalCompilationInfo(
     post_include_bits=["""
             void f(void) {
-                pypy_reg = &f;
+                pypy_r15 = &f;
             }
     """]))
 
 try:
     rffi_platform.verify_eci(_test_eci)
-    var_name_in_c = 'pypy_reg'
     register_number = 15      # r15
 except rffi_platform.CompilationError:
     eci = None
-    var_name_in_c = None
     register_number = None
+else:
+
+    from pypy.rpython.lltypesystem import lltype, llmemory, rffi
+
+    # use load_from_reg(TYPE) and store_into_reg(llvalue) to load and store
+    # a value out of the special register.  When running on top of Python.
+    # the behavior is emulated.
+
+    _value_reg = None
+
+    def _pypy_get_r15():
+        assert _value_reg is not None
+        return _value_reg
+
+    def _pypy_set_r15(addr):
+        global _value_reg
+        _value_reg = addr
+
+    load_from_reg = rffi.llexternal('PYPY_GET_R15', [], llmemory.Address,
+                                    _callable=_pypy_get_r15,
+                                    compilation_info=eci,
+                                    _nowrapper=True)
+
+    store_into_reg = rffi.llexternal('PYPY_SET_R15', [llmemory.Address],
+                                     lltype.Void,
+                                     _callable=_pypy_set_r15,
+                                     compilation_info=eci,
+                                     _nowrapper=True)
diff --git a/pypy/translator/test/test_register.py b/pypy/rlib/test/test_register.py
rename from pypy/translator/test/test_register.py
rename to pypy/rlib/test/test_register.py
--- a/pypy/translator/test/test_register.py
+++ b/pypy/rlib/test/test_register.py
@@ -1,13 +1,48 @@
+import py
+from pypy.rlib import register
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi
+
 
 def test_register():
-    from pypy.translator import register
     #
     from pypy.jit.backend.detect_cpu import autodetect
     if autodetect() == 'x86_64':
         assert register.eci is not None
-        assert register.var_name_in_c is not None
         assert register.register_number == 15        # r15
     else:
         assert register.eci is None
-        assert register.var_name_in_c is None
         assert register.register_number is None
+
+
+class TestLoadStore(object):
+    def setup_class(cls):
+        if register.register_number is None:
+            py.test.skip("rlib/register not supported on this platform")
+
+    def test_direct(self):
+        a = rffi.cast(llmemory.Address, 27)
+        register.store_into_reg(a)
+        b = register.load_from_reg()
+        assert lltype.typeOf(b) == llmemory.Address
+        assert rffi.cast(lltype.Signed, b) == 27
+
+    def test_llinterp(self):
+        from pypy.rpython.test.test_llinterp import interpret
+        def f(n):
+            a = rffi.cast(llmemory.Address, n)
+            register.store_into_reg(a)
+            b = register.load_from_reg()
+            return rffi.cast(lltype.Signed, b)
+        res = interpret(f, [41])
+        assert res == 41
+
+    def test_compiled(self):
+        from pypy.translator.c.test.test_genc import compile
+        def f(n):
+            a = rffi.cast(llmemory.Address, n)
+            register.store_into_reg(a)
+            b = register.load_from_reg()
+            return rffi.cast(lltype.Signed, b)
+        cfn = compile(f, [int])
+        res = cfn(43)
+        assert res == 43


More information about the pypy-commit mailing list