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é 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 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) 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 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