blob: c151343cdc388f22c6d6a89acd9be6243223e048 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15/*
16 Copyright (c) 2005 Eliot Dresselhaus
17
18 Permission is hereby granted, free of charge, to any person obtaining
19 a copy of this software and associated documentation files (the
20 "Software"), to deal in the Software without restriction, including
21 without limitation the rights to use, copy, modify, merge, publish,
22 distribute, sublicense, and/or sell copies of the Software, and to
23 permit persons to whom the Software is furnished to do so, subject to
24 the following conditions:
25
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
28
29 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36*/
Damjan Marion4dffd1c2018-09-03 12:30:36 +020037
38#if defined(__APPLE__)
39# define cdecl(s) _##s
40#else
41# define cdecl(s) s
42#endif
43
Ed Warnickecb9cada2015-12-08 15:45:58 -070044#if defined(__x86_64__)
Damjan Marion4dffd1c2018-09-03 12:30:36 +020045 .global cdecl(clib_setjmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -070046 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +020047#ifndef __APPLE__
48 .type cdecl(clib_setjmp), @function
49#endif
50
51cdecl(clib_setjmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -070052 movq %rbx, 8*0(%rdi)
53 movq %rbp, 8*1(%rdi)
54 movq %r12, 8*2(%rdi)
55 movq %r13, 8*3(%rdi)
56 movq %r14, 8*4(%rdi)
57 movq %r15, 8*5(%rdi)
58
59 /* Save SP after return. */
60 leaq 8(%rsp), %rdx
61 movq %rdx, 8*6(%rdi)
Damjan Mariond466c0c2020-05-16 00:40:48 +020062
Ed Warnickecb9cada2015-12-08 15:45:58 -070063 /* Save PC we are returning to from stack frame. */
64 movq 0(%rsp), %rax
65 movq %rax, 8*7(%rdi)
Damjan Mariond466c0c2020-05-16 00:40:48 +020066
Ed Warnickecb9cada2015-12-08 15:45:58 -070067 /* Give back user's return value. */
68 movq %rsi, %rax
69 ret
Damjan Mariond466c0c2020-05-16 00:40:48 +020070
Damjan Marion4dffd1c2018-09-03 12:30:36 +020071 .global cdecl(clib_longjmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -070072 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +020073#ifndef __APPLE__
74 .type cdecl(clib_longjmp), @function
75#endif
Damjan Mariond466c0c2020-05-16 00:40:48 +020076cdecl(clib_longjmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -070077 /* Restore regs. */
78 movq 8*0(%rdi), %rbx
79 movq 8*1(%rdi), %rbp
80 movq 8*2(%rdi), %r12
81 movq 8*3(%rdi), %r13
82 movq 8*4(%rdi), %r14
83 movq 8*5(%rdi), %r15
84 movq 8*6(%rdi), %rsp
85 movq 8*7(%rdi), %rdx
Damjan Mariond466c0c2020-05-16 00:40:48 +020086
Ed Warnickecb9cada2015-12-08 15:45:58 -070087 /* Give back user's return value. */
88 movq %rsi, %rax
Damjan Mariond466c0c2020-05-16 00:40:48 +020089
Ed Warnickecb9cada2015-12-08 15:45:58 -070090 /* Away we go. */
Damjan Mariond466c0c2020-05-16 00:40:48 +020091 jmpq *%rdx
92
Damjan Marion4dffd1c2018-09-03 12:30:36 +020093 .global cdecl(clib_calljmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -070094 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +020095#ifndef __APPLE__
96 .type cdecl(clib_calljmp), @function
97#endif
98cdecl(clib_calljmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -070099 /* Make sure stack is 16-byte aligned. */
100 movq %rdx, %rax
101 andq $0xf, %rax
102 subq %rax, %rdx
Damjan Mariond466c0c2020-05-16 00:40:48 +0200103
Ed Warnickecb9cada2015-12-08 15:45:58 -0700104 /* Get return address. */
105 pop %rax
Damjan Mariond466c0c2020-05-16 00:40:48 +0200106
Ed Warnickecb9cada2015-12-08 15:45:58 -0700107 /* Switch to new stack. */
108 xchgq %rsp, %rdx
Damjan Mariond466c0c2020-05-16 00:40:48 +0200109
Ed Warnickecb9cada2015-12-08 15:45:58 -0700110 /* Save return address on new stack. */
111 push %rax
Damjan Mariond466c0c2020-05-16 00:40:48 +0200112
Ed Warnickecb9cada2015-12-08 15:45:58 -0700113 /* Save old stack pointer on new stack. */
114 push %rdx
Damjan Mariond466c0c2020-05-16 00:40:48 +0200115
Ed Warnickecb9cada2015-12-08 15:45:58 -0700116 /* Get function. */
117 movq %rdi, %rdx
Damjan Mariond466c0c2020-05-16 00:40:48 +0200118
Ed Warnickecb9cada2015-12-08 15:45:58 -0700119 /* Move argument into place. */
120 movq %rsi, %rdi
Damjan Mariond466c0c2020-05-16 00:40:48 +0200121
Ed Warnickecb9cada2015-12-08 15:45:58 -0700122 /* Away we go. */
123 callq *%rdx
Damjan Mariond466c0c2020-05-16 00:40:48 +0200124
Ed Warnickecb9cada2015-12-08 15:45:58 -0700125 /* Switch back to old stack. */
126 movq 8(%rsp), %rdx
127 movq 0(%rsp), %rcx
128 xchgq %rcx, %rsp
Damjan Mariond466c0c2020-05-16 00:40:48 +0200129
Ed Warnickecb9cada2015-12-08 15:45:58 -0700130 /* Return to caller. */
131 jmpq *%rdx
132
133#elif defined(i386)
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200134 .global cdecl(clib_setjmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700135 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200136 .type cdecl(clib_setjmp), @function
137cdecl(clib_setjmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -0700138 movl 4(%esp), %ecx
Damjan Mariond466c0c2020-05-16 00:40:48 +0200139
Ed Warnickecb9cada2015-12-08 15:45:58 -0700140 movl %ebp, 4*0(%ecx)
141 movl %ebx, 4*1(%ecx)
142 movl %edi, 4*2(%ecx)
143 movl %esi, 4*3(%ecx)
144
145 /* Save SP after return. */
146 leal 4(%esp), %edx
147 movl %edx, 4*4(%ecx)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200148
Ed Warnickecb9cada2015-12-08 15:45:58 -0700149 /* Save PC we are returning to from stack frame. */
150 movl 0(%esp), %eax
151 movl %eax, 4*5(%ecx)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200152
Ed Warnickecb9cada2015-12-08 15:45:58 -0700153 /* Give back user's return value. */
154 movl 8(%esp), %eax
155 ret
Damjan Mariond466c0c2020-05-16 00:40:48 +0200156
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200157 .global cdecl(clib_longjmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700158 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200159 .type cdecl(clib_longjmp), @function
Damjan Mariond466c0c2020-05-16 00:40:48 +0200160cdecl(clib_longjmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -0700161 movl 4(%esp), %ecx
Damjan Mariond466c0c2020-05-16 00:40:48 +0200162
Ed Warnickecb9cada2015-12-08 15:45:58 -0700163 /* Give back user's return value. */
164 movl 8(%esp), %eax
Damjan Mariond466c0c2020-05-16 00:40:48 +0200165
Ed Warnickecb9cada2015-12-08 15:45:58 -0700166 /* Restore regs. */
167 movl 4*0(%ecx), %ebp
168 movl 4*1(%ecx), %ebx
169 movl 4*2(%ecx), %edi
170 movl 4*3(%ecx), %esi
171 movl 4*4(%ecx), %esp
172 movl 4*5(%ecx), %edx
Damjan Mariond466c0c2020-05-16 00:40:48 +0200173
Ed Warnickecb9cada2015-12-08 15:45:58 -0700174 /* Away we go. */
Damjan Mariond466c0c2020-05-16 00:40:48 +0200175 jmp *%edx
176
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200177 .global cdecl(clib_calljmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700178 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200179 .type cdecl(clib_calljmp), @function
Damjan Mariond466c0c2020-05-16 00:40:48 +0200180cdecl(clib_calljmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -0700181 /* Get new stack pointer. */
182 movl 12(%esp), %edx
Damjan Mariond466c0c2020-05-16 00:40:48 +0200183
Ed Warnickecb9cada2015-12-08 15:45:58 -0700184 /* Switch stacks. */
185 xchgl %esp, %edx
Damjan Mariond466c0c2020-05-16 00:40:48 +0200186
Ed Warnickecb9cada2015-12-08 15:45:58 -0700187 /* Save old stack pointer on new stack. */
188 sub $8, %esp
189 movl %edx, 4(%esp)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200190
Ed Warnickecb9cada2015-12-08 15:45:58 -0700191 /* Put function argument in stack frame. */
192 movl 8(%edx), %eax
193 movl %eax, 0(%esp)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200194
Ed Warnickecb9cada2015-12-08 15:45:58 -0700195 /* Get function. */
196 movl 4(%edx), %eax
Damjan Mariond466c0c2020-05-16 00:40:48 +0200197
Ed Warnickecb9cada2015-12-08 15:45:58 -0700198 /* Away we go. */
199 call *%eax
Damjan Mariond466c0c2020-05-16 00:40:48 +0200200
Ed Warnickecb9cada2015-12-08 15:45:58 -0700201 /* Switch back to old stack. */
202 movl 4(%esp), %edx
203 xchgl %edx, %esp
Damjan Mariond466c0c2020-05-16 00:40:48 +0200204
Ed Warnickecb9cada2015-12-08 15:45:58 -0700205 /* Return to caller. */
206 ret
Damjan Mariond466c0c2020-05-16 00:40:48 +0200207
Ed Warnickecb9cada2015-12-08 15:45:58 -0700208#elif defined(__SPU__)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200209
Ed Warnickecb9cada2015-12-08 15:45:58 -0700210#elif defined(__powerpc64__)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200211
Ed Warnickecb9cada2015-12-08 15:45:58 -0700212 .text
213
214#define _prologue(n) \
215 .align 2 ; \
216 .globl n, .##n ; \
217 .section ".opd", "aw" ; \
218 .align 3 ; \
219n: .quad .##n, .TOC.@tocbase, 0 ; \
220 .previous ; \
221 .size n, 24 ; \
222 .type .##n, @function ; \
223.##n:
224
225#define _foreach_14_31 \
226_ (14, 0) _ (15, 1) _ (16, 2) _ (17, 3) _ (18, 4) _ (19, 5) \
227_ (20, 6) _ (21, 7) _ (22, 8) _ (23, 9) _ (24, 10) _ (25, 11) \
228_ (26, 12) _ (27, 13) _ (28, 14) _ (29, 15) _ (30, 16) _ (31, 17)
229
230#define _foreach_20_31 \
231_ (20, 0) _ (21, 1) _ (22, 2) _ (23, 3) _ (24, 4) _ (25, 5) \
232_ (26, 6) _ (27, 7) _ (28, 8) _ (29, 9) _ (30, 10) _ (31, 11)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200233
Ed Warnickecb9cada2015-12-08 15:45:58 -0700234#ifdef __ALTIVEC__
235#define CLIB_POWERPC_ALTIVEC_N_REGS 12
236#else
237#define CLIB_POWERPC_ALTIVEC_N_REGS 0
238#endif
239
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200240_prologue (cdecl(clib_setjmp))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700241 mflr 0
242 std 0, 8*0(3)
243 std 1, 8*1(3)
244 std 2, 8*2(3)
245 mfcr 0
246 std 0, 8*3(3)
247 mfspr 0, 256
248 stw 0, 8*4(3)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200249
Ed Warnickecb9cada2015-12-08 15:45:58 -0700250 /* gprs 14 - 31 */
Damjan Mariond466c0c2020-05-16 00:40:48 +0200251#define _(a,b) std a, 8*((b) + 4 + 18*0)(3) ;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700252 _foreach_14_31
253#undef _
Damjan Mariond466c0c2020-05-16 00:40:48 +0200254
Ed Warnickecb9cada2015-12-08 15:45:58 -0700255 /* fprs 14 - 31 */
Damjan Mariond466c0c2020-05-16 00:40:48 +0200256#define _(a,b) stfd a, 8*((b) + 4 + 18*1)(3) ;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700257 _foreach_14_31
258#undef _
259
260#if CLIB_POWERPC_ALTIVEC_N_REGS > 0
261 /* vrs 20 - 31 */
262 li 5, 8*(4 + 18*2)
263#define _(a,b) stvx a, 5, 3 ; addi 5, 5, 16 ;
264 _foreach_20_31
265#undef _
266#endif /* CLIB_POWERPC_ALTIVEC_N_REGS > 0 */
Damjan Mariond466c0c2020-05-16 00:40:48 +0200267
Ed Warnickecb9cada2015-12-08 15:45:58 -0700268 /* Return value. */
269 mr 3, 4
Damjan Mariond466c0c2020-05-16 00:40:48 +0200270
Ed Warnickecb9cada2015-12-08 15:45:58 -0700271 blr
Damjan Mariond466c0c2020-05-16 00:40:48 +0200272
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200273_prologue (cdecl(clib_longjmp))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700274 ld 0, 8*0(3)
275 mtlr 0
276 ld 1, 8*1(3)
277 ld 2, 8*2(3)
278 ld 0, 8*3(3)
279 mtcrf 0xff, 0
280 lwz 0, 8*3(3)
281 mtspr 256, 0
Damjan Mariond466c0c2020-05-16 00:40:48 +0200282
Ed Warnickecb9cada2015-12-08 15:45:58 -0700283 /* gprs 14 - 31 */
Damjan Mariond466c0c2020-05-16 00:40:48 +0200284#define _(a,b) ld a, 8*((b) + 4 + 18*0)(3) ;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700285 _foreach_14_31
286#undef _
Damjan Mariond466c0c2020-05-16 00:40:48 +0200287
Ed Warnickecb9cada2015-12-08 15:45:58 -0700288 /* fprs 14 - 31 */
Damjan Mariond466c0c2020-05-16 00:40:48 +0200289#define _(a,b) lfd a, 8*((b) + 4 + 18*1)(3) ;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700290 _foreach_14_31
291#undef _
Damjan Mariond466c0c2020-05-16 00:40:48 +0200292
Ed Warnickecb9cada2015-12-08 15:45:58 -0700293#if CLIB_POWERPC_ALTIVEC_N_REGS > 0
294 /* vrs 20 - 31 */
295 li 5, 8*(4 + 18*2)
296#define _(a,b) lvx a, 5, 3 ; addi 5, 5, 16 ;
297 _foreach_20_31
298#undef _
299#endif /* CLIB_POWERPC_ALTIVEC_N_REGS > 0 */
Damjan Mariond466c0c2020-05-16 00:40:48 +0200300
Ed Warnickecb9cada2015-12-08 15:45:58 -0700301 /* Return value. */
302 mr 3, 4
Damjan Mariond466c0c2020-05-16 00:40:48 +0200303
Ed Warnickecb9cada2015-12-08 15:45:58 -0700304 blr
305
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200306 .globl cdecl(clib_calljmp)
Dave Barachbfdedbd2016-01-20 09:11:55 -0500307 .section ".opd","aw"
308 .align 3
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200309cdecl(clib_calljmp):
310 .quad .L.cdecl(clib_calljmp),.TOC.@tocbase,0
Dave Barachbfdedbd2016-01-20 09:11:55 -0500311 .previous
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200312 .type cdecl(clib_calljmp), @function
313.L.cdecl(clib_calljmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -0700314 mflr 0
Dave Barachbfdedbd2016-01-20 09:11:55 -0500315 mr 9,3
316 std 0,16(1)
317 stdu 1,-112(1)
318#APP
319 std 1,-8(5)
320 addi 5,5,-256
321 mr 1,5
322#NO_APP
323 ld 10,0(9)
324 std 2,40(1)
325 mr 3,4
326 mtctr 10
327 ld 11,16(9)
328 ld 2,8(9)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700329 bctrl
Dave Barachbfdedbd2016-01-20 09:11:55 -0500330 ld 2,40(1)
331#APP
332 addi 1,1,256
333 ld 1,-8(1)
334#NO_APP
335 addi 1,1,112
336 ld 0,16(1)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700337 mtlr 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700338 blr
Dave Barachbfdedbd2016-01-20 09:11:55 -0500339 .long 0
340 .byte 0,0,0,1,128,0,0,0
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200341 .size cdecl(clib_calljmp),.-.L.cdecl(clib_calljmp)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200342
Ed Warnickecb9cada2015-12-08 15:45:58 -0700343#elif defined(__powerpc__)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200344
Ed Warnickecb9cada2015-12-08 15:45:58 -0700345#define _foreach_14_31 \
346_ (14, 0) _ (15, 1) _ (16, 2) _ (17, 3) _ (18, 4) _ (19, 5) \
347_ (20, 6) _ (21, 7) _ (22, 8) _ (23, 9) _ (24, 10) _ (25, 11) \
348_ (26, 12) _ (27, 13) _ (28, 14) _ (29, 15) _ (30, 16) _ (31, 17)
349
350#define _foreach_20_31 \
351_ (20, 0) _ (21, 1) _ (22, 2) _ (23, 3) _ (24, 4) _ (25, 5) \
352_ (26, 6) _ (27, 7) _ (28, 8) _ (29, 9) _ (30, 10) _ (31, 11)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200353
Ed Warnickecb9cada2015-12-08 15:45:58 -0700354#ifdef __ALTIVEC__
355#define CLIB_POWERPC_ALTIVEC_N_REGS 12
356#else
357#define CLIB_POWERPC_ALTIVEC_N_REGS 0
358#endif
359
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200360 .global cdecl(clib_setjmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700361 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200362 .type cdecl(clib_setjmp), @function
363cdecl(clib_setjmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -0700364 mflr 0
365 stw 0, 4*0(3)
366 stw 1, 4*1(3)
367 mfcr 0
368 stw 0, 4*2(3)
369#if CLIB_POWERPC_ALTIVEC_N_REGS > 0
370 mfspr 0, 256
371#endif
372 stw 0, 4*3(3)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200373
Ed Warnickecb9cada2015-12-08 15:45:58 -0700374#if CLIB_POWERPC_ALTIVEC_N_REGS > 0
375 li 5, 4*4
376#define _(a,b) stvx a, 3, 5 ; addi 5, 5, 16 ;
377 _foreach_20_31
378#undef _
379#endif /* CLIB_POWERPC_ALTIVEC_N_REGS > 0 */
Damjan Mariond466c0c2020-05-16 00:40:48 +0200380
Ed Warnickecb9cada2015-12-08 15:45:58 -0700381 /* gp 14 - 31 */
Damjan Mariond466c0c2020-05-16 00:40:48 +0200382#define _(a,b) stw a, 4*(1*(b) + 4 + 4*CLIB_POWERPC_ALTIVEC_N_REGS + 0*18)(3) ;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700383 _foreach_14_31
384#undef _
Damjan Mariond466c0c2020-05-16 00:40:48 +0200385
Ed Warnickecb9cada2015-12-08 15:45:58 -0700386 /* fp 14 - 31 */
387#define _(a,b) stfd a, 4*(2*(b) + 4 + 4*CLIB_POWERPC_ALTIVEC_N_REGS + 1*18)(3) ;
388 _foreach_14_31
389#undef _
390
391 /* Return value. */
392 mr 3, 4
Damjan Mariond466c0c2020-05-16 00:40:48 +0200393
Ed Warnickecb9cada2015-12-08 15:45:58 -0700394 blr
Damjan Mariond466c0c2020-05-16 00:40:48 +0200395
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200396 .global cdecl(clib_longjmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700397 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200398 .type cdecl(clib_longjmp), @function
Damjan Mariond466c0c2020-05-16 00:40:48 +0200399cdecl(clib_longjmp):
400
Ed Warnickecb9cada2015-12-08 15:45:58 -0700401 lwz 0, 4*0(3)
402 mtlr 0
403 lwz 1, 4*1(3)
404 lwz 0, 4*2(3)
405 mtcr 0
406 lwz 0, 4*3(3)
407#if CLIB_POWERPC_ALTIVEC_N_REGS > 0
408 mtspr 256, 0
409#endif
Damjan Mariond466c0c2020-05-16 00:40:48 +0200410
Ed Warnickecb9cada2015-12-08 15:45:58 -0700411#if CLIB_POWERPC_ALTIVEC_N_REGS > 0
412 li 5, 4*4
413#define _(a,b) lvx a, 3, 5 ; addi 5, 5, 16 ;
414 _foreach_20_31
415#undef _
416#endif /* CLIB_POWERPC_ALTIVEC_N_REGS > 0 */
Damjan Mariond466c0c2020-05-16 00:40:48 +0200417
Ed Warnickecb9cada2015-12-08 15:45:58 -0700418 /* gp 14 - 31 */
419#define _(a,b) lwz a, 4*(1*(b) + 4 + 4*CLIB_POWERPC_ALTIVEC_N_REGS + 0*18)(3) ;
420 _foreach_14_31
421#undef _
Damjan Mariond466c0c2020-05-16 00:40:48 +0200422
Ed Warnickecb9cada2015-12-08 15:45:58 -0700423 /* fp 14 - 31 */
424#define _(a,b) lfd a, 4*(2*(b) + 4 + 4*CLIB_POWERPC_ALTIVEC_N_REGS + 1*18)(3) ;
425 _foreach_14_31
426#undef _
427
428 /* Return value. */
429 mr 3, 4
Damjan Mariond466c0c2020-05-16 00:40:48 +0200430
Ed Warnickecb9cada2015-12-08 15:45:58 -0700431 blr
432
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200433 .global cdecl(clib_calljmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700434 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200435 .type cdecl(clib_calljmp), @function
Damjan Mariond466c0c2020-05-16 00:40:48 +0200436cdecl(clib_calljmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -0700437 /* Make sure stack is 16 byte aligned. */
438 andi. 0, 5, 0xf
439 sub 5, 5, 0
440 addi 5, 5, -16
Damjan Mariond466c0c2020-05-16 00:40:48 +0200441
Ed Warnickecb9cada2015-12-08 15:45:58 -0700442 /* Save old stack/link pointer on new stack. */
443 stw 1, 0(5)
444 mflr 0
445 stw 0, 4(5)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200446
Ed Warnickecb9cada2015-12-08 15:45:58 -0700447 /* account for (sp, lr) tuple, and keep aligned */
448 addi 5, 5, -16
Damjan Mariond466c0c2020-05-16 00:40:48 +0200449
Ed Warnickecb9cada2015-12-08 15:45:58 -0700450 /* Switch stacks. */
451 mr 1, 5
Damjan Mariond466c0c2020-05-16 00:40:48 +0200452
Ed Warnickecb9cada2015-12-08 15:45:58 -0700453 /* Move argument into place. */
454 mtctr 3
455 mr 3, 4
Damjan Mariond466c0c2020-05-16 00:40:48 +0200456
Ed Warnickecb9cada2015-12-08 15:45:58 -0700457 /* Away we go. */
458 bctrl
Damjan Mariond466c0c2020-05-16 00:40:48 +0200459
Ed Warnickecb9cada2015-12-08 15:45:58 -0700460 /* back to our synthetic frame */
461 addi 1,1,16
Damjan Mariond466c0c2020-05-16 00:40:48 +0200462
Ed Warnickecb9cada2015-12-08 15:45:58 -0700463 /* Switch back to old stack. */
464 lwz 0, 4(1)
465 mtlr 0
466 lwz 0, 0(1)
467 mr 1, 0
Damjan Mariond466c0c2020-05-16 00:40:48 +0200468
Ed Warnickecb9cada2015-12-08 15:45:58 -0700469 /* Return to caller. */
470 blr
Damjan Mariond466c0c2020-05-16 00:40:48 +0200471
Ed Warnickecb9cada2015-12-08 15:45:58 -0700472#elif defined(__arm__)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200473
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200474 .global cdecl(clib_setjmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700475 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200476 .type cdecl(clib_setjmp), %function
477cdecl(clib_setjmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -0700478 mov ip, r0 /* jmp buffer */
479
480 /* Save integer registers */
481 stmia ip!, {v1-v6, sl, fp, sp, lr}
Damjan Mariond466c0c2020-05-16 00:40:48 +0200482
Ed Warnickecb9cada2015-12-08 15:45:58 -0700483#ifdef __IWMMXT__
484 /* Save the call-preserved iWMMXt registers. */
485 wstrd wr10, [ip], #8
486 wstrd wr11, [ip], #8
487 wstrd wr12, [ip], #8
488 wstrd wr13, [ip], #8
489 wstrd wr14, [ip], #8
490 wstrd wr15, [ip], #8
491#endif
492
493 /* Give back user's return value. */
Christophe Fontainefef15b42016-04-09 12:38:49 +0900494 mov r0, r1
Ed Warnickecb9cada2015-12-08 15:45:58 -0700495 bx lr
Damjan Mariond466c0c2020-05-16 00:40:48 +0200496
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200497 .global cdecl(clib_longjmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700498 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200499 .type cdecl(clib_longjmp), %function
Damjan Mariond466c0c2020-05-16 00:40:48 +0200500cdecl(clib_longjmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -0700501 mov ip, r0 /* jmp buffer */
502
503 /* Restore integer registers. */
504 ldmia ip!, {v1-v6, sl, fp, sp, lr}
Damjan Mariond466c0c2020-05-16 00:40:48 +0200505
Ed Warnickecb9cada2015-12-08 15:45:58 -0700506#ifdef __IWMMXT__
507 /* Save the call-preserved iWMMXt registers. */
508 wldrd wr10, [ip], #8
509 wldrd wr11, [ip], #8
510 wldrd wr12, [ip], #8
511 wldrd wr13, [ip], #8
512 wldrd wr14, [ip], #8
513 wldrd wr15, [ip], #8
514#endif
Damjan Mariond466c0c2020-05-16 00:40:48 +0200515
Ed Warnickecb9cada2015-12-08 15:45:58 -0700516 /* Give back user's return value. */
Christophe Fontainefef15b42016-04-09 12:38:49 +0900517 mov r0, r1
Ed Warnickecb9cada2015-12-08 15:45:58 -0700518 bx lr
519
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200520 .global cdecl(clib_calljmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700521 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200522 .type cdecl(clib_calljmp), %function
Damjan Mariond466c0c2020-05-16 00:40:48 +0200523cdecl(clib_calljmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -0700524 /* Make sure stack is 8 byte aligned. */
525 bic r2, r2, #7
Damjan Mariond466c0c2020-05-16 00:40:48 +0200526
Ed Warnickecb9cada2015-12-08 15:45:58 -0700527 /* Allocate space for stack/link pointer on new stack. */
Damjan Mariond466c0c2020-05-16 00:40:48 +0200528 sub r2, r2, #8
529
Ed Warnickecb9cada2015-12-08 15:45:58 -0700530 /* Save old stack/link pointer on new stack. */
531 str sp, [r2, #0]
532 str lr, [r2, #4]
Damjan Mariond466c0c2020-05-16 00:40:48 +0200533
Ed Warnickecb9cada2015-12-08 15:45:58 -0700534 /* Switch stacks. */
535 mov sp, r2
Damjan Mariond466c0c2020-05-16 00:40:48 +0200536
Ed Warnickecb9cada2015-12-08 15:45:58 -0700537 /* Save function to call. */
538 mov ip, r0
Damjan Mariond466c0c2020-05-16 00:40:48 +0200539
Ed Warnickecb9cada2015-12-08 15:45:58 -0700540 /* Move argument into place. */
541 mov r0, r1
Damjan Mariond466c0c2020-05-16 00:40:48 +0200542
Ed Warnickecb9cada2015-12-08 15:45:58 -0700543 /* Away we go. */
544 bx ip
Damjan Mariond466c0c2020-05-16 00:40:48 +0200545
Ed Warnickecb9cada2015-12-08 15:45:58 -0700546 /* Switch back to old stack. */
547 ldr lr, [sp, #4]
548 ldr ip, [sp, #0]
549 mov sp, ip
Damjan Mariond466c0c2020-05-16 00:40:48 +0200550
Ed Warnickecb9cada2015-12-08 15:45:58 -0700551 /* Return to caller. */
552 bx lr
Damjan Mariond466c0c2020-05-16 00:40:48 +0200553
Ed Warnickecb9cada2015-12-08 15:45:58 -0700554#elif defined(__xtensa__)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200555
Ed Warnickecb9cada2015-12-08 15:45:58 -0700556 /* FIXME implement if needed. */
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200557 .global cdecl(clib_setjmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700558 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200559 .type cdecl(clib_setjmp), %function
560cdecl(clib_setjmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -07005611: j 1b
562
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200563 .global cdecl(clib_longjmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700564 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200565 .type cdecl(clib_longjmp), @function
Damjan Mariond466c0c2020-05-16 00:40:48 +0200566cdecl(clib_longjmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -07005671: j 1b
Damjan Mariond466c0c2020-05-16 00:40:48 +0200568
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200569 .global cdecl(clib_calljmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700570 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200571 .type cdecl(clib_calljmp), %function
Damjan Mariond466c0c2020-05-16 00:40:48 +0200572cdecl(clib_calljmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -07005731: j 1b
Damjan Mariond466c0c2020-05-16 00:40:48 +0200574
Ed Warnickecb9cada2015-12-08 15:45:58 -0700575#elif defined(__TMS320C6X__)
Damjan Mariond466c0c2020-05-16 00:40:48 +0200576
Ed Warnickecb9cada2015-12-08 15:45:58 -0700577 /* FIXME implement if needed. */
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200578 .global cdecl(clib_setjmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700579 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200580 .type cdecl(clib_setjmp), %function
581cdecl(clib_setjmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -07005821: B .S1 1b
583
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200584 .global cdecl(clib_longjmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700585 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200586 .type cdecl(clib_longjmp), @function
Damjan Mariond466c0c2020-05-16 00:40:48 +0200587cdecl(clib_longjmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -07005881: B .S1 1b
Damjan Mariond466c0c2020-05-16 00:40:48 +0200589
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200590 .global cdecl(clib_calljmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700591 .align 4
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200592 .type cdecl(clib_calljmp), %function
Damjan Mariond466c0c2020-05-16 00:40:48 +0200593cdecl(clib_calljmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -07005941: B .S1 1b
Damjan Mariond466c0c2020-05-16 00:40:48 +0200595
Carl Smith28d42712018-07-26 15:45:28 +1200596#elif defined(_mips) && __mips == 64
597
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200598 .global cdecl(clib_setjmp)
Carl Smith28d42712018-07-26 15:45:28 +1200599 .align 8
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200600 .type cdecl(clib_setjmp), %function
601cdecl(clib_setjmp):
Carl Smith28d42712018-07-26 15:45:28 +1200602 sd $ra, 0($a0)
603 sd $sp, 8($a0)
604 sd $gp, 16($a0)
605 sd $16, 24($a0)
606 sd $17, 32($a0)
607 sd $18, 40($a0)
608 sd $19, 48($a0)
609 sd $20, 56($a0)
610 sd $21, 64($a0)
611 sd $22, 72($a0)
612 sd $23, 80($a0)
613 sd $30, 88($a0)
614 move $v0, $a1
615 jr $ra
616 nop
617
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200618 .global cdecl(clib_longjmp)
Carl Smith28d42712018-07-26 15:45:28 +1200619 .align 8
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200620 .type cdecl(clib_longjmp), @function
621cdecl(clib_longjmp):
Carl Smith28d42712018-07-26 15:45:28 +1200622 move $v0, $a1
623 bne $v0, $0, 1f
624 nop
625 daddu $v0, $v0, 1
6261:
627 ld $ra, 0($a0)
628 ld $sp, 8($a0)
629 ld $gp, 16($a0)
630 ld $16, 24($a0)
631 ld $17, 32($a0)
632 ld $18, 40($a0)
633 ld $19, 48($a0)
634 ld $20, 56($a0)
635 ld $21, 64($a0)
636 ld $22, 72($a0)
637 ld $23, 80($a0)
638 ld $30, 88($a0)
639 jr $ra
640 nop
641
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200642 .global cdecl(clib_calljmp)
Carl Smith28d42712018-07-26 15:45:28 +1200643 .align 8
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200644 .type cdecl(clib_calljmp), %function
645cdecl(clib_calljmp):
Carl Smith28d42712018-07-26 15:45:28 +1200646 /* Force 16 byte alignment of the new stack */
647 li $t1, -16
648 and $t0, $a2, $t1
649 /* Save old ra/gp/sp on new stack */
650 daddiu $t0, $t0, (-24)
651 sd $ra, 0($t0)
652 sd $gp, 8($t0)
653 sd $sp, 16($t0)
654 /* Switch stacks */
655 move $sp, $t0
656 /* Away we go */
657 move $t9, $a0
658 move $a0, $a1
659 jalr $t9
660 nop
661 /* Switch back to old ra/gp/sp */
662 move $t0, $sp
663 ld $ra, 0($t0)
664 ld $gp, 8($t0)
665 ld $sp, 16($t0)
666 /* Return to caller */
667 jr $ra
668 nop
669
Dave Barach61efa142016-01-22 08:23:09 -0500670#elif defined (__aarch64__)
671/*
672 Copyright (c) 2011, 2012 ARM Ltd
673 All rights reserved.
674 Redistribution and use in source and binary forms, with or without
675 modification, are permitted provided that the following conditions
676 are met:
677 1. Redistributions of source code must retain the above copyright
678 notice, this list of conditions and the following disclaimer.
679 2. Redistributions in binary form must reproduce the above copyright
680 notice, this list of conditions and the following disclaimer in the
681 documentation and/or other materials provided with the distribution.
682 3. The name of the company may not be used to endorse or promote
683 products derived from this software without specific prior written
684 permission.
685 THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
686 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
687 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
688 IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
689 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
690 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
691 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
692 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
693 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
694 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
695 */
696#define GPR_LAYOUT \
697 REG_PAIR (x19, x20, 0); \
698 REG_PAIR (x21, x22, 16); \
699 REG_PAIR (x23, x24, 32); \
700 REG_PAIR (x25, x26, 48); \
701 REG_PAIR (x27, x28, 64); \
702 REG_PAIR (x29, x30, 80); \
703 REG_ONE (x16, 96)
704#define FPR_LAYOUT \
705 REG_PAIR ( d8, d9, 112); \
706 REG_PAIR (d10, d11, 128); \
707 REG_PAIR (d12, d13, 144); \
708 REG_PAIR (d14, d15, 160);
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200709// int cdecl(clib_setjmp) (jmp_buf)
710 .global cdecl(clib_setjmp)
711 .type cdecl(clib_setjmp), %function
712cdecl(clib_setjmp):
Dave Barach61efa142016-01-22 08:23:09 -0500713 mov x16, sp
714#define REG_PAIR(REG1, REG2, OFFS) stp REG1, REG2, [x0, OFFS]
715#define REG_ONE(REG1, OFFS) str REG1, [x0, OFFS]
716 GPR_LAYOUT
717 FPR_LAYOUT
718#undef REG_PAIR
719#undef REG_ONE
720 mov x0, x1
721 ret
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200722 .size cdecl(clib_setjmp), .-cdecl(clib_setjmp)
723// void cdecl(clib_longjmp) (jmp_buf, int) __attribute__ ((noreturn))
724 .global cdecl(clib_longjmp)
725 .type cdecl(clib_longjmp), %function
726cdecl(clib_longjmp):
Dave Barach61efa142016-01-22 08:23:09 -0500727#define REG_PAIR(REG1, REG2, OFFS) ldp REG1, REG2, [x0, OFFS]
728#define REG_ONE(REG1, OFFS) ldr REG1, [x0, OFFS]
729 GPR_LAYOUT
730 FPR_LAYOUT
731#undef REG_PAIR
732#undef REG_ONE
733 mov sp, x16
734 mov x0, x1
735 // cmp w1, #0
736 // cinc w0, w1, eq
737 // use br not ret, as ret is guaranteed to mispredict
738 br x30
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200739 .size cdecl(clib_longjmp), .-cdecl(clib_longjmp)
Dave Barach61efa142016-01-22 08:23:09 -0500740
741
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200742// void cdecl(clib_calljmp) (x0=function, x1=arg, x2=new_stack)
743 .global cdecl(clib_calljmp)
744 .type cdecl(clib_calljmp), %function
745cdecl(clib_calljmp):
Dave Barach61efa142016-01-22 08:23:09 -0500746 // save fn ptr
747 mov x3, x0
748 // set up fn arg
749 mov x0, x1
750 // switch stacks
751 mov x4, sp
Damjan Mariond466c0c2020-05-16 00:40:48 +0200752
Dave Barach61efa142016-01-22 08:23:09 -0500753 // space for saved sp, lr on new stack
754 sub x2, x2, #16
755 mov sp, x2
Damjan Mariond466c0c2020-05-16 00:40:48 +0200756
Dave Barach61efa142016-01-22 08:23:09 -0500757 // save old sp and link register on new stack
758 str x4, [sp]
759 str x30,[sp,#8]
760 mov x4, sp
761
762 // go there
763 blr x3
Damjan Mariond466c0c2020-05-16 00:40:48 +0200764
Dave Barach61efa142016-01-22 08:23:09 -0500765 // restore old sp and link register
766 mov x4, sp
Damjan Mariond466c0c2020-05-16 00:40:48 +0200767
Dave Barach61efa142016-01-22 08:23:09 -0500768 ldr x3, [x4]
769 ldr x30,[x4, #8]
770 mov sp, x3
771 ret
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200772 .size cdecl(clib_calljmp), .-cdecl(clib_calljmp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700773#else
774#error "unknown machine"
Damjan Mariond466c0c2020-05-16 00:40:48 +0200775#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700776
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200777#ifndef __APPLE__
Ed Warnickecb9cada2015-12-08 15:45:58 -0700778.section .note.GNU-stack,"",%progbits
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200779#endif