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 <shiva0...@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
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;