|
11 | 11 | #include <asm/barrier.h>
|
12 | 12 | #include <asm/fence.h>
|
13 | 13 |
|
14 |
| -#define __xchg_relaxed(ptr, new, size) \ |
| 14 | +#define __arch_xchg(sfx, prepend, append, r, p, n) \ |
15 | 15 | ({ \
|
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"); \ |
45 | 23 | })
|
46 | 24 |
|
47 |
| -#define __xchg_acquire(ptr, new, size) \ |
| 25 | +#define _arch_xchg(ptr, new, sfx, prepend, append) \ |
48 | 26 | ({ \
|
49 | 27 | __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)) { \ |
53 | 31 | 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); \ |
60 | 34 | break; \
|
61 | 35 | 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); \ |
68 | 38 | break; \
|
69 | 39 | default: \
|
70 | 40 | BUILD_BUG(); \
|
71 | 41 | } \
|
72 |
| - __ret; \ |
| 42 | + (__typeof__(*(__ptr)))__ret; \ |
73 | 43 | })
|
74 | 44 |
|
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, "", "", "") |
81 | 47 |
|
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) |
109 | 50 |
|
110 | 51 | #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, "") |
142 | 53 |
|
143 | 54 | #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", "", "") |
148 | 56 |
|
149 | 57 | #define xchg32(ptr, x) \
|
150 | 58 | ({ \
|
|
0 commit comments