On 2026/08/26 10:38 AM, Chinmay Rath wrote:
> From: Utkarsh Verma <[email protected]>
> 
> Move the following store conditional instructions to decodetree
> specification:
> 
> stbcx.        : X-form
> sthcx.        : X-form
> stwcx.        : X-form
> stdcx.        : X-form
> stqcx.        : X-form
> 
> The changes were verified by checking that the generated TCG ops remain
> semantically identical to the legacy translation, using logs captured
> with the -d in_asm,op flag.
> 
> Signed-off-by: Utkarsh Verma <[email protected]>
> Reviewed-by: Nikhil Kumar Singh <[email protected]>
> Reviewed-by: Glenn Miles <[email protected]>
> Signed-off-by: Chinmay Rath <[email protected]>
> ---
>  target/ppc/insn32.decode                   |   8 ++
>  target/ppc/translate.c                     | 103 ---------------------
>  target/ppc/translate/fixedpoint-impl.c.inc |  84 +++++++++++++++++
>  3 files changed, 92 insertions(+), 103 deletions(-)

Reviewed-by: Amit Machhiwal <[email protected]>

> 
> diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
> index c51efbfd33..701c66b347 100644
> --- a/target/ppc/insn32.decode
> +++ b/target/ppc/insn32.decode
> @@ -732,6 +732,14 @@ DSCLIQ          111111 ..... ..... ...... 001000010 .   
> @Z22_tap_sh_rc
>  DSCRI           111011 ..... ..... ...... 001100010 .   @Z22_ta_sh_rc
>  DSCRIQ          111111 ..... ..... ...... 001100010 .   @Z22_tap_sh_rc
>  
> +### Store Conditional Instructions
> +
> +STBCX           011111 ..... ..... ..... 1010110110 1   @X
> +STHCX           011111 ..... ..... ..... 1011010110 1   @X
> +STWCX           011111 ..... ..... ..... 0010010110 1   @X
> +STDCX           011111 ..... ..... ..... 0011010110 1   @X
> +STQCX           011111 ..... ..... ..... 0010110110 1   @X
> +
>  ## Vector Exclusive-OR-based Instructions
>  
>  VPMSUMD         000100 ..... ..... ..... 10011001000    @VX
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 60c88a6153..ee14fbfd96 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -3153,104 +3153,6 @@ static void gen_stdat(DisasContext *ctx)
>  }
>  #endif
>  
> -static void gen_conditional_store(DisasContext *ctx, MemOp memop)
> -{
> -    TCGLabel *lfail;
> -    TCGv EA;
> -    TCGv cr0;
> -    TCGv t0;
> -    int rs = rS(ctx->opcode);
> -
> -    lfail = gen_new_label();
> -    EA = tcg_temp_new();
> -    cr0 = tcg_temp_new();
> -    t0 = tcg_temp_new();
> -
> -    tcg_gen_mov_tl(cr0, cpu_so);
> -    gen_set_access_type(ctx, ACCESS_RES);
> -    gen_addr_reg_index(ctx, EA);
> -    tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, lfail);
> -    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_reserve_length, memop_size(memop), 
> lfail);
> -
> -    tcg_gen_atomic_cmpxchg_tl(t0, cpu_reserve, cpu_reserve_val,
> -                              cpu_gpr[rs], ctx->mem_idx,
> -                              DEF_MEMOP(memop) | MO_ALIGN);
> -    tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_reserve_val);
> -    tcg_gen_shli_tl(t0, t0, CRF_EQ_BIT);
> -    tcg_gen_or_tl(cr0, cr0, t0);
> -
> -    gen_set_label(lfail);
> -    tcg_gen_trunc_tl_i32(cpu_crf[0], cr0);
> -    tcg_gen_movi_tl(cpu_reserve, -1);
> -}
> -
> -#define STCX(name, memop)                  \
> -static void gen_##name(DisasContext *ctx)  \
> -{                                          \
> -    gen_conditional_store(ctx, memop);     \
> -}
> -
> -STCX(stbcx_, MO_UB)
> -STCX(sthcx_, MO_UW)
> -STCX(stwcx_, MO_UL)
> -
> -#if defined(TARGET_PPC64)
> -/* stdcx. */
> -STCX(stdcx_, MO_UQ)
> -
> -/* stqcx. */
> -static void gen_stqcx_(DisasContext *ctx)
> -{
> -    TCGLabel *lfail;
> -    TCGv EA, t0, t1;
> -    TCGv cr0;
> -    TCGv_i128 cmp, val;
> -    int rs = rS(ctx->opcode);
> -
> -    if (unlikely(rs & 1)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
> -        return;
> -    }
> -
> -    lfail = gen_new_label();
> -    EA = tcg_temp_new();
> -    cr0 = tcg_temp_new();
> -
> -    tcg_gen_mov_tl(cr0, cpu_so);
> -    gen_set_access_type(ctx, ACCESS_RES);
> -    gen_addr_reg_index(ctx, EA);
> -    tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, lfail);
> -    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_reserve_length, 16, lfail);
> -
> -    cmp = tcg_temp_new_i128();
> -    val = tcg_temp_new_i128();
> -
> -    tcg_gen_concat_i64_i128(cmp, cpu_reserve_val2, cpu_reserve_val);
> -
> -    /* Note that the low part is always in RS+1, even in LE mode.  */
> -    tcg_gen_concat_i64_i128(val, cpu_gpr[rs + 1], cpu_gpr[rs]);
> -
> -    tcg_gen_atomic_cmpxchg_i128(val, cpu_reserve, cmp, val, ctx->mem_idx,
> -                                DEF_MEMOP(MO_128 | MO_ALIGN));
> -
> -    t0 = tcg_temp_new();
> -    t1 = tcg_temp_new();
> -    tcg_gen_extr_i128_i64(t1, t0, val);
> -
> -    tcg_gen_xor_tl(t1, t1, cpu_reserve_val2);
> -    tcg_gen_xor_tl(t0, t0, cpu_reserve_val);
> -    tcg_gen_or_tl(t0, t0, t1);
> -
> -    tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, 0);
> -    tcg_gen_shli_tl(t0, t0, CRF_EQ_BIT);
> -    tcg_gen_or_tl(cr0, cr0, t0);
> -
> -    gen_set_label(lfail);
> -    tcg_gen_trunc_tl_i32(cpu_crf[0], cr0);
> -    tcg_gen_movi_tl(cpu_reserve, -1);
> -}
> -#endif /* defined(TARGET_PPC64) */
> -
>  /* wait */
>  static void gen_wait(DisasContext *ctx)
>  {
> @@ -5899,14 +5801,9 @@ GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, 
> PPC_STRING),
>  GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
>  GEN_HANDLER_E(lwat, 0x1F, 0x06, 0x12, 0x00000001, PPC_NONE, PPC2_ISA300),
>  GEN_HANDLER_E(stwat, 0x1F, 0x06, 0x16, 0x00000001, PPC_NONE, PPC2_ISA300),
> -GEN_HANDLER_E(stbcx_, 0x1F, 0x16, 0x15, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
> -GEN_HANDLER_E(sthcx_, 0x1F, 0x16, 0x16, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
> -GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
>  #if defined(TARGET_PPC64)
>  GEN_HANDLER_E(ldat, 0x1F, 0x06, 0x13, 0x00000001, PPC_NONE, PPC2_ISA300),
>  GEN_HANDLER_E(stdat, 0x1F, 0x06, 0x17, 0x00000001, PPC_NONE, PPC2_ISA300),
> -GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
> -GEN_HANDLER_E(stqcx_, 0x1F, 0x16, 0x05, 0, PPC_NONE, PPC2_LSQ_ISA207),
>  #endif
>  /* ISA v3.0 changed the extended opcode from 62 to 30 */
>  GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x039FF801, PPC_WAIT),
> diff --git a/target/ppc/translate/fixedpoint-impl.c.inc 
> b/target/ppc/translate/fixedpoint-impl.c.inc
> index fa0191e866..91f9c6c391 100644
> --- a/target/ppc/translate/fixedpoint-impl.c.inc
> +++ b/target/ppc/translate/fixedpoint-impl.c.inc
> @@ -204,6 +204,90 @@ TRANS64(PSTD, do_ldst_PLS_D, false, true, MO_UQ)
>  TRANS64(STQ, do_ldst_quad, true, false);
>  TRANS64(PSTQ, do_ldst_quad_PLS_D, true);
>  
> +/* Store Conditional Instructions */
> +
> +static bool do_store_cond(DisasContext *ctx, arg_X *a, MemOp mop)
> +{
> +    TCGLabel *lfail = gen_new_label();
> +    TCGv ea = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
> +    TCGv cr0 = tcg_temp_new();
> +    TCGv t0 = tcg_temp_new();
> +
> +    tcg_gen_mov_tl(cr0, cpu_so);
> +    gen_set_access_type(ctx, ACCESS_RES);
> +
> +    tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_reserve, lfail);
> +    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_reserve_length, memop_size(mop), 
> lfail);
> +
> +    tcg_gen_atomic_cmpxchg_tl(t0, cpu_reserve, cpu_reserve_val,
> +                              cpu_gpr[a->rt], ctx->mem_idx,
> +                              DEF_MEMOP(mop) | MO_ALIGN);
> +    tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_reserve_val);
> +    tcg_gen_shli_tl(t0, t0, CRF_EQ_BIT);
> +    tcg_gen_or_tl(cr0, cr0, t0);
> +
> +    gen_set_label(lfail);
> +    tcg_gen_trunc_tl_i32(cpu_crf[0], cr0);
> +    tcg_gen_movi_tl(cpu_reserve, -1);
> +    return true;
> +}
> +
> +TRANS_FLAGS2(ATOMIC_ISA206, STBCX, do_store_cond, MO_UB);
> +TRANS_FLAGS2(ATOMIC_ISA206, STHCX, do_store_cond, MO_UW);
> +TRANS(STWCX, do_store_cond, MO_UL);
> +TRANS64(STDCX, do_store_cond, MO_UQ);
> +
> +static bool trans_STQCX(DisasContext *ctx, arg_STQCX *a)
> +{
> +    REQUIRE_64BIT(ctx);
> +    REQUIRE_INSNS_FLAGS2(ctx, LSQ_ISA207);
> +#if defined(TARGET_PPC64)
> +    TCGLabel *lfail = gen_new_label();
> +    TCGv ea = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
> +    TCGv t0 = tcg_temp_new();
> +    TCGv t1 = tcg_temp_new();
> +    TCGv cr0 = tcg_temp_new();
> +    TCGv_i128 cmp = tcg_temp_new_i128();
> +    TCGv_i128 val = tcg_temp_new_i128();
> +
> +    if (unlikely(a->rt & 1)) {
> +        gen_invalid(ctx);
> +        return true;
> +    }
> +
> +    tcg_gen_mov_tl(cr0, cpu_so);
> +    gen_set_access_type(ctx, ACCESS_RES);
> +
> +    tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_reserve, lfail);
> +    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_reserve_length, 16, lfail);
> +
> +    tcg_gen_concat_i64_i128(cmp, cpu_reserve_val2, cpu_reserve_val);
> +
> +    /* Note that the low part is always in RS+1, even in LE mode.  */
> +    tcg_gen_concat_i64_i128(val, cpu_gpr[a->rt + 1], cpu_gpr[a->rt]);
> +
> +    tcg_gen_atomic_cmpxchg_i128(val, cpu_reserve, cmp, val, ctx->mem_idx,
> +                                DEF_MEMOP(MO_128 | MO_ALIGN));
> +
> +    tcg_gen_extr_i128_i64(t1, t0, val);
> +
> +    tcg_gen_xor_tl(t1, t1, cpu_reserve_val2);
> +    tcg_gen_xor_tl(t0, t0, cpu_reserve_val);
> +    tcg_gen_or_tl(t0, t0, t1);
> +
> +    tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, 0);
> +    tcg_gen_shli_tl(t0, t0, CRF_EQ_BIT);
> +    tcg_gen_or_tl(cr0, cr0, t0);
> +
> +    gen_set_label(lfail);
> +    tcg_gen_trunc_tl_i32(cpu_crf[0], cr0);
> +    tcg_gen_movi_tl(cpu_reserve, -1);
> +#else
> +    qemu_build_not_reached();
> +#endif
> +    return true;
> +}
> +
>  /*
>   * Fixed-Point Compare Instructions
>   */
> -- 
> 2.55.0
> 

Reply via email to