diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h index d0d162e654e..60f28681f9e 100644 --- a/src/include/storage/s_lock.h +++ b/src/include/storage/s_lock.h @@ -598,14 +598,31 @@ tas(volatile slock_t *lock) #if defined(__mips__) && !defined(__sgi) /* non-SGI MIPS */ -/* Note: on SGI we use the OS' mutex ABI, see below */ -/* Note: R10000 processors require a separate SYNC */ #define HAS_TEST_AND_SET typedef unsigned int slock_t; #define TAS(lock) tas(lock) +/* + * Original MIPS-I processors lacked the LL/SC instructions, but if we are + * so unfortunate as to be running on one of those, we expect that the kernel + * will handle the illegal-instruction traps and emulate them for us. On + * anything newer (and really, MIPS-I is extinct) LL/SC is the only sane + * choice because any other synchronization method must involve a kernel + * call. Unfortunately, many toolchains still default to MIPS-I as the + * codegen target; if the symbol __mips shows that that's the case, we + * have to force the assembler to accept LL/SC. + * + * R10000 and up processors require a separate SYNC, which has the same + * issues as LL/SC. + */ +#if __mips < 2 +#define MIPS_SET_MIPS2 " .set mips2 \n" +#else +#define MIPS_SET_MIPS2 +#endif + static __inline__ int tas(volatile slock_t *lock) { @@ -615,7 +632,7 @@ tas(volatile slock_t *lock) __asm__ __volatile__( " .set push \n" - " .set mips2 \n" + MIPS_SET_MIPS2 " .set noreorder \n" " .set nomacro \n" " ll %0, %2 \n" @@ -637,7 +654,7 @@ do \ { \ __asm__ __volatile__( \ " .set push \n" \ - " .set mips2 \n" \ + MIPS_SET_MIPS2 \ " .set noreorder \n" \ " .set nomacro \n" \ " sync \n" \