xref: /reactos/sdk/lib/crt/setjmp/amd64/setjmp.s (revision c2c66aff)
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