1# 2# 3# Nim's Runtime Library 4# (c) Copyright 2015 Rokas Kupstys 5# 6# See the file "copying.txt", included in this 7# distribution, for details about the copyright. 8# 9# Partially based on code from musl libc Copyright © 2005-2014 Rich Felker, et al. 10 11.globl narch_coroExecWithStack 12.globl narch_setjmp 13.globl narch_longjmp 14.text 15 16 17# SysV ABI - first argument is rdi. 18# MS ABI - first argument is rcx. 19#if defined(__MINGW32__) || defined(__MINGW64__) 20 #define REG_ARG1 rcx 21 #define REG_ARG2 rdx 22#else 23 #define REG_ARG1 rdi 24 #define REG_ARG2 rsi 25#endif 26 27 28narch_coroExecWithStack: 29 mov %REG_ARG2, %rsp # swap stack with one passed to func 30 sub $0x30, %rsp # shadow space (for ms ABI) 0x20 + 0x10 for possible misalignment 31 and $-0x10, %rsp # 16-byte stack alignment 32 call *%REG_ARG1 33 34 35narch_setjmp: 36 add $0x10, %REG_ARG1 # 16-byte alignment 37 and $-0x10, %REG_ARG1 38 mov %rbx, 0x00(%REG_ARG1) # jmp_buf, move registers onto it 39 mov %rbp, 0x08(%REG_ARG1) 40 mov %r12, 0x10(%REG_ARG1) 41 mov %r13, 0x18(%REG_ARG1) 42 mov %r14, 0x20(%REG_ARG1) 43 mov %r15, 0x28(%REG_ARG1) 44 lea 0x08(%rsp), %rdx # this is our rsp WITHOUT current ret addr 45 mov %rdx, 0x30(%REG_ARG1) 46 mov (%rsp), %rdx # save return addr ptr for new rip 47 mov %rdx, 0x38(%REG_ARG1) 48 mov %rsi, 0x40(%REG_ARG1) 49 mov %rdi, 0x48(%REG_ARG1) 50#if defined(__MINGW32__) || defined(__MINGW64__) 51 movaps %xmm6, 0x50(%REG_ARG1) 52 movaps %xmm7, 0x60(%REG_ARG1) 53 movaps %xmm8, 0x70(%REG_ARG1) 54 movaps %xmm9, 0x80(%REG_ARG1) 55 movaps %xmm10, 0x90(%REG_ARG1) 56 movaps %xmm11, 0xA0(%REG_ARG1) 57 movaps %xmm12, 0xB0(%REG_ARG1) 58 movaps %xmm13, 0xC0(%REG_ARG1) 59 movaps %xmm14, 0xD0(%REG_ARG1) 60 movaps %xmm15, 0xE0(%REG_ARG1) 61#endif 62 xor %rax, %rax # always return 0 63 ret 64 65 66narch_longjmp: 67 add $0x10, %REG_ARG1 # 16-byte alignment 68 and $-0x10, %REG_ARG1 # 69 mov %REG_ARG2, %rax # val will be longjmp return 70 test %rax, %rax 71 jnz narch_longjmp_1 72 inc %rax # if val==0, val=1 per longjmp semantics 73narch_longjmp_1: 74 mov 0x00(%REG_ARG1), %rbx # jmp_buf, restore regs from it 75 mov 0x08(%REG_ARG1), %rbp 76 mov 0x10(%REG_ARG1), %r12 77 mov 0x18(%REG_ARG1), %r13 78 mov 0x20(%REG_ARG1), %r14 79 mov 0x28(%REG_ARG1), %r15 80 mov 0x30(%REG_ARG1), %rsp # this ends up being the stack pointer 81 mov 0x38(%REG_ARG1), %rdx # this is the instruction pointer 82 mov 0x40(%REG_ARG1), %rsi 83 mov 0x48(%REG_ARG1), %rdi 84#if defined(__MINGW32__) || defined(__MINGW64__) 85 movaps 0x50(%REG_ARG1), %xmm6 86 movaps 0x60(%REG_ARG1), %xmm7 87 movaps 0x70(%REG_ARG1), %xmm8 88 movaps 0x80(%REG_ARG1), %xmm9 89 movaps 0x90(%REG_ARG1), %xmm10 90 movaps 0xA0(%REG_ARG1), %xmm11 91 movaps 0xB0(%REG_ARG1), %xmm12 92 movaps 0xC0(%REG_ARG1), %xmm13 93 movaps 0xD0(%REG_ARG1), %xmm14 94 movaps 0xE0(%REG_ARG1), %xmm15 95#endif 96 jmp *%rdx # goto saved address without altering rsp 97