diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2011-10-24 12:33:08 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2011-10-24 16:06:18 -0700 |
| commit | 8f2d75d53c18c56e419a4e998699f2b525d68f07 (patch) | |
| tree | 8cd0901c43185b8e5f4a54c9d7ba47858c2d44bd /src/comp | |
| parent | d69a83b0213952f2fdd48cddad493ad7a8dc0d6a (diff) | |
| download | rust-8f2d75d53c18c56e419a4e998699f2b525d68f07.tar.gz rust-8f2d75d53c18c56e419a4e998699f2b525d68f07.zip | |
switch over sqrt from llvm to c-stack-cdecl, exposing a bug in
the supported return types of upcall_c_stack
Diffstat (limited to 'src/comp')
| -rw-r--r-- | src/comp/back/upcall.rs | 6 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 25 |
2 files changed, 24 insertions, 7 deletions
diff --git a/src/comp/back/upcall.rs b/src/comp/back/upcall.rs index 2589247e2cd..04bdebb04a1 100644 --- a/src/comp/back/upcall.rs +++ b/src/comp/back/upcall.rs @@ -5,7 +5,7 @@ import trans::decl_cdecl_fn; 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; @@ -28,6 +28,7 @@ type upcalls = 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, @@ -77,6 +78,9 @@ 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()) }; } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 8391f40df47..c655d7d4b5d 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3864,20 +3864,33 @@ fn trans_c_stack_native_call(bcx: @block_ctxt, f: @ast::expr, 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); } |
