From: Tanushree Shah <[email protected]> -Moving the following instructions to decodetree specification: rlwimi : M-form rlwimi. : M-form rlwinm : M-form rlwinm. : M-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.
Additionally, validated using small assembly tests confirming the destination register is correctly updated based on rotated and masked source values and confirmed that the value was same before and after the change Signed-off-by: Tanushree Shah <[email protected]> Reviewed-by: Glenn Miles <[email protected]> Signed-off-by: Chinmay Rath <[email protected]> Reviewed-by: Amit Machhiwal <[email protected]> Tested-by: Aniket Sahu <[email protected]> Link: https://lore.kernel.org/qemu-devel/[email protected] Signed-off-by: Harsh Prateek Bora <[email protected]> --- target/ppc/insn32.decode | 6 ++ target/ppc/translate.c | 106 --------------------- target/ppc/translate/fixedpoint-impl.c.inc | 102 ++++++++++++++++++++ 3 files changed, 108 insertions(+), 106 deletions(-) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 69d60605bd..92ee278f63 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -312,6 +312,9 @@ @Z23_te_tbp ...... ....0 te:5 ....0 rmc:2 ........ rc:1 &Z23_te_tb frt=%z23_frtp frb=%z23_frbp +&M ra rs sh mb me rc:bool +@M ...... rs:5 ra:5 sh:5 mb:5 me:5 rc:1 &M + ### Fixed-Point Load Instructions LBZ 100010 ..... ..... ................ @D @@ -561,6 +564,9 @@ SRADI 011111 ..... ..... ..... 110011101 . . @XS EXTSWSLI 011111 ..... ..... ..... 110111101 . . @XS +RLWIMI 010100 ..... ..... ..... ..... ...... @M +RLWINM 010101 ..... ..... ..... ..... ...... @M + ## BCD Assist ADDG6S 011111 ..... ..... ..... - 001001010 - @X diff --git a/target/ppc/translate.c b/target/ppc/translate.c index d17d77a9d9..ce94f9e4e6 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -2012,110 +2012,6 @@ static void gen_pause(DisasContext *ctx) /*** Integer rotate ***/ -/* rlwimi & rlwimi. */ -static void gen_rlwimi(DisasContext *ctx) -{ - TCGv t_ra = cpu_gpr[rA(ctx->opcode)]; - TCGv t_rs = cpu_gpr[rS(ctx->opcode)]; - uint32_t sh = SH(ctx->opcode); - uint32_t mb = MB(ctx->opcode); - uint32_t me = ME(ctx->opcode); - - if (sh == (31 - me) && mb <= me) { - tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1); - } else { - target_ulong mask; - bool mask_in_32b = true; - TCGv t1; - -#if defined(TARGET_PPC64) - mb += 32; - me += 32; -#endif - mask = MASK(mb, me); - -#if defined(TARGET_PPC64) - if (mask > 0xffffffffu) { - mask_in_32b = false; - } -#endif - t1 = tcg_temp_new(); - if (mask_in_32b) { - TCGv_i32 t0 = tcg_temp_new_i32(); - tcg_gen_trunc_tl_i32(t0, t_rs); - tcg_gen_rotli_i32(t0, t0, sh); - tcg_gen_extu_i32_tl(t1, t0); - } else { -#if defined(TARGET_PPC64) - tcg_gen_deposit_i64(t1, t_rs, t_rs, 32, 32); - tcg_gen_rotli_i64(t1, t1, sh); -#else - g_assert_not_reached(); -#endif - } - - tcg_gen_andi_tl(t1, t1, mask); - tcg_gen_andi_tl(t_ra, t_ra, ~mask); - tcg_gen_or_tl(t_ra, t_ra, t1); - } - if (unlikely(Rc(ctx->opcode) != 0)) { - gen_set_Rc0(ctx, t_ra); - } -} - -/* rlwinm & rlwinm. */ -static void gen_rlwinm(DisasContext *ctx) -{ - TCGv t_ra = cpu_gpr[rA(ctx->opcode)]; - TCGv t_rs = cpu_gpr[rS(ctx->opcode)]; - int sh = SH(ctx->opcode); - int mb = MB(ctx->opcode); - int me = ME(ctx->opcode); - int len = me - mb + 1; - int rsh = (32 - sh) & 31; - - if (sh != 0 && len > 0 && me == (31 - sh)) { - tcg_gen_deposit_z_tl(t_ra, t_rs, sh, len); - } else if (me == 31 && rsh + len <= 32) { - tcg_gen_extract_tl(t_ra, t_rs, rsh, len); - } else { - target_ulong mask; - bool mask_in_32b = true; -#if defined(TARGET_PPC64) - mb += 32; - me += 32; -#endif - mask = MASK(mb, me); -#if defined(TARGET_PPC64) - if (mask > 0xffffffffu) { - mask_in_32b = false; - } -#endif - if (mask_in_32b) { - if (sh == 0) { - tcg_gen_andi_tl(t_ra, t_rs, mask); - } else { - TCGv_i32 t0 = tcg_temp_new_i32(); - tcg_gen_trunc_tl_i32(t0, t_rs); - tcg_gen_rotli_i32(t0, t0, sh); - tcg_gen_andi_i32(t0, t0, mask); - tcg_gen_extu_i32_tl(t_ra, t0); - } - } else { -#if defined(TARGET_PPC64) - tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32); - tcg_gen_rotli_i64(t_ra, t_ra, sh); - tcg_gen_andi_i64(t_ra, t_ra, mask); -#else - g_assert_not_reached(); -#endif - } - } - if (unlikely(Rc(ctx->opcode) != 0)) { - gen_set_Rc0(ctx, t_ra); - } -} - /* rlwnm & rlwnm. */ static void gen_rlwnm(DisasContext *ctx) { @@ -4794,8 +4690,6 @@ GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE), GEN_HANDLER_E(copy, 0x1F, 0x06, 0x18, 0x03C00001, PPC_NONE, PPC2_ISA300), GEN_HANDLER_E(cp_abort, 0x1F, 0x06, 0x1A, 0x03FFF801, PPC_NONE, PPC2_ISA300), GEN_HANDLER_E(paste, 0x1F, 0x06, 0x1C, 0x03C00000, PPC_NONE, PPC2_ISA300), -GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), -GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), /* handles lfdp, lxsd, lxssp */ GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205), diff --git a/target/ppc/translate/fixedpoint-impl.c.inc b/target/ppc/translate/fixedpoint-impl.c.inc index 4b79e24f6f..efef56a119 100644 --- a/target/ppc/translate/fixedpoint-impl.c.inc +++ b/target/ppc/translate/fixedpoint-impl.c.inc @@ -1872,6 +1872,108 @@ static bool trans_SRAWI(DisasContext *ctx, arg_SRAWI *a) return true; } +static bool trans_RLWIMI(DisasContext *ctx, arg_RLWIMI *a) +{ + TCGv t_ra = cpu_gpr[a->ra]; + TCGv t_rs = cpu_gpr[a->rs]; + int mb = a->mb; + int me = a->me; + + if (a->sh == (31 - me) && mb <= me) { + tcg_gen_deposit_tl(t_ra, t_ra, t_rs, a->sh, me - mb + 1); + } else { + target_ulong mask; + bool mask_in_32b = true; + TCGv t1; + +#if defined(TARGET_PPC64) + mb += 32; + me += 32; +#endif + mask = MASK(mb, me); + +#if defined(TARGET_PPC64) + if (mask > 0xffffffffu) { + mask_in_32b = false; + } +#endif + t1 = tcg_temp_new(); + if (mask_in_32b) { + TCGv_i32 t0 = tcg_temp_new_i32(); + tcg_gen_trunc_tl_i32(t0, t_rs); + tcg_gen_rotli_i32(t0, t0, a->sh); + tcg_gen_extu_i32_tl(t1, t0); + } else { +#if defined(TARGET_PPC64) + tcg_gen_deposit_i64(t1, t_rs, t_rs, 32, 32); + tcg_gen_rotli_i64(t1, t1, a->sh); +#else + g_assert_not_reached(); +#endif + } + + tcg_gen_andi_tl(t1, t1, mask); + tcg_gen_andi_tl(t_ra, t_ra, ~mask); + tcg_gen_or_tl(t_ra, t_ra, t1); + } + if (unlikely(a->rc)) { + gen_set_Rc0(ctx, t_ra); + } + return true; +} + +static bool trans_RLWINM(DisasContext *ctx, arg_RLWINM *a) +{ + TCGv t_ra = cpu_gpr[a->ra]; + TCGv t_rs = cpu_gpr[a->rs]; + int me = a->me; + int mb = a->mb; + int len = me - mb + 1; + int rsh = (32 - a->sh) & 31; + + if (a->sh != 0 && len > 0 && me == (31 - a->sh)) { + tcg_gen_deposit_z_tl(t_ra, t_rs, a->sh, len); + } else if (me == 31 && rsh + len <= 32) { + tcg_gen_extract_tl(t_ra, t_rs, rsh, len); + } else { + target_ulong mask; + bool mask_in_32b = true; +#if defined(TARGET_PPC64) + mb += 32; + me += 32; +#endif + mask = MASK(mb, me); +#if defined(TARGET_PPC64) + if (mask > 0xffffffffu) { + mask_in_32b = false; + } +#endif + if (mask_in_32b) { + if (a->sh == 0) { + tcg_gen_andi_tl(t_ra, t_rs, mask); + } else { + TCGv_i32 t0 = tcg_temp_new_i32(); + tcg_gen_trunc_tl_i32(t0, t_rs); + tcg_gen_rotli_i32(t0, t0, a->sh); + tcg_gen_andi_i32(t0, t0, mask); + tcg_gen_extu_i32_tl(t_ra, t0); + } + } else { +#if defined(TARGET_PPC64) + tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32); + tcg_gen_rotli_i64(t_ra, t_ra, a->sh); + tcg_gen_andi_i64(t_ra, t_ra, mask); +#else + g_assert_not_reached(); +#endif + } + } + if (unlikely(a->rc)) { + gen_set_Rc0(ctx, t_ra); + } + return true; +} + static void do_fetch_inc_conditional(DisasContext *ctx, MemOp memop, TCGv EA, int rt, TCGCond cond, int addend) -- 2.52.0
