diff options
Diffstat (limited to 'libc/sysdeps/linux/xtensa')
-rw-r--r-- | libc/sysdeps/linux/xtensa/__longjmp.S | 17 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/setjmp.h | 9 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/clone.S | 21 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/crt1.S | 30 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/crti.S | 15 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/crtn.S | 17 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/mmap.S | 2 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/setjmp.S | 17 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/syscall.S | 4 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/sysdep.h | 45 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/vfork.S | 23 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/windowspill.S | 3 |
12 files changed, 188 insertions, 15 deletions
diff --git a/libc/sysdeps/linux/xtensa/__longjmp.S b/libc/sysdeps/linux/xtensa/__longjmp.S index 4d55906db..acc0b4ff2 100644 --- a/libc/sysdeps/linux/xtensa/__longjmp.S +++ b/libc/sysdeps/linux/xtensa/__longjmp.S @@ -48,6 +48,7 @@ ENTRY (__longjmp) +#if defined(__XTENSA_WINDOWED_ABI__) /* Invalidate all but the current window. Reading and writing special registers WINDOWBASE and WINDOWSTART are privileged operations, so user processes must call the @@ -120,6 +121,22 @@ ENTRY (__longjmp) movnez a2, a3, a3 retw +#elif defined(__XTENSA_CALL0_ABI__) + l32i a0, a2, 0 + l32i a1, a2, 4 + l32i a12, a2, 8 + l32i a13, a2, 12 + l32i a14, a2, 16 + l32i a15, a2, 20 + + /* Return v ? v : 1. */ + movi a2, 1 + movnez a2, a3, a3 + + ret +#else +#error Unsupported Xtensa ABI +#endif END (__longjmp) libc_hidden_def (__longjmp) diff --git a/libc/sysdeps/linux/xtensa/bits/setjmp.h b/libc/sysdeps/linux/xtensa/bits/setjmp.h index 183fa3e64..5d3e5509e 100644 --- a/libc/sysdeps/linux/xtensa/bits/setjmp.h +++ b/libc/sysdeps/linux/xtensa/bits/setjmp.h @@ -23,6 +23,7 @@ # error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead." #endif +#if defined(__XTENSA_WINDOWED_ABI__) /* The jmp_buf structure for Xtensa holds the following (where "proc" is the procedure that calls setjmp): 4-12 registers from the window of proc, the 4 words from the save area at proc's $sp (in case a @@ -30,5 +31,13 @@ proc. Everything else is saved on the stack in the normal save areas. */ typedef int __jmp_buf[17]; +#elif defined(__XTENSA_CALL0_ABI__) +/* The jmp_buf structure for Xtensa Call0 ABI holds the return address, + the stack pointer and callee-saved registers (a12 - a15). */ + +typedef int __jmp_buf[6]; +#else +#error Unsupported Xtensa ABI +#endif #endif /* bits/setjmp.h */ diff --git a/libc/sysdeps/linux/xtensa/clone.S b/libc/sysdeps/linux/xtensa/clone.S index 34d68a875..88cd6c1c3 100644 --- a/libc/sysdeps/linux/xtensa/clone.S +++ b/libc/sysdeps/linux/xtensa/clone.S @@ -51,7 +51,7 @@ ENTRY (__clone) mov a8, a6 /* use a8 as a temp */ mov a6, a4 mov a4, a8 - l32i a8, a1, 16 /* child_tid */ + l32i a8, a1, FRAMESIZE /* child_tid */ movi a2, SYS_ify(clone) /* syscall(NR_clone,clone_flags, usp, parent_tid, child_tls, child_tid) @@ -65,7 +65,7 @@ ENTRY (__clone) /* fall through for parent */ .Lpseudo_end: - retw + abi_ret .Leinval: movi a2, -EINVAL @@ -94,17 +94,26 @@ ENTRY (__clone) /* start child thread */ movi a0, 0 /* terminate the stack frame */ + +#if defined(__XTENSA_WINDOWED_ABI__) mov a6, a9 /* load up the 'arg' parameter */ callx4 a7 /* call the user's function */ /* Call _exit. Note that any return parameter from the user's function in a6 is seen as inputs to _exit. */ -#ifdef PIC - movi a2, _exit@PLT + movi a2, JUMPTARGET(_exit) + callx4 a2 +#elif defined(__XTENSA_CALL0_ABI__) + mov a2, a9 /* load up the 'arg' parameter */ + callx0 a7 /* call the user's function */ + + /* Call _exit. Note that any return parameter from the user's + function in a2 is seen as inputs to _exit. */ + movi a0, JUMPTARGET(_exit) + callx0 a0 #else - movi a2, _exit +#error Unsupported Xtensa ABI #endif - callx4 a2 PSEUDO_END (__clone) diff --git a/libc/sysdeps/linux/xtensa/crt1.S b/libc/sysdeps/linux/xtensa/crt1.S index 025ebd070..efbe264c0 100644 --- a/libc/sysdeps/linux/xtensa/crt1.S +++ b/libc/sysdeps/linux/xtensa/crt1.S @@ -76,6 +76,7 @@ .global _start .type _start, @function _start: +#if defined(__XTENSA_WINDOWED_ABI__) /* Clear a0 to obviously mark the outermost frame. */ movi a0, 0 @@ -104,6 +105,35 @@ _start: But let the libc call main. */ movi a4, __uClibc_main callx4 a4 +#elif defined(__XTENSA_CALL0_ABI__) + /* Setup the shared library termination function. */ + mov a7, a2 + + /* Load up the user's main function. */ + movi a2, main + + /* Extract the arguments as encoded on the stack and set up + the arguments for `main': argc, argv. envp will be determined + later in __uClibc_main. */ + l32i a3, a1, 0 /* Load the argument count. */ + addi a4, a1, 4 /* Compute the argv pointer. */ + + /* Push address of our own entry points to .fini and .init. */ + movi a5, _init + movi a6, _fini + + /* Provide the highest stack address to the user code (for stacks + which grow downwards). Note that we destroy the stack version + of argc here. */ + s32i a1, a1, 0 + + /* Call the user's main function, and exit with its value. + But let the libc call main. */ + movi a0, __uClibc_main + callx0 a0 +#else +#error Unsupported Xtensa ABI +#endif /* Crash if somehow `exit' does return. */ ill diff --git a/libc/sysdeps/linux/xtensa/crti.S b/libc/sysdeps/linux/xtensa/crti.S index a01c02c9f..ba804eb45 100644 --- a/libc/sysdeps/linux/xtensa/crti.S +++ b/libc/sysdeps/linux/xtensa/crti.S @@ -5,12 +5,25 @@ .global _init .type _init, @function _init: +#if defined(__XTENSA_WINDOWED_ABI__) entry sp, 48 - +#elif defined(__XTENSA_CALL0_ABI__) + addi sp, sp, -16 + s32i a0, sp, 0 +#else +#error Unsupported Xtensa ABI +#endif .section .fini .align 4 .global _fini .type _fini, @function _fini: +#if defined(__XTENSA_WINDOWED_ABI__) entry sp, 48 +#elif defined(__XTENSA_CALL0_ABI__) + addi sp, sp, -16 + s32i a0, sp, 0 +#else +#error Unsupported Xtensa ABI +#endif diff --git a/libc/sysdeps/linux/xtensa/crtn.S b/libc/sysdeps/linux/xtensa/crtn.S index ab1a489c5..a3598da1a 100644 --- a/libc/sysdeps/linux/xtensa/crtn.S +++ b/libc/sysdeps/linux/xtensa/crtn.S @@ -1,8 +1,23 @@ /* glibc's sysdeps/xtensa/elf/initfini.c used for reference [EPILOG] */ .section .init +#if defined(__XTENSA_WINDOWED_ABI__) retw - +#elif defined(__XTENSA_CALL0_ABI__) + l32i a0, sp, 0 + addi sp, sp, 16 + ret +#else +#error Unsupported Xtensa ABI +#endif .section .fini +#if defined(__XTENSA_WINDOWED_ABI__) retw +#elif defined(__XTENSA_CALL0_ABI__) + l32i a0, sp, 0 + addi sp, sp, 16 + ret +#else +#error Unsupported Xtensa ABI +#endif diff --git a/libc/sysdeps/linux/xtensa/mmap.S b/libc/sysdeps/linux/xtensa/mmap.S index c05036aae..b4dd7c53b 100644 --- a/libc/sysdeps/linux/xtensa/mmap.S +++ b/libc/sysdeps/linux/xtensa/mmap.S @@ -48,7 +48,7 @@ ENTRY (__mmap) bltz a2, SYSCALL_ERROR_LABEL .Lpseudo_end: - retw + abi_ret PSEUDO_END (__mmap) diff --git a/libc/sysdeps/linux/xtensa/setjmp.S b/libc/sysdeps/linux/xtensa/setjmp.S index bf4691294..862bf6729 100644 --- a/libc/sysdeps/linux/xtensa/setjmp.S +++ b/libc/sysdeps/linux/xtensa/setjmp.S @@ -88,6 +88,7 @@ END (setjmp) ENTRY (__sigsetjmp) 1: +#if defined(__XTENSA_WINDOWED_ABI__) /* Flush registers. */ movi a4, __window_spill callx4 a4 @@ -146,6 +147,22 @@ ENTRY (__sigsetjmp) callx4 a3 mov a2, a6 retw +#elif defined(__XTENSA_CALL0_ABI__) + s32i a0, a2, 0 + s32i a1, a2, 4 + s32i a12, a2, 8 + s32i a13, a2, 12 + s32i a14, a2, 16 + s32i a15, a2, 20 + mov a12, a2 + movi a0, __sigjmp_save + callx0 a0 + l32i a0, a12, 0 + l32i a12, a12, 8 + ret +#else +#error Unsupported Xtensa ABI +#endif END(__sigsetjmp) weak_extern(_setjmp) diff --git a/libc/sysdeps/linux/xtensa/syscall.S b/libc/sysdeps/linux/xtensa/syscall.S index 0e1a5d0be..790a8d018 100644 --- a/libc/sysdeps/linux/xtensa/syscall.S +++ b/libc/sysdeps/linux/xtensa/syscall.S @@ -26,7 +26,7 @@ */ ENTRY (syscall) - l32i a9, a1, 16 /* load extra argument from stack */ + l32i a9, a1, FRAMESIZE/* load extra argument from stack */ mov a8, a7 mov a7, a3 /* preserve a3 in a7 */ mov a3, a4 @@ -37,5 +37,5 @@ ENTRY (syscall) movi a4, -4095 bgeu a2, a4, SYSCALL_ERROR_LABEL .Lpseudo_end: - retw + abi_ret PSEUDO_END (syscall) diff --git a/libc/sysdeps/linux/xtensa/sysdep.h b/libc/sysdeps/linux/xtensa/sysdep.h index 4873a413d..ce2b0a0d6 100644 --- a/libc/sysdeps/linux/xtensa/sysdep.h +++ b/libc/sysdeps/linux/xtensa/sysdep.h @@ -28,13 +28,24 @@ #define ASM_TYPE_DIRECTIVE(name, typearg) .type name, typearg #define ASM_SIZE_DIRECTIVE(name) .size name, . - name +#if defined(__XTENSA_WINDOWED_ABI__) +#define abi_entry(reg, frame_size) entry reg, frame_size +#define abi_ret retw +#elif defined(__XTENSA_CALL0_ABI__) +#define abi_entry(reg, frame_size) +#define abi_ret ret +#else +#error Unsupported Xtensa ABI +#endif + + #define ENTRY(name) \ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), @function); \ .align ALIGNARG(2); \ LITERAL_POSITION; \ C_LABEL(name) \ - entry sp, FRAMESIZE; \ + abi_entry(sp, FRAMESIZE); \ CALL_MCOUNT #define HIDDEN_ENTRY(name) \ @@ -44,7 +55,7 @@ .align ALIGNARG(2); \ LITERAL_POSITION; \ C_LABEL(name) \ - entry sp, FRAMESIZE; \ + abi_entry(sp, FRAMESIZE); \ CALL_MCOUNT #undef END @@ -73,7 +84,13 @@ #endif #ifndef FRAMESIZE +#if defined(__XTENSA_WINDOWED_ABI__) #define FRAMESIZE 16 +#elif defined(__XTENSA_CALL0_ABI__) +#define FRAMESIZE 0 +#else +#error Unsupported Xtensa ABI +#endif #endif #define CALL_MCOUNT /* Do nothing. */ @@ -118,7 +135,7 @@ END (name) #undef ret_NOERRNO -#define ret_NOERRNO retw +#define ret_NOERRNO abi_ret /* The function has to return the error code. */ #undef PSEUDO_ERRVAL @@ -133,7 +150,7 @@ END (name) #undef ret_ERRVAL -#define ret_ERRVAL retw +#define ret_ERRVAL abi_ret #if defined _LIBC_REENTRANT # if defined USE___THREAD @@ -151,6 +168,8 @@ movi a2, -1; \ j .Lpseudo_end; # else /* !USE___THREAD */ + +#if defined(__XTENSA_WINDOWED_ABI__) # define SYSCALL_ERROR_HANDLER \ 0: neg a2, a2; \ mov a6, a2; \ @@ -159,6 +178,24 @@ s32i a2, a6, 0; \ movi a2, -1; \ j .Lpseudo_end; +#elif defined(__XTENSA_CALL0_ABI__) +# define SYSCALL_ERROR_HANDLER \ +0: neg a2, a2; \ + addi a1, a1, -16; \ + s32i a0, a1, 0; \ + s32i a2, a1, 4; \ + movi a0, __errno_location@PLT; \ + callx0 a0; \ + l32i a0, a1, 0; \ + l32i a3, a1, 4; \ + addi a1, a1, 16; \ + s32i a3, a2, 0; \ + movi a2, -1; \ + j .Lpseudo_end; +#else +#error Unsupported Xtensa ABI +#endif + # endif /* !USE___THREAD */ #else /* !_LIBC_REENTRANT */ #define SYSCALL_ERROR_HANDLER \ diff --git a/libc/sysdeps/linux/xtensa/vfork.S b/libc/sysdeps/linux/xtensa/vfork.S index 6aced0a50..b8db5c1a1 100644 --- a/libc/sysdeps/linux/xtensa/vfork.S +++ b/libc/sysdeps/linux/xtensa/vfork.S @@ -51,6 +51,8 @@ HIDDEN_ENTRY (__vfork) + +#if defined(__XTENSA_WINDOWED_ABI__) .literal .Ljumptable, 0, .L4, .L8, .L12 mov a3, a0 # move return address out of the way @@ -163,6 +165,27 @@ HIDDEN_ENTRY (__vfork) PSEUDO_END (__vfork) .Lpseudo_end: retw +#elif defined(__XTENSA_CALL0_ABI__) + SAVE_PID(a5, a8, a3, a4) + + /* Use syscall 'clone'. Set new stack pointer to the same address. */ + movi a2, SYS_ify (clone) + movi a3, 0 + movi a6, CLONE_VM | CLONE_VFORK | SIGCHLD + syscall + + RESTORE_PID(a5, a8, a2) + + movi a3, -4096 + bgeu a2, a3, 1f + ret +1: + PSEUDO_END (__vfork) +.Lpseudo_end: + ret +#else +#error Unsupported Xtensa ABI +#endif weak_alias (__vfork, vfork) libc_hidden_def(vfork) diff --git a/libc/sysdeps/linux/xtensa/windowspill.S b/libc/sysdeps/linux/xtensa/windowspill.S index 4167b2877..013025648 100644 --- a/libc/sysdeps/linux/xtensa/windowspill.S +++ b/libc/sysdeps/linux/xtensa/windowspill.S @@ -18,6 +18,7 @@ #include <bits/xtensa-config.h> +#ifdef __XTENSA_WINDOWED_ABI__ .text .align 4 .literal_position @@ -93,3 +94,5 @@ __window_spill: #endif #endif retw + +#endif |