From f5c8fc6bbedfe62bcb9514568b8ee13e073c807b Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Wed, 24 Oct 2018 16:21:41 +0100 Subject: [PATCH] arch-arm: AArch64 Instruction for MISCREG_IMPDEF_UNIMPL 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 Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/c/13779 Maintainer: Andreas Sandberg --- src/arch/arm/insts/misc64.cc | 32 ++++++++++++++++++++++++++++ src/arch/arm/insts/misc64.hh | 28 ++++++++++++++++++++++++ src/arch/arm/isa/formats/aarch64.isa | 14 ++++++------ 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/src/arch/arm/insts/misc64.cc b/src/arch/arm/insts/misc64.cc index b2761e76c..7df2f76ed 100644 --- a/src/arch/arm/insts/misc64.cc +++ b/src/arch/arm/insts/misc64.cc @@ -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(machInst, false, + mnemonic); + } +} + +std::string +MiscRegImplDefined64::generateDisassembly(Addr pc, + const SymbolTable *symtab) const +{ + return csprintf("%-10s (implementation defined)", fullMnemonic.c_str()); +} diff --git a/src/arch/arm/insts/misc64.hh b/src/arch/arm/insts/misc64.hh index 8af488a02..f70344bcb 100644 --- a/src/arch/arm/insts/misc64.hh +++ b/src/arch/arm/insts/misc64.hh @@ -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 diff --git a/src/arch/arm/isa/formats/aarch64.isa b/src/arch/arm/isa/formats/aarch64.isa index 26c65ec8f..3f4e33711 100644 --- a/src/arch/arm/isa/formats/aarch64.isa +++ b/src/arch/arm/isa/formats/aarch64.isa @@ -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) { -- 2.30.2