[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