Avoid misaligned atomic operations
authorAndrew Waterman <waterman@cs.berkeley.edu>
Wed, 21 Jan 2015 17:17:03 +0000 (17:17 +0000)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 21 Jan 2015 17:17:03 +0000 (09:17 -0800)
 Andrew Waterman <waterman@cs.berkeley.edu>

 * fop_n.c (libat_fetch_op): Align address to word boundary.
 (libat_op_fetch): Likewise.

From-SVN: r219954

libatomic/ChangeLog
libatomic/fop_n.c

index ef5b6cd..5048725 100644 (file)
@@ -1,3 +1,8 @@
+2015-01-21  Andrew Waterman <waterman@cs.berkeley.edu>
+
+       * fop_n.c (libat_fetch_op): Align address to word boundary.
+       (libat_op_fetch): Likewise.
+
 2015-01-16  Ilya Verbin  <ilya.verbin@intel.com>
 
        PR testsuite/64605
index 307184d..854d648 100644 (file)
@@ -112,9 +112,9 @@ SIZE(C2(libat_fetch_,NAME)) (UTYPE *mptr, UTYPE opval, int smodel)
 
   pre_barrier (smodel);
 
-  wptr = (UWORD *)mptr;
-  shift = 0;
-  mask = -1;
+  wptr = (UWORD *)((uintptr_t)mptr & -WORDSIZE);
+  shift = (((uintptr_t)mptr % WORDSIZE) * CHAR_BIT) ^ SIZE(INVERT_MASK);
+  mask = SIZE(MASK) << shift;
 
   wopval = (UWORD)opval << shift;
   woldval = __atomic_load_n (wptr, __ATOMIC_RELAXED);
@@ -136,9 +136,9 @@ SIZE(C3(libat_,NAME,_fetch)) (UTYPE *mptr, UTYPE opval, int smodel)
 
   pre_barrier (smodel);
 
-  wptr = (UWORD *)mptr;
-  shift = 0;
-  mask = -1;
+  wptr = (UWORD *)((uintptr_t)mptr & -WORDSIZE);
+  shift = (((uintptr_t)mptr % WORDSIZE) * CHAR_BIT) ^ SIZE(INVERT_MASK);
+  mask = SIZE(MASK) << shift;
 
   wopval = (UWORD)opval << shift;
   woldval = __atomic_load_n (wptr, __ATOMIC_RELAXED);