checker: CheckerCPU handling of MiscRegs was incorrect

The CheckerCPU model in pre-v8 code was not checking the
updates to miscellaneous registers due to some methods
for setting misc regs were not instrumented.  The v8 patches
exposed this by calling the instrumented misc reg update
methods and then invoking the checker before the main CPU had
updated its misc regs, leading to false positives about
register mismatches. This patch fixes the non-instrumented
misc reg update methods and places calls to the checker in
the proper places in the O3 model.
This commit is contained in:
Geoffrey Blake
2014-01-24 15:29:30 -06:00
parent 7d0344704a
commit 9633282fc8
4 changed files with 12 additions and 14 deletions

View File

@@ -78,7 +78,7 @@ CheckerCPU::CheckerCPU(Params *p)
startNumLoad = 0;
youngestSN = 0;
changedPC = willChangePC = changedNextPC = false;
changedPC = willChangePC = false;
exitOnError = p->exitOnError;
warnOnlyOnLoadError = p->warnOnlyOnLoadError;

View File

@@ -296,12 +296,14 @@ class CheckerCPU : public BaseCPU
void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
DPRINTF(Checker, "Setting misc reg %d with no effect to check later\n", misc_reg);
miscRegIdxs.push(misc_reg);
return thread->setMiscRegNoEffect(misc_reg, val);
}
void setMiscReg(int misc_reg, const MiscReg &val)
{
DPRINTF(Checker, "Setting misc reg %d with effect to check later\n", misc_reg);
miscRegIdxs.push(misc_reg);
return thread->setMiscReg(misc_reg, val);
}
@@ -316,7 +318,7 @@ class CheckerCPU : public BaseCPU
const StaticInst *si, int idx, const MiscReg &val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
return thread->setMiscReg(reg_idx, val);
return this->setMiscReg(reg_idx, val);
}
#if THE_ISA == MIPS_ISA
@@ -392,7 +394,6 @@ class CheckerCPU : public BaseCPU
bool changedPC;
bool willChangePC;
TheISA::PCState newPCState;
bool changedNextPC;
bool exitOnError;
bool updateOnError;
bool warnOnlyOnLoadError;

View File

@@ -230,11 +230,6 @@ Checker<Impl>::verify(DynInstPtr &completed_inst)
}
changedPC = false;
}
if (changedNextPC) {
DPRINTF(Checker, "Changed NextPC recently to %#x\n",
thread->nextInstAddr());
changedNextPC = false;
}
// Try to fetch the instruction
uint64_t fetchOffset = 0;

View File

@@ -1043,6 +1043,12 @@ DefaultCommit<Impl>::commitInsts()
// Updates misc. registers.
head_inst->updateMiscRegs();
// Check instruction execution if it successfully commits and
// is not carrying a fault.
if (cpu->checker) {
cpu->checker->verify(head_inst);
}
cpu->traceFunctions(pc[tid].instAddr());
TheISA::advancePC(pc[tid], head_inst->staticInst);
@@ -1168,12 +1174,6 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
head_inst->setCompleted();
}
// Use checker prior to updating anything due to traps or PC
// based events.
if (cpu->checker) {
cpu->checker->verify(head_inst);
}
if (inst_fault != NoFault) {
DPRINTF(Commit, "Inst [sn:%lli] PC %s has a fault\n",
head_inst->seqNum, head_inst->pcState());
@@ -1185,6 +1185,8 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
head_inst->setCompleted();
// If instruction has faulted, let the checker execute it and
// check if it sees the same fault and control flow.
if (cpu->checker) {
// Need to check the instruction before its fault is processed
cpu->checker->verify(head_inst);