The following commits changed the code such that these instructions became invalid on pre 3.0 ISAs:
bf8adfd88b547680aa857c46098f3a1e94373160 - target/ppc: Move mffscrn[i] to decodetree 394c2e2fda70da722f20fb60412d6c0ca4bfaa03 - target/ppc: Move mffsce to decodetree 3e5bce70efe6bd1f684efbb21fd2a316cbf0657e - target/ppc: Move mffsl to decodetree The hardware will handle them as a MFFS instruction as the code did previously. Restore that behaviour. This means applications that were segfaulting under qemu when encountering these instructions now operate correctly. The instruction is used in glibc libm functions for example. Signed-off-by: Richard Purdie <richard.pur...@linuxfoundation.org> --- target/ppc/translate/fp-impl.c.inc | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc index 57d8437851..cb86381c3f 100644 --- a/target/ppc/translate/fp-impl.c.inc +++ b/target/ppc/translate/fp-impl.c.inc @@ -584,7 +584,10 @@ static bool trans_MFFSCE(DisasContext *ctx, arg_X_t *a) { TCGv_i64 fpscr; - REQUIRE_INSNS_FLAGS2(ctx, ISA300); + if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) { + return trans_MFFS(ctx, a); + } + REQUIRE_FPU(ctx); gen_reset_fpstatus(); @@ -597,7 +600,10 @@ static bool trans_MFFSCRN(DisasContext *ctx, arg_X_tb *a) { TCGv_i64 t1, fpscr; - REQUIRE_INSNS_FLAGS2(ctx, ISA300); + if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) { + return trans_MFFS(ctx, a); + } + REQUIRE_FPU(ctx); t1 = tcg_temp_new_i64(); @@ -631,7 +637,10 @@ static bool trans_MFFSCRNI(DisasContext *ctx, arg_X_imm2 *a) { TCGv_i64 t1, fpscr; - REQUIRE_INSNS_FLAGS2(ctx, ISA300); + if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) { + return trans_MFFS(ctx, a); + } + REQUIRE_FPU(ctx); t1 = tcg_temp_new_i64(); @@ -661,7 +670,10 @@ static bool trans_MFFSCDRNI(DisasContext *ctx, arg_X_imm3 *a) static bool trans_MFFSL(DisasContext *ctx, arg_X_t *a) { - REQUIRE_INSNS_FLAGS2(ctx, ISA300); + if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) { + return trans_MFFS(ctx, a); + } + REQUIRE_FPU(ctx); gen_reset_fpstatus();