diff options
25 files changed, 388 insertions, 91 deletions
diff --git a/ldso/ldso/xtensa/dl-startup.h b/ldso/ldso/xtensa/dl-startup.h index 8fe54a3c7..aece0cd96 100644 --- a/ldso/ldso/xtensa/dl-startup.h +++ b/ldso/ldso/xtensa/dl-startup.h @@ -23,6 +23,7 @@ __asm__ ( " .align 4\n" "0: movi a3, _start+3\n" " sub a2, a0, a3\n" +#if defined(__XTENSA_WINDOWED_ABI__) " # Make sure a0 is cleared to mark the top of stack.\n" " movi a0, 0\n" " # user_entry_point = _dl_start(pointer to argument block)\n" @@ -32,6 +33,17 @@ __asm__ ( " callx4 a4\n" " # Save user_entry_point so we can jump to it.\n" " mov a3, a6\n" +#elif defined(__XTENSA_CALL0_ABI__) + " # user_entry_point = _dl_start(pointer to argument block)\n" + " movi a0, _dl_start\n" + " add a0, a0, a2\n" + " mov a2, sp\n" + " callx0 a0\n" + " # Save user_entry_point so we can jump to it.\n" + " mov a3, a2\n" +#else +#error Unsupported Xtensa ABI +#endif " l32i a7, sp, 0 # load argc\n" " # Load _dl_skip_args into a4.\n" " movi a4, _dl_skip_args\n" diff --git a/ldso/ldso/xtensa/dl-tlsdesc.S b/ldso/ldso/xtensa/dl-tlsdesc.S index 0638af439..6f417f61a 100644 --- a/ldso/ldso/xtensa/dl-tlsdesc.S +++ b/ldso/ldso/xtensa/dl-tlsdesc.S @@ -23,16 +23,11 @@ #include "tlsdesc.h" .text - .align 4 - .hidden _dl_tlsdesc_return - .global _dl_tlsdesc_return - .type _dl_tlsdesc_return, @function -_dl_tlsdesc_return: - entry a1, 16 +HIDDEN_ENTRY (_dl_tlsdesc_return) rur.threadptr a3 add a2, a2, a3 - retw - .size _dl_tlsdesc_return, .-_dl_tlsdesc_return + abi_ret +END (_dl_tlsdesc_return) #ifdef SHARED @@ -57,12 +52,7 @@ _dl_tlsdesc_return: } */ - .align 4 - .hidden _dl_tlsdesc_dynamic - .global _dl_tlsdesc_dynamic - .type _dl_tlsdesc_dynamic, @function -_dl_tlsdesc_dynamic: - entry a1, 32 +HIDDEN_ENTRY (_dl_tlsdesc_dynamic) /* dtv_t *dtv = (dtv_t *)THREAD_DTV(); */ rur.threadptr a3 @@ -83,16 +73,31 @@ _dl_tlsdesc_dynamic: + td->tlsinfo.ti_offset - __builtin_thread_pointer(); */ l32i a6, a2, TLSDESC_MODOFF sub a2, a6, a3 - retw + abi_ret /* return __tls_get_addr (&td->tlsinfo) - __builtin_thread_pointer(); */ .Lslow: - mov a10, a2 - movi a8, __tls_get_addr - callx8 a8 - sub a2, a10, a3 +#if defined(__XTENSA_WINDOWED_ABI__) + mov a6, a2 + movi a4, __tls_get_addr + callx4 a4 + sub a2, a6, a3 retw - .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic +#elif defined(__XTENSA_CALL0_ABI__) + addi a1, a1, -16 + s32i a0, a1, 0 + s32i a3, a1, 4 + movi a0, __tls_get_addr + callx0 a0 + l32i a3, a1, 4 + l32i a0, a1, 0 + sub a2, a2, a3 + addi a1, a1, 16 + ret +#else +#error Unsupported Xtensa ABI +#endif +END (_dl_tlsdesc_dynamic) #endif /* SHARED */ #endif diff --git a/ldso/ldso/xtensa/resolve.S b/ldso/ldso/xtensa/resolve.S index 8061af247..12a554de7 100644 --- a/ldso/ldso/xtensa/resolve.S +++ b/ldso/ldso/xtensa/resolve.S @@ -31,6 +31,7 @@ .global _dl_linux_resolve .type _dl_linux_resolve, @function _dl_linux_resolve: +#if defined(__XTENSA_WINDOWED_ABI__) /* Call the fixup function. */ movi a8, _dl_linux_resolver callx8 a8 @@ -47,4 +48,38 @@ _dl_linux_resolve: /* Jump to the next instruction past the ENTRY. */ addi a10, a10, 3 jx a10 +#elif defined(__XTENSA_CALL0_ABI__) + /* Reserve stack space and save incoming arguments. */ + addi a1, a1, -32 + s32i a0, a1, 0 + s32i a2, a1, 8 + s32i a3, a1, 12 + s32i a4, a1, 16 + s32i a5, a1, 20 + s32i a6, a1, 24 + s32i a7, a1, 28 + + /* Move arguments for the _dl_linux_resolver to proper registers. */ + mov a2, a10 + mov a3, a11 + /* Call the fixup function. */ + movi a0, _dl_linux_resolver + callx0 a0 + mov a10, a2 + + /* Restore incoming arguments from stack and deallocate reservation. */ + l32i a0, a1, 0 + l32i a2, a1, 8 + l32i a3, a1, 12 + l32i a4, a1, 16 + l32i a5, a1, 20 + l32i a6, a1, 24 + l32i a7, a1, 28 + addi a1, a1, 32 + + /* Jump to the target function. */ + jx a10 +#else +#error Unsupported Xtensa ABI +#endif .size _dl_linux_resolve, . - _dl_linux_resolve diff --git a/libc/string/xtensa/memcpy.S b/libc/string/xtensa/memcpy.S index 2b23b4113..244205611 100644 --- a/libc/string/xtensa/memcpy.S +++ b/libc/string/xtensa/memcpy.S @@ -91,7 +91,7 @@ __memcpy_aux: #if !XCHAL_HAVE_LOOPS blt a3, a7, 1b #endif -2: retw +2: abi_ret /* Destination is unaligned. */ @@ -181,7 +181,7 @@ ENTRY (memcpy) 3: bbsi.l a4, 2, 4f bbsi.l a4, 1, 5f bbsi.l a4, 0, 6f - retw + abi_ret /* Copy 4 bytes. */ 4: l32i a6, a3, 0 @@ -190,7 +190,7 @@ ENTRY (memcpy) addi a5, a5, 4 bbsi.l a4, 1, 5f bbsi.l a4, 0, 6f - retw + abi_ret /* Copy 2 bytes. */ 5: l16ui a6, a3, 0 @@ -198,14 +198,14 @@ ENTRY (memcpy) s16i a6, a5, 0 addi a5, a5, 2 bbsi.l a4, 0, 6f - retw + abi_ret /* Copy 1 byte. */ 6: l8ui a6, a3, 0 s8i a6, a5, 0 .Ldone: - retw + abi_ret /* Destination is aligned; source is unaligned. */ @@ -276,7 +276,7 @@ ENTRY (memcpy) #endif bbsi.l a4, 1, 5f bbsi.l a4, 0, 6f - retw + abi_ret /* Copy 2 bytes. */ 5: l8ui a6, a3, 0 @@ -286,11 +286,11 @@ ENTRY (memcpy) s8i a7, a5, 1 addi a5, a5, 2 bbsi.l a4, 0, 6f - retw + abi_ret /* Copy 1 byte. */ 6: l8ui a6, a3, 0 s8i a6, a5, 0 - retw + abi_ret libc_hidden_def (memcpy) diff --git a/libc/string/xtensa/memset.S b/libc/string/xtensa/memset.S index 435d6dea0..20bf14c75 100644 --- a/libc/string/xtensa/memset.S +++ b/libc/string/xtensa/memset.S @@ -63,7 +63,7 @@ __memset_aux: #if !XCHAL_HAVE_LOOPS blt a5, a6, 1b #endif -2: retw +2: abi_ret /* Destination is unaligned. */ @@ -159,6 +159,6 @@ ENTRY (memset) /* Set 1 byte. */ s8i a3, a5, 0 -6: retw +6: abi_ret libc_hidden_def (memset) diff --git a/libc/string/xtensa/strcmp.S b/libc/string/xtensa/strcmp.S index 8ed1ed009..2dce590db 100644 --- a/libc/string/xtensa/strcmp.S +++ b/libc/string/xtensa/strcmp.S @@ -108,7 +108,7 @@ ENTRY (strcmp) #endif .Lretdiff: sub a2, a8, a9 - retw + abi_ret /* s1 is word-aligned; s2 is word-aligned. @@ -229,7 +229,7 @@ ENTRY (strcmp) /* Words are equal; some byte is zero. */ .Leq: movi a2, 0 /* return equal */ - retw + abi_ret .Lwne2: /* Words are not equal. On big-endian processors, if none of the bytes are zero, the return value can be determined by a simple @@ -239,10 +239,10 @@ ENTRY (strcmp) bnall a10, a7, .Lsomezero bgeu a8, a9, .Lposreturn movi a2, -1 - retw + abi_ret .Lposreturn: movi a2, 1 - retw + abi_ret .Lsomezero: /* There is probably some zero byte. */ #endif /* __XTENSA_EB__ */ .Lwne: /* Words are not equal. */ @@ -263,14 +263,14 @@ ENTRY (strcmp) byte. Just subtract words to get the return value. The high order equal bytes cancel, leaving room for the sign. */ sub a2, a8, a9 - retw + abi_ret .Ldiff0: /* Need to make room for the sign, so can't subtract whole words. */ extui a10, a8, 24, 8 extui a11, a9, 24, 8 sub a2, a10, a11 - retw + abi_ret #else /* !__XTENSA_EB__ */ /* Little-endian is a little more difficult because can't subtract @@ -281,28 +281,28 @@ ENTRY (strcmp) extui a10, a8, 24, 8 extui a11, a9, 24, 8 sub a2, a10, a11 - retw + abi_ret .Ldiff0: /* Byte 0 is different. */ extui a10, a8, 0, 8 extui a11, a9, 0, 8 sub a2, a10, a11 - retw + abi_ret .Ldiff1: /* Byte 0 is equal; byte 1 is different. */ extui a10, a8, 8, 8 extui a11, a9, 8, 8 sub a2, a10, a11 - retw + abi_ret .Ldiff2: /* Bytes 0-1 are equal; byte 2 is different. */ extui a10, a8, 16, 8 extui a11, a9, 16, 8 sub a2, a10, a11 - retw + abi_ret #endif /* !__XTENSA_EB */ diff --git a/libc/string/xtensa/strcpy.S b/libc/string/xtensa/strcpy.S index f9f586896..9f42b34e6 100644 --- a/libc/string/xtensa/strcpy.S +++ b/libc/string/xtensa/strcpy.S @@ -68,7 +68,7 @@ ENTRY (strcpy) s8i a8, a10, 1 /* store byte 0 */ addi a10, a10, 2 /* advance dst pointer */ bnez a8, .Lsrcaligned -1: retw +1: abi_ret /* dst is word-aligned; src is word-aligned. */ @@ -102,21 +102,21 @@ ENTRY (strcpy) #endif /* !XCHAL_HAVE_LOOPS */ .Lz3: /* Byte 3 is zero. */ - retw + abi_ret .Lz0: /* Byte 0 is zero. */ #ifdef __XTENSA_EB__ movi a8, 0 #endif s8i a8, a10, 0 - retw + abi_ret .Lz1: /* Byte 1 is zero. */ #ifdef __XTENSA_EB__ extui a8, a8, 16, 16 #endif s16i a8, a10, 0 - retw + abi_ret .Lz2: /* Byte 2 is zero. */ #ifdef __XTENSA_EB__ @@ -125,7 +125,7 @@ ENTRY (strcpy) s16i a8, a10, 0 movi a8, 0 s8i a8, a10, 2 - retw + abi_ret .align 4 /* (2 mod 4) alignment for loop instruction */ @@ -144,6 +144,6 @@ ENTRY (strcpy) #else bnez a8, 1b #endif -2: retw +2: abi_ret libc_hidden_def (strcpy) diff --git a/libc/string/xtensa/strlen.S b/libc/string/xtensa/strlen.S index 86fe11390..e1c98c8f0 100644 --- a/libc/string/xtensa/strlen.S +++ b/libc/string/xtensa/strlen.S @@ -59,7 +59,7 @@ ENTRY (strlen) /* Byte 3 is zero. */ addi a3, a3, 3 /* point to zero byte */ sub a2, a3, a2 /* subtract to get length */ - retw + abi_ret /* String is word-aligned. */ @@ -88,16 +88,16 @@ ENTRY (strlen) .Lz0: /* Byte 0 is zero. */ sub a2, a3, a2 /* subtract to get length */ - retw + abi_ret .Lz1: /* Byte 1 is zero. */ addi a3, a3, 1 /* point to zero byte */ sub a2, a3, a2 /* subtract to get length */ - retw + abi_ret .Lz2: /* Byte 2 is zero. */ addi a3, a3, 2 /* point to zero byte */ sub a2, a3, a2 /* subtract to get length */ - retw + abi_ret libc_hidden_def (strlen) diff --git a/libc/string/xtensa/strncpy.S b/libc/string/xtensa/strncpy.S index 115d44cf8..aa8db5da1 100644 --- a/libc/string/xtensa/strncpy.S +++ b/libc/string/xtensa/strncpy.S @@ -67,7 +67,7 @@ __strncpy_aux: j .Lfill .Lret: - retw + abi_ret ENTRY (strncpy) @@ -129,7 +129,7 @@ ENTRY (strncpy) addi a10, a10, 1 bnez a4, .Lfillcleanup -2: retw +2: abi_ret .Lfill1mod2: /* dst address is odd */ s8i a9, a10, 0 /* store byte 0 */ @@ -235,6 +235,6 @@ ENTRY (strncpy) #endif 2: j .Lfill -3: retw +3: abi_ret libc_hidden_def (strncpy) 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 diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/sysdep-cancel.h index f82957d15..02fe27869 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/sysdep-cancel.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/sysdep-cancel.h @@ -25,6 +25,7 @@ #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt +#if defined(__XTENSA_WINDOWED_ABI__) /* CENABLE/CDISABLE in PSEUDO below use call8, stack frame size must be * at least 32. */ @@ -58,6 +59,64 @@ j SYSCALL_ERROR_LABEL; \ .Lpseudo_end: +# define CENABLE movi a8, CENABLE_FUNC; \ + callx8 a8 +# define CDISABLE movi a8, CDISABLE_FUNC; \ + callx8 a8 +#elif defined(__XTENSA_CALL0_ABI__) + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args) \ + .text; \ + ENTRY (name) \ + SINGLE_THREAD_P(a10); \ + bnez a10, .Lpseudo_cancel; \ + DO_CALL (syscall_name, args); \ + bgez a2, .Lpseudo_done; \ + movi a4, -4095; \ + blt a2, a4, .Lpseudo_done; \ + j SYSCALL_ERROR_LABEL; \ + .Lpseudo_done: \ + ret; \ + .Lpseudo_cancel: \ + addi a1, a1, -32; \ + /* The syscall args are in a2...a7; save them */ \ + s32i a0, a1, 0; \ + s32i a2, a1, 4; \ + s32i a3, a1, 8; \ + s32i a4, a1, 12; \ + s32i a5, a1, 16; \ + s32i a6, a1, 20; \ + s32i a7, a1, 24; \ + CENABLE; \ + /* Move return value to a10 preserved across the syscall */ \ + mov a10, a2; \ + l32i a2, a1, 4; \ + l32i a3, a1, 8; \ + l32i a4, a1, 12; \ + l32i a5, a1, 16; \ + l32i a6, a1, 20; \ + l32i a7, a1, 24; \ + DO_CALL (syscall_name, args); \ + s32i a2, a1, 4; \ + mov a2, a10; \ + CDISABLE; \ + l32i a2, a1, 4; \ + l32i a0, a1, 0; \ + addi a1, a1, 32; \ + bgez a2, .Lpseudo_end; \ + movi a4, -4095; \ + blt a2, a4, .Lpseudo_end; \ + j SYSCALL_ERROR_LABEL; \ + .Lpseudo_end: + +# define CENABLE movi a0, CENABLE_FUNC; \ + callx0 a0 +# define CDISABLE movi a0, CDISABLE_FUNC; \ + callx0 a0 +#else +#error Unsupported Xtensa ABI +#endif # ifdef IS_IN_libpthread # define CENABLE_FUNC __pthread_enable_asynccancel @@ -74,11 +133,6 @@ # error Unsupported library # endif -# define CENABLE movi a8, CENABLE_FUNC; \ - callx8 a8 -# define CDISABLE movi a8, CDISABLE_FUNC; \ - callx8 a8 - # if defined IS_IN_libpthread || !defined NOT_IN_libc # ifndef __ASSEMBLER__ extern int __local_multiple_threads attribute_hidden; diff --git a/libpthread/nptl/sysdeps/xtensa/pthread_spin_lock.S b/libpthread/nptl/sysdeps/xtensa/pthread_spin_lock.S index 1e220a863..10b1c00f5 100644 --- a/libpthread/nptl/sysdeps/xtensa/pthread_spin_lock.S +++ b/libpthread/nptl/sysdeps/xtensa/pthread_spin_lock.S @@ -16,13 +16,10 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ - .text - .align 4 - - .globl pthread_spin_lock -pthread_spin_lock: +#include <sysdep.h> - entry a1, 16 + .text +ENTRY (pthread_spin_lock) movi a3, 0 wsr a3, scompare1 @@ -31,7 +28,6 @@ pthread_spin_lock: bnez a3, 1b movi a2, 0 - retw + abi_ret - .type pthread_spin_lock, @function - .size pthread_spin_lock, .-pthread_spin_lock +END (pthread_spin_lock) diff --git a/libpthread/nptl/sysdeps/xtensa/pthread_spin_trylock.S b/libpthread/nptl/sysdeps/xtensa/pthread_spin_trylock.S index a736b010f..4742bdb1c 100644 --- a/libpthread/nptl/sysdeps/xtensa/pthread_spin_trylock.S +++ b/libpthread/nptl/sysdeps/xtensa/pthread_spin_trylock.S @@ -18,14 +18,10 @@ #define _ERRNO_H 1 #include <bits/errno.h> +#include <sysdep.h> .text - .align 4 - - .globl pthread_spin_trylock -pthread_spin_trylock: - - entry a1, 16 +ENTRY (pthread_spin_trylock) movi a3, 0 wsr a3, scompare1 @@ -34,7 +30,6 @@ pthread_spin_trylock: movi a2, EBUSY moveqz a2, a3, a3 - retw + abi_ret - .type pthread_spin_trylock, @function - .size pthread_spin_trylock, .-pthread_spin_trylock +END (pthread_spin_trylock) diff --git a/test/tls/tls-macros.h b/test/tls/tls-macros.h index 7d8927400..315f0e2b9 100644 --- a/test/tls/tls-macros.h +++ b/test/tls/tls-macros.h @@ -887,6 +887,7 @@ register void *__gp __asm__("$29"); #elif defined __xtensa__ +#if defined(__XTENSA_WINDOWED_ABI__) #define TLS_GD(x) \ ({ int *__l; \ __asm__ ("movi a8, " #x "@TLSFUNC\n\t" \ @@ -909,6 +910,32 @@ register void *__gp __asm__("$29"); : \ : "a8", "a9", "a10", "a11", "a12", "a13", "a14", "a15"); \ __l; }) +#elif defined(__XTENSA_CALL0_ABI__) +#define TLS_GD(x) \ + ({ int *__l; \ + __asm__ ("movi a0, " #x "@TLSFUNC\n\t" \ + "movi a2, " #x "@TLSARG\n\t" \ + "callx0.tls a0, " #x "@TLSCALL\n\t" \ + "mov %0, a2\n\t" \ + : "=r" (__l) \ + : \ + : "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11");\ + __l; }) + +#define TLS_LD(x) \ + ({ int *__l; \ + __asm__ ("movi a0, _TLS_MODULE_BASE_@TLSFUNC\n\t" \ + "movi a2, _TLS_MODULE_BASE_@TLSARG\n\t" \ + "callx0.tls a0, _TLS_MODULE_BASE_@TLSCALL\n\t" \ + "movi %0, " #x "@TPOFF\n\t" \ + "add %0, %0, a2\n\t" \ + : "=r" (__l) \ + : \ + : "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11");\ + __l; }) +#else +#error Unsupported Xtensa ABI +#endif #define TLS_IE(x) TLS_LE(x) |