Hi, There was a small mistake in the previous patch so here's a new one.
The only change is to remove the include of '../loadstore/acquire_release_volatile.h' because in most mips64 processors, use of volatile variables does not have acquire/release semantics. I also don't think that this is an absolute requirement of any mips processor (according to the ISA manuals I've found), so I've removed it for both mips32 and mips64 just to be safe. Thanks, James
From 9a876e1fbc85d84ffce52a27f628484d4e7b64d2 Mon Sep 17 00:00:00 2001 From: James Cowgill <james...@cowgill.org.uk> Date: Tue, 16 Dec 2014 11:42:26 +0000 Subject: [PATCH] Use LLD / SCD instructions on mips64 --- src/atomic_ops/sysdeps/gcc/mips.h | 56 +++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src/atomic_ops/sysdeps/gcc/mips.h b/src/atomic_ops/sysdeps/gcc/mips.h index a891de6..f3796ea 100644 --- a/src/atomic_ops/sysdeps/gcc/mips.h +++ b/src/atomic_ops/sysdeps/gcc/mips.h @@ -15,26 +15,33 @@ * FIXME: This should probably make finer distinctions. SGI MIPS is * much more strongly ordered, and in fact closer to sequentially * consistent. This is really aimed at modern embedded implementations. - * It looks to me like this assumes a 32-bit ABI. -HB */ #include "../all_aligned_atomic_load_store.h" -#include "../loadstore/acquire_release_volatile.h" - #include "../test_and_set_t_is_ao_t.h" /* Data dependence does not imply read ordering. */ #define AO_NO_DD_ORDERING +#ifdef __mips64 +# define AO_MIPS_SET_ISA " .set mips3\n" +# define AO_MIPS_LL_1(args) " lld " args "\n" +# define AO_MIPS_SC(args) " scd " args "\n" +#else +# define AO_MIPS_SET_ISA " .set mips2\n" +# define AO_MIPS_LL_1(args) " ll " args "\n" +# define AO_MIPS_SC(args) " sc " args "\n" +# define AO_T_IS_INT +#endif + #ifdef AO_ICE9A1_LLSC_WAR /* ICE9 rev A1 chip (used in very few systems) is reported to */ /* have a low-frequency bug that causes LL to fail. */ /* To workaround, just issue the second 'LL'. */ -# define AO_MIPS_LL_FIX(args_str) \ - " ll " args_str "\n" +# define AO_MIPS_LL(args) AO_MIPS_LL_1(args) AO_MIPS_LL_1(args) #else -# define AO_MIPS_LL_FIX(args_str) "" +# define AO_MIPS_LL(args) AO_MIPS_LL_1(args) #endif AO_INLINE void @@ -42,7 +49,7 @@ AO_nop_full(void) { __asm__ __volatile__( " .set push \n" - " .set mips2 \n" + AO_MIPS_SET_ISA " .set noreorder \n" " .set nomacro \n" " sync \n" @@ -60,13 +67,13 @@ AO_fetch_and_add(volatile AO_t *addr, AO_t incr) __asm__ __volatile__( " .set push\n" - " .set mips2\n" + AO_MIPS_SET_ISA " .set noreorder\n" " .set nomacro\n" - "1: ll %0, %2\n" - AO_MIPS_LL_FIX("%0, %2") + "1: " + AO_MIPS_LL("%0, %2") " addu %1, %0, %3\n" - " sc %1, %2\n" + AO_MIPS_SC("%1, %2") " beqz %1, 1b\n" " nop\n" " .set pop " @@ -85,13 +92,13 @@ AO_test_and_set(volatile AO_TS_t *addr) __asm__ __volatile__( " .set push\n" - " .set mips2\n" + AO_MIPS_SET_ISA " .set noreorder\n" " .set nomacro\n" - "1: ll %0, %2\n" - AO_MIPS_LL_FIX("%0, %2") + "1: " + AO_MIPS_LL("%0, %2") " move %1, %3\n" - " sc %1, %2\n" + AO_MIPS_SC("%1, %2") " beqz %1, 1b\n" " nop\n" " .set pop " @@ -114,14 +121,14 @@ AO_test_and_set(volatile AO_TS_t *addr) __asm__ __volatile__( " .set push \n" - " .set mips2 \n" + AO_MIPS_SET_ISA " .set noreorder \n" " .set nomacro \n" - "1: ll %0, %1 \n" - AO_MIPS_LL_FIX("%0, %1") + "1: " + AO_MIPS_LL("%0, %1") " bne %0, %4, 2f \n" " move %0, %3 \n" - " sc %0, %1 \n" + AO_MIPS_SC("%0, %1") " .set pop \n" " beqz %0, 1b \n" " li %2, 1 \n" @@ -142,14 +149,14 @@ AO_fetch_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val) __asm__ __volatile__( " .set push\n" - " .set mips2\n" + AO_MIPS_SET_ISA " .set noreorder\n" " .set nomacro\n" - "1: ll %0, %2\n" - AO_MIPS_LL_FIX("%0, %2") + "1: " + AO_MIPS_LL("%0, %2") " bne %0, %4, 2f\n" " move %1, %3\n" - " sc %1, %2\n" + AO_MIPS_SC("%1, %2") " beqz %1, 1b\n" " nop\n" " .set pop\n" @@ -167,6 +174,3 @@ AO_fetch_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val) /* CAS primitives with acquire, release and full semantics are */ /* generated automatically (and AO_int_... primitives are */ /* defined properly after the first generalization pass). */ - -/* FIXME: 32-bit ABI is assumed. */ -#define AO_T_IS_INT -- 2.1.3