target/ppc: Move fixed-point Shift insns to decodetree
Move the below instructions to decodetree specification: s{r,l}d, and srad[i] : X-form The changes were verified by validating that the TCG ops generated by these instructions remain the same after these changes. The TCG micro-ops were captured with the '-d op,in_asm' QEMU flag. Move all shift insntructions to one place in insn32.decode Signed-off-by: Sathvika Vasireddy <sv@linux.ibm.com> Signed-off-by: Amit Machhiwal <amachhiw@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-11-rathc@linux.ibm.com Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Amit Machhiwal committed
Aug 27, 2026 at 18:59 UTC
e48c09b73786843c82ede4b6917dbafea2d00dd6
5 files changed
+82
-102
target/ppc/helper.h
+1
-1
@@ -74,7 +74,7 @@ DEF_HELPER_FLAGS_1(CBCDTD, TCG_CALL_NO_RWG_SE, tl, tl)
74
DEF_HELPER_FLAGS_2(CMPEQB, TCG_CALL_NO_RWG_SE, i32, tl, tl)
75
DEF_HELPER_FLAGS_1(POPCNTW, TCG_CALL_NO_RWG_SE, tl, tl)
76
DEF_HELPER_FLAGS_2(BPERMD, TCG_CALL_NO_RWG_SE, i64, i64, i64)
77
-DEF_HELPER_3(srad, tl, env, tl, tl)
77
+DEF_HELPER_3(SRAD, tl, env, tl, tl)
78
DEF_HELPER_FLAGS_0(DARN32, TCG_CALL_NO_RWG, tl)
79
DEF_HELPER_FLAGS_0(DARN64, TCG_CALL_NO_RWG, tl)
80
#endif
target/ppc/insn32.decode
+8
-4
@@ -119,7 +119,7 @@
119
120
# XS-form with fractured shift amount
121
%xs_sh 1:1 11:5
122
-&XS rs ra sh rc
122
+&XS rs ra sh rc:bool
123
@XS ...... rs:5 ra:5 ..... ......... . rc:1 &XS sh=%xs_sh
124
125
%x_frtp 22:4 !function=times_2
@@ -512,6 +512,13 @@ SRW 011111 ..... ..... ..... 1000011000 . @X_rc
512
SRAW 011111 ..... ..... ..... 1100011000 . @X_rc
513
SRAWI 011111 ..... ..... ..... 1100111000 . @X_rc
514
515
+SLD 011111 ..... ..... ..... 0000011011 . @X_rc
516
+SRD 011111 ..... ..... ..... 1000011011 . @X_rc
517
+SRAD 011111 ..... ..... ..... 1100011010 . @X_rc
518
+SRADI 011111 ..... ..... ..... 110011101 . . @XS
519
+
520
+EXTSWSLI 011111 ..... ..... ..... 110111101 . . @XS
521
+
522
## BCD Assist
523
524
ADDG6S 011111 ..... ..... ..... - 001001010 - @X
@@ -1379,9 +1386,6 @@ DST 011111 ----- ..... ..... 0101010110 - @X_ea
1386
DSTST 011111 ----- ..... ..... 0101110110 - @X_ea
1387
DSS 011111 ----- ..... ..... 1100110110 - @X_ea
1388
1382
-##Extend Sign Word and Shift Left Immediate XS-form
1383
-EXTSWSLI 011111 ..... ..... ..... 110111101 . . @XS
1384
-
1389
## Load and Reserve Instructions
1390
LBARX 011111 ..... ..... ..... 0000110100 . @X_rc
1391
LHARX 011111 ..... ..... ..... 0001110100 . @X_rc
target/ppc/int_helper.c
+1
-1
@@ -261,7 +261,7 @@ target_ulong helper_SRAW(CPUPPCState *env, target_ulong value,
261
}
262
263
#if defined(TARGET_PPC64)
264
-target_ulong helper_srad(CPUPPCState *env, target_ulong value,
264
+target_ulong helper_SRAD(CPUPPCState *env, target_ulong value,
265
target_ulong shift)
266
{
267
int64_t ret;
target/ppc/translate.c
-96
@@ -2313,95 +2313,6 @@ static void gen_rldimi(DisasContext *ctx, int mbn, int shn)
2313
GEN_PPC64_R4(rldimi, 0x1E, 0x06);
2314
#endif
2315
2316
-/*** Integer shift ***/
2317
-
2318
-
2319
-#if defined(TARGET_PPC64)
2320
-/* sld & sld. */
2321
-static void gen_sld(DisasContext *ctx)
2322
-{
2323
- TCGv t0, t1;
2324
-
2325
- t0 = tcg_temp_new();
2326
- /* AND rS with a mask that is 0 when rB >= 0x40 */
2327
- tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
2328
- tcg_gen_sari_tl(t0, t0, 0x3f);
2329
- tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2330
- t1 = tcg_temp_new();
2331
- tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
2332
- tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2333
- if (unlikely(Rc(ctx->opcode) != 0)) {
2334
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2335
- }
2336
-}
2337
-
2338
-/* srad & srad. */
2339
-static void gen_srad(DisasContext *ctx)
2340
-{
2341
- gen_helper_srad(cpu_gpr[rA(ctx->opcode)], tcg_env,
2342
- cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2343
- if (unlikely(Rc(ctx->opcode) != 0)) {
2344
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2345
- }
2346
-}
2347
-/* sradi & sradi. */
2348
-static inline void gen_sradi(DisasContext *ctx, int n)
2349
-{
2350
- int sh = SH(ctx->opcode) + (n << 5);
2351
- TCGv dst = cpu_gpr[rA(ctx->opcode)];
2352
- TCGv src = cpu_gpr[rS(ctx->opcode)];
2353
- if (sh == 0) {
2354
- tcg_gen_mov_tl(dst, src);
2355
- tcg_gen_movi_tl(cpu_ca, 0);
2356
- if (is_isa300(ctx)) {
2357
- tcg_gen_movi_tl(cpu_ca32, 0);
2358
- }
2359
- } else {
2360
- TCGv t0;
2361
- tcg_gen_andi_tl(cpu_ca, src, (1ULL << sh) - 1);
2362
- t0 = tcg_temp_new();
2363
- tcg_gen_sari_tl(t0, src, TARGET_LONG_BITS - 1);
2364
- tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
2365
- tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
2366
- if (is_isa300(ctx)) {
2367
- tcg_gen_mov_tl(cpu_ca32, cpu_ca);
2368
- }
2369
- tcg_gen_sari_tl(dst, src, sh);
2370
- }
2371
- if (unlikely(Rc(ctx->opcode) != 0)) {
2372
- gen_set_Rc0(ctx, dst);
2373
- }
2374
-}
2375
-
2376
-static void gen_sradi0(DisasContext *ctx)
2377
-{
2378
- gen_sradi(ctx, 0);
2379
-}
2380
-
2381
-static void gen_sradi1(DisasContext *ctx)
2382
-{
2383
- gen_sradi(ctx, 1);
2384
-}
2385
-
2386
-/* srd & srd. */
2387
-static void gen_srd(DisasContext *ctx)
2388
-{
2389
- TCGv t0, t1;
2390
-
2391
- t0 = tcg_temp_new();
2392
- /* AND rS with a mask that is 0 when rB >= 0x40 */
2393
- tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
2394
- tcg_gen_sari_tl(t0, t0, 0x3f);
2395
- tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2396
- t1 = tcg_temp_new();
2397
- tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
2398
- tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2399
- if (unlikely(Rc(ctx->opcode) != 0)) {
2400
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2401
- }
2402
-}
2403
-#endif
2404
-
2316
/*** Addressing modes ***/
2317
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
2318
static inline void gen_addr_imm_index(DisasContext *ctx, TCGv EA,
@@ -5671,13 +5582,6 @@ GEN_HANDLER_E(paste, 0x1F, 0x06, 0x1C, 0x03C00000, PPC_NONE, PPC2_ISA300),
5582
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
5583
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
5584
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
5674
-#if defined(TARGET_PPC64)
5675
-GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B),
5676
-GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B),
5677
-GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B),
5678
-GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B),
5679
-GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B),
5680
-#endif
5585
/* handles lfdp, lxsd, lxssp */
5586
GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
5587
/* handles stfdp, stxsd, stxssp */
target/ppc/translate/fixedpoint-impl.c.inc
+72
@@ -486,6 +486,76 @@ static bool do_add_const_XO(DisasContext *ctx, arg_XO_ta *a, TCGv const_val,
486
return true;
487
}
488
489
+static bool do_shift_X_rc(DisasContext *ctx, arg_X_rc *a,
490
+ void(*op)(TCGv, TCGv, TCGv))
491
+{
492
+ REQUIRE_64BIT(ctx);
493
+#if defined(TARGET_PPC64)
494
+ TCGv t0 = tcg_temp_new();
495
+ TCGv t1 = tcg_temp_new();
496
+
497
+ /* AND rt with a mask that is 0 when rb >= 0x40 */
498
+ tcg_gen_shli_tl(t0, cpu_gpr[a->rb], 0x39);
499
+ tcg_gen_sari_tl(t0, t0, 0x3f);
500
+ tcg_gen_andc_tl(t0, cpu_gpr[a->rt], t0);
501
+ tcg_gen_andi_tl(t1, cpu_gpr[a->rb], 0x3f);
502
+ op(cpu_gpr[a->ra], t0, t1);
503
+ if (unlikely(a->rc)) {
504
+ gen_set_Rc0(ctx, cpu_gpr[a->ra]);
505
+ }
506
+#else
507
+ qemu_build_not_reached();
508
+#endif
509
+ return true;
510
+}
511
+
512
+static bool trans_SRAD(DisasContext *ctx, arg_SRAD *a)
513
+{
514
+ REQUIRE_64BIT(ctx);
515
+#if defined(TARGET_PPC64)
516
+ gen_helper_SRAD(cpu_gpr[a->ra], tcg_env, cpu_gpr[a->rt], cpu_gpr[a->rb]);
517
+ if (unlikely(a->rc)) {
518
+ gen_set_Rc0(ctx, cpu_gpr[a->ra]);
519
+ }
520
+#else
521
+ qemu_build_not_reached();
522
+#endif
523
+ return true;
524
+}
525
+
526
+static bool trans_SRADI(DisasContext *ctx, arg_SRADI *a)
527
+{
528
+ REQUIRE_64BIT(ctx);
529
+#if defined(TARGET_PPC64)
530
+ int sh = a->sh;
531
+ TCGv dst = cpu_gpr[a->ra];
532
+ TCGv src = cpu_gpr[a->rs];
533
+ if (sh == 0) {
534
+ tcg_gen_mov_tl(dst, src);
535
+ tcg_gen_movi_tl(cpu_ca, 0);
536
+ if (is_isa300(ctx)) {
537
+ tcg_gen_movi_tl(cpu_ca32, 0);
538
+ }
539
+ } else {
540
+ TCGv t0 = tcg_temp_new();
541
+ tcg_gen_andi_tl(cpu_ca, src, (1ULL << sh) - 1);
542
+ tcg_gen_sari_tl(t0, src, TARGET_LONG_BITS - 1);
543
+ tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
544
+ tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
545
+ if (is_isa300(ctx)) {
546
+ tcg_gen_mov_tl(cpu_ca32, cpu_ca);
547
+ }
548
+ tcg_gen_sari_tl(dst, src, sh);
549
+ }
550
+ if (unlikely(a->rc)) {
551
+ gen_set_Rc0(ctx, dst);
552
+ }
553
+#else
554
+ qemu_build_not_reached();
555
+#endif
556
+ return true;
557
+}
558
+
559
TRANS(ADD, do_add_XO, false, false);
560
TRANS(ADDC, do_add_XO, false, true);
561
TRANS(ADDE, do_add_XO, true, true);
@@ -493,6 +563,8 @@ TRANS(ADDME, do_add_const_XO, tcg_constant_tl(-1LL), true, true);
563
TRANS(ADDZE, do_add_const_XO, tcg_constant_tl(0), true, true);
564
TRANS(ADDIC, do_add_D, false, true, false, false);
565
TRANS(ADDIC_, do_add_D, false, true, false, true);
566
+TRANS(SLD, do_shift_X_rc, tcg_gen_shl_tl);
567
+TRANS(SRD, do_shift_X_rc, tcg_gen_shr_tl);
568
569
static bool trans_SUBFIC(DisasContext *ctx, arg_D *a)
570
{