summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldso/ldso/xtensa/dl-startup.h12
-rw-r--r--ldso/ldso/xtensa/dl-tlsdesc.S45
-rw-r--r--ldso/ldso/xtensa/resolve.S35
-rw-r--r--libc/string/xtensa/memcpy.S16
-rw-r--r--libc/string/xtensa/memset.S4
-rw-r--r--libc/string/xtensa/strcmp.S20
-rw-r--r--libc/string/xtensa/strcpy.S12
-rw-r--r--libc/string/xtensa/strlen.S8
-rw-r--r--libc/string/xtensa/strncpy.S6
-rw-r--r--libc/sysdeps/linux/xtensa/__longjmp.S17
-rw-r--r--libc/sysdeps/linux/xtensa/bits/setjmp.h9
-rw-r--r--libc/sysdeps/linux/xtensa/clone.S21
-rw-r--r--libc/sysdeps/linux/xtensa/crt1.S30
-rw-r--r--libc/sysdeps/linux/xtensa/crti.S15
-rw-r--r--libc/sysdeps/linux/xtensa/crtn.S17
-rw-r--r--libc/sysdeps/linux/xtensa/mmap.S2
-rw-r--r--libc/sysdeps/linux/xtensa/setjmp.S17
-rw-r--r--libc/sysdeps/linux/xtensa/syscall.S4
-rw-r--r--libc/sysdeps/linux/xtensa/sysdep.h45
-rw-r--r--libc/sysdeps/linux/xtensa/vfork.S23
-rw-r--r--libc/sysdeps/linux/xtensa/windowspill.S3
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/sysdep-cancel.h64
-rw-r--r--libpthread/nptl/sysdeps/xtensa/pthread_spin_lock.S14
-rw-r--r--libpthread/nptl/sysdeps/xtensa/pthread_spin_trylock.S13
-rw-r--r--test/tls/tls-macros.h27
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)