diff options
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); } |
