@@ -57,13 +57,16 @@
#define __cmpxchg_relaxed(ptr, old, new, size) \
({ \
__typeof__(ptr) __ptr = (ptr); \
- __typeof__(new) __new = (new); \
- __typeof__(new) __tmp; \
- __typeof__(old) __old = (old); \
+ unsigned long __old = (unsigned long)(0 ? *(ptr) : (old)); \
+ unsigned long __new = (unsigned long)(0 ? *(ptr) : (new)); \
+ unsigned long __tmp; \
__typeof__(*(ptr)) __ret; \
switch (size) { \
case 1: \
- __ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, (uintptr_t)__old, (uintptr_t)__new); \
+ __ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, __old, __new); \
+ break; \
+ case 2: \
+ __ret = (__typeof__(*(ptr)))cmpxchg_emu_u16((volatile u16 *)__ptr, __old, __new); \
break; \
case 4: \
asm volatile ( \
@@ -90,13 +93,16 @@
#define __cmpxchg_acquire(ptr, old, new, size) \
({ \
__typeof__(ptr) __ptr = (ptr); \
- __typeof__(new) __new = (new); \
- __typeof__(new) __tmp; \
- __typeof__(old) __old = (old); \
+ unsigned long __old = (unsigned long)(0 ? *(ptr) : (old)); \
+ unsigned long __new = (unsigned long)(0 ? *(ptr) : (new)); \
+ unsigned long __tmp; \
__typeof__(*(ptr)) __ret; \
switch (size) { \
case 1: \
- __ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, (uintptr_t)__old, (uintptr_t)__new); \
+ __ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, __old, __new); \
+ break; \
+ case 2: \
+ __ret = (__typeof__(*(ptr)))cmpxchg_emu_u16((volatile u16 *)__ptr, __old, __new); \
break; \
case 4: \
asm volatile ( \
@@ -124,13 +130,16 @@
#define __cmpxchg(ptr, old, new, size) \
({ \
__typeof__(ptr) __ptr = (ptr); \
- __typeof__(new) __new = (new); \
- __typeof__(new) __tmp; \
- __typeof__(old) __old = (old); \
+ unsigned long __old = (unsigned long)(0 ? *(ptr) : (old)); \
+ unsigned long __new = (unsigned long)(0 ? *(ptr) : (new)); \
+ unsigned long __tmp; \
__typeof__(*(ptr)) __ret; \
switch (size) { \
case 1: \
- __ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, (uintptr_t)__old, (uintptr_t)__new); \
+ __ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, __old, __new); \
+ break; \
+ case 2: \
+ __ret = (__typeof__(*(ptr)))cmpxchg_emu_u16((volatile u16 *)__ptr, __old, __new); \
break; \
case 4: \
asm volatile ( \
CSKY has no two-byte atomic compare and swap, so the __cmpxchg() switches in cmpxchg.h let case 2 fall through to the undefined __cmpxchg_called_with_bad_pointer(), failing at link time. Route case 2 through the new cmpxchg_emu_u16(), which takes the old and new values as unsigned long and narrows them itself, so the (uintptr_t) casts on __old and __new come off in all three switch instances. The (u16) casts are gone for the same reason. The __old and __new declarations were typed __typeof__(old) and __typeof__(new), which skips the pointer-integer type check, so cmpxchg(&p, 4, 5) compiled silently. Typing them through (unsigned long)(0 ? *(ptr) : (old)) keeps the value conversion while making the compiler reject mismatched types, the idiom David Laight suggested. The same check is added for new. Signed-off-by: Bradley Morgan <brads@mainlining.org> --- arch/csky/include/asm/cmpxchg.h | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-)