^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright IBM Corp. 1999, 2011
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #ifndef __ASM_CMPXCHG_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define __ASM_CMPXCHG_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/mmdebug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define cmpxchg(ptr, o, n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) __typeof__(*(ptr)) __o = (o); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) __typeof__(*(ptr)) __n = (n); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) (__typeof__(*(ptr))) __sync_val_compare_and_swap((ptr),__o,__n);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define cmpxchg64 cmpxchg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define cmpxchg_local cmpxchg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define cmpxchg64_local cmpxchg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define xchg(ptr, x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) __typeof__(ptr) __ptr = (ptr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) __typeof__(*(ptr)) __old; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) __old = *__ptr; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) } while (!__sync_bool_compare_and_swap(__ptr, __old, x)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) __old; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define __cmpxchg_double(p1, p2, o1, o2, n1, n2) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) register __typeof__(*(p1)) __old1 asm("2") = (o1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) register __typeof__(*(p2)) __old2 asm("3") = (o2); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) register __typeof__(*(p1)) __new1 asm("4") = (n1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) register __typeof__(*(p2)) __new2 asm("5") = (n2); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int cc; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) asm volatile( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) " cdsg %[old],%[new],%[ptr]\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) " ipm %[cc]\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) " srl %[cc],28" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) : [cc] "=d" (cc), [old] "+d" (__old1), "+d" (__old2) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) : [new] "d" (__new1), "d" (__new2), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) [ptr] "Q" (*(p1)), "Q" (*(p2)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) : "memory", "cc"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) !cc; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define cmpxchg_double(p1, p2, o1, o2, n1, n2) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) __typeof__(p1) __p1 = (p1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) __typeof__(p2) __p2 = (p2); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) BUILD_BUG_ON(sizeof(*(p1)) != sizeof(long)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) BUILD_BUG_ON(sizeof(*(p2)) != sizeof(long)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) VM_BUG_ON((unsigned long)((__p1) + 1) != (unsigned long)(__p2));\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) __cmpxchg_double(__p1, __p2, o1, o2, n1, n2); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define system_has_cmpxchg_double() 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #endif /* __ASM_CMPXCHG_H */