|
108 | 108 | * indicated by comparing RETURN with OLD. |
109 | 109 | */ |
110 | 110 |
|
111 | | -#define __arch_cmpxchg_masked(sc_sfx, prepend, append, r, p, o, n) \ |
112 | | -({ \ |
113 | | - u32 *__ptr32b = (u32 *)((ulong)(p) & ~0x3); \ |
114 | | - ulong __s = ((ulong)(p) & (0x4 - sizeof(*p))) * BITS_PER_BYTE; \ |
115 | | - ulong __mask = GENMASK(((sizeof(*p)) * BITS_PER_BYTE) - 1, 0) \ |
116 | | - << __s; \ |
117 | | - ulong __newx = (ulong)(n) << __s; \ |
118 | | - ulong __oldx = (ulong)(o) << __s; \ |
119 | | - ulong __retx; \ |
120 | | - ulong __rc; \ |
121 | | - \ |
122 | | - __asm__ __volatile__ ( \ |
123 | | - prepend \ |
124 | | - "0: lr.w %0, %2\n" \ |
125 | | - " and %1, %0, %z5\n" \ |
126 | | - " bne %1, %z3, 1f\n" \ |
127 | | - " and %1, %0, %z6\n" \ |
128 | | - " or %1, %1, %z4\n" \ |
129 | | - " sc.w" sc_sfx " %1, %1, %2\n" \ |
130 | | - " bnez %1, 0b\n" \ |
131 | | - append \ |
132 | | - "1:\n" \ |
133 | | - : "=&r" (__retx), "=&r" (__rc), "+A" (*(__ptr32b)) \ |
134 | | - : "rJ" ((long)__oldx), "rJ" (__newx), \ |
135 | | - "rJ" (__mask), "rJ" (~__mask) \ |
136 | | - : "memory"); \ |
137 | | - \ |
138 | | - r = (__typeof__(*(p)))((__retx & __mask) >> __s); \ |
| 111 | +#define __arch_cmpxchg_masked(sc_sfx, cas_sfx, prepend, append, r, p, o, n) \ |
| 112 | +({ \ |
| 113 | + if (IS_ENABLED(CONFIG_RISCV_ISA_ZABHA) && \ |
| 114 | + IS_ENABLED(CONFIG_RISCV_ISA_ZACAS) && \ |
| 115 | + riscv_has_extension_unlikely(RISCV_ISA_EXT_ZABHA) && \ |
| 116 | + riscv_has_extension_unlikely(RISCV_ISA_EXT_ZACAS)) { \ |
| 117 | + r = o; \ |
| 118 | + \ |
| 119 | + __asm__ __volatile__ ( \ |
| 120 | + prepend \ |
| 121 | + " amocas" cas_sfx " %0, %z2, %1\n" \ |
| 122 | + append \ |
| 123 | + : "+&r" (r), "+A" (*(p)) \ |
| 124 | + : "rJ" (n) \ |
| 125 | + : "memory"); \ |
| 126 | + } else { \ |
| 127 | + u32 *__ptr32b = (u32 *)((ulong)(p) & ~0x3); \ |
| 128 | + ulong __s = ((ulong)(p) & (0x4 - sizeof(*p))) * BITS_PER_BYTE; \ |
| 129 | + ulong __mask = GENMASK(((sizeof(*p)) * BITS_PER_BYTE) - 1, 0) \ |
| 130 | + << __s; \ |
| 131 | + ulong __newx = (ulong)(n) << __s; \ |
| 132 | + ulong __oldx = (ulong)(o) << __s; \ |
| 133 | + ulong __retx; \ |
| 134 | + ulong __rc; \ |
| 135 | + \ |
| 136 | + __asm__ __volatile__ ( \ |
| 137 | + prepend \ |
| 138 | + "0: lr.w %0, %2\n" \ |
| 139 | + " and %1, %0, %z5\n" \ |
| 140 | + " bne %1, %z3, 1f\n" \ |
| 141 | + " and %1, %0, %z6\n" \ |
| 142 | + " or %1, %1, %z4\n" \ |
| 143 | + " sc.w" sc_sfx " %1, %1, %2\n" \ |
| 144 | + " bnez %1, 0b\n" \ |
| 145 | + append \ |
| 146 | + "1:\n" \ |
| 147 | + : "=&r" (__retx), "=&r" (__rc), "+A" (*(__ptr32b)) \ |
| 148 | + : "rJ" ((long)__oldx), "rJ" (__newx), \ |
| 149 | + "rJ" (__mask), "rJ" (~__mask) \ |
| 150 | + : "memory"); \ |
| 151 | + \ |
| 152 | + r = (__typeof__(*(p)))((__retx & __mask) >> __s); \ |
| 153 | + } \ |
139 | 154 | }) |
140 | 155 |
|
141 | 156 | #define __arch_cmpxchg(lr_sfx, sc_cas_sfx, prepend, append, r, p, co, o, n) \ |
|
177 | 192 | \ |
178 | 193 | switch (sizeof(*__ptr)) { \ |
179 | 194 | case 1: \ |
| 195 | + __arch_cmpxchg_masked(sc_cas_sfx, ".b" sc_cas_sfx, \ |
| 196 | + prepend, append, \ |
| 197 | + __ret, __ptr, __old, __new); \ |
| 198 | + break; \ |
180 | 199 | case 2: \ |
181 | | - __arch_cmpxchg_masked(sc_cas_sfx, prepend, append, \ |
| 200 | + __arch_cmpxchg_masked(sc_cas_sfx, ".h" sc_cas_sfx, \ |
| 201 | + prepend, append, \ |
182 | 202 | __ret, __ptr, __old, __new); \ |
183 | 203 | break; \ |
184 | 204 | case 4: \ |
|
0 commit comments