On Sun, Sep 27, 2026 at 5:08 AM Richard Henderson
<[email protected]> wrote:
>
> These are done in bulk because of existing macro magic.
>
> Signed-off-by: Richard Henderson <[email protected]>
> ---
>  include/tcg/tcg-op-common.h  |  80 +-------------
>  include/tcg/tcg-op-mem.h     |   2 +-
>  include/tcg/tcg-op-def.h.inc |  20 ++++
>  tcg/tcg-op-ldst.c            | 206 +++++++++++++----------------------
>  4 files changed, 102 insertions(+), 206 deletions(-)
>
> diff --git a/include/tcg/tcg-op-common.h b/include/tcg/tcg-op-common.h
> index 9864674f1c2..bc96c02aaea 100644
> --- a/include/tcg/tcg-op-common.h
> +++ b/include/tcg/tcg-op-common.h
> @@ -181,89 +181,15 @@ void tcg_gen_st_i128(TCGv_i128 val, TCGv_ptr base, 
> tcg_target_long offset);
>  void tcg_gen_qemu_ld_chk_i128(TCGv_i128, TCGTemp *, TCGArg, MemOp, TCGType);
>  void tcg_gen_qemu_st_chk_i128(TCGv_i128, TCGTemp *, TCGArg, MemOp, TCGType);
>
> -/* Atomic ops */
> -
>  void tcg_gen_atomic_cmpxchg_chk_i128(TCGv_i128, TCGTemp *, TCGv_i128,
>                                       TCGv_i128, TCGArg, MemOp, TCGType);
>  void tcg_gen_nonatomic_cmpxchg_chk_i128(TCGv_i128, TCGTemp *, TCGv_i128,
>                                          TCGv_i128, TCGArg, MemOp, TCGType);
> -
> -void tcg_gen_atomic_xchg_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                 TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_xchg_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                 TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_xchg_i128_chk(TCGv_i128, TCGTemp *, TCGv_i128,
> +void tcg_gen_atomic_xchg_chk_i128(TCGv_i128, TCGTemp *, TCGv_i128,
>                                    TCGArg, MemOp, TCGType);
> -
> -void tcg_gen_atomic_fetch_add_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                      TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_add_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                      TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_and_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                      TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_and_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                      TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_or_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                     TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_or_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                     TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_xor_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                      TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_xor_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                      TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_smin_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> +void tcg_gen_atomic_fetch_and_chk_i128(TCGv_i128, TCGTemp *, TCGv_i128,
>                                         TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_smin_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                       TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_umin_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                       TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_umin_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                       TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_smax_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                       TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_smax_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                       TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_umax_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                       TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_umax_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                       TCGArg, MemOp, TCGType);
> -
> -void tcg_gen_atomic_add_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                      TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_add_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                      TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_and_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                      TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_and_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                      TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_or_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                     TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_or_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                     TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_xor_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                      TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_xor_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                      TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_smin_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                       TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_smin_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                       TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_umin_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                       TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_umin_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                       TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_smax_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                       TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_smax_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                       TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_umax_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
> -                                       TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_umax_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
> -                                       TCGArg, MemOp, TCGType);
> -
> -void tcg_gen_atomic_fetch_and_i128_chk(TCGv_i128, TCGTemp *, TCGv_i128,
> -                                       TCGArg, MemOp, TCGType);
> -void tcg_gen_atomic_fetch_or_i128_chk(TCGv_i128, TCGTemp *, TCGv_i128,
> +void tcg_gen_atomic_fetch_or_chk_i128(TCGv_i128, TCGTemp *, TCGv_i128,
>                                        TCGArg, MemOp, TCGType);
>
>  /* Vector ops */
> diff --git a/include/tcg/tcg-op-mem.h b/include/tcg/tcg-op-mem.h
> index 935860f1442..6533704082e 100644
> --- a/include/tcg/tcg-op-mem.h
> +++ b/include/tcg/tcg-op-mem.h
> @@ -67,7 +67,7 @@ tcg_gen_qemu_st_i128(TCGv_i128 v, TCGv_va a, TCGArg i, 
> MemOp m)
>  #define DEF_ATOMIC2(N, S)                                               \
>      QEMU_ARG_NONNULL static inline void                                 \
>      N##_##S(TCGv_##S r, TCGv_va a, TCGv_##S v, TCGArg i, MemOp m)       \
> -    { N##_##S##_chk(r, tcgv_va_temp(a), v, i, m, TCG_TYPE_VA); }
> +    { N##_chk_##S(r, tcgv_va_temp(a), v, i, m, TCG_TYPE_VA); }
>
>  #define DEF_ATOMIC3(N, S)                                               \
>      QEMU_ARG_NONNULL static inline void                                 \
> diff --git a/include/tcg/tcg-op-def.h.inc b/include/tcg/tcg-op-def.h.inc
> index e0ffd0da678..e694f0e38c4 100644
> --- a/include/tcg/tcg-op-def.h.inc
> +++ b/include/tcg/tcg-op-def.h.inc
> @@ -88,3 +88,23 @@ DEF3(xori, TCGV, TCGV, TINT)
>
>  DEF7(atomic_cmpxchg_chk, TCGV, TCGTempPtr, TCGV, TCGV, unsigned, MemOp, 
> TCGType)
>  DEF7(nonatomic_cmpxchg_chk, TCGV, TCGTempPtr, TCGV, TCGV, unsigned, MemOp, 
> TCGType)
> +
> +DEF6(atomic_xchg_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +
> +DEF6(atomic_fetch_add_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +DEF6(atomic_fetch_and_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +DEF6(atomic_fetch_or_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +DEF6(atomic_fetch_smax_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +DEF6(atomic_fetch_smin_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +DEF6(atomic_fetch_umax_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +DEF6(atomic_fetch_umin_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +DEF6(atomic_fetch_xor_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +
> +DEF6(atomic_add_fetch_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +DEF6(atomic_and_fetch_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +DEF6(atomic_or_fetch_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +DEF6(atomic_smax_fetch_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +DEF6(atomic_smin_fetch_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +DEF6(atomic_umax_fetch_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +DEF6(atomic_umin_fetch_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> +DEF6(atomic_xor_fetch_chk, TCGV, TCGTempPtr, TCGV, unsigned, MemOp, TCGType)
> diff --git a/tcg/tcg-op-ldst.c b/tcg/tcg-op-ldst.c
> index b3143f6311b..77679634cbf 100644
> --- a/tcg/tcg-op-ldst.c
> +++ b/tcg/tcg-op-ldst.c
> @@ -877,113 +877,92 @@ void tcg_gen_atomic_cmpxchg_chk_i128(TCGv_i128 retv, 
> TCGTemp *addr,
>      tcg_gen_atomic_cmpxchg_int_i128(retv, addr, cmpv, newv, idx, memop);
>  }
>
> -static void do_nonatomic_op_i32(TCGv_i32 ret, TCGTemp *addr, TCGv_i32 val,
> -                                TCGArg idx, MemOp memop, bool new_val,
> -                                void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
> +static void do_nonatomic_op(TCGType type, TCGTemp *ret, TCGTemp *addr,
> +                            TCGTemp *val, unsigned idx, MemOp memop,
> +                            bool new_val,
> +                            void (*gen)(TCGType, TCGTemp *,
> +                                        TCGTemp *, TCGTemp *))
>  {
> -    TCGv_i32 t1 = tcg_temp_ebb_new_i32();
> -    TCGv_i32 t2 = tcg_temp_ebb_new_i32();
> +    g_autoptr(TCGTemp) t1 = tcg_temp_new_ebb(type);
> +    g_autoptr(TCGTemp) t2 = tcg_temp_new_ebb(type);
>
> -    memop = tcg_canonicalize_memop(memop, 0, 0);
> +    memop = tcg_canonicalize_memop(memop, type != TCG_TYPE_I32, 0);
>
> -    tcg_gen_qemu_ld_int(TCG_TYPE_I32, tcgv_i32_temp(t1), addr, idx, memop);
> -    tcg_gen_ext_i32(t2, val, memop);
> -    gen(t2, t1, t2);
> -    tcg_gen_qemu_st_int(TCG_TYPE_I32, tcgv_i32_temp(t2), addr, idx, memop);
> +    tcg_gen_qemu_ld_int(type, t1, addr, idx, memop);
> +    tcg_gen_ext(type, t2, val, memop);
> +    gen(type, t2, t1, t2);
> +    tcg_gen_qemu_st_int(type, t2, addr, idx, memop);
>
> -    tcg_gen_ext_i32(ret, (new_val ? t2 : t1), memop);
> -    tcg_temp_free_i32(t1);
> -    tcg_temp_free_i32(t2);
> +    tcg_gen_ext(type, ret, (new_val ? t2 : t1), memop);
>  }
>
> -static void do_atomic_op_i32(TCGv_i32 ret, TCGTemp *addr, TCGv_i32 val,
> -                             TCGArg idx, MemOp memop, void * const table[])
> +static void do_atomic_op(TCGType type, TCGTemp *ret, TCGTemp *addr,
> +                         TCGTemp *val, unsigned idx, MemOp memop,
> +                         void * const table[])
>  {
> -    gen_atomic_op_i32 gen;
> -    TCGv_i64 a64;
> +    TCGv_i64 a64 = maybe_extend_addr64(addr);
>      MemOpIdx oi;
>
> -    memop = tcg_canonicalize_memop(memop, 0, 0);
> -
> -    gen = table[memop & (MO_SIZE | MO_BSWAP)];
> -    tcg_debug_assert(gen != NULL);
> -
> -    oi = make_memop_idx(memop & ~MO_SIGN, idx);
> -    a64 = maybe_extend_addr64(addr);
> -    gen(ret, tcg_env, a64, val, tcg_constant_i32(oi));
> -    maybe_free_addr64(a64);
> -
> -    if (memop & MO_SIGN) {
> -        tcg_gen_ext_i32(ret, ret, memop);
> -    }
> -}
> -
> -static void do_nonatomic_op_i64(TCGv_i64 ret, TCGTemp *addr, TCGv_i64 val,
> -                                TCGArg idx, MemOp memop, bool new_val,
> -                                void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64))
> -{
> -    TCGv_i64 t1 = tcg_temp_ebb_new_i64();
> -    TCGv_i64 t2 = tcg_temp_ebb_new_i64();
> -
> -    memop = tcg_canonicalize_memop(memop, 1, 0);
> -
> -    tcg_gen_qemu_ld_int(TCG_TYPE_I64, tcgv_i64_temp(t1), addr, idx, memop);
> -    tcg_gen_ext_i64(t2, val, memop);
> -    gen(t2, t1, t2);
> -    tcg_gen_qemu_st_int(TCG_TYPE_I64, tcgv_i64_temp(t2), addr, idx, memop);
> -
> -    tcg_gen_ext_i64(ret, (new_val ? t2 : t1), memop);
> -    tcg_temp_free_i64(t1);
> -    tcg_temp_free_i64(t2);
> -}
> -
> -static void do_atomic_op_i64(TCGv_i64 ret, TCGTemp *addr, TCGv_i64 val,
> -                             TCGArg idx, MemOp memop, void * const table[])
> -{
> -    memop = tcg_canonicalize_memop(memop, 1, 0);
> -
>      if ((memop & MO_SIZE) == MO_64) {
>          gen_atomic_op_i64 gen = table[memop & (MO_SIZE | MO_BSWAP)];
> +        tcg_debug_assert(gen != NULL);
> +        tcg_debug_assert(type == TCG_TYPE_I64);
>
> -        if (gen) {
> -            MemOpIdx oi = make_memop_idx(memop & ~MO_SIGN, idx);
> -            TCGv_i64 a64 = maybe_extend_addr64(addr);
> -            gen(ret, tcg_env, a64, val, tcg_constant_i32(oi));
> -            maybe_free_addr64(a64);
> -            return;
> +        memop = tcg_canonicalize_memop(memop, 1, 0);
> +        oi = make_memop_idx(memop & ~MO_SIGN, idx);
> +
> +        gen(temp_tcgv_i64(ret), tcg_env, a64,
> +            temp_tcgv_i64(val), tcg_constant_i32(oi));
> +    } else {
> +        g_autoptr(TCGTemp) v32 = NULL;
> +        g_autoptr(TCGTemp) r32 = NULL;
> +        TCGTemp *ret_orig = ret;
> +
> +        gen_atomic_op_i32 gen = table[memop & (MO_SIZE | MO_BSWAP)];
> +        tcg_debug_assert(gen != NULL);
> +
> +        if (type == TCG_TYPE_I64) {
> +            v32 = tcg_temp_new_ebb(TCG_TYPE_I32);
> +            r32 = tcg_temp_new_ebb(TCG_TYPE_I32);
> +
> +            tcg_gen_extrl(v32, val);
> +            val = v32;
> +            ret = r32;
>          }
>
> -        gen_helper_exit_atomic(tcg_env);
> -        /* Produce a result, so that we have a well-formed opcode stream
> -           with respect to uses of the result in the (dead) code following.  
> */
> -        tcg_gen_movi_i64(ret, 0);
> -    } else {
> -        TCGv_i32 v32 = tcg_temp_ebb_new_i32();
> -        TCGv_i32 r32 = tcg_temp_ebb_new_i32();
> +        memop = tcg_canonicalize_memop(memop, 0, 0);
> +        oi = make_memop_idx(memop & ~MO_SIGN, idx);
>
> -        tcg_gen_extrl_i64_i32(v32, val);
> -        do_atomic_op_i32(r32, addr, v32, idx, memop & ~MO_SIGN, table);
> -        tcg_temp_free_i32(v32);
> -
> -        tcg_gen_extu_i32_i64(ret, r32);
> -        tcg_temp_free_i32(r32);
> +        gen(temp_tcgv_i32(ret), tcg_env, a64,
> +            temp_tcgv_i32(val), tcg_constant_i32(oi));
>
>          if (memop & MO_SIGN) {
> -            tcg_gen_ext_i64(ret, ret, memop);
> +            tcg_gen_ext(TCG_TYPE_I32, ret, ret, memop);
> +        }
> +        if (ret != ret_orig) {
> +            if (memop & MO_SIGN) {
> +                tcg_gen_exts(ret_orig, ret);

Same two comments from 099/101 apply to this patch.

Reply via email to