|
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