1 /* SPDX-License-Identifier: GPL-2.0 */
3 #ifndef __ASM_CSKY_CMPXCHG_H
4 #define __ASM_CSKY_CMPXCHG_H
8 #include <asm/barrier.h>
9 #include <linux/cmpxchg-emu.h>
11 #define __xchg_relaxed(new, ptr, size) \
13 __typeof__(ptr) __ptr = (ptr); \
14 __typeof__(new) __new = (new); \
15 __typeof__(*(ptr)) __ret; \
20 u32 shif = ((ulong)__ptr & 2) ? 16 : 0; \
21 u32 mask = 0xffff << shif; \
22 __ptr = (__typeof__(ptr))((ulong)__ptr & ~2); \
23 __asm__ __volatile__ ( \
24 "1: ldex.w %0, (%4)\n" \
27 " stex.w %1, (%4)\n" \
29 : "=&r" (ret), "=&r" (tmp) \
31 "r" ((u32)__new << shif), \
34 __ret = (__typeof__(*(ptr))) \
35 ((ret & mask) >> shif); \
40 "1: ldex.w %0, (%3) \n" \
42 " stex.w %1, (%3) \n" \
44 : "=&r" (__ret), "=&r" (tmp) \
45 : "r" (__new), "r"(__ptr) \
54 #define arch_xchg_relaxed(ptr, x) \
55 (__xchg_relaxed((x), (ptr), sizeof(*(ptr))))
57 #define __cmpxchg_relaxed(ptr, old, new, size) \
59 __typeof__(ptr) __ptr = (ptr); \
60 __typeof__(new) __new = (new); \
61 __typeof__(new) __tmp; \
62 __typeof__(old) __old = (old); \
63 __typeof__(*(ptr)) __ret; \
66 __ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, (uintptr_t)__old, (uintptr_t)__new); \
70 "1: ldex.w %0, (%3) \n" \
74 " stex.w %1, (%3) \n" \
77 : "=&r" (__ret), "=&r" (__tmp) \
78 : "r" (__new), "r"(__ptr), "r"(__old) \
87 #define arch_cmpxchg_relaxed(ptr, o, n) \
88 (__cmpxchg_relaxed((ptr), (o), (n), sizeof(*(ptr))))
90 #define __cmpxchg_acquire(ptr, old, new, size) \
92 __typeof__(ptr) __ptr = (ptr); \
93 __typeof__(new) __new = (new); \
94 __typeof__(new) __tmp; \
95 __typeof__(old) __old = (old); \
96 __typeof__(*(ptr)) __ret; \
99 __ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, (uintptr_t)__old, (uintptr_t)__new); \
103 "1: ldex.w %0, (%3) \n" \
107 " stex.w %1, (%3) \n" \
111 : "=&r" (__ret), "=&r" (__tmp) \
112 : "r" (__new), "r"(__ptr), "r"(__old) \
121 #define arch_cmpxchg_acquire(ptr, o, n) \
122 (__cmpxchg_acquire((ptr), (o), (n), sizeof(*(ptr))))
124 #define __cmpxchg(ptr, old, new, size) \
126 __typeof__(ptr) __ptr = (ptr); \
127 __typeof__(new) __new = (new); \
128 __typeof__(new) __tmp; \
129 __typeof__(old) __old = (old); \
130 __typeof__(*(ptr)) __ret; \
133 __ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, (uintptr_t)__old, (uintptr_t)__new); \
138 "1: ldex.w %0, (%3) \n" \
142 " stex.w %1, (%3) \n" \
146 : "=&r" (__ret), "=&r" (__tmp) \
147 : "r" (__new), "r"(__ptr), "r"(__old) \
156 #define arch_cmpxchg(ptr, o, n) \
157 (__cmpxchg((ptr), (o), (n), sizeof(*(ptr))))
159 #define arch_cmpxchg_local(ptr, o, n) \
160 (__cmpxchg_relaxed((ptr), (o), (n), sizeof(*(ptr))))
162 #include <asm-generic/cmpxchg.h>
165 #endif /* __ASM_CSKY_CMPXCHG_H */