xref: /openbmc/qemu/accel/tcg/atomic_template.h (revision ec4a9629a14c45157d0e89daaff3c982df818cd6)
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é 
5610f7d4d5SPhilippe Mathieu-Daudé #if DATA_SIZE >= 4
5710f7d4d5SPhilippe Mathieu-Daudé # define ABI_TYPE  DATA_TYPE
5810f7d4d5SPhilippe Mathieu-Daudé #else
5910f7d4d5SPhilippe Mathieu-Daudé # define ABI_TYPE  uint32_t
6010f7d4d5SPhilippe Mathieu-Daudé #endif
6110f7d4d5SPhilippe Mathieu-Daudé 
6210f7d4d5SPhilippe Mathieu-Daudé /* Define host-endian atomic operations.  Note that END is used within
6310f7d4d5SPhilippe Mathieu-Daudé    the ATOMIC_NAME macro, and redefined below.  */
6410f7d4d5SPhilippe Mathieu-Daudé #if DATA_SIZE == 1
6510f7d4d5SPhilippe Mathieu-Daudé # define END
66e03b5686SMarc-André Lureau #elif HOST_BIG_ENDIAN
6710f7d4d5SPhilippe Mathieu-Daudé # define END  _be
6810f7d4d5SPhilippe Mathieu-Daudé #else
6910f7d4d5SPhilippe Mathieu-Daudé # define END  _le
7010f7d4d5SPhilippe Mathieu-Daudé #endif
7110f7d4d5SPhilippe Mathieu-Daudé 
7210f7d4d5SPhilippe Mathieu-Daudé ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
7348688fafSRichard Henderson                               ABI_TYPE cmpv, ABI_TYPE newv,
749002ffcbSRichard Henderson                               MemOpIdx oi, uintptr_t retaddr)
7510f7d4d5SPhilippe Mathieu-Daudé {
76a754f7f3SRichard Henderson     DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE,
77a754f7f3SRichard Henderson                                          PAGE_READ | PAGE_WRITE, retaddr);
78d071f4cdSEmilio G. Cota     DATA_TYPE ret;
79d071f4cdSEmilio G. Cota 
80e6cd4bb5SRichard Henderson #if DATA_SIZE == 16
81e6cd4bb5SRichard Henderson     ret = atomic16_cmpxchg(haddr, cmpv, newv);
82e6cd4bb5SRichard Henderson #else
83d73415a3SStefan Hajnoczi     ret = qatomic_cmpxchg__nocheck(haddr, cmpv, newv);
84e6cd4bb5SRichard Henderson #endif
85ec603b55SRichard Henderson     ATOMIC_MMU_CLEANUP;
86c3e83e37SRichard Henderson     atomic_trace_rmw_post(env, addr, oi);
87ec603b55SRichard Henderson     return ret;
8810f7d4d5SPhilippe Mathieu-Daudé }
8910f7d4d5SPhilippe Mathieu-Daudé 
90*ec4a9629SRichard Henderson #if DATA_SIZE < 16
9148688fafSRichard Henderson ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, ABI_TYPE val,
929002ffcbSRichard Henderson                            MemOpIdx oi, uintptr_t retaddr)
9310f7d4d5SPhilippe Mathieu-Daudé {
94a754f7f3SRichard Henderson     DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE,
95a754f7f3SRichard Henderson                                          PAGE_READ | PAGE_WRITE, retaddr);
96d071f4cdSEmilio G. Cota     DATA_TYPE ret;
97d071f4cdSEmilio G. Cota 
98d73415a3SStefan Hajnoczi     ret = qatomic_xchg__nocheck(haddr, val);
99ec603b55SRichard Henderson     ATOMIC_MMU_CLEANUP;
100c3e83e37SRichard Henderson     atomic_trace_rmw_post(env, addr, oi);
101ec603b55SRichard Henderson     return ret;
10210f7d4d5SPhilippe Mathieu-Daudé }
10310f7d4d5SPhilippe Mathieu-Daudé 
10410f7d4d5SPhilippe Mathieu-Daudé #define GEN_ATOMIC_HELPER(X)                                        \
10510f7d4d5SPhilippe Mathieu-Daudé ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr,       \
1069002ffcbSRichard Henderson                         ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) \
10710f7d4d5SPhilippe Mathieu-Daudé {                                                                   \
108a754f7f3SRichard Henderson     DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE,  \
109a754f7f3SRichard Henderson                                          PAGE_READ | PAGE_WRITE, retaddr); \
110d071f4cdSEmilio G. Cota     DATA_TYPE ret;                                                  \
111d73415a3SStefan Hajnoczi     ret = qatomic_##X(haddr, val);                                  \
112ec603b55SRichard Henderson     ATOMIC_MMU_CLEANUP;                                             \
113c3e83e37SRichard Henderson     atomic_trace_rmw_post(env, addr, oi);                           \
114ec603b55SRichard Henderson     return ret;                                                     \
115ec603b55SRichard Henderson }
11610f7d4d5SPhilippe Mathieu-Daudé 
11710f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(fetch_add)
11810f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(fetch_and)
11910f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(fetch_or)
12010f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(fetch_xor)
12110f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(add_fetch)
12210f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(and_fetch)
12310f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(or_fetch)
12410f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(xor_fetch)
12510f7d4d5SPhilippe Mathieu-Daudé 
12610f7d4d5SPhilippe Mathieu-Daudé #undef GEN_ATOMIC_HELPER
1275507c2bfSRichard Henderson 
128a754f7f3SRichard Henderson /*
129a754f7f3SRichard Henderson  * These helpers are, as a whole, full barriers.  Within the helper,
1305507c2bfSRichard Henderson  * the leading barrier is explicit and the trailing barrier is within
1315507c2bfSRichard Henderson  * cmpxchg primitive.
132d071f4cdSEmilio G. Cota  *
133d071f4cdSEmilio G. Cota  * Trace this load + RMW loop as a single RMW op. This way, regardless
134d071f4cdSEmilio G. Cota  * of CF_PARALLEL's value, we'll trace just a read and a write.
1355507c2bfSRichard Henderson  */
1365507c2bfSRichard Henderson #define GEN_ATOMIC_HELPER_FN(X, FN, XDATA_TYPE, RET)                \
1375507c2bfSRichard Henderson ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr,       \
1389002ffcbSRichard Henderson                         ABI_TYPE xval, MemOpIdx oi, uintptr_t retaddr) \
1395507c2bfSRichard Henderson {                                                                   \
140a754f7f3SRichard Henderson     XDATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, \
141a754f7f3SRichard Henderson                                           PAGE_READ | PAGE_WRITE, retaddr); \
1425507c2bfSRichard Henderson     XDATA_TYPE cmp, old, new, val = xval;                           \
1435507c2bfSRichard Henderson     smp_mb();                                                       \
144d73415a3SStefan Hajnoczi     cmp = qatomic_read__nocheck(haddr);                             \
1455507c2bfSRichard Henderson     do {                                                            \
1465507c2bfSRichard Henderson         old = cmp; new = FN(old, val);                              \
147d73415a3SStefan Hajnoczi         cmp = qatomic_cmpxchg__nocheck(haddr, old, new);            \
1485507c2bfSRichard Henderson     } while (cmp != old);                                           \
1495507c2bfSRichard Henderson     ATOMIC_MMU_CLEANUP;                                             \
150c3e83e37SRichard Henderson     atomic_trace_rmw_post(env, addr, oi);                           \
1515507c2bfSRichard Henderson     return RET;                                                     \
1525507c2bfSRichard Henderson }
1535507c2bfSRichard Henderson 
1545507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_smin, MIN, SDATA_TYPE, old)
1555507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_umin, MIN,  DATA_TYPE, old)
1565507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_smax, MAX, SDATA_TYPE, old)
1575507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_umax, MAX,  DATA_TYPE, old)
1585507c2bfSRichard Henderson 
1595507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(smin_fetch, MIN, SDATA_TYPE, new)
1605507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(umin_fetch, MIN,  DATA_TYPE, new)
1615507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(smax_fetch, MAX, SDATA_TYPE, new)
1625507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(umax_fetch, MAX,  DATA_TYPE, new)
1635507c2bfSRichard Henderson 
1645507c2bfSRichard Henderson #undef GEN_ATOMIC_HELPER_FN
165*ec4a9629SRichard Henderson #endif /* DATA SIZE < 16 */
16610f7d4d5SPhilippe Mathieu-Daudé 
16710f7d4d5SPhilippe Mathieu-Daudé #undef END
16810f7d4d5SPhilippe Mathieu-Daudé 
16910f7d4d5SPhilippe Mathieu-Daudé #if DATA_SIZE > 1
17010f7d4d5SPhilippe Mathieu-Daudé 
17110f7d4d5SPhilippe Mathieu-Daudé /* Define reverse-host-endian atomic operations.  Note that END is used
17210f7d4d5SPhilippe Mathieu-Daudé    within the ATOMIC_NAME macro.  */
173e03b5686SMarc-André Lureau #if HOST_BIG_ENDIAN
17410f7d4d5SPhilippe Mathieu-Daudé # define END  _le
17510f7d4d5SPhilippe Mathieu-Daudé #else
17610f7d4d5SPhilippe Mathieu-Daudé # define END  _be
17710f7d4d5SPhilippe Mathieu-Daudé #endif
17810f7d4d5SPhilippe Mathieu-Daudé 
17910f7d4d5SPhilippe Mathieu-Daudé ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
18048688fafSRichard Henderson                               ABI_TYPE cmpv, ABI_TYPE newv,
1819002ffcbSRichard Henderson                               MemOpIdx oi, uintptr_t retaddr)
18210f7d4d5SPhilippe Mathieu-Daudé {
183a754f7f3SRichard Henderson     DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE,
184a754f7f3SRichard Henderson                                          PAGE_READ | PAGE_WRITE, retaddr);
185d071f4cdSEmilio G. Cota     DATA_TYPE ret;
186d071f4cdSEmilio G. Cota 
187e6cd4bb5SRichard Henderson #if DATA_SIZE == 16
188e6cd4bb5SRichard Henderson     ret = atomic16_cmpxchg(haddr, BSWAP(cmpv), BSWAP(newv));
189e6cd4bb5SRichard Henderson #else
190d73415a3SStefan Hajnoczi     ret = qatomic_cmpxchg__nocheck(haddr, BSWAP(cmpv), BSWAP(newv));
191e6cd4bb5SRichard Henderson #endif
192ec603b55SRichard Henderson     ATOMIC_MMU_CLEANUP;
193c3e83e37SRichard Henderson     atomic_trace_rmw_post(env, addr, oi);
194ec603b55SRichard Henderson     return BSWAP(ret);
19510f7d4d5SPhilippe Mathieu-Daudé }
19610f7d4d5SPhilippe Mathieu-Daudé 
197*ec4a9629SRichard Henderson #if DATA_SIZE < 16
19848688fafSRichard Henderson ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, ABI_TYPE val,
1999002ffcbSRichard Henderson                            MemOpIdx oi, uintptr_t retaddr)
20010f7d4d5SPhilippe Mathieu-Daudé {
201a754f7f3SRichard Henderson     DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE,
202a754f7f3SRichard Henderson                                          PAGE_READ | PAGE_WRITE, retaddr);
203d071f4cdSEmilio G. Cota     ABI_TYPE ret;
204d071f4cdSEmilio G. Cota 
205d73415a3SStefan Hajnoczi     ret = qatomic_xchg__nocheck(haddr, BSWAP(val));
206ec603b55SRichard Henderson     ATOMIC_MMU_CLEANUP;
207c3e83e37SRichard Henderson     atomic_trace_rmw_post(env, addr, oi);
208ec603b55SRichard Henderson     return BSWAP(ret);
20910f7d4d5SPhilippe Mathieu-Daudé }
21010f7d4d5SPhilippe Mathieu-Daudé 
21110f7d4d5SPhilippe Mathieu-Daudé #define GEN_ATOMIC_HELPER(X)                                        \
21210f7d4d5SPhilippe Mathieu-Daudé ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr,       \
2139002ffcbSRichard Henderson                         ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) \
21410f7d4d5SPhilippe Mathieu-Daudé {                                                                   \
215a754f7f3SRichard Henderson     DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE,  \
216a754f7f3SRichard Henderson                                          PAGE_READ | PAGE_WRITE, retaddr); \
217d071f4cdSEmilio G. Cota     DATA_TYPE ret;                                                  \
218d73415a3SStefan Hajnoczi     ret = qatomic_##X(haddr, BSWAP(val));                           \
219ec603b55SRichard Henderson     ATOMIC_MMU_CLEANUP;                                             \
220c3e83e37SRichard Henderson     atomic_trace_rmw_post(env, addr, oi);                           \
221ec603b55SRichard Henderson     return BSWAP(ret);                                              \
22210f7d4d5SPhilippe Mathieu-Daudé }
22310f7d4d5SPhilippe Mathieu-Daudé 
22410f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(fetch_and)
22510f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(fetch_or)
22610f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(fetch_xor)
22710f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(and_fetch)
22810f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(or_fetch)
22910f7d4d5SPhilippe Mathieu-Daudé GEN_ATOMIC_HELPER(xor_fetch)
23010f7d4d5SPhilippe Mathieu-Daudé 
23110f7d4d5SPhilippe Mathieu-Daudé #undef GEN_ATOMIC_HELPER
23210f7d4d5SPhilippe Mathieu-Daudé 
2335507c2bfSRichard Henderson /* These helpers are, as a whole, full barriers.  Within the helper,
2345507c2bfSRichard Henderson  * the leading barrier is explicit and the trailing barrier is within
2355507c2bfSRichard Henderson  * cmpxchg primitive.
236d071f4cdSEmilio G. Cota  *
237d071f4cdSEmilio G. Cota  * Trace this load + RMW loop as a single RMW op. This way, regardless
238d071f4cdSEmilio G. Cota  * of CF_PARALLEL's value, we'll trace just a read and a write.
2395507c2bfSRichard Henderson  */
2405507c2bfSRichard Henderson #define GEN_ATOMIC_HELPER_FN(X, FN, XDATA_TYPE, RET)                \
2415507c2bfSRichard Henderson ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr,       \
2429002ffcbSRichard Henderson                         ABI_TYPE xval, MemOpIdx oi, uintptr_t retaddr) \
2435507c2bfSRichard Henderson {                                                                   \
244a754f7f3SRichard Henderson     XDATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, \
245a754f7f3SRichard Henderson                                           PAGE_READ | PAGE_WRITE, retaddr); \
2465507c2bfSRichard Henderson     XDATA_TYPE ldo, ldn, old, new, val = xval;                      \
2475507c2bfSRichard Henderson     smp_mb();                                                       \
248d73415a3SStefan Hajnoczi     ldn = qatomic_read__nocheck(haddr);                             \
2495507c2bfSRichard Henderson     do {                                                            \
2505507c2bfSRichard Henderson         ldo = ldn; old = BSWAP(ldo); new = FN(old, val);            \
251d73415a3SStefan Hajnoczi         ldn = qatomic_cmpxchg__nocheck(haddr, ldo, BSWAP(new));     \
2525507c2bfSRichard Henderson     } while (ldo != ldn);                                           \
2535507c2bfSRichard Henderson     ATOMIC_MMU_CLEANUP;                                             \
254c3e83e37SRichard Henderson     atomic_trace_rmw_post(env, addr, oi);                           \
2555507c2bfSRichard Henderson     return RET;                                                     \
2565507c2bfSRichard Henderson }
2575507c2bfSRichard Henderson 
2585507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_smin, MIN, SDATA_TYPE, old)
2595507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_umin, MIN,  DATA_TYPE, old)
2605507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_smax, MAX, SDATA_TYPE, old)
2615507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_umax, MAX,  DATA_TYPE, old)
2625507c2bfSRichard Henderson 
2635507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(smin_fetch, MIN, SDATA_TYPE, new)
2645507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(umin_fetch, MIN,  DATA_TYPE, new)
2655507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(smax_fetch, MAX, SDATA_TYPE, new)
2665507c2bfSRichard Henderson GEN_ATOMIC_HELPER_FN(umax_fetch, MAX,  DATA_TYPE, new)
2675507c2bfSRichard Henderson 
26858edf9eeSRichard Henderson /* Note that for addition, we need to use a separate cmpxchg loop instead
26958edf9eeSRichard Henderson    of bswaps for the reverse-host-endian helpers.  */
27058edf9eeSRichard Henderson #define ADD(X, Y)   (X + Y)
27158edf9eeSRichard Henderson GEN_ATOMIC_HELPER_FN(fetch_add, ADD, DATA_TYPE, old)
27258edf9eeSRichard Henderson GEN_ATOMIC_HELPER_FN(add_fetch, ADD, DATA_TYPE, new)
27358edf9eeSRichard Henderson #undef ADD
27458edf9eeSRichard Henderson 
2755507c2bfSRichard Henderson #undef GEN_ATOMIC_HELPER_FN
276*ec4a9629SRichard Henderson #endif /* DATA_SIZE < 16 */
27710f7d4d5SPhilippe Mathieu-Daudé 
27810f7d4d5SPhilippe Mathieu-Daudé #undef END
27910f7d4d5SPhilippe Mathieu-Daudé #endif /* DATA_SIZE > 1 */
28010f7d4d5SPhilippe Mathieu-Daudé 
28110f7d4d5SPhilippe Mathieu-Daudé #undef BSWAP
28210f7d4d5SPhilippe Mathieu-Daudé #undef ABI_TYPE
28310f7d4d5SPhilippe Mathieu-Daudé #undef DATA_TYPE
2845507c2bfSRichard Henderson #undef SDATA_TYPE
28510f7d4d5SPhilippe Mathieu-Daudé #undef SUFFIX
28610f7d4d5SPhilippe Mathieu-Daudé #undef DATA_SIZE
287d071f4cdSEmilio G. Cota #undef SHIFT
288