Skip to content

Commit 4bfa185

Browse files
Leonardo Braspalmer-dabbelt
authored andcommitted
riscv/cmpxchg: Deduplicate xchg() asm functions
In this header every xchg define (_relaxed, _acquire, _release, vanilla) contain it's own asm file, both for 4-byte variables an 8-byte variables, on a total of 8 versions of mostly the same asm. This is usually bad, as it means any change may be done in up to 8 different places. Unify those versions by creating a new define with enough parameters to generate any version of the previous 8. Then unify the result under a more general define, and simplify arch_xchg* generation. (This did not cause any change in generated asm) Signed-off-by: Leonardo Bras <[email protected]> Reviewed-by: Guo Ren <[email protected]> Reviewed-by: Andrea Parri <[email protected]> Tested-by: Guo Ren <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 6613476 commit 4bfa185

File tree

1 file changed

+23
-115
lines changed

1 file changed

+23
-115
lines changed

arch/riscv/include/asm/cmpxchg.h

Lines changed: 23 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -11,140 +11,48 @@
1111
#include <asm/barrier.h>
1212
#include <asm/fence.h>
1313

14-
#define __xchg_relaxed(ptr, new, size) \
14+
#define __arch_xchg(sfx, prepend, append, r, p, n) \
1515
({ \
16-
__typeof__(ptr) __ptr = (ptr); \
17-
__typeof__(new) __new = (new); \
18-
__typeof__(*(ptr)) __ret; \
19-
switch (size) { \
20-
case 4: \
21-
__asm__ __volatile__ ( \
22-
" amoswap.w %0, %2, %1\n" \
23-
: "=r" (__ret), "+A" (*__ptr) \
24-
: "r" (__new) \
25-
: "memory"); \
26-
break; \
27-
case 8: \
28-
__asm__ __volatile__ ( \
29-
" amoswap.d %0, %2, %1\n" \
30-
: "=r" (__ret), "+A" (*__ptr) \
31-
: "r" (__new) \
32-
: "memory"); \
33-
break; \
34-
default: \
35-
BUILD_BUG(); \
36-
} \
37-
__ret; \
38-
})
39-
40-
#define arch_xchg_relaxed(ptr, x) \
41-
({ \
42-
__typeof__(*(ptr)) _x_ = (x); \
43-
(__typeof__(*(ptr))) __xchg_relaxed((ptr), \
44-
_x_, sizeof(*(ptr))); \
16+
__asm__ __volatile__ ( \
17+
prepend \
18+
" amoswap" sfx " %0, %2, %1\n" \
19+
append \
20+
: "=r" (r), "+A" (*(p)) \
21+
: "r" (n) \
22+
: "memory"); \
4523
})
4624

47-
#define __xchg_acquire(ptr, new, size) \
25+
#define _arch_xchg(ptr, new, sfx, prepend, append) \
4826
({ \
4927
__typeof__(ptr) __ptr = (ptr); \
50-
__typeof__(new) __new = (new); \
51-
__typeof__(*(ptr)) __ret; \
52-
switch (size) { \
28+
__typeof__(*(__ptr)) __new = (new); \
29+
__typeof__(*(__ptr)) __ret; \
30+
switch (sizeof(*__ptr)) { \
5331
case 4: \
54-
__asm__ __volatile__ ( \
55-
" amoswap.w %0, %2, %1\n" \
56-
RISCV_ACQUIRE_BARRIER \
57-
: "=r" (__ret), "+A" (*__ptr) \
58-
: "r" (__new) \
59-
: "memory"); \
32+
__arch_xchg(".w" sfx, prepend, append, \
33+
__ret, __ptr, __new); \
6034
break; \
6135
case 8: \
62-
__asm__ __volatile__ ( \
63-
" amoswap.d %0, %2, %1\n" \
64-
RISCV_ACQUIRE_BARRIER \
65-
: "=r" (__ret), "+A" (*__ptr) \
66-
: "r" (__new) \
67-
: "memory"); \
36+
__arch_xchg(".d" sfx, prepend, append, \
37+
__ret, __ptr, __new); \
6838
break; \
6939
default: \
7040
BUILD_BUG(); \
7141
} \
72-
__ret; \
42+
(__typeof__(*(__ptr)))__ret; \
7343
})
7444

75-
#define arch_xchg_acquire(ptr, x) \
76-
({ \
77-
__typeof__(*(ptr)) _x_ = (x); \
78-
(__typeof__(*(ptr))) __xchg_acquire((ptr), \
79-
_x_, sizeof(*(ptr))); \
80-
})
45+
#define arch_xchg_relaxed(ptr, x) \
46+
_arch_xchg(ptr, x, "", "", "")
8147

82-
#define __xchg_release(ptr, new, size) \
83-
({ \
84-
__typeof__(ptr) __ptr = (ptr); \
85-
__typeof__(new) __new = (new); \
86-
__typeof__(*(ptr)) __ret; \
87-
switch (size) { \
88-
case 4: \
89-
__asm__ __volatile__ ( \
90-
RISCV_RELEASE_BARRIER \
91-
" amoswap.w %0, %2, %1\n" \
92-
: "=r" (__ret), "+A" (*__ptr) \
93-
: "r" (__new) \
94-
: "memory"); \
95-
break; \
96-
case 8: \
97-
__asm__ __volatile__ ( \
98-
RISCV_RELEASE_BARRIER \
99-
" amoswap.d %0, %2, %1\n" \
100-
: "=r" (__ret), "+A" (*__ptr) \
101-
: "r" (__new) \
102-
: "memory"); \
103-
break; \
104-
default: \
105-
BUILD_BUG(); \
106-
} \
107-
__ret; \
108-
})
48+
#define arch_xchg_acquire(ptr, x) \
49+
_arch_xchg(ptr, x, "", "", RISCV_ACQUIRE_BARRIER)
10950

11051
#define arch_xchg_release(ptr, x) \
111-
({ \
112-
__typeof__(*(ptr)) _x_ = (x); \
113-
(__typeof__(*(ptr))) __xchg_release((ptr), \
114-
_x_, sizeof(*(ptr))); \
115-
})
116-
117-
#define __arch_xchg(ptr, new, size) \
118-
({ \
119-
__typeof__(ptr) __ptr = (ptr); \
120-
__typeof__(new) __new = (new); \
121-
__typeof__(*(ptr)) __ret; \
122-
switch (size) { \
123-
case 4: \
124-
__asm__ __volatile__ ( \
125-
" amoswap.w.aqrl %0, %2, %1\n" \
126-
: "=r" (__ret), "+A" (*__ptr) \
127-
: "r" (__new) \
128-
: "memory"); \
129-
break; \
130-
case 8: \
131-
__asm__ __volatile__ ( \
132-
" amoswap.d.aqrl %0, %2, %1\n" \
133-
: "=r" (__ret), "+A" (*__ptr) \
134-
: "r" (__new) \
135-
: "memory"); \
136-
break; \
137-
default: \
138-
BUILD_BUG(); \
139-
} \
140-
__ret; \
141-
})
52+
_arch_xchg(ptr, x, "", RISCV_RELEASE_BARRIER, "")
14253

14354
#define arch_xchg(ptr, x) \
144-
({ \
145-
__typeof__(*(ptr)) _x_ = (x); \
146-
(__typeof__(*(ptr))) __arch_xchg((ptr), _x_, sizeof(*(ptr))); \
147-
})
55+
_arch_xchg(ptr, x, ".aqrl", "", "")
14856

14957
#define xchg32(ptr, x) \
15058
({ \

0 commit comments

Comments
 (0)