@samitouri / QOSamiQemu / commits / 67257829f0

target/ppc: Move mfmsr, mtmsr[d] instructions to decodetree

Moving the following instructions to decodetree specification: mfmsr : X-form mtmsr[d] : 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. This also includes improvements from review feedback: - Gate MFMSR/MTMSR on PPC_MISC via TRANS_FLAGS() - Use UINT32_MAX instead of 0xFFFFFFFF for clarity Signed-off-by: Vishal Chourasia <vishalc@linux.ibm.com> Reviewed-by: Glenn Miles <milesg@linux.ibm.com> Reviewed-by: Amit Machhiwal <amachhiw@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-28-rathc@linux.ibm.com Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>

Vishal Chourasia committed Aug 27, 2026 at 18:59 UTC 67257829f046eeeffbc08c53349cbc3f9c4f1902
3 files changed +69 -97
target/ppc/insn32.decode
+5
@@ -315,6 +315,11 @@
315 &M ra rs sh mb me rc:bool
316 @M ...... rs:5 ra:5 sh:5 mb:5 me:5 rc:1 &M
317
318 +### MSR
319 +MFMSR 011111 ..... ----- ----- 0001010011 - @X_t
320 +MTMSR 011111 ..... ---- . ----- 0010010010 - @X_rs_l
321 +MTMSRD 011111 ..... ---- . ----- 0010110010 - @X_rs_l
322 +
323 ### Fixed-Point Load Instructions
324
325 LBZ 100010 ..... ..... ................ @D
target/ppc/translate.c
-97
@@ -2843,13 +2843,6 @@ static void gen_mcrxrx(DisasContext *ctx)
2843 }
2844 #endif
2845
2846 -/* mfmsr */
2847 -static void gen_mfmsr(DisasContext *ctx)
2848 -{
2849 - CHK_SV(ctx);
2850 - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
2851 -}
2852 -
2846 /* mfspr */
2847 static inline void gen_op_mfspr(DisasContext *ctx)
2848 {
@@ -2923,93 +2916,6 @@ static void gen_mftb(DisasContext *ctx)
2916 gen_op_mfspr(ctx);
2917 }
2918
2926 -/* mtmsr */
2927 -#if defined(TARGET_PPC64)
2928 -static void gen_mtmsrd(DisasContext *ctx)
2929 -{
2930 - if (unlikely(!is_book3s_arch2x(ctx))) {
2931 - gen_invalid(ctx);
2932 - return;
2933 - }
2934 -
2935 - CHK_SV(ctx);
2936 -
2937 -#if !defined(CONFIG_USER_ONLY)
2938 - TCGv t0, t1;
2939 - target_ulong mask;
2940 -
2941 - t0 = tcg_temp_new();
2942 - t1 = tcg_temp_new();
2943 -
2944 - translator_io_start(&ctx->base);
2945 -
2946 - if (ctx->opcode & 0x00010000) {
2947 - /* L=1 form only updates EE and RI */
2948 - mask = (1ULL << MSR_RI) | (1ULL << MSR_EE);
2949 - } else {
2950 - /* mtmsrd does not alter HV, S, ME, or LE */
2951 - mask = ~((1ULL << MSR_LE) | (1ULL << MSR_ME) | (1ULL << MSR_S) |
2952 - (1ULL << MSR_HV));
2953 - /*
2954 - * XXX: we need to update nip before the store if we enter
2955 - * power saving mode, we will exit the loop directly from
2956 - * ppc_store_msr
2957 - */
2958 - gen_update_nip(ctx, ctx->base.pc_next);
2959 - }
2960 -
2961 - tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], mask);
2962 - tcg_gen_andi_tl(t1, cpu_msr, ~mask);
2963 - tcg_gen_or_tl(t0, t0, t1);
2964 -
2965 - gen_helper_store_msr(tcg_env, t0);
2966 -
2967 - /* Must stop the translation as machine state (may have) changed */
2968 - ctx->base.is_jmp = DISAS_EXIT_UPDATE;
2969 -#endif /* !defined(CONFIG_USER_ONLY) */
2970 -}
2971 -#endif /* defined(TARGET_PPC64) */
2972 -
2973 -static void gen_mtmsr(DisasContext *ctx)
2974 -{
2975 - CHK_SV(ctx);
2976 -
2977 -#if !defined(CONFIG_USER_ONLY)
2978 - TCGv t0, t1;
2979 - target_ulong mask = 0xFFFFFFFF;
2980 -
2981 - t0 = tcg_temp_new();
2982 - t1 = tcg_temp_new();
2983 -
2984 - translator_io_start(&ctx->base);
2985 - if (ctx->opcode & 0x00010000) {
2986 - /* L=1 form only updates EE and RI */
2987 - mask &= (1ULL << MSR_RI) | (1ULL << MSR_EE);
2988 - } else {
2989 - if (likely(!(ctx->insns_flags2 & PPC2_PPE42))) {
2990 - /* mtmsr does not alter S, ME, or LE */
2991 - mask &= ~((1ULL << MSR_LE) | (1ULL << MSR_ME) | (1ULL << MSR_S));
2992 - }
2993 -
2994 - /*
2995 - * XXX: we need to update nip before the store if we enter
2996 - * power saving mode, we will exit the loop directly from
2997 - * ppc_store_msr
2998 - */
2999 - gen_update_nip(ctx, ctx->base.pc_next);
3000 - }
3001 -
3002 - tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], mask);
3003 - tcg_gen_andi_tl(t1, cpu_msr, ~mask);
3004 - tcg_gen_or_tl(t0, t0, t1);
3005 -
3006 - gen_helper_store_msr(tcg_env, t0);
3007 -
3008 - /* Must stop the translation as machine state (may have) changed */
3009 - ctx->base.is_jmp = DISAS_EXIT_UPDATE;
3010 -#endif
3011 -}
3012 -
2919 /* mtspr */
2920 static void gen_mtspr(DisasContext *ctx)
2921 {
@@ -4674,15 +4580,12 @@ GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
4580 GEN_HANDLER(sc, 0x11, 0x11, 0xFF, 0x03FFF01D, PPC_FLOW),
4581 GEN_HANDLER(sc, 0x11, 0x01, 0xFF, 0x03FFF01D, PPC_FLOW),
4582 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
4677 -GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC),
4583 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
4584 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
4585 #if defined(TARGET_PPC64)
4681 -GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
4586 GEN_HANDLER_E(setb, 0x1F, 0x00, 0x04, 0x0003F801, PPC_NONE, PPC2_ISA300),
4587 GEN_HANDLER_E(mcrxrx, 0x1F, 0x00, 0x12, 0x007FF801, PPC_NONE, PPC2_ISA300),
4588 #endif
4685 -GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001EF801, PPC_MISC),
4589 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC),
4590 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ),
4591 GEN_HANDLER_E(dcbzep, 0x1F, 0x1F, 0x1F, 0x03C00001, PPC_NONE, PPC2_BOOKE206),
target/ppc/translate/misc-impl.c.inc
+64
@@ -161,3 +161,67 @@ static bool trans_MCRF(DisasContext *ctx, arg_MCRF *a)
161 tcg_gen_mov_i32(cpu_crf[a->bf], cpu_crf[a->bfa]);
162 return true;
163 }
164 +
165 +static bool do_mfmsr(DisasContext *ctx, arg_X_t *a)
166 +{
167 + REQUIRE_SV(ctx);
168 + tcg_gen_mov_tl(cpu_gpr[a->rt], cpu_msr);
169 + return true;
170 +}
171 +TRANS_FLAGS(MISC, MFMSR, do_mfmsr)
172 +
173 +static bool do_mtmsr(DisasContext *ctx, arg_X_rs_l *a, bool is_mtmsrd)
174 +{
175 + REQUIRE_SV(ctx);
176 +#if !defined(CONFIG_USER_ONLY)
177 + TCGv t0, t1;
178 + target_ulong mask;
179 +
180 + if (is_mtmsrd) {
181 + if (unlikely(!is_book3s_arch2x(ctx))) {
182 + gen_invalid(ctx);
183 + return true;
184 + }
185 + mask = ~(target_ulong)0;
186 + } else {
187 + mask = UINT32_MAX;
188 + }
189 +
190 + t0 = tcg_temp_new();
191 + t1 = tcg_temp_new();
192 + translator_io_start(&ctx->base);
193 +
194 + if (a->l) {
195 + /* L=1 form only updates EE and RI */
196 + mask &= (1ULL << MSR_RI) | (1ULL << MSR_EE);
197 + } else {
198 + if (is_mtmsrd) {
199 + /* mtmsrd does not alter HV, S, ME, or LE */
200 + mask &= ~((1ULL << MSR_LE) | (1ULL << MSR_ME) |
201 + (1ULL << MSR_S) | (1ULL << MSR_HV));
202 + } else if (likely(!(ctx->insns_flags2 & PPC2_PPE42))) {
203 + /* mtmsr does not alter S, ME, or LE */
204 + mask &= ~((1ULL << MSR_LE) | (1ULL << MSR_ME) | (1ULL << MSR_S));
205 + }
206 + /*
207 + * XXX: we need to update nip before the store if we enter
208 + * power saving mode, we will exit the loop directly from
209 + * ppc_store_msr
210 + */
211 + gen_update_nip(ctx, ctx->base.pc_next);
212 + }
213 +
214 + tcg_gen_andi_tl(t0, cpu_gpr[a->rs], mask);
215 + tcg_gen_andi_tl(t1, cpu_msr, ~mask);
216 + tcg_gen_or_tl(t0, t0, t1);
217 +
218 + gen_helper_store_msr(tcg_env, t0);
219 +
220 + /* Must stop the translation as machine state (may have) changed */
221 + ctx->base.is_jmp = DISAS_EXIT_UPDATE;
222 +#endif /* !CONFIG_USER_ONLY */
223 + return true;
224 +}
225 +
226 +TRANS_FLAGS(MISC, MTMSR, do_mtmsr, false)
227 +TRANS64(MTMSRD, do_mtmsr, true)