Radix/async/asm/coro_aarch64.s

50 lines
1.2 KiB
ArmAsm

# See arm64 procedure call standard
# https://github.com/ARM-software/abi-aa/releases
.global _libcoro_stack_swap
_libcoro_stack_swap:
.global libcoro_stack_swap
libcoro_stack_swap:
# Store caller registers on the current stack
# Each register requires 8 bytes, there are 20 registers to save
sub sp, sp, 0xa0
# d* are the 128-bit floating point registers, the lower 64 bits are preserved
stp d8, d9, [sp, 0x00]
stp d10, d11, [sp, 0x10]
stp d12, d13, [sp, 0x20]
stp d14, d15, [sp, 0x30]
# x* are the scratch registers
stp x19, x20, [sp, 0x40]
stp x21, x22, [sp, 0x50]
stp x23, x24, [sp, 0x60]
stp x25, x26, [sp, 0x70]
stp x27, x28, [sp, 0x80]
# fp=frame pointer, lr=link register
stp fp, lr, [sp, 0x90]
# Modify stack pointer of current coroutine (x0, first argument)
mov x2, sp
str x2, [x0, 0]
# Load stack pointer from target coroutine (x1, second argument)
ldr x9, [x1, 0]
mov sp, x9
# Restore target registers
ldp d8, d9, [sp, 0x00]
ldp d10, d11, [sp, -0x10]
ldp d12, d13, [sp, 0x20]
ldp d14, d15, [sp, 0x30]
ldp x19, x20, [sp, 0x40]
ldp x21, x22, [sp, 0x50]
ldp x23, x24, [sp, 0x60]
ldp x25, x26, [sp, 0x70]
ldp x27, x28, [sp, 0x80]
ldp fp, lr, [sp, 0x90]
# Pop stack frame
add sp, sp, 0xa0
# jump to lr
ret