Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

locking/atomic, arch/arm64: Generate LSE non-return cases using common macros

atomic[64]_{add,and,andnot,or,xor} all follow the same patterns, so
generate them using macros, like we do for the LL/SC case already.

Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steve Capper <steve.capper@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-arch@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Link: http://lkml.kernel.org/r/1461344493-8262-1-git-send-email-will.deacon@arm.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Will Deacon and committed by
Ingo Molnar
6822a84d e490f9b1

+32 -90
+32 -90
arch/arm64/include/asm/atomic_lse.h
··· 26 26 #endif 27 27 28 28 #define __LL_SC_ATOMIC(op) __LL_SC_CALL(atomic_##op) 29 - 30 - static inline void atomic_andnot(int i, atomic_t *v) 31 - { 32 - register int w0 asm ("w0") = i; 33 - register atomic_t *x1 asm ("x1") = v; 34 - 35 - asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(andnot), 36 - " stclr %w[i], %[v]\n") 37 - : [i] "+r" (w0), [v] "+Q" (v->counter) 38 - : "r" (x1) 39 - : __LL_SC_CLOBBERS); 29 + #define ATOMIC_OP(op, asm_op) \ 30 + static inline void atomic_##op(int i, atomic_t *v) \ 31 + { \ 32 + register int w0 asm ("w0") = i; \ 33 + register atomic_t *x1 asm ("x1") = v; \ 34 + \ 35 + asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(op), \ 36 + " " #asm_op " %w[i], %[v]\n") \ 37 + : [i] "+r" (w0), [v] "+Q" (v->counter) \ 38 + : "r" (x1) \ 39 + : __LL_SC_CLOBBERS); \ 40 40 } 41 41 42 - static inline void atomic_or(int i, atomic_t *v) 43 - { 44 - register int w0 asm ("w0") = i; 45 - register atomic_t *x1 asm ("x1") = v; 42 + ATOMIC_OP(andnot, stclr) 43 + ATOMIC_OP(or, stset) 44 + ATOMIC_OP(xor, steor) 45 + ATOMIC_OP(add, stadd) 46 46 47 - asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(or), 48 - " stset %w[i], %[v]\n") 49 - : [i] "+r" (w0), [v] "+Q" (v->counter) 50 - : "r" (x1) 51 - : __LL_SC_CLOBBERS); 52 - } 53 - 54 - static inline void atomic_xor(int i, atomic_t *v) 55 - { 56 - register int w0 asm ("w0") = i; 57 - register atomic_t *x1 asm ("x1") = v; 58 - 59 - asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(xor), 60 - " steor %w[i], %[v]\n") 61 - : [i] "+r" (w0), [v] "+Q" (v->counter) 62 - : "r" (x1) 63 - : __LL_SC_CLOBBERS); 64 - } 65 - 66 - static inline void atomic_add(int i, atomic_t *v) 67 - { 68 - register int w0 asm ("w0") = i; 69 - register atomic_t *x1 asm ("x1") = v; 70 - 71 - asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(add), 72 - " stadd %w[i], %[v]\n") 73 - : [i] "+r" (w0), [v] "+Q" (v->counter) 74 - : "r" (x1) 75 - : __LL_SC_CLOBBERS); 76 - } 47 + #undef ATOMIC_OP 77 48 78 49 #define ATOMIC_OP_ADD_RETURN(name, mb, cl...) \ 79 50 static inline int atomic_add_return##name(int i, atomic_t *v) \ ··· 138 167 #undef __LL_SC_ATOMIC 139 168 140 169 #define __LL_SC_ATOMIC64(op) __LL_SC_CALL(atomic64_##op) 141 - 142 - static inline void atomic64_andnot(long i, atomic64_t *v) 143 - { 144 - register long x0 asm ("x0") = i; 145 - register atomic64_t *x1 asm ("x1") = v; 146 - 147 - asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC64(andnot), 148 - " stclr %[i], %[v]\n") 149 - : [i] "+r" (x0), [v] "+Q" (v->counter) 150 - : "r" (x1) 151 - : __LL_SC_CLOBBERS); 170 + #define ATOMIC64_OP(op, asm_op) \ 171 + static inline void atomic64_##op(long i, atomic64_t *v) \ 172 + { \ 173 + register long x0 asm ("x0") = i; \ 174 + register atomic64_t *x1 asm ("x1") = v; \ 175 + \ 176 + asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC64(op), \ 177 + " " #asm_op " %[i], %[v]\n") \ 178 + : [i] "+r" (x0), [v] "+Q" (v->counter) \ 179 + : "r" (x1) \ 180 + : __LL_SC_CLOBBERS); \ 152 181 } 153 182 154 - static inline void atomic64_or(long i, atomic64_t *v) 155 - { 156 - register long x0 asm ("x0") = i; 157 - register atomic64_t *x1 asm ("x1") = v; 183 + ATOMIC64_OP(andnot, stclr) 184 + ATOMIC64_OP(or, stset) 185 + ATOMIC64_OP(xor, steor) 186 + ATOMIC64_OP(add, stadd) 158 187 159 - asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC64(or), 160 - " stset %[i], %[v]\n") 161 - : [i] "+r" (x0), [v] "+Q" (v->counter) 162 - : "r" (x1) 163 - : __LL_SC_CLOBBERS); 164 - } 165 - 166 - static inline void atomic64_xor(long i, atomic64_t *v) 167 - { 168 - register long x0 asm ("x0") = i; 169 - register atomic64_t *x1 asm ("x1") = v; 170 - 171 - asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC64(xor), 172 - " steor %[i], %[v]\n") 173 - : [i] "+r" (x0), [v] "+Q" (v->counter) 174 - : "r" (x1) 175 - : __LL_SC_CLOBBERS); 176 - } 177 - 178 - static inline void atomic64_add(long i, atomic64_t *v) 179 - { 180 - register long x0 asm ("x0") = i; 181 - register atomic64_t *x1 asm ("x1") = v; 182 - 183 - asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC64(add), 184 - " stadd %[i], %[v]\n") 185 - : [i] "+r" (x0), [v] "+Q" (v->counter) 186 - : "r" (x1) 187 - : __LL_SC_CLOBBERS); 188 - } 188 + #undef ATOMIC64_OP 189 189 190 190 #define ATOMIC64_OP_ADD_RETURN(name, mb, cl...) \ 191 191 static inline long atomic64_add_return##name(long i, atomic64_t *v) \