aarch64 CPU arch / ThunderX platform initial support
[vpp.git] / vppinfra / vppinfra / longjmp.S
index ac138a9..9ba237d 100644 (file)
@@ -580,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