diff options
Diffstat (limited to 'libpthread')
| -rw-r--r-- | libpthread/linuxthreads/sysdeps/xtensa/pt-machine.h | 56 | ||||
| -rw-r--r-- | libpthread/nptl/sysdeps/xtensa/pthread_spin_lock.S | 16 | ||||
| -rw-r--r-- | libpthread/nptl/sysdeps/xtensa/pthread_spin_trylock.S | 17 | 
3 files changed, 89 insertions, 0 deletions
diff --git a/libpthread/linuxthreads/sysdeps/xtensa/pt-machine.h b/libpthread/linuxthreads/sysdeps/xtensa/pt-machine.h index 82d9b540c..0b7f58b63 100644 --- a/libpthread/linuxthreads/sysdeps/xtensa/pt-machine.h +++ b/libpthread/linuxthreads/sysdeps/xtensa/pt-machine.h @@ -21,6 +21,7 @@  #ifndef _PT_MACHINE_H  #define _PT_MACHINE_H   1 +#include <bits/xtensa-config.h>  #include <sys/syscall.h>  #include <asm/unistd.h> @@ -34,6 +35,55 @@  extern long int testandset (int *spinlock);  extern int __compare_and_swap (long int *p, long int oldval, long int newval); +#if XCHAL_HAVE_EXCLUSIVE + +/* Spinlock implementation; required.  */ +PT_EI long int +testandset (int *spinlock) +{ +	unsigned long tmp; +	__asm__ volatile ( +"	memw				\n" +"1:	l32ex	%0, %1			\n" +"	bnez	%0, 2f			\n" +"	movi	%0, 1			\n" +"	s32ex	%0, %1			\n" +"	getex	%0			\n" +"	beqz	%0, 1b			\n" +"	movi	%0, 0			\n" +"	memw				\n" +"2:					\n" +	: "=&a" (tmp) +	: "a" (spinlock) +	: "memory" +	); +	return tmp; +} + +PT_EI int +__compare_and_swap (long int *p, long int oldval, long int newval) +{ +        unsigned long tmp; +        unsigned long value; +        __asm__ volatile ( +"       memw                         \n" +"1:     l32ex   %0, %2               \n" +"       bne     %0, %4, 2f           \n" +"       mov     %1, %3               \n" +"       s32ex   %1, %2               \n" +"       getex   %1                   \n" +"       beqz    %1, 1b               \n" +"       memw                         \n" +"2:                                  \n" +          : "=&a" (tmp), "=&a" (value) +          : "a" (p), "a" (newval), "a" (oldval) +          : "memory" ); + +        return tmp == oldval; +} + +#elif XCHAL_HAVE_S32C1I +  /* Spinlock implementation; required.  */  PT_EI long int  testandset (int *spinlock) @@ -71,6 +121,12 @@ __compare_and_swap (long int *p, long int oldval, long int newval)          return tmp == oldval;  } +#else + +#error No hardware atomic operations + +#endif +  /* Get some notion of the current stack.  Need not be exactly the top     of the stack, just something somewhere in the current frame.  */  #define CURRENT_STACK_FRAME __builtin_frame_address (0) diff --git a/libpthread/nptl/sysdeps/xtensa/pthread_spin_lock.S b/libpthread/nptl/sysdeps/xtensa/pthread_spin_lock.S index 3386afae9..3faac36da 100644 --- a/libpthread/nptl/sysdeps/xtensa/pthread_spin_lock.S +++ b/libpthread/nptl/sysdeps/xtensa/pthread_spin_lock.S @@ -15,16 +15,32 @@     License along with the GNU C Library; see the file COPYING.LIB.  If     not, see <http://www.gnu.org/licenses/>.  */ +#include <bits/xtensa-config.h>  #include <sysdep.h>  	.text  ENTRY (pthread_spin_lock) +#if XCHAL_HAVE_EXCLUSIVE +	memw +1:	l32ex	a3, a2 +	bnez	a3, 1b +	movi	a3, 1 +	s32ex	a3, a2 +	getex	a3 +	beqz	a3, 1b +	memw +#elif XCHAL_HAVE_S32C1I  	movi	a3, 0  	wsr 	a3, scompare1  	movi	a3, 1  1:	s32c1i	a3, a2, 0  	bnez	a3, 1b +#else + +#error No hardware atomic operations + +#endif  	movi	a2, 0  	abi_ret diff --git a/libpthread/nptl/sysdeps/xtensa/pthread_spin_trylock.S b/libpthread/nptl/sysdeps/xtensa/pthread_spin_trylock.S index 72b2dda92..0669682ec 100644 --- a/libpthread/nptl/sysdeps/xtensa/pthread_spin_trylock.S +++ b/libpthread/nptl/sysdeps/xtensa/pthread_spin_trylock.S @@ -17,15 +17,32 @@  #define _ERRNO_H 1  #include <bits/errno.h> +#include <bits/xtensa-config.h>  #include <sysdep.h>  	.text  ENTRY (pthread_spin_trylock) +#if XCHAL_HAVE_EXCLUSIVE +	memw +	l32ex	a3, a2 +	bnez	a3, 1f +	movi	a3, 1 +	s32ex	a3, a2 +	getex	a3 +	addi	a3, a3, -1 +	memw +1: +#elif XCHAL_HAVE_S32C1I  	movi	a3, 0  	wsr 	a3, scompare1  	movi	a3, 1  	s32c1i	a3, a2, 0 +#else + +#error No hardware atomic operations + +#endif  	movi	a2, EBUSY  	moveqz	a2, a3, a3  | 
