Loading...
Note: File does not exist in v5.9.
1/* SPDX-License-Identifier: GPL-2.0-only */
2
3#ifndef _ASM_ARC_ATOMIC_LLSC_H
4#define _ASM_ARC_ATOMIC_LLSC_H
5
6#define arch_atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
7
8#define ATOMIC_OP(op, asm_op) \
9static inline void arch_atomic_##op(int i, atomic_t *v) \
10{ \
11 unsigned int val; \
12 \
13 __asm__ __volatile__( \
14 "1: llock %[val], [%[ctr]] \n" \
15 " " #asm_op " %[val], %[val], %[i] \n" \
16 " scond %[val], [%[ctr]] \n" \
17 " bnz 1b \n" \
18 : [val] "=&r" (val) /* Early clobber to prevent reg reuse */ \
19 : [ctr] "r" (&v->counter), /* Not "m": llock only supports reg direct addr mode */ \
20 [i] "ir" (i) \
21 : "cc", "memory"); \
22} \
23
24#define ATOMIC_OP_RETURN(op, asm_op) \
25static inline int arch_atomic_##op##_return_relaxed(int i, atomic_t *v) \
26{ \
27 unsigned int val; \
28 \
29 __asm__ __volatile__( \
30 "1: llock %[val], [%[ctr]] \n" \
31 " " #asm_op " %[val], %[val], %[i] \n" \
32 " scond %[val], [%[ctr]] \n" \
33 " bnz 1b \n" \
34 : [val] "=&r" (val) \
35 : [ctr] "r" (&v->counter), \
36 [i] "ir" (i) \
37 : "cc", "memory"); \
38 \
39 return val; \
40}
41
42#define arch_atomic_add_return_relaxed arch_atomic_add_return_relaxed
43#define arch_atomic_sub_return_relaxed arch_atomic_sub_return_relaxed
44
45#define ATOMIC_FETCH_OP(op, asm_op) \
46static inline int arch_atomic_fetch_##op##_relaxed(int i, atomic_t *v) \
47{ \
48 unsigned int val, orig; \
49 \
50 __asm__ __volatile__( \
51 "1: llock %[orig], [%[ctr]] \n" \
52 " " #asm_op " %[val], %[orig], %[i] \n" \
53 " scond %[val], [%[ctr]] \n" \
54 " bnz 1b \n" \
55 : [val] "=&r" (val), \
56 [orig] "=&r" (orig) \
57 : [ctr] "r" (&v->counter), \
58 [i] "ir" (i) \
59 : "cc", "memory"); \
60 \
61 return orig; \
62}
63
64#define arch_atomic_fetch_add_relaxed arch_atomic_fetch_add_relaxed
65#define arch_atomic_fetch_sub_relaxed arch_atomic_fetch_sub_relaxed
66
67#define arch_atomic_fetch_and_relaxed arch_atomic_fetch_and_relaxed
68#define arch_atomic_fetch_andnot_relaxed arch_atomic_fetch_andnot_relaxed
69#define arch_atomic_fetch_or_relaxed arch_atomic_fetch_or_relaxed
70#define arch_atomic_fetch_xor_relaxed arch_atomic_fetch_xor_relaxed
71
72#define ATOMIC_OPS(op, asm_op) \
73 ATOMIC_OP(op, asm_op) \
74 ATOMIC_OP_RETURN(op, asm_op) \
75 ATOMIC_FETCH_OP(op, asm_op)
76
77ATOMIC_OPS(add, add)
78ATOMIC_OPS(sub, sub)
79
80#undef ATOMIC_OPS
81#define ATOMIC_OPS(op, asm_op) \
82 ATOMIC_OP(op, asm_op) \
83 ATOMIC_FETCH_OP(op, asm_op)
84
85ATOMIC_OPS(and, and)
86ATOMIC_OPS(andnot, bic)
87ATOMIC_OPS(or, or)
88ATOMIC_OPS(xor, xor)
89
90#define arch_atomic_andnot arch_atomic_andnot
91
92#undef ATOMIC_OPS
93#undef ATOMIC_FETCH_OP
94#undef ATOMIC_OP_RETURN
95#undef ATOMIC_OP
96
97#endif