91 lines
2.4 KiB
ArmAsm
91 lines
2.4 KiB
ArmAsm
#include "regs.h"
|
|
|
|
#define ARG0 RUSTRT_ARG0_S
|
|
#define ARG1 RUSTRT_ARG1_S
|
|
#define ARG2 RUSTRT_ARG2_S
|
|
|
|
.text
|
|
|
|
// upcall_call_c_stack(void (*fn)(), void *new_esp)
|
|
//
|
|
// Note that we could use |enter| and |leave| but the manuals tell me they're
|
|
// slower.
|
|
#if defined(__APPLE__) || defined(_WIN32)
|
|
.globl _upcall_call_c_stack
|
|
.globl _upcall_call_c_stack_i64
|
|
.globl _upcall_call_c_stack_float
|
|
_upcall_call_c_stack:
|
|
_upcall_call_c_stack_i64:
|
|
_upcall_call_c_stack_float:
|
|
#else
|
|
.globl upcall_call_c_stack
|
|
.globl upcall_call_c_stack_i64
|
|
.globl upcall_call_c_stack_float
|
|
upcall_call_c_stack:
|
|
upcall_call_c_stack_i64:
|
|
upcall_call_c_stack_float:
|
|
#endif
|
|
push %rbp
|
|
mov %rsp,%rbp // save rsp
|
|
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
|
|
|
|
#if defined(__APPLE__) || defined(_WIN32)
|
|
.globl _upcall_call_c_stack_shim
|
|
_upcall_call_c_stack_shim:
|
|
#else
|
|
.globl upcall_call_c_stack_shim
|
|
upcall_call_c_stack_shim:
|
|
#endif
|
|
push %rbp
|
|
mov %rsp,%rbp // save rsp
|
|
mov ARG1,%rsp // switch stack
|
|
mov ARG0,%r11 // Remember target address
|
|
mov ARG1,ARG0 // setup the parameter shim expects
|
|
call *%r11
|
|
mov %rbp,%rsp
|
|
pop %rbp
|
|
ret
|
|
|
|
#if defined(__APPLE__) || defined(_WIN32)
|
|
.globl _asm_call_on_stack
|
|
_asm_call_on_stack:
|
|
#else
|
|
.globl asm_call_on_stack
|
|
asm_call_on_stack:
|
|
#endif
|
|
push %rbp
|
|
mov %rsp,%rbp // save rsp
|
|
mov ARG2,%rsp // switch stack
|
|
call *ARG1 // invoke target address
|
|
mov %rbp,%rsp
|
|
pop %rbp
|
|
ret
|