From 933c01bd15a801d69570f6ea1421c362c568f46e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Mon, 21 Mar 2011 17:47:38 -0400 Subject: 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. --- src/comp/back/abi.rs | 7 +++++-- src/comp/back/x86.rs | 26 +++++++++++++++++--------- 2 files changed, 22 insertions(+), 11 deletions(-) (limited to 'src/comp/back') 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"); } -- cgit v1.2.3