diff options
Diffstat (limited to 'vendor/psm/src/arch/x86.s')
-rw-r--r-- | vendor/psm/src/arch/x86.s | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/vendor/psm/src/arch/x86.s b/vendor/psm/src/arch/x86.s new file mode 100644 index 000000000..2e388760d --- /dev/null +++ b/vendor/psm/src/arch/x86.s @@ -0,0 +1,91 @@ +#include "psm.h" +/* NOTE: fastcall calling convention used on all x86 targets */ + +.text + +#if CFG_TARGET_OS_darwin || CFG_TARGET_OS_macos || CFG_TARGET_OS_ios + +#define GLOBL(fnname) .globl _##fnname +#define TYPE(fnname) +#define FUNCTION(fnname) _##fnname +#define SIZE(fnname,endlabel) + +#else + +#define GLOBL(fnname) .globl fnname +#define TYPE(fnname) .type fnname,@function +#define FUNCTION(fnname) fnname +#define SIZE(fnname,endlabel) .size fnname,endlabel-fnname + +#endif + + +GLOBL(rust_psm_stack_direction) +.p2align 4 +TYPE(rust_psm_stack_direction) +FUNCTION(rust_psm_stack_direction): +/* extern "fastcall" fn() -> u8 (%al) */ +.cfi_startproc + movb $STACK_DIRECTION_DESCENDING, %al # always descending on x86_64 + retl +.rust_psm_stack_direction_end: +SIZE(rust_psm_stack_direction,.rust_psm_stack_direction_end) +.cfi_endproc + + +GLOBL(rust_psm_stack_pointer) +.p2align 4 +TYPE(rust_psm_stack_pointer) +FUNCTION(rust_psm_stack_pointer): +/* extern "fastcall" fn() -> *mut u8 (%rax) */ +.cfi_startproc + leal 4(%esp), %eax + retl +.rust_psm_stack_pointer_end: +SIZE(rust_psm_stack_pointer,.rust_psm_stack_pointer_end) +.cfi_endproc + + +GLOBL(rust_psm_replace_stack) +.p2align 4 +TYPE(rust_psm_replace_stack) +FUNCTION(rust_psm_replace_stack): +/* extern "fastcall" fn(%ecx: usize, %edx: extern "fastcall" fn(usize), 4(%esp): *mut u8) */ +.cfi_startproc +/* + All we gotta do is set the stack pointer to 4(%esp) & tail-call the callback in %edx + + Note, that the callee expects the stack to be offset by 4 bytes (normally, a return address + would be store there) off the required stack alignment on entry. To offset the stack in such a + way we use the `calll` instruction, however it would also be possible to to use plain `jmpl` but + would require to adjust the stack manually, which cannot be easily done, because the stack + pointer argument is already stored in memory. + */ + movl 4(%esp), %esp + calll *%edx + ud2 +.rust_psm_replace_stack_end: +SIZE(rust_psm_replace_stack,.rust_psm_replace_stack_end) +.cfi_endproc + + +GLOBL(rust_psm_on_stack) +.p2align 4 +TYPE(rust_psm_on_stack) +FUNCTION(rust_psm_on_stack): +/* extern "fastcall" fn(%ecx: usize, %edx: usize, 4(%esp): extern "fastcall" fn(usize, usize), 8(%esp): *mut u8) */ +.cfi_startproc + pushl %ebp + .cfi_def_cfa %esp, 8 + .cfi_offset %ebp, -8 + movl %esp, %ebp + .cfi_def_cfa_register %ebp + movl 12(%ebp), %esp + calll *8(%ebp) + movl %ebp, %esp + popl %ebp + .cfi_def_cfa %esp, 4 + retl $8 +.rust_psm_on_stack_end: +SIZE(rust_psm_on_stack,.rust_psm_on_stack_end) +.cfi_endproc |