arch-arm: Move AArch32 IMPLEMENTATION DEFINED registers
Moving AArch32 instruction accessing IMPLEMENTATION DEFINED registers from pseudo.[cc/hh] to misc.[cc/hh] in order to symmetrically match with AArch64 implementation. Change-Id: I27b0d65925d7965589b765269ae54129426e4c88 Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/15735 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
@@ -326,3 +326,72 @@ UnknownOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
return csprintf("%-10s (inst %#08x)", "unknown", machInst & mask(32));
|
||||
}
|
||||
|
||||
McrMrcMiscInst::McrMrcMiscInst(const char *_mnemonic, ExtMachInst _machInst,
|
||||
uint64_t _iss, MiscRegIndex _miscReg)
|
||||
: ArmStaticInst(_mnemonic, _machInst, No_OpClass)
|
||||
{
|
||||
flags[IsNonSpeculative] = true;
|
||||
iss = _iss;
|
||||
miscReg = _miscReg;
|
||||
}
|
||||
|
||||
Fault
|
||||
McrMrcMiscInst::execute(ExecContext *xc, Trace::InstRecord *traceData) const
|
||||
{
|
||||
uint32_t cpsr = xc->readMiscReg(MISCREG_CPSR);
|
||||
uint32_t hcr = xc->readMiscReg(MISCREG_HCR);
|
||||
uint32_t scr = xc->readMiscReg(MISCREG_SCR);
|
||||
uint32_t hdcr = xc->readMiscReg(MISCREG_HDCR);
|
||||
uint32_t hstr = xc->readMiscReg(MISCREG_HSTR);
|
||||
uint32_t hcptr = xc->readMiscReg(MISCREG_HCPTR);
|
||||
|
||||
bool hypTrap = mcrMrc15TrapToHyp(miscReg, hcr, cpsr, scr, hdcr, hstr,
|
||||
hcptr, iss);
|
||||
if (hypTrap) {
|
||||
return std::make_shared<HypervisorTrap>(machInst, iss,
|
||||
EC_TRAPPED_CP15_MCR_MRC);
|
||||
} else {
|
||||
return NoFault;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
McrMrcMiscInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
return csprintf("%-10s (pipe flush)", mnemonic);
|
||||
}
|
||||
|
||||
McrMrcImplDefined::McrMrcImplDefined(const char *_mnemonic,
|
||||
ExtMachInst _machInst, uint64_t _iss,
|
||||
MiscRegIndex _miscReg)
|
||||
: McrMrcMiscInst(_mnemonic, _machInst, _iss, _miscReg)
|
||||
{}
|
||||
|
||||
Fault
|
||||
McrMrcImplDefined::execute(ExecContext *xc, Trace::InstRecord *traceData) const
|
||||
{
|
||||
uint32_t cpsr = xc->readMiscReg(MISCREG_CPSR);
|
||||
uint32_t hcr = xc->readMiscReg(MISCREG_HCR);
|
||||
uint32_t scr = xc->readMiscReg(MISCREG_SCR);
|
||||
uint32_t hdcr = xc->readMiscReg(MISCREG_HDCR);
|
||||
uint32_t hstr = xc->readMiscReg(MISCREG_HSTR);
|
||||
uint32_t hcptr = xc->readMiscReg(MISCREG_HCPTR);
|
||||
|
||||
bool hypTrap = mcrMrc15TrapToHyp(miscReg, hcr, cpsr, scr, hdcr, hstr,
|
||||
hcptr, iss);
|
||||
if (hypTrap) {
|
||||
return std::make_shared<HypervisorTrap>(machInst, iss,
|
||||
EC_TRAPPED_CP15_MCR_MRC);
|
||||
} else {
|
||||
return std::make_shared<UndefinedInstruction>(machInst, false,
|
||||
mnemonic);
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
McrMrcImplDefined::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
return csprintf("%-10s (implementation defined)", mnemonic);
|
||||
}
|
||||
|
||||
@@ -374,4 +374,46 @@ class UnknownOp : public PredOp
|
||||
Addr pc, const SymbolTable *symtab) const override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Certain mrc/mcr instructions act as nops or flush the pipe based on what
|
||||
* register the instruction is trying to access. This inst/class exists so that
|
||||
* we can still check for hyp traps, as the normal nop instruction
|
||||
* does not.
|
||||
*/
|
||||
class McrMrcMiscInst : public ArmStaticInst
|
||||
{
|
||||
protected:
|
||||
uint64_t iss;
|
||||
MiscRegIndex miscReg;
|
||||
|
||||
public:
|
||||
McrMrcMiscInst(const char *_mnemonic, ExtMachInst _machInst,
|
||||
uint64_t _iss, MiscRegIndex _miscReg);
|
||||
|
||||
Fault execute(ExecContext *xc,
|
||||
Trace::InstRecord *traceData) const override;
|
||||
|
||||
std::string generateDisassembly(
|
||||
Addr pc, const SymbolTable *symtab) const override;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is also used for IMPLEMENTATION DEFINED registers, whose mcr/mrc
|
||||
* behaviour is trappable even for unimplemented registers.
|
||||
*/
|
||||
class McrMrcImplDefined : public McrMrcMiscInst
|
||||
{
|
||||
public:
|
||||
McrMrcImplDefined(const char *_mnemonic, ExtMachInst _machInst,
|
||||
uint64_t _iss, MiscRegIndex _miscReg);
|
||||
|
||||
Fault execute(ExecContext *xc,
|
||||
Trace::InstRecord *traceData) const override;
|
||||
|
||||
std::string generateDisassembly(
|
||||
Addr pc, const SymbolTable *symtab) const override;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -181,75 +181,6 @@ WarnUnimplemented::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
fullMnemonic.size() ? fullMnemonic.c_str() : mnemonic);
|
||||
}
|
||||
|
||||
McrMrcMiscInst::McrMrcMiscInst(const char *_mnemonic, ExtMachInst _machInst,
|
||||
uint64_t _iss, MiscRegIndex _miscReg)
|
||||
: ArmStaticInst(_mnemonic, _machInst, No_OpClass)
|
||||
{
|
||||
flags[IsNonSpeculative] = true;
|
||||
iss = _iss;
|
||||
miscReg = _miscReg;
|
||||
}
|
||||
|
||||
Fault
|
||||
McrMrcMiscInst::execute(ExecContext *xc, Trace::InstRecord *traceData) const
|
||||
{
|
||||
uint32_t cpsr = xc->readMiscReg(MISCREG_CPSR);
|
||||
uint32_t hcr = xc->readMiscReg(MISCREG_HCR);
|
||||
uint32_t scr = xc->readMiscReg(MISCREG_SCR);
|
||||
uint32_t hdcr = xc->readMiscReg(MISCREG_HDCR);
|
||||
uint32_t hstr = xc->readMiscReg(MISCREG_HSTR);
|
||||
uint32_t hcptr = xc->readMiscReg(MISCREG_HCPTR);
|
||||
|
||||
bool hypTrap = mcrMrc15TrapToHyp(miscReg, hcr, cpsr, scr, hdcr, hstr,
|
||||
hcptr, iss);
|
||||
if (hypTrap) {
|
||||
return std::make_shared<HypervisorTrap>(machInst, iss,
|
||||
EC_TRAPPED_CP15_MCR_MRC);
|
||||
} else {
|
||||
return NoFault;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
McrMrcMiscInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
return csprintf("%-10s (pipe flush)", mnemonic);
|
||||
}
|
||||
|
||||
McrMrcImplDefined::McrMrcImplDefined(const char *_mnemonic,
|
||||
ExtMachInst _machInst, uint64_t _iss,
|
||||
MiscRegIndex _miscReg)
|
||||
: McrMrcMiscInst(_mnemonic, _machInst, _iss, _miscReg)
|
||||
{}
|
||||
|
||||
Fault
|
||||
McrMrcImplDefined::execute(ExecContext *xc, Trace::InstRecord *traceData) const
|
||||
{
|
||||
uint32_t cpsr = xc->readMiscReg(MISCREG_CPSR);
|
||||
uint32_t hcr = xc->readMiscReg(MISCREG_HCR);
|
||||
uint32_t scr = xc->readMiscReg(MISCREG_SCR);
|
||||
uint32_t hdcr = xc->readMiscReg(MISCREG_HDCR);
|
||||
uint32_t hstr = xc->readMiscReg(MISCREG_HSTR);
|
||||
uint32_t hcptr = xc->readMiscReg(MISCREG_HCPTR);
|
||||
|
||||
bool hypTrap = mcrMrc15TrapToHyp(miscReg, hcr, cpsr, scr, hdcr, hstr,
|
||||
hcptr, iss);
|
||||
if (hypTrap) {
|
||||
return std::make_shared<HypervisorTrap>(machInst, iss,
|
||||
EC_TRAPPED_CP15_MCR_MRC);
|
||||
} else {
|
||||
return std::make_shared<UndefinedInstruction>(machInst, false,
|
||||
mnemonic);
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
McrMrcImplDefined::generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
return csprintf("%-10s (implementation defined)", mnemonic);
|
||||
}
|
||||
|
||||
IllegalExecInst::IllegalExecInst(ExtMachInst _machInst)
|
||||
: ArmStaticInst("Illegal Execution", _machInst, No_OpClass)
|
||||
{}
|
||||
|
||||
@@ -119,48 +119,6 @@ class WarnUnimplemented : public ArmStaticInst
|
||||
Addr pc, const SymbolTable *symtab) const override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Certain mrc/mcr instructions act as nops or flush the pipe based on what
|
||||
* register the instruction is trying to access. This inst/class exists so that
|
||||
* we can still check for hyp traps, as the normal nop instruction
|
||||
* does not.
|
||||
*/
|
||||
class McrMrcMiscInst : public ArmStaticInst
|
||||
{
|
||||
protected:
|
||||
uint64_t iss;
|
||||
MiscRegIndex miscReg;
|
||||
|
||||
public:
|
||||
McrMrcMiscInst(const char *_mnemonic, ExtMachInst _machInst,
|
||||
uint64_t _iss, MiscRegIndex _miscReg);
|
||||
|
||||
Fault execute(ExecContext *xc,
|
||||
Trace::InstRecord *traceData) const override;
|
||||
|
||||
std::string generateDisassembly(
|
||||
Addr pc, const SymbolTable *symtab) const override;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is also used for IMPLEMENTATION DEFINED registers, whose mcr/mrc
|
||||
* behaviour is trappable even for unimplemented registers.
|
||||
*/
|
||||
class McrMrcImplDefined : public McrMrcMiscInst
|
||||
{
|
||||
public:
|
||||
McrMrcImplDefined(const char *_mnemonic, ExtMachInst _machInst,
|
||||
uint64_t _iss, MiscRegIndex _miscReg);
|
||||
|
||||
Fault execute(ExecContext *xc,
|
||||
Trace::InstRecord *traceData) const override;
|
||||
|
||||
std::string generateDisassembly(
|
||||
Addr pc, const SymbolTable *symtab) const override;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is modelling instructions which are not going to be
|
||||
* executed since they are flagged as Illegal Execution Instructions
|
||||
|
||||
Reference in New Issue
Block a user