Author: Armin Rigo <[email protected]>
Branch: ffi-backend
Changeset: r55811:b8dc5e65e118
Date: 2012-06-24 21:30 +0200
http://bitbucket.org/pypy/pypy/changeset/b8dc5e65e118/
Log: (fijal, arigo) We added tests and removed code. Progress. We also
broke stuff, but well, later.
diff --git a/pypy/jit/backend/llgraph/llimpl.py
b/pypy/jit/backend/llgraph/llimpl.py
--- a/pypy/jit/backend/llgraph/llimpl.py
+++ b/pypy/jit/backend/llgraph/llimpl.py
@@ -21,7 +21,6 @@
from pypy.jit.backend.llgraph import symbolic
from pypy.jit.codewriter import longlong
-from pypy.rlib import libffi, clibffi
from pypy.rlib.objectmodel import ComputedIntSymbolic, we_are_translated
from pypy.rlib.rarithmetic import ovfcheck
from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint
@@ -850,7 +849,7 @@
elif arraydescr.typeinfo == INT:
return do_raw_load_int(addr, offset, arraydescr.ofs)
elif arraydescr.typeinfo == FLOAT:
- xxx
+ return do_raw_load_float(addr, offset, arraydescr.ofs)
else:
raise NotImplementedError
@@ -939,9 +938,7 @@
raise NotImplementedError
def op_setfield_raw(self, fielddescr, struct, newvalue):
- if fielddescr.arg_types == 'dynamic': # abuse of .arg_types
- do_setfield_raw_dynamic(struct, fielddescr, newvalue)
- elif fielddescr.typeinfo == REF:
+ if fielddescr.typeinfo == REF:
do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue)
elif fielddescr.typeinfo == INT:
do_setfield_raw_int(struct, fielddescr.ofs, newvalue)
@@ -1496,18 +1493,6 @@
struct = array._obj.container.getitem(index)
return cast_to_ptr(_getinteriorfield_gc(struct, fieldnum))
-def _getinteriorfield_raw(ffitype, array, index, width, ofs):
- addr = rffi.cast(rffi.VOIDP, array)
- return libffi.array_getitem(ffitype, width, addr, index, ofs)
-
-def do_getinteriorfield_raw_int(array, index, width, ofs):
- res = _getinteriorfield_raw(libffi.types.slong, array, index, width, ofs)
- return res
-
-def do_getinteriorfield_raw_float(array, index, width, ofs):
- res = _getinteriorfield_raw(libffi.types.double, array, index, width, ofs)
- return res
-
def _getfield_raw(struct, fieldnum):
STRUCT, fieldname = symbolic.TokenToField[fieldnum]
ptr = cast_from_int(lltype.Ptr(STRUCT), struct)
@@ -1522,17 +1507,6 @@
def do_getfield_raw_ptr(struct, fieldnum):
return cast_to_ptr(_getfield_raw(struct, fieldnum))
-def do_getfield_raw_dynamic(struct, fielddescr):
- from pypy.rlib import libffi
- addr = cast_from_int(rffi.VOIDP, struct)
- ofs = fielddescr.ofs
- if fielddescr.is_pointer_field():
- assert False, 'fixme'
- elif fielddescr.is_float_field():
- assert False, 'fixme'
- else:
- return libffi._struct_getfield(lltype.Signed, addr, ofs)
-
def do_raw_load_int(struct, offset, descrofs):
TYPE = symbolic.Size2Type[descrofs]
ll_p = rffi.cast(rffi.CCHARP, struct)
@@ -1540,6 +1514,13 @@
value = ll_p[0]
return rffi.cast(lltype.Signed, value)
+def do_raw_load_float(struct, offset, descrofs):
+ TYPE = symbolic.Size2Type[descrofs]
+ ll_p = rffi.cast(rffi.CCHARP, struct)
+ ll_p = rffi.cast(lltype.Ptr(TYPE), rffi.ptradd(ll_p, offset))
+ value = ll_p[0]
+ return rffi.cast(lltype.Float, value)
+
def do_raw_store_int(struct, offset, descrofs, value):
TYPE = symbolic.Size2Type[descrofs]
ll_p = rffi.cast(rffi.CCHARP, struct)
@@ -1610,18 +1591,6 @@
do_setinteriorfield_gc_float = new_setinteriorfield_gc(cast_from_floatstorage)
do_setinteriorfield_gc_ptr = new_setinteriorfield_gc(cast_from_ptr)
-def new_setinteriorfield_raw(cast_func, ffitype):
- def do_setinteriorfield_raw(array, index, newvalue, width, ofs):
- addr = rffi.cast(rffi.VOIDP, array)
- for TYPE, ffitype2 in clibffi.ffitype_map:
- if ffitype2 is ffitype:
- newvalue = cast_func(TYPE, newvalue)
- break
- return libffi.array_setitem(ffitype, width, addr, index, ofs, newvalue)
- return do_setinteriorfield_raw
-do_setinteriorfield_raw_int = new_setinteriorfield_raw(cast_from_int,
libffi.types.slong)
-do_setinteriorfield_raw_float =
new_setinteriorfield_raw(cast_from_floatstorage, libffi.types.double)
-
def do_setfield_raw_int(struct, fieldnum, newvalue):
STRUCT, fieldname = symbolic.TokenToField[fieldnum]
ptr = cast_from_int(lltype.Ptr(STRUCT), struct)
@@ -1643,17 +1612,6 @@
newvalue = cast_from_ptr(FIELDTYPE, newvalue)
setattr(ptr, fieldname, newvalue)
-def do_setfield_raw_dynamic(struct, fielddescr, newvalue):
- from pypy.rlib import libffi
- addr = cast_from_int(rffi.VOIDP, struct)
- ofs = fielddescr.ofs
- if fielddescr.is_pointer_field():
- assert False, 'fixme'
- elif fielddescr.is_float_field():
- assert False, 'fixme'
- else:
- libffi._struct_setfield(lltype.Signed, addr, ofs, newvalue)
-
def do_newstr(length):
x = rstr.mallocstr(length)
return cast_to_ptr(x)
diff --git a/pypy/jit/backend/llsupport/descr.py
b/pypy/jit/backend/llsupport/descr.py
--- a/pypy/jit/backend/llsupport/descr.py
+++ b/pypy/jit/backend/llsupport/descr.py
@@ -237,29 +237,6 @@
cache[(ARRAY, name)] = descr
return descr
-def compute_flag(is_pointer, is_float, is_signed):
- if is_pointer:
- assert not is_float
- return FLAG_POINTER
- elif is_float:
- return FLAG_FLOAT
- elif is_signed:
- return FLAG_SIGNED
- else:
- return FLAG_UNSIGNED
-
-def get_dynamic_field_descr(offset, fieldsize, is_pointer, is_float,
is_signed):
- flag = compute_flag(is_pointer, is_float, is_signed)
- return FieldDescr('dynamic', offset, fieldsize, flag)
-
-def get_dynamic_interiorfield_descr(gc_ll_descr, offset, width, fieldsize,
- is_pointer, is_float, is_signed):
- arraydescr = ArrayDescr(0, width, None, FLAG_STRUCT)
- flag = compute_flag(is_pointer, is_float, is_signed)
- fielddescr = FieldDescr('dynamic', offset, fieldsize, flag)
- return InteriorFieldDescr(arraydescr, fielddescr)
-
-
# ____________________________________________________________
# CallDescrs
diff --git a/pypy/jit/backend/test/runner_test.py
b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -3340,6 +3340,58 @@
fail = self.cpu.execute_token(looptoken2, -9)
assert fail.identifier == 42
+ def test_raw_load_int(self):
+ from pypy.rlib import rawstorage
+ for T in [rffi.UCHAR, rffi.SIGNEDCHAR,
+ rffi.USHORT, rffi.SHORT,
+ rffi.UINT, rffi.INT,
+ rffi.ULONG, rffi.LONG]:
+ ops = """
+ [i0, i1]
+ i2 = raw_load(i0, i1, descr=arraydescr)
+ finish(i2)
+ """
+ arraydescr = self.cpu.arraydescrof(rffi.CArray(T))
+ p = rawstorage.alloc_raw_storage(31)
+ for i in range(31):
+ p[i] = '\xDD'
+ value = rffi.cast(T, 0x4243444546474849)
+ rawstorage.raw_storage_setitem(p, 16, value)
+ loop = parse(ops, self.cpu, namespace=locals())
+ looptoken = JitCellToken()
+ self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+ self.cpu.execute_token(looptoken,
+ rffi.cast(lltype.Signed, p), 16)
+ result = self.cpu.get_latest_value_int(0)
+ assert result == rffi.cast(lltype.Signed, value)
+ rawstorage.free_raw_storage(p)
+
+ def test_raw_load_float(self):
+ if not self.cpu.supports_floats:
+ py.test.skip("requires floats")
+ from pypy.rlib import rawstorage
+ for T in [rffi.DOUBLE]:
+ ops = """
+ [i0, i1]
+ f2 = raw_load(i0, i1, descr=arraydescr)
+ finish(f2)
+ """
+ arraydescr = self.cpu.arraydescrof(rffi.CArray(T))
+ p = rawstorage.alloc_raw_storage(31)
+ for i in range(31):
+ p[i] = '\xDD'
+ value = rffi.cast(T, 1.12e20)
+ rawstorage.raw_storage_setitem(p, 16, value)
+ loop = parse(ops, self.cpu, namespace=locals())
+ looptoken = JitCellToken()
+ self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+ self.cpu.execute_token(looptoken,
+ rffi.cast(lltype.Signed, p), 16)
+ result = self.cpu.get_latest_value_float(0)
+ result = longlong.getrealfloat(result)
+ assert result == rffi.cast(lltype.Float, value)
+ rawstorage.free_raw_storage(p)
+
class OOtypeBackendTest(BaseBackendTest):
diff --git a/pypy/jit/backend/x86/assembler.py
b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -1570,9 +1570,6 @@
ofs_loc)
self.load_from_mem(resloc, src_addr, fieldsize_loc, sign_loc)
- genop_getinteriorfield_raw = genop_getinteriorfield_gc
-
-
def genop_discard_setfield_gc(self, op, arglocs):
base_loc, ofs_loc, size_loc, value_loc = arglocs
assert isinstance(size_loc, ImmedLoc)
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -1166,8 +1166,6 @@
self.Perform(op, [base_loc, ofs, itemsize, fieldsize,
index_loc, temp_loc, sign_loc], result_loc)
- consider_getinteriorfield_raw = consider_getinteriorfield_gc
-
def consider_int_is_true(self, op, guard_op):
# doesn't need arg to be in a register
argloc = self.loc(op.getarg(0))
diff --git a/pypy/jit/metainterp/executor.py b/pypy/jit/metainterp/executor.py
--- a/pypy/jit/metainterp/executor.py
+++ b/pypy/jit/metainterp/executor.py
@@ -363,6 +363,7 @@
rop.DEBUG_MERGE_POINT,
rop.JIT_DEBUG,
rop.SETARRAYITEM_RAW,
+ rop.SETINTERIORFIELD_RAW,
rop.CALL_RELEASE_GIL,
rop.QUASIIMMUT_FIELD,
rop.CALL_MALLOC_GC,
diff --git a/pypy/jit/metainterp/optimizeopt/fficall.py
b/pypy/jit/metainterp/optimizeopt/fficall.py
--- a/pypy/jit/metainterp/optimizeopt/fficall.py
+++ b/pypy/jit/metainterp/optimizeopt/fficall.py
@@ -120,12 +120,6 @@
ops = self.do_push_arg(op)
elif oopspec == EffectInfo.OS_LIBFFI_CALL:
ops = self.do_call(op)
- elif (oopspec == EffectInfo.OS_LIBFFI_STRUCT_GETFIELD or
- oopspec == EffectInfo.OS_LIBFFI_STRUCT_SETFIELD):
- ops = self.do_struct_getsetfield(op, oopspec)
- elif (oopspec == EffectInfo.OS_LIBFFI_GETARRAYITEM or
- oopspec == EffectInfo.OS_LIBFFI_SETARRAYITEM):
- ops = self.do_getsetarrayitem(op, oopspec)
#
for op in ops:
self.emit_operation(op)
@@ -200,97 +194,6 @@
ops.append(newop)
return ops
- def do_struct_getsetfield(self, op, oopspec):
- ffitypeval = self.getvalue(op.getarg(1))
- addrval = self.getvalue(op.getarg(2))
- offsetval = self.getvalue(op.getarg(3))
- if not ffitypeval.is_constant() or not offsetval.is_constant():
- return [op]
- #
- ffitypeaddr = ffitypeval.box.getaddr()
- ffitype = llmemory.cast_adr_to_ptr(ffitypeaddr, clibffi.FFI_TYPE_P)
- offset = offsetval.box.getint()
- descr = self._get_field_descr(ffitype, offset)
- #
- arglist = [addrval.force_box(self.optimizer)]
- if oopspec == EffectInfo.OS_LIBFFI_STRUCT_GETFIELD:
- opnum = rop.GETFIELD_RAW
- else:
- opnum = rop.SETFIELD_RAW
- newval = self.getvalue(op.getarg(4))
- arglist.append(newval.force_box(self.optimizer))
- #
- newop = ResOperation(opnum, arglist, op.result, descr=descr)
- return [newop]
-
- def _get_field_descr(self, ffitype, offset):
- kind = libffi.types.getkind(ffitype)
- is_pointer = is_float = is_signed = False
- if ffitype is libffi.types.pointer:
- is_pointer = True
- elif kind == 'i':
- is_signed = True
- elif kind == 'f' or kind == 'I' or kind == 'U':
- # longlongs are treated as floats, see e.g.
llsupport/descr.py:getDescrClass
- is_float = True
- else:
- assert False, "unsupported ffitype or kind"
- #
- fieldsize = intmask(ffitype.c_size)
- return self.optimizer.cpu.fielddescrof_dynamic(offset, fieldsize,
- is_pointer, is_float,
is_signed)
-
- def do_getsetarrayitem(self, op, oopspec):
- ffitypeval = self.getvalue(op.getarg(1))
- widthval = self.getvalue(op.getarg(2))
- offsetval = self.getvalue(op.getarg(5))
- if not ffitypeval.is_constant() or not widthval.is_constant() or not
offsetval.is_constant():
- return [op]
-
- ffitypeaddr = ffitypeval.box.getaddr()
- ffitype = llmemory.cast_adr_to_ptr(ffitypeaddr, clibffi.FFI_TYPE_P)
- offset = offsetval.box.getint()
- width = widthval.box.getint()
- descr = self._get_interior_descr(ffitype, width, offset)
-
- arglist = [
- self.getvalue(op.getarg(3)).force_box(self.optimizer),
- self.getvalue(op.getarg(4)).force_box(self.optimizer),
- ]
- if oopspec == EffectInfo.OS_LIBFFI_GETARRAYITEM:
- opnum = rop.GETINTERIORFIELD_RAW
- elif oopspec == EffectInfo.OS_LIBFFI_SETARRAYITEM:
- opnum = rop.SETINTERIORFIELD_RAW
-
arglist.append(self.getvalue(op.getarg(6)).force_box(self.optimizer))
- else:
- assert False
- return [
- ResOperation(opnum, arglist, op.result, descr=descr),
- ]
-
- def _get_interior_descr(self, ffitype, width, offset):
- kind = libffi.types.getkind(ffitype)
- is_pointer = is_float = is_signed = False
- if ffitype is libffi.types.pointer:
- is_pointer = True
- elif kind == 'i':
- is_signed = True
- elif kind == 'f' or kind == 'I' or kind == 'U':
- # longlongs are treated as floats, see
- # e.g. llsupport/descr.py:getDescrClass
- is_float = True
- elif kind == 'u' or kind == 's':
- # they're all False
- pass
- else:
- raise NotImplementedError("unsupported ffitype or kind: %s" % kind)
- #
- fieldsize = rffi.getintfield(ffitype, 'c_size')
- return self.optimizer.cpu.interiorfielddescrof_dynamic(
- offset, width, fieldsize, is_pointer, is_float, is_signed
- )
-
-
def propagate_forward(self, op):
if self.logops is not None:
debug_print(self.logops.repr_of_resop(op))
diff --git a/pypy/jit/metainterp/resoperation.py
b/pypy/jit/metainterp/resoperation.py
--- a/pypy/jit/metainterp/resoperation.py
+++ b/pypy/jit/metainterp/resoperation.py
@@ -490,6 +490,7 @@
'SETARRAYITEM_GC/3d',
'SETARRAYITEM_RAW/3d',
'SETINTERIORFIELD_GC/3d',
+ 'SETINTERIORFIELD_RAW/3d', # only used by llsupport/rewrite.py
'RAW_STORE/3d',
'SETFIELD_GC/2d',
'SETFIELD_RAW/2d',
diff --git a/pypy/rlib/libffi.py b/pypy/rlib/libffi.py
--- a/pypy/rlib/libffi.py
+++ b/pypy/rlib/libffi.py
@@ -432,127 +432,3 @@
flags=FUNCFLAG_STDCALL):
return Func(name, argtypes, restype, dlsym_byordinal(self.lib,
name),
flags=flags, keepalive=self)
-
-# ======================================================================
-
[email protected]('libffi_struct_getfield(ffitype, addr, offset)')
-def struct_getfield_int(ffitype, addr, offset):
- """
- Return the field of type ``ffitype`` at ``addr+offset``, widened to
- lltype.Signed.
- """
- for TYPE, ffitype2 in clibffi.ffitype_map_int_or_ptr:
- if ffitype is ffitype2:
- value = _struct_getfield(TYPE, addr, offset)
- return rffi.cast(lltype.Signed, value)
- assert False, "cannot find the given ffitype"
-
-
[email protected]('libffi_struct_setfield(ffitype, addr, offset, value)')
-def struct_setfield_int(ffitype, addr, offset, value):
- """
- Set the field of type ``ffitype`` at ``addr+offset``. ``value`` is of
- type lltype.Signed, and it's automatically converted to the right type.
- """
- for TYPE, ffitype2 in clibffi.ffitype_map_int_or_ptr:
- if ffitype is ffitype2:
- value = rffi.cast(TYPE, value)
- _struct_setfield(TYPE, addr, offset, value)
- return
- assert False, "cannot find the given ffitype"
-
-
[email protected]('libffi_struct_getfield(ffitype, addr, offset)')
-def struct_getfield_longlong(ffitype, addr, offset):
- """
- Return the field of type ``ffitype`` at ``addr+offset``, casted to
- lltype.LongLong.
- """
- value = _struct_getfield(lltype.SignedLongLong, addr, offset)
- return value
-
[email protected]('libffi_struct_setfield(ffitype, addr, offset, value)')
-def struct_setfield_longlong(ffitype, addr, offset, value):
- """
- Set the field of type ``ffitype`` at ``addr+offset``. ``value`` is of
- type lltype.LongLong
- """
- _struct_setfield(lltype.SignedLongLong, addr, offset, value)
-
-
[email protected]('libffi_struct_getfield(ffitype, addr, offset)')
-def struct_getfield_float(ffitype, addr, offset):
- value = _struct_getfield(lltype.Float, addr, offset)
- return value
-
[email protected]('libffi_struct_setfield(ffitype, addr, offset, value)')
-def struct_setfield_float(ffitype, addr, offset, value):
- _struct_setfield(lltype.Float, addr, offset, value)
-
-
[email protected]('libffi_struct_getfield(ffitype, addr, offset)')
-def struct_getfield_singlefloat(ffitype, addr, offset):
- value = _struct_getfield(lltype.SingleFloat, addr, offset)
- return value
-
[email protected]('libffi_struct_setfield(ffitype, addr, offset, value)')
-def struct_setfield_singlefloat(ffitype, addr, offset, value):
- _struct_setfield(lltype.SingleFloat, addr, offset, value)
-
-
[email protected](0)
-def _struct_getfield(TYPE, addr, offset):
- """
- Read the field of type TYPE at addr+offset.
- addr is of type rffi.VOIDP, offset is an int.
- """
- addr = rffi.ptradd(addr, offset)
- PTR_FIELD = lltype.Ptr(rffi.CArray(TYPE))
- return rffi.cast(PTR_FIELD, addr)[0]
-
-
[email protected](0)
-def _struct_setfield(TYPE, addr, offset, value):
- """
- Write the field of type TYPE at addr+offset.
- addr is of type rffi.VOIDP, offset is an int.
- """
- addr = rffi.ptradd(addr, offset)
- PTR_FIELD = lltype.Ptr(rffi.CArray(TYPE))
- rffi.cast(PTR_FIELD, addr)[0] = value
-
-# ======================================================================
-
-# These specialize.call_location's should really be specialize.arg(0), however
-# you can't hash a pointer obj, which the specialize machinery wants to do.
-# Given the present usage of these functions, it's good enough.
[email protected]_location()
[email protected]("libffi_array_getitem(ffitype, width, addr, index, offset)")
-def array_getitem(ffitype, width, addr, index, offset):
- for TYPE, ffitype2 in clibffi.ffitype_map:
- if ffitype is ffitype2:
- addr = rffi.ptradd(addr, index * width)
- addr = rffi.ptradd(addr, offset)
- return rffi.cast(rffi.CArrayPtr(TYPE), addr)[0]
- assert False
-
-def array_getitem_T(TYPE, width, addr, index, offset):
- addr = rffi.ptradd(addr, index * width)
- addr = rffi.ptradd(addr, offset)
- return rffi.cast(rffi.CArrayPtr(TYPE), addr)[0]
-
[email protected]_location()
[email protected]("libffi_array_setitem(ffitype, width, addr, index, offset,
value)")
-def array_setitem(ffitype, width, addr, index, offset, value):
- for TYPE, ffitype2 in clibffi.ffitype_map:
- if ffitype is ffitype2:
- addr = rffi.ptradd(addr, index * width)
- addr = rffi.ptradd(addr, offset)
- rffi.cast(rffi.CArrayPtr(TYPE), addr)[0] = value
- return
- assert False
-
-def array_setitem_T(TYPE, width, addr, index, offset, value):
- addr = rffi.ptradd(addr, index * width)
- addr = rffi.ptradd(addr, offset)
- rffi.cast(rffi.CArrayPtr(TYPE), addr)[0] = value
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit