Author: Maciej Fijalkowski <fij...@gmail.com> Branch: Changeset: r54041:372ef0512d66 Date: 2012-03-28 10:53 +0200 http://bitbucket.org/pypy/pypy/changeset/372ef0512d66/
Log: merge 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 @@ -27,6 +27,12 @@ def constfloat(x): return ConstFloat(longlong.getfloatstorage(x)) +def boxlonglong(ll): + if longlong.is_64_bit: + return BoxInt(ll) + else: + return BoxFloat(ll) + class Runner(object): @@ -1623,6 +1629,11 @@ [boxfloat(2.5)], t).value assert res == longlong2float.float2longlong(2.5) + bytes = longlong2float.float2longlong(2.5) + res = self.execute_operation(rop.CONVERT_LONGLONG_BYTES_TO_FLOAT, + [boxlonglong(res)], 'float').value + assert longlong.getrealfloat(res) == 2.5 + def test_ooops_non_gc(self): x = lltype.malloc(lltype.Struct('x'), flavor='raw') v = heaptracker.adr2int(llmemory.cast_ptr_to_adr(x)) diff --git a/pypy/jit/backend/test/test_random.py b/pypy/jit/backend/test/test_random.py --- a/pypy/jit/backend/test/test_random.py +++ b/pypy/jit/backend/test/test_random.py @@ -328,6 +328,15 @@ def produce_into(self, builder, r): self.put(builder, [r.choice(builder.intvars)]) +class CastLongLongToFloatOperation(AbstractFloatOperation): + def produce_into(self, builder, r): + if longlong.is_64_bit: + self.put(builder, [r.choice(builder.intvars)]) + else: + if not builder.floatvars: + raise CannotProduceOperation + self.put(builder, [r.choice(builder.floatvars)]) + class CastFloatToIntOperation(AbstractFloatOperation): def produce_into(self, builder, r): if not builder.floatvars: @@ -450,6 +459,7 @@ OPERATIONS.append(CastFloatToIntOperation(rop.CAST_FLOAT_TO_INT)) OPERATIONS.append(CastIntToFloatOperation(rop.CAST_INT_TO_FLOAT)) OPERATIONS.append(CastFloatToIntOperation(rop.CONVERT_FLOAT_BYTES_TO_LONGLONG)) +OPERATIONS.append(CastLongLongToFloatOperation(rop.CONVERT_LONGLONG_BYTES_TO_FLOAT)) OperationBuilder.OPERATIONS = OPERATIONS 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 @@ -1251,6 +1251,15 @@ else: self.mov(loc0, resloc) + def genop_convert_longlong_bytes_to_float(self, op, arglocs, resloc): + loc0, = arglocs + if longlong.is_64_bit: + assert isinstance(resloc, RegLoc) + assert isinstance(loc0, RegLoc) + self.mc.MOVD(resloc, loc0) + else: + self.mov(loc0, resloc) + def genop_guard_int_is_true(self, op, guard_op, guard_token, arglocs, resloc): guard_opnum = guard_op.getopnum() self.mc.CMP(arglocs[0], imm0) 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 @@ -777,7 +777,20 @@ loc0 = self.xrm.loc(arg0) loc1 = self.xrm.force_allocate_reg(op.result, forbidden_vars=[arg0]) self.Perform(op, [loc0], loc1) - self.xrm.possibly_free_var(op.getarg(0)) + self.xrm.possibly_free_var(arg0) + + def consider_convert_longlong_bytes_to_float(self, op): + if longlong.is_64_bit: + loc0 = self.rm.make_sure_var_in_reg(op.getarg(0)) + loc1 = self.xrm.force_allocate_reg(op.result) + self.Perform(op, [loc0], loc1) + self.rm.possibly_free_var(op.getarg(0)) + else: + arg0 = op.getarg(0) + loc0 = self.xrm.make_sure_var_in_reg(arg0) + loc1 = self.xrm.force_allocate_reg(op.result, forbidden_vars=[arg0]) + self.Perform(op, [loc0], loc1) + self.xrm.possibly_free_var(arg0) def _consider_llong_binop_xx(self, op): # must force both arguments into xmm registers, because we don't 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 @@ -295,6 +295,7 @@ return op rewrite_op_convert_float_bytes_to_longlong = _noop_rewrite + rewrite_op_convert_longlong_bytes_to_float = _noop_rewrite # ---------- # Various kinds of calls 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 @@ -968,20 +968,22 @@ int_return %i2 """, transform=True) - def test_convert_float_bytes_to_int(self): - from pypy.rlib.longlong2float import float2longlong + def test_convert_float_bytes(self): + from pypy.rlib.longlong2float import float2longlong, longlong2float def f(x): - return float2longlong(x) + ll = float2longlong(x) + return longlong2float(ll) if longlong.is_64_bit: - result_var = "%i0" - return_op = "int_return" + tmp_var = "%i0" + result_var = "%f1" else: - result_var = "%f1" - return_op = "float_return" + tmp_var = "%f1" + result_var = "%f2" self.encoding_test(f, [25.0], """ - convert_float_bytes_to_longlong %%f0 -> %(result_var)s - %(return_op)s %(result_var)s - """ % {"result_var": result_var, "return_op": return_op}) + convert_float_bytes_to_longlong %%f0 -> %(tmp_var)s + convert_longlong_bytes_to_float %(tmp_var)s -> %(result_var)s + float_return %(result_var)s + """ % {"result_var": result_var, "tmp_var": tmp_var}, transform=True) def check_force_cast(FROM, TO, operations, value): diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py --- a/pypy/jit/metainterp/blackhole.py +++ b/pypy/jit/metainterp/blackhole.py @@ -672,6 +672,11 @@ a = longlong.getrealfloat(a) return longlong2float.float2longlong(a) + @arguments(LONGLONG_TYPECODE, returns="f") + def bhimpl_convert_longlong_bytes_to_float(a): + a = longlong2float.longlong2float(a) + return longlong.getfloatstorage(a) + # ---------- # control flow operations diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -224,6 +224,7 @@ 'float_neg', 'float_abs', 'cast_ptr_to_int', 'cast_int_to_ptr', 'convert_float_bytes_to_longlong', + 'convert_longlong_bytes_to_float', ]: exec py.code.Source(''' @arguments("box") 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 @@ -420,6 +420,7 @@ 'CAST_FLOAT_TO_SINGLEFLOAT/1', 'CAST_SINGLEFLOAT_TO_FLOAT/1', 'CONVERT_FLOAT_BYTES_TO_LONGLONG/1', + 'CONVERT_LONGLONG_BYTES_TO_FLOAT/1', # 'INT_LT/2b', 'INT_LE/2b', diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py --- a/pypy/jit/metainterp/test/test_ajit.py +++ b/pypy/jit/metainterp/test/test_ajit.py @@ -1,3 +1,4 @@ +import math import sys import py @@ -15,7 +16,7 @@ loop_invariant, elidable, promote, jit_debug, assert_green, AssertGreenFailed, unroll_safe, current_trace_length, look_inside_iff, isconstant, isvirtual, promote_string, set_param, record_known_class) -from pypy.rlib.longlong2float import float2longlong +from pypy.rlib.longlong2float import float2longlong, longlong2float from pypy.rlib.rarithmetic import ovfcheck, is_valid_int from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.ootypesystem import ootype @@ -3795,15 +3796,15 @@ res = self.interp_operations(g, [1]) assert res == 3 - def test_float2longlong(self): + def test_float_bytes(self): def f(n): - return float2longlong(n) + ll = float2longlong(n) + return longlong2float(ll) for x in [2.5, float("nan"), -2.5, float("inf")]: # There are tests elsewhere to verify the correctness of this. - expected = float2longlong(x) res = self.interp_operations(f, [x]) - assert longlong.getfloatstorage(res) == expected + assert res == x or math.isnan(x) and math.isnan(res) class TestLLtype(BaseLLtypeTests, LLJitMixin): diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -28,7 +28,7 @@ return self.identity def descr_call(self, space, __args__): - from interp_numarray import BaseArray + from interp_numarray import BaseArray args_w, kwds_w = __args__.unpack() # it occurs to me that we don't support any datatypes that # require casting, change it later when we do diff --git a/pypy/rlib/longlong2float.py b/pypy/rlib/longlong2float.py --- a/pypy/rlib/longlong2float.py +++ b/pypy/rlib/longlong2float.py @@ -21,7 +21,7 @@ FLOAT_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.FLOAT)) # these definitions are used only in tests, when not translated -def longlong2float_emulator(llval): +def longlong2float(llval): with lltype.scoped_alloc(DOUBLE_ARRAY_PTR.TO, 1) as d_array: ll_array = rffi.cast(LONGLONG_ARRAY_PTR, d_array) ll_array[0] = llval @@ -51,12 +51,6 @@ eci = ExternalCompilationInfo(includes=['string.h', 'assert.h'], post_include_bits=[""" -static double pypy__longlong2float(long long x) { - double dd; - assert(sizeof(double) == 8 && sizeof(long long) == 8); - memcpy(&dd, &x, 8); - return dd; -} static float pypy__uint2singlefloat(unsigned int x) { float ff; assert(sizeof(float) == 4 && sizeof(unsigned int) == 4); @@ -71,12 +65,6 @@ } """]) -longlong2float = rffi.llexternal( - "pypy__longlong2float", [rffi.LONGLONG], rffi.DOUBLE, - _callable=longlong2float_emulator, compilation_info=eci, - _nowrapper=True, elidable_function=True, sandboxsafe=True, - oo_primitive="pypy__longlong2float") - uint2singlefloat = rffi.llexternal( "pypy__uint2singlefloat", [rffi.UINT], rffi.FLOAT, _callable=uint2singlefloat_emulator, compilation_info=eci, @@ -99,4 +87,17 @@ def specialize_call(self, hop): [v_float] = hop.inputargs(lltype.Float) - return hop.genop("convert_float_bytes_to_longlong", [v_float], resulttype=hop.r_result) + hop.exception_cannot_occur() + return hop.genop("convert_float_bytes_to_longlong", [v_float], resulttype=lltype.SignedLongLong) + +class LongLong2FloatEntry(ExtRegistryEntry): + _about_ = longlong2float + + def compute_result_annotation(self, s_longlong): + assert annmodel.SomeInteger(knowntype=r_int64).contains(s_longlong) + return annmodel.SomeFloat() + + def specialize_call(self, hop): + [v_longlong] = hop.inputargs(lltype.SignedLongLong) + hop.exception_cannot_occur() + return hop.genop("convert_longlong_bytes_to_float", [v_longlong], resulttype=lltype.Float) diff --git a/pypy/rlib/test/test_longlong2float.py b/pypy/rlib/test/test_longlong2float.py --- a/pypy/rlib/test/test_longlong2float.py +++ b/pypy/rlib/test/test_longlong2float.py @@ -2,6 +2,7 @@ from pypy.rlib.longlong2float import longlong2float, float2longlong from pypy.rlib.longlong2float import uint2singlefloat, singlefloat2uint from pypy.rlib.rarithmetic import r_singlefloat +from pypy.rpython.test.test_llinterp import interpret def fn(f1): @@ -31,6 +32,18 @@ res = fn2(x) assert repr(res) == repr(x) +def test_interpreted(): + def f(f1): + try: + ll = float2longlong(f1) + return longlong2float(ll) + except Exception: + return 500 + + for x in enum_floats(): + res = interpret(f, [x]) + assert repr(res) == repr(x) + # ____________________________________________________________ def fnsingle(f1): diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py --- a/pypy/rpython/lltypesystem/lloperation.py +++ b/pypy/rpython/lltypesystem/lloperation.py @@ -350,6 +350,7 @@ 'truncate_longlong_to_int':LLOp(canfold=True), 'force_cast': LLOp(sideeffects=False), # only for rffi.cast() 'convert_float_bytes_to_longlong': LLOp(canfold=True), + 'convert_longlong_bytes_to_float': LLOp(canfold=True), # __________ pointer operations __________ diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py --- a/pypy/rpython/lltypesystem/opimpl.py +++ b/pypy/rpython/lltypesystem/opimpl.py @@ -431,6 +431,10 @@ from pypy.rlib.longlong2float import float2longlong return float2longlong(a) +def op_convert_longlong_bytes_to_float(a): + from pypy.rlib.longlong2float import longlong2float + return longlong2float(a) + def op_unichar_eq(x, y): assert isinstance(x, unicode) and len(x) == 1 diff --git a/pypy/translator/c/gcc/test/test_asmgcroot.py b/pypy/translator/c/gcc/test/test_asmgcroot.py --- a/pypy/translator/c/gcc/test/test_asmgcroot.py +++ b/pypy/translator/c/gcc/test/test_asmgcroot.py @@ -7,10 +7,17 @@ from pypy import conftest from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.translator.platform import platform as compiler +from pypy.rlib.rarithmetic import is_emulated_long from pypy.rpython.lltypesystem import lltype, rffi from pypy.rlib.entrypoint import entrypoint, secondary_entrypoints from pypy.rpython.lltypesystem.lloperation import llop +_MSVC = compiler.name == "msvc" +_MINGW = compiler.name == "mingw32" +_WIN32 = _MSVC or _MINGW +_WIN64 = _WIN32 and is_emulated_long +# XXX get rid of 'is_emulated_long' and have a real config here. + class AbstractTestAsmGCRoot: # the asmgcroot gc transformer doesn't generate gc_reload_possibly_moved # instructions: @@ -18,8 +25,8 @@ @classmethod def make_config(cls): - if compiler.name == "msvc": - py.test.skip("all asmgcroot tests disabled for MSVC") + if _MSVC and _WIN64: + py.test.skip("all asmgcroot tests disabled for MSVC X64") from pypy.config.pypyoption import get_pypy_config config = get_pypy_config(translating=True) config.translation.gc = cls.gcpolicy diff --git a/pypy/translator/c/src/float.h b/pypy/translator/c/src/float.h --- a/pypy/translator/c/src/float.h +++ b/pypy/translator/c/src/float.h @@ -43,5 +43,6 @@ #define OP_CAST_FLOAT_TO_LONGLONG(x,r) r = (long long)(x) #define OP_CAST_FLOAT_TO_ULONGLONG(x,r) r = (unsigned long long)(x) #define OP_CONVERT_FLOAT_BYTES_TO_LONGLONG(x,r) memcpy(&r, &x, sizeof(double)) +#define OP_CONVERT_LONGLONG_BYTES_TO_FLOAT(x,r) memcpy(&r, &x, sizeof(long long)) #endif diff --git a/pypy/translator/jvm/opcodes.py b/pypy/translator/jvm/opcodes.py --- a/pypy/translator/jvm/opcodes.py +++ b/pypy/translator/jvm/opcodes.py @@ -243,4 +243,5 @@ 'force_cast': [PushAllArgs, CastPrimitive, StoreResult], 'convert_float_bytes_to_longlong': jvm.PYPYDOUBLEBYTESTOLONG, + 'convert_longlong_bytes_to_float': jvm.PYPYLONGBYTESTODOUBLE, }) diff --git a/pypy/translator/jvm/typesystem.py b/pypy/translator/jvm/typesystem.py --- a/pypy/translator/jvm/typesystem.py +++ b/pypy/translator/jvm/typesystem.py @@ -942,6 +942,7 @@ PYPYULONGTODOUBLE = Method.s(jPyPy, 'ulong_to_double', (jLong,), jDouble) PYPYLONGBITWISENEGATE = Method.v(jPyPy, 'long_bitwise_negate', (jLong,), jLong) PYPYDOUBLEBYTESTOLONG = Method.v(jPyPy, 'pypy__float2longlong', (jDouble,), jLong) +PYPYLONGBYTESTODOUBLE = Method.v(jPyPy, 'pypy__longlong2float', (jLong,), jDouble) PYPYSTRTOINT = Method.v(jPyPy, 'str_to_int', (jString,), jInt) PYPYSTRTOUINT = Method.v(jPyPy, 'str_to_uint', (jString,), jInt) PYPYSTRTOLONG = Method.v(jPyPy, 'str_to_long', (jString,), jLong) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit