summaryrefslogtreecommitdiff
path: root/src/cpu/checker
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/checker')
-rw-r--r--src/cpu/checker/cpu.hh19
-rw-r--r--src/cpu/checker/cpu_impl.hh25
2 files changed, 37 insertions, 7 deletions
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh
index 6d6ae1e0a..737b4b5d4 100644
--- a/src/cpu/checker/cpu.hh
+++ b/src/cpu/checker/cpu.hh
@@ -102,6 +102,7 @@ class CheckerCPU : public BaseCPU
Process *process;
#endif
bool exitOnError;
+ bool updateOnError;
bool warnOnlyOnLoadError;
};
@@ -148,7 +149,7 @@ class CheckerCPU : public BaseCPU
union Result {
uint64_t integer;
- float fp;
+// float fp;
double dbl;
};
@@ -269,7 +270,7 @@ class CheckerCPU : public BaseCPU
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
thread->setFloatReg(reg_idx, val);
- result.fp = val;
+ result.dbl = (double)val;
}
void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val,
@@ -318,7 +319,7 @@ class CheckerCPU : public BaseCPU
return thread->setMiscRegWithEffect(misc_reg, val);
}
- void recordPCChange(uint64_t val) { changedPC = true; }
+ void recordPCChange(uint64_t val) { changedPC = true; newPC = val; }
void recordNextPCChange(uint64_t val) { changedNextPC = true; }
bool translateInstReq(Request *req);
@@ -360,6 +361,7 @@ class CheckerCPU : public BaseCPU
uint64_t newPC;
bool changedNextPC;
bool exitOnError;
+ bool updateOnError;
bool warnOnlyOnLoadError;
InstSeqNum youngestSN;
@@ -376,7 +378,7 @@ class Checker : public CheckerCPU
{
public:
Checker(Params *p)
- : CheckerCPU(p)
+ : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL)
{ }
void switchOut();
@@ -393,12 +395,19 @@ class Checker : public CheckerCPU
private:
void handleError(DynInstPtr &inst)
{
- if (exitOnError)
+ if (exitOnError) {
dumpAndExit(inst);
+ } else if (updateOnError) {
+ updateThisCycle = true;
+ }
}
void dumpAndExit(DynInstPtr &inst);
+ bool updateThisCycle;
+
+ DynInstPtr unverifiedInst;
+
std::list<DynInstPtr> instList;
typedef typename std::list<DynInstPtr>::iterator InstListIt;
void dumpInsts();
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh
index 81f97726c..3bb81c4b9 100644
--- a/src/cpu/checker/cpu_impl.hh
+++ b/src/cpu/checker/cpu_impl.hh
@@ -94,6 +94,8 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
}
}
+ unverifiedInst = inst;
+
// Try to check all instructions that are completed, ending if we
// run out of instructions to check or if an instruction is not
// yet completed.
@@ -171,7 +173,7 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
thread->setPC(thread->readNextPC());
thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
- return;
+ break;
} else {
// The instruction is carrying an ITB fault. Handle
// the fault and see if our results match the CPU on
@@ -220,7 +222,8 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
thread->funcExeInst++;
- fault = curStaticInst->execute(this, NULL);
+ if (!inst->isUnverifiable())
+ fault = curStaticInst->execute(this, NULL);
// Checks to make sure instrution results are correct.
validateExecution(inst);
@@ -289,6 +292,7 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
break;
}
}
+ unverifiedInst = NULL;
}
template <class DynInstPtr>
@@ -395,6 +399,23 @@ template <class DynInstPtr>
void
Checker<DynInstPtr>::validateState()
{
+ if (updateThisCycle) {
+ warn("%lli: Instruction PC %#x results didn't match up, copying all "
+ "registers from main CPU", curTick, unverifiedInst->readPC());
+ // Heavy-weight copying of all registers
+ cpuXC->copyArchRegs(unverifiedInst->xcBase());
+ // Also advance the PC. Hopefully no PC-based events happened.
+#if THE_ISA != MIPS_ISA
+ // go to the next instruction
+ cpuXC->setPC(cpuXC->readNextPC());
+ cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst));
+#else
+ // go to the next instruction
+ cpuXC->setPC(cpuXC->readNextPC());
+ cpuXC->setNextPC(cpuXC->readNextNPC());
+ cpuXC->setNextNPC(cpuXC->readNextNPC() + sizeof(MachInst));
+#endif
+ updateThisCycle = false;
}
template <class DynInstPtr>