blob: 6468dba45bf5c77849f52f7cabed3aa92d3776e7 [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*/
37
38#if defined(__x86_64__)
39 .global clib_setjmp
40 .align 4
41 .type clib_setjmp, @function
42clib_setjmp:
43 movq %rbx, 8*0(%rdi)
44 movq %rbp, 8*1(%rdi)
45 movq %r12, 8*2(%rdi)
46 movq %r13, 8*3(%rdi)
47 movq %r14, 8*4(%rdi)
48 movq %r15, 8*5(%rdi)
49
50 /* Save SP after return. */
51 leaq 8(%rsp), %rdx
52 movq %rdx, 8*6(%rdi)
53
54 /* Save PC we are returning to from stack frame. */
55 movq 0(%rsp), %rax
56 movq %rax, 8*7(%rdi)
57
58 /* Give back user's return value. */
59 movq %rsi, %rax
60 ret
61
62 .global clib_longjmp
63 .align 4
64 .type clib_longjmp, @function
65clib_longjmp:
66 /* Restore regs. */
67 movq 8*0(%rdi), %rbx
68 movq 8*1(%rdi), %rbp
69 movq 8*2(%rdi), %r12
70 movq 8*3(%rdi), %r13
71 movq 8*4(%rdi), %r14
72 movq 8*5(%rdi), %r15
73 movq 8*6(%rdi), %rsp
74 movq 8*7(%rdi), %rdx
75
76 /* Give back user's return value. */
77 movq %rsi, %rax
78
79 /* Away we go. */
80 jmpq *%rdx
81
82 .global clib_calljmp
83 .align 4
84 .type clib_calljmp, @function
85clib_calljmp:
86 /* Make sure stack is 16-byte aligned. */
87 movq %rdx, %rax
88 andq $0xf, %rax
89 subq %rax, %rdx
90
91 /* Get return address. */
92 pop %rax
93
94 /* Switch to new stack. */
95 xchgq %rsp, %rdx
96
97 /* Save return address on new stack. */
98 push %rax
99
100 /* Save old stack pointer on new stack. */
101 push %rdx
102
103 /* Get function. */
104 movq %rdi, %rdx
105
106 /* Move argument into place. */
107 movq %rsi, %rdi
108
109 /* Away we go. */
110 callq *%rdx
111
112 /* Switch back to old stack. */
113 movq 8(%rsp), %rdx
114 movq 0(%rsp), %rcx
115 xchgq %rcx, %rsp
116
117 /* Return to caller. */
118 jmpq *%rdx
119
120#elif defined(i386)
121 .global clib_setjmp
122 .align 4
123 .type clib_setjmp, @function
124clib_setjmp:
125 movl 4(%esp), %ecx
126
127 movl %ebp, 4*0(%ecx)
128 movl %ebx, 4*1(%ecx)
129 movl %edi, 4*2(%ecx)
130 movl %esi, 4*3(%ecx)
131
132 /* Save SP after return. */
133 leal 4(%esp), %edx
134 movl %edx, 4*4(%ecx)
135
136 /* Save PC we are returning to from stack frame. */
137 movl 0(%esp), %eax
138 movl %eax, 4*5(%ecx)
139
140 /* Give back user's return value. */
141 movl 8(%esp), %eax
142 ret
143
144 .global clib_longjmp
145 .align 4
146 .type clib_longjmp, @function
147clib_longjmp:
148 movl 4(%esp), %ecx
149
150 /* Give back user's return value. */
151 movl 8(%esp), %eax
152
153 /* Restore regs. */
154 movl 4*0(%ecx), %ebp
155 movl 4*1(%ecx), %ebx
156 movl 4*2(%ecx), %edi
157 movl 4*3(%ecx), %esi
158 movl 4*4(%ecx), %esp
159 movl 4*5(%ecx), %edx
160
161 /* Away we go. */
162 jmp *%edx
163
164 .global clib_calljmp
165 .align 4
166 .type clib_calljmp, @function
167clib_calljmp:
168 /* Get new stack pointer. */
169 movl 12(%esp), %edx
170
171 /* Switch stacks. */
172 xchgl %esp, %edx
173
174 /* Save old stack pointer on new stack. */
175 sub $8, %esp
176 movl %edx, 4(%esp)
177
178 /* Put function argument in stack frame. */
179 movl 8(%edx), %eax
180 movl %eax, 0(%esp)
181
182 /* Get function. */
183 movl 4(%edx), %eax
184
185 /* Away we go. */
186 call *%eax
187
188 /* Switch back to old stack. */
189 movl 4(%esp), %edx
190 xchgl %edx, %esp
191
192 /* Return to caller. */
193 ret
194
195#elif defined(__SPU__)
196
197#elif defined(__powerpc64__)
198
199 .text
200
201#define _prologue(n) \
202 .align 2 ; \
203 .globl n, .##n ; \
204 .section ".opd", "aw" ; \
205 .align 3 ; \
206n: .quad .##n, .TOC.@tocbase, 0 ; \
207 .previous ; \
208 .size n, 24 ; \
209 .type .##n, @function ; \
210.##n:
211
212#define _foreach_14_31 \
213_ (14, 0) _ (15, 1) _ (16, 2) _ (17, 3) _ (18, 4) _ (19, 5) \
214_ (20, 6) _ (21, 7) _ (22, 8) _ (23, 9) _ (24, 10) _ (25, 11) \
215_ (26, 12) _ (27, 13) _ (28, 14) _ (29, 15) _ (30, 16) _ (31, 17)
216
217#define _foreach_20_31 \
218_ (20, 0) _ (21, 1) _ (22, 2) _ (23, 3) _ (24, 4) _ (25, 5) \
219_ (26, 6) _ (27, 7) _ (28, 8) _ (29, 9) _ (30, 10) _ (31, 11)
220
221#ifdef __ALTIVEC__
222#define CLIB_POWERPC_ALTIVEC_N_REGS 12
223#else
224#define CLIB_POWERPC_ALTIVEC_N_REGS 0
225#endif
226
227_prologue (clib_setjmp)
228 mflr 0
229 std 0, 8*0(3)
230 std 1, 8*1(3)
231 std 2, 8*2(3)
232 mfcr 0
233 std 0, 8*3(3)
234 mfspr 0, 256
235 stw 0, 8*4(3)
236
237 /* gprs 14 - 31 */
238#define _(a,b) std a, 8*((b) + 4 + 18*0)(3) ;
239 _foreach_14_31
240#undef _
241
242 /* fprs 14 - 31 */
243#define _(a,b) stfd a, 8*((b) + 4 + 18*1)(3) ;
244 _foreach_14_31
245#undef _
246
247#if CLIB_POWERPC_ALTIVEC_N_REGS > 0
248 /* vrs 20 - 31 */
249 li 5, 8*(4 + 18*2)
250#define _(a,b) stvx a, 5, 3 ; addi 5, 5, 16 ;
251 _foreach_20_31
252#undef _
253#endif /* CLIB_POWERPC_ALTIVEC_N_REGS > 0 */
254
255 /* Return value. */
256 mr 3, 4
257
258 blr
259
260_prologue (clib_longjmp)
261 ld 0, 8*0(3)
262 mtlr 0
263 ld 1, 8*1(3)
264 ld 2, 8*2(3)
265 ld 0, 8*3(3)
266 mtcrf 0xff, 0
267 lwz 0, 8*3(3)
268 mtspr 256, 0
269
270 /* gprs 14 - 31 */
271#define _(a,b) ld a, 8*((b) + 4 + 18*0)(3) ;
272 _foreach_14_31
273#undef _
274
275 /* fprs 14 - 31 */
276#define _(a,b) lfd a, 8*((b) + 4 + 18*1)(3) ;
277 _foreach_14_31
278#undef _
279
280#if CLIB_POWERPC_ALTIVEC_N_REGS > 0
281 /* vrs 20 - 31 */
282 li 5, 8*(4 + 18*2)
283#define _(a,b) lvx a, 5, 3 ; addi 5, 5, 16 ;
284 _foreach_20_31
285#undef _
286#endif /* CLIB_POWERPC_ALTIVEC_N_REGS > 0 */
287
288 /* Return value. */
289 mr 3, 4
290
291 blr
292
Dave Barachbfdedbd2016-01-20 09:11:55 -0500293 .globl clib_calljmp
294 .section ".opd","aw"
295 .align 3
296clib_calljmp:
297 .quad .L.clib_calljmp,.TOC.@tocbase,0
298 .previous
299 .type clib_calljmp, @function
300.L.clib_calljmp:
Ed Warnickecb9cada2015-12-08 15:45:58 -0700301 mflr 0
Dave Barachbfdedbd2016-01-20 09:11:55 -0500302 mr 9,3
303 std 0,16(1)
304 stdu 1,-112(1)
305#APP
306 std 1,-8(5)
307 addi 5,5,-256
308 mr 1,5
309#NO_APP
310 ld 10,0(9)
311 std 2,40(1)
312 mr 3,4
313 mtctr 10
314 ld 11,16(9)
315 ld 2,8(9)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700316 bctrl
Dave Barachbfdedbd2016-01-20 09:11:55 -0500317 ld 2,40(1)
318#APP
319 addi 1,1,256
320 ld 1,-8(1)
321#NO_APP
322 addi 1,1,112
323 ld 0,16(1)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700324 mtlr 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700325 blr
Dave Barachbfdedbd2016-01-20 09:11:55 -0500326 .long 0
327 .byte 0,0,0,1,128,0,0,0
328 .size clib_calljmp,.-.L.clib_calljmp
Ed Warnickecb9cada2015-12-08 15:45:58 -0700329
330#elif defined(__powerpc__)
331
332#define _foreach_14_31 \
333_ (14, 0) _ (15, 1) _ (16, 2) _ (17, 3) _ (18, 4) _ (19, 5) \
334_ (20, 6) _ (21, 7) _ (22, 8) _ (23, 9) _ (24, 10) _ (25, 11) \
335_ (26, 12) _ (27, 13) _ (28, 14) _ (29, 15) _ (30, 16) _ (31, 17)
336
337#define _foreach_20_31 \
338_ (20, 0) _ (21, 1) _ (22, 2) _ (23, 3) _ (24, 4) _ (25, 5) \
339_ (26, 6) _ (27, 7) _ (28, 8) _ (29, 9) _ (30, 10) _ (31, 11)
340
341#ifdef __ALTIVEC__
342#define CLIB_POWERPC_ALTIVEC_N_REGS 12
343#else
344#define CLIB_POWERPC_ALTIVEC_N_REGS 0
345#endif
346
347 .global clib_setjmp
348 .align 4
349 .type clib_setjmp, @function
350clib_setjmp:
351 mflr 0
352 stw 0, 4*0(3)
353 stw 1, 4*1(3)
354 mfcr 0
355 stw 0, 4*2(3)
356#if CLIB_POWERPC_ALTIVEC_N_REGS > 0
357 mfspr 0, 256
358#endif
359 stw 0, 4*3(3)
360
361#if CLIB_POWERPC_ALTIVEC_N_REGS > 0
362 li 5, 4*4
363#define _(a,b) stvx a, 3, 5 ; addi 5, 5, 16 ;
364 _foreach_20_31
365#undef _
366#endif /* CLIB_POWERPC_ALTIVEC_N_REGS > 0 */
367
368 /* gp 14 - 31 */
369#define _(a,b) stw a, 4*(1*(b) + 4 + 4*CLIB_POWERPC_ALTIVEC_N_REGS + 0*18)(3) ;
370 _foreach_14_31
371#undef _
372
373 /* fp 14 - 31 */
374#define _(a,b) stfd a, 4*(2*(b) + 4 + 4*CLIB_POWERPC_ALTIVEC_N_REGS + 1*18)(3) ;
375 _foreach_14_31
376#undef _
377
378 /* Return value. */
379 mr 3, 4
380
381 blr
382
383 .global clib_longjmp
384 .align 4
385 .type clib_longjmp, @function
386clib_longjmp:
387
388 lwz 0, 4*0(3)
389 mtlr 0
390 lwz 1, 4*1(3)
391 lwz 0, 4*2(3)
392 mtcr 0
393 lwz 0, 4*3(3)
394#if CLIB_POWERPC_ALTIVEC_N_REGS > 0
395 mtspr 256, 0
396#endif
397
398#if CLIB_POWERPC_ALTIVEC_N_REGS > 0
399 li 5, 4*4
400#define _(a,b) lvx a, 3, 5 ; addi 5, 5, 16 ;
401 _foreach_20_31
402#undef _
403#endif /* CLIB_POWERPC_ALTIVEC_N_REGS > 0 */
404
405 /* gp 14 - 31 */
406#define _(a,b) lwz a, 4*(1*(b) + 4 + 4*CLIB_POWERPC_ALTIVEC_N_REGS + 0*18)(3) ;
407 _foreach_14_31
408#undef _
409
410 /* fp 14 - 31 */
411#define _(a,b) lfd a, 4*(2*(b) + 4 + 4*CLIB_POWERPC_ALTIVEC_N_REGS + 1*18)(3) ;
412 _foreach_14_31
413#undef _
414
415 /* Return value. */
416 mr 3, 4
417
418 blr
419
420 .global clib_calljmp
421 .align 4
422 .type clib_calljmp, @function
423clib_calljmp:
424 /* Make sure stack is 16 byte aligned. */
425 andi. 0, 5, 0xf
426 sub 5, 5, 0
427 addi 5, 5, -16
428
429 /* Save old stack/link pointer on new stack. */
430 stw 1, 0(5)
431 mflr 0
432 stw 0, 4(5)
433
434 /* account for (sp, lr) tuple, and keep aligned */
435 addi 5, 5, -16
436
437 /* Switch stacks. */
438 mr 1, 5
439
440 /* Move argument into place. */
441 mtctr 3
442 mr 3, 4
443
444 /* Away we go. */
445 bctrl
446
447 /* back to our synthetic frame */
448 addi 1,1,16
449
450 /* Switch back to old stack. */
451 lwz 0, 4(1)
452 mtlr 0
453 lwz 0, 0(1)
454 mr 1, 0
455
456 /* Return to caller. */
457 blr
458
459#elif defined(__arm__)
460
461 .global clib_setjmp
462 .align 4
463 .type clib_setjmp, %function
464clib_setjmp:
465 mov ip, r0 /* jmp buffer */
466
467 /* Save integer registers */
468 stmia ip!, {v1-v6, sl, fp, sp, lr}
469
470#ifdef __IWMMXT__
471 /* Save the call-preserved iWMMXt registers. */
472 wstrd wr10, [ip], #8
473 wstrd wr11, [ip], #8
474 wstrd wr12, [ip], #8
475 wstrd wr13, [ip], #8
476 wstrd wr14, [ip], #8
477 wstrd wr15, [ip], #8
478#endif
479
480 /* Give back user's return value. */
Christophe Fontainefef15b42016-04-09 12:38:49 +0900481 mov r0, r1
Ed Warnickecb9cada2015-12-08 15:45:58 -0700482 bx lr
483
484 .global clib_longjmp
485 .align 4
486 .type clib_longjmp, %function
487clib_longjmp:
488 mov ip, r0 /* jmp buffer */
489
490 /* Restore integer registers. */
491 ldmia ip!, {v1-v6, sl, fp, sp, lr}
492
493#ifdef __IWMMXT__
494 /* Save the call-preserved iWMMXt registers. */
495 wldrd wr10, [ip], #8
496 wldrd wr11, [ip], #8
497 wldrd wr12, [ip], #8
498 wldrd wr13, [ip], #8
499 wldrd wr14, [ip], #8
500 wldrd wr15, [ip], #8
501#endif
502
503 /* Give back user's return value. */
Christophe Fontainefef15b42016-04-09 12:38:49 +0900504 mov r0, r1
Ed Warnickecb9cada2015-12-08 15:45:58 -0700505 bx lr
506
507 .global clib_calljmp
508 .align 4
509 .type clib_calljmp, %function
510clib_calljmp:
511 /* Make sure stack is 8 byte aligned. */
512 bic r2, r2, #7
513
514 /* Allocate space for stack/link pointer on new stack. */
515 sub r2, r2, #8
516
517 /* Save old stack/link pointer on new stack. */
518 str sp, [r2, #0]
519 str lr, [r2, #4]
520
521 /* Switch stacks. */
522 mov sp, r2
523
524 /* Save function to call. */
525 mov ip, r0
526
527 /* Move argument into place. */
528 mov r0, r1
529
530 /* Away we go. */
531 bx ip
532
533 /* Switch back to old stack. */
534 ldr lr, [sp, #4]
535 ldr ip, [sp, #0]
536 mov sp, ip
537
538 /* Return to caller. */
539 bx lr
540
541#elif defined(__xtensa__)
542
543 /* FIXME implement if needed. */
544 .global clib_setjmp
545 .align 4
546 .type clib_setjmp, %function
547clib_setjmp:
5481: j 1b
549
550 .global clib_longjmp
551 .align 4
552 .type clib_longjmp, @function
553clib_longjmp:
5541: j 1b
555
556 .global clib_calljmp
557 .align 4
558 .type clib_calljmp, %function
559clib_calljmp:
5601: j 1b
561
562#elif defined(__TMS320C6X__)
563
564 /* FIXME implement if needed. */
565 .global clib_setjmp
566 .align 4
567 .type clib_setjmp, %function
568clib_setjmp:
5691: B .S1 1b
570
571 .global clib_longjmp
572 .align 4
573 .type clib_longjmp, @function
574clib_longjmp:
5751: B .S1 1b
576
577 .global clib_calljmp
578 .align 4
579 .type clib_calljmp, %function
580clib_calljmp:
5811: B .S1 1b
582
Carl Smith28d42712018-07-26 15:45:28 +1200583#elif defined(_mips) && __mips == 64
584
585 .global clib_setjmp
586 .align 8
587 .type clib_setjmp, %function
588clib_setjmp:
589 sd $ra, 0($a0)
590 sd $sp, 8($a0)
591 sd $gp, 16($a0)
592 sd $16, 24($a0)
593 sd $17, 32($a0)
594 sd $18, 40($a0)
595 sd $19, 48($a0)
596 sd $20, 56($a0)
597 sd $21, 64($a0)
598 sd $22, 72($a0)
599 sd $23, 80($a0)
600 sd $30, 88($a0)
601 move $v0, $a1
602 jr $ra
603 nop
604
605 .global clib_longjmp
606 .align 8
607 .type clib_longjmp, @function
608clib_longjmp:
609 move $v0, $a1
610 bne $v0, $0, 1f
611 nop
612 daddu $v0, $v0, 1
6131:
614 ld $ra, 0($a0)
615 ld $sp, 8($a0)
616 ld $gp, 16($a0)
617 ld $16, 24($a0)
618 ld $17, 32($a0)
619 ld $18, 40($a0)
620 ld $19, 48($a0)
621 ld $20, 56($a0)
622 ld $21, 64($a0)
623 ld $22, 72($a0)
624 ld $23, 80($a0)
625 ld $30, 88($a0)
626 jr $ra
627 nop
628
629 .global clib_calljmp
630 .align 8
631 .type clib_calljmp, %function
632clib_calljmp:
633 /* Force 16 byte alignment of the new stack */
634 li $t1, -16
635 and $t0, $a2, $t1
636 /* Save old ra/gp/sp on new stack */
637 daddiu $t0, $t0, (-24)
638 sd $ra, 0($t0)
639 sd $gp, 8($t0)
640 sd $sp, 16($t0)
641 /* Switch stacks */
642 move $sp, $t0
643 /* Away we go */
644 move $t9, $a0
645 move $a0, $a1
646 jalr $t9
647 nop
648 /* Switch back to old ra/gp/sp */
649 move $t0, $sp
650 ld $ra, 0($t0)
651 ld $gp, 8($t0)
652 ld $sp, 16($t0)
653 /* Return to caller */
654 jr $ra
655 nop
656
Dave Barach61efa142016-01-22 08:23:09 -0500657#elif defined (__aarch64__)
658/*
659 Copyright (c) 2011, 2012 ARM Ltd
660 All rights reserved.
661 Redistribution and use in source and binary forms, with or without
662 modification, are permitted provided that the following conditions
663 are met:
664 1. Redistributions of source code must retain the above copyright
665 notice, this list of conditions and the following disclaimer.
666 2. Redistributions in binary form must reproduce the above copyright
667 notice, this list of conditions and the following disclaimer in the
668 documentation and/or other materials provided with the distribution.
669 3. The name of the company may not be used to endorse or promote
670 products derived from this software without specific prior written
671 permission.
672 THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
673 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
674 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
675 IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
676 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
677 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
678 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
679 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
680 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
681 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
682 */
683#define GPR_LAYOUT \
684 REG_PAIR (x19, x20, 0); \
685 REG_PAIR (x21, x22, 16); \
686 REG_PAIR (x23, x24, 32); \
687 REG_PAIR (x25, x26, 48); \
688 REG_PAIR (x27, x28, 64); \
689 REG_PAIR (x29, x30, 80); \
690 REG_ONE (x16, 96)
691#define FPR_LAYOUT \
692 REG_PAIR ( d8, d9, 112); \
693 REG_PAIR (d10, d11, 128); \
694 REG_PAIR (d12, d13, 144); \
695 REG_PAIR (d14, d15, 160);
696// int clib_setjmp (jmp_buf)
697 .global clib_setjmp
698 .type clib_setjmp, %function
699clib_setjmp:
700 mov x16, sp
701#define REG_PAIR(REG1, REG2, OFFS) stp REG1, REG2, [x0, OFFS]
702#define REG_ONE(REG1, OFFS) str REG1, [x0, OFFS]
703 GPR_LAYOUT
704 FPR_LAYOUT
705#undef REG_PAIR
706#undef REG_ONE
707 mov x0, x1
708 ret
709 .size clib_setjmp, .-clib_setjmp
710// void clib_longjmp (jmp_buf, int) __attribute__ ((noreturn))
711 .global clib_longjmp
712 .type clib_longjmp, %function
713clib_longjmp:
714#define REG_PAIR(REG1, REG2, OFFS) ldp REG1, REG2, [x0, OFFS]
715#define REG_ONE(REG1, OFFS) ldr REG1, [x0, OFFS]
716 GPR_LAYOUT
717 FPR_LAYOUT
718#undef REG_PAIR
719#undef REG_ONE
720 mov sp, x16
721 mov x0, x1
722 // cmp w1, #0
723 // cinc w0, w1, eq
724 // use br not ret, as ret is guaranteed to mispredict
725 br x30
726 .size clib_longjmp, .-clib_longjmp
727
728
729// void clib_calljmp (x0=function, x1=arg, x2=new_stack)
730 .global clib_calljmp
731 .type clib_calljmp, %function
732clib_calljmp:
733 // save fn ptr
734 mov x3, x0
735 // set up fn arg
736 mov x0, x1
737 // switch stacks
738 mov x4, sp
739
740 // space for saved sp, lr on new stack
741 sub x2, x2, #16
742 mov sp, x2
743
744 // save old sp and link register on new stack
745 str x4, [sp]
746 str x30,[sp,#8]
747 mov x4, sp
748
749 // go there
750 blr x3
751
752 // restore old sp and link register
753 mov x4, sp
754
755 ldr x3, [x4]
756 ldr x30,[x4, #8]
757 mov sp, x3
758 ret
759 .size clib_calljmp, .-clib_calljmp
Ed Warnickecb9cada2015-12-08 15:45:58 -0700760#else
761#error "unknown machine"
762#endif
763
764.section .note.GNU-stack,"",%progbits