[pypy-svn] r20372 - in pypy/dist/pypy/translator/llvm: . module test

rxe at codespeak.net rxe at codespeak.net
Mon Nov 28 22:41:32 CET 2005


Author: rxe
Date: Mon Nov 28 22:41:27 2005
New Revision: 20372

Added:
   pypy/dist/pypy/translator/llvm/test/test_lladdresses.py   (contents, props changed)
Modified:
   pypy/dist/pypy/translator/llvm/database.py
   pypy/dist/pypy/translator/llvm/module/genexterns.c
   pypy/dist/pypy/translator/llvm/opwriter.py
Log:
Quick hacks to make address ops work (opwriter needs a refactor).



Modified: pypy/dist/pypy/translator/llvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/database.py	(original)
+++ pypy/dist/pypy/translator/llvm/database.py	Mon Nov 28 22:41:27 2005
@@ -12,6 +12,7 @@
      OpaqueTypeNode, ExtOpaqueTypeNode
 from pypy.rpython.lltypesystem import lltype
 from pypy.objspace.flow.model import Constant, Variable
+from pypy.rpython.memory.lladdress import Address, NULL
             
 log = log.database 
 
@@ -34,7 +35,8 @@
             lltype.Bool: "bool",
             lltype.Float: "double",
             lltype.UniChar: "uint",
-            lltype.Void: "void"}
+            lltype.Void: "void",
+            Address: "sbyte*"}
 
         # 32 bit platform
         if sys.maxint == 2**31-1:
@@ -311,7 +313,7 @@
     def repr_tmpvar(self): 
         count = self._tmpcount 
         self._tmpcount += 1
-        return "%tmp." + str(count) 
+        return "%tmp_" + str(count) 
 
     def repr_constructor(self, type_):
         return self.obj2node[type_].constructor_ref
@@ -354,6 +356,9 @@
             repr = str(ord(value))
         elif type_ is lltype.Float:
             repr = self.float_to_str(value)
+        elif type_ is Address:
+            assert value == NULL
+            repr = 'null' 
         else:
             repr = str(value)
         return repr

Modified: pypy/dist/pypy/translator/llvm/module/genexterns.c
==============================================================================
--- pypy/dist/pypy/translator/llvm/module/genexterns.c	(original)
+++ pypy/dist/pypy/translator/llvm/module/genexterns.c	Mon Nov 28 22:41:27 2005
@@ -45,6 +45,19 @@
   return NULL;
 }
 
+
+char *raw_malloc(int size) {
+  return malloc(size);
+}
+
+void raw_free(void *ptr) {
+  free(ptr);
+}
+
+void raw_memcopy(char *ptr1, char *ptr2, int size) {
+  memcpy((void *) ptr2, (void *) ptr1, size);
+}
+
 #include <gc/gc.h>
 #define USING_BOEHM_GC
 
@@ -56,6 +69,7 @@
 }
 
 char *pypy_malloc_atomic(unsigned int size) {
+  // use the macros luke
   return GC_MALLOC_ATOMIC(size);
 }
 

Modified: pypy/dist/pypy/translator/llvm/opwriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/opwriter.py	(original)
+++ pypy/dist/pypy/translator/llvm/opwriter.py	Mon Nov 28 22:41:27 2005
@@ -509,3 +509,144 @@
         targetvar = self.db.repr_arg(op.result)
         targettype = self.db.repr_arg_type(op.result)
         self.codewriter.load(targetvar, targettype, tmpvar)
+
+    def adr_delta(self, op):
+        tmp = self.db.repr_tmpvar
+        addr1, addr2 = tmp(), tmp()
+        arg1, argtype1 = self.db.repr_argwithtype(op.args[0])
+        arg2, argtype2 = self.db.repr_argwithtype(op.args[1])
+        self.codewriter.cast(addr1, argtype1, arg1, "int")
+        self.codewriter.cast(addr2, argtype2, arg2, "int")
+        targetvar = self.db.repr_arg(op.result)
+        targettype = self.db.repr_arg_type(op.result)
+        self.codewriter.binaryop("sub",
+                                 targetvar, targettype,
+                                 addr1, addr2,)
+
+    def _op_adr_generic(self, op, llvm_op):
+        tmp = self.db.repr_tmpvar
+        addr, res = tmp(), tmp()
+        arg, argtype = self.db.repr_argwithtype(op.args[0])
+        self.codewriter.cast(addr, argtype, arg, "int")
+        arg2, argtype2 = self.db.repr_argwithtype(op.args[1])        
+        self.codewriter.binaryop(llvm_op,
+                                 res, "int",
+                                 addr, arg2)
+        targetvar = self.db.repr_arg(op.result)
+        targettype = self.db.repr_arg_type(op.result)
+        self.codewriter.cast(targetvar, "int", res, targettype)
+
+    def adr_add(self, op):
+        self._op_adr_generic(op, "add")
+
+    def adr_sub(self, op):
+        self._op_adr_generic(op, "sub")
+
+    def _op_adr_comparison_generic(self, op, llvm_op):
+        tmp = self.db.repr_tmpvar
+        addr1, addr2 = tmp(), tmp()
+        arg1, argtype1 = self.db.repr_argwithtype(op.args[0])
+        arg2, argtype2 = self.db.repr_argwithtype(op.args[1])
+        self.codewriter.cast(addr1, argtype1, arg1, "int")
+        self.codewriter.cast(addr2, argtype2, arg2, "int")
+        targetvar = self.db.repr_arg(op.result)
+        targettype = self.db.repr_arg_type(op.result)
+        assert targettype == "bool"
+        self.codewriter.binaryop(llvm_op,
+                                 targetvar, "int",
+                                 addr1, addr2)
+
+    def adr_eq(self, op):
+        self._op_adr_comparison_generic(op, "seteq")
+
+    def adr_ne(self, op):
+        self._op_adr_comparison_generic(op, "setne")
+
+    def adr_le(self, op):
+        self._op_adr_comparison_generic(op, "setle")
+
+    def adr_gt(self, op):
+        self._op_adr_comparison_generic(op, "setgt")
+
+    def adr_lt(self, op):
+        self._op_adr_comparison_generic(op, "setlt")
+
+    def adr_ge(self, op):
+        self._op_adr_comparison_generic(op, "setge")
+
+    def raw_malloc(self, op):
+        # XXX Ignore raise as not last op
+        targetvar = self.db.repr_arg(op.result)
+        targettype = self.db.repr_arg_type(op.result)
+        argrefs = self.db.repr_arg_multi(op.args)
+        argtypes = self.db.repr_arg_type_multi(op.args)
+        self.codewriter.call(targetvar, targettype, "%raw_malloc",
+                             argrefs, argtypes)
+    def raw_free(self, op):
+        targetvar = self.db.repr_arg(op.result)
+        targettype = self.db.repr_arg_type(op.result)
+        argrefs = self.db.repr_arg_multi(op.args)
+        argtypes = self.db.repr_arg_type_multi(op.args)
+        self.codewriter.call(targetvar, targettype, "%raw_free",
+                             argrefs, argtypes)
+
+    def raw_memcopy(self, op):
+        targetvar = self.db.repr_arg(op.result)
+        targettype = self.db.repr_arg_type(op.result)
+        argrefs = self.db.repr_arg_multi(op.args)
+        argtypes = self.db.repr_arg_type_multi(op.args)
+        self.codewriter.call(targetvar, targettype, "%raw_memcopy",
+                             argrefs, argtypes)
+
+    def raw_store(self, op):
+        tmp = self.db.repr_tmpvar
+
+        # XXX what is dummy suppose to be?
+        (arg_addr, arg_dummy,
+         arg_incr, arg_value) = self.db.repr_arg_multi(op.args)
+        (argtype_addr, argtype_dummy,
+         argtype_incr, argtype_value) = self.db.repr_arg_type_multi(op.args)
+
+        cast_addr = tmp()
+        addr_type = argtype_value + "*"
+
+        # cast to the correct type before arithmetic/storing
+        self.codewriter.cast(cast_addr, argtype_addr, arg_addr, addr_type)
+
+        # pointer arithmetic
+        if arg_incr:
+            incr_addr = tmp()
+            self.codewriter.raw_getelementptr(incr_addr,
+                                              addr_type,
+                                              cast_addr,
+                                              ("int", arg_incr))
+            cast_addr = incr_addr
+        self.codewriter.store(argtype_value, arg_value, cast_addr)
+
+        
+    def raw_load(self, op):
+        tmp = self.db.repr_tmpvar
+
+        # XXX what is dummy suppose to be?
+        arg_addr, arg_dummy, arg_incr = self.db.repr_arg_multi(op.args)
+        argtype_addr, argtype_dummy, argtype_incr = \
+                                      self.db.repr_arg_type_multi(op.args)
+        targetvar = self.db.repr_arg(op.result)
+        targettype = self.db.repr_arg_type(op.result)
+
+        cast_addr = tmp()
+        addr_type = targettype + "*"
+
+        # cast to the correct type before arithmetic/loading
+        self.codewriter.cast(cast_addr, argtype_addr, arg_addr, addr_type)
+        # pointer arithmetic
+        if arg_incr:
+            incr_addr = tmp()
+            self.codewriter.raw_getelementptr(incr_addr,
+                                              addr_type,
+                                              cast_addr,
+                                              ("int", arg_incr))
+            cast_addr = incr_addr
+
+        self.codewriter.load(targetvar, targettype, cast_addr) 
+        

Added: pypy/dist/pypy/translator/llvm/test/test_lladdresses.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/llvm/test/test_lladdresses.py	Mon Nov 28 22:41:27 2005
@@ -0,0 +1,103 @@
+from pypy.rpython.memory.lladdress import *
+from pypy.annotation.model import SomeAddress, SomeChar
+from pypy.translator.llvm.test.runtest import compile_function as compile
+import py
+
+def test_null():
+    def f():
+        return NULL - NULL
+    fc = compile(f, [])
+
+def test_convert_to_bool():
+    def convert_to_bool(x):
+        if x:
+            return bool(NULL)
+        else:
+            return bool(NULL + 1)
+    fc = compile(convert_to_bool, [int])
+    res = fc(1)
+    assert isinstance(res, int) and not res
+    res = fc(0)
+    assert isinstance(res, int) and res
+
+def test_memory_access():
+    def f(value):
+        addr = raw_malloc(16)
+        addr.signed[0] = value
+        return addr.signed[0]
+    fc = compile(f, [int])
+    res = fc(42)
+    assert res == 42
+    res = fc(1)
+    assert res == 1
+
+def test_memory_access2():
+    def f(value1, value2):
+        addr = raw_malloc(16)
+        addr.signed[0] = value1
+        addr.signed[1] = value2
+        return addr.signed[0] + addr.signed[1]
+    fc = compile(f, [int, int])
+    res = fc(23, 19)
+    assert res == 42
+    res = fc(42, -59)
+    assert res == -17
+    
+def test_pointer_arithmetic():
+    def f(offset, char):
+        char = chr(char)
+        addr = raw_malloc(10000)
+        same_offset = (addr + 2 * offset - offset) - addr 
+        addr.char[offset] = char
+        result = (addr + same_offset).char[0]
+        raw_free(addr)
+        return ord(result)
+    fc = compile(f, [int, int])
+    res = fc(10, ord("c"))
+    assert res == ord("c")
+    res = fc(12, ord("x"))
+    assert res == ord("x")
+
+def test_pointer_arithmetic_inplace():
+    def f(offset, char):
+        char = chr(char)
+        addr = raw_malloc(10000)
+        addr += offset
+        addr.char[-offset] = char
+        addr -= offset
+        return ord(addr.char[0])
+    fc = compile(f, [int, int])
+    res = fc(10, ord("c"))
+    assert res == ord("c")
+
+def test_raw_memcopy():
+    def f():
+        addr = raw_malloc(100)
+        addr.signed[0] = 12
+        (addr + 10).signed[0] = 42
+        (addr + 20).char[0] = "a"
+        addr1 = raw_malloc(100)
+        raw_memcopy(addr, addr1, 100)
+        result = addr1.signed[0] == 12
+        result += (addr1 + 10).signed[0] == 42
+        result += (addr1 + 20).char[0] == "a"
+        return result
+    fc = compile(f, [])
+    res = fc()
+    assert res == 3
+
+def test_pointer_comparison():
+    def f():
+        result = 0
+        for addr1 in [raw_malloc(1), NULL]:
+            addr2 = addr1 + 1
+            result = result * 2 + int(addr1 == addr2)
+            result = result * 2 + int(addr1 != addr2)
+            result = result * 2 + int(addr1 <  addr2)
+            result = result * 2 + int(addr1 <= addr2)
+            result = result * 2 + int(addr1 >  addr2)
+            result = result * 2 + int(addr1 >= addr2)
+        return result
+    fc = compile(f, [])
+    res = fc()
+    assert res == int('011100' * 2, 2)



More information about the Pypy-commit mailing list