[pypy-commit] pypy default: Support casts between floats and (u)longlongs written as a force_cast.
arigo
noreply at buildbot.pypy.org
Mon Oct 24 17:58:24 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r48380:054d434f5e82
Date: 2011-10-24 17:58 +0200
http://bitbucket.org/pypy/pypy/changeset/054d434f5e82/
Log: Support casts between floats and (u)longlongs written as a
force_cast.
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
@@ -849,14 +849,12 @@
return self._float_to_float_cast(v_arg, v_result)
elif not float_arg and float_res:
# some int -> some float
- size1, unsigned1 = rffi.size_and_sign(v_arg.concretetype)
- assert size1 <= rffi.sizeof(lltype.Signed), (
- "not implemented: cast_longlong_to_float")
- from_uint = (unsigned1 and size1 == rffi.sizeof(lltype.Signed))
- #
ops = []
v2 = varoftype(lltype.Float)
- if not from_uint:
+ sizesign = rffi.size_and_sign(v_arg.concretetype)
+ if sizesign <= rffi.size_and_sign(lltype.Signed):
+ # cast from a type that fits in an int: either the size is
+ # smaller, or it is equal and it is not unsigned
v1 = varoftype(lltype.Signed)
oplist = self.rewrite_operation(
SpaceOperation('force_cast', [v_arg], v1)
@@ -870,8 +868,16 @@
)
ops.append(op)
else:
+ if sizesign == rffi.size_and_sign(lltype.Unsigned):
+ opname = 'cast_uint_to_float'
+ elif sizesign == rffi.size_and_sign(lltype.SignedLongLong):
+ opname = 'cast_longlong_to_float'
+ elif sizesign == rffi.size_and_sign(lltype.UnsignedLongLong):
+ opname = 'cast_ulonglong_to_float'
+ else:
+ raise AssertionError('cast_x_to_float: %r' % (sizesign,))
ops1 = self.rewrite_operation(
- SpaceOperation('cast_uint_to_float', [v_arg], v2)
+ SpaceOperation(opname, [v_arg], v2)
)
if not isinstance(ops1, list): ops1 = [ops1]
ops.extend(ops1)
@@ -885,11 +891,6 @@
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")
- to_uint = (unsigned2 and size2 == rffi.sizeof(lltype.Signed))
- #
ops = []
v1 = varoftype(lltype.Float)
op1 = self.rewrite_operation(
@@ -899,7 +900,10 @@
ops.append(op1)
else:
v1 = v_arg
- if not to_uint:
+ sizesign = rffi.size_and_sign(v_result.concretetype)
+ if sizesign <= rffi.size_and_sign(lltype.Signed):
+ # cast to a type that fits in an int: either the size is
+ # smaller, or it is equal and it is not unsigned
v2 = varoftype(lltype.Signed)
op = self.rewrite_operation(
SpaceOperation('cast_float_to_int', [v1], v2)
@@ -913,8 +917,16 @@
else:
op.result = v_result
else:
+ if sizesign == rffi.size_and_sign(lltype.Unsigned):
+ opname = 'cast_float_to_uint'
+ elif sizesign == rffi.size_and_sign(lltype.SignedLongLong):
+ opname = 'cast_float_to_longlong'
+ elif sizesign == rffi.size_and_sign(lltype.UnsignedLongLong):
+ opname = 'cast_float_to_ulonglong'
+ else:
+ raise AssertionError('cast_float_to_x: %r' % (sizesign,))
ops1 = self.rewrite_operation(
- SpaceOperation('cast_float_to_uint', [v1], v_result)
+ SpaceOperation(opname, [v1], v_result)
)
if not isinstance(ops1, list): ops1 = [ops1]
ops.extend(ops1)
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
@@ -230,9 +230,13 @@
return x
def _ll_1_cast_uint_to_float(x):
+ # XXX on 32-bit platforms, this should be done using cast_longlong_to_float
+ # (which is a residual call right now in the x86 backend)
return llop.cast_uint_to_float(lltype.Float, x)
def _ll_1_cast_float_to_uint(x):
+ # XXX on 32-bit platforms, this should be done using cast_float_to_longlong
+ # (which is a residual call right now in the x86 backend)
return llop.cast_float_to_uint(lltype.Unsigned, x)
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
@@ -8,7 +8,7 @@
from pypy.rpython.lltypesystem import lltype, rclass, rstr
from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
from pypy.translator.unsimplify import varoftype
-from pypy.rlib.rarithmetic import ovfcheck, r_uint
+from pypy.rlib.rarithmetic import ovfcheck, r_uint, r_longlong, r_ulonglong
from pypy.rlib.jit import dont_look_inside, _we_are_jitted, JitDriver
from pypy.rlib.objectmodel import keepalive_until_here
from pypy.rlib import jit
@@ -930,6 +930,38 @@
float_return %f0
""", transform=True)
+ if not longlong.is_64_bit:
+ def f(dbl):
+ return rffi.cast(lltype.SignedLongLong, dbl)
+ self.encoding_test(f, [12.3], """
+ residual_call_irf_f $<* fn llong_from_float>, <Descr>, I[], R[], F[%f0] -> %f1
+ float_return %f1
+ """, transform=True)
+
+ def f(dbl):
+ return rffi.cast(lltype.UnsignedLongLong, dbl)
+ self.encoding_test(f, [12.3], """
+ residual_call_irf_f $<* fn ullong_from_float>, <Descr>, I[], R[], F[%f0] -> %f1
+ float_return %f1
+ """, transform=True)
+
+ def f(x):
+ ll = r_longlong(x)
+ return rffi.cast(lltype.Float, ll)
+ self.encoding_test(f, [12], """
+ residual_call_irf_f $<* fn llong_from_int>, <Descr>, I[%i0], R[], F[] -> %f0
+ residual_call_irf_f $<* fn llong_to_float>, <Descr>, I[], R[], F[%f0] -> %f1
+ float_return %f1
+ """, transform=True)
+
+ def f(x):
+ ll = r_ulonglong(x)
+ return rffi.cast(lltype.Float, ll)
+ self.encoding_test(f, [12], """
+ residual_call_irf_f $<* fn ullong_from_int>, <Descr>, I[%i0], R[], F[] -> %f0
+ residual_call_irf_f $<* fn ullong_u_to_float>, <Descr>, I[], R[], F[%f0] -> %f1
+ float_return %f1
+ """, 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
@@ -74,11 +74,6 @@
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):
- #def test_cast_float_to_longlong(self):
- #def test_cast_float_to_ulonglong(self):
-
class TestOOtype(FloatTests, OOJitMixin):
pass
More information about the pypy-commit
mailing list