diff options
| author | Rafael Ávila de Espíndola <[email protected]> | 2011-03-21 17:47:38 -0400 |
|---|---|---|
| committer | Rafael Ávila de Espíndola <[email protected]> | 2011-03-21 17:53:11 -0400 |
| commit | 933c01bd15a801d69570f6ea1421c362c568f46e (patch) | |
| tree | ed3060d1fe2fef2a94040c024886e69999e90439 /src/comp/back | |
| parent | Adjust run rules to avoid early substitution. Testsuite begins to run. (diff) | |
| download | rust-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.rs | 7 | ||||
| -rw-r--r-- | src/comp/back/x86.rs | 26 |
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"); } |