dpdk: Add support for Mellanox ConnectX-4 devices
[vpp.git] / vppinfra / vppinfra / longjmp.S
index a469b64..d4dd4c7 100644 (file)
@@ -290,38 +290,42 @@ _prologue (clib_longjmp)
        
        blr
 
-_prologue (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. */
-       std 1, 0(5)
+       .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
-       std 0, 8(5)
-       
-       /* Switch stacks. */
-       mr 1, 5
-       
-       /* Get function pointer. */
-       ld 0, 0(3)
-       mtctr 0
-       
-       /* Move argument into place. */
-       mr 3, 4
-       
-       /* Away we go. */
+       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
+       ld 10,0(9)
+       std 2,40(1)
+       mr 3,4
+       mtctr 10
+       ld 11,16(9)
+       ld 2,8(9)
        bctrl
-       
-       /* Switch back to old stack. */
-       ld 0, 8(1)
+       ld 2,40(1)
+#APP
+       addi 1,1,256
+       ld 1,-8(1)
+#NO_APP
+       addi 1,1,112
+       ld 0,16(1)
        mtlr 0
-       ld 0, 0(1)
-       mr 1, 0
-       
-       /* Return to caller. */
        blr
+       .long 0
+       .byte 0,0,0,1,128,0,0,0
+       .size   clib_calljmp,.-.L.clib_calljmp
        
 #elif defined(__powerpc__)
        
@@ -474,7 +478,7 @@ clib_setjmp:
 #endif
 
        /* Give back user's return value. */
-       mov r1, r0
+       mov r0, r1
        bx lr
        
        .global clib_longjmp
@@ -497,7 +501,7 @@ clib_longjmp:
 #endif
        
        /* Give back user's return value. */
-       mov r1, r0
+       mov r0, r1
        bx lr
 
        .global clib_calljmp
@@ -576,6 +580,109 @@ clib_longjmp:
 clib_calljmp:  
 1:     B       .S1     1b
        
+#elif defined (__aarch64__)
+/*
+   Copyright (c) 2011, 2012 ARM Ltd
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   1. Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+   3. The name of the company may not be used to endorse or promote
+      products derived from this software without specific prior written
+      permission.
+   THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
+   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+   IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#define GPR_LAYOUT                     \
+       REG_PAIR (x19, x20,  0);        \
+       REG_PAIR (x21, x22, 16);        \
+       REG_PAIR (x23, x24, 32);        \
+       REG_PAIR (x25, x26, 48);        \
+       REG_PAIR (x27, x28, 64);        \
+       REG_PAIR (x29, x30, 80);        \
+       REG_ONE (x16,      96)
+#define FPR_LAYOUT                     \
+       REG_PAIR ( d8,  d9, 112);       \
+       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:
+       mov     x16, sp
+#define REG_PAIR(REG1, REG2, OFFS)     stp REG1, REG2, [x0, OFFS]
+#define REG_ONE(REG1, OFFS)            str REG1, [x0, OFFS]
+       GPR_LAYOUT
+       FPR_LAYOUT
+#undef REG_PAIR
+#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:
+#define REG_PAIR(REG1, REG2, OFFS)     ldp REG1, REG2, [x0, OFFS]
+#define REG_ONE(REG1, OFFS)            ldr REG1, [x0, OFFS]
+       GPR_LAYOUT
+       FPR_LAYOUT
+#undef REG_PAIR
+#undef REG_ONE
+       mov     sp, x16
+       mov     x0, x1
+       // cmp  w1, #0
+       // cinc w0, w1, eq
+       // use br not ret, as ret is guaranteed to mispredict
+       br      x30
+       .size   clib_longjmp, .-clib_longjmp
+
+
+// void clib_calljmp (x0=function, x1=arg, x2=new_stack)
+       .global clib_calljmp
+       .type   clib_calljmp, %function
+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]
+        mov     x4, sp
+
+       // 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
 #else
 #error "unknown machine"
 #endif