def primitiveAt(interp, s_frame, words, index0): uintword = rffi.cast(rffi.UINT, words[index0]) singlefloat = uint2singlefloat(uintword) doublefloat = rffi.cast(rffi.DOUBLE, singlefloat) try: return interp.space.wrap_float(float(doublefloat)) except IndexError: raise PrimitiveFailedError
def bits2float(bits): # This is a bit convoluted, but this is much faster than ieee.pack # stuff. In addition to normal casting through uint2singlefloat, we have # additional casting because integer and float types that we can do # arithmetic operations on are standard Python sizes (native machine # size). Here's the typing going on below: # Python Int (64-bit) -> r_uint32 -> r_singlefloat -> Python Float (64-bit) flt = rffi.cast(lltype.Float, uint2singlefloat(r_uint32(bits))) return flt
def byteswap(arg): """ Convert little->big endian and the opposite """ from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rlib.longlong2float import longlong2float, float2longlong,\ uint2singlefloat, singlefloat2uint T = lltype.typeOf(arg) if T == lltype.SingleFloat: arg = singlefloat2uint(arg) elif T == lltype.Float: arg = float2longlong(arg) elif T == lltype.LongFloat: assert False else: # we cannot do arithmetics on small ints arg = widen(arg) if rffi.sizeof(T) == 1: res = arg elif rffi.sizeof(T) == 2: a, b = arg & 0xFF, arg & 0xFF00 res = (a << 8) | (b >> 8) elif rffi.sizeof(T) == 4: FF = r_uint(0xFF) arg = r_uint(arg) a, b, c, d = (arg & FF, arg & (FF << 8), arg & (FF << 16), arg & (FF << 24)) res = (a << 24) | (b << 8) | (c >> 8) | (d >> 24) elif rffi.sizeof(T) == 8: FF = r_ulonglong(0xFF) arg = r_ulonglong(arg) a, b, c, d = (arg & FF, arg & (FF << 8), arg & (FF << 16), arg & (FF << 24)) e, f, g, h = (arg & (FF << 32), arg & (FF << 40), arg & (FF << 48), arg & (FF << 56)) res = ((a << 56) | (b << 40) | (c << 24) | (d << 8) | (e >> 8) | (f >> 24) | (g >> 40) | (h >> 56)) else: assert False # unreachable code if T == lltype.SingleFloat: return uint2singlefloat(rffi.cast(rffi.UINT, res)) if T == lltype.Float: return longlong2float(rffi.cast(rffi.LONGLONG, res)) return rffi.cast(T, res)
def test_call_stubs_single_float(): from rpython.rlib.longlong2float import uint2singlefloat, singlefloat2uint from rpython.rlib.rarithmetic import r_singlefloat, intmask # c0 = GcCache(False) ARGS = [lltype.SingleFloat, lltype.SingleFloat, lltype.SingleFloat] RES = lltype.SingleFloat def f(a, b, c): a = float(a) b = float(b) c = float(c) x = a - (b / c) return r_singlefloat(x) fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) descr2 = get_call_descr(c0, ARGS, RES) a = intmask(singlefloat2uint(r_singlefloat(-10.0))) b = intmask(singlefloat2uint(r_singlefloat(3.0))) c = intmask(singlefloat2uint(r_singlefloat(2.0))) res = descr2.call_stub_i(rffi.cast(lltype.Signed, fnptr), [a, b, c], [], []) assert float(uint2singlefloat(rffi.r_uint(res))) == -11.5
def fnsingle(f1): sf1 = r_singlefloat(f1) ii = singlefloat2uint(sf1) sf2 = uint2singlefloat(ii) f2 = float(sf2) return f2
def int2singlefloat(x): x = rffi.r_uint(x) return longlong2float.uint2singlefloat(x)