;
;
; Nim's Runtime Library
; (c) Copyright 2015 Rokas Kupstys
;
; See the file "copying.txt", included in this
; distribution, for details about the copyright.
;
format MS64 COFF
section ".text" executable align 16
public narch_getRegisters
public narch_setjmp
public narch_longjmp
public narch_coroSwitchStack
public narch_coroRestoreStack
narch_getRegisters:
mov [rcx], rax
mov [rcx+8], rbx
mov [rcx+10h], rcx
mov [rcx+18h], rdx
mov [rcx+20h], rsi
mov [rcx+28h], rdi
mov [rcx+30h], rbp
mov [rcx+38h], rsp
mov rax, [rsp]
mov [rcx+40h], rax ; rip
mov [rcx+48h], r8
mov [rcx+50h], r9
mov [rcx+58h], r10
mov [rcx+60h], r11
mov [rcx+68h], r12
mov [rcx+70h], r13
mov [rcx+78h], r14
mov [rcx+80h], r15
ret
narch_setjmp:
; Based on code from musl libc Copyright © 2005-2014 Rich Felker, et al.
mov [rcx], rbx ; rcx is jmp_buf, move registers onto it
mov [rcx+8], rbp
mov [rcx+10h], r12
mov [rcx+18h], r13
mov [rcx+20h], r14
mov [rcx+28h], r15
lea rdx, [rsp+8] ; this is our rsp WITHOUT current ret addr
mov [rcx+30h], rdx
mov rdx, [rsp] ; save return addr ptr for new rip
mov [rcx+38h], rdx
mov [rcx+40h], rsi
mov [rcx+48h], rdi
xor rax, rax ; always return 0
ret
narch_longjmp:
; Based on code from musl libc Copyright © 2005-2014 Rich Felker, et al.
mov rax, rdx ; val will be longjmp return
test rax, rax
jnz @F
inc rax ; if val==0, val=1 per longjmp semantics
@@:
mov rbx, [rcx] ; rax is the jmp_buf, restore regs from it
mov rbp, [rcx+8]
mov r12, [rcx+10h]
mov r13, [rcx+18h]
mov r14, [rcx+20h]
mov r15, [rcx+28h]
mov rsp, [rcx+30h] ; this ends up being the stack pointer
mov rdx, [rcx+38h] ; this is the instruction pointer
jmp rdx ; goto saved address without altering rsp
narch_coroSwitchStack:
pop rax ; return address
mov rdx, rsp ; old rsp for saving
mov rsp, rcx ; swap stack with one passed to func
push rdx ; store old stack pointer on newly switched stack
sub rsp, 28h ; stack alignment + shadow space
jmp rax ; return
narch_coroRestoreStack:
pop rax ; return address
add rsp, 28h ; stack alignment + shadow space
pop rsp ; resture old stack pointer
jmp rax ; return