arch-arm: AArch64 Instruction for MISCREG_IMPDEF_UNIMPL
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Wed, 24 Oct 2018 15:21:41 +0000 (16:21 +0100)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Fri, 26 Oct 2018 09:45:47 +0000 (09:45 +0000)
While there is a AArch32 class for instructions accessing implementation
defined registers, we are lacking for the AArch64 counterpart.
we were relying on FailUnimplemented, which is untrappable at EL2 (except
for HCR_EL2.TGE) since it is just raising Undefined Instruction.

Change-Id: I923cb914658ca958af031612cf005159707b0b4f
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/13779
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>

src/arch/arm/insts/misc64.cc
src/arch/arm/insts/misc64.hh
src/arch/arm/isa/formats/aarch64.isa

index b2761e76caecc8c163181c030e86419a47e042bd..7df2f76ed57061a4cf015e0cb42282ad2ac6bd4d 100644 (file)
@@ -266,6 +266,8 @@ MiscRegOp64::checkEL2Trap(ThreadContext *tc, const MiscRegIndex misc_reg,
             assert(miscRead);
             trap_to_hyp = hcr.tid1 && el == EL1;
             break;
+          case MISCREG_IMPDEF_UNIMPL:
+            trap_to_hyp = hcr.tidcp && el == EL1;
           default:
             break;
         }
@@ -330,3 +332,33 @@ RegMiscRegImmOp64::generateDisassembly(
     printMiscReg(ss, op1);
     return ss.str();
 }
+
+Fault
+MiscRegImplDefined64::execute(ExecContext *xc,
+                              Trace::InstRecord *traceData) const
+{
+    auto tc = xc->tcBase();
+    const CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
+    const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
+
+    Fault fault = trap(tc, miscReg, el, imm);
+
+    if (fault != NoFault) {
+        return fault;
+
+    } else if (warning) {
+        warn_once("\tinstruction '%s' unimplemented\n", fullMnemonic.c_str());
+        return NoFault;
+
+    } else {
+        return std::make_shared<UndefinedInstruction>(machInst, false,
+                                                      mnemonic);
+    }
+}
+
+std::string
+MiscRegImplDefined64::generateDisassembly(Addr pc,
+                                          const SymbolTable *symtab) const
+{
+    return csprintf("%-10s (implementation defined)", fullMnemonic.c_str());
+}
index 8af488a02b078903f1f1bc3c60133b2f0bce5679..f70344bcba9f80a10b6ed0e57fbb0844d61fbf85 100644 (file)
@@ -178,4 +178,32 @@ class RegMiscRegImmOp64 : public MiscRegOp64
             Addr pc, const SymbolTable *symtab) const override;
 };
 
+class MiscRegImplDefined64 : public MiscRegOp64
+{
+  protected:
+    const std::string fullMnemonic;
+    const MiscRegIndex miscReg;
+    const uint32_t imm;
+    const bool warning;
+
+  public:
+    MiscRegImplDefined64(const char *mnem, ExtMachInst _machInst,
+                         MiscRegIndex misc_reg, bool misc_read,
+                         uint32_t _imm, const std::string full_mnem,
+                         bool _warning) :
+        MiscRegOp64(mnem, _machInst, No_OpClass, misc_read),
+        fullMnemonic(full_mnem), miscReg(misc_reg), imm(_imm),
+        warning(_warning)
+    {
+        assert(miscReg == MISCREG_IMPDEF_UNIMPL);
+    }
+
+  protected:
+    Fault execute(ExecContext *xc,
+                  Trace::InstRecord *traceData) const override;
+
+    std::string generateDisassembly(
+            Addr pc, const SymbolTable *symtab) const override;
+};
+
 #endif
index 26c65ec8f6b2fe71fbcf3f3bf0b107f1b30e2077..3f4e3371173cfca88062d478e6a7d96286580cf6 100644 (file)
@@ -446,13 +446,13 @@ namespace Aarch64
                                      read ? "mrs" : "msr",
                                      op0, op1, crn, crm, op2);
 
-                        if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) {
-                            return new WarnUnimplemented(read ? "mrs" : "msr",
-                                machInst, full_mnemonic + " treated as NOP");
-                        } else {
-                            return new FailUnimplemented(read ? "mrs" : "msr",
-                                machInst, full_mnemonic);
-                        }
+                        uint32_t iss = msrMrs64IssBuild(
+                            read, op0, op1, crn, crm, op2, rt);
+
+                        return new MiscRegImplDefined64(
+                            read ? "mrs" : "msr",
+                            machInst, miscReg, read, iss, full_mnemonic,
+                            miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]);
 
                     } else if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) {
                         if (miscReg == MISCREG_NZCV) {