about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2011-10-24 12:33:08 -0700
committerBrian Anderson <banderson@mozilla.com>2011-10-24 16:06:18 -0700
commit8f2d75d53c18c56e419a4e998699f2b525d68f07 (patch)
tree8cd0901c43185b8e5f4a54c9d7ba47858c2d44bd /src/comp
parentd69a83b0213952f2fdd48cddad493ad7a8dc0d6a (diff)
downloadrust-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.rs6
-rw-r--r--src/comp/middle/trans.rs25
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);
     }