From 8f2d75d53c18c56e419a4e998699f2b525d68f07 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 24 Oct 2011 12:33:08 -0700 Subject: [PATCH] switch over sqrt from llvm to c-stack-cdecl, exposing a bug in the supported return types of upcall_c_stack --- src/comp/back/upcall.rs | 6 +++++- src/comp/middle/trans.rs | 25 +++++++++++++++++++------ src/rt/arch/i386/ccall.S | 4 ++++ src/rt/rustrt.def.in | 1 + src/test/bench/shootout-nbody.rs | 4 ++-- 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/comp/back/upcall.rs b/src/comp/back/upcall.rs index 2589247e2cda..04bdebb04a17 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 8391f40df47e..c655d7d4b5dc 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); } diff --git a/src/rt/arch/i386/ccall.S b/src/rt/arch/i386/ccall.S index 44d0c2177360..378ea5e0b67e 100644 --- a/src/rt/arch/i386/ccall.S +++ b/src/rt/arch/i386/ccall.S @@ -6,10 +6,14 @@ // 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 diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 3430f77c8927..6b70e2839572 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -65,6 +65,7 @@ task_join unsupervise upcall_alloc_c_stack upcall_call_c_stack +upcall_call_c_stack_float upcall_cmp_type upcall_dynastack_alloc upcall_dynastack_alloc_2 diff --git a/src/test/bench/shootout-nbody.rs b/src/test/bench/shootout-nbody.rs index 61122d8e6b48..e6f196f2869c 100644 --- a/src/test/bench/shootout-nbody.rs +++ b/src/test/bench/shootout-nbody.rs @@ -1,8 +1,8 @@ // 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() {