summary refs log tree commit diff stats
path: root/lib/arch
diff options
context:
space:
mode:
authorrku <rokups@zoho.com>2015-07-31 17:18:16 +0300
committerrku <rokups@zoho.com>2015-07-31 17:59:50 +0300
commit43bfda057b56d6c67222d4c86e3be90dd3f01e59 (patch)
tree45fd5d1b1934b698618d221334b172bfd23b1567 /lib/arch
parentdf0e1a515b40d09527f0ad7f5aafa226d3ff37a5 (diff)
downloadNim-43bfda057b56d6c67222d4c86e3be90dd3f01e59.tar.gz
Coroutine support for i386/amd64 platforms unix/windows OSes markAndSweep/refCounting GCs.
Diffstat (limited to 'lib/arch')
-rw-r--r--lib/arch/arch.nim59
-rw-r--r--lib/arch/i386.asm79
-rw-r--r--lib/arch/ms_amd64.asm90
-rw-r--r--lib/arch/ms_i386.asm12
-rw-r--r--lib/arch/unix_amd64.asm89
-rw-r--r--lib/arch/unix_i386.asm12
6 files changed, 341 insertions, 0 deletions
diff --git a/lib/arch/arch.nim b/lib/arch/arch.nim
new file mode 100644
index 000000000..a11bfb21f
--- /dev/null
+++ b/lib/arch/arch.nim
@@ -0,0 +1,59 @@
+#
+#
+#            Nim's Runtime Library
+#        (c) Copyright 2015 Rokas Kupstys
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+when defined(windows):
+  const
+    ABI* = "ms"
+elif defined(unix):
+  const
+    ABI* = "unix"
+else:
+  {.error: "Unsupported ABI".}
+
+when defined(amd64):
+  when defined(unix):
+    # unix (sysv) ABI
+    type
+      JmpBufReg* {.pure.} = enum
+        BX, BP, R12, R13, R14, R15, SP, IP, TOTAL
+  elif defined(windows):
+    # ms ABI
+    type
+      JmpBufReg* {.pure.} = enum
+        BX, BP, R12, R13, R14, R15, SP, IP, SI, DI, TOTAL
+  type
+    Reg* {.pure.} = enum
+      AX, BX, CX, DX, SI, DI, BP, SP, IP, R8, R9, R10, R11, R12, R13, R14, R15, TOTAL
+
+elif defined(i386):
+    # identical fastcall calling convention on all x86 OS
+    type
+      JmpBufReg* {.pure.} = enum
+        BX, SI, DI, BP, SP, IP, TOTAL
+
+      Reg* {.pure.} = enum
+        AX, BX, CX, BP, SP, DI, SI, TOTAL
+
+else:
+  {.error: "Unsupported architecture".}
+
+{.compile: "./" & ABI & "_" & hostCPU & ".asm"}
+
+type
+  JmpBuf* = array[JmpBufReg.TOTAL, pointer]
+  Registers* = array[Reg.TOTAL, pointer]
+
+
+proc getRegisters*(ctx: var Registers) {.importc: "narch_$1", fastcall.}
+
+proc setjmp*(ctx: var JmpBuf): int {.importc: "narch_$1", fastcall.}
+proc longjmp*(ctx: JmpBuf, ret=1) {.importc: "narch_$1", fastcall.}
+
+proc coroSwitchStack*(sp: pointer) {.importc: "narch_$1", fastcall.}
+proc coroRestoreStack*() {.importc: "narch_$1", fastcall.}
diff --git a/lib/arch/i386.asm b/lib/arch/i386.asm
new file mode 100644
index 000000000..61f6fdda7
--- /dev/null
+++ b/lib/arch/i386.asm
@@ -0,0 +1,79 @@
+;
+;
+;            Nim's Runtime Library
+;        (c) Copyright 2015 Rokas Kupstys
+;
+;    See the file "copying.txt", included in this
+;    distribution, for details about the copyright.
+;
+
+section ".text" executable
+public narch_getRegisters
+public @narch_getRegisters@4
+public narch_setjmp
+public @narch_setjmp@4
+public narch_longjmp
+public @narch_longjmp@8
+public narch_coroSwitchStack
+public @narch_coroSwitchStack@4
+public narch_coroRestoreStack
+public @narch_coroRestoreStack@0
+
+@narch_getRegisters@4:
+narch_getRegisters:
+    mov   [ecx], eax
+    mov   [ecx+4], ebx
+    mov   [ecx+8], ecx
+    mov   [ecx+0Ch], ebp
+    mov   [ecx+10h], esp
+    mov   [ecx+14h], edi
+    mov   [ecx+18h], esi
+    ret
+
+
+@narch_setjmp@4:
+narch_setjmp:
+    ; Based on code from musl libc Copyright © 2005-2014 Rich Felker, et al.
+    mov  [ecx], ebx
+    mov  [ecx+4], esi
+    mov  [ecx+8], edi
+    mov  [ecx+0Ch], ebp
+    lea  eax, [esp+4]
+    mov  [ecx+10h], eax
+    mov  eax, [esp]
+    mov  [ecx+14h], eax
+    xor  eax, eax
+    ret
+
+
+@narch_longjmp@8:
+narch_longjmp:
+    ; Based on code from musl libc Copyright © 2005-2014 Rich Felker, et al.
+    mov  eax, edx
+    test eax, eax
+    jnz  @F
+    inc  eax
+@@:
+    mov  ebx, [ecx]
+    mov  esi, [ecx+4]
+    mov  edi, [ecx+8]
+    mov  ebp, [ecx+0Ch]
+    mov  esp, [ecx+10h]
+    mov  edx, [ecx+14h]
+    jmp  edx
+
+
+@narch_coroSwitchStack@4:
+narch_coroSwitchStack:
+    pop eax                   ; return address
+    mov edx, esp              ; old esp for saving
+    mov esp, ecx              ; swap stack with one passed to func
+    push edx                  ; store old stack pointer on newly switched stack
+    jmp eax                   ; return
+
+
+@narch_coroRestoreStack@0:
+narch_coroRestoreStack:
+    pop eax                   ; return address
+    pop esp                   ; resture old stack pointer
+    jmp eax                   ; return
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
diff --git a/lib/arch/ms_i386.asm b/lib/arch/ms_i386.asm
new file mode 100644
index 000000000..a31a698d1
--- /dev/null
+++ b/lib/arch/ms_i386.asm
@@ -0,0 +1,12 @@
+;
+;
+;            Nim's Runtime Library
+;        (c) Copyright 2015 Rokas Kupstys
+;
+;    See the file "copying.txt", included in this
+;    distribution, for details about the copyright.
+;
+
+format MS COFF
+
+include 'i386.asm'
diff --git a/lib/arch/unix_amd64.asm b/lib/arch/unix_amd64.asm
new file mode 100644
index 000000000..3005c150c
--- /dev/null
+++ b/lib/arch/unix_amd64.asm
@@ -0,0 +1,89 @@
+;
+;
+;            Nim's Runtime Library
+;        (c) Copyright 2015 Rokas Kupstys
+;
+;    See the file "copying.txt", included in this
+;    distribution, for details about the copyright.
+;
+
+format ELF64
+
+section ".text" executable align 16
+public narch_getRegisters
+public narch_setjmp
+public narch_longjmp
+public narch_coroSwitchStack
+public narch_coroRestoreStack
+
+
+narch_getRegisters:
+    mov   [rdi], rax
+    mov   [rdi+8], rbx
+    mov   [rdi+10h], rcx
+    mov   [rdi+18h], rdx
+    mov   [rdi+20h], rsi
+    mov   [rdi+28h], rdi
+    mov   [rdi+30h], rbp
+    mov   [rdi+38h], rsp
+    mov   rax, [rsp]
+    mov   [rdi+40h], rax      ; rip
+    mov   [rdi+48h], r8
+    mov   [rdi+50h], r9
+    mov   [rdi+58h], r10
+    mov   [rdi+60h], r11
+    mov   [rdi+68h], r12
+    mov   [rdi+70h], r13
+    mov   [rdi+78h], r14
+    mov   [rdi+80h], r15
+    ret
+
+
+narch_setjmp:
+    ; Based on code from musl libc Copyright © 2005-2014 Rich Felker, et al.
+    mov   [rdi], rbx          ; rdi is jmp_buf, move registers onto it
+    mov   [rdi+8], rbp
+    mov   [rdi+10h], r12
+    mov   [rdi+18h], r13
+    mov   [rdi+20h], r14
+    mov   [rdi+28h], r15
+    lea   rdx, [rsp+8]        ; this is our rsp WITHOUT current ret addr
+    mov   [rdi+30h], rdx
+    mov   rdx, [rsp]          ; save return addr ptr for new rip
+    mov   [rdi+38h], rdx
+    xor   rax, rax            ; always return 0
+    ret
+
+
+narch_longjmp:
+    ; Based on code from musl libc Copyright © 2005-2014 Rich Felker, et al.
+    mov   rax, rsi            ; val will be longjmp return
+    test  rax, rax
+    jnz   @F
+    inc   rax                 ; if val==0, val=1 per longjmp semantics
+@@:
+    mov   rbx, [rdi]          ; rdi is the jmp_buf, restore regs from it
+    mov   rbp, [rdi+8]
+    mov   r12, [rdi+10h]
+    mov   r13, [rdi+18h]
+    mov   r14, [rdi+20h]
+    mov   r15, [rdi+28h]
+    mov   rsp, [rdi+30h]      ; this ends up being the stack pointer
+    mov   rdx, [rdi+38h]      ; this is the instruction pointer
+    jmp   rdx                 ; goto saved address without altering rsp
+
+
+narch_coroSwitchStack:
+    pop rsi                   ; return address
+    mov rdx, rsp              ; old rsp for saving
+    mov rsp, rdi              ; swap stack with one passed to func
+    push rdx                  ; store old stack pointer on newly switched stack
+    sub rsp, 8h               ; stack alignment
+    jmp rsi                   ; return
+
+
+narch_coroRestoreStack:
+	pop rsi                   ; return address
+	add rsp, 8h               ; stack alignment
+	pop rsp                   ; resture old stack pointer
+	jmp rsi                   ; return
diff --git a/lib/arch/unix_i386.asm b/lib/arch/unix_i386.asm
new file mode 100644
index 000000000..278679067
--- /dev/null
+++ b/lib/arch/unix_i386.asm
@@ -0,0 +1,12 @@
+;
+;
+;            Nim's Runtime Library
+;        (c) Copyright 2015 Rokas Kupstys
+;
+;    See the file "copying.txt", included in this
+;    distribution, for details about the copyright.
+;
+
+format ELF
+
+include 'i386.asm'