24.22.6.1.2. gem5 O3ThreadContext
Instantiation happens in the FullO3CPU
constructor:
FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params) for (ThreadID tid = 0; tid < this->numThreads; ++tid) { if (FullSystem) { // SMT is not supported in FS mode yet. assert(this->numThreads == 1); this->thread[tid] = new Thread(this, 0, NULL); // Setup the TC that will serve as the interface to the threads/CPU. O3ThreadContext<Impl> *o3_tc = new O3ThreadContext<Impl>;
and the SimObject DerivO3CPU
is just a FullO3CPU
instantiation:
class DerivO3CPU : public FullO3CPU<O3CPUImpl>
O3ThreadContext
is a template class:
template <class Impl> class O3ThreadContext : public ThreadContext
The only Impl
used appears to be O3CPUImpl
? This is explicitly instantiated in the source:
template class O3ThreadContext<O3CPUImpl>;
Unlike in SimpleThread
however, O3ThreadContext
does not contain the register data itself, e.g. O3ThreadContext::readIntRegFlat
instead forwards to cpu
:
template <class Impl> RegVal O3ThreadContext<Impl>::readIntRegFlat(RegIndex reg_idx) const { return cpu->readArchIntReg(reg_idx, thread->threadId()); }
where:
typedef typename Impl::O3CPU O3CPU; /** Pointer to the CPU. */ O3CPU *cpu;
and:
struct O3CPUImpl { /** The O3CPU type to be used. */ typedef FullO3CPU<O3CPUImpl> O3CPU;
and at long last FullO3CPU
contains the register values:
template <class Impl> RegVal FullO3CPU<Impl>::readArchIntReg(int reg_idx, ThreadID tid) { intRegfileReads++; PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup( RegId(IntRegClass, reg_idx)); return regFile.readIntReg(phys_reg); }
So we guess that this difference from SimpleThread
is due to register renaming of the out of order implementation.