qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] target/ppc: Ease L=0 requirement on cmp/cmpi/cmpl/cmpli for ppc32
@ 2021-07-15 12:29 matheus.ferst
  2021-07-15 13:12 ` BALATON Zoltan
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: matheus.ferst @ 2021-07-15 12:29 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Matheus Ferst, richard.henderson, groug, david

From: Matheus Ferst <matheus.ferst@eldorado.org.br>

In commit 8f0a4b6a9, we started to require L=0 for ppc32 to match what
The Programming Environments Manual say:

"For 32-bit implementations, the L field must be cleared, otherwise
the instruction form is invalid."

Further digging, however, shown that older CPUs have different behavior
concerning invalid forms. E.g.: 440 and 405 manuals say that:

"Unless otherwise noted, the PPC440 will execute all invalid instruction
forms without causing an Illegal Instruction exception".

While the PowerISA has an arguably more restrictive:

"In general, any attempt to execute an invalid form of an instruction
will either cause the system illegal instruction error handler to be
invoked or yield boundedly undefined results."

Finally, BALATON Zoltan (CC'ed) reported that the stricter behavior
broke AROS boot on sam460ex. This patch address this regression by only
logging a guest error, except for CPUs known to raise an exception for
this case (e500 and e500mc).

Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
---
 target/ppc/translate/fixedpoint-impl.c.inc | 58 +++++++++++++++++++++-
 1 file changed, 56 insertions(+), 2 deletions(-)

diff --git a/target/ppc/translate/fixedpoint-impl.c.inc b/target/ppc/translate/fixedpoint-impl.c.inc
index f4fcfadbfc..1c35b60eb4 100644
--- a/target/ppc/translate/fixedpoint-impl.c.inc
+++ b/target/ppc/translate/fixedpoint-impl.c.inc
@@ -145,8 +145,35 @@ TRANS64(PSTD, do_ldst_PLS_D, false, true, MO_Q)
 
 static bool do_cmp_X(DisasContext *ctx, arg_X_bfl *a, bool s)
 {
+    if ((ctx->insns_flags & PPC_64B) == 0) {
+        /*
+         * For 32-bit implementations, The Programming Environments Manual says
+         * that "the L field must be cleared, otherwise the instruction form is
+         * invalid." It seems, however, that most 32-bit CPUs ignore invalid
+         * forms (e.g., section "Instruction Formats" of the 405 and 440
+         * manuals, "Integer Compare Instructions" of the 601 manual), with the
+         * notable exception of the e500 and e500mc, where L=1 was reported to
+         * cause an exception.
+         */
+        if (a->l) {
+            if ((ctx->insns_flags2 & PPC2_BOOKE206)) {
+                /*
+                 * For 32-bit Book E v2.06 implementations (i.e. e500/e500mc),
+                 * generate an illegal instruction exception.
+                 */
+                return false;
+            } else {
+                qemu_log_mask(LOG_GUEST_ERROR,
+                        "Invalid form of CMP%s at 0x" TARGET_FMT_lx ", L = 1\n",
+                        s ? "" : "L", ctx->cia);
+            }
+        }
+        gen_op_cmp32(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf);
+        return true;
+    }
+
+    /* For 64-bit implementations, deal with bit L accordingly. */
     if (a->l) {
-        REQUIRE_64BIT(ctx);
         gen_op_cmp(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf);
     } else {
         gen_op_cmp32(cpu_gpr[a->ra], cpu_gpr[a->rb], s, a->bf);
@@ -156,8 +183,35 @@ static bool do_cmp_X(DisasContext *ctx, arg_X_bfl *a, bool s)
 
 static bool do_cmp_D(DisasContext *ctx, arg_D_bf *a, bool s)
 {
+    if ((ctx->insns_flags & PPC_64B) == 0) {
+        /*
+         * For 32-bit implementations, The Programming Environments Manual says
+         * that "the L field must be cleared, otherwise the instruction form is
+         * invalid." It seems, however, that most 32-bit CPUs ignore invalid
+         * forms (e.g., section "Instruction Formats" of the 405 and 440
+         * manuals, "Integer Compare Instructions" of the 601 manual), with the
+         * notable exception of the e500 and e500mc, where L=1 was reported to
+         * cause an exception.
+         */
+        if (a->l) {
+            if ((ctx->insns_flags2 & PPC2_BOOKE206)) {
+                /*
+                 * For 32-bit Book E v2.06 implementations (i.e. e500/e500mc),
+                 * generate an illegal instruction exception.
+                 */
+                return false;
+            } else {
+                qemu_log_mask(LOG_GUEST_ERROR,
+                        "Invalid form of CMP%s at 0x" TARGET_FMT_lx ", L = 1\n",
+                        s ? "I" : "LI", ctx->cia);
+            }
+        }
+        gen_op_cmp32(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf);
+        return true;
+    }
+
+    /* For 64-bit implementations, deal with bit L accordingly. */
     if (a->l) {
-        REQUIRE_64BIT(ctx);
         gen_op_cmp(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf);
     } else {
         gen_op_cmp32(cpu_gpr[a->ra], tcg_constant_tl(a->imm), s, a->bf);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-07-20  1:27 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-07-15 12:29 [PATCH] target/ppc: Ease L=0 requirement on cmp/cmpi/cmpl/cmpli for ppc32 matheus.ferst
2021-07-15 13:12 ` BALATON Zoltan
2021-07-15 13:14 ` BALATON Zoltan
2021-07-15 14:29   ` Matheus K. Ferst
2021-07-19  2:42 ` David Gibson
2021-07-19 10:21   ` BALATON Zoltan
2021-07-19 12:09     ` David Gibson
2021-07-19 20:07   ` Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).