> +#define GEN_ATOMIC_HELPER(NAME, OP, NEW) \ > +static void * const table_##NAME[16] = { \ > + [MO_8] = gen_helper_atomic_##NAME##b, \ > + [MO_16 | MO_LE] = gen_helper_atomic_##NAME##w_le, \ > + [MO_16 | MO_BE] = gen_helper_atomic_##NAME##w_be, \ > + [MO_32 | MO_LE] = gen_helper_atomic_##NAME##l_le, \ > + [MO_32 | MO_BE] = gen_helper_atomic_##NAME##l_be, \ > + [MO_64 | MO_LE] = gen_helper_atomic_##NAME##q_le, \ > + [MO_64 | MO_BE] = gen_helper_atomic_##NAME##q_be, \ > +}; \ > +void tcg_gen_atomic_##NAME##_i32 \ > + (TCGv_i32 ret, TCGv addr, TCGv_i32 val, TCGArg idx, TCGMemOp memop) \ > +{ \ > + if (parallel_cpus) { \ > + do_atomic_op_i32(ret, addr, val, idx, memop, table_##NAME); \ > + } else { \ > + do_nonatomic_op_i32(ret, addr, val, idx, memop, NEW, \ > + tcg_gen_##OP##_i32); \ > + } \ > +} \ > +void tcg_gen_atomic_##NAME##_i64 \ > + (TCGv_i64 ret, TCGv addr, TCGv_i64 val, TCGArg idx, TCGMemOp memop) \ > +{ \ > + if (parallel_cpus) { \ > + do_atomic_op_i64(ret, addr, val, idx, memop, table_##NAME); \ > + } else { \ > + do_nonatomic_op_i64(ret, addr, val, idx, memop, NEW, \ > + tcg_gen_##OP##_i64); \ > + } \ > +} > + > +GEN_ATOMIC_HELPER(fetch_add, add, 0) > +GEN_ATOMIC_HELPER(fetch_and, and, 0) > +GEN_ATOMIC_HELPER(fetch_or, or, 0) > +GEN_ATOMIC_HELPER(fetch_xor, xor, 0) > + > +GEN_ATOMIC_HELPER(add_fetch, add, 1) > +GEN_ATOMIC_HELPER(and_fetch, and, 1) > +GEN_ATOMIC_HELPER(or_fetch, or, 1) > +GEN_ATOMIC_HELPER(xor_fetch, xor, 1)
This causes build errors on CentOS6.5 (where __ATOMIC_RELAXED is undefined): /user/lea/dev/qemu/tcg/tcg-op.c:2280: error: ‘gen_helper_atomic_fetch_addb’ undeclared here (not in a function) /user/lea/dev/qemu/tcg/tcg-op.c:2280: error: ‘gen_helper_atomic_fetch_addw_le’ undeclared here (not in a function) /user/lea/dev/qemu/tcg/tcg-op.c:2280: error: ‘gen_helper_atomic_fetch_addw_be’ undeclared here (not in a function) (...) The fix I've been using locally while working on enabling MTTCG for MIPS: diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h index 5542416..818a5a4 100644 --- a/include/qemu/atomic.h +++ b/include/qemu/atomic.h @@ -409,22 +409,22 @@ /* Provide shorter names for GCC atomic builtins. */ #define atomic_fetch_inc(ptr) __sync_fetch_and_add(ptr, 1) #define atomic_fetch_dec(ptr) __sync_fetch_and_add(ptr, -1) -#define atomic_fetch_add __sync_fetch_and_add -#define atomic_fetch_sub __sync_fetch_and_sub -#define atomic_fetch_and __sync_fetch_and_and -#define atomic_fetch_or __sync_fetch_and_or -#define atomic_fetch_xor __sync_fetch_and_xor +#define atomic_fetch_add(ptr, n) __sync_fetch_and_add(ptr, n) +#define atomic_fetch_sub(ptr, n) __sync_fetch_and_sub(ptr, n) +#define atomic_fetch_and(ptr, n) __sync_fetch_and_and(ptr, n) +#define atomic_fetch_or(ptr, n) __sync_fetch_and_or(ptr, n) +#define atomic_fetch_xor(ptr, n) __sync_fetch_and_xor(ptr, n) #define atomic_inc_fetch(ptr) __sync_add_and_fetch(ptr, 1) #define atomic_dec_fetch(ptr) __sync_add_and_fetch(ptr, -1) -#define atomic_add_fetch __sync_add_and_fetch -#define atomic_sub_fetch __sync_sub_and_fetch -#define atomic_and_fetch __sync_and_and_fetch -#define atomic_or_fetch __sync_or_and_fetch -#define atomic_xor_fetch __sync_xor_and_fetch - -#define atomic_cmpxchg __sync_val_compare_and_swap -#define atomic_cmpxchg__nocheck atomic_cmpxchg +#define atomic_add_fetch(ptr, n) __sync_add_and_fetch(ptr, n) +#define atomic_sub_fetch(ptr, n) __sync_sub_and_fetch(ptr, n) +#define atomic_and_fetch(ptr, n) __sync_and_and_fetch(ptr, n) +#define atomic_or_fetch(ptr, n) __sync_or_and_fetch(ptr, n) +#define atomic_xor_fetch(ptr, n) __sync_xor_and_fetch(ptr, n) + +#define atomic_cmpxchg(ptr, old, new) __sync_val_compare_and_swap(ptr, old, new) +#define atomic_cmpxchg__nocheck(ptr, old, new) atomic_cmpxchg(ptr, old, new) /* And even shorter names that return void. */ #define atomic_inc(ptr) ((void) __sync_fetch_and_add(ptr, 1))