import middle::trans_common::{T_f32, T_f64, T_fn, T_bool, T_i1, T_i8, T_i32,
T_int, T_vec, T_nil, T_opaque_chan_ptr,
T_opaque_vec, T_opaque_port_ptr, T_ptr,
- T_size_t, T_void};
+ T_size_t, T_void, T_float};
import lib::llvm::type_names;
import lib::llvm::llvm::ModuleRef;
import lib::llvm::llvm::ValueRef;
dynastack_free: ValueRef,
alloc_c_stack: ValueRef,
call_c_stack: ValueRef,
+ call_c_stack_float: ValueRef,
rust_personality: ValueRef};
fn declare_upcalls(_tn: type_names, tydesc_type: TypeRef,
call_c_stack: d("call_c_stack",
[T_ptr(T_fn([], T_int())), T_ptr(T_i8())],
T_int()),
+ call_c_stack_float: d("call_c_stack_float",
+ [T_ptr(T_fn([], T_int())), T_ptr(T_i8())],
+ T_float()),
rust_personality: d("rust_personality", [], T_i32())
};
}
i += 1u;
}
- // Call.
- // TODO: Invoke instead.
- let llrawretval = Call(bcx, ccx.upcalls.call_c_stack,
- [llfn, llrawargbundle]);
-
- // Cast return type.
+ // Determine return type.
let ret_ty = ty::ty_fn_ret(bcx_tcx(bcx), fn_ty);
check type_has_static_size(ccx, ret_ty);
let llretty = type_of(ccx, f.span, ret_ty);
+ // Determine which upcall fn to use based on the return type.
+ let upcall_fn = alt lib::llvm::llvm::LLVMGetTypeKind(llretty) {
+ 1 | 2 | 3 | 4 | 5 {
+ // LLVMFloatTypeKind, LLVMDoubleTypeKind,
+ // LLVMX86_FP80TypeKind, LLVMFP128TypeKind
+ // LLVMPPC_FP128TypeKind
+ ccx.upcalls.call_c_stack_float
+ }
+
+ _ { ccx.upcalls.call_c_stack }
+ };
+
+ // Call and cast the return type.
+ // TODO: Invoke instead.
+ let llrawretval = Call(bcx, upcall_fn,
+ [llfn, llrawargbundle]);
let llretval;
if lib::llvm::llvm::LLVMGetTypeKind(llretty) as int == 11 { // pointer
llretval = IntToPtr(bcx, llrawretval, llretty);
} else {
+ log_err("TruncOrBitCast(", val_str(ccx.tn, llrawretval), ", ",
+ ty_str(ccx.tn, llretty), ")");
llretval = TruncOrBitCast(bcx, llrawretval, llretty);
}
// slower.
#if defined(__APPLE__) || defined(_WIN32)
.globl _upcall_call_c_stack
+.globl _upcall_call_c_stack_float
_upcall_call_c_stack:
+_upcall_call_c_stack_float:
#else
.globl upcall_call_c_stack
+.globl upcall_call_c_stack_float
upcall_call_c_stack:
+upcall_call_c_stack_float:
#endif
pushl %ebp
movl %esp,%ebp // save esp
unsupervise
upcall_alloc_c_stack
upcall_call_c_stack
+upcall_call_c_stack_float
upcall_cmp_type
upcall_dynastack_alloc
upcall_dynastack_alloc_2
// based on:
// http://shootout.alioth.debian.org/u32/benchmark.php?test=nbody&lang=java
-native "llvm" mod llvm {
- fn sqrt(n: float) -> float = "sqrt.f64";
+native "c-stack-cdecl" mod llvm = "" {
+ fn sqrt(n: float) -> float;
}
fn main() {