[pypy-commit] pypy default: cast_uint_to_float and cast_float_to_uint are needed for
arigo
noreply at buildbot.pypy.org
Mon Oct 24 15:32:26 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r48374:9977c322a23b
Date: 2011-10-24 15:32 +0200
http://bitbucket.org/pypy/pypy/changeset/9977c322a23b/
Log: cast_uint_to_float and cast_float_to_uint are needed for micronumpy.
Implement them (hopefully correctly now) as a residual call for now.
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -443,6 +443,8 @@
rewrite_op_gc_identityhash = _do_builtin_call
rewrite_op_gc_id = _do_builtin_call
rewrite_op_uint_mod = _do_builtin_call
+ rewrite_op_cast_float_to_uint = _do_builtin_call
+ rewrite_op_cast_uint_to_float = _do_builtin_call
# ----------
# getfield/setfield/mallocs etc.
@@ -850,38 +852,43 @@
size1, unsigned1 = rffi.size_and_sign(v_arg.concretetype)
assert size1 <= rffi.sizeof(lltype.Signed), (
"not implemented: cast_longlong_to_float")
- assert size1 < rffi.sizeof(lltype.Signed) or not unsigned1, (
- "not implemented: cast_uint_to_float")
+ from_uint = (unsigned1 and size1 == rffi.sizeof(lltype.Signed))
#
ops = []
- v1 = varoftype(lltype.Signed)
- oplist = self.rewrite_operation(
- SpaceOperation('force_cast', [v_arg], v1)
- )
- if oplist:
- ops.extend(oplist)
+ v2 = varoftype(lltype.Float)
+ if not from_uint:
+ v1 = varoftype(lltype.Signed)
+ oplist = self.rewrite_operation(
+ SpaceOperation('force_cast', [v_arg], v1)
+ )
+ if oplist:
+ ops.extend(oplist)
+ else:
+ v1 = v_arg
+ op = self.rewrite_operation(
+ SpaceOperation('cast_int_to_float', [v1], v2)
+ )
+ ops.append(op)
else:
- v1 = v_arg
- v2 = varoftype(lltype.Float)
- op = self.rewrite_operation(
- SpaceOperation('cast_int_to_float', [v1], v2)
- )
- ops.append(op)
+ ops1 = self.rewrite_operation(
+ SpaceOperation('cast_uint_to_float', [v_arg], v2)
+ )
+ if not isinstance(ops1, list): ops1 = [ops1]
+ ops.extend(ops1)
op2 = self.rewrite_operation(
SpaceOperation('force_cast', [v2], v_result)
)
if op2:
ops.append(op2)
else:
- op.result = v_result
+ ops[-1].result = v_result
return ops
elif float_arg and not float_res:
# some float -> some int
size2, unsigned2 = rffi.size_and_sign(v_result.concretetype)
assert size2 <= rffi.sizeof(lltype.Signed), (
"not implemented: cast_float_to_longlong")
- assert size2 < rffi.sizeof(lltype.Signed) or not unsigned2, (
- "not implemented: cast_float_to_uint")
+ to_uint = (unsigned2 and size2 == rffi.sizeof(lltype.Signed))
#
ops = []
v1 = varoftype(lltype.Float)
@@ -892,18 +899,25 @@
ops.append(op1)
else:
v1 = v_arg
- v2 = varoftype(lltype.Signed)
- op = self.rewrite_operation(
- SpaceOperation('cast_float_to_int', [v1], v2)
- )
- ops.append(op)
- oplist = self.rewrite_operation(
- SpaceOperation('force_cast', [v2], v_result)
- )
- if oplist:
- ops.extend(oplist)
+ if not to_uint:
+ v2 = varoftype(lltype.Signed)
+ op = self.rewrite_operation(
+ SpaceOperation('cast_float_to_int', [v1], v2)
+ )
+ ops.append(op)
+ oplist = self.rewrite_operation(
+ SpaceOperation('force_cast', [v2], v_result)
+ )
+ if oplist:
+ ops.extend(oplist)
+ else:
+ op.result = v_result
else:
- op.result = v_result
+ ops1 = self.rewrite_operation(
+ SpaceOperation('cast_float_to_uint', [v1], v_result)
+ )
+ if not isinstance(ops1, list): ops1 = [ops1]
+ ops.extend(ops1)
return ops
else:
assert False
@@ -1109,8 +1123,6 @@
# The new operation is optionally further processed by rewrite_operation().
for _old, _new in [('bool_not', 'int_is_zero'),
('cast_bool_to_float', 'cast_int_to_float'),
- ('cast_uint_to_float', 'cast_primitive'),
- ('cast_float_to_uint', 'cast_primitive'),
('int_add_nonneg_ovf', 'int_add_ovf'),
('keepalive', '-live-'),
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -229,6 +229,13 @@
else:
return x
+def _ll_1_cast_uint_to_float(x):
+ return llop.cast_uint_to_float(lltype.Float, x)
+
+def _ll_1_cast_float_to_uint(x):
+ return llop.cast_float_to_uint(lltype.Unsigned, x)
+
+
# math support
# ------------
diff --git a/pypy/jit/codewriter/test/test_flatten.py b/pypy/jit/codewriter/test/test_flatten.py
--- a/pypy/jit/codewriter/test/test_flatten.py
+++ b/pypy/jit/codewriter/test/test_flatten.py
@@ -70,7 +70,8 @@
return 'residual'
def getcalldescr(self, op, oopspecindex=None, extraeffect=None):
try:
- if 'cannot_raise' in op.args[0].value._obj.graph.name:
+ name = op.args[0].value._obj._name
+ if 'cannot_raise' in name or name.startswith('cast_'):
return self._descr_cannot_raise
except AttributeError:
pass
@@ -900,6 +901,35 @@
int_return %i4
""", transform=True)
+ def f(dbl):
+ return rffi.cast(rffi.UCHAR, dbl)
+ self.encoding_test(f, [12.456], """
+ cast_float_to_int %f0 -> %i0
+ int_and %i0, $255 -> %i1
+ int_return %i1
+ """, transform=True)
+
+ def f(dbl):
+ return rffi.cast(lltype.Unsigned, dbl)
+ self.encoding_test(f, [12.456], """
+ residual_call_irf_i $<* fn cast_float_to_uint>, <Descr>, I[], R[], F[%f0] -> %i0
+ int_return %i0
+ """, transform=True)
+
+ def f(i):
+ return rffi.cast(lltype.Float, chr(i)) # "char -> float"
+ self.encoding_test(f, [12], """
+ cast_int_to_float %i0 -> %f0
+ float_return %f0
+ """, transform=True)
+
+ def f(i):
+ return rffi.cast(lltype.Float, r_uint(i)) # "uint -> float"
+ self.encoding_test(f, [12], """
+ residual_call_irf_f $<* fn cast_uint_to_float>, <Descr>, I[%i0], R[], F[] -> %f0
+ float_return %f0
+ """, transform=True)
+
def test_direct_ptradd(self):
from pypy.rpython.lltypesystem import rffi
diff --git a/pypy/jit/metainterp/test/test_float.py b/pypy/jit/metainterp/test/test_float.py
--- a/pypy/jit/metainterp/test/test_float.py
+++ b/pypy/jit/metainterp/test/test_float.py
@@ -55,11 +55,10 @@
def test_cast_float_to_uint(self):
def g(f):
return intmask(r_uint(f))
- raises(AssertionError, self.interp_operations, g, [0.0]) # for now
- #res = self.interp_operations(g, [sys.maxint*2.0])
- #assert res == intmask(long(sys.maxint*2.0))
- #res = self.interp_operations(g, [-12345.9])
- #assert res == -12345
+ res = self.interp_operations(g, [sys.maxint*2.0])
+ assert res == intmask(long(sys.maxint*2.0))
+ res = self.interp_operations(g, [-12345.9])
+ assert res == -12345
def test_cast_int_to_float(self):
def g(i):
@@ -70,11 +69,10 @@
def test_cast_uint_to_float(self):
def g(i):
return float(r_uint(i))
- raises(AssertionError, self.interp_operations, g, [0]) # for now
- #res = self.interp_operations(g, [sys.maxint*2])
- #assert type(res) is float and res == float(sys.maxint*2)
- #res = self.interp_operations(g, [-12345])
- #assert type(res) is float and res == float(long(r_uint(-12345)))
+ res = self.interp_operations(g, [intmask(sys.maxint*2)])
+ assert type(res) is float and res == float(sys.maxint*2)
+ res = self.interp_operations(g, [-12345])
+ assert type(res) is float and res == float(long(r_uint(-12345)))
#def test_cast_longlong_to_float(self):
#def test_cast_ulonglong_to_float(self):
More information about the pypy-commit
mailing list