From patchwork Tue Jul 20 16:33:08 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [ARM] Fix atomic nand operations. Date: Tue, 20 Jul 2010 06:33:08 -0000 From: Ramana Radhakrishnan X-Patchwork-Id: 59345 Message-Id: <1279643588.23062.16.camel@e102325-lin.cambridge.arm.com> To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw , Marcus Shawcroft Hi , Marcus pointed out that the way we implement __sync_nand_and_fetch in the helper routines is broken today because of the way we test the value we get. http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Atomic-Builtins.html#Atomic-Builtins and later - state that : Note: GCC 4.4 and later implement __sync_fetch_and_nand builtin as *ptr = ~(tmp & value) instead of *ptr = ~tmp & value. Shouldn't the implementation of this be changed to reflect the semantics of the documentation in all release branches ? Ok to commit on trunk and all release branches ? cheers Ramana 2010-07-20 Ramana Radhakrishnan * config/arm/linux-atomic.c (FETCH_AND_OP_WORD): Add appropriate paranthesis for prefix operations. (OP_AND_FETCH_WORD): Likewise. (SUBWORD_SYNC_OP): Likewise. Index: gcc/config/arm/linux-atomic.c =================================================================== --- gcc/config/arm/linux-atomic.c (revision 162305) +++ gcc/config/arm/linux-atomic.c (working copy) @@ -56,7 +56,7 @@ typedef void (__kernel_dmb_t) (void); \ do { \ tmp = *ptr; \ - failure = __kernel_cmpxchg (tmp, PFX_OP tmp INF_OP val, ptr); \ + failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \ } while (failure != 0); \ \ return tmp; \ @@ -88,8 +88,8 @@ FETCH_AND_OP_WORD (nand, ~, &) \ do { \ oldval = *wordptr; \ - newval = ((PFX_OP ((oldval & mask) >> shift) \ - INF_OP (unsigned int) val) << shift) & mask; \ + newval = ((PFX_OP (((oldval & mask) >> shift) \ + INF_OP (unsigned int) val) << shift)) & mask; \ newval |= oldval & ~mask; \ failure = __kernel_cmpxchg (oldval, newval, wordptr); \ } while (failure != 0); \ @@ -119,10 +119,10 @@ SUBWORD_SYNC_OP (nand, ~, &, char, 1, ol \ do { \ tmp = *ptr; \ - failure = __kernel_cmpxchg (tmp, PFX_OP tmp INF_OP val, ptr); \ + failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \ } while (failure != 0); \ \ - return PFX_OP tmp INF_OP val; \ + return PFX_OP (tmp INF_OP val); \ } OP_AND_FETCH_WORD (add, , +)