aboutsummaryrefslogtreecommitdiff
path: root/src/comp/back
diff options
context:
space:
mode:
authorRafael Ávila de Espíndola <[email protected]>2011-03-21 17:47:38 -0400
committerRafael Ávila de Espíndola <[email protected]>2011-03-21 17:53:11 -0400
commit933c01bd15a801d69570f6ea1421c362c568f46e (patch)
treeed3060d1fe2fef2a94040c024886e69999e90439 /src/comp/back
parentAdjust run rules to avoid early substitution. Testsuite begins to run. (diff)
downloadrust-933c01bd15a801d69570f6ea1421c362c568f46e.tar.xz
rust-933c01bd15a801d69570f6ea1421c362c568f46e.zip
Every upcall needs a task pointer to find the C stack. It is just that when
handling cdecl call they should skip it when calling the final function. There is some cleanup to be done on the generated IL, but this gets us running Hello World for real.
Diffstat (limited to 'src/comp/back')
-rw-r--r--src/comp/back/abi.rs7
-rw-r--r--src/comp/back/x86.rs26
2 files changed, 22 insertions, 11 deletions
diff --git a/src/comp/back/abi.rs b/src/comp/back/abi.rs
index dd058590..cae1dc90 100644
--- a/src/comp/back/abi.rs
+++ b/src/comp/back/abi.rs
@@ -75,8 +75,11 @@ fn vec_append_glue_name() -> str {
ret "rust_vec_append_glue";
}
-fn upcall_glue_name(int n) -> str {
- ret "rust_upcall_" + util.common.istr(n);
+fn upcall_glue_name(int n, bool pass_task) -> str {
+ if (pass_task) {
+ ret "rust_upcall_rust_" + util.common.istr(n);
+ }
+ ret "rust_upcall_cdecl_" + util.common.istr(n);
}
fn activate_glue_name() -> str {
diff --git a/src/comp/back/x86.rs b/src/comp/back/x86.rs
index 345603bb..1ac03d1f 100644
--- a/src/comp/back/x86.rs
+++ b/src/comp/back/x86.rs
@@ -179,7 +179,7 @@ fn rust_yield_glue() -> vec[str] {
+ vec("ret");
}
-fn upcall_glue(int n_args) -> vec[str] {
+fn upcall_glue(int n_args, bool pass_task) -> vec[str] {
/*
* 0, 4, 8, 12 are callee-saves
@@ -191,18 +191,23 @@ fn upcall_glue(int n_args) -> vec[str] {
*
*/
- fn copy_arg(uint i) -> str {
- if (i == 0u) {
+ fn copy_arg(bool pass_task, uint i) -> str {
+ if (i == 0u && pass_task) {
ret "movl %edx, (%esp)";
}
- auto src_off = wstr(4 + (i as int));
auto dst_off = wstr(0 + (i as int));
+ auto src_off;
+ if (pass_task) {
+ src_off = wstr(4 + (i as int));
+ } else {
+ src_off = wstr(5 + (i as int));
+ }
auto m = vec("movl " + src_off + "(%ebp),%eax",
"movl %eax," + dst_off + "(%esp)");
ret _str.connect(m, "\n\t");
}
- auto carg = copy_arg;
+ auto carg = bind copy_arg(pass_task, _);
ret
save_callee_saves()
@@ -237,11 +242,11 @@ fn decl_glue(int align, str prefix, str name, vec[str] insns) -> str {
}
-fn decl_upcall_glue(int align, str prefix, uint n) -> str {
+fn decl_upcall_glue(int align, str prefix, bool pass_task, uint n) -> str {
let int i = n as int;
ret decl_glue(align, prefix,
- abi.upcall_glue_name(i),
- upcall_glue(i));
+ abi.upcall_glue_name(i, pass_task),
+ upcall_glue(i, pass_task));
}
fn get_symbol_prefix() -> str {
@@ -267,9 +272,12 @@ fn get_module_asm() -> str {
abi.yield_glue_name(),
rust_yield_glue()))
- + _vec.init_fn[str](bind decl_upcall_glue(align, prefix, _),
+ + _vec.init_fn[str](bind decl_upcall_glue(align, prefix, true, _),
+ (abi.n_upcall_glues + 1) as uint)
+ + _vec.init_fn[str](bind decl_upcall_glue(align, prefix, false, _),
(abi.n_upcall_glues + 1) as uint);
+
ret _str.connect(glues, "\n\n");
}