From edac0a60c7514b8c9b59488cffdac6b22267e757 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 31 Jan 2015 19:07:28 -0800 Subject: Fix two bugs in sparc atomics. * sysdeps/sparc/sparc32/bits/atomic.h (__sparc32_atomic_do_unlock24): Put the memory barrier before the unlock not after it. (__v9_compare_and_exchange_val_32_acq): Use unions to avoid getting volatile register usage warnings from the compiler. --- sysdeps/sparc/sparc32/bits/atomic.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'sysdeps/sparc') diff --git a/sysdeps/sparc/sparc32/bits/atomic.h b/sysdeps/sparc/sparc32/bits/atomic.h index 5f21b83..4242ba8 100644 --- a/sysdeps/sparc/sparc32/bits/atomic.h +++ b/sysdeps/sparc/sparc32/bits/atomic.h @@ -105,27 +105,28 @@ volatile unsigned char __sparc32_atomic_locks[64] #define __sparc32_atomic_do_unlock24(addr) \ do \ { \ - *(char *) (addr) = 0; \ __asm __volatile ("" ::: "memory"); \ + *(char *) (addr) = 0; \ } \ while (0) #ifndef SHARED # define __v9_compare_and_exchange_val_32_acq(mem, newval, oldval) \ -({ \ - register __typeof (*(mem)) __acev_tmp __asm ("%g6"); \ +({union { __typeof (oldval) a; uint32_t v; } oldval_arg = { .a = (oldval) }; \ + union { __typeof (newval) a; uint32_t v; } newval_arg = { .a = (newval) }; \ + register uint32_t __acev_tmp __asm ("%g6"); \ register __typeof (mem) __acev_mem __asm ("%g1") = (mem); \ - register __typeof (*(mem)) __acev_oldval __asm ("%g5"); \ - __acev_tmp = (newval); \ - __acev_oldval = (oldval); \ + register uint32_t __acev_oldval __asm ("%g5"); \ + __acev_tmp = newval_arg.v; \ + __acev_oldval = oldval_arg.v; \ /* .word 0xcde05005 is cas [%g1], %g5, %g6. Can't use cas here though, \ because as will then mark the object file as V8+ arch. */ \ __asm __volatile (".word 0xcde05005" \ : "+r" (__acev_tmp), "=m" (*__acev_mem) \ : "r" (__acev_oldval), "m" (*__acev_mem), \ "r" (__acev_mem) : "memory"); \ - __acev_tmp; }) + (__typeof (oldval)) __acev_tmp; }) #endif /* The only basic operation needed is compare and exchange. */ -- cgit v1.1