On 2026/08/26 10:38 AM, Chinmay Rath wrote:
> From: Ojaswin Mujoo <[email protected]>
> 
> Convert the following instructions to decode tree specification:
> 
> doze
> nap
> sleep
> rvwinkle
> stop
> 
> The functionality was tested by comparing the qemu -D log -d op,in_asm
> output as well as single stepping gdb to confirm behavior was not
> changed for ISA3.x (stop) as well as ISA206 (doze, nap, sleep,
> rvwinkle).
> 
> Signed-off-by: Ojaswin Mujoo <[email protected]>
> Reviewed-by: Glenn Miles <[email protected]>
> Signed-off-by: Chinmay Rath <[email protected]>
> ---
>  target/ppc/insn32.decode                      |   8 ++
>  target/ppc/translate.c                        |  85 ---------------
>  .../ppc/translate/processor-ctrl-impl.c.inc   | 101 ++++++++++++++++++
>  3 files changed, 109 insertions(+), 85 deletions(-)
> 
> diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
> index 3b8387b60c..d23168a303 100644
> --- a/target/ppc/insn32.decode
> +++ b/target/ppc/insn32.decode
> @@ -913,6 +913,14 @@ VPERMR          000100 ..... ..... ..... ..... 111011   
> @VA
>  
>  VSEL            000100 ..... ..... ..... ..... 101010   @VA
>  
> +## Power Management Instructions
> +
> +DOZE            010011 ----- ----- ----- 0110010010 -
> +NAP             010011 ----- ----- ----- 0110110010 -
> +SLEEP           010011 ----- ----- ----- 0111010010 -
> +RVWINKLE        010011 ----- ----- ----- 0111110010 -
> +STOP            010011 ----- ----- ----- 0101110010 -
> +
>  ## Vector Integer Shift Instruction
>  
>  VSLB            000100 ..... ..... ..... 00100000100    @VX
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 2d5157080c..f6f7bb4e6b 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -2728,86 +2728,6 @@ static inline void gen_check_tlb_flush(DisasContext 
> *ctx, bool global) { }
>  #endif
>  
>  #if defined(TARGET_PPC64)
> -static void gen_doze(DisasContext *ctx)
> -{
> -#if defined(CONFIG_USER_ONLY)
> -    GEN_PRIV(ctx);
> -#else
> -    TCGv_i32 t;
> -
> -    CHK_HV(ctx);
> -    translator_io_start(&ctx->base);
> -    t = tcg_constant_i32(PPC_PM_DOZE);
> -    gen_helper_pminsn(tcg_env, t);
> -    /* Stop translation, as the CPU is supposed to sleep from now */
> -    gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
> -#endif /* defined(CONFIG_USER_ONLY) */
> -}
> -
> -static void gen_nap(DisasContext *ctx)
> -{
> -#if defined(CONFIG_USER_ONLY)
> -    GEN_PRIV(ctx);
> -#else
> -    TCGv_i32 t;
> -
> -    CHK_HV(ctx);
> -    translator_io_start(&ctx->base);
> -    t = tcg_constant_i32(PPC_PM_NAP);
> -    gen_helper_pminsn(tcg_env, t);
> -    /* Stop translation, as the CPU is supposed to sleep from now */
> -    gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
> -#endif /* defined(CONFIG_USER_ONLY) */
> -}
> -
> -static void gen_stop(DisasContext *ctx)
> -{
> -#if defined(CONFIG_USER_ONLY)
> -    GEN_PRIV(ctx);
> -#else
> -    TCGv_i32 t;
> -
> -    CHK_HV(ctx);
> -    translator_io_start(&ctx->base);
> -    t = tcg_constant_i32(PPC_PM_STOP);
> -    gen_helper_pminsn(tcg_env, t);
> -    /* Stop translation, as the CPU is supposed to sleep from now */
> -    gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
> -#endif /* defined(CONFIG_USER_ONLY) */
> -}
> -
> -static void gen_sleep(DisasContext *ctx)
> -{
> -#if defined(CONFIG_USER_ONLY)
> -    GEN_PRIV(ctx);
> -#else
> -    TCGv_i32 t;
> -
> -    CHK_HV(ctx);
> -    translator_io_start(&ctx->base);
> -    t = tcg_constant_i32(PPC_PM_SLEEP);
> -    gen_helper_pminsn(tcg_env, t);
> -    /* Stop translation, as the CPU is supposed to sleep from now */
> -    gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
> -#endif /* defined(CONFIG_USER_ONLY) */
> -}
> -
> -static void gen_rvwinkle(DisasContext *ctx)
> -{
> -#if defined(CONFIG_USER_ONLY)
> -    GEN_PRIV(ctx);
> -#else
> -    TCGv_i32 t;
> -
> -    CHK_HV(ctx);
> -    translator_io_start(&ctx->base);
> -    t = tcg_constant_i32(PPC_PM_RVWINKLE);
> -    gen_helper_pminsn(tcg_env, t);
> -    /* Stop translation, as the CPU is supposed to sleep from now */
> -    gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
> -#endif /* defined(CONFIG_USER_ONLY) */
> -}
> -
>  static inline TCGv gen_write_bhrb(TCGv_ptr base, TCGv offset, TCGv mask, 
> TCGv value)
>  {
>      TCGv_ptr tmp = tcg_temp_new_ptr();
> @@ -5117,11 +5037,6 @@ GEN_HANDLER_E(scv, 0x11, 0x10, 0xFF, 0x03FFF01E, 
> PPC_NONE, PPC2_ISA300),
>  GEN_HANDLER_E(scv, 0x11, 0x00, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300),
>  GEN_HANDLER_E(rfscv, 0x13, 0x12, 0x02, 0x03FF8001, PPC_NONE, PPC2_ISA300),
>  #endif
> -GEN_HANDLER_E(stop, 0x13, 0x12, 0x0b, 0x03FFF801, PPC_NONE, PPC2_ISA300),
> -GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
> -GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
> -GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
> -GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, 
> PPC2_PM_ISA206),
>  GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
>  #endif
>  /* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */
> diff --git a/target/ppc/translate/processor-ctrl-impl.c.inc 
> b/target/ppc/translate/processor-ctrl-impl.c.inc
> index 8abbb89630..bdbc195294 100644
> --- a/target/ppc/translate/processor-ctrl-impl.c.inc
> +++ b/target/ppc/translate/processor-ctrl-impl.c.inc
> @@ -103,3 +103,104 @@ static bool trans_MSGSYNC(DisasContext *ctx, 
> arg_MSGSYNC *a)
>      /* interpreted as no-op */
>      return true;
>  }
> +
> +static bool do_doze(DisasContext *ctx, arg_DOZE *a)
> +{
> +    REQUIRE_64BIT(ctx);
> +
> +#if defined(CONFIG_USER_ONLY)
> +    gen_priv_opc(ctx);
> +#else
> +    TCGv_i32 t;
> +
> +    REQUIRE_HV(ctx);
> +    translator_io_start(&ctx->base);
> +    t = tcg_constant_i32(PPC_PM_DOZE);
> +    gen_helper_pminsn(tcg_env, t);
> +    /* Stop translation, as the CPU is supposed to sleep from now */
> +    gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
> +#endif /* defined(CONFIG_USER_ONLY) */
> +

Nit: Inconsistent blank line

> +    return true;
> +}
> +TRANS_FLAGS2(PM_ISA206, DOZE, do_doze);
> +
> +static bool do_nap(DisasContext *ctx, arg_NAP *a)
> +{
> +    REQUIRE_64BIT(ctx);
> +
> +#if defined(CONFIG_USER_ONLY)
> +    gen_priv_opc(ctx);
> +#else
> +    TCGv_i32 t;
> +
> +    REQUIRE_HV(ctx);
> +    translator_io_start(&ctx->base);
> +    t = tcg_constant_i32(PPC_PM_NAP);
> +    gen_helper_pminsn(tcg_env, t);
> +    /* Stop translation, as the CPU is supposed to sleep from now */
> +    gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
> +#endif /* defined(CONFIG_USER_ONLY) */
> +    return true;
> +}
> +TRANS_FLAGS2(PM_ISA206, NAP, do_nap);
> +
> +static bool do_sleep(DisasContext *ctx, arg_SLEEP *a)
> +{
> +    REQUIRE_64BIT(ctx);
> +
> +#if defined(CONFIG_USER_ONLY)
> +    gen_priv_opc(ctx);
> +#else
> +    TCGv_i32 t;
> +
> +    REQUIRE_HV(ctx);
> +    translator_io_start(&ctx->base);
> +    t = tcg_constant_i32(PPC_PM_SLEEP);
> +    gen_helper_pminsn(tcg_env, t);
> +    /* Stop translation, as the CPU is supposed to sleep from now */
> +    gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
> +#endif /* defined(CONFIG_USER_ONLY) */
> +    return true;
> +}
> +TRANS_FLAGS2(PM_ISA206, SLEEP, do_sleep);
> +
> +static bool do_rvwinkle(DisasContext *ctx, arg_RVWINKLE *a)
> +{
> +    REQUIRE_64BIT(ctx);
> +
> +#if defined(CONFIG_USER_ONLY)
> +    gen_priv_opc(ctx);
> +#else
> +    TCGv_i32 t;
> +
> +    REQUIRE_HV(ctx);
> +    translator_io_start(&ctx->base);
> +    t = tcg_constant_i32(PPC_PM_RVWINKLE);
> +    gen_helper_pminsn(tcg_env, t);
> +    /* Stop translation, as the CPU is supposed to sleep from now */
> +    gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
> +#endif /* defined(CONFIG_USER_ONLY) */
> +    return true;
> +}
> +TRANS_FLAGS2(PM_ISA206, RVWINKLE, do_rvwinkle);
> +
> +static bool do_stop(DisasContext *ctx, arg_STOP *a)
> +{
> +    REQUIRE_64BIT(ctx);
> +
> +#if defined(CONFIG_USER_ONLY)
> +    gen_priv_opc(ctx);
> +#else
> +    TCGv_i32 t;
> +
> +    REQUIRE_HV(ctx);
> +    translator_io_start(&ctx->base);
> +    t = tcg_constant_i32(PPC_PM_STOP);
> +    gen_helper_pminsn(tcg_env, t);
> +    /* Stop translation, as the CPU is supposed to sleep from now */
> +    gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
> +#endif

Nit: Can be replaced with:

 #endif /* defined(CONFIG_USER_ONLY) */ 

..consistent with other 3 patches and for better readability. Rest LGTM.

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

> +    return true;
> +}
> +TRANS_FLAGS2(ISA300, STOP, do_stop);
> -- 
> 2.55.0
> 

Reply via email to