110f7d4d5SPhilippe Mathieu-Daudé /*
210f7d4d5SPhilippe Mathieu-Daudé * Atomic helper templates
310f7d4d5SPhilippe Mathieu-Daudé * Included from tcg-runtime.c and cputlb.c.
410f7d4d5SPhilippe Mathieu-Daudé *
510f7d4d5SPhilippe Mathieu-Daudé * Copyright (c) 2016 Red Hat, Inc
610f7d4d5SPhilippe Mathieu-Daudé *
710f7d4d5SPhilippe Mathieu-Daudé * This library is free software; you can redistribute it and/or
810f7d4d5SPhilippe Mathieu-Daudé * modify it under the terms of the GNU Lesser General Public
910f7d4d5SPhilippe Mathieu-Daudé * License as published by the Free Software Foundation; either
10fb0343d5SThomas Huth * version 2.1 of the License, or (at your option) any later version.
1110f7d4d5SPhilippe Mathieu-Daudé *
1210f7d4d5SPhilippe Mathieu-Daudé * This library is distributed in the hope that it will be useful,
1310f7d4d5SPhilippe Mathieu-Daudé * but WITHOUT ANY WARRANTY; without even the implied warranty of
1410f7d4d5SPhilippe Mathieu-Daudé * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1510f7d4d5SPhilippe Mathieu-Daudé * Lesser General Public License for more details.
1610f7d4d5SPhilippe Mathieu-Daudé *
1710f7d4d5SPhilippe Mathieu-Daudé * You should have received a copy of the GNU Lesser General Public
1810f7d4d5SPhilippe Mathieu-Daudé * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1910f7d4d5SPhilippe Mathieu-Daudé */
2010f7d4d5SPhilippe Mathieu-Daudé
21e6d86bedSEmilio G. Cota #include "qemu/plugin.h"
22d071f4cdSEmilio G. Cota
2310f7d4d5SPhilippe Mathieu-Daudé #if DATA_SIZE == 16
2410f7d4d5SPhilippe Mathieu-Daudé # define SUFFIX o
2510f7d4d5SPhilippe Mathieu-Daudé # define DATA_TYPE Int128
2610f7d4d5SPhilippe Mathieu-Daudé # define BSWAP bswap128
27d071f4cdSEmilio G. Cota # define SHIFT 4
2810f7d4d5SPhilippe Mathieu-Daudé #elif DATA_SIZE == 8
2910f7d4d5SPhilippe Mathieu-Daudé # define SUFFIX q
309ef0c6d6SRichard Henderson # define DATA_TYPE aligned_uint64_t
319ef0c6d6SRichard Henderson # define SDATA_TYPE aligned_int64_t
3210f7d4d5SPhilippe Mathieu-Daudé # define BSWAP bswap64
33d071f4cdSEmilio G. Cota # define SHIFT 3
3410f7d4d5SPhilippe Mathieu-Daudé #elif DATA_SIZE == 4
3510f7d4d5SPhilippe Mathieu-Daudé # define SUFFIX l
3610f7d4d5SPhilippe Mathieu-Daudé # define DATA_TYPE uint32_t
375507c2bfSRichard Henderson # define SDATA_TYPE int32_t
3810f7d4d5SPhilippe Mathieu-Daudé # define BSWAP bswap32
39d071f4cdSEmilio G. Cota # define SHIFT 2
4010f7d4d5SPhilippe Mathieu-Daudé #elif DATA_SIZE == 2
4110f7d4d5SPhilippe Mathieu-Daudé # define SUFFIX w
4210f7d4d5SPhilippe Mathieu-Daudé # define DATA_TYPE uint16_t
435507c2bfSRichard Henderson # define SDATA_TYPE int16_t
4410f7d4d5SPhilippe Mathieu-Daudé # define BSWAP bswap16
45d071f4cdSEmilio G. Cota # define SHIFT 1
4610f7d4d5SPhilippe Mathieu-Daudé #elif DATA_SIZE == 1
4710f7d4d5SPhilippe Mathieu-Daudé # define SUFFIX b
4810f7d4d5SPhilippe Mathieu-Daudé # define DATA_TYPE uint8_t
495507c2bfSRichard Henderson # define SDATA_TYPE int8_t
5010f7d4d5SPhilippe Mathieu-Daudé # define BSWAP
51d071f4cdSEmilio G. Cota # define SHIFT 0
5210f7d4d5SPhilippe Mathieu-Daudé #else
5310f7d4d5SPhilippe Mathieu-Daudé # error unsupported data size
5410f7d4d5SPhilippe Mathieu-Daudé #endif
5510f7d4d5SPhilippe Mathieu-Daudé
56*b709da5dSPierrick Bouvier #if DATA_SIZE == 16
57*b709da5dSPierrick Bouvier # define VALUE_LOW(val) int128_getlo(val)
58*b709da5dSPierrick Bouvier # define VALUE_HIGH(val) int128_gethi(val)
59*b709da5dSPierrick Bouvier #else
60*b709da5dSPierrick Bouvier # define VALUE_LOW(val) val
61*b709da5dSPierrick Bouvier # define VALUE_HIGH(val) 0
62*b709da5dSPierrick Bouvier #endif
63*b709da5dSPierrick Bouvier
6410f7d4d5SPhilippe Mathieu-Daudé #if DATA_SIZE >= 4
6510f7d4d5SPhilippe Mathieu-Daudé # define ABI_TYPE DATA_TYPE
6610f7d4d5SPhilippe Mathieu-Daudé #else
6710f7d4d5SPhilippe Mathieu-Daudé # define ABI_TYPE uint32_t
6810f7d4d5SPhilippe Mathieu-Daudé #endif
6910f7d4d5SPhilippe Mathieu-Daudé
7010f7d4d5SPhilippe Mathieu-Daudé /* Define host-endian atomic operations. Note that END is used within
7110f7d4d5SPhilippe Mathieu-Daudé the ATOMIC_NAME macro, and redefined below. */
7210f7d4d5SPhilippe Mathieu-Daudé #if DATA_SIZE == 1
7310f7d4d5SPhilippe Mathieu-Daudé # define END
74e03b5686SMarc-André Lureau #elif HOST_BIG_ENDIAN
7510f7d4d5SPhilippe Mathieu-Daudé # define END _be
7610f7d4d5SPhilippe Mathieu-Daudé #else
7710f7d4d5SPhilippe Mathieu-Daudé # define END _le
7810f7d4d5SPhilippe Mathieu-Daudé #endif
7910f7d4d5SPhilippe Mathieu-Daudé
ATOMIC_NAME(cmpxchg)80022b9bceSAnton Johansson ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, abi_ptr addr,
8148688fafSRichard Henderson ABI_TYPE cmpv, ABI_TYPE newv,
829002ffcbSRichard Henderson MemOpIdx oi, uintptr_t retaddr)
8310f7d4d5SPhilippe Mathieu-Daudé {
84d560225fSAnton Johansson DATA_TYPE *haddr = atomic_mmu_lookup(env_cpu(env), addr, oi,
85d560225fSAnton Johansson DATA_SIZE, retaddr);
86d071f4cdSEmilio G. Cota DATA_TYPE ret;
87d071f4cdSEmilio G. Cota
88e6cd4bb5SRichard Henderson #if DATA_SIZE == 16
89e6cd4bb5SRichard Henderson ret = atomic16_cmpxchg(haddr, cmpv, newv);
90e6cd4bb5SRichard Henderson #else
91d73415a3SStefan Hajnoczi ret = qatomic_cmpxchg__nocheck(haddr, cmpv, newv);
92e6cd4bb5SRichard Henderson #endif
93ec603b55SRichard Henderson ATOMIC_MMU_CLEANUP;
94*b709da5dSPierrick Bouvier atomic_trace_rmw_post(env, addr,
95*b709da5dSPierrick Bouvier VALUE_LOW(ret),
96*b709da5dSPierrick Bouvier VALUE_HIGH(ret),
97*b709da5dSPierrick Bouvier VALUE_LOW(newv),
98*b709da5dSPierrick Bouvier VALUE_HIGH(newv),
99*b709da5dSPierrick Bouvier oi);
100ec603b55SRichard Henderson return ret;
10110f7d4d5SPhilippe Mathieu-Daudé }
10210f7d4d5SPhilippe Mathieu-Daudé
103ec4a9629SRichard Henderson #if DATA_SIZE < 16
ATOMIC_NAME(xchg)104022b9bceSAnton Johansson ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, abi_ptr addr, ABI_TYPE val,
1059002ffcbSRichard Henderson MemOpIdx oi, uintptr_t retaddr)
10610f7d4d5SPhilippe Mathieu-Daudé {
107d560225fSAnton Johansson DATA_TYPE *haddr = atomic_mmu_lookup(env_cpu(env), addr, oi,
108d560225fSAnton Johansson DATA_SIZE, retaddr);
109d071f4cdSEmilio G. Cota DATA_TYPE ret;
110d071f4cdSEmilio G. Cota
111d73415a3SStefan Hajnoczi ret = qatomic_xchg__nocheck(haddr, val);
112ec603b55SRichard Henderson ATOMIC_MMU_CLEANUP;
113*b709da5dSPierrick Bouvier atomic_trace_rmw_post(env, addr,
114*b709da5dSPierrick Bouvier VALUE_LOW(ret),
115*b709da5dSPierrick Bouvier VALUE_HIGH(ret),
116*b709da5dSPierrick Bouvier VALUE_LOW(val),
117*b709da5dSPierrick Bouvier VALUE_HIGH(val),
118*b709da5dSPierrick Bouvier oi);
119ec603b55SRichard Henderson return ret;
12010f7d4d5SPhilippe Mathieu-Daudé }
12110f7d4d5SPhilippe Mathieu-Daudé
12210f7d4d5SPhilippe Mathieu-Daudé #define GEN_ATOMIC_HELPER(X) \
123022b9bceSAnton Johansson ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr, \
1249002ffcbSRichard Henderson ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) \
12510f7d4d5SPhilippe Mathieu-Daudé { \
1267bedee32SRichard Henderson DATA_TYPE *haddr, ret; \
127d560225fSAnton Johansson haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, DATA_SIZE, retaddr); \
128d73415a3SStefan Hajnoczi ret = qatomic_##X(haddr, val); \
129ec603b55SRichard Henderson ATOMIC_MMU_CLEANUP; \
130*b709da5dSPierrick Bouvier atomic_trace_rmw_post(env, addr, \
131*b709da5dSPierrick Bouvier VALUE_LOW(ret), \
132*b709da5dSPierrick Bouvier VALUE_HIGH(ret), \
133*b709da5dSPierrick Bouvier VALUE_LOW(val), \
134*b709da5dSPierrick Bouvier VALUE_HIGH(val), \
135*b709da5dSPierrick Bouvier oi); \
136ec603b55SRichard Henderson return ret; \
137ec603b55SRichard Henderson }
13810f7d4d5SPhilippe Mathieu-Daudé
13910f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(fetch_add)
GEN_ATOMIC_HELPER(fetch_and)14010f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(fetch_and)
14110f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(fetch_or)
14210f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(fetch_xor)
14310f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(add_fetch)
14410f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(and_fetch)
14510f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(or_fetch)
14610f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(xor_fetch)
14710f7d4d5SPhilippe Mathieu-Daudé
14810f7d4d5SPhilippe Mathieu-Daudé #undef GEN_ATOMIC_HELPER
1495507c2bfSRichard Henderson
150a754f7f3SRichard Henderson /*
151a754f7f3SRichard Henderson * These helpers are, as a whole, full barriers. Within the helper,
1525507c2bfSRichard Henderson * the leading barrier is explicit and the trailing barrier is within
1535507c2bfSRichard Henderson * cmpxchg primitive.
154d071f4cdSEmilio G. Cota *
155d071f4cdSEmilio G. Cota * Trace this load + RMW loop as a single RMW op. This way, regardless
156d071f4cdSEmilio G. Cota * of CF_PARALLEL's value, we'll trace just a read and a write.
1575507c2bfSRichard Henderson */
1585507c2bfSRichard Henderson #define GEN_ATOMIC_HELPER_FN(X, FN, XDATA_TYPE, RET) \
159022b9bceSAnton Johansson ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr, \
1609002ffcbSRichard Henderson ABI_TYPE xval, MemOpIdx oi, uintptr_t retaddr) \
1615507c2bfSRichard Henderson { \
1627bedee32SRichard Henderson XDATA_TYPE *haddr, cmp, old, new, val = xval; \
163d560225fSAnton Johansson haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, DATA_SIZE, retaddr); \
1645507c2bfSRichard Henderson smp_mb(); \
165d73415a3SStefan Hajnoczi cmp = qatomic_read__nocheck(haddr); \
1665507c2bfSRichard Henderson do { \
1675507c2bfSRichard Henderson old = cmp; new = FN(old, val); \
168d73415a3SStefan Hajnoczi cmp = qatomic_cmpxchg__nocheck(haddr, old, new); \
1695507c2bfSRichard Henderson } while (cmp != old); \
1705507c2bfSRichard Henderson ATOMIC_MMU_CLEANUP; \
171*b709da5dSPierrick Bouvier atomic_trace_rmw_post(env, addr, \
172*b709da5dSPierrick Bouvier VALUE_LOW(old), \
173*b709da5dSPierrick Bouvier VALUE_HIGH(old), \
174*b709da5dSPierrick Bouvier VALUE_LOW(xval), \
175*b709da5dSPierrick Bouvier VALUE_HIGH(xval), \
176*b709da5dSPierrick Bouvier oi); \
1775507c2bfSRichard Henderson return RET; \
1785507c2bfSRichard Henderson }
1795507c2bfSRichard Henderson
1805507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_smin, MIN, SDATA_TYPE, old)
1815507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_umin, MIN, DATA_TYPE, old)
1825507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_smax, MAX, SDATA_TYPE, old)
1835507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_umax, MAX, DATA_TYPE, old)
1845507c2bfSRichard Henderson
1855507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(smin_fetch, MIN, SDATA_TYPE, new)
1865507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(umin_fetch, MIN, DATA_TYPE, new)
1875507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(smax_fetch, MAX, SDATA_TYPE, new)
1885507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(umax_fetch, MAX, DATA_TYPE, new)
1895507c2bfSRichard Henderson
1905507c2bfSRichard Henderson #undef GEN_ATOMIC_HELPER_FN
191ec4a9629SRichard Henderson #endif /* DATA SIZE < 16 */
19210f7d4d5SPhilippe Mathieu-Daudé
19310f7d4d5SPhilippe Mathieu-Daudé #undef END
19410f7d4d5SPhilippe Mathieu-Daudé
19510f7d4d5SPhilippe Mathieu-Daudé #if DATA_SIZE > 1
19610f7d4d5SPhilippe Mathieu-Daudé
19710f7d4d5SPhilippe Mathieu-Daudé /* Define reverse-host-endian atomic operations. Note that END is used
19810f7d4d5SPhilippe Mathieu-Daudé within the ATOMIC_NAME macro. */
199e03b5686SMarc-André Lureau #if HOST_BIG_ENDIAN
20010f7d4d5SPhilippe Mathieu-Daudé # define END _le
20110f7d4d5SPhilippe Mathieu-Daudé #else
20210f7d4d5SPhilippe Mathieu-Daudé # define END _be
20310f7d4d5SPhilippe Mathieu-Daudé #endif
20410f7d4d5SPhilippe Mathieu-Daudé
205022b9bceSAnton Johansson ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, abi_ptr addr,
20648688fafSRichard Henderson ABI_TYPE cmpv, ABI_TYPE newv,
2079002ffcbSRichard Henderson MemOpIdx oi, uintptr_t retaddr)
20810f7d4d5SPhilippe Mathieu-Daudé {
209d560225fSAnton Johansson DATA_TYPE *haddr = atomic_mmu_lookup(env_cpu(env), addr, oi,
210d560225fSAnton Johansson DATA_SIZE, retaddr);
211d071f4cdSEmilio G. Cota DATA_TYPE ret;
212d071f4cdSEmilio G. Cota
213e6cd4bb5SRichard Henderson #if DATA_SIZE == 16
214e6cd4bb5SRichard Henderson ret = atomic16_cmpxchg(haddr, BSWAP(cmpv), BSWAP(newv));
215e6cd4bb5SRichard Henderson #else
216d73415a3SStefan Hajnoczi ret = qatomic_cmpxchg__nocheck(haddr, BSWAP(cmpv), BSWAP(newv));
217e6cd4bb5SRichard Henderson #endif
218ec603b55SRichard Henderson ATOMIC_MMU_CLEANUP;
219*b709da5dSPierrick Bouvier atomic_trace_rmw_post(env, addr,
220*b709da5dSPierrick Bouvier VALUE_LOW(ret),
221*b709da5dSPierrick Bouvier VALUE_HIGH(ret),
222*b709da5dSPierrick Bouvier VALUE_LOW(newv),
223*b709da5dSPierrick Bouvier VALUE_HIGH(newv),
224*b709da5dSPierrick Bouvier oi);
225ec603b55SRichard Henderson return BSWAP(ret);
22610f7d4d5SPhilippe Mathieu-Daudé }
22710f7d4d5SPhilippe Mathieu-Daudé
228ec4a9629SRichard Henderson #if DATA_SIZE < 16
ATOMIC_NAME(xchg)229022b9bceSAnton Johansson ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, abi_ptr addr, ABI_TYPE val,
2309002ffcbSRichard Henderson MemOpIdx oi, uintptr_t retaddr)
23110f7d4d5SPhilippe Mathieu-Daudé {
232d560225fSAnton Johansson DATA_TYPE *haddr = atomic_mmu_lookup(env_cpu(env), addr, oi,
233d560225fSAnton Johansson DATA_SIZE, retaddr);
234d071f4cdSEmilio G. Cota ABI_TYPE ret;
235d071f4cdSEmilio G. Cota
236d73415a3SStefan Hajnoczi ret = qatomic_xchg__nocheck(haddr, BSWAP(val));
237ec603b55SRichard Henderson ATOMIC_MMU_CLEANUP;
238*b709da5dSPierrick Bouvier atomic_trace_rmw_post(env, addr,
239*b709da5dSPierrick Bouvier VALUE_LOW(ret),
240*b709da5dSPierrick Bouvier VALUE_HIGH(ret),
241*b709da5dSPierrick Bouvier VALUE_LOW(val),
242*b709da5dSPierrick Bouvier VALUE_HIGH(val),
243*b709da5dSPierrick Bouvier oi);
244ec603b55SRichard Henderson return BSWAP(ret);
24510f7d4d5SPhilippe Mathieu-Daudé }
24610f7d4d5SPhilippe Mathieu-Daudé
24710f7d4d5SPhilippe Mathieu-Daudé #define GEN_ATOMIC_HELPER(X) \
248022b9bceSAnton Johansson ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr, \
2499002ffcbSRichard Henderson ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) \
25010f7d4d5SPhilippe Mathieu-Daudé { \
2517bedee32SRichard Henderson DATA_TYPE *haddr, ret; \
252d560225fSAnton Johansson haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, DATA_SIZE, retaddr); \
253d73415a3SStefan Hajnoczi ret = qatomic_##X(haddr, BSWAP(val)); \
254ec603b55SRichard Henderson ATOMIC_MMU_CLEANUP; \
255*b709da5dSPierrick Bouvier atomic_trace_rmw_post(env, addr, \
256*b709da5dSPierrick Bouvier VALUE_LOW(ret), \
257*b709da5dSPierrick Bouvier VALUE_HIGH(ret), \
258*b709da5dSPierrick Bouvier VALUE_LOW(val), \
259*b709da5dSPierrick Bouvier VALUE_HIGH(val), \
260*b709da5dSPierrick Bouvier oi); \
261ec603b55SRichard Henderson return BSWAP(ret); \
26210f7d4d5SPhilippe Mathieu-Daudé }
26310f7d4d5SPhilippe Mathieu-Daudé
26410f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(fetch_and)
26510f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(fetch_or)
26610f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(fetch_xor)
26710f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(and_fetch)
26810f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(or_fetch)
26910f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(xor_fetch)
27010f7d4d5SPhilippe Mathieu-Daudé
27110f7d4d5SPhilippe Mathieu-Daudé #undef GEN_ATOMIC_HELPER
27210f7d4d5SPhilippe Mathieu-Daudé
2735507c2bfSRichard Henderson /* These helpers are, as a whole, full barriers. Within the helper,
2745507c2bfSRichard Henderson * the leading barrier is explicit and the trailing barrier is within
2755507c2bfSRichard Henderson * cmpxchg primitive.
276d071f4cdSEmilio G. Cota *
277d071f4cdSEmilio G. Cota * Trace this load + RMW loop as a single RMW op. This way, regardless
278d071f4cdSEmilio G. Cota * of CF_PARALLEL's value, we'll trace just a read and a write.
2795507c2bfSRichard Henderson */
2805507c2bfSRichard Henderson #define GEN_ATOMIC_HELPER_FN(X, FN, XDATA_TYPE, RET) \
281022b9bceSAnton Johansson ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr, \
2829002ffcbSRichard Henderson ABI_TYPE xval, MemOpIdx oi, uintptr_t retaddr) \
2835507c2bfSRichard Henderson { \
2847bedee32SRichard Henderson XDATA_TYPE *haddr, ldo, ldn, old, new, val = xval; \
285d560225fSAnton Johansson haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, DATA_SIZE, retaddr); \
2865507c2bfSRichard Henderson smp_mb(); \
287d73415a3SStefan Hajnoczi ldn = qatomic_read__nocheck(haddr); \
2885507c2bfSRichard Henderson do { \
2895507c2bfSRichard Henderson ldo = ldn; old = BSWAP(ldo); new = FN(old, val); \
290d73415a3SStefan Hajnoczi ldn = qatomic_cmpxchg__nocheck(haddr, ldo, BSWAP(new)); \
2915507c2bfSRichard Henderson } while (ldo != ldn); \
2925507c2bfSRichard Henderson ATOMIC_MMU_CLEANUP; \
293*b709da5dSPierrick Bouvier atomic_trace_rmw_post(env, addr, \
294*b709da5dSPierrick Bouvier VALUE_LOW(old), \
295*b709da5dSPierrick Bouvier VALUE_HIGH(old), \
296*b709da5dSPierrick Bouvier VALUE_LOW(xval), \
297*b709da5dSPierrick Bouvier VALUE_HIGH(xval), \
298*b709da5dSPierrick Bouvier oi); \
2995507c2bfSRichard Henderson return RET; \
3005507c2bfSRichard Henderson }
3015507c2bfSRichard Henderson
3025507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_smin, MIN, SDATA_TYPE, old)
3035507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_umin, MIN, DATA_TYPE, old)
3045507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_smax, MAX, SDATA_TYPE, old)
3055507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_umax, MAX, DATA_TYPE, old)
3065507c2bfSRichard Henderson
3075507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(smin_fetch, MIN, SDATA_TYPE, new)
3085507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(umin_fetch, MIN, DATA_TYPE, new)
3095507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(smax_fetch, MAX, SDATA_TYPE, new)
3105507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(umax_fetch, MAX, DATA_TYPE, new)
3115507c2bfSRichard Henderson
31258edf9eeSRichard Henderson /* Note that for addition, we need to use a separate cmpxchg loop instead
31358edf9eeSRichard Henderson of bswaps for the reverse-host-endian helpers. */
31458edf9eeSRichard Henderson #define ADD(X, Y) (X + Y)
31558edf9eeSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_add, ADD, DATA_TYPE, old)
31658edf9eeSRichard Henderson GEN_ATOMIC_HELPER_FN(add_fetch, ADD, DATA_TYPE, new)
31758edf9eeSRichard Henderson #undef ADD
31858edf9eeSRichard Henderson
3195507c2bfSRichard Henderson #undef GEN_ATOMIC_HELPER_FN
320ec4a9629SRichard Henderson #endif /* DATA_SIZE < 16 */
32110f7d4d5SPhilippe Mathieu-Daudé
32210f7d4d5SPhilippe Mathieu-Daudé #undef END
32310f7d4d5SPhilippe Mathieu-Daudé #endif /* DATA_SIZE > 1 */
32410f7d4d5SPhilippe Mathieu-Daudé
32510f7d4d5SPhilippe Mathieu-Daudé #undef BSWAP
32610f7d4d5SPhilippe Mathieu-Daudé #undef ABI_TYPE
32710f7d4d5SPhilippe Mathieu-Daudé #undef DATA_TYPE
3285507c2bfSRichard Henderson #undef SDATA_TYPE
32910f7d4d5SPhilippe Mathieu-Daudé #undef SUFFIX
33010f7d4d5SPhilippe Mathieu-Daudé #undef DATA_SIZE
331d071f4cdSEmilio G. Cota #undef SHIFT
332*b709da5dSPierrick Bouvier #undef VALUE_LOW
333*b709da5dSPierrick Bouvier #undef VALUE_HIGH
334