@samitouri / QOSamiQemu / commits / bfaa88910d

target/ppc: Move system call and rfi instructions to decodetree

Moving the following instructions to decodetree specification: sc, scv : SC-form rfi, rfid, rfscv, hrfid : XL-form This builds upon the previous work that moved mfmsr and mtmsr[d] instructions to decodetree. The changes were verified by validating that the tcg ops generated by those instructions remain the same, which were captured with the `-d in_asm,op` flag, and also by booting a pseries qemu guest. This also includes improvements from review feedback: - Rename helpers to uppercase (RFI/RFID/RFSCV/HRFID) to match ISA mnemonics - Add TRANS64_FLAGS() macro variants - Add REQUIRE_INSNS_FLAGS_NOT() check for flag exclusion - Specify lev field as uint8_t in SC instruction format - Remove redundant masking in SCV since lev is already 7-bit - Replace TARGET_PPC64 ifdefs with REQUIRE_64BIT() macro - Gate SC, SCV, RFI, RFID, RFSCV, and HRFID with appropriate flags - Consolidate CONFIG_USER_ONLY guards into single block Signed-off-by: Vishal Chourasia <vishalc@linux.ibm.com> Reviewed-by: Glenn Miles <milesg@linux.ibm.com> Signed-off-by: Chinmay Rath <rathc@linux.ibm.com> Reviewed-by: Amit Machhiwal <amachhiw@linux.ibm.com> Tested-by: Aniket Sahu <asahu1x@linux.ibm.com> Link: https://lore.kernel.org/qemu-devel/20260827133010.278889-30-rathc@linux.ibm.com Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>

Vishal Chourasia committed Aug 27, 2026 at 18:59 UTC bfaa88910d289fee673054cceed124cbb5068242
5 files changed +128 -127
target/ppc/helper.h
+4 -4
@@ -11,7 +11,7 @@ DEF_HELPER_4(HASHCHKP, void, env, tl, tl, tl)
11 #if !defined(CONFIG_USER_ONLY)
12 DEF_HELPER_2(store_msr, void, env, tl)
13 DEF_HELPER_1(ppc_maybe_interrupt, void, env)
14 -DEF_HELPER_1(rfi, void, env)
14 +DEF_HELPER_1(RFI, void, env)
15 DEF_HELPER_1(40x_rfci, void, env)
16 DEF_HELPER_1(rfci, void, env)
17 DEF_HELPER_1(rfdi, void, env)
@@ -19,9 +19,9 @@ DEF_HELPER_1(rfmci, void, env)
19 #if defined(TARGET_PPC64)
20 DEF_HELPER_2(scv, noreturn, env, i32)
21 DEF_HELPER_2(PMINSN, void, env, i32)
22 -DEF_HELPER_1(rfid, void, env)
23 -DEF_HELPER_1(rfscv, void, env)
24 -DEF_HELPER_1(hrfid, void, env)
22 +DEF_HELPER_1(RFID, void, env)
23 +DEF_HELPER_1(RFSCV, void, env)
24 +DEF_HELPER_1(HRFID, void, env)
25 DEF_HELPER_2(rfebb, void, env, tl)
26 DEF_HELPER_2(store_lpcr, void, env, tl)
27 DEF_HELPER_2(store_pcr, void, env, tl)
target/ppc/insn32.decode
+11
@@ -199,6 +199,9 @@
199 &X_rs_l rs l:bool
200 @X_rs_l ...... rs:5 .... l:1 ..... .......... . &X_rs_l
201
202 +&SC lev:uint8_t
203 +@SC ...... ..... ..... .... lev:7 ... . . &SC
204 +
205 &X_uim5 xt uim:uint8_t
206 @X_uim5 ...... ..... ..... uim:5 .......... . &X_uim5 xt=%x_xt
207
@@ -320,6 +323,14 @@ MFMSR 011111 ..... ----- ----- 0001010011 - @X_t
323 MTMSR 011111 ..... ---- . ----- 0010010010 - @X_rs_l
324 MTMSRD 011111 ..... ---- . ----- 0010110010 - @X_rs_l
325
326 +### System Call and Return from Interrupt
327 +SC 010001 ----- ----- ---- ....... --- 1 - @SC
328 +SCV 010001 ----- ----- ---- ....... --- 0 1 @SC
329 +RFI 010011 ----- ----- ----- 0000110010 -
330 +RFID 010011 ----- ----- ----- 0000010010 -
331 +RFSCV 010011 ----- ----- ----- 0001010010 -
332 +HRFID 010011 ----- ----- ----- 0100010010 -
333 +
334 ### Fixed-Point Byte-Reverse Instructions
335 BRW 011111 ..... ..... ----- 0010011011 - @X_sa
336 BRD 011111 ..... ..... ----- 0010111011 - @X_sa
target/ppc/tcg-excp_helper.c
+4 -4
@@ -528,13 +528,13 @@ static void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
528 check_tlb_flush(env, false);
529 }
530
531 -void helper_rfi(CPUPPCState *env)
531 +void helper_RFI(CPUPPCState *env)
532 {
533 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
534 }
535
536 #ifdef TARGET_PPC64
537 -void helper_rfid(CPUPPCState *env)
537 +void helper_RFID(CPUPPCState *env)
538 {
539 /*
540 * The architecture defines a number of rules for which bits can
@@ -545,12 +545,12 @@ void helper_rfid(CPUPPCState *env)
545 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
546 }
547
548 -void helper_rfscv(CPUPPCState *env)
548 +void helper_RFSCV(CPUPPCState *env)
549 {
550 do_rfi(env, env->lr, env->ctr);
551 }
552
553 -void helper_hrfid(CPUPPCState *env)
553 +void helper_HRFID(CPUPPCState *env)
554 {
555 do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
556 }
target/ppc/translate.c
+7 -119
@@ -2679,110 +2679,6 @@ static inline void gen_setlr(DisasContext *ctx, target_ulong nip)
2679 tcg_gen_movi_tl(cpu_lr, nip);
2680 }
2681
2682 -/*** System linkage ***/
2683 -
2684 -/* rfi (supervisor only) */
2685 -static void gen_rfi(DisasContext *ctx)
2686 -{
2687 -#if defined(CONFIG_USER_ONLY)
2688 - GEN_PRIV(ctx);
2689 -#else
2690 - /*
2691 - * This instruction doesn't exist anymore on 64-bit server
2692 - * processors compliant with arch 2.x
2693 - */
2694 - if (is_book3s_arch2x(ctx)) {
2695 - gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2696 - return;
2697 - }
2698 - /* Restore CPU state */
2699 - CHK_SV(ctx);
2700 - translator_io_start(&ctx->base);
2701 - gen_update_branch_history(ctx, ctx->cia, NULL, BHRB_TYPE_NORECORD);
2702 - gen_helper_rfi(tcg_env);
2703 - ctx->base.is_jmp = DISAS_EXIT;
2704 -#endif
2705 -}
2706 -
2707 -#if defined(TARGET_PPC64)
2708 -static void gen_rfid(DisasContext *ctx)
2709 -{
2710 -#if defined(CONFIG_USER_ONLY)
2711 - GEN_PRIV(ctx);
2712 -#else
2713 - /* Restore CPU state */
2714 - CHK_SV(ctx);
2715 - translator_io_start(&ctx->base);
2716 - gen_update_branch_history(ctx, ctx->cia, NULL, BHRB_TYPE_NORECORD);
2717 - gen_helper_rfid(tcg_env);
2718 - ctx->base.is_jmp = DISAS_EXIT;
2719 -#endif
2720 -}
2721 -
2722 -#if !defined(CONFIG_USER_ONLY)
2723 -static void gen_rfscv(DisasContext *ctx)
2724 -{
2725 -#if defined(CONFIG_USER_ONLY)
2726 - GEN_PRIV(ctx);
2727 -#else
2728 - /* Restore CPU state */
2729 - CHK_SV(ctx);
2730 - translator_io_start(&ctx->base);
2731 - gen_update_branch_history(ctx, ctx->cia, NULL, BHRB_TYPE_NORECORD);
2732 - gen_helper_rfscv(tcg_env);
2733 - ctx->base.is_jmp = DISAS_EXIT;
2734 -#endif
2735 -}
2736 -#endif
2737 -
2738 -static void gen_hrfid(DisasContext *ctx)
2739 -{
2740 -#if defined(CONFIG_USER_ONLY)
2741 - GEN_PRIV(ctx);
2742 -#else
2743 - /* Restore CPU state */
2744 - CHK_HV(ctx);
2745 - translator_io_start(&ctx->base);
2746 - gen_helper_hrfid(tcg_env);
2747 - ctx->base.is_jmp = DISAS_EXIT;
2748 -#endif
2749 -}
2750 -#endif
2751 -
2752 -/* sc */
2753 -#if defined(CONFIG_USER_ONLY)
2754 -#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
2755 -#else
2756 -#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
2757 -#endif
2758 -static void gen_sc(DisasContext *ctx)
2759 -{
2760 - uint32_t lev;
2761 -
2762 - /*
2763 - * LEV is a 7-bit field, but the top 6 bits are treated as a reserved
2764 - * field (i.e., ignored). ISA v3.1 changes that to 5 bits, but that is
2765 - * for Ultravisor which TCG does not support, so just ignore the top 6.
2766 - */
2767 - lev = (ctx->opcode >> 5) & 0x1;
2768 - gen_exception_err(ctx, POWERPC_SYSCALL, lev);
2769 -}
2770 -
2771 -#if defined(TARGET_PPC64)
2772 -#if !defined(CONFIG_USER_ONLY)
2773 -static void gen_scv(DisasContext *ctx)
2774 -{
2775 - uint32_t lev = (ctx->opcode >> 5) & 0x7F;
2776 -
2777 - /* Set the PC back to the faulting instruction. */
2778 - gen_update_nip(ctx, ctx->cia);
2779 - gen_helper_scv(tcg_env, tcg_constant_i32(lev));
2780 -
2781 - ctx->base.is_jmp = DISAS_NORETURN;
2782 -}
2783 -#endif
2784 -#endif
2785 -
2682 /*** Trap ***/
2683
2684 /* Check for unconditional traps (always or never) */
@@ -4155,6 +4051,13 @@ static int64_t dw_compose_ea(DisasContext *ctx, int x)
4051 #define TRANS64(NAME, FUNC, ...) \
4052 static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
4053 { REQUIRE_64BIT(ctx); return FUNC(ctx, a, ##__VA_ARGS__); }
4054 +#define TRANS64_FLAGS(FLAGS, NAME, FUNC, ...) \
4055 + static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
4056 + { \
4057 + REQUIRE_64BIT(ctx); \
4058 + REQUIRE_INSNS_FLAGS(ctx, FLAGS); \
4059 + return FUNC(ctx, a, ##__VA_ARGS__); \
4060 + }
4061 #define TRANS64_FLAGS2(FLAGS2, NAME, FUNC, ...) \
4062 static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
4063 { \
@@ -4529,21 +4432,6 @@ GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
4432 GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
4433 /* handles stfdp, stxsd, stxssp */
4434 GEN_HANDLER_E(dform3D, 0x3D, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
4532 -/* ISA v3.0 changed the extended opcode from 62 to 30 */
4533 -GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
4534 -#if defined(TARGET_PPC64)
4535 -GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
4536 -#if !defined(CONFIG_USER_ONLY)
4537 -/* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */
4538 -GEN_HANDLER_E(scv, 0x11, 0x10, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300),
4539 -GEN_HANDLER_E(scv, 0x11, 0x00, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300),
4540 -GEN_HANDLER_E(rfscv, 0x13, 0x12, 0x02, 0x03FF8001, PPC_NONE, PPC2_ISA300),
4541 -#endif
4542 -GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
4543 -#endif
4544 -/* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */
4545 -GEN_HANDLER(sc, 0x11, 0x11, 0xFF, 0x03FFF01D, PPC_FLOW),
4546 -GEN_HANDLER(sc, 0x11, 0x01, 0xFF, 0x03FFF01D, PPC_FLOW),
4435 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
4436 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
4437 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
target/ppc/translate/misc-impl.c.inc
+102
@@ -225,3 +225,105 @@ static bool do_mtmsr(DisasContext *ctx, arg_X_rs_l *a, bool is_mtmsrd)
225
226 TRANS_FLAGS(MISC, MTMSR, do_mtmsr, false)
227 TRANS64(MTMSRD, do_mtmsr, true)
228 +
229 +/*
230 + * System Call and Return from Interrupt Instructions
231 + */
232 +
233 +static bool do_SC(DisasContext *ctx, arg_SC *a, uint32_t excp)
234 +{
235 + uint32_t lev;
236 +
237 + /*
238 + * LEV is a 7-bit field, but the top 6 bits are treated as a reserved
239 + * field (i.e., ignored). ISA v3.1 changes that to 5 bits, but that is
240 + * for Ultravisor which TCG does not support, so just ignore the top 6.
241 + */
242 + lev = a->lev & 0x1;
243 + gen_exception_err(ctx, excp, lev);
244 + return true;
245 +}
246 +
247 +static bool do_SCV(DisasContext *ctx, arg_SC *a)
248 +{
249 +#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
250 + /* Set the PC back to the faulting instruction. */
251 + gen_update_nip(ctx, ctx->cia);
252 + gen_helper_scv(tcg_env, tcg_constant_i32(a->lev));
253 +
254 + ctx->base.is_jmp = DISAS_NORETURN;
255 + return true;
256 +#else
257 + gen_invalid(ctx);
258 + return true;
259 +#endif
260 +}
261 +
262 +/*
263 + * Common helper for return-from-interrupt instructions
264 + */
265 +enum {
266 + RFI_KIND_RFI = 0,
267 + RFI_KIND_RFID = 1,
268 + RFI_KIND_HRFID = 2,
269 + RFI_KIND_RFSCV = 3,
270 +};
271 +
272 +static bool do_rfi(DisasContext *ctx, arg_RFID *a, int kind)
273 +{
274 +#if defined(CONFIG_USER_ONLY)
275 + gen_priv_opc(ctx);
276 + return true;
277 +#else
278 + void (*helper)(TCGv_ptr);
279 +
280 + switch (kind) {
281 + case RFI_KIND_RFI:
282 + if (is_book3s_arch2x(ctx)) {
283 + gen_invalid(ctx);
284 + return true;
285 + }
286 + REQUIRE_SV(ctx);
287 + helper = gen_helper_RFI;
288 + break;
289 +#if defined(TARGET_PPC64)
290 + case RFI_KIND_HRFID:
291 + REQUIRE_HV(ctx);
292 + helper = gen_helper_HRFID;
293 + break;
294 + case RFI_KIND_RFID:
295 + REQUIRE_SV(ctx);
296 + helper = gen_helper_RFID;
297 + break;
298 + case RFI_KIND_RFSCV:
299 + REQUIRE_SV(ctx);
300 + helper = gen_helper_RFSCV;
301 + break;
302 +#endif
303 + default:
304 + gen_invalid(ctx);
305 + return true;
306 + }
307 +
308 + translator_io_start(&ctx->base);
309 + if (kind != RFI_KIND_HRFID) {
310 + gen_update_branch_history(ctx, ctx->cia, NULL, BHRB_TYPE_NORECORD);
311 + }
312 + helper(tcg_env);
313 + ctx->base.is_jmp = DISAS_EXIT;
314 + return true;
315 +#endif
316 +}
317 +
318 +#if defined(CONFIG_USER_ONLY)
319 +TRANS_FLAGS(FLOW, SC, do_SC, POWERPC_EXCP_SYSCALL_USER)
320 +#else
321 +TRANS_FLAGS(FLOW, SC, do_SC, POWERPC_EXCP_SYSCALL)
322 +#endif
323 +
324 +TRANS64_FLAGS2(ISA300, SCV, do_SCV)
325 +
326 +TRANS_FLAGS(FLOW, RFI, do_rfi, RFI_KIND_RFI)
327 +TRANS64(RFID, do_rfi, RFI_KIND_RFID)
328 +TRANS64_FLAGS(64H, HRFID, do_rfi, RFI_KIND_HRFID)
329 +TRANS64_FLAGS2(ISA300, RFSCV, do_rfi, RFI_KIND_RFSCV)