@samitouri / QOSamiQemu / commits / 66220c0e3e

target/ppc: Move Fixed-Point Load/Store String instructions to decodetree.

Move below instructions to decodetree specification : lsw{i, x}, stsw{i, x} : X-form 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. Signed-off-by: Shivang Upadhyay <shivangu@linux.ibm.com> Reviewed-by: Glenn Miles <milesg@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-24-rathc@linux.ibm.com Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>

Shivang Upadhyay committed Aug 27, 2026 at 18:59 UTC 66220c0e3e91c45c2273ff895959e8072560ba18
5 files changed +115 -108
target/ppc/helper.h
+3 -3
@@ -45,9 +45,9 @@ DEF_HELPER_1(check_tlb_flush_global, void, env)
45
46 DEF_HELPER_3(lmw, void, env, tl, i32)
47 DEF_HELPER_FLAGS_3(stmw, TCG_CALL_NO_WG, void, env, tl, i32)
48 -DEF_HELPER_4(lsw, void, env, tl, i32, i32)
49 -DEF_HELPER_5(lswx, void, env, tl, i32, i32, i32)
50 -DEF_HELPER_FLAGS_4(stsw, TCG_CALL_NO_WG, void, env, tl, i32, i32)
48 +DEF_HELPER_4(LSW, void, env, tl, i32, i32)
49 +DEF_HELPER_5(LSWX, void, env, tl, i32, i32, i32)
50 +DEF_HELPER_FLAGS_4(STSW, TCG_CALL_NO_WG, void, env, tl, i32, i32)
51 DEF_HELPER_FLAGS_3(dcbz, TCG_CALL_NO_WG, void, env, tl, int)
52 #ifdef TARGET_PPC64
53 DEF_HELPER_FLAGS_2(dcbzl, TCG_CALL_NO_WG, void, env, tl)
target/ppc/insn32.decode
+7
@@ -527,6 +527,13 @@ CREQV 010011 ..... ..... ..... 0100100001 - @X
527 CRANDC 010011 ..... ..... ..... 0010000001 - @X
528 CRORC 010011 ..... ..... ..... 0110100001 - @X
529
530 +# Fixed Point Move Assist Instructions
531 +
532 +LSWI 011111 ..... ..... ..... 1 001010101 - @X
533 +LSWX 011111 ..... ..... ..... 1 000010101 - @X
534 +STSWI 011111 ..... ..... ..... 1 011010101 - @X
535 +STSWX 011111 ..... ..... ..... 1 010010101 - @X
536 +
537 # Fixed-Point Hash Instructions
538
539 HASHST 011111 ..... ..... ..... 1011010010 . @X_DW
target/ppc/mem_helper.c
+3 -3
@@ -190,7 +190,7 @@ static void do_lsw(CPUPPCState *env, target_ulong addr, uint32_t nb,
190 env->gpr[reg] = val;
191 }
192
193 -void helper_lsw(CPUPPCState *env, target_ulong addr,
193 +void helper_LSW(CPUPPCState *env, target_ulong addr,
194 uint32_t nb, uint32_t reg)
195 {
196 do_lsw(env, addr, nb, reg, GETPC());
@@ -202,7 +202,7 @@ void helper_lsw(CPUPPCState *env, target_ulong addr,
202 * this is valid, but rA won't be loaded. For now, I'll follow the
203 * spec...
204 */
205 -void helper_lswx(CPUPPCState *env, target_ulong addr, uint32_t reg,
205 +void helper_LSWX(CPUPPCState *env, target_ulong addr, uint32_t reg,
206 uint32_t ra, uint32_t rb)
207 {
208 if (likely(xer_bc != 0)) {
@@ -218,7 +218,7 @@ void helper_lswx(CPUPPCState *env, target_ulong addr, uint32_t reg,
218 }
219 }
220
221 -void helper_stsw(CPUPPCState *env, target_ulong addr, uint32_t nb,
221 +void helper_STSW(CPUPPCState *env, target_ulong addr, uint32_t nb,
222 uint32_t reg)
223 {
224 uintptr_t raddr = GETPC();
target/ppc/translate.c
-102
@@ -2595,104 +2595,6 @@ static void gen_stmw(DisasContext *ctx)
2595 gen_helper_stmw(tcg_env, t0, t1);
2596 }
2597
2598 -/*** Integer load and store strings ***/
2599 -
2600 -/* lswi */
2601 -/*
2602 - * PowerPC32 specification says we must generate an exception if rA is
2603 - * in the range of registers to be loaded. In an other hand, IBM says
2604 - * this is valid, but rA won't be loaded. For now, I'll follow the
2605 - * spec...
2606 - */
2607 -static void gen_lswi(DisasContext *ctx)
2608 -{
2609 - TCGv t0;
2610 - TCGv_i32 t1, t2;
2611 - int nb = NB(ctx->opcode);
2612 - int start = rD(ctx->opcode);
2613 - int ra = rA(ctx->opcode);
2614 - int nr;
2615 -
2616 - if (ctx->le_mode) {
2617 - gen_align_no_le(ctx);
2618 - return;
2619 - }
2620 - if (nb == 0) {
2621 - nb = 32;
2622 - }
2623 - nr = DIV_ROUND_UP(nb, 4);
2624 - if (unlikely(lsw_reg_in_range(start, nr, ra))) {
2625 - gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
2626 - return;
2627 - }
2628 - gen_set_access_type(ctx, ACCESS_INT);
2629 - t0 = tcg_temp_new();
2630 - gen_addr_register(ctx, t0);
2631 - t1 = tcg_constant_i32(nb);
2632 - t2 = tcg_constant_i32(start);
2633 - gen_helper_lsw(tcg_env, t0, t1, t2);
2634 -}
2635 -
2636 -/* lswx */
2637 -static void gen_lswx(DisasContext *ctx)
2638 -{
2639 - TCGv t0;
2640 - TCGv_i32 t1, t2, t3;
2641 -
2642 - if (ctx->le_mode) {
2643 - gen_align_no_le(ctx);
2644 - return;
2645 - }
2646 - gen_set_access_type(ctx, ACCESS_INT);
2647 - t0 = tcg_temp_new();
2648 - gen_addr_reg_index(ctx, t0);
2649 - t1 = tcg_constant_i32(rD(ctx->opcode));
2650 - t2 = tcg_constant_i32(rA(ctx->opcode));
2651 - t3 = tcg_constant_i32(rB(ctx->opcode));
2652 - gen_helper_lswx(tcg_env, t0, t1, t2, t3);
2653 -}
2654 -
2655 -/* stswi */
2656 -static void gen_stswi(DisasContext *ctx)
2657 -{
2658 - TCGv t0;
2659 - TCGv_i32 t1, t2;
2660 - int nb = NB(ctx->opcode);
2661 -
2662 - if (ctx->le_mode) {
2663 - gen_align_no_le(ctx);
2664 - return;
2665 - }
2666 - gen_set_access_type(ctx, ACCESS_INT);
2667 - t0 = tcg_temp_new();
2668 - gen_addr_register(ctx, t0);
2669 - if (nb == 0) {
2670 - nb = 32;
2671 - }
2672 - t1 = tcg_constant_i32(nb);
2673 - t2 = tcg_constant_i32(rS(ctx->opcode));
2674 - gen_helper_stsw(tcg_env, t0, t1, t2);
2675 -}
2676 -
2677 -/* stswx */
2678 -static void gen_stswx(DisasContext *ctx)
2679 -{
2680 - TCGv t0;
2681 - TCGv_i32 t1, t2;
2682 -
2683 - if (ctx->le_mode) {
2684 - gen_align_no_le(ctx);
2685 - return;
2686 - }
2687 - gen_set_access_type(ctx, ACCESS_INT);
2688 - t0 = tcg_temp_new();
2689 - gen_addr_reg_index(ctx, t0);
2690 - t1 = tcg_temp_new_i32();
2691 - tcg_gen_trunc_tl_i32(t1, cpu_xer);
2692 - tcg_gen_andi_i32(t1, t1, 0x7F);
2693 - t2 = tcg_constant_i32(rS(ctx->opcode));
2694 - gen_helper_stsw(tcg_env, t0, t1, t2);
2695 -}
2598
2599 #if !defined(CONFIG_USER_ONLY)
2600 static inline void gen_check_tlb_flush(DisasContext *ctx, bool global)
@@ -4901,10 +4803,6 @@ GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
4803 GEN_HANDLER_E(dform3D, 0x3D, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
4804 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
4805 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
4904 -GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
4905 -GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING),
4906 -GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
4907 -GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
4806 /* ISA v3.0 changed the extended opcode from 62 to 30 */
4807 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
4808 #if defined(TARGET_PPC64)
target/ppc/translate/fixedpoint-impl.c.inc
+102
@@ -584,6 +584,108 @@ TRANS(CRANDC, cr_logic_common, tcg_gen_andc_i32);
584 TRANS(CREQV, cr_logic_common, tcg_gen_eqv_i32);
585 TRANS(CRORC, cr_logic_common, tcg_gen_orc_i32);
586
587 +/*** Integer load and store strings ***/
588 +
589 +/* lswi */
590 +static bool trans_LSWI(DisasContext *ctx, arg_LSWI *a)
591 +{
592 + TCGv t0;
593 + TCGv_i32 t1, t2;
594 + int nb = a->rb;
595 + int start = a->rt;
596 + int ra = a->ra;
597 + int nr;
598 +
599 + REQUIRE_INSNS_FLAGS(ctx, STRING);
600 + if (ctx->le_mode) {
601 + gen_align_no_le(ctx);
602 + return true;
603 + }
604 + if (nb == 0) {
605 + nb = 32;
606 + }
607 + nr = DIV_ROUND_UP(nb, 4);
608 + if (unlikely(lsw_reg_in_range(start, nr, ra))) {
609 + gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
610 + return true;
611 + }
612 + gen_set_access_type(ctx, ACCESS_INT);
613 + t0 = do_ea_calc_ra(ctx, ra);
614 + t1 = tcg_constant_i32(nb);
615 + t2 = tcg_constant_i32(start);
616 + gen_helper_LSW(tcg_env, t0, t1, t2);
617 +
618 + return true;
619 +}
620 +
621 +/* lswx */
622 +static bool trans_LSWX(DisasContext *ctx, arg_LSWX *a)
623 +{
624 + TCGv t0;
625 + TCGv_i32 t1, t2, t3;
626 +
627 + REQUIRE_INSNS_FLAGS(ctx, STRING);
628 + if (ctx->le_mode) {
629 + gen_align_no_le(ctx);
630 + return true;
631 + }
632 +
633 + gen_set_access_type(ctx, ACCESS_INT);
634 + t0 = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
635 + t1 = tcg_constant_i32(a->rt);
636 + t2 = tcg_constant_i32(a->ra);
637 + t3 = tcg_constant_i32(a->rb);
638 + gen_helper_LSWX(tcg_env, t0, t1, t2, t3);
639 +
640 + return true;
641 +}
642 +
643 +/* stswi */
644 +static bool trans_STSWI(DisasContext *ctx, arg_STSWI *a)
645 +{
646 + TCGv t0;
647 + TCGv_i32 t1, t2;
648 + int nb = a->rb;
649 +
650 + REQUIRE_INSNS_FLAGS(ctx, STRING);
651 + if (ctx->le_mode) {
652 + gen_align_no_le(ctx);
653 + return true;
654 + }
655 + gen_set_access_type(ctx, ACCESS_INT);
656 + t0 = do_ea_calc_ra(ctx, a->ra);
657 + if (nb == 0) {
658 + nb = 32;
659 + }
660 + t1 = tcg_constant_i32(nb);
661 + t2 = tcg_constant_i32(a->rt);
662 + gen_helper_STSW(tcg_env, t0, t1, t2);
663 +
664 + return true;
665 +}
666 +
667 +/* stswx */
668 +static bool trans_STSWX(DisasContext *ctx, arg_STSWX *a)
669 +{
670 + TCGv t0;
671 + TCGv_i32 t1, t2;
672 +
673 + REQUIRE_INSNS_FLAGS(ctx, STRING);
674 + if (ctx->le_mode) {
675 + gen_align_no_le(ctx);
676 + return true;
677 + }
678 + gen_set_access_type(ctx, ACCESS_INT);
679 + t0 = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
680 + t1 = tcg_temp_new_i32();
681 + tcg_gen_trunc_tl_i32(t1, cpu_xer);
682 + tcg_gen_andi_i32(t1, t1, 0x7F);
683 + t2 = tcg_constant_i32(a->rt);
684 + gen_helper_STSW(tcg_env, t0, t1, t2);
685 +
686 + return true;
687 +}
688 +
689 static bool do_add_D(DisasContext *ctx, arg_D *a, bool add_ca, bool compute_ca,
690 bool compute_ov, bool compute_rc0)
691 {