blob: ade1daf61ffae766711f520cc2b91b40ecfd53ee [file] [log] [blame]
target/ppc: Fix fallback to MFSS for MFFSCRN, MFFSCRNI, MFFSCE and MFFSL
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.
Upstream-Status: Submitted [https://lore.kernel.org/qemu-devel/20230504110150.3044402-1-richard.purdie@linuxfoundation.org/]
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Index: qemu-8.0.0/target/ppc/translate/fp-impl.c.inc
===================================================================
--- qemu-8.0.0.orig/target/ppc/translate/fp-impl.c.inc
+++ qemu-8.0.0/target/ppc/translate/fp-impl.c.inc
@@ -584,7 +584,10 @@ static bool trans_MFFSCE(DisasContext *c
{
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 *
{
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
{
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
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();