summaryrefslogtreecommitdiffstats
path: root/vendor/psm/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/psm/src/arch')
-rw-r--r--vendor/psm/src/arch/aarch64_armasm.asm38
-rw-r--r--vendor/psm/src/arch/aarch_aapcs64.s85
-rw-r--r--vendor/psm/src/arch/arm_aapcs.s106
-rw-r--r--vendor/psm/src/arch/arm_armasm.asm39
-rw-r--r--vendor/psm/src/arch/mips64_eabi.s87
-rw-r--r--vendor/psm/src/arch/mips_eabi.s88
-rw-r--r--vendor/psm/src/arch/powerpc32.s76
-rw-r--r--vendor/psm/src/arch/powerpc64.s90
-rw-r--r--vendor/psm/src/arch/powerpc64_openpower.s86
-rw-r--r--vendor/psm/src/arch/psm.h10
-rw-r--r--vendor/psm/src/arch/riscv.s64
-rw-r--r--vendor/psm/src/arch/riscv64.s64
-rw-r--r--vendor/psm/src/arch/sparc64.s67
-rw-r--r--vendor/psm/src/arch/sparc_sysv.s65
-rw-r--r--vendor/psm/src/arch/wasm32.s60
-rw-r--r--vendor/psm/src/arch/x86.s91
-rw-r--r--vendor/psm/src/arch/x86_64.s87
-rw-r--r--vendor/psm/src/arch/x86_64_msvc.asm61
-rw-r--r--vendor/psm/src/arch/x86_64_windows_gnu.s95
-rw-r--r--vendor/psm/src/arch/x86_msvc.asm70
-rw-r--r--vendor/psm/src/arch/x86_windows_gnu.s94
-rw-r--r--vendor/psm/src/arch/zseries_linux.s75
22 files changed, 1598 insertions, 0 deletions
diff --git a/vendor/psm/src/arch/aarch64_armasm.asm b/vendor/psm/src/arch/aarch64_armasm.asm
new file mode 100644
index 000000000..95349f9cc
--- /dev/null
+++ b/vendor/psm/src/arch/aarch64_armasm.asm
@@ -0,0 +1,38 @@
+ AREA |.text|, CODE, READONLY
+
+ GLOBAL |rust_psm_stack_direction|
+ ALIGN 4
+|rust_psm_stack_direction| PROC
+ orr w0, wzr, #2
+ ret
+ ENDP
+
+
+ GLOBAL |rust_psm_stack_pointer|
+ ALIGN 4
+|rust_psm_stack_pointer| PROC
+ mov x0, sp
+ ret
+ ENDP
+
+
+ GLOBAL |rust_psm_replace_stack|
+ ALIGN 4
+|rust_psm_replace_stack| PROC
+ mov sp, x2
+ br x1
+ ENDP
+
+ GLOBAL |rust_psm_on_stack|
+ ALIGN 4
+|rust_psm_on_stack| PROC
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+ mov sp, x3
+ blr x2
+ mov sp, x29
+ ldp x29, x30, [sp], #16
+ ret
+ ENDP
+
+ END
diff --git a/vendor/psm/src/arch/aarch_aapcs64.s b/vendor/psm/src/arch/aarch_aapcs64.s
new file mode 100644
index 000000000..55917f329
--- /dev/null
+++ b/vendor/psm/src/arch/aarch_aapcs64.s
@@ -0,0 +1,85 @@
+#include "psm.h"
+
+.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 2
+TYPE(rust_psm_stack_direction)
+FUNCTION(rust_psm_stack_direction):
+/* extern "C" fn() -> u8 */
+.cfi_startproc
+ orr w0, wzr, #STACK_DIRECTION_DESCENDING
+ ret
+.rust_psm_stack_direction_end:
+SIZE(rust_psm_stack_direction,.rust_psm_stack_direction_end)
+.cfi_endproc
+
+
+GLOBL(rust_psm_stack_pointer)
+.p2align 2
+TYPE(rust_psm_stack_pointer)
+FUNCTION(rust_psm_stack_pointer):
+/* extern "C" fn() -> *mut u8 */
+.cfi_startproc
+ mov x0, sp
+ ret
+.rust_psm_stack_pointer_end:
+SIZE(rust_psm_stack_pointer,.rust_psm_stack_pointer_end)
+.cfi_endproc
+
+
+GLOBL(rust_psm_replace_stack)
+.p2align 2
+TYPE(rust_psm_replace_stack)
+FUNCTION(rust_psm_replace_stack):
+/* extern "C" fn(r0: usize, r1: extern "C" fn(usize), r2: *mut u8) */
+.cfi_startproc
+/* All we gotta do is set the stack pointer to %rdx & tail-call the callback in %rsi */
+ mov sp, x2
+ br x1
+.rust_psm_replace_stack_end:
+SIZE(rust_psm_replace_stack,.rust_psm_replace_stack_end)
+.cfi_endproc
+
+
+GLOBL(rust_psm_on_stack)
+.p2align 2
+TYPE(rust_psm_on_stack)
+FUNCTION(rust_psm_on_stack):
+/* extern "C" fn(r0: usize, r1: usize, r2: extern "C" fn(usize, usize), r3: *mut u8) */
+.cfi_startproc
+ stp x29, x30, [sp, #-16]!
+ .cfi_def_cfa sp, 16
+ mov x29, sp
+ .cfi_def_cfa x29, 16
+ .cfi_offset x29, -16
+ .cfi_offset x30, -8
+ mov sp, x3
+ blr x2
+ mov sp, x29
+ .cfi_def_cfa sp, 16
+ ldp x29, x30, [sp], #16
+ .cfi_def_cfa sp, 0
+ .cfi_restore x29
+ .cfi_restore x30
+ ret
+.rust_psm_on_stack_end:
+SIZE(rust_psm_on_stack,.rust_psm_on_stack_end)
+.cfi_endproc
diff --git a/vendor/psm/src/arch/arm_aapcs.s b/vendor/psm/src/arch/arm_aapcs.s
new file mode 100644
index 000000000..c2fa9d81d
--- /dev/null
+++ b/vendor/psm/src/arch/arm_aapcs.s
@@ -0,0 +1,106 @@
+#include "psm.h"
+
+.text
+.syntax unified
+
+#if CFG_TARGET_OS_darwin || CFG_TARGET_OS_macos || CFG_TARGET_OS_ios
+
+#define GLOBL(fnname) .globl _##fnname
+#define THUMBTYPE(fnname) .thumb_func _##fnname
+#define FUNCTION(fnname) _##fnname
+#define THUMBFN .code 16
+#define SIZE(fnname,endlabel)
+#define FNSTART
+#define CANTUNWIND
+#define FNEND
+
+#else
+
+#define GLOBL(fnname) .globl fnname
+#define THUMBTYPE(fnname) .type fnname,%function
+#define FUNCTION(fnname) fnname
+#define THUMBFN .code 16
+#define SIZE(fnname,endlabel) .size fnname,endlabel-fnname
+#define FNSTART .fnstart
+#define CANTUNWIND .cantunwind
+#define FNEND .fnend
+
+#endif
+
+
+GLOBL(rust_psm_stack_direction)
+.p2align 2
+THUMBTYPE(rust_psm_stack_direction)
+THUMBFN
+FUNCTION(rust_psm_stack_direction):
+/* extern "C" fn() -> u8 */
+FNSTART
+.cfi_startproc
+ /* movs to support Thumb-1 */
+ movs r0, #STACK_DIRECTION_DESCENDING
+ bx lr
+.rust_psm_stack_direction_end:
+SIZE(rust_psm_stack_direction,.rust_psm_stack_direction_end)
+.cfi_endproc
+CANTUNWIND
+FNEND
+
+GLOBL(rust_psm_stack_pointer)
+.p2align 2
+THUMBTYPE(rust_psm_stack_pointer)
+THUMBFN
+FUNCTION(rust_psm_stack_pointer):
+/* extern "C" fn() -> *mut u8 */
+FNSTART
+.cfi_startproc
+ mov r0, sp
+ bx lr
+.rust_psm_stack_pointer_end:
+SIZE(rust_psm_stack_pointer,.rust_psm_stack_pointer_end)
+.cfi_endproc
+CANTUNWIND
+FNEND
+
+
+GLOBL(rust_psm_replace_stack)
+.p2align 2
+THUMBTYPE(rust_psm_replace_stack)
+THUMBFN
+FUNCTION(rust_psm_replace_stack):
+/* extern "C" fn(r0: usize, r1: extern "C" fn(usize), r2: *mut u8) */
+FNSTART
+.cfi_startproc
+/* All we gotta do is set the stack pointer to %rdx & tail-call the callback in %rsi */
+ mov sp, r2
+ bx r1
+.rust_psm_replace_stack_end:
+SIZE(rust_psm_replace_stack,.rust_psm_replace_stack_end)
+.cfi_endproc
+CANTUNWIND
+FNEND
+
+
+GLOBL(rust_psm_on_stack)
+.p2align 2
+THUMBTYPE(rust_psm_on_stack)
+THUMBFN
+FUNCTION(rust_psm_on_stack):
+/* extern "C" fn(r0: usize, r1: usize, r2: extern "C" fn(usize, usize), r3: *mut u8) */
+FNSTART
+.cfi_startproc
+ push {r4, lr}
+ .cfi_def_cfa_offset 8
+ mov r4, sp
+ .cfi_def_cfa_register r4
+ .cfi_offset lr, -4
+ .cfi_offset r4, -8
+ mov sp, r3
+ blx r2
+ mov sp, r4
+ .cfi_restore sp
+ pop {r4, pc}
+.rust_psm_on_stack_end:
+SIZE(rust_psm_on_stack,.rust_psm_on_stack_end)
+.cfi_endproc
+CANTUNWIND
+FNEND
diff --git a/vendor/psm/src/arch/arm_armasm.asm b/vendor/psm/src/arch/arm_armasm.asm
new file mode 100644
index 000000000..ab8a5bcf0
--- /dev/null
+++ b/vendor/psm/src/arch/arm_armasm.asm
@@ -0,0 +1,39 @@
+ THUMB
+ AREA |.text|, CODE, READONLY
+
+
+ GLOBAL |rust_psm_stack_direction|
+ ALIGN 4
+|rust_psm_stack_direction| PROC
+ movs r0, #2
+ bx lr
+ ENDP
+
+ GLOBAL |rust_psm_stack_pointer|
+ ALIGN 4
+|rust_psm_stack_pointer| PROC
+ mov r0, sp
+ bx lr
+ ENDP
+
+
+ GLOBAL |rust_psm_replace_stack|
+ ALIGN 4
+|rust_psm_replace_stack| PROC
+ mov sp, r2
+ bx r1
+ ENDP
+
+
+ GLOBAL |rust_psm_on_stack|
+ ALIGN 4
+|rust_psm_on_stack| PROC
+ push {r4, lr}
+ mov r4, sp
+ mov sp, r3
+ blx r2
+ mov sp, r4
+ pop {r4, pc}
+ ENDP
+
+ END
diff --git a/vendor/psm/src/arch/mips64_eabi.s b/vendor/psm/src/arch/mips64_eabi.s
new file mode 100644
index 000000000..72bc01eb7
--- /dev/null
+++ b/vendor/psm/src/arch/mips64_eabi.s
@@ -0,0 +1,87 @@
+/*
+Not only MIPS has 20 different ABIs... nobody tells anybody what specific variant of which ABI is
+used where.
+
+This is an "EABI" implementation based on the following page:
+
+http://www.cygwin.com/ml/binutils/2003-06/msg00436.html
+*/
+
+#include "psm.h"
+
+.set noreorder /* we’ll manage the delay slots on our own, thanks! */
+
+.text
+.globl rust_psm_stack_direction
+.p2align 3
+.type rust_psm_stack_direction,@function
+.ent rust_psm_stack_direction
+/* extern "C" fn() -> u8 */
+rust_psm_stack_direction:
+.cfi_startproc
+ jr $31
+ addiu $2, $zero, STACK_DIRECTION_DESCENDING
+.end rust_psm_stack_direction
+.rust_psm_stack_direction_end:
+.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction
+.cfi_endproc
+
+
+.globl rust_psm_stack_pointer
+.p2align 3
+.type rust_psm_stack_pointer,@function
+.ent rust_psm_stack_pointer
+/* extern "C" fn() -> *mut u8 */
+rust_psm_stack_pointer:
+.cfi_startproc
+ jr $31
+ move $2, $29
+.end rust_psm_stack_pointer
+.rust_psm_stack_pointer_end:
+.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer
+.cfi_endproc
+
+
+
+.globl rust_psm_replace_stack
+.p2align 3
+.type rust_psm_replace_stack,@function
+.ent rust_psm_replace_stack
+/* extern "C" fn(r4: usize, r5: extern "C" fn(usize), r6: *mut u8) */
+rust_psm_replace_stack:
+.cfi_startproc
+ move $25, $5
+ jr $5
+ move $29, $6
+.end rust_psm_replace_stack
+.rust_psm_replace_stack_end:
+.size rust_psm_replace_stack,.rust_psm_on_stack_end-rust_psm_on_stack
+.cfi_endproc
+
+
+.globl rust_psm_on_stack
+.p2align 3
+.type rust_psm_on_stack,@function
+.ent rust_psm_on_stack
+/* extern "C" fn(r4: usize, r5: usize, r6: extern "C" fn(usize), r7: *mut u8) */
+rust_psm_on_stack:
+.cfi_startproc
+ sd $29, -8($7)
+ sd $31, -16($7)
+ .cfi_def_cfa 7, 0
+ .cfi_offset 31, -16
+ .cfi_offset 29, -8
+ move $25, $6
+ jalr $31, $6
+ daddiu $29, $7, -16
+ .cfi_def_cfa 29, 16
+ ld $31, 0($29)
+ .cfi_restore 31
+ ld $29, 8($29)
+ .cfi_restore 29
+ jr $31
+ nop
+.end rust_psm_on_stack
+.rust_psm_on_stack_end:
+.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack
+.cfi_endproc
diff --git a/vendor/psm/src/arch/mips_eabi.s b/vendor/psm/src/arch/mips_eabi.s
new file mode 100644
index 000000000..e08ed278a
--- /dev/null
+++ b/vendor/psm/src/arch/mips_eabi.s
@@ -0,0 +1,88 @@
+/*
+Not only MIPS has 20 different ABIs... nobody tells anybody what specific variant of which ABI is
+used where.
+
+This is an "EABI" implementation based on the following page:
+
+http://www.cygwin.com/ml/binutils/2003-06/msg00436.html
+*/
+
+#include "psm.h"
+
+.set noreorder /* we’ll manage the delay slots on our own, thanks! */
+
+.text
+.abicalls
+.globl rust_psm_stack_direction
+.p2align 2
+.type rust_psm_stack_direction,@function
+.ent rust_psm_stack_direction
+/* extern "C" fn() -> u8 */
+rust_psm_stack_direction:
+.cfi_startproc
+ jr $31
+ addiu $2, $zero, STACK_DIRECTION_DESCENDING
+.end rust_psm_stack_direction
+.rust_psm_stack_direction_end:
+.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction
+.cfi_endproc
+
+
+.globl rust_psm_stack_pointer
+.p2align 2
+.type rust_psm_stack_pointer,@function
+.ent rust_psm_stack_pointer
+/* extern "C" fn() -> *mut u8 */
+rust_psm_stack_pointer:
+.cfi_startproc
+ jr $31
+ move $2, $29
+.end rust_psm_stack_pointer
+.rust_psm_stack_pointer_end:
+.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer
+.cfi_endproc
+
+
+
+.globl rust_psm_replace_stack
+.p2align 2
+.type rust_psm_replace_stack,@function
+.ent rust_psm_replace_stack
+/* extern "C" fn(r4: usize, r5: extern "C" fn(usize), r6: *mut u8) */
+rust_psm_replace_stack:
+.cfi_startproc
+ move $25, $5
+ jr $5
+ move $29, $6
+.end rust_psm_replace_stack
+.rust_psm_replace_stack_end:
+.size rust_psm_replace_stack,.rust_psm_on_stack_end-rust_psm_on_stack
+.cfi_endproc
+
+
+.globl rust_psm_on_stack
+.p2align 2
+.type rust_psm_on_stack,@function
+.ent rust_psm_on_stack
+/* extern "C" fn(r4: usize, r5: usize, r6: extern "C" fn(usize), r7: *mut u8) */
+rust_psm_on_stack:
+.cfi_startproc
+ sw $29, -4($7)
+ sw $31, -8($7)
+ .cfi_def_cfa 7, 0
+ .cfi_offset 31, -8
+ .cfi_offset 29, -4
+ move $25, $6
+ jalr $31, $6
+ addiu $29, $7, -8
+ .cfi_def_cfa 29, 8
+ lw $31, 0($29)
+ .cfi_restore 31
+ lw $29, 4($29)
+ .cfi_restore 29
+ jr $31
+ nop
+.end rust_psm_on_stack
+.rust_psm_on_stack_end:
+.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack
+.cfi_endproc
diff --git a/vendor/psm/src/arch/powerpc32.s b/vendor/psm/src/arch/powerpc32.s
new file mode 100644
index 000000000..1f7a08619
--- /dev/null
+++ b/vendor/psm/src/arch/powerpc32.s
@@ -0,0 +1,76 @@
+#include "psm.h"
+/* FIXME: this probably does not cover all ABIs? Tested with sysv only, possibly works for AIX as
+ well?
+*/
+
+.text
+.globl rust_psm_stack_direction
+.p2align 2
+.type rust_psm_stack_direction,@function
+rust_psm_stack_direction:
+/* extern "C" fn() -> u8 */
+.cfi_startproc
+ li 3, STACK_DIRECTION_DESCENDING
+ blr
+.rust_psm_stack_direction_end:
+.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction
+.cfi_endproc
+
+
+.globl rust_psm_stack_pointer
+.p2align 2
+.type rust_psm_stack_pointer,@function
+rust_psm_stack_pointer:
+/* extern "C" fn() -> *mut u8 */
+.cfi_startproc
+ mr 3, 1
+ blr
+.rust_psm_stack_pointer_end:
+.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer
+.cfi_endproc
+
+
+.globl rust_psm_replace_stack
+.p2align 2
+.type rust_psm_replace_stack,@function
+rust_psm_replace_stack:
+/* extern "C" fn(3: usize, 4: extern "C" fn(usize), 5: *mut u8) */
+.cfi_startproc
+/* NOTE: perhaps add a debug-assertion for stack alignment? */
+ addi 5, 5, -16
+ mr 1, 5
+ mtctr 4
+ bctr
+.rust_psm_replace_stack_end:
+.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack
+.cfi_endproc
+
+
+.globl rust_psm_on_stack
+.p2align 2
+.type rust_psm_on_stack,@function
+rust_psm_on_stack:
+/* extern "C" fn(3: usize, 4: usize, 5: extern "C" fn(usize, usize), 6: *mut u8) */
+.cfi_startproc
+ mflr 0
+ stw 0, -24(6)
+ sub 6, 6, 1
+ addi 6, 6, -32
+ stwux 1, 1, 6
+ .cfi_def_cfa r1, 32
+ .cfi_offset r1, -32
+ .cfi_offset lr, -24
+ mtctr 5
+ bctrl
+ lwz 0, 8(1)
+ mtlr 0
+ .cfi_restore lr
+ /* FIXME: after this instruction backtrace breaks until control returns to the caller
+ That being said compiler-generated code has the same issue, so I guess that is fine for now?
+ */
+ lwz 1, 0(1)
+ .cfi_restore r1
+ blr
+.rust_psm_on_stack_end:
+.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack
+.cfi_endproc
diff --git a/vendor/psm/src/arch/powerpc64.s b/vendor/psm/src/arch/powerpc64.s
new file mode 100644
index 000000000..1504a8c01
--- /dev/null
+++ b/vendor/psm/src/arch/powerpc64.s
@@ -0,0 +1,90 @@
+/* Implementation of the AIX-like PowerPC ABI. Seems to be used by the big-endian PowerPC targets.
+ The following references were used during the implementation of this code:
+
+ https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.alangref/idalangref_rntime_stack.htm
+ https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.alangref/idalangref_reg_use_conv.htm
+ https://www.ibm.com/developerworks/library/l-powasm4/index.html
+*/
+
+#include "psm.h"
+
+.text
+.globl rust_psm_stack_direction
+.p2align 2
+.type rust_psm_stack_direction,@function
+rust_psm_stack_direction:
+/* extern "C" fn() -> u8 */
+.cfi_startproc
+ li 3, STACK_DIRECTION_DESCENDING
+ blr
+.rust_psm_stack_direction_end:
+.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction
+.cfi_endproc
+
+
+.globl rust_psm_stack_pointer
+.p2align 2
+.type rust_psm_stack_pointer,@function
+rust_psm_stack_pointer:
+/* extern "C" fn() -> *mut u8 */
+.cfi_startproc
+ mr 3, 1
+ blr
+.rust_psm_stack_pointer_end:
+.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer
+.cfi_endproc
+
+
+.globl rust_psm_replace_stack
+.p2align 2
+.type rust_psm_replace_stack,@function
+rust_psm_replace_stack:
+/* extern "C" fn(3: usize, 4: extern "C" fn(usize), 5: *mut u8) */
+.cfi_startproc
+ ld 2, 8(4)
+ ld 4, 0(4)
+ /* do not allocate the whole 112-byte sized frame, we know wont be used */
+ addi 5, 5, -48
+ mr 1, 5
+ mtctr 4
+ bctr
+.rust_psm_replace_stack_end:
+.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack
+.cfi_endproc
+
+
+.globl rust_psm_on_stack
+.p2align 2
+.type rust_psm_on_stack,@function
+rust_psm_on_stack:
+/* extern "C" fn(3: usize, 4: usize, 5: extern "C" fn(usize, usize), 6: *mut u8) */
+.cfi_startproc
+ mflr 0
+ std 2, -72(6)
+ std 0, -8(6)
+ sub 6, 6, 1
+ addi 6, 6, -112
+ stdux 1, 1, 6
+ .cfi_def_cfa r1, 112
+ .cfi_offset r1, -112
+ .cfi_offset r2, -72
+ .cfi_offset lr, -8
+ /* load the function pointer from TOC and make the call */
+ ld 2, 8(5)
+ ld 5, 0(5)
+ mtctr 5
+ bctrl
+ ld 2, 40(1)
+ .cfi_restore r2
+ ld 0, 104(1)
+ mtlr 0
+ .cfi_restore lr
+ /* FIXME: after this instruction backtrace breaks until control returns to the caller.
+ That being said compiler-generated code has the same issue, so I guess that is fine for now?
+ */
+ ld 1, 0(1)
+ .cfi_restore r1
+ blr
+.rust_psm_on_stack_end:
+.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack
+.cfi_endproc
diff --git a/vendor/psm/src/arch/powerpc64_openpower.s b/vendor/psm/src/arch/powerpc64_openpower.s
new file mode 100644
index 000000000..eb3c1c174
--- /dev/null
+++ b/vendor/psm/src/arch/powerpc64_openpower.s
@@ -0,0 +1,86 @@
+/* Implementation of stack swtiching routines for OpenPOWER 64-bit ELF ABI
+ The specification can be found at
+ http://openpowerfoundation.org/wp-content/uploads/resources/leabi/content/ch_preface.html
+
+ This ABI is usually used by the ppc64le targets.
+*/
+
+#include "psm.h"
+
+.text
+.abiversion 2
+
+
+.globl rust_psm_stack_direction
+.p2align 4
+.type rust_psm_stack_direction,@function
+rust_psm_stack_direction:
+/* extern "C" fn() -> u8 */
+.cfi_startproc
+ li 3, STACK_DIRECTION_DESCENDING
+ blr
+.rust_psm_stack_direction_end:
+.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction
+.cfi_endproc
+
+
+.globl rust_psm_stack_pointer
+.p2align 4
+.type rust_psm_stack_pointer,@function
+rust_psm_stack_pointer:
+/* extern "C" fn() -> *mut u8 */
+.cfi_startproc
+ mr 3, 1
+ blr
+.rust_psm_stack_pointer_end:
+.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer
+.cfi_endproc
+
+
+.globl rust_psm_replace_stack
+.p2align 4
+.type rust_psm_replace_stack,@function
+rust_psm_replace_stack:
+/* extern "C" fn(3: usize, 4: extern "C" fn(usize), 5: *mut u8) */
+.cfi_startproc
+ addi 5, 5, -32
+ mtctr 4
+ mr 12, 4
+ mr 1, 5
+ bctr
+.rust_psm_replace_stack_end:
+.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack
+.cfi_endproc
+
+
+
+.globl rust_psm_on_stack
+.p2align 4
+.type rust_psm_on_stack,@function
+rust_psm_on_stack:
+/* extern "C" fn(3: usize, 4: usize, 5: extern "C" fn(usize, usize), 6: *mut u8) */
+.cfi_startproc
+ mflr 0
+ std 0, -8(6)
+ std 2, -24(6)
+ sub 6, 6, 1
+ addi 6, 6, -48
+ stdux 1, 1, 6
+ .cfi_def_cfa r1, 48
+ .cfi_offset r1, -48
+ .cfi_offset r2, -24
+ .cfi_offset lr, -8
+ mr 12, 5
+ mtctr 5
+ bctrl
+ ld 2, 24(1)
+ .cfi_restore r2
+ ld 0, 40(1)
+ mtlr 0
+ .cfi_restore lr
+ /* FIXME: after this instructin backtrace breaks until control returns to the caller */
+ ld 1, 0(1)
+ blr
+.rust_psm_on_stack_end:
+.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack
+.cfi_endproc
diff --git a/vendor/psm/src/arch/psm.h b/vendor/psm/src/arch/psm.h
new file mode 100644
index 000000000..c1137f984
--- /dev/null
+++ b/vendor/psm/src/arch/psm.h
@@ -0,0 +1,10 @@
+#define STACK_DIRECTION_ASCENDING 1
+#define STACK_DIRECTION_DESCENDING 2
+
+
+/*
+Various defines for values produced by `-DCFG_TARGET_*` flags. Only needs to be mutually unique
+*/
+#define darwin 1
+#define macos 2
+#define ios 3
diff --git a/vendor/psm/src/arch/riscv.s b/vendor/psm/src/arch/riscv.s
new file mode 100644
index 000000000..4972993c9
--- /dev/null
+++ b/vendor/psm/src/arch/riscv.s
@@ -0,0 +1,64 @@
+#include "psm.h"
+
+.text
+.globl rust_psm_stack_direction
+.p2align 2
+.type rust_psm_stack_direction,@function
+rust_psm_stack_direction:
+/* extern "C" fn() -> u8 */
+.cfi_startproc
+ li x10, STACK_DIRECTION_DESCENDING
+ jr x1
+.rust_psm_stack_direction_end:
+.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction
+.cfi_endproc
+
+
+.globl rust_psm_stack_pointer
+.p2align 2
+.type rust_psm_stack_pointer,@function
+rust_psm_stack_pointer:
+/* extern "C" fn() -> *mut u8 */
+.cfi_startproc
+ add x10, x2, x0
+ jr x1
+.rust_psm_stack_pointer_end:
+.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer
+.cfi_endproc
+
+
+.globl rust_psm_replace_stack
+.p2align 2
+.type rust_psm_replace_stack,@function
+rust_psm_replace_stack:
+/* extern "C" fn(x10: usize, x11: extern "C" fn(usize), x12: *mut u8) */
+.cfi_startproc
+ add x2, x12, x0
+ jr x11
+.rust_psm_replace_stack_end:
+.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack
+.cfi_endproc
+
+
+.globl rust_psm_on_stack
+.p2align 2
+.type rust_psm_on_stack,@function
+rust_psm_on_stack:
+/* extern "C" fn(x10: usize, x11: usize, x12: extern "C" fn(usize, usize), x13: *mut u8) */
+.cfi_startproc
+ sw x1, -12(x13)
+ sw x2, -16(x13)
+ .cfi_def_cfa x13, 0
+ .cfi_offset x1, -12
+ .cfi_offset x2, -16
+ addi x2, x13, -16
+ .cfi_def_cfa x2, -16
+ jalr x1, x12, 0
+ lw x1, 4(x2)
+ .cfi_restore x1
+ lw x2, 0(x2)
+ .cfi_restore x2
+ jr x1
+.rust_psm_on_stack_end:
+.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack
+.cfi_endproc
diff --git a/vendor/psm/src/arch/riscv64.s b/vendor/psm/src/arch/riscv64.s
new file mode 100644
index 000000000..1b275ec27
--- /dev/null
+++ b/vendor/psm/src/arch/riscv64.s
@@ -0,0 +1,64 @@
+#include "psm.h"
+
+.text
+.globl rust_psm_stack_direction
+.p2align 2
+.type rust_psm_stack_direction,@function
+rust_psm_stack_direction:
+/* extern "C" fn() -> u8 */
+.cfi_startproc
+ li x10, STACK_DIRECTION_DESCENDING
+ jr x1
+.rust_psm_stack_direction_end:
+.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction
+.cfi_endproc
+
+
+.globl rust_psm_stack_pointer
+.p2align 2
+.type rust_psm_stack_pointer,@function
+rust_psm_stack_pointer:
+/* extern "C" fn() -> *mut u8 */
+.cfi_startproc
+ add x10, x2, x0
+ jr x1
+.rust_psm_stack_pointer_end:
+.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer
+.cfi_endproc
+
+
+.globl rust_psm_replace_stack
+.p2align 2
+.type rust_psm_replace_stack,@function
+rust_psm_replace_stack:
+/* extern "C" fn(x10: usize, x11: extern "C" fn(usize), x12: *mut u8) */
+.cfi_startproc
+ add x2, x12, x0
+ jr x11
+.rust_psm_replace_stack_end:
+.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack
+.cfi_endproc
+
+
+.globl rust_psm_on_stack
+.p2align 2
+.type rust_psm_on_stack,@function
+rust_psm_on_stack:
+/* extern "C" fn(x10: usize, x11: usize, x12: extern "C" fn(usize, usize), x13: *mut u8) */
+.cfi_startproc
+ sd x1, -8(x13)
+ sd x2, -16(x13)
+ .cfi_def_cfa x13, 0
+ .cfi_offset x1, -8
+ .cfi_offset x2, -16
+ addi x2, x13, -16
+ .cfi_def_cfa x2, -16
+ jalr x1, x12, 0
+ ld x1, 8(x2)
+ .cfi_restore x1
+ ld x2, 0(x2)
+ .cfi_restore x2
+ jr x1
+.rust_psm_on_stack_end:
+.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack
+.cfi_endproc
diff --git a/vendor/psm/src/arch/sparc64.s b/vendor/psm/src/arch/sparc64.s
new file mode 100644
index 000000000..a0db27dde
--- /dev/null
+++ b/vendor/psm/src/arch/sparc64.s
@@ -0,0 +1,67 @@
+#include "psm.h"
+
+.text
+.globl rust_psm_stack_direction
+.p2align 2
+.type rust_psm_stack_direction,@function
+rust_psm_stack_direction:
+/* extern "C" fn() -> u8 */
+.cfi_startproc
+ jmpl %o7 + 8, %g0
+ mov STACK_DIRECTION_DESCENDING, %o0
+.rust_psm_stack_direction_end:
+.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction
+.cfi_endproc
+
+
+.globl rust_psm_stack_pointer
+.p2align 2
+.type rust_psm_stack_pointer,@function
+rust_psm_stack_pointer:
+/* extern "C" fn() -> *mut u8 */
+.cfi_startproc
+ jmpl %o7 + 8, %g0
+ mov %o6, %o0
+.rust_psm_stack_pointer_end:
+.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer
+.cfi_endproc
+
+
+.globl rust_psm_replace_stack
+.p2align 2
+.type rust_psm_replace_stack,@function
+rust_psm_replace_stack:
+/* extern "C" fn(%i0: usize, %i1: extern "C" fn(usize), %i2: *mut u8) */
+.cfi_startproc
+ .cfi_def_cfa 0, 0
+ .cfi_return_column 0
+ jmpl %o1, %g0
+ /* WEIRD: Why is the LSB set for the %sp and %fp on SPARC?? */
+ add %o2, -0x7ff, %o6
+.rust_psm_replace_stack_end:
+.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack
+.cfi_endproc
+
+
+.globl rust_psm_on_stack
+.p2align 2
+.type rust_psm_on_stack,@function
+rust_psm_on_stack:
+/* extern "C" fn(%i0: usize, %i1: usize, %i2: extern "C" fn(usize, usize), %i3: *mut u8) */
+.cfi_startproc
+ /* The fact that locals and saved register windows are offset by 2kB is
+ very nasty property of SPARC architecture and ABI. In this case it forces us to slice off
+ 2kB of the stack space outright for no good reason other than adapting to a botched design.
+ */
+ save %o3, -0x87f, %o6
+ .cfi_def_cfa_register %fp
+ .cfi_window_save
+ .cfi_register %r15, %r31
+ mov %i1, %o1
+ jmpl %i2, %o7
+ mov %i0, %o0
+ ret
+ restore
+.rust_psm_on_stack_end:
+.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack
+.cfi_endproc
diff --git a/vendor/psm/src/arch/sparc_sysv.s b/vendor/psm/src/arch/sparc_sysv.s
new file mode 100644
index 000000000..27d95e933
--- /dev/null
+++ b/vendor/psm/src/arch/sparc_sysv.s
@@ -0,0 +1,65 @@
+#include "psm.h"
+
+/* FIXME: this ABI has definitely not been verified at all */
+
+.text
+.globl rust_psm_stack_direction
+.p2align 2
+.type rust_psm_stack_direction,@function
+rust_psm_stack_direction:
+/* extern "C" fn() -> u8 */
+.cfi_startproc
+ jmpl %o7 + 8, %g0
+ mov STACK_DIRECTION_DESCENDING, %o0
+.rust_psm_stack_direction_end:
+.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction
+.cfi_endproc
+
+
+.globl rust_psm_stack_pointer
+.p2align 2
+.type rust_psm_stack_pointer,@function
+rust_psm_stack_pointer:
+/* extern "C" fn() -> *mut u8 */
+.cfi_startproc
+ jmpl %o7 + 8, %g0
+ mov %o6, %o0
+.rust_psm_stack_pointer_end:
+.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer
+.cfi_endproc
+
+
+.globl rust_psm_replace_stack
+.p2align 2
+.type rust_psm_replace_stack,@function
+rust_psm_replace_stack:
+/* extern "C" fn(%i0: usize, %i1: extern "C" fn(usize), %i2: *mut u8) */
+.cfi_startproc
+ .cfi_def_cfa 0, 0
+ .cfi_return_column 0
+ jmpl %o1, %g0
+ /* WEIRD: Why is the LSB set for the %sp and %fp on SPARC?? */
+ add %o2, -0x3ff, %o6
+.rust_psm_replace_stack_end:
+.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack
+.cfi_endproc
+
+
+.globl rust_psm_on_stack
+.p2align 2
+.type rust_psm_on_stack,@function
+rust_psm_on_stack:
+/* extern "C" fn(%i0: usize, %i1: usize, %i2: extern "C" fn(usize, usize), %i3: *mut u8) */
+.cfi_startproc
+ save %o3, -0x43f, %o6
+ .cfi_def_cfa_register %fp
+ .cfi_window_save
+ .cfi_register %r15, %r31
+ mov %i1, %o1
+ jmpl %i2, %o7
+ mov %i0, %o0
+ ret
+ restore
+.rust_psm_on_stack_end:
+.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack
+.cfi_endproc
diff --git a/vendor/psm/src/arch/wasm32.s b/vendor/psm/src/arch/wasm32.s
new file mode 100644
index 000000000..e3364e7af
--- /dev/null
+++ b/vendor/psm/src/arch/wasm32.s
@@ -0,0 +1,60 @@
+#include "psm.h"
+
+# Note that this function is not compiled when this package is uploaded to
+# crates.io, this source is only here as a reference for how the corresponding
+# wasm32.o was generated. This file can be compiled with:
+#
+# cpp psm/src/arch/wasm32.s | llvm-mc -o psm/src/arch/wasm32.o --arch=wasm32 -filetype=obj
+#
+# where you'll want to ensure that `llvm-mc` is from a relatively recent
+# version of LLVM.
+
+.globaltype __stack_pointer, i32
+
+.globl rust_psm_stack_direction
+.type rust_psm_stack_direction,@function
+rust_psm_stack_direction:
+.functype rust_psm_stack_direction () -> (i32)
+ i32.const STACK_DIRECTION_DESCENDING
+ end_function
+
+.globl rust_psm_stack_pointer
+.type rust_psm_stack_pointer,@function
+rust_psm_stack_pointer:
+.functype rust_psm_stack_pointer () -> (i32)
+ global.get __stack_pointer
+ end_function
+
+.globl rust_psm_on_stack
+.type rust_psm_on_stack,@function
+rust_psm_on_stack:
+.functype rust_psm_on_stack (i32, i32, i32, i32) -> ()
+ # get our new stack argument, then save the old stack
+ # pointer into that local
+ local.get 3
+ global.get __stack_pointer
+ local.set 3
+ global.set __stack_pointer
+
+ # Call our indirect function specified
+ local.get 0
+ local.get 1
+ local.get 2
+ call_indirect (i32, i32) -> ()
+
+ # restore the stack pointer before returning
+ local.get 3
+ global.set __stack_pointer
+ end_function
+
+.globl rust_psm_replace_stack
+.type rust_psm_replace_stack,@function
+rust_psm_replace_stack:
+.functype rust_psm_replace_stack (i32, i32, i32) -> ()
+ local.get 2
+ global.set __stack_pointer
+ local.get 0
+ local.get 1
+ call_indirect (i32) -> ()
+ unreachable
+ end_function
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
diff --git a/vendor/psm/src/arch/x86_64.s b/vendor/psm/src/arch/x86_64.s
new file mode 100644
index 000000000..5f5ece5b1
--- /dev/null
+++ b/vendor/psm/src/arch/x86_64.s
@@ -0,0 +1,87 @@
+#include "psm.h"
+/* NOTE: sysv64 calling convention is used on all x86_64 targets, including Windows! */
+
+.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 "sysv64" fn() -> u8 (%al) */
+.cfi_startproc
+ movb $STACK_DIRECTION_DESCENDING, %al # always descending on x86_64
+ retq
+.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 "sysv64" fn() -> *mut u8 (%rax) */
+.cfi_startproc
+ leaq 8(%rsp), %rax
+ retq
+.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 "sysv64" fn(%rdi: usize, %rsi: extern "sysv64" fn(usize), %rdx: *mut u8) */
+.cfi_startproc
+/*
+ All we gotta do is set the stack pointer to %rdx & tail-call the callback in %rsi.
+
+ 8-byte offset necessary to account for the "return" pointer that would otherwise be placed onto
+ stack with a regular call
+*/
+ leaq -8(%rdx), %rsp
+ jmpq *%rsi
+.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 "sysv64" fn(%rdi: usize, %rsi: usize, %rdx: extern "sysv64" fn(usize, usize), %rcx: *mut u8) */
+.cfi_startproc
+ pushq %rbp
+ .cfi_def_cfa %rsp, 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movq %rcx, %rsp
+ callq *%rdx
+ movq %rbp, %rsp
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.rust_psm_on_stack_end:
+SIZE(rust_psm_on_stack,.rust_psm_on_stack_end)
+.cfi_endproc
diff --git a/vendor/psm/src/arch/x86_64_msvc.asm b/vendor/psm/src/arch/x86_64_msvc.asm
new file mode 100644
index 000000000..67d72832f
--- /dev/null
+++ b/vendor/psm/src/arch/x86_64_msvc.asm
@@ -0,0 +1,61 @@
+PUBLIC rust_psm_stack_direction
+PUBLIC rust_psm_stack_pointer
+PUBLIC rust_psm_replace_stack
+PUBLIC rust_psm_on_stack
+
+_TEXT SEGMENT
+
+; extern "sysv64" fn() -> u8 (%al)
+rust_psm_stack_direction PROC
+ mov al, 2
+ ret
+rust_psm_stack_direction ENDP
+
+; extern "sysv64" fn() -> *mut u8 (%rax)
+rust_psm_stack_pointer PROC
+ lea rax, [rsp + 8]
+ ret
+rust_psm_stack_pointer ENDP
+
+; extern "sysv64" fn(%rdi: usize, %rsi: extern "sysv64" fn(usize), %rdx: *mut u8, %rcx: *mut u8)
+rust_psm_replace_stack PROC
+ mov gs:[08h], rdx
+ mov gs:[10h], rcx
+ lea rsp, [rdx - 8]
+ jmp rsi
+rust_psm_replace_stack ENDP
+
+; extern "sysv64" fn(%rdi: usize, %rsi: usize,
+; %rdx: extern "sysv64" fn(usize, usize), %rcx: *mut u8, %r8: *mut u8)
+;
+; NB: on Windows for SEH to work at all, the pointers in TIB, thread information block, need to be
+; fixed up. Otherwise, it seems that exception mechanism on Windows will not bother looking for
+; exception handlers at *all* if they happen to fall outside the are specified in TIB.
+;
+; This necessitates an API difference from the usual 4-argument signature used elsewhere.
+;
+; FIXME: this needs a catch-all exception handler that aborts in case somebody unwinds into here.
+rust_psm_on_stack PROC FRAME
+ push rbp
+ .pushreg rbp
+ mov rbp, rsp
+ .setframe rbp, 0
+ .endprolog
+
+ push gs:[08h]
+ mov gs:[08h], rcx
+ push gs:[10h]
+ mov gs:[10h], r8
+ mov rsp, rcx
+ call rdx
+ lea rsp, [rbp - 010h]
+ pop gs:[10h]
+ pop gs:[08h]
+
+ pop rbp
+ ret
+rust_psm_on_stack ENDP
+
+_TEXT ENDS
+
+END
diff --git a/vendor/psm/src/arch/x86_64_windows_gnu.s b/vendor/psm/src/arch/x86_64_windows_gnu.s
new file mode 100644
index 000000000..8f1258356
--- /dev/null
+++ b/vendor/psm/src/arch/x86_64_windows_gnu.s
@@ -0,0 +1,95 @@
+.text
+
+.def rust_psm_stack_direction
+.scl 2
+.type 32
+.endef
+.globl rust_psm_stack_direction
+.p2align 4
+rust_psm_stack_direction:
+/* extern "sysv64" fn() -> u8 (%al) */
+.cfi_startproc
+ movb $2, %al # always descending on x86_64
+ retq
+.cfi_endproc
+
+.def rust_psm_stack_pointer
+.scl 2
+.type 32
+.endef
+.globl rust_psm_stack_pointer
+.p2align 4
+rust_psm_stack_pointer:
+/* extern "sysv64" fn() -> *mut u8 (%rax) */
+.cfi_startproc
+ leaq 8(%rsp), %rax
+ retq
+.cfi_endproc
+
+
+.def rust_psm_replace_stack
+.scl 2
+.type 32
+.endef
+.globl rust_psm_replace_stack
+.p2align 4
+rust_psm_replace_stack:
+/* extern "sysv64" fn(%rdi: usize, %rsi: extern "sysv64" fn(usize), %rdx: *mut u8, %rcx: *mut u8) */
+.cfi_startproc
+/*
+ All we gotta do is set the stack pointer to %rdx & tail-call the callback in %rsi.
+
+ 8-byte offset necessary to account for the "return" pointer that would otherwise be placed onto
+ stack with a regular call
+*/
+ movq %gs:0x08, %rdx
+ movq %gs:0x10, %rcx
+ leaq -8(%rdx), %rsp
+ jmpq *%rsi
+.cfi_endproc
+
+
+.def rust_psm_on_stack
+.scl 2
+.type 32
+.endef
+.globl rust_psm_on_stack
+.p2align 4
+rust_psm_on_stack:
+/*
+extern "sysv64" fn(%rdi: usize, %rsi: usize,
+ %rdx: extern "sysv64" fn(usize, usize), %rcx: *mut u8, %r8: *mut u8)
+
+NB: on Windows for SEH to work at all, the pointers in TIB, thread information block, need to be
+fixed up. Otherwise, it seems that exception mechanism on Windows will not bother looking for
+exception handlers at *all* if they happen to fall outside the are specified in TIB.
+
+This necessitates an API difference from the usual 4-argument signature used elsewhere.
+
+FIXME: this needs a catch-all exception handler that aborts in case somebody unwinds into here.
+*/
+.cfi_startproc
+ pushq %rbp
+ .cfi_def_cfa %rsp, 16
+ .cfi_offset %rbp, -16
+ pushq %gs:0x08
+ .cfi_def_cfa %rsp, 24
+ pushq %gs:0x10
+ .cfi_def_cfa %rsp, 32
+
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movq %rcx, %gs:0x08
+ movq %r8, %gs:0x10
+ movq %rcx, %rsp
+ callq *%rdx
+ movq %rbp, %rsp
+
+ popq %gs:0x10
+ .cfi_def_cfa %rsp, 24
+ popq %gs:0x08
+ .cfi_def_cfa %rsp, 16
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.cfi_endproc
diff --git a/vendor/psm/src/arch/x86_msvc.asm b/vendor/psm/src/arch/x86_msvc.asm
new file mode 100644
index 000000000..3838759f7
--- /dev/null
+++ b/vendor/psm/src/arch/x86_msvc.asm
@@ -0,0 +1,70 @@
+; FIXME: this is weird, this works locally but not on appveyor?!??!
+
+.386
+.model flat
+
+ASSUME FS:NOTHING
+
+; WTF: PUBLIC conflicts with "SYSCALL" but "SYSCALL" is the only way to stop MASM from manging the
+; symbol names?
+;
+; PUBLIC @rust_psm_stack_direction@0
+; PUBLIC @rust_psm_stack_pointer@0
+; PUBLIC @rust_psm_replace_stack@12
+; PUBLIC @rust_psm_on_stack@16
+
+_TEXT SEGMENT
+
+; extern "fastcall" fn() -> u8 (%al)
+@rust_psm_stack_direction@0 PROC SYSCALL
+ mov al, 2
+ ret
+@rust_psm_stack_direction@0 ENDP
+
+; extern "fastcall" fn() -> *mut u8 (%rax)
+@rust_psm_stack_pointer@0 PROC SYSCALL
+ lea eax, [esp + 4]
+ ret
+@rust_psm_stack_pointer@0 ENDP
+
+; extern "fastcall" fn(%ecx: usize, %edx: extern "fastcall" fn(usize),
+; 4(%esp): *mut u8, 8(%esp): *mut u8)
+@rust_psm_replace_stack@16 PROC SYSCALL
+ mov eax, dword ptr [esp + 8]
+ mov fs:[08h], eax
+ mov esp, dword ptr [esp + 4]
+ mov fs:[04h], esp
+ jmp edx
+@rust_psm_replace_stack@16 ENDP
+
+; extern "fastcall" fn(%ecx: usize, %edx: usize, 4(%esp): extern "fastcall" fn(usize, usize),
+; 8(%esp): *mut u8, 12(%esp): *mut u8)
+;
+; NB: on Windows for SEH to work at all, the pointers in TIB, thread information block, need to be
+; fixed up. Otherwise, it seems that exception mechanism on Windows will not bother looking for
+; exception handlers at *all* if they happen to fall outside the are specified in TIB.
+;
+; This necessitates an API difference from the usual 4-argument signature used elsewhere.
+@rust_psm_on_stack@20 PROC SYSCALL
+ push ebp
+ mov ebp, esp
+
+ push fs:[0E0Ch]
+ push fs:[08h]
+ mov eax, dword ptr [ebp + 4 + 12]
+ mov dword ptr fs:[08h], eax
+ mov dword ptr fs:[0E0Ch], eax
+ push fs:[04h]
+ mov esp, dword ptr [ebp + 4 + 8]
+ mov dword ptr fs:[04h], esp
+ call dword ptr [ebp + 4 + 4]
+
+ lea esp, [ebp - 12]
+ pop fs:[04h]
+ pop fs:[08h]
+ pop fs:[0E0Ch]
+ pop ebp
+ ret 12
+@rust_psm_on_stack@20 ENDP
+
+END
diff --git a/vendor/psm/src/arch/x86_windows_gnu.s b/vendor/psm/src/arch/x86_windows_gnu.s
new file mode 100644
index 000000000..474d4168a
--- /dev/null
+++ b/vendor/psm/src/arch/x86_windows_gnu.s
@@ -0,0 +1,94 @@
+/* FIXME: this works locally but not on appveyor??!? */
+/* NOTE: fastcall calling convention used on all x86 targets */
+.text
+
+.def @rust_psm_stack_direction@0
+.scl 2
+.type 32
+.endef
+.globl @rust_psm_stack_direction@0
+.p2align 4
+@rust_psm_stack_direction@0:
+/* extern "fastcall" fn() -> u8 (%al) */
+.cfi_startproc
+ movb $2, %al # always descending on x86_64
+ retl
+.cfi_endproc
+
+
+.def @rust_psm_stack_pointer@0
+.scl 2
+.type 32
+.endef
+.globl @rust_psm_stack_pointer@0
+.p2align 4
+@rust_psm_stack_pointer@0:
+/* extern "fastcall" fn() -> *mut u8 (%rax) */
+.cfi_startproc
+ leal 4(%esp), %eax
+ retl
+.cfi_endproc
+
+
+.def @rust_psm_replace_stack@16
+.scl 2
+.type 32
+.endef
+.globl @rust_psm_replace_stack@16
+.p2align 4
+@rust_psm_replace_stack@16:
+/* 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 8(%esp), %eax
+ mov %eax, %fs:0x08
+ movl 4(%esp), %esp
+ mov %esp, %fs:0x04
+ calll *%edx
+ ud2
+.cfi_endproc
+
+
+.def @rust_psm_on_stack@16
+.scl 2
+.type 32
+.endef
+.globl @rust_psm_on_stack@16
+.p2align 4
+@rust_psm_on_stack@16:
+/* 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
+ pushl %fs:0x04
+ .cfi_def_cfa %esp, 12
+ pushl %fs:0x08
+ .cfi_def_cfa %esp, 16
+ movl %esp, %ebp
+ .cfi_def_cfa_register %ebp
+
+ movl 24(%ebp), %eax
+ movl %eax, %fs:0x08
+ movl 20(%ebp), %esp
+ movl %esp, %fs:0x04
+ calll *16(%ebp)
+
+ movl %ebp, %esp
+ popl %fs:0x08
+ .cfi_def_cfa %esp, 12
+ popl %fs:0x04
+ .cfi_def_cfa %esp, 8
+ popl %ebp
+ .cfi_def_cfa %esp, 4
+ retl $12
+.cfi_endproc
+
diff --git a/vendor/psm/src/arch/zseries_linux.s b/vendor/psm/src/arch/zseries_linux.s
new file mode 100644
index 000000000..e2536a1c9
--- /dev/null
+++ b/vendor/psm/src/arch/zseries_linux.s
@@ -0,0 +1,75 @@
+/* Implementation of stack swtiching routines for zSeries LINUX ABI.
+
+ This ABI is used by the s390x-unknown-linux-gnu target.
+
+ Documents used:
+
+ * LINUX for zSeries: ELF Application Binary Interface Supplement (1st ed., 2001) (LNUX-1107-01)
+ * z/Architecture: Principles of Operation (4th ed., 2004) (SA22-7832-03)
+*/
+
+#include "psm.h"
+
+.text
+
+
+.globl rust_psm_stack_direction
+.p2align 4
+.type rust_psm_stack_direction,@function
+rust_psm_stack_direction:
+/* extern "C" fn() -> u8 */
+.cfi_startproc
+ lghi %r2, STACK_DIRECTION_DESCENDING
+ br %r14
+.rust_psm_stack_direction_end:
+.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction
+.cfi_endproc
+
+
+.globl rust_psm_stack_pointer
+.p2align 4
+.type rust_psm_stack_pointer,@function
+rust_psm_stack_pointer:
+/* extern "C" fn() -> *mut u8 */
+.cfi_startproc
+ la %r2, 0(%r15)
+ br %r14
+.rust_psm_stack_pointer_end:
+.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer
+.cfi_endproc
+
+
+.globl rust_psm_replace_stack
+.p2align 4
+.type rust_psm_replace_stack,@function
+rust_psm_replace_stack:
+/* extern "C" fn(r2: usize, r3: extern "C" fn(usize), r4: *mut u8) */
+.cfi_startproc
+ /* FIXME: backtrace does not terminate cleanly for some reason */
+ lay %r15, -160(%r4)
+ /* FIXME: this is `basr` instead of `br` purely to remove the backtrace link to the caller */
+ basr %r14, %r3
+.rust_psm_replace_stack_end:
+.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack
+.cfi_endproc
+
+
+.globl rust_psm_on_stack
+.p2align 4
+.type rust_psm_on_stack,@function
+rust_psm_on_stack:
+/* extern "C" fn(r2: usize, r3: usize, r4: extern "C" fn(usize, usize), r5: *mut u8) */
+.cfi_startproc
+ stmg %r14, %r15, -16(%r5)
+ lay %r15, -176(%r5)
+ .cfi_def_cfa %r15, 176
+ .cfi_offset %r14, -16
+ .cfi_offset %r15, -8
+ basr %r14, %r4
+ lmg %r14, %r15, 160(%r15)
+ .cfi_restore %r14
+ .cfi_restore %r15
+ br %r14
+.rust_psm_on_stack_end:
+.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack
+.cfi_endproc