diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2011-11-09 11:01:12 -0800 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2011-11-09 20:05:49 -0800 |
| commit | 7baf68b0bdf38baeba482075b12fc50f9ff51d13 (patch) | |
| tree | ffae4e33bb1abf753c14a3a20081bbb50a56f382 /src/rt/arch/x86_64 | |
| parent | fc064f441026f2f34417925a26c1f6d73a7faf2c (diff) | |
| download | rust-7baf68b0bdf38baeba482075b12fc50f9ff51d13.tar.gz rust-7baf68b0bdf38baeba482075b12fc50f9ff51d13.zip | |
hack around the problem that x86_64 expects first few args in regs.
call on c-stack expects all data to be delivered on the stack.
Diffstat (limited to 'src/rt/arch/x86_64')
| -rw-r--r-- | src/rt/arch/x86_64/ccall.S | 35 | ||||
| -rw-r--r-- | src/rt/arch/x86_64/regs.h | 6 |
2 files changed, 38 insertions, 3 deletions
diff --git a/src/rt/arch/x86_64/ccall.S b/src/rt/arch/x86_64/ccall.S index 428ac7437c1..d9221067175 100644 --- a/src/rt/arch/x86_64/ccall.S +++ b/src/rt/arch/x86_64/ccall.S @@ -1,4 +1,9 @@ - .text +#include "regs.h" + +#define ARG0 RUSTRT_ARG0_S +#define ARG1 RUSTRT_ARG1_S + + .text // upcall_call_c_stack(void (*fn)(), void *new_esp) // @@ -21,8 +26,32 @@ upcall_call_c_stack_float: #endif push %rbp mov %rsp,%rbp // save rsp - mov %rsi,%rsp // switch stack - call *%rdi + mov ARG1,%rsp // switch stack + + // Hack: the arguments to the function are sitting + // on the stack right now, as in i386 calling + // convention. We need them in registers. + // For now, we just load them into registers. + // + // This is a total hack because it does not consider + // the actual arguments of the target function. + // It fails if there are non-INTEGER class arguments, + // which would get pushed on the stack, or if there are + // additional arguments beyond those that will get + // passed in registers. + mov ARG0,%r11 // Remember target address + mov 0(%rsp),RUSTRT_ARG0_S + mov 8(%rsp),RUSTRT_ARG1_S + mov 16(%rsp),RUSTRT_ARG2_S + mov 24(%rsp),RUSTRT_ARG3_S +# ifdef RUSTRT_ARG4_S + mov 32(%rsp),RUSTRT_ARG4_S +# endif +# ifdef RUSTRT_ARG5_S + mov 40(%rsp),RUSTRT_ARG5_S +# endif + + call *%r11 mov %rbp,%rsp // would like to use "leave" but it's slower pop %rbp ret diff --git a/src/rt/arch/x86_64/regs.h b/src/rt/arch/x86_64/regs.h index 7d090ff5b27..5ebcdf7429b 100644 --- a/src/rt/arch/x86_64/regs.h +++ b/src/rt/arch/x86_64/regs.h @@ -21,9 +21,15 @@ #if defined(__MINGW32__) || defined(_WINDOWS) # define RUSTRT_ARG0_S %rcx # define RUSTRT_ARG1_S %rdx +# define RUSTRT_ARG2_S %r8 +# define RUSTRT_ARG3_S %r9 #else # define RUSTRT_ARG0_S %rdi # define RUSTRT_ARG1_S %rsi +# define RUSTRT_ARG2_S %rdx +# define RUSTRT_ARG3_S %rcx +# define RUSTRT_ARG4_S %r8 +# define RUSTRT_ARG5_S %r9 #endif |
