blob: 0b7449f866935888a895ffe8dcb3ea18bd160244 [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)
62
63 /* Save PC we are returning to from stack frame. */
64 movq 0(%rsp), %rax
65 movq %rax, 8*7(%rdi)
66
67 /* Give back user's return value. */
68 movq %rsi, %rax
69 ret
70
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
76cdecl(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
86
87 /* Give back user's return value. */
88 movq %rsi, %rax
89
90 /* Away we go. */
91 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
103
104 /* Get return address. */
105 pop %rax
106
107 /* Switch to new stack. */
108 xchgq %rsp, %rdx
109
110 /* Save return address on new stack. */
111 push %rax
112
113 /* Save old stack pointer on new stack. */
114 push %rdx
115
116 /* Get function. */
117 movq %rdi, %rdx
118
119 /* Move argument into place. */
120 movq %rsi, %rdi
121
122 /* Away we go. */
123 callq *%rdx
124
125 /* Switch back to old stack. */
126 movq 8(%rsp), %rdx
127 movq 0(%rsp), %rcx
128 xchgq %rcx, %rsp
129
130 /* 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
139
140 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)
148
149 /* Save PC we are returning to from stack frame. */
150 movl 0(%esp), %eax
151 movl %eax, 4*5(%ecx)
152
153 /* Give back user's return value. */
154 movl 8(%esp), %eax
155 ret
156
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
160cdecl(clib_longjmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -0700161 movl 4(%esp), %ecx
162
163 /* Give back user's return value. */
164 movl 8(%esp), %eax
165
166 /* 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
173
174 /* Away we go. */
175 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
180cdecl(clib_calljmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -0700181 /* Get new stack pointer. */
182 movl 12(%esp), %edx
183
184 /* Switch stacks. */
185 xchgl %esp, %edx
186
187 /* Save old stack pointer on new stack. */
188 sub $8, %esp
189 movl %edx, 4(%esp)
190
191 /* Put function argument in stack frame. */
192 movl 8(%edx), %eax
193 movl %eax, 0(%esp)
194
195 /* Get function. */
196 movl 4(%edx), %eax
197
198 /* Away we go. */
199 call *%eax
200
201 /* Switch back to old stack. */
202 movl 4(%esp), %edx
203 xchgl %edx, %esp
204
205 /* Return to caller. */
206 ret
207
208#elif defined(__SPU__)
209
210#elif defined(__powerpc64__)
211
212 .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)
233
234#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)
249
250 /* gprs 14 - 31 */
251#define _(a,b) std a, 8*((b) + 4 + 18*0)(3) ;
252 _foreach_14_31
253#undef _
254
255 /* fprs 14 - 31 */
256#define _(a,b) stfd a, 8*((b) + 4 + 18*1)(3) ;
257 _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 */
267
268 /* Return value. */
269 mr 3, 4
270
271 blr
272
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
282
283 /* gprs 14 - 31 */
284#define _(a,b) ld a, 8*((b) + 4 + 18*0)(3) ;
285 _foreach_14_31
286#undef _
287
288 /* fprs 14 - 31 */
289#define _(a,b) lfd a, 8*((b) + 4 + 18*1)(3) ;
290 _foreach_14_31
291#undef _
292
293#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 */
300
301 /* Return value. */
302 mr 3, 4
303
304 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)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700342
343#elif defined(__powerpc__)
344
345#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)
353
354#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)
373
374#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 */
380
381 /* gp 14 - 31 */
382#define _(a,b) stw a, 4*(1*(b) + 4 + 4*CLIB_POWERPC_ALTIVEC_N_REGS + 0*18)(3) ;
383 _foreach_14_31
384#undef _
385
386 /* 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
393
394 blr
395
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
399cdecl(clib_longjmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -0700400
401 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
410
411#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 */
417
418 /* 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 _
422
423 /* 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
430
431 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
436cdecl(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
441
442 /* Save old stack/link pointer on new stack. */
443 stw 1, 0(5)
444 mflr 0
445 stw 0, 4(5)
446
447 /* account for (sp, lr) tuple, and keep aligned */
448 addi 5, 5, -16
449
450 /* Switch stacks. */
451 mr 1, 5
452
453 /* Move argument into place. */
454 mtctr 3
455 mr 3, 4
456
457 /* Away we go. */
458 bctrl
459
460 /* back to our synthetic frame */
461 addi 1,1,16
462
463 /* Switch back to old stack. */
464 lwz 0, 4(1)
465 mtlr 0
466 lwz 0, 0(1)
467 mr 1, 0
468
469 /* Return to caller. */
470 blr
471
472#elif defined(__arm__)
473
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}
482
483#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
496
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
500cdecl(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}
505
506#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
515
516 /* 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
523cdecl(clib_calljmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -0700524 /* Make sure stack is 8 byte aligned. */
525 bic r2, r2, #7
526
527 /* Allocate space for stack/link pointer on new stack. */
528 sub r2, r2, #8
529
530 /* Save old stack/link pointer on new stack. */
531 str sp, [r2, #0]
532 str lr, [r2, #4]
533
534 /* Switch stacks. */
535 mov sp, r2
536
537 /* Save function to call. */
538 mov ip, r0
539
540 /* Move argument into place. */
541 mov r0, r1
542
543 /* Away we go. */
544 bx ip
545
546 /* Switch back to old stack. */
547 ldr lr, [sp, #4]
548 ldr ip, [sp, #0]
549 mov sp, ip
550
551 /* Return to caller. */
552 bx lr
553
554#elif defined(__xtensa__)
555
556 /* 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
566cdecl(clib_longjmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -07005671: j 1b
568
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
572cdecl(clib_calljmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -07005731: j 1b
574
575#elif defined(__TMS320C6X__)
576
577 /* 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
587cdecl(clib_longjmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -07005881: B .S1 1b
589
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
593cdecl(clib_calljmp):
Ed Warnickecb9cada2015-12-08 15:45:58 -07005941: B .S1 1b
595
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
752
753 // space for saved sp, lr on new stack
754 sub x2, x2, #16
755 mov sp, x2
756
757 // 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
764
765 // restore old sp and link register
766 mov x4, sp
767
768 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"
775#endif
776
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