summary refs log tree commit diff stats
path: root/lib/arch/ms_amd64.asm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/arch/ms_amd64.asm')
-rw-r--r--lib/arch/ms_amd64.asm90
1 files changed, 90 insertions, 0 deletions
diff --git a/lib/arch/ms_amd64.asm b/lib/arch/ms_amd64.asm
new file mode 100644
index 000000000..0503b31c9
--- /dev/null
+++ b/lib/arch/ms_amd64.asm
@@ -0,0 +1,90 @@
+;
+;
+;            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