diff options
| author | Rafael Ávila de Espíndola <[email protected]> | 2011-03-09 15:05:22 -0500 |
|---|---|---|
| committer | Rafael Ávila de Espíndola <[email protected]> | 2011-03-09 15:05:22 -0500 |
| commit | 10d8b4e861faedb734636a80dc4963392f1f82c5 (patch) | |
| tree | 8e592e999737c2be6df261375a7f55ec7340b3b3 | |
| parent | swap taskptr and callee in preparation for making taskptr optional. (diff) | |
| download | rust-10d8b4e861faedb734636a80dc4963392f1f82c5.tar.xz rust-10d8b4e861faedb734636a80dc4963392f1f82c5.zip | |
Fix access to the rust stack.
| -rw-r--r-- | src/comp/back/x86.rs | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/src/comp/back/x86.rs b/src/comp/back/x86.rs index 04f5d5af..b9ba24c6 100644 --- a/src/comp/back/x86.rs +++ b/src/comp/back/x86.rs @@ -25,22 +25,39 @@ fn restore_callee_saves() -> vec[str] { "popl %ebp"); } -fn load_esp_from_rust_sp() -> vec[str] { +fn load_esp_from_rust_sp_first_arg() -> vec[str] { ret vec("movl " + wstr(abi.task_field_rust_sp) + "(%ecx), %esp"); } -fn load_esp_from_runtime_sp() -> vec[str] { +fn load_esp_from_runtime_sp_first_arg() -> vec[str] { ret vec("movl " + wstr(abi.task_field_runtime_sp) + "(%ecx), %esp"); } -fn store_esp_to_rust_sp() -> vec[str] { +fn store_esp_to_rust_sp_first_arg() -> vec[str] { ret vec("movl %esp, " + wstr(abi.task_field_rust_sp) + "(%ecx)"); } -fn store_esp_to_runtime_sp() -> vec[str] { +fn store_esp_to_runtime_sp_first_arg() -> vec[str] { ret vec("movl %esp, " + wstr(abi.task_field_runtime_sp) + "(%ecx)"); } +fn load_esp_from_rust_sp_second_arg() -> vec[str] { + ret vec("movl " + wstr(abi.task_field_rust_sp) + "(%edx), %esp"); +} + +fn load_esp_from_runtime_sp_second_arg() -> vec[str] { + ret vec("movl " + wstr(abi.task_field_runtime_sp) + "(%edx), %esp"); +} + +fn store_esp_to_rust_sp_second_arg() -> vec[str] { + ret vec("movl %esp, " + wstr(abi.task_field_rust_sp) + "(%edx)"); +} + +fn store_esp_to_runtime_sp_second_arg() -> vec[str] { + ret vec("movl %esp, " + wstr(abi.task_field_runtime_sp) + "(%edx)"); +} + + /* * This is a bit of glue-code. It should be emitted once per * compilation unit. @@ -61,8 +78,8 @@ fn store_esp_to_runtime_sp() -> vec[str] { fn rust_activate_glue() -> vec[str] { ret vec("movl 4(%esp), %ecx # ecx = rust_task") + save_callee_saves() - + store_esp_to_runtime_sp() - + load_esp_from_rust_sp() + + store_esp_to_runtime_sp_first_arg() + + load_esp_from_rust_sp_first_arg() /* * There are two paths we can arrive at this code from: @@ -154,10 +171,10 @@ fn rust_activate_glue() -> vec[str] { fn rust_yield_glue() -> vec[str] { ret vec("movl 0(%esp), %ecx # ecx = rust_task") - + load_esp_from_rust_sp() + + load_esp_from_rust_sp_first_arg() + save_callee_saves() - + store_esp_to_rust_sp() - + load_esp_from_runtime_sp() + + store_esp_to_rust_sp_first_arg() + + load_esp_from_runtime_sp_first_arg() + restore_callee_saves() + vec("ret"); } @@ -192,19 +209,19 @@ fn upcall_glue(int n_args) -> vec[str] { + vec("movl %esp, %ebp # ebp = rust_sp") - + store_esp_to_rust_sp() - + load_esp_from_runtime_sp() + + store_esp_to_rust_sp_second_arg() + + load_esp_from_runtime_sp_second_arg() + vec("subl $" + wstr(n_args + 1) + ", %esp # esp -= args", "andl $~0xf, %esp # align esp down") + _vec.init_fn[str](carg, (n_args + 1) as uint) - + vec("movl %edx, %edi # save task from ecx to edi", - "call *%ecx # call *%edx", - "movl %edi, %edx # restore edi-saved task to ecx") + + vec("movl %edx, %edi # save task from edx to edi", + "call *%ecx # call *%ecx", + "movl %edi, %edx # restore edi-saved task to edx") - + load_esp_from_rust_sp() + + load_esp_from_rust_sp_second_arg() + restore_callee_saves() + vec("ret"); |