api: API trace improvements
[vpp.git] / src / vppinfra / longjmp.S
index d4dd4c7..a3435cc 100644 (file)
   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
-       
+
+#if defined(__APPLE__)
+# define cdecl(s) _##s
+#else
+# define cdecl(s) s
+#endif
+
 #if defined(__x86_64__)
-       .global clib_setjmp
+       .global cdecl(clib_setjmp)
        .align 4
-       .type clib_setjmp, @function
-clib_setjmp:
+#ifndef __APPLE__
+       .type cdecl(clib_setjmp), @function
+#endif
+
+cdecl(clib_setjmp):
        movq %rbx, 8*0(%rdi)
        movq %rbp, 8*1(%rdi)
        movq %r12, 8*2(%rdi)
@@ -50,19 +59,21 @@ clib_setjmp:
        /* Save SP after return. */
        leaq 8(%rsp), %rdx
        movq %rdx, 8*6(%rdi)
-       
+
        /* Save PC we are returning to from stack frame. */
        movq 0(%rsp), %rax
        movq %rax, 8*7(%rdi)
-       
+
        /* Give back user's return value. */
        movq %rsi, %rax
        ret
-       
-       .global clib_longjmp
+
+       .global cdecl(clib_longjmp)
        .align 4
-       .type clib_longjmp, @function
-clib_longjmp:  
+#ifndef __APPLE__
+       .type cdecl(clib_longjmp), @function
+#endif
+cdecl(clib_longjmp):
         /* Restore regs. */
        movq 8*0(%rdi), %rbx
        movq 8*1(%rdi), %rbp
@@ -72,58 +83,60 @@ clib_longjmp:
        movq 8*5(%rdi), %r15
        movq 8*6(%rdi), %rsp
        movq 8*7(%rdi), %rdx
-       
+
        /* Give back user's return value. */
        movq %rsi, %rax
-       
+
        /* Away we go. */
-       jmpq *%rdx      
-       
-       .global clib_calljmp
+       jmpq *%rdx
+
+       .global cdecl(clib_calljmp)
        .align 4
-       .type clib_calljmp, @function
-clib_calljmp:
+#ifndef __APPLE__
+       .type cdecl(clib_calljmp), @function
+#endif
+cdecl(clib_calljmp):
        /* Make sure stack is 16-byte aligned. */
        movq %rdx, %rax
        andq $0xf, %rax
        subq %rax, %rdx
-       
+
        /* Get return address. */
        pop %rax
-       
+
        /* Switch to new stack. */
        xchgq %rsp, %rdx
-       
+
        /* Save return address on new stack. */
        push %rax
-       
+
        /* Save old stack pointer on new stack. */
        push %rdx
-       
+
        /* Get function. */
        movq %rdi, %rdx
-       
+
        /* Move argument into place. */
        movq %rsi, %rdi
-       
+
        /* Away we go. */
        callq *%rdx
-       
+
        /* Switch back to old stack. */
        movq 8(%rsp), %rdx
        movq 0(%rsp), %rcx
        xchgq %rcx, %rsp
-       
+
        /* Return to caller. */
        jmpq *%rdx
 
 #elif defined(i386)
-       .global clib_setjmp
+       .global cdecl(clib_setjmp)
        .align 4
-       .type clib_setjmp, @function
-clib_setjmp:
+       .type cdecl(clib_setjmp), @function
+cdecl(clib_setjmp):
        movl 4(%esp), %ecx
-       
+
        movl %ebp, 4*0(%ecx)
        movl %ebx, 4*1(%ecx)
        movl %edi, 4*2(%ecx)
@@ -132,24 +145,24 @@ clib_setjmp:
        /* Save SP after return. */
        leal 4(%esp), %edx
        movl %edx, 4*4(%ecx)
-       
+
        /* Save PC we are returning to from stack frame. */
        movl 0(%esp), %eax
        movl %eax, 4*5(%ecx)
-       
+
        /* Give back user's return value. */
        movl 8(%esp), %eax
        ret
-       
-       .global clib_longjmp
+
+       .global cdecl(clib_longjmp)
        .align 4
-       .type clib_longjmp, @function
-clib_longjmp:  
+       .type cdecl(clib_longjmp), @function
+cdecl(clib_longjmp):
        movl 4(%esp), %ecx
-       
+
        /* Give back user's return value. */
        movl 8(%esp), %eax
-       
+
         /* Restore regs. */
        movl 4*0(%ecx), %ebp
        movl 4*1(%ecx), %ebx
@@ -157,57 +170,44 @@ clib_longjmp:
        movl 4*3(%ecx), %esi
        movl 4*4(%ecx), %esp
        movl 4*5(%ecx), %edx
-       
+
        /* Away we go. */
-       jmp *%edx       
-       
-       .global clib_calljmp
+       jmp *%edx
+
+       .global cdecl(clib_calljmp)
        .align 4
-       .type clib_calljmp, @function
-clib_calljmp:  
+       .type cdecl(clib_calljmp), @function
+cdecl(clib_calljmp):
        /* Get new stack pointer. */
        movl 12(%esp), %edx
-       
+
        /* Switch stacks. */
        xchgl %esp, %edx
-       
+
        /* Save old stack pointer on new stack. */
        sub $8, %esp
        movl %edx, 4(%esp)
-       
+
        /* Put function argument in stack frame. */
        movl 8(%edx), %eax
        movl %eax, 0(%esp)
-       
+
        /* Get function. */
        movl 4(%edx), %eax
-       
+
        /* Away we go. */
        call *%eax
-       
+
        /* Switch back to old stack. */
        movl 4(%esp), %edx
        xchgl %edx, %esp
-       
+
        /* Return to caller. */
        ret
-       
+
 #elif defined(__SPU__)
-       
-#elif defined(__powerpc64__)
-       
-       .text
 
-#define _prologue(n)                           \
-    .align 2 ;                                 \
-    .globl n, .##n ;                           \
-    .section ".opd", "aw" ;                    \
-    .align 3 ;                                 \
-n:  .quad .##n, .TOC.@tocbase, 0 ;             \
-    .previous ;                                        \
-    .size n, 24 ;                              \
-    .type .##n, @function ;                    \
-.##n:
+#elif defined(__powerpc64__)
 
 #define _foreach_14_31                                                 \
 _ (14, 0)  _ (15, 1)  _ (16, 2)  _ (17, 3)  _ (18, 4)  _ (19, 5)       \
@@ -217,14 +217,60 @@ _ (26, 12) _ (27, 13) _ (28, 14) _ (29, 15) _ (30, 16) _ (31, 17)
 #define _foreach_20_31                                         \
 _ (20, 0) _ (21, 1) _ (22, 2) _ (23, 3) _ (24, 4)  _ (25, 5)   \
 _ (26, 6) _ (27, 7) _ (28, 8) _ (29, 9) _ (30, 10) _ (31, 11)
-       
+
 #ifdef __ALTIVEC__
 #define CLIB_POWERPC_ALTIVEC_N_REGS 12
 #else
 #define CLIB_POWERPC_ALTIVEC_N_REGS 0
 #endif
 
-_prologue (clib_setjmp)
+#if _CALL_ELF == 2
+
+#define _prologue(n)                           \
+       .globl n ;                              \
+       .p2align 4 ;                            \
+       .type n, @function ;                    \
+n: ;                                           \
+.L##n##_begin: ;
+
+#define _gep_lep(n)                            \
+.L##n##_gep: ;                                 \
+       addis 2, 12, .TOC.-.L##n##_gep@ha ;     \
+       addi 2, 2, .TOC.-.L##n##_gep@l ;        \
+.L##n##_lep: ;                                 \
+       .localentry n, .L##n##_lep-.L##n##_gep
+
+#else /* _CALL_ELF == 1 */
+
+#define _prologue(n)                           \
+    .globl n ;                                 \
+    .p2align 4 ;                               \
+    .type .##n, @function ;                    \
+    .section ".opd", "aw" ,@progbits ;         \
+n: ;                                           \
+    .p2align 3 ;                               \
+    .quad .L##n##_begin ;                      \
+    .quad .TOC.@tocbase ;                      \
+    .quad 0 ;                                  \
+    .text ;                                    \
+.L##n##_begin: ;
+
+#endif
+
+#define _epilogue(n)                           \
+       .long   0 ;                             \
+       .quad   0 ;                             \
+.L##n##_end: ;                                 \
+       .size   n, .L##n##_end-.L##n##_begin
+
+#if _CALL_ELF == 2
+       .abiversion 2
+       .section        ".text"
+#else
+       .text
+#endif
+
+_prologue(clib_setjmp)
        mflr 0
        std 0, 8*0(3)
        std 1, 8*1(3)
@@ -233,14 +279,14 @@ _prologue (clib_setjmp)
        std 0, 8*3(3)
        mfspr 0, 256
        stw 0, 8*4(3)
-       
+
        /* gprs 14 - 31 */
-#define _(a,b) std a, 8*((b) + 4 + 18*0)(3) ; 
+#define _(a,b) std a, 8*((b) + 4 + 18*0)(3) ;
        _foreach_14_31
 #undef _
-       
+
        /* fprs 14 - 31 */
-#define _(a,b) stfd a, 8*((b) + 4 + 18*1)(3) ; 
+#define _(a,b) stfd a, 8*((b) + 4 + 18*1)(3) ;
        _foreach_14_31
 #undef _
 
@@ -251,13 +297,13 @@ _prologue (clib_setjmp)
        _foreach_20_31
 #undef _
 #endif /* CLIB_POWERPC_ALTIVEC_N_REGS > 0 */
-       
+
        /* Return value. */
        mr 3, 4
-       
        blr
-       
-_prologue (clib_longjmp)
+_epilogue(clib_setjmp)
+
+_prologue(clib_longjmp)
        ld 0, 8*0(3)
        mtlr 0
        ld 1, 8*1(3)
@@ -266,17 +312,17 @@ _prologue (clib_longjmp)
        mtcrf 0xff, 0
        lwz 0, 8*3(3)
        mtspr 256, 0
-       
+
        /* gprs 14 - 31 */
-#define _(a,b) ld a, 8*((b) + 4 + 18*0)(3) ; 
+#define _(a,b) ld a, 8*((b) + 4 + 18*0)(3) ;
        _foreach_14_31
 #undef _
-       
+
        /* fprs 14 - 31 */
-#define _(a,b) lfd a, 8*((b) + 4 + 18*1)(3) ; 
+#define _(a,b) lfd a, 8*((b) + 4 + 18*1)(3) ;
        _foreach_14_31
 #undef _
-       
+
 #if CLIB_POWERPC_ALTIVEC_N_REGS > 0
        /* vrs 20 - 31 */
        li 5, 8*(4 + 18*2)
@@ -284,51 +330,64 @@ _prologue (clib_longjmp)
        _foreach_20_31
 #undef _
 #endif /* CLIB_POWERPC_ALTIVEC_N_REGS > 0 */
-       
+
        /* Return value. */
        mr 3, 4
-       
        blr
+_epilogue(clib_longjmp)
 
-       .globl clib_calljmp
-       .section        ".opd","aw"
-       .align 3
-clib_calljmp:
-       .quad   .L.clib_calljmp,.TOC.@tocbase,0
-       .previous
-       .type   clib_calljmp, @function
-.L.clib_calljmp:
-       mflr 0
-       mr 9,3
-       std 0,16(1)
-       stdu 1,-112(1)
-#APP
-       std 1,-8(5)
-       addi 5,5,-256
-       mr 1,5
-#NO_APP
+#if _CALL_ELF == 2
+_prologue(clib_calljmp)
+_gep_lep(clib_calljmp)
+       mflr 0                  /* get link register into r0 */
+       std 0,16(1)             /* store r0 into the stack frame */
+       stdu 1,-32(1)           /* move sp down for one frame */
+       mr 12,3                 /* move func pointer to r12 */
+       mr 3,4                  /* pass func_arg as first arg */
+       std 1,-8(5)             /* store old sp into the top of the new stack */
+       addi 5,5,-256           /* stack_addr =- 256 */
+       mr 1,5                  /* set new sp */
+       mtctr 12                /* put function pointer into CTR register */
+       std 2,24(1)             /* store TOC pointer into stack frame */
+       bctrl                   /* unconditional branch to counter register */
+       ld 2,24(1)              /* load TOC pointer from stack frame */
+       addi 1,1,256            /* go back to the start of the new stack */
+       ld 1,-8(1)              /* load old sp */
+       addi 1,1,32             /* move sp back to previous frame */
+       ld 0,16(1)              /* get old link reg value from the stack */
+       mtlr 0                  /* restore link reg value */
+       blr
+_epilogue(clib_calljmp)
+
+#else /* v1 ABI */
+
+_prologue(clib_calljmp)
+       mflr 0                  /* get link register into r0 */
+       mr 9,3                  /* store function pointer into the r9 */
+       std 0,16(1)             /* store r0 into the stack frame */
+       stdu 1,-112(1)          /* move sp down for one frame */
+       std 1,-8(5)             /* store old sp into the top of the new stack */
+       addi 5,5,-256           /* stack_addr =- 256 */
+       mr 1,5                  /* set new sp */
        ld 10,0(9)
-       std 2,40(1)
+       std 2,40(1)             /* store TOC pointer into the stack */
        mr 3,4
        mtctr 10
        ld 11,16(9)
        ld 2,8(9)
-       bctrl
-       ld 2,40(1)
-#APP
-       addi 1,1,256
-       ld 1,-8(1)
-#NO_APP
-       addi 1,1,112
-       ld 0,16(1)
+       bctrl                   /* unconditional branch to counter register */
+       ld 2,40(1)              /* load TOC pointer from the stack */
+       addi 1,1,256            /* go back to the start of the new stack */
+       ld 1,-8(1)              /* load the old sp */
+       addi 1,1,112            /* move sp back to previous frame */
+       ld 0,16(1)              /* restore link register from the stack frame */
        mtlr 0
        blr
-       .long 0
-       .byte 0,0,0,1,128,0,0,0
-       .size   clib_calljmp,.-.L.clib_calljmp
-       
+_epilogue(clib_calljmp)
+
+#endif
 #elif defined(__powerpc__)
-       
+
 #define _foreach_14_31                                                 \
 _ (14, 0)  _ (15, 1)  _ (16, 2)  _ (17, 3)  _ (18, 4)  _ (19, 5)       \
 _ (20, 6)  _ (21, 7)  _ (22, 8)  _ (23, 9)  _ (24, 10) _ (25, 11)      \
@@ -337,17 +396,17 @@ _ (26, 12) _ (27, 13) _ (28, 14) _ (29, 15) _ (30, 16) _ (31, 17)
 #define _foreach_20_31                                         \
 _ (20, 0) _ (21, 1) _ (22, 2) _ (23, 3) _ (24, 4)  _ (25, 5)   \
 _ (26, 6) _ (27, 7) _ (28, 8) _ (29, 9) _ (30, 10) _ (31, 11)
-       
+
 #ifdef __ALTIVEC__
 #define CLIB_POWERPC_ALTIVEC_N_REGS 12
 #else
 #define CLIB_POWERPC_ALTIVEC_N_REGS 0
 #endif
 
-       .global clib_setjmp
+       .global cdecl(clib_setjmp)
        .align 4
-       .type clib_setjmp, @function
-clib_setjmp:
+       .type cdecl(clib_setjmp), @function
+cdecl(clib_setjmp):
        mflr 0
        stw 0, 4*0(3)
        stw 1, 4*1(3)
@@ -357,19 +416,19 @@ clib_setjmp:
        mfspr 0, 256
 #endif
        stw 0, 4*3(3)
-       
+
 #if CLIB_POWERPC_ALTIVEC_N_REGS > 0
        li 5, 4*4
 #define _(a,b) stvx a, 3, 5 ; addi 5, 5, 16 ;
        _foreach_20_31
 #undef _
 #endif /* CLIB_POWERPC_ALTIVEC_N_REGS > 0 */
-       
+
        /* gp 14 - 31 */
-#define _(a,b) stw a,  4*(1*(b) + 4 + 4*CLIB_POWERPC_ALTIVEC_N_REGS + 0*18)(3) ; 
+#define _(a,b) stw a,  4*(1*(b) + 4 + 4*CLIB_POWERPC_ALTIVEC_N_REGS + 0*18)(3) ;
        _foreach_14_31
 #undef _
-       
+
        /* fp 14 - 31 */
 #define _(a,b) stfd a, 4*(2*(b) + 4 + 4*CLIB_POWERPC_ALTIVEC_N_REGS + 1*18)(3) ;
        _foreach_14_31
@@ -377,14 +436,14 @@ clib_setjmp:
 
        /* Return value. */
        mr 3, 4
-       
+
        blr
-       
-       .global clib_longjmp
+
+       .global cdecl(clib_longjmp)
        .align 4
-       .type clib_longjmp, @function
-clib_longjmp:  
-       
+       .type cdecl(clib_longjmp), @function
+cdecl(clib_longjmp):
+
        lwz 0, 4*0(3)
        mtlr 0
        lwz 1, 4*1(3)
@@ -394,19 +453,19 @@ clib_longjmp:
 #if CLIB_POWERPC_ALTIVEC_N_REGS > 0
        mtspr 256, 0
 #endif
-       
+
 #if CLIB_POWERPC_ALTIVEC_N_REGS > 0
        li 5, 4*4
 #define _(a,b) lvx a, 3, 5 ; addi 5, 5, 16 ;
        _foreach_20_31
 #undef _
 #endif /* CLIB_POWERPC_ALTIVEC_N_REGS > 0 */
-       
+
        /* gp 14 - 31 */
 #define _(a,b) lwz a, 4*(1*(b) + 4 + 4*CLIB_POWERPC_ALTIVEC_N_REGS + 0*18)(3) ;
        _foreach_14_31
 #undef _
-       
+
        /* fp 14 - 31 */
 #define _(a,b) lfd a, 4*(2*(b) + 4 + 4*CLIB_POWERPC_ALTIVEC_N_REGS + 1*18)(3) ;
        _foreach_14_31
@@ -414,59 +473,59 @@ clib_longjmp:
 
        /* Return value. */
        mr 3, 4
-       
+
        blr
 
-       .global clib_calljmp
+       .global cdecl(clib_calljmp)
        .align 4
-       .type clib_calljmp, @function
-clib_calljmp:  
+       .type cdecl(clib_calljmp), @function
+cdecl(clib_calljmp):
        /* Make sure stack is 16 byte aligned. */
        andi. 0, 5, 0xf
        sub  5, 5, 0
        addi 5, 5, -16
-       
+
        /* Save old stack/link pointer on new stack. */
        stw 1, 0(5)
        mflr 0
        stw 0, 4(5)
-       
+
        /* account for (sp, lr) tuple, and keep aligned */
        addi 5, 5, -16
-       
+
        /* Switch stacks. */
        mr 1, 5
-       
+
        /* Move argument into place. */
        mtctr 3
        mr 3, 4
-       
+
        /* Away we go. */
        bctrl
-       
+
        /* back to our synthetic frame */
        addi 1,1,16
-       
+
        /* Switch back to old stack. */
        lwz 0, 4(1)
        mtlr 0
        lwz 0, 0(1)
        mr 1, 0
-       
+
        /* Return to caller. */
        blr
-       
+
 #elif defined(__arm__)
-       
-       .global clib_setjmp
+
+       .global cdecl(clib_setjmp)
        .align 4
-       .type clib_setjmp, %function
-clib_setjmp:
+       .type cdecl(clib_setjmp), %function
+cdecl(clib_setjmp):
        mov ip, r0              /* jmp buffer */
 
        /* Save integer registers */
        stmia ip!, {v1-v6, sl, fp, sp, lr}
-       
+
 #ifdef __IWMMXT__
        /* Save the call-preserved iWMMXt registers.  */
        wstrd wr10, [ip], #8
@@ -480,16 +539,16 @@ clib_setjmp:
        /* Give back user's return value. */
        mov r0, r1
        bx lr
-       
-       .global clib_longjmp
+
+       .global cdecl(clib_longjmp)
        .align 4
-       .type clib_longjmp, %function
-clib_longjmp:  
+       .type cdecl(clib_longjmp), %function
+cdecl(clib_longjmp):
        mov ip, r0              /* jmp buffer */
 
        /* Restore integer registers. */
        ldmia     ip!,  {v1-v6, sl, fp, sp, lr}
-       
+
 #ifdef __IWMMXT__
        /* Save the call-preserved iWMMXt registers.  */
        wldrd wr10, [ip], #8
@@ -499,87 +558,161 @@ clib_longjmp:
        wldrd wr14, [ip], #8
        wldrd wr15, [ip], #8
 #endif
-       
+
        /* Give back user's return value. */
        mov r0, r1
        bx lr
 
-       .global clib_calljmp
+       .global cdecl(clib_calljmp)
        .align 4
-       .type clib_calljmp, %function
-clib_calljmp:  
+       .type cdecl(clib_calljmp), %function
+cdecl(clib_calljmp):
        /* Make sure stack is 8 byte aligned. */
        bic r2, r2, #7
-       
+
        /* Allocate space for stack/link pointer on new stack. */
-       sub r2, r2, #8  
-       
+       sub r2, r2, #8
+
        /* Save old stack/link pointer on new stack. */
        str sp, [r2, #0]
        str lr, [r2, #4]
-       
+
        /* Switch stacks. */
        mov sp, r2
-       
+
        /* Save function to call. */
        mov ip, r0
-       
+
        /* Move argument into place. */
        mov r0, r1
-       
+
        /* Away we go. */
        bx ip
-       
+
        /* Switch back to old stack. */
        ldr lr, [sp, #4]
        ldr ip, [sp, #0]
        mov sp, ip
-       
+
        /* Return to caller. */
        bx lr
-       
+
 #elif defined(__xtensa__)
-       
+
        /* FIXME implement if needed. */
-       .global clib_setjmp
+       .global cdecl(clib_setjmp)
        .align 4
-       .type clib_setjmp, %function
-clib_setjmp:
+       .type cdecl(clib_setjmp), %function
+cdecl(clib_setjmp):
 1:     j 1b
 
-       .global clib_longjmp
+       .global cdecl(clib_longjmp)
        .align 4
-       .type clib_longjmp, @function
-clib_longjmp:  
+       .type cdecl(clib_longjmp), @function
+cdecl(clib_longjmp):
 1:     j 1b
-       
-       .global clib_calljmp
+
+       .global cdecl(clib_calljmp)
        .align 4
-       .type clib_calljmp, %function
-clib_calljmp:  
+       .type cdecl(clib_calljmp), %function
+cdecl(clib_calljmp):
 1:     j 1b
-       
+
 #elif defined(__TMS320C6X__)
-       
+
        /* FIXME implement if needed. */
-       .global clib_setjmp
+       .global cdecl(clib_setjmp)
        .align 4
-       .type clib_setjmp, %function
-clib_setjmp:
+       .type cdecl(clib_setjmp), %function
+cdecl(clib_setjmp):
 1:     B       .S1     1b
 
-       .global clib_longjmp
+       .global cdecl(clib_longjmp)
        .align 4
-       .type clib_longjmp, @function
-clib_longjmp:  
+       .type cdecl(clib_longjmp), @function
+cdecl(clib_longjmp):
 1:     B       .S1     1b
-       
-       .global clib_calljmp
+
+       .global cdecl(clib_calljmp)
        .align 4
-       .type clib_calljmp, %function
-clib_calljmp:  
+       .type cdecl(clib_calljmp), %function
+cdecl(clib_calljmp):
 1:     B       .S1     1b
-       
+
+#elif defined(_mips) && __mips == 64
+
+       .global cdecl(clib_setjmp)
+       .align 8
+       .type cdecl(clib_setjmp), %function
+cdecl(clib_setjmp):
+       sd $ra, 0($a0)
+       sd $sp, 8($a0)
+       sd $gp, 16($a0)
+       sd $16, 24($a0)
+       sd $17, 32($a0)
+       sd $18, 40($a0)
+       sd $19, 48($a0)
+       sd $20, 56($a0)
+       sd $21, 64($a0)
+       sd $22, 72($a0)
+       sd $23, 80($a0)
+       sd $30, 88($a0)
+       move $v0, $a1
+       jr $ra
+       nop
+
+       .global cdecl(clib_longjmp)
+       .align 8
+       .type cdecl(clib_longjmp), @function
+cdecl(clib_longjmp):
+       move $v0, $a1
+       bne $v0, $0, 1f
+       nop
+       daddu $v0, $v0, 1
+1:
+       ld $ra, 0($a0)
+       ld $sp, 8($a0)
+       ld $gp, 16($a0)
+       ld $16, 24($a0)
+       ld $17, 32($a0)
+       ld $18, 40($a0)
+       ld $19, 48($a0)
+       ld $20, 56($a0)
+       ld $21, 64($a0)
+       ld $22, 72($a0)
+       ld $23, 80($a0)
+       ld $30, 88($a0)
+       jr $ra
+       nop
+
+       .global cdecl(clib_calljmp)
+       .align 8
+       .type cdecl(clib_calljmp), %function
+cdecl(clib_calljmp):
+       /* Force 16 byte alignment of the new stack */
+       li $t1, -16
+       and $t0, $a2, $t1
+       /* Save old ra/gp/sp on new stack */
+       daddiu $t0, $t0, (-24)
+       sd $ra, 0($t0)
+       sd $gp, 8($t0)
+       sd $sp, 16($t0)
+       /* Switch stacks */
+       move $sp, $t0
+       /* Away we go */
+       move $t9, $a0
+       move $a0, $a1
+       jalr $t9
+       nop
+       /* Switch back to old ra/gp/sp */
+       move $t0, $sp
+       ld $ra, 0($t0)
+       ld $gp, 8($t0)
+       ld $sp, 16($t0)
+       /* Return to caller */
+       jr $ra
+       nop
+
 #elif defined (__aarch64__)
 /*
    Copyright (c) 2011, 2012 ARM Ltd
@@ -619,10 +752,10 @@ clib_calljmp:
        REG_PAIR (d10, d11, 128);       \
        REG_PAIR (d12, d13, 144);       \
        REG_PAIR (d14, d15, 160);
-// int clib_setjmp (jmp_buf)
-       .global clib_setjmp
-       .type   clib_setjmp, %function
-clib_setjmp:
+// int cdecl(clib_setjmp) (jmp_buf)
+       .global cdecl(clib_setjmp)
+       .type   cdecl(clib_setjmp), %function
+cdecl(clib_setjmp):
        mov     x16, sp
 #define REG_PAIR(REG1, REG2, OFFS)     stp REG1, REG2, [x0, OFFS]
 #define REG_ONE(REG1, OFFS)            str REG1, [x0, OFFS]
@@ -632,11 +765,11 @@ clib_setjmp:
 #undef REG_ONE
        mov     x0, x1
        ret
-       .size   clib_setjmp, .-clib_setjmp
-// void clib_longjmp (jmp_buf, int) __attribute__ ((noreturn))
-       .global clib_longjmp
-       .type   clib_longjmp, %function
-clib_longjmp:
+       .size   cdecl(clib_setjmp), .-cdecl(clib_setjmp)
+// void cdecl(clib_longjmp) (jmp_buf, int) __attribute__ ((noreturn))
+       .global cdecl(clib_longjmp)
+       .type   cdecl(clib_longjmp), %function
+cdecl(clib_longjmp):
 #define REG_PAIR(REG1, REG2, OFFS)     ldp REG1, REG2, [x0, OFFS]
 #define REG_ONE(REG1, OFFS)            ldr REG1, [x0, OFFS]
        GPR_LAYOUT
@@ -649,24 +782,24 @@ clib_longjmp:
        // cinc w0, w1, eq
        // use br not ret, as ret is guaranteed to mispredict
        br      x30
-       .size   clib_longjmp, .-clib_longjmp
+       .size   cdecl(clib_longjmp), .-cdecl(clib_longjmp)
 
 
-// void clib_calljmp (x0=function, x1=arg, x2=new_stack)
-       .global clib_calljmp
-       .type   clib_calljmp, %function
-clib_calljmp:
+// void cdecl(clib_calljmp) (x0=function, x1=arg, x2=new_stack)
+       .global cdecl(clib_calljmp)
+       .type   cdecl(clib_calljmp), %function
+cdecl(clib_calljmp):
        // save fn ptr
        mov     x3, x0
        // set up fn arg
        mov     x0, x1
        // switch stacks
        mov     x4, sp
-       
+
        // space for saved sp, lr on new stack
        sub     x2, x2, #16
        mov     sp, x2
-       
+
        // save old sp and link register on new stack
         str     x4, [sp]
        str     x30,[sp,#8]
@@ -674,17 +807,19 @@ clib_calljmp:
 
        // go there
         blr     x3
-       
+
        // restore old sp and link register
        mov     x4, sp
-        
+
        ldr     x3, [x4]
        ldr     x30,[x4, #8]
         mov     sp, x3
        ret
-       .size   clib_calljmp, .-clib_calljmp
+       .size   cdecl(clib_calljmp), .-cdecl(clib_calljmp)
 #else
 #error "unknown machine"
-#endif 
+#endif
 
+#ifndef __APPLE__
 .section .note.GNU-stack,"",%progbits
+#endif