cpu: Remove all notion that we know when the cpu is misspeculating.
We have no way of knowing if a CPU model is on the wrong path with our execute-in-execute CPU models. Don't pretend that we do.
This commit is contained in:
parent
0bd986015b
commit
f6742ea26e
16 changed files with 21 additions and 86 deletions
|
@ -161,8 +161,7 @@ ISA::readIpr(int idx, ThreadContext *tc)
|
||||||
|
|
||||||
case IPR_DTB_PTE:
|
case IPR_DTB_PTE:
|
||||||
{
|
{
|
||||||
TlbEntry &entry
|
TlbEntry &entry = tc->getDTBPtr()->index(1);
|
||||||
= tc->getDTBPtr()->index(!tc->misspeculating());
|
|
||||||
|
|
||||||
retval |= ((uint64_t)entry.ppn & ULL(0x7ffffff)) << 32;
|
retval |= ((uint64_t)entry.ppn & ULL(0x7ffffff)) << 32;
|
||||||
retval |= ((uint64_t)entry.xre & ULL(0xf)) << 8;
|
retval |= ((uint64_t)entry.xre & ULL(0xf)) << 8;
|
||||||
|
@ -202,9 +201,6 @@ int break_ipl = -1;
|
||||||
void
|
void
|
||||||
ISA::setIpr(int idx, uint64_t val, ThreadContext *tc)
|
ISA::setIpr(int idx, uint64_t val, ThreadContext *tc)
|
||||||
{
|
{
|
||||||
if (tc->misspeculating())
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (idx) {
|
switch (idx) {
|
||||||
case IPR_PALtemp0:
|
case IPR_PALtemp0:
|
||||||
case IPR_PALtemp1:
|
case IPR_PALtemp1:
|
||||||
|
@ -484,10 +480,8 @@ SimpleThread::hwrei()
|
||||||
|
|
||||||
CPA::cpa()->swAutoBegin(tc, pc.npc());
|
CPA::cpa()->swAutoBegin(tc, pc.npc());
|
||||||
|
|
||||||
if (!misspeculating()) {
|
if (kernelStats)
|
||||||
if (kernelStats)
|
kernelStats->hwrei();
|
||||||
kernelStats->hwrei();
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: XXX check for interrupts? XXX
|
// FIXME: XXX check for interrupts? XXX
|
||||||
return NoFault;
|
return NoFault;
|
||||||
|
|
|
@ -147,8 +147,7 @@ DtbFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||||
// on VPTE loads (instead of locking the registers until IPR_VA is
|
// on VPTE loads (instead of locking the registers until IPR_VA is
|
||||||
// read, like the EV5). The EV6 approach is cleaner and seems to
|
// read, like the EV5). The EV6 approach is cleaner and seems to
|
||||||
// work with EV5 PAL code, but not the other way around.
|
// work with EV5 PAL code, but not the other way around.
|
||||||
if (!tc->misspeculating() &&
|
if (reqFlags.noneSet(Request::VPTE | Request::PREFETCH)) {
|
||||||
reqFlags.noneSet(Request::VPTE | Request::PREFETCH)) {
|
|
||||||
// set VA register with faulting address
|
// set VA register with faulting address
|
||||||
tc->setMiscRegNoEffect(IPR_VA, vaddr);
|
tc->setMiscRegNoEffect(IPR_VA, vaddr);
|
||||||
|
|
||||||
|
@ -172,11 +171,9 @@ void
|
||||||
ItbFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
ItbFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||||
{
|
{
|
||||||
if (FullSystem) {
|
if (FullSystem) {
|
||||||
if (!tc->misspeculating()) {
|
tc->setMiscRegNoEffect(IPR_ITB_TAG, pc);
|
||||||
tc->setMiscRegNoEffect(IPR_ITB_TAG, pc);
|
tc->setMiscRegNoEffect(IPR_IFAULT_VA_FORM,
|
||||||
tc->setMiscRegNoEffect(IPR_IFAULT_VA_FORM,
|
tc->readMiscRegNoEffect(IPR_IVPTBR) | (VAddr(pc).vpn() << 3));
|
||||||
tc->readMiscRegNoEffect(IPR_IVPTBR) | (VAddr(pc).vpn() << 3));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AlphaFault::invoke(tc);
|
AlphaFault::invoke(tc);
|
||||||
|
|
|
@ -81,7 +81,6 @@ DebugFlag('ExecFetchSeq', 'Format: Fetch sequence number')
|
||||||
DebugFlag('ExecOpClass', 'Format: Include operand class')
|
DebugFlag('ExecOpClass', 'Format: Include operand class')
|
||||||
DebugFlag('ExecRegDelta')
|
DebugFlag('ExecRegDelta')
|
||||||
DebugFlag('ExecResult', 'Format: Include results from execution')
|
DebugFlag('ExecResult', 'Format: Include results from execution')
|
||||||
DebugFlag('ExecSpeculative', 'Format: Include a miss-/speculation flag (-/+)')
|
|
||||||
DebugFlag('ExecSymbol', 'Format: Try to include symbol names')
|
DebugFlag('ExecSymbol', 'Format: Try to include symbol names')
|
||||||
DebugFlag('ExecThread', 'Format: Include thread ID in trace')
|
DebugFlag('ExecThread', 'Format: Include thread ID in trace')
|
||||||
DebugFlag('ExecTicks', 'Format: Include tick count')
|
DebugFlag('ExecTicks', 'Format: Include tick count')
|
||||||
|
@ -100,7 +99,7 @@ DebugFlag('Mwait')
|
||||||
|
|
||||||
CompoundFlag('ExecAll', [ 'ExecEnable', 'ExecCPSeq', 'ExecEffAddr',
|
CompoundFlag('ExecAll', [ 'ExecEnable', 'ExecCPSeq', 'ExecEffAddr',
|
||||||
'ExecFaulting', 'ExecFetchSeq', 'ExecOpClass', 'ExecRegDelta',
|
'ExecFaulting', 'ExecFetchSeq', 'ExecOpClass', 'ExecRegDelta',
|
||||||
'ExecResult', 'ExecSpeculative', 'ExecSymbol', 'ExecThread',
|
'ExecResult', 'ExecSymbol', 'ExecThread',
|
||||||
'ExecTicks', 'ExecMicro', 'ExecMacro', 'ExecUser', 'ExecKernel',
|
'ExecTicks', 'ExecMicro', 'ExecMacro', 'ExecUser', 'ExecKernel',
|
||||||
'ExecAsid', 'ExecFlags' ])
|
'ExecAsid', 'ExecFlags' ])
|
||||||
CompoundFlag('Exec', [ 'ExecEnable', 'ExecTicks', 'ExecOpClass', 'ExecThread',
|
CompoundFlag('Exec', [ 'ExecEnable', 'ExecTicks', 'ExecOpClass', 'ExecThread',
|
||||||
|
|
|
@ -310,9 +310,6 @@ class CheckerThreadContext : public ThreadContext
|
||||||
actualTC->setStCondFailures(sc_failures);
|
actualTC->setStCondFailures(sc_failures);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo: Fix this!
|
|
||||||
bool misspeculating() { return actualTC->misspeculating(); }
|
|
||||||
|
|
||||||
Counter readFuncExeInst() { return actualTC->readFuncExeInst(); }
|
Counter readFuncExeInst() { return actualTC->readFuncExeInst(); }
|
||||||
|
|
||||||
uint64_t readIntRegFlat(int idx)
|
uint64_t readIntRegFlat(int idx)
|
||||||
|
|
|
@ -71,9 +71,6 @@ Trace::ExeTracerRecord::traceInst(const StaticInstPtr &inst, bool ran)
|
||||||
|
|
||||||
outs << thread->getCpuPtr()->name() << " ";
|
outs << thread->getCpuPtr()->name() << " ";
|
||||||
|
|
||||||
if (Debug::ExecSpeculative)
|
|
||||||
outs << (misspeculating ? "-" : "+") << " ";
|
|
||||||
|
|
||||||
if (Debug::ExecAsid)
|
if (Debug::ExecAsid)
|
||||||
outs << "A" << dec << TheISA::getExecutingAsid(thread) << " ";
|
outs << "A" << dec << TheISA::getExecutingAsid(thread) << " ";
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#include "cpu/static_inst.hh"
|
#include "cpu/static_inst.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/ExecEnable.hh"
|
#include "debug/ExecEnable.hh"
|
||||||
#include "debug/ExecSpeculative.hh"
|
|
||||||
#include "params/ExeTracer.hh"
|
#include "params/ExeTracer.hh"
|
||||||
#include "sim/insttracer.hh"
|
#include "sim/insttracer.hh"
|
||||||
|
|
||||||
|
@ -50,9 +49,8 @@ class ExeTracerRecord : public InstRecord
|
||||||
public:
|
public:
|
||||||
ExeTracerRecord(Tick _when, ThreadContext *_thread,
|
ExeTracerRecord(Tick _when, ThreadContext *_thread,
|
||||||
const StaticInstPtr _staticInst, TheISA::PCState _pc,
|
const StaticInstPtr _staticInst, TheISA::PCState _pc,
|
||||||
bool spec, const StaticInstPtr _macroStaticInst = NULL)
|
const StaticInstPtr _macroStaticInst = NULL)
|
||||||
: InstRecord(_when, _thread, _staticInst, _pc, spec,
|
: InstRecord(_when, _thread, _staticInst, _pc, _macroStaticInst)
|
||||||
_macroStaticInst)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,11 +78,8 @@ class ExeTracer : public InstTracer
|
||||||
if (!Trace::enabled)
|
if (!Trace::enabled)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!Debug::ExecSpeculative && tc->misspeculating())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return new ExeTracerRecord(when, tc,
|
return new ExeTracerRecord(when, tc,
|
||||||
staticInst, pc, tc->misspeculating(), macroStaticInst);
|
staticInst, pc, macroStaticInst);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,8 @@ class InOrderTraceRecord : public ExeTracerRecord
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InOrderTraceRecord(unsigned num_stages, bool _stage_tracing,
|
InOrderTraceRecord(unsigned num_stages, bool _stage_tracing,
|
||||||
ThreadContext *_thread, TheISA::PCState _pc, bool spec = false)
|
ThreadContext *_thread, TheISA::PCState _pc)
|
||||||
: ExeTracerRecord(0, _thread, NULL, _pc, spec)
|
: ExeTracerRecord(0, _thread, NULL, _pc)
|
||||||
{
|
{
|
||||||
stageTrace = _stage_tracing;
|
stageTrace = _stage_tracing;
|
||||||
stageCycle.resize(num_stages);
|
stageCycle.resize(num_stages);
|
||||||
|
|
|
@ -290,14 +290,6 @@ class InOrderThreadContext : public ThreadContext
|
||||||
void setStCondFailures(unsigned sc_failures)
|
void setStCondFailures(unsigned sc_failures)
|
||||||
{ thread->storeCondFailures = sc_failures; }
|
{ thread->storeCondFailures = sc_failures; }
|
||||||
|
|
||||||
// Only really makes sense for old CPU model. Lots of code
|
|
||||||
// outside the CPU still checks this function, so it will
|
|
||||||
// always return false to keep everything working.
|
|
||||||
/** Checks if the thread is misspeculating. Because it is
|
|
||||||
* very difficult to determine if the thread is
|
|
||||||
* misspeculating, this is set as false. */
|
|
||||||
bool misspeculating() { return false; }
|
|
||||||
|
|
||||||
/** Executes a syscall in SE mode. */
|
/** Executes a syscall in SE mode. */
|
||||||
void syscall(int64_t callnum)
|
void syscall(int64_t callnum)
|
||||||
{ return cpu->syscall(callnum, thread->threadId()); }
|
{ return cpu->syscall(callnum, thread->threadId()); }
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#include "cpu/static_inst.hh"
|
#include "cpu/static_inst.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/ExecEnable.hh"
|
#include "debug/ExecEnable.hh"
|
||||||
#include "debug/ExecSpeculative.hh"
|
|
||||||
#include "params/IntelTrace.hh"
|
#include "params/IntelTrace.hh"
|
||||||
#include "sim/insttracer.hh"
|
#include "sim/insttracer.hh"
|
||||||
|
|
||||||
|
@ -48,8 +47,8 @@ class IntelTraceRecord : public InstRecord
|
||||||
public:
|
public:
|
||||||
IntelTraceRecord(Tick _when, ThreadContext *_thread,
|
IntelTraceRecord(Tick _when, ThreadContext *_thread,
|
||||||
const StaticInstPtr _staticInst, TheISA::PCState _pc,
|
const StaticInstPtr _staticInst, TheISA::PCState _pc,
|
||||||
bool spec, const StaticInstPtr _macroStaticInst = NULL)
|
const StaticInstPtr _macroStaticInst = NULL)
|
||||||
: InstRecord(_when, _thread, _staticInst, _pc, spec,
|
: InstRecord(_when, _thread, _staticInst, _pc,
|
||||||
_macroStaticInst)
|
_macroStaticInst)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -75,11 +74,7 @@ class IntelTrace : public InstTracer
|
||||||
if (!Trace::enabled)
|
if (!Trace::enabled)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!Debug::ExecSpeculative && tc->misspeculating())
|
return new IntelTraceRecord(when, tc, staticInst, pc, macroStaticInst);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return new IntelTraceRecord(when, tc,
|
|
||||||
staticInst, pc, tc->misspeculating(), macroStaticInst);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -56,9 +56,8 @@ class NativeTraceRecord : public ExeTracerRecord
|
||||||
NativeTraceRecord(NativeTrace * _parent,
|
NativeTraceRecord(NativeTrace * _parent,
|
||||||
Tick _when, ThreadContext *_thread,
|
Tick _when, ThreadContext *_thread,
|
||||||
const StaticInstPtr _staticInst, TheISA::PCState _pc,
|
const StaticInstPtr _staticInst, TheISA::PCState _pc,
|
||||||
bool spec, const StaticInstPtr _macroStaticInst = NULL)
|
const StaticInstPtr _macroStaticInst = NULL)
|
||||||
: ExeTracerRecord(_when, _thread, _staticInst, _pc, spec,
|
: ExeTracerRecord(_when, _thread, _staticInst, _pc, _macroStaticInst),
|
||||||
_macroStaticInst),
|
|
||||||
parent(_parent)
|
parent(_parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -83,11 +82,8 @@ class NativeTrace : public ExeTracer
|
||||||
const StaticInstPtr staticInst, TheISA::PCState pc,
|
const StaticInstPtr staticInst, TheISA::PCState pc,
|
||||||
const StaticInstPtr macroStaticInst = NULL)
|
const StaticInstPtr macroStaticInst = NULL)
|
||||||
{
|
{
|
||||||
if (tc->misspeculating())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return new NativeTraceRecord(this, when, tc,
|
return new NativeTraceRecord(this, when, tc,
|
||||||
staticInst, pc, tc->misspeculating(), macroStaticInst);
|
staticInst, pc, macroStaticInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|
|
@ -257,14 +257,6 @@ class O3ThreadContext : public ThreadContext
|
||||||
virtual void setStCondFailures(unsigned sc_failures)
|
virtual void setStCondFailures(unsigned sc_failures)
|
||||||
{ thread->storeCondFailures = sc_failures; }
|
{ thread->storeCondFailures = sc_failures; }
|
||||||
|
|
||||||
// Only really makes sense for old CPU model. Lots of code
|
|
||||||
// outside the CPU still checks this function, so it will
|
|
||||||
// always return false to keep everything working.
|
|
||||||
/** Checks if the thread is misspeculating. Because it is
|
|
||||||
* very difficult to determine if the thread is
|
|
||||||
* misspeculating, this is set as false. */
|
|
||||||
virtual bool misspeculating() { return false; }
|
|
||||||
|
|
||||||
/** Executes a syscall in SE mode. */
|
/** Executes a syscall in SE mode. */
|
||||||
virtual void syscall(int64_t callnum)
|
virtual void syscall(int64_t callnum)
|
||||||
{ return cpu->syscall(callnum, thread->threadId()); }
|
{ return cpu->syscall(callnum, thread->threadId()); }
|
||||||
|
|
|
@ -449,7 +449,6 @@ class BaseSimpleCPU : public BaseCPU, public ExecContext
|
||||||
thread->syscall(callnum);
|
thread->syscall(callnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool misspeculating() { return thread->misspeculating(); }
|
|
||||||
ThreadContext *tcBase() { return tc; }
|
ThreadContext *tcBase() { return tc; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -220,8 +220,6 @@ class SimpleThread : public ThreadState
|
||||||
/// Set the status to Halted.
|
/// Set the status to Halted.
|
||||||
void halt();
|
void halt();
|
||||||
|
|
||||||
virtual bool misspeculating();
|
|
||||||
|
|
||||||
void copyArchRegs(ThreadContext *tc);
|
void copyArchRegs(ThreadContext *tc);
|
||||||
|
|
||||||
void clearArchRegs()
|
void clearArchRegs()
|
||||||
|
@ -455,11 +453,4 @@ class SimpleThread : public ThreadState
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// for non-speculative execution context, spec_mode is always false
|
|
||||||
inline bool
|
|
||||||
SimpleThread::misspeculating()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __CPU_CPU_EXEC_CONTEXT_HH__
|
#endif // __CPU_CPU_EXEC_CONTEXT_HH__
|
||||||
|
|
|
@ -255,9 +255,6 @@ class ThreadContext
|
||||||
|
|
||||||
virtual void setStCondFailures(unsigned sc_failures) = 0;
|
virtual void setStCondFailures(unsigned sc_failures) = 0;
|
||||||
|
|
||||||
// Only really makes sense for old CPU model. Still could be useful though.
|
|
||||||
virtual bool misspeculating() = 0;
|
|
||||||
|
|
||||||
// Same with st cond failures.
|
// Same with st cond failures.
|
||||||
virtual Counter readFuncExeInst() = 0;
|
virtual Counter readFuncExeInst() = 0;
|
||||||
|
|
||||||
|
@ -462,9 +459,6 @@ class ProxyThreadContext : public ThreadContext
|
||||||
void setStCondFailures(unsigned sc_failures)
|
void setStCondFailures(unsigned sc_failures)
|
||||||
{ actualTC->setStCondFailures(sc_failures); }
|
{ actualTC->setStCondFailures(sc_failures); }
|
||||||
|
|
||||||
// @todo: Fix this!
|
|
||||||
bool misspeculating() { return actualTC->misspeculating(); }
|
|
||||||
|
|
||||||
void syscall(int64_t callnum)
|
void syscall(int64_t callnum)
|
||||||
{ actualTC->syscall(callnum); }
|
{ actualTC->syscall(callnum); }
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,6 @@ void FaultBase::invoke(ThreadContext * tc, const StaticInstPtr &inst)
|
||||||
{
|
{
|
||||||
if (FullSystem) {
|
if (FullSystem) {
|
||||||
DPRINTF(Fault, "Fault %s at PC: %s\n", name(), tc->pcState());
|
DPRINTF(Fault, "Fault %s at PC: %s\n", name(), tc->pcState());
|
||||||
assert(!tc->misspeculating());
|
|
||||||
} else {
|
} else {
|
||||||
panic("fault (%s) detected @ PC %s", name(), tc->pcState());
|
panic("fault (%s) detected @ PC %s", name(), tc->pcState());
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,6 @@ class InstRecord
|
||||||
StaticInstPtr staticInst;
|
StaticInstPtr staticInst;
|
||||||
TheISA::PCState pc;
|
TheISA::PCState pc;
|
||||||
StaticInstPtr macroStaticInst;
|
StaticInstPtr macroStaticInst;
|
||||||
bool misspeculating;
|
|
||||||
bool predicate;
|
bool predicate;
|
||||||
|
|
||||||
// The remaining fields are only valid for particular instruction
|
// The remaining fields are only valid for particular instruction
|
||||||
|
@ -89,12 +88,12 @@ class InstRecord
|
||||||
public:
|
public:
|
||||||
InstRecord(Tick _when, ThreadContext *_thread,
|
InstRecord(Tick _when, ThreadContext *_thread,
|
||||||
const StaticInstPtr _staticInst,
|
const StaticInstPtr _staticInst,
|
||||||
TheISA::PCState _pc, bool spec,
|
TheISA::PCState _pc,
|
||||||
const StaticInstPtr _macroStaticInst = NULL)
|
const StaticInstPtr _macroStaticInst = NULL)
|
||||||
: when(_when), thread(_thread),
|
: when(_when), thread(_thread),
|
||||||
staticInst(_staticInst), pc(_pc),
|
staticInst(_staticInst), pc(_pc),
|
||||||
macroStaticInst(_macroStaticInst),
|
macroStaticInst(_macroStaticInst),
|
||||||
misspeculating(spec), predicate(true), addr(0), addr_valid(false),
|
predicate(true), addr(0), addr_valid(false),
|
||||||
data_status(DataInvalid),
|
data_status(DataInvalid),
|
||||||
fetch_seq(0), fetch_seq_valid(false), cp_seq(0), cp_seq_valid(false)
|
fetch_seq(0), fetch_seq_valid(false), cp_seq(0), cp_seq_valid(false)
|
||||||
{
|
{
|
||||||
|
@ -136,7 +135,6 @@ class InstRecord
|
||||||
StaticInstPtr getStaticInst() { return staticInst; }
|
StaticInstPtr getStaticInst() { return staticInst; }
|
||||||
TheISA::PCState getPCState() { return pc; }
|
TheISA::PCState getPCState() { return pc; }
|
||||||
StaticInstPtr getMacroStaticInst() { return macroStaticInst; }
|
StaticInstPtr getMacroStaticInst() { return macroStaticInst; }
|
||||||
bool getMisspeculating() { return misspeculating; }
|
|
||||||
|
|
||||||
Addr getAddr() { return addr; }
|
Addr getAddr() { return addr; }
|
||||||
bool getAddrValid() { return addr_valid; }
|
bool getAddrValid() { return addr_valid; }
|
||||||
|
|
Loading…
Reference in a new issue