diff mbox

[libatomic] Fix libatomic behavior for big endian toolchain

Message ID CAH=PD7Yz=0L6miPKxMjspBA8a_5je+uKLzrPWBgh_xfoz0AiUQ@mail.gmail.com
State New
Headers show

Commit Message

Shiva Chen Oct. 17, 2014, 7:25 a.m. UTC
Hi,

I noticed that libatomic implementation for builtin function parameter
smaller than word.
It would shift the parameter value to word and then store word.
However, the shift amount for big endian would be wrong.
This patch fix libatomic builtin function behavior for big endian toolchain.

Is it ok for trunk ?

Shiva


2014-10-17     Shiva Chen <shiva0217@gmail.com>

Fix libatomic behavior for big endian toolchain
* libatomic/cas_n.c: Fix shift amount for big endian toolchain
* libatomic/config/arm/exch_n.c: Fix shift amount for big endian toolchain
* libatomic/exch_n.c: Fix shift amount for big endian toolchain
* libatomic/fop_n.c: Fix shift amount for big endian toolchain

Comments

Joseph Myers Oct. 17, 2014, 3:41 p.m. UTC | #1
Changes to architecture-independent files must use 
architecture-independent conditionals, so __BYTE_ORDER__ not __ARMEB__.
diff mbox

Patch

diff --git a/libatomic/cas_n.c b/libatomic/cas_n.c
index 801262d..aea49f0 100644
--- a/libatomic/cas_n.c
+++ b/libatomic/cas_n.c
@@ -60,7 +60,11 @@  SIZE(libat_compare_exchange) (UTYPE *mptr, UTYPE *eptr, UTYPE newval,
   if (N < WORDSIZE)
     {
       wptr = (UWORD *)((uintptr_t)mptr & -WORDSIZE);
-      shift = (((uintptr_t)mptr % WORDSIZE) * CHAR_BIT) ^ SIZE(INVERT_MASK);
+#ifdef __ARMEB__
+      shift = ((WORDSIZE - N - ((uintptr_t)mptr % WORDSIZE)) * CHAR_BIT);
+#else
+      shift = (((uintptr_t)mptr % WORDSIZE) * CHAR_BIT);
+#endif
       mask = SIZE(MASK) << shift;
     }
   else
diff --git a/libatomic/config/arm/exch_n.c b/libatomic/config/arm/exch_n.c
index c90d57f..0d71c5a 100644
--- a/libatomic/config/arm/exch_n.c
+++ b/libatomic/config/arm/exch_n.c
@@ -88,7 +88,11 @@  SIZE(libat_exchange) (UTYPE *mptr, UTYPE newval, int smodel)
   __atomic_thread_fence (__ATOMIC_SEQ_CST);
 
   wptr = (UWORD *)((uintptr_t)mptr & -WORDSIZE);
-  shift = (((uintptr_t)mptr % WORDSIZE) * CHAR_BIT) ^ INVERT_MASK_1;
+#ifdef __ARMEB__
+  shift = ((WORDSIZE - N - ((uintptr_t)mptr % WORDSIZE)) * CHAR_BIT);
+#else
+  shift = (((uintptr_t)mptr % WORDSIZE) * CHAR_BIT);
+#endif
   mask = MASK_1 << shift;
   wnewval = newval << shift;
 
diff --git a/libatomic/exch_n.c b/libatomic/exch_n.c
index 23558b0..e293d0b 100644
--- a/libatomic/exch_n.c
+++ b/libatomic/exch_n.c
@@ -77,7 +77,11 @@  SIZE(libat_exchange) (UTYPE *mptr, UTYPE newval, int smodel)
   if (N < WORDSIZE)
     {
       wptr = (UWORD *)((uintptr_t)mptr & -WORDSIZE);
-      shift = (((uintptr_t)mptr % WORDSIZE) * CHAR_BIT) ^ SIZE(INVERT_MASK);
+#ifdef __ARMEB__
+      shift = ((WORDSIZE - N - ((uintptr_t)mptr % WORDSIZE)) * CHAR_BIT);
+#else
+      shift = (((uintptr_t)mptr % WORDSIZE) * CHAR_BIT);
+#endif
       mask = SIZE(MASK) << shift;
     }
   else
diff --git a/libatomic/fop_n.c b/libatomic/fop_n.c
index 4a18da9..b3184b7 100644
--- a/libatomic/fop_n.c
+++ b/libatomic/fop_n.c
@@ -113,7 +113,11 @@  SIZE(C2(libat_fetch_,NAME)) (UTYPE *mptr, UTYPE opval, int smodel)
   pre_barrier (smodel);
 
   wptr = (UWORD *)mptr;
+#ifdef __ARMEB__
+  shift = (WORDSIZE - N) * CHAR_BIT;
+#else
   shift = 0;
+#endif
   mask = -1;
 
   wopval = (UWORD)opval << shift;
@@ -137,7 +141,11 @@  SIZE(C3(libat_,NAME,_fetch)) (UTYPE *mptr, UTYPE opval, int smodel)
   pre_barrier (smodel);
 
   wptr = (UWORD *)mptr;
+#ifdef __ARMEB__
+  shift = (WORDSIZE - N) * CHAR_BIT;
+#else
   shift = 0;
+#endif
   mask = -1;
 
   wopval = (UWORD)opval << shift;