diff options
author | Rich Felker <dalias@aerifal.cx> | 2016-01-22 00:10:40 +0000 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2016-01-22 00:10:40 +0000 |
commit | 369b22f9c4aebba2b8fe905db8469b2667572ee1 (patch) | |
tree | cf3426f434e54ca53f5f124fbe9b950a45623913 /arch | |
parent | e617b9eea9d45b170eabadf5ca96ca0536c538be (diff) | |
download | musl-369b22f9c4aebba2b8fe905db8469b2667572ee1.tar.gz musl-369b22f9c4aebba2b8fe905db8469b2667572ee1.tar.bz2 musl-369b22f9c4aebba2b8fe905db8469b2667572ee1.tar.xz musl-369b22f9c4aebba2b8fe905db8469b2667572ee1.zip |
overhaul mips atomics for new atomics framework
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/atomic_arch.h | 84 |
1 files changed, 31 insertions, 53 deletions
diff --git a/arch/mips/atomic_arch.h b/arch/mips/atomic_arch.h index b111c894..ce2823b8 100644 --- a/arch/mips/atomic_arch.h +++ b/arch/mips/atomic_arch.h @@ -1,61 +1,39 @@ -#define a_cas a_cas -static inline int a_cas(volatile int *p, int t, int s) +#define a_ll a_ll +static inline int a_ll(volatile int *p) { - int dummy; - __asm__ __volatile__( - ".set push\n" - ".set mips2\n" - ".set noreorder\n" - " sync\n" - "1: ll %0, %2\n" - " bne %0, %3, 1f\n" - " addu %1, %4, $0\n" - " sc %1, %2\n" - " beq %1, $0, 1b\n" - " nop\n" - " sync\n" - "1: \n" - ".set pop\n" - : "=&r"(t), "=&r"(dummy), "+m"(*p) : "r"(t), "r"(s) : "memory" ); - return t; + int v; + __asm__ __volatile__ ( + ".set push ; .set mips2\n\t" + "ll %0, %1" + "\n\t.set pop" + : "=r"(v) : "m"(*p)); + return v; } -#define a_swap a_swap -static inline int a_swap(volatile int *x, int v) +#define a_sc a_sc +static inline int a_sc(volatile int *p, int v) { - int old, dummy; - __asm__ __volatile__( - ".set push\n" - ".set mips2\n" - ".set noreorder\n" - " sync\n" - "1: ll %0, %2\n" - " addu %1, %3, $0\n" - " sc %1, %2\n" - " beq %1, $0, 1b\n" - " nop\n" - " sync\n" - ".set pop\n" - : "=&r"(old), "=&r"(dummy), "+m"(*x) : "r"(v) : "memory" ); - return old; + int r; + __asm__ __volatile__ ( + ".set push ; .set mips2\n\t" + "sc %0, %1" + "\n\t.set pop" + : "=r"(r), "=m"(*p) : "0"(v) : "memory"); + return r; } -#define a_fetch_add a_fetch_add -static inline int a_fetch_add(volatile int *x, int v) +#define a_barrier a_barrier +static inline void a_barrier() { - int old, dummy; - __asm__ __volatile__( - ".set push\n" - ".set mips2\n" - ".set noreorder\n" - " sync\n" - "1: ll %0, %2\n" - " addu %1, %0, %3\n" - " sc %1, %2\n" - " beq %1, $0, 1b\n" - " nop\n" - " sync\n" - ".set pop\n" - : "=&r"(old), "=&r"(dummy), "+m"(*x) : "r"(v) : "memory" ); - return old; + /* mips2 sync, but using too many directives causes + * gcc not to inline it, so encode with .long instead. */ + __asm__ __volatile__ (".long 0xf" : : : "memory"); +#if 0 + __asm__ __volatile__ ( + ".set push ; .set mips2 ; sync ; .set pop" + : : : "memory"); +#endif } + +#define a_pre_llsc a_barrier +#define a_post_llsc a_barrier |