[libatomic PATCH] Fix libatomic behavior for big endian toolchain

Shiva Chen shiva0217@gmail.com
Fri Oct 17 07:28:00 GMT 2014


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
-------------- next part --------------
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;


More information about the Gcc-patches mailing list