@samitouri / QOSamiQemu / commits / 453b78afa9

target/ppc: Move sleep & friends to decodetree

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 <ojaswin@linux.ibm.com> Reviewed-by: Glenn Miles <milesg@linux.ibm.com> Reviewed-by: Amit Machhiwal <amachhiw@linux.ibm.com> Signed-off-by: Chinmay Rath <rathc@linux.ibm.com> Tested-by: Aniket Sahu <asahu1x@linux.ibm.com> Link: https://lore.kernel.org/qemu-devel/20260827133010.278889-19-rathc@linux.ibm.com Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>

Ojaswin Mujoo committed Aug 27, 2026 at 18:59 UTC 453b78afa9b0c5a09bf3e1618a1c33bb9cf482b4
3 files changed +108 -85
target/ppc/insn32.decode
+8
@@ -913,6 +913,14 @@ VPERMR 000100 ..... ..... ..... ..... 111011 @VA
913
914 VSEL 000100 ..... ..... ..... ..... 101010 @VA
915
916 +## Power Management Instructions
917 +
918 +DOZE 010011 ----- ----- ----- 0110010010 -
919 +NAP 010011 ----- ----- ----- 0110110010 -
920 +SLEEP 010011 ----- ----- ----- 0111010010 -
921 +RVWINKLE 010011 ----- ----- ----- 0111110010 -
922 +STOP 010011 ----- ----- ----- 0101110010 -
923 +
924 ## Vector Integer Shift Instruction
925
926 VSLB 000100 ..... ..... ..... 00100000100 @VX
target/ppc/translate.c
-85
@@ -2728,86 +2728,6 @@ static inline void gen_check_tlb_flush(DisasContext *ctx, bool global) { }
2728 #endif
2729
2730 #if defined(TARGET_PPC64)
2731 -static void gen_doze(DisasContext *ctx)
2732 -{
2733 -#if defined(CONFIG_USER_ONLY)
2734 - GEN_PRIV(ctx);
2735 -#else
2736 - TCGv_i32 t;
2737 -
2738 - CHK_HV(ctx);
2739 - translator_io_start(&ctx->base);
2740 - t = tcg_constant_i32(PPC_PM_DOZE);
2741 - gen_helper_pminsn(tcg_env, t);
2742 - /* Stop translation, as the CPU is supposed to sleep from now */
2743 - gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
2744 -#endif /* defined(CONFIG_USER_ONLY) */
2745 -}
2746 -
2747 -static void gen_nap(DisasContext *ctx)
2748 -{
2749 -#if defined(CONFIG_USER_ONLY)
2750 - GEN_PRIV(ctx);
2751 -#else
2752 - TCGv_i32 t;
2753 -
2754 - CHK_HV(ctx);
2755 - translator_io_start(&ctx->base);
2756 - t = tcg_constant_i32(PPC_PM_NAP);
2757 - gen_helper_pminsn(tcg_env, t);
2758 - /* Stop translation, as the CPU is supposed to sleep from now */
2759 - gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
2760 -#endif /* defined(CONFIG_USER_ONLY) */
2761 -}
2762 -
2763 -static void gen_stop(DisasContext *ctx)
2764 -{
2765 -#if defined(CONFIG_USER_ONLY)
2766 - GEN_PRIV(ctx);
2767 -#else
2768 - TCGv_i32 t;
2769 -
2770 - CHK_HV(ctx);
2771 - translator_io_start(&ctx->base);
2772 - t = tcg_constant_i32(PPC_PM_STOP);
2773 - gen_helper_pminsn(tcg_env, t);
2774 - /* Stop translation, as the CPU is supposed to sleep from now */
2775 - gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
2776 -#endif /* defined(CONFIG_USER_ONLY) */
2777 -}
2778 -
2779 -static void gen_sleep(DisasContext *ctx)
2780 -{
2781 -#if defined(CONFIG_USER_ONLY)
2782 - GEN_PRIV(ctx);
2783 -#else
2784 - TCGv_i32 t;
2785 -
2786 - CHK_HV(ctx);
2787 - translator_io_start(&ctx->base);
2788 - t = tcg_constant_i32(PPC_PM_SLEEP);
2789 - gen_helper_pminsn(tcg_env, t);
2790 - /* Stop translation, as the CPU is supposed to sleep from now */
2791 - gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
2792 -#endif /* defined(CONFIG_USER_ONLY) */
2793 -}
2794 -
2795 -static void gen_rvwinkle(DisasContext *ctx)
2796 -{
2797 -#if defined(CONFIG_USER_ONLY)
2798 - GEN_PRIV(ctx);
2799 -#else
2800 - TCGv_i32 t;
2801 -
2802 - CHK_HV(ctx);
2803 - translator_io_start(&ctx->base);
2804 - t = tcg_constant_i32(PPC_PM_RVWINKLE);
2805 - gen_helper_pminsn(tcg_env, t);
2806 - /* Stop translation, as the CPU is supposed to sleep from now */
2807 - gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
2808 -#endif /* defined(CONFIG_USER_ONLY) */
2809 -}
2810 -
2731 static inline TCGv gen_write_bhrb(TCGv_ptr base, TCGv offset, TCGv mask, TCGv value)
2732 {
2733 TCGv_ptr tmp = tcg_temp_new_ptr();
@@ -5104,11 +5024,6 @@ GEN_HANDLER_E(scv, 0x11, 0x10, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300),
5024 GEN_HANDLER_E(scv, 0x11, 0x00, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300),
5025 GEN_HANDLER_E(rfscv, 0x13, 0x12, 0x02, 0x03FF8001, PPC_NONE, PPC2_ISA300),
5026 #endif
5107 -GEN_HANDLER_E(stop, 0x13, 0x12, 0x0b, 0x03FFF801, PPC_NONE, PPC2_ISA300),
5108 -GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
5109 -GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
5110 -GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
5111 -GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
5027 GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
5028 #endif
5029 /* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */
target/ppc/translate/processor-ctrl-impl.c.inc
+100
@@ -103,3 +103,103 @@ static bool trans_MSGSYNC(DisasContext *ctx, arg_MSGSYNC *a)
103 /* interpreted as no-op */
104 return true;
105 }
106 +
107 +static bool do_doze(DisasContext *ctx, arg_DOZE *a)
108 +{
109 + REQUIRE_64BIT(ctx);
110 +
111 +#if defined(CONFIG_USER_ONLY)
112 + gen_priv_opc(ctx);
113 +#else
114 + TCGv_i32 t;
115 +
116 + REQUIRE_HV(ctx);
117 + translator_io_start(&ctx->base);
118 + t = tcg_constant_i32(PPC_PM_DOZE);
119 + gen_helper_pminsn(tcg_env, t);
120 + /* Stop translation, as the CPU is supposed to sleep from now */
121 + gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
122 +#endif /* defined(CONFIG_USER_ONLY) */
123 + return true;
124 +}
125 +TRANS_FLAGS2(PM_ISA206, DOZE, do_doze);
126 +
127 +static bool do_nap(DisasContext *ctx, arg_NAP *a)
128 +{
129 + REQUIRE_64BIT(ctx);
130 +
131 +#if defined(CONFIG_USER_ONLY)
132 + gen_priv_opc(ctx);
133 +#else
134 + TCGv_i32 t;
135 +
136 + REQUIRE_HV(ctx);
137 + translator_io_start(&ctx->base);
138 + t = tcg_constant_i32(PPC_PM_NAP);
139 + gen_helper_pminsn(tcg_env, t);
140 + /* Stop translation, as the CPU is supposed to sleep from now */
141 + gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
142 +#endif /* defined(CONFIG_USER_ONLY) */
143 + return true;
144 +}
145 +TRANS_FLAGS2(PM_ISA206, NAP, do_nap);
146 +
147 +static bool do_sleep(DisasContext *ctx, arg_SLEEP *a)
148 +{
149 + REQUIRE_64BIT(ctx);
150 +
151 +#if defined(CONFIG_USER_ONLY)
152 + gen_priv_opc(ctx);
153 +#else
154 + TCGv_i32 t;
155 +
156 + REQUIRE_HV(ctx);
157 + translator_io_start(&ctx->base);
158 + t = tcg_constant_i32(PPC_PM_SLEEP);
159 + gen_helper_pminsn(tcg_env, t);
160 + /* Stop translation, as the CPU is supposed to sleep from now */
161 + gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
162 +#endif /* defined(CONFIG_USER_ONLY) */
163 + return true;
164 +}
165 +TRANS_FLAGS2(PM_ISA206, SLEEP, do_sleep);
166 +
167 +static bool do_rvwinkle(DisasContext *ctx, arg_RVWINKLE *a)
168 +{
169 + REQUIRE_64BIT(ctx);
170 +
171 +#if defined(CONFIG_USER_ONLY)
172 + gen_priv_opc(ctx);
173 +#else
174 + TCGv_i32 t;
175 +
176 + REQUIRE_HV(ctx);
177 + translator_io_start(&ctx->base);
178 + t = tcg_constant_i32(PPC_PM_RVWINKLE);
179 + gen_helper_pminsn(tcg_env, t);
180 + /* Stop translation, as the CPU is supposed to sleep from now */
181 + gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
182 +#endif /* defined(CONFIG_USER_ONLY) */
183 + return true;
184 +}
185 +TRANS_FLAGS2(PM_ISA206, RVWINKLE, do_rvwinkle);
186 +
187 +static bool do_stop(DisasContext *ctx, arg_STOP *a)
188 +{
189 + REQUIRE_64BIT(ctx);
190 +
191 +#if defined(CONFIG_USER_ONLY)
192 + gen_priv_opc(ctx);
193 +#else
194 + TCGv_i32 t;
195 +
196 + REQUIRE_HV(ctx);
197 + translator_io_start(&ctx->base);
198 + t = tcg_constant_i32(PPC_PM_STOP);
199 + gen_helper_pminsn(tcg_env, t);
200 + /* Stop translation, as the CPU is supposed to sleep from now */
201 + gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
202 +#endif /* defined(CONFIG_USER_ONLY) */
203 + return true;
204 +}
205 +TRANS_FLAGS2(ISA300, STOP, do_stop);