def declare(name, signatures, mathname=None): """ Declare a unary math function named `name` for the given signatures. """ mathname = mathname or name.title() for signature in signatures: @jit(signature, opaque=True) def mathfunc(*args): return getattr(math, name)(*args) # pure python def impl(builder, argtypes, *args): [ty] = argtypes lty = lltype(ty) return builder.ret(builder.call_math(lty, mathname, list(args))) add_impl(mathfunc, "flypy_" + name, impl) for f, _, _ in mathfunc.overloads: f.__name__ = name return mathfunc
def inttoptr_impl(builder, argtypes, value, type): convert_impl(builder, argtypes, value, type) def ptrtoint_impl(builder, argtypes, value, type): ptrcast(builder, argtypes, value, type) # ---------- helper ------------- def convert_impl(builder, argtypes, value, type): valtype, typetype = argtypes # e.g. `int, Type[double]` type = typetype.parameters[0] result = builder.convert(lltype(type), value) builder.ret(result) def ptrcast(builder, argtypes, value, type): valtype, typetype = argtypes # e.g. `int, Type[double]` type = typetype.parameters[0] result = builder.ptrcast(lltype(type), value) builder.ret(result) # ---------- add impls ------------- def result_type(argtypes): return lltype(argtypes[1].parameters[0]) add_impl(numeric_cast, "numeric_cast", numeric_cast_impl, restype_func=result_type) add_impl(bitcast, "bitcast", bitcast_impl, restype_func=result_type) add_impl(inttoptr, "inttoptr", inttoptr_impl, restype_func=result_type) add_impl(ptrtoint, "ptrtoint", ptrtoint_impl, restype_func=result_type)
def convert_impl(builder, argtypes, value, type): valtype, typetype = argtypes # e.g. `int, Type[double]` type = typetype.parameters[0] result = builder.convert(lltype(type), value) builder.ret(result) def ptrcast(builder, argtypes, value, type): valtype, typetype = argtypes # e.g. `int, Type[double]` type = typetype.parameters[0] result = builder.ptrcast(lltype(type), value) builder.ret(result) # ---------- add impls ------------- def result_type(argtypes): return lltype(argtypes[1].parameters[0]) add_impl(numeric_cast, "numeric_cast", numeric_cast_impl, restype_func=result_type) add_impl(bitcast, "bitcast", bitcast_impl, restype_func=result_type) add_impl(inttoptr, "inttoptr", inttoptr_impl, restype_func=result_type) add_impl(ptrtoint, "ptrtoint", ptrtoint_impl, restype_func=result_type)
def restype_from_array(argtypes): base, count = argtypes[0] return ptypes.Vector(base, count) def restype_from_int(argtypes): (bits,), count = argtypes[0] base_t = argtypes[1] assert bits % base_t.bits == 0 return ptypes.Vector(base_t, bits / base_t.bits) def implement_from_int(builder, argtypes, i, base_t): vector_type = restype_from_int(argtypes) v = builder.bitcast(i, vector_type) return builder.ret(v) add_impl(from_array, "from_array", implement_from_array, restype_func=restype_from_array) add_impl(from_int, "from_int", implement_from_int, restype_func=restype_from_int) # low level operations def implement_len(builder, argtypes, vector): count = argtypes[0].parameters[1] return builder.ret(ir.Const(count, ptypes.Int64)) def implement_to_array(builder, argtypes, vector, parray): pvector_t = ptypes.Pointer(argtypes[0]) pvector = builder.bitcast(pvector_t, parray) builder.ptrstore(vector, pvector) def restype_to_int(argtypes): (bits,), count = argtypes[0]
def restype_from_int(argtypes): (bits, ), count = argtypes[0] base_t = argtypes[1] assert bits % base_t.bits == 0 return ptypes.Vector(base_t, bits / base_t.bits) def implement_from_int(builder, argtypes, i, base_t): vector_type = restype_from_int(argtypes) v = builder.bitcast(i, vector_type) return builder.ret(v) add_impl(from_array, "from_array", implement_from_array, restype_func=restype_from_array) add_impl(from_int, "from_int", implement_from_int, restype_func=restype_from_int) # low level operations def implement_len(builder, argtypes, vector): count = argtypes[0].parameters[1] return builder.ret(ir.Const(count, ptypes.Int64)) def implement_to_array(builder, argtypes, vector, parray):