1*c2c66affSColin Finck/* 2*c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory 3*c2c66affSColin Finck * PROJECT: ReactOS system libraries 4*c2c66affSColin Finck * PURPOSE: Implementation of _setjmp/longjmp 5*c2c66affSColin Finck * FILE: lib/sdk/crt/setjmp/amd64/setjmp.s 6*c2c66affSColin Finck * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org) 7*c2c66affSColin Finck */ 8*c2c66affSColin Finck 9*c2c66affSColin Finck/* INCLUDES ******************************************************************/ 10*c2c66affSColin Finck 11*c2c66affSColin Finck#include <asm.inc> 12*c2c66affSColin Finck#include <ksamd64.inc> 13*c2c66affSColin Finck 14*c2c66affSColin Finck#define JUMP_BUFFER_Frame 0 /* 0x00 */ 15*c2c66affSColin Finck#define JUMP_BUFFER_Rbx 8 /* 0x08 */ 16*c2c66affSColin Finck#define JUMP_BUFFER_Rsp 16 /* 0x10 */ 17*c2c66affSColin Finck#define JUMP_BUFFER_Rbp 24 /* 0x18 */ 18*c2c66affSColin Finck#define JUMP_BUFFER_Rsi 32 /* 0x20 */ 19*c2c66affSColin Finck#define JUMP_BUFFER_Rdi 40 /* 0x28 */ 20*c2c66affSColin Finck#define JUMP_BUFFER_R12 48 /* 0x30 */ 21*c2c66affSColin Finck#define JUMP_BUFFER_R13 56 /* 0x38 */ 22*c2c66affSColin Finck#define JUMP_BUFFER_R14 64 /* 0x40 */ 23*c2c66affSColin Finck#define JUMP_BUFFER_R15 72 /* 0x48 */ 24*c2c66affSColin Finck#define JUMP_BUFFER_Rip 80 /* 0x50 */ 25*c2c66affSColin Finck#define JUMP_BUFFER_Spare 88 /* 0x58 */ 26*c2c66affSColin Finck#define JUMP_BUFFER_Xmm6 96 /* 0x60 */ 27*c2c66affSColin Finck#define JUMP_BUFFER_Xmm7 112 /* 0x70 */ 28*c2c66affSColin Finck#define JUMP_BUFFER_Xmm8 128 /* 0x80 */ 29*c2c66affSColin Finck#define JUMP_BUFFER_Xmm9 144 /* 0x90 */ 30*c2c66affSColin Finck#define JUMP_BUFFER_Xmm10 160 /* 0xa0 */ 31*c2c66affSColin Finck#define JUMP_BUFFER_Xmm11 176 /* 0xb0 */ 32*c2c66affSColin Finck#define JUMP_BUFFER_Xmm12 192 /* 0xc0 */ 33*c2c66affSColin Finck#define JUMP_BUFFER_Xmm13 208 /* 0xd0 */ 34*c2c66affSColin Finck#define JUMP_BUFFER_Xmm14 224 /* 0xe0 */ 35*c2c66affSColin Finck#define JUMP_BUFFER_Xmm15 240 /* 0xf0 */ 36*c2c66affSColin Finck 37*c2c66affSColin Finck 38*c2c66affSColin Finck/* FUNCTIONS ******************************************************************/ 39*c2c66affSColin Finck.code64 40*c2c66affSColin Finck 41*c2c66affSColin Finck/*! 42*c2c66affSColin Finck * int _setjmp(jmp_buf env); 43*c2c66affSColin Finck * 44*c2c66affSColin Finck * \param <rcx> - jmp_buf env 45*c2c66affSColin Finck * \return 0 46*c2c66affSColin Finck * \note Sets up the jmp_buf 47*c2c66affSColin Finck */ 48*c2c66affSColin FinckPUBLIC _setjmp 49*c2c66affSColin FinckFUNC _setjmp 50*c2c66affSColin Finck 51*c2c66affSColin Finck .endprolog 52*c2c66affSColin Finck 53*c2c66affSColin Finck /* Load rsp as it was before the call into rax */ 54*c2c66affSColin Finck lea rax, [rsp + 8] 55*c2c66affSColin Finck /* Load return address into r8 */ 56*c2c66affSColin Finck mov r8, [rsp] 57*c2c66affSColin Finck mov qword ptr [rcx + JUMP_BUFFER_Frame], 0 58*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_Rbx], rbx 59*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_Rbp], rbp 60*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_Rsi], rsi 61*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_Rdi], rdi 62*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_R12], r12 63*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_R13], r13 64*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_R14], r14 65*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_R15], r15 66*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_Rsp], rax 67*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_Rip], r8 68*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm6], xmm6 69*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm7], xmm7 70*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm8], xmm8 71*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm9], xmm9 72*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm10], xmm10 73*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm11], xmm11 74*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm12], xmm12 75*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm13], xmm13 76*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm14], xmm14 77*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm15], xmm15 78*c2c66affSColin Finck xor rax, rax 79*c2c66affSColin Finck ret 80*c2c66affSColin FinckENDFUNC 81*c2c66affSColin Finck 82*c2c66affSColin Finck/*! 83*c2c66affSColin Finck * int _setjmpex(jmp_buf _Buf,void *_Ctx); 84*c2c66affSColin Finck * 85*c2c66affSColin Finck * \param <rcx> - jmp_buf env 86*c2c66affSColin Finck * \param <rdx> - frame 87*c2c66affSColin Finck * \return 0 88*c2c66affSColin Finck * \note Sets up the jmp_buf 89*c2c66affSColin Finck */ 90*c2c66affSColin FinckPUBLIC _setjmpex 91*c2c66affSColin FinckFUNC _setjmpex 92*c2c66affSColin Finck 93*c2c66affSColin Finck .endprolog 94*c2c66affSColin Finck 95*c2c66affSColin Finck /* Load rsp as it was before the call into rax */ 96*c2c66affSColin Finck lea rax, [rsp + 8] 97*c2c66affSColin Finck /* Load return address into r8 */ 98*c2c66affSColin Finck mov r8, [rsp] 99*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_Frame], rdx 100*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_Rbx], rbx 101*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_Rbp], rbp 102*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_Rsi], rsi 103*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_Rdi], rdi 104*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_R12], r12 105*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_R13], r13 106*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_R14], r14 107*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_R15], r15 108*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_Rsp], rax 109*c2c66affSColin Finck mov [rcx + JUMP_BUFFER_Rip], r8 110*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm6], xmm6 111*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm7], xmm7 112*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm8], xmm8 113*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm9], xmm9 114*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm10], xmm10 115*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm11], xmm11 116*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm12], xmm12 117*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm13], xmm13 118*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm14], xmm14 119*c2c66affSColin Finck movdqa [rcx + JUMP_BUFFER_Xmm15], xmm15 120*c2c66affSColin Finck xor rax, rax 121*c2c66affSColin Finck ret 122*c2c66affSColin FinckENDFUNC 123*c2c66affSColin Finck 124*c2c66affSColin Finck 125*c2c66affSColin Finck/*! 126*c2c66affSColin Finck * void longjmp(jmp_buf env, int value); 127*c2c66affSColin Finck * 128*c2c66affSColin Finck * \param <rcx> - jmp_buf setup by _setjmp 129*c2c66affSColin Finck * \param <rdx> - int value to return 130*c2c66affSColin Finck * \return Doesn't return 131*c2c66affSColin Finck * \note Non-local goto 132*c2c66affSColin Finck */ 133*c2c66affSColin FinckPUBLIC longjmp 134*c2c66affSColin FinckFUNC longjmp 135*c2c66affSColin Finck 136*c2c66affSColin Finck .endprolog 137*c2c66affSColin Finck 138*c2c66affSColin Finck // FIXME: handle frame 139*c2c66affSColin Finck 140*c2c66affSColin Finck mov rbx, [rcx + JUMP_BUFFER_Rbx] 141*c2c66affSColin Finck mov rbp, [rcx + JUMP_BUFFER_Rbp] 142*c2c66affSColin Finck mov rsi, [rcx + JUMP_BUFFER_Rsi] 143*c2c66affSColin Finck mov rdi, [rcx + JUMP_BUFFER_Rdi] 144*c2c66affSColin Finck mov r12, [rcx + JUMP_BUFFER_R12] 145*c2c66affSColin Finck mov r13, [rcx + JUMP_BUFFER_R13] 146*c2c66affSColin Finck mov r14, [rcx + JUMP_BUFFER_R14] 147*c2c66affSColin Finck mov r15, [rcx + JUMP_BUFFER_R15] 148*c2c66affSColin Finck mov rsp, [rcx + JUMP_BUFFER_Rsp] 149*c2c66affSColin Finck mov r8, [rcx + JUMP_BUFFER_Rip] 150*c2c66affSColin Finck movdqa xmm6, [rcx + JUMP_BUFFER_Xmm6] 151*c2c66affSColin Finck movdqa xmm7, [rcx + JUMP_BUFFER_Xmm7] 152*c2c66affSColin Finck movdqa xmm8, [rcx + JUMP_BUFFER_Xmm8] 153*c2c66affSColin Finck movdqa xmm9, [rcx + JUMP_BUFFER_Xmm9] 154*c2c66affSColin Finck movdqa xmm10, [rcx + JUMP_BUFFER_Xmm10] 155*c2c66affSColin Finck movdqa xmm11, [rcx + JUMP_BUFFER_Xmm11] 156*c2c66affSColin Finck movdqa xmm12, [rcx + JUMP_BUFFER_Xmm12] 157*c2c66affSColin Finck movdqa xmm13, [rcx + JUMP_BUFFER_Xmm13] 158*c2c66affSColin Finck movdqa xmm14, [rcx + JUMP_BUFFER_Xmm14] 159*c2c66affSColin Finck movdqa xmm15, [rcx + JUMP_BUFFER_Xmm15] 160*c2c66affSColin Finck 161*c2c66affSColin Finck /* return param2 or 1 if it was 0 */ 162*c2c66affSColin Finck mov rax, rdx 163*c2c66affSColin Finck test rax, rax 164*c2c66affSColin Finck jnz l2 165*c2c66affSColin Finck inc rax 166*c2c66affSColin Finckl2: jmp r8 167*c2c66affSColin FinckENDFUNC 168*c2c66affSColin Finck 169*c2c66affSColin FinckEND 170