summaryrefslogtreecommitdiffstats
path: root/vendor/psm/src/arch/x86.s
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/psm/src/arch/x86.s')
-rw-r--r--vendor/psm/src/arch/x86.s91
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