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 <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>
This commit is contained in:
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user