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
{