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)  | 
