vppinfra: remove trailing whitespace in longjmp.S
[vpp.git] / src / vppinfra / longjmp.S
1 /*
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(__APPLE__)
39 # define cdecl(s) _##s
40 #else
41 # define cdecl(s) s
42 #endif
43
44 #if defined(__x86_64__)
45         .global cdecl(clib_setjmp)
46         .align 4
47 #ifndef __APPLE__
48         .type cdecl(clib_setjmp), @function
49 #endif
50
51 cdecl(clib_setjmp):
52         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
71         .global cdecl(clib_longjmp)
72         .align 4
73 #ifndef __APPLE__
74         .type cdecl(clib_longjmp), @function
75 #endif
76 cdecl(clib_longjmp):
77         /* 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
93         .global cdecl(clib_calljmp)
94         .align 4
95 #ifndef __APPLE__
96         .type cdecl(clib_calljmp), @function
97 #endif
98 cdecl(clib_calljmp):
99         /* 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)
134         .global cdecl(clib_setjmp)
135         .align 4
136         .type cdecl(clib_setjmp), @function
137 cdecl(clib_setjmp):
138         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
157         .global cdecl(clib_longjmp)
158         .align 4
159         .type cdecl(clib_longjmp), @function
160 cdecl(clib_longjmp):
161         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
177         .global cdecl(clib_calljmp)
178         .align 4
179         .type cdecl(clib_calljmp), @function
180 cdecl(clib_calljmp):
181         /* 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 ;                                  \
219 n:  .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
240 _prologue (cdecl(clib_setjmp))
241         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
273 _prologue (cdecl(clib_longjmp))
274         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
306         .globl cdecl(clib_calljmp)
307         .section        ".opd","aw"
308         .align 3
309 cdecl(clib_calljmp):
310         .quad   .L.cdecl(clib_calljmp),.TOC.@tocbase,0
311         .previous
312         .type   cdecl(clib_calljmp), @function
313 .L.cdecl(clib_calljmp):
314         mflr 0
315         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)
329         bctrl
330         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)
337         mtlr 0
338         blr
339         .long 0
340         .byte 0,0,0,1,128,0,0,0
341         .size   cdecl(clib_calljmp),.-.L.cdecl(clib_calljmp)
342
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
360         .global cdecl(clib_setjmp)
361         .align 4
362         .type cdecl(clib_setjmp), @function
363 cdecl(clib_setjmp):
364         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
396         .global cdecl(clib_longjmp)
397         .align 4
398         .type cdecl(clib_longjmp), @function
399 cdecl(clib_longjmp):
400
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
433         .global cdecl(clib_calljmp)
434         .align 4
435         .type cdecl(clib_calljmp), @function
436 cdecl(clib_calljmp):
437         /* 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
474         .global cdecl(clib_setjmp)
475         .align 4
476         .type cdecl(clib_setjmp), %function
477 cdecl(clib_setjmp):
478         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. */
494         mov r0, r1
495         bx lr
496
497         .global cdecl(clib_longjmp)
498         .align 4
499         .type cdecl(clib_longjmp), %function
500 cdecl(clib_longjmp):
501         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. */
517         mov r0, r1
518         bx lr
519
520         .global cdecl(clib_calljmp)
521         .align 4
522         .type cdecl(clib_calljmp), %function
523 cdecl(clib_calljmp):
524         /* 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. */
557         .global cdecl(clib_setjmp)
558         .align 4
559         .type cdecl(clib_setjmp), %function
560 cdecl(clib_setjmp):
561 1:      j 1b
562
563         .global cdecl(clib_longjmp)
564         .align 4
565         .type cdecl(clib_longjmp), @function
566 cdecl(clib_longjmp):
567 1:      j 1b
568
569         .global cdecl(clib_calljmp)
570         .align 4
571         .type cdecl(clib_calljmp), %function
572 cdecl(clib_calljmp):
573 1:      j 1b
574
575 #elif defined(__TMS320C6X__)
576
577         /* FIXME implement if needed. */
578         .global cdecl(clib_setjmp)
579         .align 4
580         .type cdecl(clib_setjmp), %function
581 cdecl(clib_setjmp):
582 1:      B       .S1     1b
583
584         .global cdecl(clib_longjmp)
585         .align 4
586         .type cdecl(clib_longjmp), @function
587 cdecl(clib_longjmp):
588 1:      B       .S1     1b
589
590         .global cdecl(clib_calljmp)
591         .align 4
592         .type cdecl(clib_calljmp), %function
593 cdecl(clib_calljmp):
594 1:      B       .S1     1b
595
596 #elif defined(_mips) && __mips == 64
597
598         .global cdecl(clib_setjmp)
599         .align 8
600         .type cdecl(clib_setjmp), %function
601 cdecl(clib_setjmp):
602         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
618         .global cdecl(clib_longjmp)
619         .align 8
620         .type cdecl(clib_longjmp), @function
621 cdecl(clib_longjmp):
622         move $v0, $a1
623         bne $v0, $0, 1f
624         nop
625         daddu $v0, $v0, 1
626 1:
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
642         .global cdecl(clib_calljmp)
643         .align 8
644         .type cdecl(clib_calljmp), %function
645 cdecl(clib_calljmp):
646         /* 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
670 #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);
709 // int cdecl(clib_setjmp) (jmp_buf)
710         .global cdecl(clib_setjmp)
711         .type   cdecl(clib_setjmp), %function
712 cdecl(clib_setjmp):
713         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
722         .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
726 cdecl(clib_longjmp):
727 #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
739         .size   cdecl(clib_longjmp), .-cdecl(clib_longjmp)
740
741
742 // void cdecl(clib_calljmp) (x0=function, x1=arg, x2=new_stack)
743         .global cdecl(clib_calljmp)
744         .type   cdecl(clib_calljmp), %function
745 cdecl(clib_calljmp):
746         // 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
772         .size   cdecl(clib_calljmp), .-cdecl(clib_calljmp)
773 #else
774 #error "unknown machine"
775 #endif
776
777 #ifndef __APPLE__
778 .section .note.GNU-stack,"",%progbits
779 #endif