[pypy-commit] pypy libgccjit-backend: Get test_field_basic to pass
dmalcolm
noreply at buildbot.pypy.org
Tue Dec 23 15:13:56 CET 2014
Author: David Malcolm <dmalcolm at redhat.com>
Branch: libgccjit-backend
Changeset: r75081:7842cdbb5db6
Date: 2014-12-23 09:21 -0500
http://bitbucket.org/pypy/pypy/changeset/7842cdbb5db6/
Log: Get test_field_basic to pass
diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py
--- a/rpython/jit/backend/libgccjit/assembler.py
+++ b/rpython/jit/backend/libgccjit/assembler.py
@@ -4,7 +4,7 @@
from rpython.jit.backend.llsupport.regalloc import FrameManager
from rpython.jit.backend.model import CompiledLoopToken
from rpython.jit.backend.libgccjit.rffi_bindings import make_eci, Library, make_param_array, make_field_array, Context, Type
-from rpython.jit.metainterp.history import BoxInt, ConstInt, BoxFloat, ConstFloat
+from rpython.jit.metainterp.history import BoxInt, ConstInt, BoxFloat, ConstFloat, BoxPtr, ConstPtr
from rpython.jit.metainterp.resoperation import *
from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref, cast_object_to_ptr
from rpython.rtyper.lltypesystem.rffi import *
@@ -196,12 +196,15 @@
self.t_bool = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_BOOL)
self.t_void_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR)
self.t_void = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID)
+ self.t_char_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_CHAR).get_pointer()
self.u_signed = self.ctxt.new_field(self.t_Signed, "u_signed")
self.u_float = self.ctxt.new_field(self.t_float, "u_float")
+ self.u_ptr = self.ctxt.new_field(self.t_void_ptr, "u_ptr")
self.t_any = self.ctxt.new_union_type ("any",
[self.u_signed,
- self.u_float])
+ self.u_float,
+ self.u_ptr])
def setup(self, looptoken):
allblocks = self.get_asmmemmgr_blocks(looptoken)
@@ -429,7 +432,7 @@
print(' %s' % expr.__dict__)
"""
- if isinstance(expr, (BoxInt, BoxFloat)):
+ if isinstance(expr, (BoxInt, BoxFloat, BoxPtr)):
return self.get_box_as_lvalue(expr).as_rvalue()
elif isinstance(expr, ConstInt):
#print('value: %r' % expr.value)
@@ -441,6 +444,11 @@
#print('type(value): %r' % type(expr.value))
return self.ctxt.new_rvalue_from_double(self.t_float,
expr.value)#r_double(expr.value))
+ elif isinstance(expr, ConstPtr):
+ #print('value: %r' % expr.value)
+ #print('type(value): %r' % type(expr.value))
+ return self.ctxt.new_rvalue_from_ptr(self.t_void_ptr,
+ expr.value)
raise ValueError('unhandled expr: %s %s' % (expr, type(expr)))
def get_box_as_lvalue(self, box):
@@ -463,7 +471,7 @@
print(' %s' % dir(expr))
print(' %s' % expr.__dict__)
"""
- if isinstance(expr, (BoxInt, BoxFloat)):
+ if isinstance(expr, (BoxInt, BoxFloat, BoxPtr)):
return self.get_box_as_lvalue(expr)
raise ValueError('unhandled expr: %s' % expr)
@@ -473,6 +481,8 @@
return self.t_Signed;
elif isinstance(box, BoxFloat):
return self.t_float;
+ elif isinstance(box, BoxPtr):
+ return self.t_void_ptr;
else:
raise ValueError('unhandled box: %s %s' % (box, type(box)))
@@ -481,6 +491,8 @@
return self.u_signed;
elif isinstance(expr, (BoxFloat, ConstFloat)):
return self.u_float;
+ elif isinstance(expr, (BoxPtr, ConstPtr)):
+ return self.u_ptr;
else:
raise ValueError('unhandled expr: %s %s' % (expr, type(expr)))
@@ -788,3 +800,72 @@
self.impl_float_cmp(resop, self.lib.GCC_JIT_COMPARISON_GT)
def emit_float_ge(self, resop):
self.impl_float_cmp(resop, self.lib.GCC_JIT_COMPARISON_GE)
+
+ def impl_get_lvalue_for_field(self, ptr_expr, fielddescr):
+ assert isinstance(ptr_expr, (BoxPtr, ConstPtr))
+ #print(fielddescr)
+ #print(dir(fielddescr))
+ #print('fielddescr.field_size: %r' % fielddescr.field_size)
+
+ ptr = self.expr_to_rvalue(ptr_expr)
+
+ # Cast to (char *) so we can use offset:
+ # ((char *)ARG0)
+ ptr = self.ctxt.new_cast(ptr, self.t_char_ptr)
+
+ # ((char *)ARG0)[offset]
+ ptr = self.ctxt.new_array_access(
+ ptr,
+ self.ctxt.new_rvalue_from_int(self.t_Signed,
+ r_int(fielddescr.offset)))
+
+ # (char **)(((char *)ARG0)[offset])
+ field_ptr_address = ptr.get_address ()
+
+ # ...and cast back to the correct type:
+ if fielddescr.is_pointer_field():
+ t_field = self.t_void_ptr
+ elif fielddescr.is_float_field():
+ # FIXME: do we need to handle C float vs C double?
+ t_field = self.t_float
+ else:
+ t_field = self.ctxt.get_int_type(r_int(fielddescr.field_size),
+ r_int(fielddescr.is_field_signed()))
+
+ # (T *)(char **)(((char *)ARG0)[offset])
+ field_ptr = self.ctxt.new_cast(field_ptr_address,
+ t_field.get_pointer())
+
+ # and dereference:
+ # *(T *)(char **)(((char *)ARG0)[offset])
+ field_lvalue = field_ptr.dereference()
+
+ return field_lvalue, t_field
+
+ def emit_getfield_gc(self, resop):
+ #print(repr(resop))
+ assert isinstance(resop._arg0, (BoxPtr, ConstPtr))
+ lvalres = self.expr_to_lvalue(resop.result)
+ field_lvalue, t_field = self.impl_get_lvalue_for_field(
+ resop._arg0,
+ resop.getdescr())
+ self.b_current.add_assignment(
+ lvalres,
+ self.ctxt.new_cast(field_lvalue.as_rvalue(),
+ self.get_type_for_box(resop.result)))
+
+ def emit_setfield_gc(self, resop):
+ #print(repr(resop))
+ assert isinstance(resop._arg0, (BoxPtr, ConstPtr))
+ #print(resop._arg1)
+
+ field_lvalue, t_field = self.impl_get_lvalue_for_field(
+ resop._arg0,
+ resop.getdescr())
+
+ self.b_current.add_assignment(
+ field_lvalue,
+
+ # ... = ARG1,
+ self.ctxt.new_cast(self.expr_to_rvalue(resop._arg1),
+ t_field))
diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py
--- a/rpython/jit/backend/libgccjit/rffi_bindings.py
+++ b/rpython/jit/backend/libgccjit/rffi_bindings.py
@@ -308,6 +308,12 @@
self.GCC_JIT_TYPE_P]),
(self.GCC_JIT_LVALUE_P,
+ 'gcc_jit_context_new_array_access', [self.GCC_JIT_CONTEXT_P,
+ self.GCC_JIT_LOCATION_P,
+ self.GCC_JIT_RVALUE_P,
+ self.GCC_JIT_RVALUE_P]),
+
+ (self.GCC_JIT_LVALUE_P,
'gcc_jit_lvalue_access_field', [self.GCC_JIT_LVALUE_P,
self.GCC_JIT_LOCATION_P,
self.GCC_JIT_FIELD_P]),
@@ -317,6 +323,14 @@
self.GCC_JIT_LOCATION_P,
self.GCC_JIT_FIELD_P]),
+ (self.GCC_JIT_LVALUE_P,
+ 'gcc_jit_rvalue_dereference', [self.GCC_JIT_RVALUE_P,
+ self.GCC_JIT_LOCATION_P]),
+
+ (self.GCC_JIT_RVALUE_P,
+ 'gcc_jit_lvalue_get_address', [self.GCC_JIT_LVALUE_P,
+ self.GCC_JIT_LOCATION_P]),
+
############################################################
# Statement-creation.
############################################################
@@ -698,6 +712,15 @@
rvalue.inner_rvalue,
type_.inner_type))
+ def new_array_access(self, ptr, index):
+ return LValue(self.lib,
+ self,
+ self.lib.gcc_jit_context_new_array_access(
+ self.inner_ctxt,
+ self.lib.null_location_ptr,
+ ptr.inner_rvalue,
+ index.inner_rvalue))
+
class LibgccjitError(Exception):
def __init__(self, ctxt):
self.msg = charp2str(ctxt.lib.gcc_jit_context_get_last_error (ctxt.inner_ctxt))
@@ -763,6 +786,13 @@
self.lib.null_location_ptr,
field.inner_field))
+ def dereference(self):
+ return LValue(self.lib,
+ self,
+ self.lib.gcc_jit_rvalue_dereference(
+ self.inner_rvalue,
+ self.lib.null_location_ptr))
+
class LValue(Object):
def __init__(self, lib, ctxt, inner_lvalue):
Object.__init__(self, lib, ctxt, inner_lvalue)
@@ -780,6 +810,13 @@
self.lib.null_location_ptr,
field.inner_field))
+ def get_address(self):
+ return RValue(self.lib,
+ self,
+ self.lib.gcc_jit_lvalue_get_address(
+ self.inner_lvalue,
+ self.lib.null_location_ptr))
+
class Param(Object):
def __init__(self, lib, ctxt, inner_param):
Object.__init__(self, lib, ctxt, inner_param)
More information about the pypy-commit
mailing list