diff options
Diffstat (limited to 'arch/mipsn32/atomic_arch.h')
-rw-r--r-- | arch/mipsn32/atomic_arch.h | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/arch/mipsn32/atomic_arch.h b/arch/mipsn32/atomic_arch.h new file mode 100644 index 00000000..ccc3878c --- /dev/null +++ b/arch/mipsn32/atomic_arch.h @@ -0,0 +1,52 @@ +#if __mips_isa_rev < 6 +#define LLSC_M "m" +#else +#define LLSC_M "ZC" +#endif + +#define a_ll a_ll +static inline int a_ll(volatile int *p) +{ + int v; +#if __mips < 2 + __asm__ __volatile__ ( + ".set push ; .set mips2\n\t" + "ll %0, %1" + "\n\t.set pop" + : "=r"(v) : "m"(*p)); +#else + __asm__ __volatile__ ( + "ll %0, %1" + : "=r"(v) : LLSC_M(*p)); +#endif + return v; +} + +#define a_sc a_sc +static inline int a_sc(volatile int *p, int v) +{ + int r; +#if __mips < 2 + __asm__ __volatile__ ( + ".set push ; .set mips2\n\t" + "sc %0, %1" + "\n\t.set pop" + : "=r"(r), "=m"(*p) : "0"(v) : "memory"); +#else + __asm__ __volatile__ ( + "sc %0, %1" + : "=r"(r), "="LLSC_M(*p) : "0"(v) : "memory"); +#endif + return r; +} + +#define a_barrier a_barrier +static inline void a_barrier() +{ + __asm__ __volatile__ ("sync" : : : "memory"); +} + +#define a_pre_llsc a_barrier +#define a_post_llsc a_barrier + +#undef LLSC_M |