about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2010-11-14 13:41:10 -0800
committerGraydon Hoare <graydon@mozilla.com>2010-11-14 13:41:10 -0800
commita352efadad7271798848c6ef4a22d8de7c8eba3a (patch)
tree13e38ac987a13c1b5cf27d1c949275af68808c36
parent4cbef9d8a1f5d894325c252a70429116c24d5364 (diff)
downloadrust-a352efadad7271798848c6ef4a22d8de7c8eba3a.tar.gz
rust-a352efadad7271798848c6ef4a22d8de7c8eba3a.zip
Switch upcall glues to fastcall as well.
-rw-r--r--src/comp/back/x86.rs21
-rw-r--r--src/comp/lib/llvm.rs9
-rw-r--r--src/comp/middle/trans.rs11
3 files changed, 24 insertions, 17 deletions
diff --git a/src/comp/back/x86.rs b/src/comp/back/x86.rs
index 961624f3600..a2a8d5cc822 100644
--- a/src/comp/back/x86.rs
+++ b/src/comp/back/x86.rs
@@ -70,16 +70,18 @@ fn upcall_glue(int n_args) -> vec[str] {
     /*
      * 0, 4, 8, 12 are callee-saves
      * 16 is retpc
-     * 20 is taskptr
-     * 24 is callee
-     * 28 .. (7+i) * 4 are args
+     * 20 .. (5+i) * 4 are args
+     *
+     * ecx is taskptr
+     * edx is callee
+     *
      */
 
     fn copy_arg(uint i) -> str {
-        auto src_off = wstr(7 + (i as int));
+        auto src_off = wstr(5 + (i as int));
         auto dst_off = wstr(1 + (i as int));
-        auto m = vec("movl  " + src_off + "(%ebp),%edx",
-                     "movl  %edx," + dst_off + "(%esp)");
+        auto m = vec("movl  " + src_off + "(%ebp),%eax",
+                     "movl  %eax," + dst_off + "(%esp)");
         ret _str.connect(m, "\n\t");
     }
 
@@ -88,8 +90,7 @@ fn upcall_glue(int n_args) -> vec[str] {
     ret
         save_callee_saves()
 
-        + vec("movl  %esp, %ebp     # ebp = rust_sp",
-              "movl  20(%esp), %ecx # ecx = rust_task")
+        + vec("movl  %esp, %ebp     # ebp = rust_sp")
 
         + store_esp_to_rust_sp()
         + load_esp_from_runtime_sp()
@@ -100,9 +101,9 @@ fn upcall_glue(int n_args) -> vec[str] {
 
         + _vec.init_fn[str](carg, n_args as uint)
 
-        +  vec("movl  24(%ebp), %edx # edx = callee",
+        +  vec("movl  %ecx, %edi     # save task from ecx to edi",
                "call  *%edx          # call *%edx",
-               "movl  20(%ebp), %ecx # edx = rust_task")
+               "movl  %edi, %ecx     # restore edi-saved task to ecx")
 
         + load_esp_from_rust_sp()
         + restore_callee_saves()
diff --git a/src/comp/lib/llvm.rs b/src/comp/lib/llvm.rs
index 0cd177a406d..da48c6b5d4d 100644
--- a/src/comp/lib/llvm.rs
+++ b/src/comp/lib/llvm.rs
@@ -1026,6 +1026,15 @@ obj builder(BuilderRef B) {
                                _str.buf(""));
     }
 
+    fn FastCall(ValueRef Fn, vec[ValueRef] Args) -> ValueRef {
+        auto v = llvm.LLVMBuildCall(B, Fn,
+                                    _vec.buf[ValueRef](Args),
+                                    _vec.len[ValueRef](Args),
+                                    _str.buf(""));
+        llvm.LLVMSetInstructionCallConv(v, LLVMFastCallConv);
+        ret v;
+    }
+
     fn Select(ValueRef If, ValueRef Then, ValueRef Else) -> ValueRef {
         ret llvm.LLVMBuildSelect(B, If, Then, Else, _str.buf(""));
     }
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 7308168725e..0c85d50b130 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -375,7 +375,7 @@ fn decl_upcall(ModuleRef llmod, uint _n) -> ValueRef {
             T_int())     // callee
         + _vec.init_elt[TypeRef](T_int(), n as uint);
 
-    ret decl_cdecl_fn(llmod, s, args, T_int());
+    ret decl_fastcall_fn(llmod, s, args, T_int());
 }
 
 fn get_upcall(@trans_ctxt cx, str name, int n_args) -> ValueRef {
@@ -400,8 +400,7 @@ fn trans_upcall(@block_ctxt cx, str name, vec[ValueRef] args) -> result {
     for (ValueRef a in args) {
         call_args += cx.build.ZExtOrBitCast(a, T_int());
     }
-
-    ret res(cx, cx.build.Call(llglue, call_args));
+    ret res(cx, cx.build.FastCall(llglue, call_args));
 }
 
 fn trans_non_gc_free(@block_ctxt cx, ValueRef v) -> result {
@@ -941,10 +940,8 @@ impure fn trans_expr(@block_ctxt cx, &ast.expr e) -> result {
             auto args_res = trans_exprs(f_res._0.bcx, args);
             auto llargs = vec(cx.fcx.lltaskptr);
             llargs += args_res._1;
-            auto call_val = args_res._0.build.Call(f_res._0.val, llargs);
-            llvm.LLVMSetInstructionCallConv(call_val,
-                                            lib.llvm.LLVMFastCallConv);
-            ret res(args_res._0, call_val);
+            ret res(args_res._0,
+                    args_res._0.build.FastCall(f_res._0.val, llargs));
         }
 
     }