diff options
author | rku <rokups@zoho.com> | 2015-07-31 17:18:16 +0300 |
---|---|---|
committer | rku <rokups@zoho.com> | 2015-07-31 17:59:50 +0300 |
commit | 43bfda057b56d6c67222d4c86e3be90dd3f01e59 (patch) | |
tree | 45fd5d1b1934b698618d221334b172bfd23b1567 /lib/arch | |
parent | df0e1a515b40d09527f0ad7f5aafa226d3ff37a5 (diff) | |
download | Nim-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.nim | 59 | ||||
-rw-r--r-- | lib/arch/i386.asm | 79 | ||||
-rw-r--r-- | lib/arch/ms_amd64.asm | 90 | ||||
-rw-r--r-- | lib/arch/ms_i386.asm | 12 | ||||
-rw-r--r-- | lib/arch/unix_amd64.asm | 89 | ||||
-rw-r--r-- | lib/arch/unix_i386.asm | 12 |
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' |