^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) #ifndef __ASM_SH_ATOMIC_GRB_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define __ASM_SH_ATOMIC_GRB_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #define ATOMIC_OP(op) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) static inline void atomic_##op(int i, atomic_t *v) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) int tmp; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) __asm__ __volatile__ ( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) " .align 2 \n\t" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) " mova 1f, r0 \n\t" /* r0 = end point */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) " mov r15, r1 \n\t" /* r1 = saved sp */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) " mov.l @%1, %0 \n\t" /* load old value */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) " " #op " %2, %0 \n\t" /* $op */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) " mov.l %0, @%1 \n\t" /* store new value */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) "1: mov r1, r15 \n\t" /* LOGOUT */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) : "=&r" (tmp), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) "+r" (v) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) : "r" (i) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) : "memory" , "r0", "r1"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define ATOMIC_OP_RETURN(op) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static inline int atomic_##op##_return(int i, atomic_t *v) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) int tmp; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) __asm__ __volatile__ ( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) " .align 2 \n\t" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) " mova 1f, r0 \n\t" /* r0 = end point */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) " mov r15, r1 \n\t" /* r1 = saved sp */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) " mov.l @%1, %0 \n\t" /* load old value */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) " " #op " %2, %0 \n\t" /* $op */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) " mov.l %0, @%1 \n\t" /* store new value */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) "1: mov r1, r15 \n\t" /* LOGOUT */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) : "=&r" (tmp), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) "+r" (v) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) : "r" (i) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) : "memory" , "r0", "r1"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return tmp; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define ATOMIC_FETCH_OP(op) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static inline int atomic_fetch_##op(int i, atomic_t *v) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int res, tmp; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) __asm__ __volatile__ ( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) " .align 2 \n\t" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) " mova 1f, r0 \n\t" /* r0 = end point */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) " mov r15, r1 \n\t" /* r1 = saved sp */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) " mov.l @%2, %0 \n\t" /* load old value */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) " mov %0, %1 \n\t" /* save old value */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) " " #op " %3, %0 \n\t" /* $op */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) " mov.l %0, @%2 \n\t" /* store new value */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) "1: mov r1, r15 \n\t" /* LOGOUT */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) : "=&r" (tmp), "=&r" (res), "+r" (v) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) : "r" (i) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) : "memory" , "r0", "r1"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return res; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) ATOMIC_FETCH_OP(op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ATOMIC_OPS(add)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) ATOMIC_OPS(sub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #undef ATOMIC_OPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_FETCH_OP(op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ATOMIC_OPS(and)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ATOMIC_OPS(or)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ATOMIC_OPS(xor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #undef ATOMIC_OPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #undef ATOMIC_FETCH_OP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #undef ATOMIC_OP_RETURN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #undef ATOMIC_OP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #endif /* __ASM_SH_ATOMIC_GRB_H */