# # # Nim's Runtime Library # (c) Copyright 2015 Rokas Kupstys # # See the file "copying.txt", included in this # distribution, for details about the copyright. # # Partially based on code from musl libc Copyright © 2005-2014 Rich Felker, et al. .globl narch_coroExecWithStack .globl narch_setjmp .globl narch_longjmp .text # SysV ABI - first argument is rdi. # MS ABI - first argument is rcx. #if defined(__MINGW32__) || defined(__MINGW64__) #define REG_ARG1 rcx #define REG_ARG2 rdx #else #define REG_ARG1 rdi #define REG_ARG2 rsi #endif narch_coroExecWithStack: mov %REG_ARG2, %rsp # swap stack with one passed to func sub $0x30, %rsp # shadow space (for ms ABI) 0x20 + 0x10 for possible misalignment and $-0x10, %rsp # 16-byte stack alignment call *%REG_ARG1 narch_setjmp: add $0x10, %REG_ARG1 # 16-byte alignment and $-0x10, %REG_ARG1 mov %rbx, 0x00(%REG_ARG1) # jmp_buf, move registers onto it mov %rbp, 0x08(%REG_ARG1) mov %r12, 0x10(%REG_ARG1) mov %r13, 0x18(%REG_ARG1) mov %r14, 0x20(%REG_ARG1) mov %r15, 0x28(%REG_ARG1) lea 0x08(%rsp), %rdx # this is our rsp WITHOUT current ret addr mov %rdx, 0x30(%REG_ARG1) mov (%rsp), %rdx # save return addr ptr for new rip mov %rdx, 0x38(%REG_ARG1) mov %rsi, 0x40(%REG_ARG1) mov %rdi, 0x48(%REG_ARG1) #if defined(__MINGW32__) || defined(__MINGW64__) movaps %xmm6, 0x50(%REG_ARG1) movaps %xmm7, 0x60(%REG_ARG1) movaps %xmm8, 0x70(%REG_ARG1) movaps %xmm9, 0x80(%REG_ARG1) movaps %xmm10, 0x90(%REG_ARG1) movaps %xmm11, 0xA0(%REG_ARG1) movaps %xmm12, 0xB0(%REG_ARG1) movaps %xmm13, 0xC0(%REG_ARG1) movaps %xmm14, 0xD0(%REG_ARG1) movaps %xmm15, 0xE0(%REG_ARG1) #endif xor %rax, %rax # always return 0 ret narch_longjmp: add $0x10, %REG_ARG1 # 16-byte alignment and $-0x10, %REG_ARG1 # mov %REG_ARG2, %rax # val will be longjmp return test %rax, %rax jnz narch_longjmp_1 inc %rax # if val==0, val=1 per longjmp semantics narch_longjmp_1: mov 0x00(%REG_ARG1), %rbx # jmp_buf, restore regs from it mov 0x08(%REG_ARG1), %rbp mov 0x10(%REG_ARG1), %r12 mov 0x18(%REG_ARG1), %r13 mov 0x20(%REG_ARG1), %r14 mov 0x28(%REG_ARG1), %r15 mov 0x30(%REG_ARG1), %rsp # this ends up being the stack pointer mov 0x38(%REG_ARG1), %rdx # this is the instruction pointer mov 0x40(%REG_ARG1), %rsi mov 0x48(%REG_ARG1), %rdi #if defined(__MINGW32__) || defined(__MINGW64__) movaps 0x50(%REG_ARG1), %xmm6 movaps 0x60(%REG_ARG1), %xmm7 movaps 0x70(%REG_ARG1), %xmm8 movaps 0x80(%REG_ARG1), %xmm9 movaps 0x90(%REG_ARG1), %xmm10 movaps 0xA0(%REG_ARG1), %xmm11 movaps 0xB0(%REG_ARG1), %xmm12 movaps 0xC0(%REG_ARG1), %xmm13 movaps 0xD0(%REG_ARG1), %xmm14 movaps 0xE0(%REG_ARG1), %xmm15 #endif jmp *%rdx # goto saved address without altering rsp