MiscReg
-MiscRegFile::readRegNoEffect(int misc_reg, unsigned tid )
+MiscRegFile::readRegNoEffect(int misc_reg, ThreadID tid)
{
switch (misc_reg) {
case MISCREG_FPCR:
}
MiscReg
-MiscRegFile::readReg(int misc_reg, ThreadContext *tc, unsigned tid )
+MiscRegFile::readReg(int misc_reg, ThreadContext *tc, ThreadID tid)
{
switch (misc_reg) {
case MISCREG_FPCR:
}
void
-MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid)
+MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val, ThreadID tid)
{
switch (misc_reg) {
case MISCREG_FPCR:
void
MiscRegFile::setReg(int misc_reg, const MiscReg &val, ThreadContext *tc,
- unsigned tid)
+ ThreadID tid)
{
switch (misc_reg) {
case MISCREG_FPCR:
int getInstAsid();
int getDataAsid();
- MiscReg readRegNoEffect(int misc_reg, unsigned tid = 0);
- MiscReg readReg(int misc_reg, ThreadContext *tc, unsigned tid = 0);
+ MiscReg readRegNoEffect(int misc_reg, ThreadID tid = 0);
+ MiscReg readReg(int misc_reg, ThreadContext *tc, ThreadID tid = 0);
- void setRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid = 0);
- void setReg(int misc_reg, const MiscReg &val, ThreadContext *tc, unsigned tid = 0);
+ void setRegNoEffect(int misc_reg, const MiscReg &val, ThreadID tid = 0);
+ void setReg(int misc_reg, const MiscReg &val, ThreadContext *tc,
+ ThreadID tid = 0);
void
clear()
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string §ion);
- void reset(std::string core_name, unsigned num_threads,
+ void reset(std::string core_name, ThreadID num_threads,
unsigned num_vpes, BaseCPU *_cpu)
{ }
- void expandForMultithreading(unsigned num_threads, unsigned num_vpes)
+ void expandForMultithreading(ThreadID num_threads, unsigned num_vpes)
{ }
int num_threads = bits(tc->readMiscRegNoEffect(MVPConf0), MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
int success = 0;
- for (int tid = 0; tid < num_threads && success == 0; tid++) {
+ for (ThreadID tid = 0; tid < num_threads && success == 0; tid++) {
unsigned tid_TCBind = tc->readRegOtherThread(MipsISA::TCBind + Ctrl_Base_DepTag,
tid);
unsigned tc_bind = tc->readMiscRegNoEffect(MipsISA::TCBind);
{
if (src_reg == 0) {
unsigned mvpconf0 = tc->readMiscRegNoEffect(MVPConf0);
- int num_threads = bits(mvpconf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
+ ThreadID num_threads = bits(mvpconf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
int ok = 0;
unsigned cur_vpe = bits(tcbind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO);
unsigned cur_tc = bits(tcbind, TCB_CUR_TC_HI, TCB_CUR_TC_LO);
- for (int tid = 0; tid < num_threads; tid++) {
+ for (ThreadID tid = 0; tid < num_threads; tid++) {
unsigned tid_TCStatus = tc->readRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag,
tid);
unsigned tid_TCHalt = tc->readRegOtherThread(MipsISA::TCHalt + Ctrl_Base_DepTag,
miscRegFile.clear();
}
-void RegFile::reset(std::string core_name, unsigned num_threads, unsigned num_vpes)
+void
+RegFile::reset(std::string core_name, ThreadID num_threads,
+ unsigned num_vpes)
{
bzero(&intRegFile, sizeof(intRegFile));
bzero(&floatRegFile, sizeof(floatRegFile));
return intRegFile.setReg(intReg, val);
}
-MiscReg RegFile::readMiscRegNoEffect(int miscReg, unsigned tid = 0)
+MiscReg
+RegFile::readMiscRegNoEffect(int miscReg, ThreadID tid = 0)
{
return miscRegFile.readRegNoEffect(miscReg, tid);
}
-MiscReg RegFile::readMiscReg(int miscReg, ThreadContext *tc,
- unsigned tid = 0)
+MiscReg
+RegFile::readMiscReg(int miscReg, ThreadContext *tc, ThreadID tid = 0)
{
return miscRegFile.readReg(miscReg, tc, tid);
}
-void RegFile::setMiscRegNoEffect(int miscReg, const MiscReg &val, unsigned tid = 0)
+void
+RegFile::setMiscRegNoEffect(int miscReg, const MiscReg &val, ThreadID tid = 0)
{
miscRegFile.setRegNoEffect(miscReg, val, tid);
}
-void RegFile::setMiscReg(int miscReg, const MiscReg &val,
- ThreadContext * tc, unsigned tid = 0)
+void
+RegFile::setMiscReg(int miscReg, const MiscReg &val,
+ ThreadContext *tc, ThreadID tid = 0)
{
miscRegFile.setReg(miscReg, val, tc, tid);
}
}
double
-FloatRegFile::readReg(int floatReg, int width, unsigned tid)
+FloatRegFile::readReg(int floatReg, int width, ThreadID tid)
{
switch(width)
{
}
FloatRegBits
-FloatRegFile::readRegBits(int floatReg, int width, unsigned tid)
+FloatRegFile::readRegBits(int floatReg, int width, ThreadID tid)
{
if (floatReg < NumFloatArchRegs - 1) {
switch(width)
}
Fault
-FloatRegFile::setReg(int floatReg, const FloatRegVal &val, int width, unsigned tid)
+FloatRegFile::setReg(int floatReg, const FloatRegVal &val, int width,
+ ThreadID tid)
{
- using namespace std;
switch(width)
{
case SingleWidth:
}
Fault
-FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width, unsigned tid)
+FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width,
+ ThreadID tid)
{
- using namespace std;
-
switch(width)
{
case SingleWidth:
static const int regWidth = SingleWidth;
void clear();
- double readReg(int floatReg, int width, unsigned tid = 0);
- FloatRegBits readRegBits(int floatReg, int width, unsigned tid = 0);
- Fault setReg(int floatReg, const FloatRegVal &val, int width, unsigned tid = 0);
- Fault setRegBits(int floatReg, const FloatRegBits &val, int width, unsigned tid = 0);
+ double readReg(int floatReg, int width, ThreadID tid = 0);
+ FloatRegBits readRegBits(int floatReg, int width, ThreadID tid = 0);
+ Fault setReg(int floatReg, const FloatRegVal &val, int width,
+ ThreadID tid = 0);
+ Fault setRegBits(int floatReg, const FloatRegBits &val, int width,
+ ThreadID tid = 0);
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string §ion);
}
void
-MiscRegFile::expandForMultithreading(unsigned num_threads, unsigned num_vpes)
+MiscRegFile::expandForMultithreading(ThreadID num_threads, unsigned num_vpes)
{
// Initialize all Per-VPE regs
uint32_t per_vpe_regs[] = { VPEControl, VPEConf0, VPEConf1, YQMask,
}
//@TODO: Use MIPS STYLE CONSTANTS (e.g. TCHALT_H instead of TCH_H)
void
-MiscRegFile::reset(std::string core_name, unsigned num_threads,
+MiscRegFile::reset(std::string core_name, ThreadID num_threads,
unsigned num_vpes, BaseCPU *_cpu)
{
DPRINTF(MipsPRA, "Resetting CP0 State with %i TCs and %i VPEs\n",
setRegNoEffect(VPEConf0, vpe_conf0);
// TCBind
- for (int tid = 0; tid < num_threads; tid++) {
+ for (ThreadID tid = 0; tid < num_threads; tid++) {
MiscReg tc_bind = readRegNoEffect(TCBind, tid);
replaceBits(tc_bind, TCB_CUR_TC_HI, TCB_CUR_TC_LO, tid);
setRegNoEffect(TCBind, tc_bind, tid);
MiscReg tc_halt = readRegNoEffect(TCHalt);
replaceBits(tc_halt, TCH_H, 0);
setRegNoEffect(TCHalt, tc_halt);
- /*for (int tid = 1; tid < num_threads; tid++) {
+ /*for (ThreadID tid = 1; tid < num_threads; tid++) {
// Set TCHalt Halt bit to 1 for all other threads
tc_halt = readRegNoEffect(TCHalt, tid);
replaceBits(tc_halt, TCH_H, 1);
setRegNoEffect(TCStatus, tc_status);
// Set Dynamically Allocatable bit to 1 for all other threads
- for (int tid = 1; tid < num_threads; tid++) {
+ for (ThreadID tid = 1; tid < num_threads; tid++) {
tc_status = readRegNoEffect(TCStatus, tid);
replaceBits(tc_status, TCSTATUS_DA, 1);
setRegNoEffect(TCStatus, tc_status, tid);
}
inline unsigned
-MiscRegFile::getVPENum(unsigned tid)
+MiscRegFile::getVPENum(ThreadID tid)
{
unsigned tc_bind = miscRegFile[TCBind - Ctrl_Base_DepTag][tid];
return bits(tc_bind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO);
}
MiscReg
-MiscRegFile::readRegNoEffect(int reg_idx, unsigned tid)
+MiscRegFile::readRegNoEffect(int reg_idx, ThreadID tid)
{
int misc_reg = reg_idx - Ctrl_Base_DepTag;
unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
// Status to TCStatus depending on current thread
//template <class TC>
MiscReg
-MiscRegFile::readReg(int reg_idx,
- ThreadContext *tc, unsigned tid)
+MiscRegFile::readReg(int reg_idx, ThreadContext *tc, ThreadID tid)
{
int misc_reg = reg_idx - Ctrl_Base_DepTag;
unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
}
void
-MiscRegFile::setRegNoEffect(int reg_idx, const MiscReg &val, unsigned tid)
+MiscRegFile::setRegNoEffect(int reg_idx, const MiscReg &val, ThreadID tid)
{
int misc_reg = reg_idx - Ctrl_Base_DepTag;
unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
miscRegFile[misc_reg][reg_sel] = val;
}
void
-MiscRegFile::setRegMask(int reg_idx, const MiscReg &val, unsigned tid)
+MiscRegFile::setRegMask(int reg_idx, const MiscReg &val, ThreadID tid)
{
// return;
int misc_reg = reg_idx - Ctrl_Base_DepTag;
//template <class TC>
void
MiscRegFile::setReg(int reg_idx, const MiscReg &val,
- ThreadContext *tc, unsigned tid)
+ ThreadContext *tc, ThreadID tid)
{
int misc_reg = reg_idx - Ctrl_Base_DepTag;
int reg_sel = (bankType[misc_reg] == perThreadContext)
//
///////////////////////////////////////////////////////////////////
unsigned mvp_conf0 = readRegNoEffect(MVPConf0);
- unsigned num_threads = bits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
+ ThreadID num_threads = bits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
- for (int tid = 0; tid < num_threads; tid++) {
+ for (ThreadID tid = 0; tid < num_threads; tid++) {
MiscReg tc_status = readRegNoEffect(TCStatus, tid);
MiscReg tc_halt = readRegNoEffect(TCHalt, tid);
void clear(unsigned tid_or_vpn = 0);
- void reset(std::string core_name, unsigned num_threads,
+ void reset(std::string core_name, ThreadID num_threads,
unsigned num_vpes, BaseCPU *_cpu);
- void expandForMultithreading(unsigned num_threads, unsigned num_vpes);
+ void expandForMultithreading(ThreadID num_threads, unsigned num_vpes);
- inline unsigned getVPENum(unsigned tid);
+ unsigned getVPENum(ThreadID tid);
//////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////
//@TODO: MIPS MT's register view automatically connects
// Status to TCStatus depending on current thread
- void updateCP0ReadView(int misc_reg, unsigned tid) { }
- MiscReg readRegNoEffect(int misc_reg, unsigned tid = 0);
+ void updateCP0ReadView(int misc_reg, ThreadID tid) { }
+ MiscReg readRegNoEffect(int misc_reg, ThreadID tid = 0);
//template <class TC>
MiscReg readReg(int misc_reg,
- ThreadContext *tc, unsigned tid = 0);
+ ThreadContext *tc, ThreadID tid = 0);
MiscReg filterCP0Write(int misc_reg, int reg_sel, const MiscReg &val);
- void setRegMask(int misc_reg, const MiscReg &val, unsigned tid = 0);
+ void setRegMask(int misc_reg, const MiscReg &val, ThreadID tid = 0);
void setRegNoEffect(int misc_reg, const MiscReg &val,
- unsigned tid = 0);
+ ThreadID tid = 0);
//template <class TC>
void setReg(int misc_reg, const MiscReg &val,
- ThreadContext *tc, unsigned tid = 0);
+ ThreadContext *tc, ThreadID tid = 0);
int getInstAsid();
int getDataAsid();
}
void
-RegFile::reset(std::string core_name, unsigned num_threads, unsigned num_vpes, BaseCPU *_cpu)
+RegFile::reset(std::string core_name, ThreadID num_threads, unsigned num_vpes,
+ BaseCPU *_cpu)
{
bzero(&intRegFile, sizeof(intRegFile));
bzero(&floatRegFile, sizeof(floatRegFile));
}
MiscReg
-RegFile::readMiscRegNoEffect(int miscReg, unsigned tid)
+RegFile::readMiscRegNoEffect(int miscReg, ThreadID tid)
{
return miscRegFile.readRegNoEffect(miscReg, tid);
}
MiscReg
-RegFile::readMiscReg(int miscReg, ThreadContext *tc,
- unsigned tid)
+RegFile::readMiscReg(int miscReg, ThreadContext *tc, ThreadID tid)
{
return miscRegFile.readReg(miscReg, tc, tid);
}
void
-RegFile::setMiscRegNoEffect(int miscReg, const MiscReg &val, unsigned tid)
+RegFile::setMiscRegNoEffect(int miscReg, const MiscReg &val, ThreadID tid)
{
miscRegFile.setRegNoEffect(miscReg, val, tid);
}
void
RegFile::setMiscReg(int miscReg, const MiscReg &val,
- ThreadContext * tc, unsigned tid)
+ ThreadContext *tc, ThreadID tid)
{
miscRegFile.setReg(miscReg, val, tc, tid);
}
public:
void clear();
- void reset(std::string core_name, unsigned num_threads, unsigned num_vpes, BaseCPU *_cpu);
+ void reset(std::string core_name, ThreadID num_threads,
+ unsigned num_vpes, BaseCPU *_cpu);
MiscRegFile *getMiscRegFilePtr();
IntReg readIntReg(int intReg);
Fault setIntReg(int intReg, const IntReg &val);
- MiscReg readMiscRegNoEffect(int miscReg, unsigned tid = 0);
+ MiscReg readMiscRegNoEffect(int miscReg, ThreadID tid = 0);
MiscReg readMiscReg(int miscReg, ThreadContext *tc,
- unsigned tid = 0);
- void setMiscRegNoEffect(int miscReg, const MiscReg &val, unsigned tid = 0);
+ ThreadID tid = 0);
+ void setMiscRegNoEffect(int miscReg, const MiscReg &val,
+ ThreadID tid = 0);
void setMiscReg(int miscReg, const MiscReg &val,
- ThreadContext * tc, unsigned tid = 0);
+ ThreadContext *tc, ThreadID tid = 0);
FloatRegVal readFloatReg(int floatReg);
FloatRegVal readFloatReg(int floatReg, int width);
const Addr MaxAddr = (Addr)-1;
+/**
+ * Thread index/ID type
+ */
+typedef int16_t ThreadID;
+const ThreadID InvalidThreadID = (ThreadID)-1;
+
#endif // __BASE_TYPES_HH__
BaseCPU::BaseCPU(Params *p)
: MemObject(p), clock(p->clock), instCnt(0), _cpuId(p->cpu_id),
interrupts(p->interrupts),
- number_of_threads(p->numThreads), system(p->system),
+ numThreads(p->numThreads), system(p->system),
phase(p->phase)
#else
BaseCPU::BaseCPU(Params *p)
: MemObject(p), clock(p->clock), _cpuId(p->cpu_id),
- number_of_threads(p->numThreads), system(p->system),
+ numThreads(p->numThreads), system(p->system),
phase(p->phase)
#endif
{
DPRINTF(SyscallVerbose, "Constructing CPU with id %d\n", _cpuId);
- if (number_of_threads > maxThreadsPerCPU)
- maxThreadsPerCPU = number_of_threads;
+ if (numThreads > maxThreadsPerCPU)
+ maxThreadsPerCPU = numThreads;
// allocate per-thread instruction-based event queues
- comInstEventQueue = new EventQueue *[number_of_threads];
- for (int i = 0; i < number_of_threads; ++i)
- comInstEventQueue[i] = new EventQueue("instruction-based event queue");
+ comInstEventQueue = new EventQueue *[numThreads];
+ for (ThreadID tid = 0; tid < numThreads; ++tid)
+ comInstEventQueue[tid] =
+ new EventQueue("instruction-based event queue");
//
// set up instruction-count-based termination events, if any
//
if (p->max_insts_any_thread != 0) {
const char *cause = "a thread reached the max instruction count";
- for (int i = 0; i < number_of_threads; ++i) {
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
Event *event = new SimLoopExitEvent(cause, 0);
- comInstEventQueue[i]->schedule(event, p->max_insts_any_thread);
+ comInstEventQueue[tid]->schedule(event, p->max_insts_any_thread);
}
}
// decrement this when triggered; simulation will terminate
// when counter reaches 0
int *counter = new int;
- *counter = number_of_threads;
- for (int i = 0; i < number_of_threads; ++i) {
+ *counter = numThreads;
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
Event *event = new CountedExitEvent(cause, *counter);
- comInstEventQueue[i]->schedule(event, p->max_insts_any_thread);
+ comInstEventQueue[tid]->schedule(event, p->max_insts_any_thread);
}
}
// allocate per-thread load-based event queues
- comLoadEventQueue = new EventQueue *[number_of_threads];
- for (int i = 0; i < number_of_threads; ++i)
- comLoadEventQueue[i] = new EventQueue("load-based event queue");
+ comLoadEventQueue = new EventQueue *[numThreads];
+ for (ThreadID tid = 0; tid < numThreads; ++tid)
+ comLoadEventQueue[tid] = new EventQueue("load-based event queue");
//
// set up instruction-count-based termination events, if any
//
if (p->max_loads_any_thread != 0) {
const char *cause = "a thread reached the max load count";
- for (int i = 0; i < number_of_threads; ++i) {
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
Event *event = new SimLoopExitEvent(cause, 0);
- comLoadEventQueue[i]->schedule(event, p->max_loads_any_thread);
+ comLoadEventQueue[tid]->schedule(event, p->max_loads_any_thread);
}
}
// decrement this when triggered; simulation will terminate
// when counter reaches 0
int *counter = new int;
- *counter = number_of_threads;
- for (int i = 0; i < number_of_threads; ++i) {
+ *counter = numThreads;
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
Event *event = new CountedExitEvent(cause, *counter);
- comLoadEventQueue[i]->schedule(event, p->max_loads_all_threads);
+ comLoadEventQueue[tid]->schedule(event, p->max_loads_all_threads);
}
}
void
BaseCPU::registerThreadContexts()
{
- for (int i = 0; i < threadContexts.size(); ++i) {
- ThreadContext *tc = threadContexts[i];
+ ThreadID size = threadContexts.size();
+ for (ThreadID tid = 0; tid < size; ++tid) {
+ ThreadContext *tc = threadContexts[tid];
/** This is so that contextId and cpuId match where there is a
* 1cpu:1context relationship. Otherwise, the order of registration
* cpu 0 has the lowest thread contexts and cpu N has the highest, but
* I'll just do this for now
*/
- if (number_of_threads == 1)
+ if (numThreads == 1)
tc->setContextId(system->registerThreadContext(tc, _cpuId));
else
tc->setContextId(system->registerThreadContext(tc));
int
BaseCPU::findContext(ThreadContext *tc)
{
- for (int i = 0; i < threadContexts.size(); ++i) {
- if (tc == threadContexts[i])
- return i;
+ ThreadID size = threadContexts.size();
+ for (ThreadID tid = 0; tid < size; ++tid) {
+ if (tc == threadContexts[tid])
+ return tid;
}
return 0;
}
_cpuId = oldCPU->cpuId();
- for (int i = 0; i < threadContexts.size(); ++i) {
+ ThreadID size = threadContexts.size();
+ for (ThreadID i = 0; i < size; ++i) {
ThreadContext *newTC = threadContexts[i];
ThreadContext *oldTC = oldCPU->threadContexts[i];
interrupts = oldCPU->interrupts;
interrupts->setCPU(this);
- for (int i = 0; i < threadContexts.size(); ++i)
+ for (ThreadID i = 0; i < size; ++i)
threadContexts[i]->profileClear();
if (profileEvent)
void
BaseCPU::ProfileEvent::process()
{
- for (int i = 0, size = cpu->threadContexts.size(); i < size; ++i) {
+ ThreadID size = cpu->threadContexts.size();
+ for (ThreadID i = 0; i < size; ++i) {
ThreadContext *tc = cpu->threadContexts[i];
tc->profileSample();
}
virtual void startup();
virtual void regStats();
- virtual void activateWhenReady(int tid) {};
+ virtual void activateWhenReady(ThreadID tid) {};
void registerThreadContexts();
* Number of threads we're actually simulating (<= SMT_MAX_THREADS).
* This is a constant for the duration of the simulation.
*/
- int number_of_threads;
+ ThreadID numThreads;
TheISA::CoreSpecific coreParams; //ISA-Specific Params That Set Up State in Core
std::bitset<NumStatus> status;
/** The thread this instruction is from. */
- short threadNumber;
+ ThreadID threadNumber;
/** data address space ID, for loads & stores. */
short asid;
void setASID(short addr_space_id) { asid = addr_space_id; }
/** Sets the thread id. */
- void setTid(unsigned tid) { threadNumber = tid; }
+ void setTid(ThreadID tid) { threadNumber = tid; }
/** Sets the pointer to the thread state. */
void setThreadState(ImplState *state) { thread = state; }
}
bool
-DefaultBTB::valid(const Addr &inst_PC, unsigned tid)
+DefaultBTB::valid(const Addr &inst_PC, ThreadID tid)
{
unsigned btb_idx = getIndex(inst_PC);
// address is valid, and also the address. For now will just use addr = 0 to
// represent invalid entry.
Addr
-DefaultBTB::lookup(const Addr &inst_PC, unsigned tid)
+DefaultBTB::lookup(const Addr &inst_PC, ThreadID tid)
{
unsigned btb_idx = getIndex(inst_PC);
}
void
-DefaultBTB::update(const Addr &inst_PC, const Addr &target, unsigned tid)
+DefaultBTB::update(const Addr &inst_PC, const Addr &target, ThreadID tid)
{
unsigned btb_idx = getIndex(inst_PC);
*
*/
-#include "config/full_system.hh"
+#include <algorithm>
#include "arch/utility.hh"
+#include "config/full_system.hh"
#include "cpu/exetrace.hh"
#include "cpu/activity.hh"
#include "cpu/simple_thread.hh"
#include "mem/translating_port.hh"
#include "sim/process.hh"
#include "sim/stat_control.hh"
-#include <algorithm>
using namespace std;
using namespace TheISA;
}
InOrderCPU::CPUEvent::CPUEvent(InOrderCPU *_cpu, CPUEventType e_type,
- Fault fault, unsigned _tid, unsigned _vpe)
+ Fault fault, ThreadID _tid, unsigned _vpe)
: Event(CPU_Tick_Pri), cpu(_cpu)
{
setEvent(e_type, fault, _tid, _vpe);
switchCount(0),
deferRegistration(false/*params->deferRegistration*/),
stageTracing(params->stageTracing),
- numThreads(params->numThreads),
numVirtProcs(1)
{
cpu_params = params;
fatal("Unable to find port for data.\n");
}
- for (int i = 0; i < numThreads; ++i) {
- if (i < params->workload.size()) {
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
+ if (tid < params->workload.size()) {
DPRINTF(InOrderCPU, "Workload[%i] process is %#x\n",
- i, this->thread[i]);
- this->thread[i] = new Thread(this, i, params->workload[i],
- i);
+ tid, this->thread[tid]);
+ this->thread[tid] =
+ new Thread(this, tid, params->workload[tid], tid);
} else {
//Allocate Empty thread so M5 can use later
//when scheduling threads to CPU
Process* dummy_proc = params->workload[0];
- this->thread[i] = new Thread(this, i, dummy_proc, i);
+ this->thread[tid] = new Thread(this, tid, dummy_proc, tid);
}
// Setup the TC that will serve as the interface to the threads/CPU.
InOrderThreadContext *tc = new InOrderThreadContext;
tc->cpu = this;
- tc->thread = this->thread[i];
+ tc->thread = thread[tid];
// Give the thread the TC.
- thread[i]->tc = tc;
- thread[i]->setFuncExeInst(0);
- globalSeqNum[i] = 1;
+ thread[tid]->tc = tc;
+ thread[tid]->setFuncExeInst(0);
+ globalSeqNum[tid] = 1;
// Add the TC to the CPU's list of TC's.
this->threadContexts.push_back(tc);
}
// Initialize thread specific variables
- for (int tid=0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
archRegDepMap[tid].setCPU(this);
nonSpecInstActive[tid] = false;
// Set inSyscall so that the CPU doesn't squash when initially
// setting up registers.
- for (int i = 0; i < number_of_threads; ++i)
- thread[i]->inSyscall = true;
+ for (ThreadID tid = 0; tid < numThreads; ++tid)
+ thread[tid]->inSyscall = true;
#if FULL_SYSTEM
- for (int tid=0; tid < number_of_threads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
ThreadContext *src_tc = threadContexts[tid];
TheISA::initCPU(src_tc, src_tc->contextId());
}
#endif
// Clear inSyscall.
- for (int i = 0; i < number_of_threads; ++i)
- thread[i]->inSyscall = false;
+ for (ThreadID tid = 0; tid < numThreads; ++tid)
+ thread[tid]->inSyscall = false;
// Call Initializiation Routine for Resource Pool
resPool->init();
}
void
-InOrderCPU::trap(Fault fault, unsigned tid, int delay)
+InOrderCPU::trap(Fault fault, ThreadID tid, int delay)
{
//@ Squash Pipeline during TRAP
scheduleCpuEvent(Trap, fault, tid, 0/*vpe*/, delay);
}
void
-InOrderCPU::trapCPU(Fault fault, unsigned tid)
+InOrderCPU::trapCPU(Fault fault, ThreadID tid)
{
fault->invoke(tcBase(tid));
}
void
InOrderCPU::scheduleCpuEvent(CPUEventType c_event, Fault fault,
- unsigned tid, unsigned vpe, unsigned delay)
+ ThreadID tid, unsigned vpe, unsigned delay)
{
CPUEvent *cpu_event = new CPUEvent(this, c_event, fault, tid, vpe);
}
// Broadcast event to the Resource Pool
- DynInstPtr dummy_inst = new InOrderDynInst(this, NULL, getNextEventNum(), tid);
+ DynInstPtr dummy_inst =
+ new InOrderDynInst(this, NULL, getNextEventNum(), tid);
resPool->scheduleEvent(c_event, dummy_inst, 0, 0, tid);
}
inline bool
-InOrderCPU::isThreadActive(unsigned tid)
+InOrderCPU::isThreadActive(ThreadID tid)
{
- list<unsigned>::iterator isActive = std::find(
- activeThreads.begin(), activeThreads.end(), tid);
+ list<ThreadID>::iterator isActive =
+ std::find(activeThreads.begin(), activeThreads.end(), tid);
return (isActive != activeThreads.end());
}
void
-InOrderCPU::activateThread(unsigned tid)
+InOrderCPU::activateThread(ThreadID tid)
{
if (!isThreadActive(tid)) {
- DPRINTF(InOrderCPU, "Adding Thread %i to active threads list in CPU.\n",
- tid);
+ DPRINTF(InOrderCPU,
+ "Adding Thread %i to active threads list in CPU.\n", tid);
activeThreads.push_back(tid);
wakeCPU();
}
void
-InOrderCPU::deactivateThread(unsigned tid)
+InOrderCPU::deactivateThread(ThreadID tid)
{
DPRINTF(InOrderCPU, "[tid:%i]: Calling deactivate thread.\n", tid);
if (isThreadActive(tid)) {
DPRINTF(InOrderCPU,"[tid:%i]: Removing from active threads list\n",
tid);
- list<unsigned>::iterator thread_it = std::find(activeThreads.begin(),
- activeThreads.end(), tid);
+ list<ThreadID>::iterator thread_it =
+ std::find(activeThreads.begin(), activeThreads.end(), tid);
removePipelineStalls(*thread_it);
}
void
-InOrderCPU::removePipelineStalls(unsigned tid)
+InOrderCPU::removePipelineStalls(ThreadID tid)
{
DPRINTF(InOrderCPU,"[tid:%i]: Removing all pipeline stalls\n",
tid);
}
bool
-InOrderCPU::isThreadInCPU(unsigned tid)
+InOrderCPU::isThreadInCPU(ThreadID tid)
{
- list<unsigned>::iterator isCurrent = std::find(
- currentThreads.begin(), currentThreads.end(), tid);
+ list<ThreadID>::iterator isCurrent =
+ std::find(currentThreads.begin(), currentThreads.end(), tid);
return (isCurrent != currentThreads.end());
}
void
-InOrderCPU::addToCurrentThreads(unsigned tid)
+InOrderCPU::addToCurrentThreads(ThreadID tid)
{
if (!isThreadInCPU(tid)) {
DPRINTF(InOrderCPU, "Adding Thread %i to current threads list in CPU.\n",
}
void
-InOrderCPU::removeFromCurrentThreads(unsigned tid)
+InOrderCPU::removeFromCurrentThreads(ThreadID tid)
{
if (isThreadInCPU(tid)) {
- DPRINTF(InOrderCPU, "Adding Thread %i to current threads list in CPU.\n",
- tid);
- list<unsigned>::iterator isCurrent = std::find(
- currentThreads.begin(), currentThreads.end(), tid);
+ DPRINTF(InOrderCPU,
+ "Adding Thread %i to current threads list in CPU.\n", tid);
+ list<ThreadID>::iterator isCurrent =
+ std::find(currentThreads.begin(), currentThreads.end(), tid);
currentThreads.erase(isCurrent);
}
}
bool
-InOrderCPU::isThreadSuspended(unsigned tid)
+InOrderCPU::isThreadSuspended(ThreadID tid)
{
- list<unsigned>::iterator isSuspended = std::find(
- suspendedThreads.begin(), suspendedThreads.end(), tid);
+ list<ThreadID>::iterator isSuspended =
+ std::find(suspendedThreads.begin(), suspendedThreads.end(), tid);
return (isSuspended!= suspendedThreads.end());
}
DPRINTF(InOrderCPU, "[vpe:%i]: Enabling Concurrent Execution "
"virtual processors %i", vpe);
- list<unsigned>::iterator thread_it = currentThreads.begin();
+ list<ThreadID>::iterator thread_it = currentThreads.begin();
while (thread_it != currentThreads.end()) {
if (!isThreadSuspended(*thread_it)) {
}
void
-InOrderCPU::disableVirtProcElement(unsigned tid, unsigned vpe)
+InOrderCPU::disableVirtProcElement(ThreadID tid, unsigned vpe)
{
DPRINTF(InOrderCPU, "[vpe:%i]: Scheduling "
"Disabling of concurrent virtual processor execution",
}
void
-InOrderCPU::disableVPEs(unsigned tid, unsigned vpe)
+InOrderCPU::disableVPEs(ThreadID tid, unsigned vpe)
{
DPRINTF(InOrderCPU, "[vpe:%i]: Disabling Concurrent Execution of "
"virtual processors %i", vpe);
unsigned base_vpe = TheISA::getVirtProcNum(tcBase(tid));
- list<unsigned>::iterator thread_it = activeThreads.begin();
+ list<ThreadID>::iterator thread_it = activeThreads.begin();
- std::vector<list<unsigned>::iterator> removeList;
+ vector<list<ThreadID>::iterator> removeList;
while (thread_it != activeThreads.end()) {
if (base_vpe != vpe) {
DPRINTF(InOrderCPU, "[vpe:%i]: Enabling Multithreading on "
"virtual processor %i", vpe);
- list<unsigned>::iterator thread_it = currentThreads.begin();
+ list<ThreadID>::iterator thread_it = currentThreads.begin();
while (thread_it != currentThreads.end()) {
if (TheISA::getVirtProcNum(tcBase(*thread_it)) == vpe) {
}
}
void
-InOrderCPU::disableMultiThreading(unsigned tid, unsigned vpe)
+InOrderCPU::disableMultiThreading(ThreadID tid, unsigned vpe)
{
// Schedule event to take place at end of cycle
DPRINTF(InOrderCPU, "[tid:%i]: Scheduling Disable Multithreading on "
}
void
-InOrderCPU::disableThreads(unsigned tid, unsigned vpe)
+InOrderCPU::disableThreads(ThreadID tid, unsigned vpe)
{
DPRINTF(InOrderCPU, "[tid:%i]: Disabling Multithreading on "
"virtual processor %i", tid, vpe);
- list<unsigned>::iterator thread_it = activeThreads.begin();
+ list<ThreadID>::iterator thread_it = activeThreads.begin();
- std::vector<list<unsigned>::iterator> removeList;
+ vector<list<ThreadID>::iterator> removeList;
while (thread_it != activeThreads.end()) {
if (TheISA::getVirtProcNum(tcBase(*thread_it)) == vpe) {
{
//DEFAULT TO ROUND ROBIN SCHEME
//e.g. Move highest priority to end of thread list
- list<unsigned>::iterator list_begin = activeThreads.begin();
- list<unsigned>::iterator list_end = activeThreads.end();
+ list<ThreadID>::iterator list_begin = activeThreads.begin();
+ list<ThreadID>::iterator list_end = activeThreads.end();
unsigned high_thread = *list_begin;
InOrderCPU::tickThreadStats()
{
/** Keep track of cycles that each thread is active */
- list<unsigned>::iterator thread_it = activeThreads.begin();
+ list<ThreadID>::iterator thread_it = activeThreads.begin();
while (thread_it != activeThreads.end()) {
threadCycles[*thread_it]++;
thread_it++;
}
void
-InOrderCPU::activateContext(unsigned tid, int delay)
+InOrderCPU::activateContext(ThreadID tid, int delay)
{
DPRINTF(InOrderCPU,"[tid:%i]: Activating ...\n", tid);
void
-InOrderCPU::suspendContext(unsigned tid, int delay)
+InOrderCPU::suspendContext(ThreadID tid, int delay)
{
scheduleCpuEvent(SuspendThread, NoFault, tid, 0/*vpe*/, delay);
//_status = Idle;
}
void
-InOrderCPU::suspendThread(unsigned tid)
+InOrderCPU::suspendThread(ThreadID tid)
{
DPRINTF(InOrderCPU,"[tid: %i]: Suspended ...\n", tid);
deactivateThread(tid);
}
void
-InOrderCPU::deallocateContext(unsigned tid, int delay)
+InOrderCPU::deallocateContext(ThreadID tid, int delay)
{
scheduleCpuEvent(DeallocateThread, NoFault, tid, 0/*vpe*/, delay);
}
void
-InOrderCPU::deallocateThread(unsigned tid)
+InOrderCPU::deallocateThread(ThreadID tid)
{
DPRINTF(InOrderCPU,"[tid:%i]: Deallocating ...", tid);
}
void
-InOrderCPU::squashThreadInPipeline(unsigned tid)
+InOrderCPU::squashThreadInPipeline(ThreadID tid)
{
//Squash all instructions in each stage
for (int stNum=NumStages - 1; stNum >= 0 ; stNum--) {
}
void
-InOrderCPU::haltContext(unsigned tid, int delay)
+InOrderCPU::haltContext(ThreadID tid, int delay)
{
DPRINTF(InOrderCPU, "[tid:%i]: Halt context called.\n", tid);
}
void
-InOrderCPU::insertThread(unsigned tid)
+InOrderCPU::insertThread(ThreadID tid)
{
panic("Unimplemented Function\n.");
}
void
-InOrderCPU::removeThread(unsigned tid)
+InOrderCPU::removeThread(ThreadID tid)
{
DPRINTF(InOrderCPU, "Removing Thread %i from CPU.\n", tid);
void
-InOrderCPU::activateWhenReady(int tid)
+InOrderCPU::activateWhenReady(ThreadID tid)
{
panic("Unimplemented Function\n.");
}
uint64_t
-InOrderCPU::readPC(unsigned tid)
+InOrderCPU::readPC(ThreadID tid)
{
return PC[tid];
}
void
-InOrderCPU::setPC(Addr new_PC, unsigned tid)
+InOrderCPU::setPC(Addr new_PC, ThreadID tid)
{
PC[tid] = new_PC;
}
uint64_t
-InOrderCPU::readNextPC(unsigned tid)
+InOrderCPU::readNextPC(ThreadID tid)
{
return nextPC[tid];
}
void
-InOrderCPU::setNextPC(uint64_t new_NPC, unsigned tid)
+InOrderCPU::setNextPC(uint64_t new_NPC, ThreadID tid)
{
nextPC[tid] = new_NPC;
}
uint64_t
-InOrderCPU::readNextNPC(unsigned tid)
+InOrderCPU::readNextNPC(ThreadID tid)
{
return nextNPC[tid];
}
void
-InOrderCPU::setNextNPC(uint64_t new_NNPC, unsigned tid)
+InOrderCPU::setNextNPC(uint64_t new_NNPC, ThreadID tid)
{
nextNPC[tid] = new_NNPC;
}
uint64_t
-InOrderCPU::readIntReg(int reg_idx, unsigned tid)
+InOrderCPU::readIntReg(int reg_idx, ThreadID tid)
{
return intRegFile[tid].readReg(reg_idx);
}
FloatReg
-InOrderCPU::readFloatReg(int reg_idx, unsigned tid, int width)
+InOrderCPU::readFloatReg(int reg_idx, ThreadID tid, int width)
{
return floatRegFile[tid].readReg(reg_idx, width);
}
FloatRegBits
-InOrderCPU::readFloatRegBits(int reg_idx, unsigned tid, int width)
+InOrderCPU::readFloatRegBits(int reg_idx, ThreadID tid, int width)
{;
return floatRegFile[tid].readRegBits(reg_idx, width);
}
void
-InOrderCPU::setIntReg(int reg_idx, uint64_t val, unsigned tid)
+InOrderCPU::setIntReg(int reg_idx, uint64_t val, ThreadID tid)
{
intRegFile[tid].setReg(reg_idx, val);
}
void
-InOrderCPU::setFloatReg(int reg_idx, FloatReg val, unsigned tid, int width)
+InOrderCPU::setFloatReg(int reg_idx, FloatReg val, ThreadID tid, int width)
{
floatRegFile[tid].setReg(reg_idx, val, width);
}
void
-InOrderCPU::setFloatRegBits(int reg_idx, FloatRegBits val, unsigned tid, int width)
+InOrderCPU::setFloatRegBits(int reg_idx, FloatRegBits val, ThreadID tid,
+ int width)
{
floatRegFile[tid].setRegBits(reg_idx, val, width);
}
uint64_t
-InOrderCPU::readRegOtherThread(unsigned reg_idx, unsigned tid)
+InOrderCPU::readRegOtherThread(unsigned reg_idx, ThreadID tid)
{
// If Default value is set, then retrieve target thread
- if (tid == -1) {
+ if (tid == InvalidThreadID) {
tid = TheISA::getTargetThread(tcBase(tid));
}
}
}
void
-InOrderCPU::setRegOtherThread(unsigned reg_idx, const MiscReg &val, unsigned tid)
+InOrderCPU::setRegOtherThread(unsigned reg_idx, const MiscReg &val,
+ ThreadID tid)
{
// If Default value is set, then retrieve target thread
- if (tid == -1) {
+ if (tid == InvalidThreadID) {
tid = TheISA::getTargetThread(tcBase(tid));
}
}
MiscReg
-InOrderCPU::readMiscRegNoEffect(int misc_reg, unsigned tid)
+InOrderCPU::readMiscRegNoEffect(int misc_reg, ThreadID tid)
{
return miscRegFile.readRegNoEffect(misc_reg, tid);
}
MiscReg
-InOrderCPU::readMiscReg(int misc_reg, unsigned tid)
+InOrderCPU::readMiscReg(int misc_reg, ThreadID tid)
{
return miscRegFile.readReg(misc_reg, tcBase(tid), tid);
}
void
-InOrderCPU::setMiscRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid)
+InOrderCPU::setMiscRegNoEffect(int misc_reg, const MiscReg &val, ThreadID tid)
{
miscRegFile.setRegNoEffect(misc_reg, val, tid);
}
void
-InOrderCPU::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid)
+InOrderCPU::setMiscReg(int misc_reg, const MiscReg &val, ThreadID tid)
{
miscRegFile.setReg(misc_reg, val, tcBase(tid), tid);
}
InOrderCPU::ListIt
InOrderCPU::addInst(DynInstPtr &inst)
{
- int tid = inst->readTid();
+ ThreadID tid = inst->readTid();
instList[tid].push_back(inst);
}
void
-InOrderCPU::instDone(DynInstPtr inst, unsigned tid)
+InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
{
// Set the CPU's PCs - This contributes to the precise state of the CPU which can be used
// when restoring a thread to the CPU after a fork or after an exception
}
void
-InOrderCPU::removeInstsUntil(const InstSeqNum &seq_num,
- unsigned tid)
+InOrderCPU::removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid)
{
//assert(!instList[tid].empty());
inline void
-InOrderCPU::squashInstIt(const ListIt &instIt, const unsigned &tid)
+InOrderCPU::squashInstIt(const ListIt &instIt, ThreadID tid)
{
if ((*instIt)->threadNumber == tid) {
DPRINTF(InOrderCPU, "Squashing instruction, "
(*removeList.front())->readPC());
DynInstPtr inst = *removeList.front();
- int tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
// Make Sure Resource Schedule Is Emptied Out
ThePipeline::ResSchedule *inst_sched = &inst->resSched;
}
void
-InOrderCPU::syscall(int64_t callnum, int tid)
+InOrderCPU::syscall(int64_t callnum, ThreadID tid)
{
DPRINTF(InOrderCPU, "[tid:%i] Executing syscall().\n\n", tid);
#include "arch/isa_traits.hh"
#include "base/statistics.hh"
#include "base/timebuf.hh"
+#include "base/types.hh"
#include "config/full_system.hh"
#include "cpu/activity.hh"
#include "cpu/base.hh"
public:
CPUEventType cpuEventType;
- unsigned tid;
+ ThreadID tid;
unsigned vpe;
Fault fault;
public:
/** Constructs a CPU event. */
CPUEvent(InOrderCPU *_cpu, CPUEventType e_type, Fault fault,
- unsigned _tid, unsigned _vpe);
+ ThreadID _tid, unsigned _vpe);
/** Set Type of Event To Be Scheduled */
- void setEvent(CPUEventType e_type, Fault _fault, unsigned _tid, unsigned _vpe)
+ void setEvent(CPUEventType e_type, Fault _fault, ThreadID _tid,
+ unsigned _vpe)
{
fault = _fault;
cpuEventType = e_type;
};
/** Schedule a CPU Event */
- void scheduleCpuEvent(CPUEventType cpu_event, Fault fault, unsigned tid,
+ void scheduleCpuEvent(CPUEventType cpu_event, Fault fault, ThreadID tid,
unsigned vpe, unsigned delay = 0);
public:
/** trap() - sets up a trap event on the cpuTraps to handle given fault.
* trapCPU() - Traps to handle given fault
*/
- void trap(Fault fault, unsigned tid, int delay = 0);
- void trapCPU(Fault fault, unsigned tid);
+ void trap(Fault fault, ThreadID tid, int delay = 0);
+ void trapCPU(Fault fault, ThreadID tid);
/** Setup CPU to insert a thread's context */
- void insertThread(unsigned tid);
+ void insertThread(ThreadID tid);
/** Remove all of a thread's context from CPU */
- void removeThread(unsigned tid);
+ void removeThread(ThreadID tid);
/** Add Thread to Active Threads List. */
- void activateContext(unsigned tid, int delay = 0);
- void activateThread(unsigned tid);
+ void activateContext(ThreadID tid, int delay = 0);
+ void activateThread(ThreadID tid);
/** Remove Thread from Active Threads List */
- void suspendContext(unsigned tid, int delay = 0);
- void suspendThread(unsigned tid);
+ void suspendContext(ThreadID tid, int delay = 0);
+ void suspendThread(ThreadID tid);
/** Remove Thread from Active Threads List &&
* Remove Thread Context from CPU.
*/
- void deallocateContext(unsigned tid, int delay = 0);
- void deallocateThread(unsigned tid);
- void deactivateThread(unsigned tid);
+ void deallocateContext(ThreadID tid, int delay = 0);
+ void deallocateThread(ThreadID tid);
+ void deactivateThread(ThreadID tid);
PipelineStage* getPipeStage(int stage_num);
/** Remove Thread from Active Threads List &&
* Remove Thread Context from CPU.
*/
- void haltContext(unsigned tid, int delay = 0);
+ void haltContext(ThreadID tid, int delay = 0);
- void removePipelineStalls(unsigned tid);
+ void removePipelineStalls(ThreadID tid);
- void squashThreadInPipeline(unsigned tid);
+ void squashThreadInPipeline(ThreadID tid);
/// Notify the CPU to enable a virtual processor element.
virtual void enableVirtProcElement(unsigned vpe);
void enableVPEs(unsigned vpe);
/// Notify the CPU to disable a virtual processor element.
- virtual void disableVirtProcElement(unsigned tid, unsigned vpe);
- void disableVPEs(unsigned tid, unsigned vpe);
+ virtual void disableVirtProcElement(ThreadID tid, unsigned vpe);
+ void disableVPEs(ThreadID tid, unsigned vpe);
/// Notify the CPU that multithreading is enabled.
virtual void enableMultiThreading(unsigned vpe);
void enableThreads(unsigned vpe);
/// Notify the CPU that multithreading is disabled.
- virtual void disableMultiThreading(unsigned tid, unsigned vpe);
- void disableThreads(unsigned tid, unsigned vpe);
+ virtual void disableMultiThreading(ThreadID tid, unsigned vpe);
+ void disableThreads(ThreadID tid, unsigned vpe);
/** Activate a Thread When CPU Resources are Available. */
- void activateWhenReady(int tid);
+ void activateWhenReady(ThreadID tid);
/** Add or Remove a Thread Context in the CPU. */
void doContextSwitch();
{ /*pipelineStage[stage_idx]->switchToActive();*/ }
/** Get the current instruction sequence number, and increment it. */
- InstSeqNum getAndIncrementInstSeq(unsigned tid)
+ InstSeqNum getAndIncrementInstSeq(ThreadID tid)
{ return globalSeqNum[tid]++; }
/** Get the current instruction sequence number, and increment it. */
- InstSeqNum nextInstSeqNum(unsigned tid)
+ InstSeqNum nextInstSeqNum(ThreadID tid)
{ return globalSeqNum[tid]; }
/** Increment Instruction Sequence Number */
- void incrInstSeqNum(unsigned tid)
+ void incrInstSeqNum(ThreadID tid)
{ globalSeqNum[tid]++; }
/** Set Instruction Sequence Number */
- void setInstSeqNum(unsigned tid, InstSeqNum seq_num)
+ void setInstSeqNum(ThreadID tid, InstSeqNum seq_num)
{
globalSeqNum[tid] = seq_num;
}
}
/** Get instruction asid. */
- int getInstAsid(unsigned tid)
+ int getInstAsid(ThreadID tid)
{ return thread[tid]->getInstAsid(); }
/** Get data asid. */
- int getDataAsid(unsigned tid)
+ int getDataAsid(ThreadID tid)
{ return thread[tid]->getDataAsid(); }
/** Register file accessors */
- uint64_t readIntReg(int reg_idx, unsigned tid);
+ uint64_t readIntReg(int reg_idx, ThreadID tid);
- FloatReg readFloatReg(int reg_idx, unsigned tid,
+ FloatReg readFloatReg(int reg_idx, ThreadID tid,
int width = TheISA::SingleWidth);
- FloatRegBits readFloatRegBits(int reg_idx, unsigned tid,
+ FloatRegBits readFloatRegBits(int reg_idx, ThreadID tid,
int width = TheISA::SingleWidth);
- void setIntReg(int reg_idx, uint64_t val, unsigned tid);
+ void setIntReg(int reg_idx, uint64_t val, ThreadID tid);
- void setFloatReg(int reg_idx, FloatReg val, unsigned tid,
+ void setFloatReg(int reg_idx, FloatReg val, ThreadID tid,
int width = TheISA::SingleWidth);
- void setFloatRegBits(int reg_idx, FloatRegBits val, unsigned tid,
+ void setFloatRegBits(int reg_idx, FloatRegBits val, ThreadID tid,
int width = TheISA::SingleWidth);
/** Reads a miscellaneous register. */
- MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid = 0);
+ MiscReg readMiscRegNoEffect(int misc_reg, ThreadID tid = 0);
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
- MiscReg readMiscReg(int misc_reg, unsigned tid = 0);
+ MiscReg readMiscReg(int misc_reg, ThreadID tid = 0);
/** Sets a miscellaneous register. */
- void setMiscRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid = 0);
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val,
+ ThreadID tid = 0);
/** Sets a misc. register, including any side effects the write
* might have as defined by the architecture.
*/
- void setMiscReg(int misc_reg, const MiscReg &val, unsigned tid = 0);
+ void setMiscReg(int misc_reg, const MiscReg &val, ThreadID tid = 0);
/** Reads a int/fp/misc reg. from another thread depending on ISA-defined
* target thread
*/
- uint64_t readRegOtherThread(unsigned misc_reg, unsigned tid = -1);
+ uint64_t readRegOtherThread(unsigned misc_reg,
+ ThreadID tid = InvalidThreadID);
/** Sets a int/fp/misc reg. from another thread depending on an ISA-defined
* target thread
*/
- void setRegOtherThread(unsigned misc_reg, const MiscReg &val, unsigned tid);
+ void setRegOtherThread(unsigned misc_reg, const MiscReg &val,
+ ThreadID tid);
/** Reads the commit PC of a specific thread. */
- uint64_t readPC(unsigned tid);
+ uint64_t readPC(ThreadID tid);
/** Sets the commit PC of a specific thread. */
- void setPC(Addr new_PC, unsigned tid);
+ void setPC(Addr new_PC, ThreadID tid);
/** Reads the next PC of a specific thread. */
- uint64_t readNextPC(unsigned tid);
+ uint64_t readNextPC(ThreadID tid);
/** Sets the next PC of a specific thread. */
- void setNextPC(uint64_t val, unsigned tid);
+ void setNextPC(uint64_t val, ThreadID tid);
/** Reads the next NPC of a specific thread. */
- uint64_t readNextNPC(unsigned tid);
+ uint64_t readNextNPC(ThreadID tid);
/** Sets the next NPC of a specific thread. */
- void setNextNPC(uint64_t val, unsigned tid);
+ void setNextNPC(uint64_t val, ThreadID tid);
/** Function to add instruction onto the head of the list of the
* instructions. Used when new instructions are fetched.
ListIt addInst(DynInstPtr &inst);
/** Function to tell the CPU that an instruction has completed. */
- void instDone(DynInstPtr inst, unsigned tid);
+ void instDone(DynInstPtr inst, ThreadID tid);
/** Add Instructions to the CPU Remove List*/
void addToRemoveList(DynInstPtr &inst);
void removeInst(DynInstPtr &inst);
/** Remove all instructions younger than the given sequence number. */
- void removeInstsUntil(const InstSeqNum &seq_num,unsigned tid);
+ void removeInstsUntil(const InstSeqNum &seq_num,ThreadID tid);
/** Removes the instruction pointed to by the iterator. */
- inline void squashInstIt(const ListIt &instIt, const unsigned &tid);
+ inline void squashInstIt(const ListIt &instIt, ThreadID tid);
/** Cleans up all instructions on the instruction remove list. */
void cleanUpRemovedInsts();
void writeHint(DynInstPtr inst);
/** Executes a syscall.*/
- void syscall(int64_t callnum, int tid);
+ void syscall(int64_t callnum, ThreadID tid);
public:
/** Per-Thread List of all the instructions in flight. */
/** Last Cycle that the CPU squashed instruction end. */
Tick lastSquashCycle[ThePipeline::MaxThreads];
- std::list<unsigned> fetchPriorityList;
+ std::list<ThreadID> fetchPriorityList;
protected:
/** Active Threads List */
- std::list<unsigned> activeThreads;
+ std::list<ThreadID> activeThreads;
/** Current Threads List */
- std::list<unsigned> currentThreads;
+ std::list<ThreadID> currentThreads;
/** Suspended Threads List */
- std::list<unsigned> suspendedThreads;
+ std::list<ThreadID> suspendedThreads;
/** Thread Status Functions (Unused Currently) */
- bool isThreadInCPU(unsigned tid);
- bool isThreadActive(unsigned tid);
- bool isThreadSuspended(unsigned tid);
- void addToCurrentThreads(unsigned tid);
- void removeFromCurrentThreads(unsigned tid);
+ bool isThreadInCPU(ThreadID tid);
+ bool isThreadActive(ThreadID tid);
+ bool isThreadSuspended(ThreadID tid);
+ void addToCurrentThreads(ThreadID tid);
+ void removeFromCurrentThreads(ThreadID tid);
private:
/** The activity recorder; used to tell if the CPU has any
void readFunctional(Addr addr, uint32_t &buffer);
/** Number of Active Threads in the CPU */
- int numActiveThreads() { return activeThreads.size(); }
+ ThreadID numActiveThreads() { return activeThreads.size(); }
/** Records that there was time buffer activity this cycle. */
void activityThisCycle() { activityRec.activity(); }
void wakeCPU();
/** Gets a free thread id. Use if thread ids change across system. */
- int getFreeTid();
+ ThreadID getFreeTid();
// LL/SC debug functionality
unsigned stCondFails;
unsigned setStCondFailures(unsigned st_fails) { return stCondFails = st_fails; }
/** Returns a pointer to a thread context. */
- ThreadContext *tcBase(unsigned tid = 0)
+ ThreadContext *tcBase(ThreadID tid = 0)
{
return thread[tid]->getTC();
}
{
Counter total(0);
- for (int i=0; i < thread.size(); i++)
- total += thread[i]->numInst;
+ for (ThreadID tid = 0; tid < thread.size(); tid++)
+ total += thread[tid]->numInst;
return total;
}
/** The cycle that the CPU was last running, used for statistics. */
Tick lastRunningCycle;
- /** Number of Threads the CPU can process */
- unsigned numThreads;
-
/** Number of Virtual Processors the CPU can process */
unsigned numVirtProcs;
: PipelineStage(params, stage_num), numFetchingThreads(1),
fetchPolicy(FirstStage::RoundRobin)
{
- for(int tid=0; tid < this->numThreads; tid++) {
+ for(ThreadID tid = 0; tid < this->numThreads; tid++) {
stageStatus[tid] = Running;
}
}
void
-FirstStage::squash(InstSeqNum squash_seq_num, unsigned tid)
+FirstStage::squash(InstSeqNum squash_seq_num, ThreadID tid)
{
// Set status to squashing.
//stageStatus[tid] = Squashing;
void
FirstStage::processStage(bool &status_change)
{
- list<unsigned>::iterator threads = (*activeThreads).begin();
+ list<ThreadID>::iterator threads = activeThreads->begin();
//Check stall and squash signals.
- while (threads != (*activeThreads).end()) {
- unsigned tid = *threads++;
+ while (threads != activeThreads->end()) {
+ ThreadID tid = *threads++;
status_change = checkSignalsAndUpdate(tid) || status_change;
}
for (int threadFetched = 0; threadFetched < numFetchingThreads;
threadFetched++) {
- int tid = getFetchingThread(fetchPolicy);
+ ThreadID tid = getFetchingThread(fetchPolicy);
if (tid >= 0) {
DPRINTF(InOrderStage, "Processing [tid:%i]\n",tid);
//@TODO: Note in documentation, that when you make a pipeline stage change, then
//make sure you change the first stage too
void
-FirstStage::processInsts(unsigned tid)
+FirstStage::processInsts(ThreadID tid)
{
bool all_reqs_completed = true;
}
}
-int
+ThreadID
FirstStage::getFetchingThread(FetchPriority &fetch_priority)
{
if (numThreads > 1) {
return roundRobin();
default:
- return -1;
+ return InvalidThreadID;
}
} else {
- int tid = *((*activeThreads).begin());
+ ThreadID tid = *activeThreads->begin();
if (stageStatus[tid] == Running ||
stageStatus[tid] == Idle) {
return tid;
} else {
- return -1;
+ return InvalidThreadID;
}
}
}
-int
+ThreadID
FirstStage::roundRobin()
{
- list<unsigned>::iterator pri_iter = (*fetchPriorityList).begin();
- list<unsigned>::iterator end = (*fetchPriorityList).end();
+ list<ThreadID>::iterator pri_iter = fetchPriorityList->begin();
+ list<ThreadID>::iterator end = fetchPriorityList->end();
- int high_pri;
+ ThreadID high_pri;
while (pri_iter != end) {
high_pri = *pri_iter;
if (stageStatus[high_pri] == Running ||
stageStatus[high_pri] == Idle) {
- (*fetchPriorityList).erase(pri_iter);
- (*fetchPriorityList).push_back(high_pri);
+ fetchPriorityList->erase(pri_iter);
+ fetchPriorityList->push_back(high_pri);
return high_pri;
}
pri_iter++;
}
- return -1;
+ return InvalidThreadID;
}
void processStage(bool &status_change);
/** Process All Instructions Available */
- void processInsts(unsigned tid);
+ void processInsts(ThreadID tid);
/** Squash Instructions Above a Seq. Num */
- void squash(InstSeqNum squash_seq_num, unsigned tid);
+ void squash(InstSeqNum squash_seq_num, ThreadID tid);
/** There are no insts. coming from previous stages, so there is
* no need to sort insts here
/** There are no skidBuffers for the first stage. So
* just use an empty function.
*/
- void skidInsert(unsigned tid) { }
+ void skidInsert(ThreadID tid) { }
/** The number of fetching threads in the CPU */
int numFetchingThreads;
FetchPriority fetchPolicy;
/** List that has the threads organized by priority. */
- std::list<unsigned> *fetchPriorityList;
+ std::list<ThreadID> *fetchPriorityList;
/** Return the next fetching thread */
- int getFetchingThread(FetchPriority &fetch_priority);
+ ThreadID getFetchingThread(FetchPriority &fetch_priority);
- /** Return next thred given Round Robin Policy for Thread Fetching */
- int roundRobin();
+ /** Return next thread given Round Robin Policy for Thread Fetching */
+ ThreadID roundRobin();
};
#endif // __CPU_INORDER_FIRST_STAGE_HH__
InOrderCPU *
InOrderCPUParams::create()
{
- int actual_num_threads =
+ ThreadID actual_num_threads =
(numThreads >= workload.size()) ? numThreads : workload.size();
if (workload.size() == 0) {
InOrderDynInst::InOrderDynInst(InOrderCPU *cpu,
InOrderThreadState *state,
InstSeqNum seq_num,
- unsigned tid,
+ ThreadID tid,
unsigned _asid)
: traceData(NULL), cpu(cpu)
{
/** Reads a integer register. */
IntReg
-InOrderDynInst::readIntRegOperand(const StaticInst *si, int idx, unsigned tid)
+InOrderDynInst::readIntRegOperand(const StaticInst *si, int idx, ThreadID tid)
{
DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Source Value %i read as %#x.\n",
threadNumber, seqNum, idx, instSrc[idx].integer);
}
MiscReg
-InOrderDynInst::readRegOtherThread(unsigned reg_idx, int tid)
+InOrderDynInst::readRegOtherThread(unsigned reg_idx, ThreadID tid)
{
if (tid == -1) {
tid = TheISA::getTargetThread(this->cpu->tcBase(threadNumber));
}
void
-InOrderDynInst::setRegOtherThread(unsigned reg_idx, const MiscReg &val, int tid)
+InOrderDynInst::setRegOtherThread(unsigned reg_idx, const MiscReg &val,
+ ThreadID tid)
{
- if (tid == -1) {
+ if (tid == InvalidThreadID) {
tid = TheISA::getTargetThread(this->cpu->tcBase(threadNumber));
}
* @param cpu Pointer to the instruction's CPU.
* NOTE: Must set Binary Instrution through Member Function
*/
- InOrderDynInst(InOrderCPU *cpu, InOrderThreadState *state, InstSeqNum seq_num,
- unsigned tid, unsigned asid = 0);
+ InOrderDynInst(InOrderCPU *cpu, InOrderThreadState *state,
+ InstSeqNum seq_num, ThreadID tid, unsigned asid = 0);
/** BaseDynInst constructor given a StaticInst pointer.
* @param _staticInst The StaticInst for this BaseDynInst.
short readTid() { return threadNumber; }
/** Sets the thread id. */
- void setTid(unsigned tid) { threadNumber = tid; }
+ void setTid(ThreadID tid) { threadNumber = tid; }
void setVpn(int id) { virtProcNumber = id; }
* language (which is why the name isnt readIntSrc(...)) Note: That
* the source reg. value is set using the setSrcReg() function.
*/
- IntReg readIntRegOperand(const StaticInst *si, int idx, unsigned tid=0);
+ IntReg readIntRegOperand(const StaticInst *si, int idx, ThreadID tid = 0);
FloatReg readFloatRegOperand(const StaticInst *si, int idx,
int width = TheISA::SingleWidth);
TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx,
void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val);
void setMiscRegOperandNoEffect(const StaticInst *si, int idx, const MiscReg &val);
- virtual uint64_t readRegOtherThread(unsigned idx, int tid = -1);
- virtual void setRegOtherThread(unsigned idx, const uint64_t &val, int tid = -1);
+ virtual uint64_t readRegOtherThread(unsigned idx,
+ ThreadID tid = InvalidThreadID);
+ virtual void setRegOtherThread(unsigned idx, const uint64_t &val,
+ ThreadID tid = InvalidThreadID);
/** Sets the number of consecutive store conditional failures. */
void setStCondFailures(unsigned sc_failures)
void
PipelineStage::init(Params *params)
{
- for(int tid=0; tid < numThreads; tid++) {
+ for(ThreadID tid = 0; tid < numThreads; tid++) {
stageStatus[tid] = Idle;
for (int stNum = 0; stNum < NumStages; stNum++) {
void
-PipelineStage::setActiveThreads(list<unsigned> *at_ptr)
+PipelineStage::setActiveThreads(list<ThreadID> *at_ptr)
{
DPRINTF(InOrderStage, "Setting active threads list pointer.\n");
activeThreads = at_ptr;
_status = Inactive;
// Be sure to reset state and clear out any old instructions.
- for (int i = 0; i < numThreads; ++i) {
- stageStatus[i] = Idle;
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
+ stageStatus[tid] = Idle;
for (int stNum = 0; stNum < NumStages; stNum++) {
- stalls[i].stage[stNum] = false;
+ stalls[tid].stage[stNum] = false;
}
- stalls[i].resources.clear();
+ stalls[tid].resources.clear();
- while (!insts[i].empty())
- insts[i].pop();
+ while (!insts[tid].empty())
+ insts[tid].pop();
- while (!skidBuffer[i].empty())
- skidBuffer[i].pop();
+ while (!skidBuffer[tid].empty())
+ skidBuffer[tid].pop();
}
wroteToTimeBuffer = false;
}
bool
-PipelineStage::checkStall(unsigned tid) const
+PipelineStage::checkStall(ThreadID tid) const
{
bool ret_val = false;
void
-PipelineStage::removeStalls(unsigned tid)
+PipelineStage::removeStalls(ThreadID tid)
{
for (int stNum = 0; stNum < NumStages; stNum++) {
stalls[tid].stage[stNum] = false;
}
bool
-PipelineStage::isBlocked(unsigned tid)
+PipelineStage::isBlocked(ThreadID tid)
{
return stageStatus[tid] == Blocked;
}
bool
-PipelineStage::block(unsigned tid)
+PipelineStage::block(ThreadID tid)
{
DPRINTF(InOrderStage, "[tid:%d]: Blocking, sending block signal back to previous stages.\n", tid);
}
void
-PipelineStage::blockDueToBuffer(unsigned tid)
+PipelineStage::blockDueToBuffer(ThreadID tid)
{
DPRINTF(InOrderStage, "[tid:%d]: Blocking instructions from passing to next stage.\n", tid);
}
bool
-PipelineStage::unblock(unsigned tid)
+PipelineStage::unblock(ThreadID tid)
{
// Stage is done unblocking only if the skid buffer is empty.
if (skidBuffer[tid].empty()) {
}
void
-PipelineStage::squashDueToBranch(DynInstPtr &inst, unsigned tid)
+PipelineStage::squashDueToBranch(DynInstPtr &inst, ThreadID tid)
{
if (cpu->squashSeqNum[tid] < inst->seqNum &&
cpu->lastSquashCycle[tid] == curTick){
}
void
-PipelineStage::squashPrevStageInsts(InstSeqNum squash_seq_num,
- unsigned tid)
+PipelineStage::squashPrevStageInsts(InstSeqNum squash_seq_num, ThreadID tid)
{
DPRINTF(InOrderStage, "[tid:%i]: Removing instructions from "
"incoming stage queue.\n", tid);
}
void
-PipelineStage::squash(InstSeqNum squash_seq_num, unsigned tid)
+PipelineStage::squash(InstSeqNum squash_seq_num, ThreadID tid)
{
// Set status to squashing.
stageStatus[tid] = Squashing;
}
void
-PipelineStage::skidInsert(unsigned tid)
+PipelineStage::skidInsert(ThreadID tid)
{
DynInstPtr inst = NULL;
bool
PipelineStage::skidsEmpty()
{
- list<unsigned>::iterator threads = (*activeThreads).begin();
+ list<ThreadID>::iterator threads = activeThreads->begin();
- while (threads != (*activeThreads).end()) {
+ while (threads != activeThreads->end()) {
if (!skidBuffer[*threads++].empty())
return false;
}
{
bool any_unblocking = false;
- list<unsigned>::iterator threads = (*activeThreads).begin();
-
- threads = (*activeThreads).begin();
+ list<ThreadID>::iterator threads = activeThreads->begin();
- while (threads != (*activeThreads).end()) {
- unsigned tid = *threads++;
+ while (threads != activeThreads->end()) {
+ ThreadID tid = *threads++;
if (stageStatus[tid] == Unblocking) {
any_unblocking = true;
prevStage->insts[i]->readTid(),
prevStage->insts[i]->seqNum);
- int tid = prevStage->insts[i]->threadNumber;
+ ThreadID tid = prevStage->insts[i]->threadNumber;
DynInstPtr inst = prevStage->insts[i];
void
-PipelineStage::readStallSignals(unsigned tid)
+PipelineStage::readStallSignals(ThreadID tid)
{
for (int stage_idx = stageNum+1; stage_idx <= lastStallingStage[tid];
stage_idx++) {
bool
-PipelineStage::checkSignalsAndUpdate(unsigned tid)
+PipelineStage::checkSignalsAndUpdate(ThreadID tid)
{
// Check if there's a squash signal, squash if there is.
// Check stall signals, block if necessary.
}
void
-PipelineStage::setResStall(ResReqPtr res_req, unsigned tid)
+PipelineStage::setResStall(ResReqPtr res_req, ThreadID tid)
{
DPRINTF(InOrderStage, "Inserting stall from %s.\n", res_req->res->name());
stalls[tid].resources.push_back(res_req);
}
void
-PipelineStage::unsetResStall(ResReqPtr res_req, unsigned tid)
+PipelineStage::unsetResStall(ResReqPtr res_req, ThreadID tid)
{
// Search through stalls to find stalling request and then
// remove it
void
PipelineStage::processStage(bool &status_change)
{
- list<unsigned>::iterator threads = (*activeThreads).begin();
+ list<ThreadID>::iterator threads = activeThreads->begin();
//Check stall and squash signals.
- while (threads != (*activeThreads).end()) {
- unsigned tid = *threads++;
+ while (threads != activeThreads->end()) {
+ ThreadID tid = *threads++;
DPRINTF(InOrderStage,"Processing [tid:%i]\n",tid);
status_change = checkSignalsAndUpdate(tid) || status_change;
}
void
-PipelineStage::processThread(bool &status_change, unsigned tid)
+PipelineStage::processThread(bool &status_change, ThreadID tid)
{
// If status is Running or idle,
// call stageInsts()
void
-PipelineStage::processInsts(unsigned tid)
+PipelineStage::processInsts(ThreadID tid)
{
// Instructions can come either from the skid buffer or the list of
// instructions coming from fetch, depending on stage's status.
PipelineStage::processInstSchedule(DynInstPtr inst)
{
bool last_req_completed = true;
- int tid;
-
- tid = inst->readTid();
+#if TRACING_ON
+ ThreadID tid = inst->readTid();
+#endif
if (inst->nextResStage() == stageNum) {
int res_stage_num = inst->nextResStage();
inst->nextStage++;
bool success = false;
- int tid = inst->readTid();
+ ThreadID tid = inst->readTid();
int next_stage = inst->nextStage;
int prev_stage = next_stage - 1;
{
cprintf("Insts in Stage %i skidbuffers\n",stageNum);
- for (int tid=0; tid < ThePipeline::MaxThreads; tid++) {
-
+ for (ThreadID tid = 0; tid < ThePipeline::MaxThreads; tid++) {
std::queue<DynInstPtr> copy_buff(skidBuffer[tid]);
while (!copy_buff.empty()) {
unsigned stageWidth;
/** Number of Threads*/
- unsigned numThreads;
+ ThreadID numThreads;
/** Stage status. */
StageStatus _status;
/** Sets CPU pointer. */
virtual void setCPU(InOrderCPU *cpu_ptr);
- virtual void scheduleStageStart(int delay, int tid) { }
+ virtual void scheduleStageStart(int delay, ThreadID tid) { }
/** Sets the main backwards communication time buffer pointer. */
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
void setNextStageQueue(TimeBuffer<InterStageStruct> *next_stage_ptr);
/** Sets pointer to list of active threads. */
- void setActiveThreads(std::list<unsigned> *at_ptr);
+ void setActiveThreads(std::list<ThreadID> *at_ptr);
bool nextStageQueueValid(int stage_num);
- bool isBlocked(unsigned tid);
+ bool isBlocked(ThreadID tid);
/** Changes the status of this stage to active, and indicates this
* to the CPU.
virtual void tick();
/** Set a resource stall in the pipeline-stage */
- void setResStall(ResReqPtr res_req, unsigned tid);
+ void setResStall(ResReqPtr res_req, ThreadID tid);
/** Unset a resource stall in the pipeline-stage */
- void unsetResStall(ResReqPtr res_req, unsigned tid);
+ void unsetResStall(ResReqPtr res_req, ThreadID tid);
/** Remove all stall signals for a particular thread; */
- virtual void removeStalls(unsigned tid);
+ virtual void removeStalls(ThreadID tid);
/** Is there room in the stage buffer? */
int stageBufferAvail();
* change (ie switching from from blocking to unblocking).
* @param tid Thread id to stage instructions from.
*/
- virtual void processThread(bool &status_change, unsigned tid);
+ virtual void processThread(bool &status_change, ThreadID tid);
/** Processes instructions from fetch and passes them on to rename.
* Decoding of instructions actually happens when they are created in
* fetch, so this function mostly checks if PC-relative branches are
* correct.
*/
- virtual void processInsts(unsigned tid);
+ virtual void processInsts(ThreadID tid);
/** Process all resources on an instruction's resource schedule */
virtual bool processInstSchedule(DynInstPtr inst);
/** Inserts a thread's instructions into the skid buffer, to be staged
* once stage unblocks.
*/
- virtual void skidInsert(unsigned tid);
+ virtual void skidInsert(ThreadID tid);
/** Total size of all skid buffers */
int skidSize();
void sortInsts();
/** Reads all stall signals from the backwards communication timebuffer. */
- virtual void readStallSignals(unsigned tid);
+ virtual void readStallSignals(ThreadID tid);
/** Checks all input signals and updates stage's status appropriately. */
- virtual bool checkSignalsAndUpdate(unsigned tid);
+ virtual bool checkSignalsAndUpdate(ThreadID tid);
/** Checks all stall signals, and returns if any are true. */
- virtual bool checkStall(unsigned tid) const;
+ virtual bool checkStall(ThreadID tid) const;
/** Returns if there any instructions from the previous stage
* on this cycle.
* become blocked.
* @return Returns true if there is a status change.
*/
- virtual bool block(unsigned tid);
+ virtual bool block(ThreadID tid);
- void blockDueToBuffer(unsigned tid);
+ void blockDueToBuffer(ThreadID tid);
/** Switches stage to unblocking if the skid buffer is empty, and
* signals back that stage has unblocked.
* @return Returns true if there is a status change.
*/
- virtual bool unblock(unsigned tid);
+ virtual bool unblock(ThreadID tid);
public:
/** Squashes if there is a PC-relative branch that was predicted
* incorrectly. Sends squash information back to fetch.
*/
- virtual void squashDueToBranch(DynInstPtr &inst, unsigned tid);
+ virtual void squashDueToBranch(DynInstPtr &inst, ThreadID tid);
/** Squash instructions from stage buffer */
- virtual void squashPrevStageInsts(InstSeqNum squash_seq_num, unsigned tid);
+ virtual void squashPrevStageInsts(InstSeqNum squash_seq_num, ThreadID tid);
/** Squashes due to commit signalling a squash. Changes status to
* squashing and clears block/unblock signals as needed.
*/
- virtual void squash(InstSeqNum squash_num, unsigned tid);
+ virtual void squash(InstSeqNum squash_num, ThreadID tid);
void dumpInsts();
Trace::InOrderTrace *tracer;
/** List of active thread ids */
- std::list<unsigned> *activeThreads;
+ std::list<ThreadID> *activeThreads;
/** Queue of all instructions coming from previous stage on this cycle. */
std::queue<DynInstPtr> insts[ThePipeline::MaxThreads];
}
void
-Resource::deactivateThread(unsigned tid)
+Resource::deactivateThread(ThreadID tid)
{
// In the most basic case, deactivation means squashing everything
// from a particular thread
}
void
-Resource::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, unsigned tid)
+Resource::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
+ ThreadID tid)
{
std::vector<int> slot_remove_list;
virtual void regStats();
/** Resources that care about thread activation override this. */
- virtual void activateThread(unsigned tid) { }
+ virtual void activateThread(ThreadID tid) { }
/** Deactivate Thread. Default action is to squash all instructions
* from deactivated thread.
*/
- virtual void deactivateThread(unsigned tid);
+ virtual void deactivateThread(ThreadID tid);
/** Resources that care when an instruction has been graduated
* can override this
*/
- virtual void instGraduated(InstSeqNum seq_num,unsigned tid) { }
+ virtual void instGraduated(InstSeqNum seq_num, ThreadID tid) { }
/** Request usage of this resource. Returns a ResourceRequest object
* with all the necessary resource information
{ panic("writeHint undefined for %s", name()); }
/** Squash All Requests After This Seq Num */
- virtual void squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, unsigned tid);
+ virtual void squash(DynInstPtr inst, int stage_num,
+ InstSeqNum squash_seq_num, ThreadID tid);
/** The number of instructions available that this resource can
* can still process
int getStageNum() { return stageNum; }
/** Set/Get Thread Ids */
- void setTid(unsigned _tid) { tid = _tid; }
- int getTid() { return tid; }
+ void setTid(ThreadID _tid) { tid = _tid; }
+ ThreadID getTid() { return tid; }
/** Instruction this request is for */
DynInstPtr getInst() { return inst; }
protected:
/** Resource Identification */
- int tid;
+ ThreadID tid;
int stageNum;
int resIdx;
int slotNum;
}
void
-ResourcePool::squash(DynInstPtr inst, int res_idx, InstSeqNum done_seq_num, int tid)
+ResourcePool::squash(DynInstPtr inst, int res_idx, InstSeqNum done_seq_num,
+ ThreadID tid)
{
resources[res_idx]->squash(inst, ThePipeline::NumStages-1, done_seq_num, tid);
}
void
ResourcePool::scheduleEvent(InOrderCPU::CPUEventType e_type, DynInstPtr inst,
- int delay, int res_idx, int tid)
+ int delay, int res_idx, ThreadID tid)
{
assert(delay >= 0);
}
void
-ResourcePool::squashAll(DynInstPtr inst, int stage_num, InstSeqNum done_seq_num, unsigned tid)
+ResourcePool::squashAll(DynInstPtr inst, int stage_num,
+ InstSeqNum done_seq_num, ThreadID tid)
{
DPRINTF(Resource, "[tid:%i] Stage %i squashing all instructions above [sn:%i].\n",
stage_num, tid, done_seq_num);
}
void
-ResourcePool::activateAll(unsigned tid)
+ResourcePool::activateAll(ThreadID tid)
{
DPRINTF(Resource, "[tid:%i] Broadcasting Thread Activation to all resources.\n",
tid);
}
void
-ResourcePool::deactivateAll(unsigned tid)
+ResourcePool::deactivateAll(ThreadID tid)
{
DPRINTF(Resource, "[tid:%i] Broadcasting Thread Deactivation to all resources.\n",
tid);
}
void
-ResourcePool::instGraduated(InstSeqNum seq_num,unsigned tid)
+ResourcePool::instGraduated(InstSeqNum seq_num, ThreadID tid)
{
DPRINTF(Resource, "[tid:%i] Broadcasting [sn:%i] graduation to all resources.\n",
tid, seq_num);
}
void
-ResourcePool::squash(DynInstPtr inst, int res_idx, InstSeqNum done_seq_num, int tid)
+ResourcePool::squash(DynInstPtr inst, int res_idx, InstSeqNum done_seq_num,
+ ThreadID tid)
{
resources[res_idx]->squash(inst, ThePipeline::NumStages-1, done_seq_num, tid);
}
void
ResourcePool::scheduleEvent(InOrderCPU::CPUEventType e_type, DynInstPtr inst,
- int delay, int res_idx, int tid)
+ int delay, int res_idx, ThreadID tid)
{
assert(delay >= 0);
}
void
-ResourcePool::squashAll(DynInstPtr inst, int stage_num, InstSeqNum done_seq_num, unsigned tid)
+ResourcePool::squashAll(DynInstPtr inst, int stage_num,
+ InstSeqNum done_seq_num, ThreadID tid)
{
DPRINTF(Resource, "[tid:%i] Stage %i squashing all instructions above [sn:%i].\n",
stage_num, tid, done_seq_num);
}
void
-ResourcePool::activateAll(unsigned tid)
+ResourcePool::activateAll(ThreadID tid)
{
DPRINTF(Resource, "[tid:%i] Broadcasting Thread Activation to all resources.\n",
tid);
}
void
-ResourcePool::deactivateAll(unsigned tid)
+ResourcePool::deactivateAll(ThreadID tid)
{
DPRINTF(Resource, "[tid:%i] Broadcasting Thread Deactivation to all resources.\n",
tid);
}
void
-ResourcePool::instGraduated(InstSeqNum seq_num,unsigned tid)
+ResourcePool::instGraduated(InstSeqNum seq_num, ThreadID tid)
{
DPRINTF(Resource, "[tid:%i] Broadcasting [sn:%i] graduation to all resources.\n",
tid, seq_num);
DynInstPtr _inst,
int stage_num,
InstSeqNum seq_num,
- unsigned _tid)
+ ThreadID _tid)
: Event(CPU_Tick_Pri), resPool(_resPool),
eventType(e_type), inst(_inst), seqNum(seq_num),
stageNum(stage_num), tid(_tid)
int stageNum;
- unsigned tid;
+ ThreadID tid;
public:
/** Constructs a resource event. */
DynInstPtr _inst,
int stage_num,
InstSeqNum seq_num,
- unsigned _tid);
+ ThreadID _tid);
/** Set Type of Event To Be Scheduled */
void setEvent(InOrderCPU::CPUEventType e_type,
DynInstPtr _inst,
int stage_num,
InstSeqNum seq_num,
- unsigned _tid)
+ ThreadID _tid)
{
eventType = e_type;
inst = _inst;
ResReqPtr request(int res_idx, DynInstPtr inst);
/** Squash The Resource */
- void squash(DynInstPtr inst, int res_idx, InstSeqNum done_seq_num, int tid);
+ void squash(DynInstPtr inst, int res_idx, InstSeqNum done_seq_num,
+ ThreadID tid);
/** Squash All Resources in Pool after Done Seq. Num */
void squashAll(DynInstPtr inst, int stage_num,
- InstSeqNum done_seq_num, unsigned tid);
+ InstSeqNum done_seq_num, ThreadID tid);
/** Activate Thread in all resources */
- void activateAll(unsigned tid);
+ void activateAll(ThreadID tid);
/** De-Activate Thread in all resources */
- void deactivateAll(unsigned tid);
+ void deactivateAll(ThreadID tid);
/** Broadcast graduation to all resources */
- void instGraduated(InstSeqNum seq_num,unsigned tid);
+ void instGraduated(InstSeqNum seq_num, ThreadID tid);
/** The number of instructions available that a resource can
* can still process.
/** Schedule resource event, regardless of its current state. */
void scheduleEvent(InOrderCPU::CPUEventType e_type, DynInstPtr inst = NULL,
- int delay = 0, int res_idx = 0, int tid = 0);
+ int delay = 0, int res_idx = 0, ThreadID tid = 0);
/** UnSchedule resource event, regardless of its current state. */
void unscheduleEvent(int res_idx, DynInstPtr inst);
ResourceRequest* agen_req = reqMap[slot_num];
DynInstPtr inst = reqMap[slot_num]->inst;
Fault fault = reqMap[slot_num]->fault;
- int tid;
+#if TRACING_ON
+ ThreadID tid = inst->readTid();
+#endif
int seq_num = inst->seqNum;
- tid = inst->readTid();
agen_req->fault = NoFault;
switch (agen_req->cmd)
{
// Load/Store Instruction
if (inst->isMemRef()) {
- DPRINTF(InOrderAGEN, "[tid:%i] Generating Address for [sn:%i] (%s).\n",
- tid, inst->seqNum, inst->staticInst->getName());
+ DPRINTF(InOrderAGEN,
+ "[tid:%i] Generating Address for [sn:%i] (%s).\n",
+ tid, seq_num, inst->staticInst->getName());
fault = inst->calcEA();
inst->setMemAddr(inst->getEA());
- DPRINTF(InOrderAGEN, "[tid:%i] [sn:%i] Effective address calculated to be: "
- "%#x.\n", tid, inst->seqNum, inst->getEA());
+ DPRINTF(InOrderAGEN,
+ "[tid:%i] [sn:%i] Effective address calculated as: %#x\n",
+ tid, seq_num, inst->getEA());
if (fault == NoFault) {
agen_req->done();
} else {
- fatal("%s encountered while calculating address for [sn:%i]",fault->name(), seq_num);
+ fatal("%s encountered while calculating address [sn:%i]",
+ fault->name(), seq_num);
}
} else {
- DPRINTF(InOrderAGEN, "[tid:] Ignoring non-memory instruction [sn:%i].\n", tid, seq_num);
+ DPRINTF(InOrderAGEN,
+ "[tid:] Ignoring non-memory instruction [sn:%i]\n",
+ tid, seq_num);
agen_req->done();
}
}
bool
-BPredUnit::predict(DynInstPtr &inst, Addr &PC, unsigned tid)
+BPredUnit::predict(DynInstPtr &inst, Addr &PC, ThreadID tid)
{
// See if branch predictor predicts taken.
// If so, get its target addr either from the BTB or the RAS.
void
-BPredUnit::update(const InstSeqNum &done_sn, unsigned tid)
+BPredUnit::update(const InstSeqNum &done_sn, ThreadID tid)
{
DPRINTF(Resource, "BranchPred: [tid:%i]: Commiting branches until sequence"
"number %lli.\n", tid, done_sn);
void
-BPredUnit::squash(const InstSeqNum &squashed_sn, unsigned tid)
+BPredUnit::squash(const InstSeqNum &squashed_sn, ThreadID tid)
{
History &pred_hist = predHist[tid];
void
BPredUnit::squash(const InstSeqNum &squashed_sn,
const Addr &corr_target,
- const bool actually_taken,
- unsigned tid)
+ bool actually_taken,
+ ThreadID tid)
{
// Now that we know that a branch was mispredicted, we need to undo
// all the branches that have been seen up until this branch and
* @param tid The thread id.
* @return Returns if the branch is taken or not.
*/
- bool predict(ThePipeline::DynInstPtr &inst, Addr &PC, unsigned tid);
+ bool predict(ThePipeline::DynInstPtr &inst, Addr &PC, ThreadID tid);
// @todo: Rename this function.
void BPUncond(void * &bp_history);
* @param done_sn The sequence number to commit any older updates up until.
* @param tid The thread id.
*/
- void update(const InstSeqNum &done_sn, unsigned tid);
+ void update(const InstSeqNum &done_sn, ThreadID tid);
/**
* Squashes all outstanding updates until a given sequence number.
* until.
* @param tid The thread id.
*/
- void squash(const InstSeqNum &squashed_sn, unsigned tid);
+ void squash(const InstSeqNum &squashed_sn, ThreadID tid);
/**
* Squashes all outstanding updates until a given sequence number, and
* @param tid The thread id.
*/
void squash(const InstSeqNum &squashed_sn, const Addr &corr_target,
- bool actually_taken, unsigned tid);
+ bool actually_taken, ThreadID tid);
/**
* @param bp_history Pointer to the history object. The predictor
* information needed to update the predictor, BTB, and RAS.
*/
PredictorHistory(const InstSeqNum &seq_num, const Addr &inst_PC,
- const bool pred_taken, void *bp_history,
- const unsigned _tid)
+ bool pred_taken, void *bp_history,
+ ThreadID _tid)
: seqNum(seq_num), PC(inst_PC), RASTarget(0),
RASIndex(0), tid(_tid), predTaken(pred_taken), usedRAS(0),
wasCall(0), bpHistory(bp_history)
unsigned RASIndex;
/** The thread id. */
- unsigned tid;
+ ThreadID tid;
/** Whether or not it was predicted taken. */
bool predTaken;
ResourceRequest* bpred_req = reqMap[slot_num];
DynInstPtr inst = bpred_req->inst;
- int tid = inst->readTid();
+ ThreadID tid = inst->readTid();
int seq_num = inst->seqNum;
//int stage_num = bpred_req->getStageNum();
void
BranchPredictor::squash(DynInstPtr inst, int squash_stage,
- InstSeqNum squash_seq_num, unsigned tid)
+ InstSeqNum squash_seq_num, ThreadID tid)
{
DPRINTF(InOrderBPred, "Squashing...\n");
branchPred.squash(squash_seq_num, tid);
}
void
-BranchPredictor::instGraduated(InstSeqNum seq_num,unsigned tid)
+BranchPredictor::instGraduated(InstSeqNum seq_num, ThreadID tid)
{
branchPred.update(seq_num, tid);
}
virtual void execute(int slot_num);
virtual void squash(DynInstPtr inst, int stage_num,
- InstSeqNum squash_seq_num, unsigned tid);
+ InstSeqNum squash_seq_num, ThreadID tid);
- virtual void instGraduated(InstSeqNum seq_num,unsigned tid);
+ virtual void instGraduated(InstSeqNum seq_num, ThreadID tid);
protected:
/** List of instructions this resource is currently
CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
int flags, TheISA::TLB::Mode tlb_mode)
{
- int tid;
- int seq_num;
- Addr aligned_addr;
- unsigned stage_num;
- unsigned slot_idx;
-
- tid = inst->readTid();
- seq_num = inst->seqNum;
- aligned_addr = inst->getMemAddr();
- stage_num = cache_req->getStageNum();
- slot_idx = cache_req->getSlot();
+ ThreadID tid = inst->readTid();
+ Addr aligned_addr = inst->getMemAddr();
+ unsigned stage_num = cache_req->getStageNum();
+ unsigned slot_idx = cache_req->getSlot();
if (tlb_mode == TheISA::TLB::Execute) {
inst->fetchMemReq = new Request(inst->readTid(), aligned_addr,
if (cache_req->fault != NoFault) {
DPRINTF(InOrderTLB, "[tid:%i]: %s encountered while translating "
"addr:%08p for [sn:%i].\n", tid, cache_req->fault->name(),
- cache_req->memReq->getVaddr(), seq_num);
+ cache_req->memReq->getVaddr(), inst->seqNum);
cpu->pipelineStage[stage_num]->setResStall(cache_req, tid);
cpu->trap(cache_req->fault, tid);
} else {
DPRINTF(InOrderTLB, "[tid:%i]: [sn:%i] virt. addr %08p translated "
- "to phys. addr:%08p.\n", tid, seq_num,
+ "to phys. addr:%08p.\n", tid, inst->seqNum,
cache_req->memReq->getVaddr(),
cache_req->memReq->getPaddr());
}
assert(cache_req);
DynInstPtr inst = cache_req->inst;
- int tid;
- int seq_num;
+#if TRACING_ON
+ ThreadID tid = inst->readTid();
+ int seq_num = inst->seqNum;
+#endif
- tid = inst->readTid();
- seq_num = inst->seqNum;
cache_req->fault = NoFault;
switch (cache_req->cmd)
if (cache_req->fault == NoFault) {
DPRINTF(InOrderCachePort,
- "[tid:%u]: Initiating fetch access to %s for addr. %08p\n",
- tid, name(), cache_req->inst->getMemAddr());
+ "[tid:%u]: Initiating fetch access to %s for addr. %08p\n",
+ tid, name(), cache_req->inst->getMemAddr());
cache_req->reqData = new uint8_t[acc_size];
CacheUnit::doCacheAccess(DynInstPtr inst, uint64_t *write_res)
{
Fault fault = NoFault;
- int tid = 0;
-
- tid = inst->readTid();
+#if TRACING_ON
+ ThreadID tid = inst->readTid();
+#endif
CacheReqPtr cache_req
= dynamic_cast<CacheReqPtr>(reqMap[inst->getCurResSlot()]);
// Get resource request info
unsigned stage_num = cache_req->getStageNum();
DynInstPtr inst = cache_req->inst;
- unsigned tid;
-
-
- tid = cache_req->inst->readTid();
+ ThreadID tid = cache_req->inst->readTid();
if (!cache_req->isSquashed()) {
if (inst->resSched.top()->cmd == CompleteFetch) {
{
DynInstPtr inst = resource->reqMap[slotIdx]->inst;
int stage_num = resource->reqMap[slotIdx]->getStageNum();
- int tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
CacheReqPtr req_ptr = dynamic_cast<CacheReqPtr>(resource->reqMap[slotIdx]);
DPRINTF(InOrderTLB, "Waking up from TLB Miss caused by [sn:%i].\n",
void
CacheUnit::squash(DynInstPtr inst, int stage_num,
- InstSeqNum squash_seq_num, unsigned tid)
+ InstSeqNum squash_seq_num, ThreadID tid)
{
vector<int> slot_remove_list;
void execute(int slot_num);
void squash(DynInstPtr inst, int stage_num,
- InstSeqNum squash_seq_num, unsigned tid);
+ InstSeqNum squash_seq_num, ThreadID tid);
/** Processes cache completion event. */
void processCacheCompletion(PacketPtr pkt);
int res_latency, InOrderCPU *_cpu, ThePipeline::Params *params)
: Resource(res_name, res_id, res_width, res_latency, _cpu)
{
- for (int tid = 0; tid < MaxThreads; tid++) {
+ for (ThreadID tid = 0; tid < MaxThreads; tid++) {
regDepMap[tid] = &cpu->archRegDepMap[tid];
}
}
ResourceRequest* decode_req = reqMap[slot_num];
DynInstPtr inst = reqMap[slot_num]->inst;
Fault fault = reqMap[slot_num]->fault;
- int tid, seq_num;
+ ThreadID tid = inst->readTid();
- tid = inst->readTid();
- seq_num = inst->seqNum;
decode_req->fault = NoFault;
switch (decode_req->cmd)
bool done_sked = ThePipeline::createBackEndSchedule(inst);
if (done_sked) {
- DPRINTF(InOrderDecode, "[tid:%i]: Setting Destination Register(s) for [sn:%i].\n",
- tid, seq_num);
+ DPRINTF(InOrderDecode,
+ "[tid:%i]: Setting Destination Register(s) for [sn:%i].\n",
+ tid, inst->seqNum);
regDepMap[tid]->insert(inst);
decode_req->done();
} else {
- DPRINTF(Resource,"[tid:%i] Static Inst not available to decode. Unable to create "
- "schedule for instruction [sn:%i] \n", tid, inst->seqNum);
+ DPRINTF(Resource,
+ "[tid:%i] Static Inst not available to decode.\n", tid);
+ DPRINTF(Resource,
+ "Unable to create schedule for instruction [sn:%i] \n",
+ inst->seqNum);
DPRINTF(InOrderStall, "STALL: \n");
decode_req->done(false);
}
void
-DecodeUnit::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, unsigned tid)
+DecodeUnit::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
+ ThreadID tid)
{
- DPRINTF(InOrderDecode, "[tid:%i]: Updating due to squash from stage %i after [sn:%i].\n",
+ DPRINTF(InOrderDecode,
+ "[tid:%i]: Updating due to squash from stage %i after [sn:%i].\n",
tid, stage_num, squash_seq_num);
//cpu->removeInstsUntil(squash_seq_num, tid);
virtual void execute(int slot_num);
- void squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, unsigned tid);
+ void squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
+ ThreadID tid);
RegDepMap *regDepMap[ThePipeline::MaxThreads];
ResourceRequest* exec_req = reqMap[slot_num];
DynInstPtr inst = reqMap[slot_num]->inst;
Fault fault = reqMap[slot_num]->fault;
- int tid = inst->readTid();
+ ThreadID tid = inst->readTid();
int seq_num = inst->seqNum;
exec_req->fault = NoFault;
// that got squashed.
if (inst->mispredicted()) {
int stage_num = exec_req->getStageNum();
- int tid = inst->readTid();
+ ThreadID tid = inst->readTid();
// If it's a branch ...
if (inst->isDirectCtrl()) {
: Resource(res_name, res_id, res_width, res_latency, _cpu),
instSize(sizeof(MachInst))
{
- for (int tid = 0; tid < ThePipeline::MaxThreads; tid++) {
+ for (ThreadID tid = 0; tid < ThePipeline::MaxThreads; tid++) {
delaySlotInfo[tid].numInsts = 0;
delaySlotInfo[tid].targetReady = false;
// for performance considerations
ResourceRequest* fs_req = reqMap[slot_num];
DynInstPtr inst = fs_req->inst;
- int tid = inst->readTid();
+ ThreadID tid = inst->readTid();
int stage_num = fs_req->getStageNum();
int seq_num = inst->seqNum;
}
inline void
-FetchSeqUnit::squashAfterInst(DynInstPtr inst, int stage_num, unsigned tid)
+FetchSeqUnit::squashAfterInst(DynInstPtr inst, int stage_num, ThreadID tid)
{
// Squash In Pipeline Stage
cpu->pipelineStage[stage_num]->squashDueToBranch(inst, tid);
}
void
FetchSeqUnit::squash(DynInstPtr inst, int squash_stage,
- InstSeqNum squash_seq_num, unsigned tid)
+ InstSeqNum squash_seq_num, ThreadID tid)
{
DPRINTF(InOrderFetchSeq, "[tid:%i]: Updating due to squash from stage %i.\n",
tid, squash_stage);
void
-FetchSeqUnit::activateThread(unsigned tid)
+FetchSeqUnit::activateThread(ThreadID tid)
{
pcValid[tid] = true;
}
void
-FetchSeqUnit::deactivateThread(unsigned tid)
+FetchSeqUnit::deactivateThread(ThreadID tid)
{
delaySlotInfo[tid].numInsts = 0;
delaySlotInfo[tid].targetReady = false;
squashSeqNum[tid] = (InstSeqNum)-1;
lastSquashCycle[tid] = 0;
- std::list<unsigned>::iterator thread_it = find(cpu->fetchPriorityList.begin(),
+ list<ThreadID>::iterator thread_it = find(cpu->fetchPriorityList.begin(),
cpu->fetchPriorityList.end(),
tid);
virtual ~FetchSeqUnit() {}
virtual void init();
- virtual void activateThread(unsigned tid);
- virtual void deactivateThread(unsigned tid);
+ virtual void activateThread(ThreadID tid);
+ virtual void deactivateThread(ThreadID tid);
virtual void execute(int slot_num);
/** Override default Resource squash sequence. This actually,
* info
*/
virtual void squash(DynInstPtr inst, int squash_stage,
- InstSeqNum squash_seq_num, unsigned tid);
+ InstSeqNum squash_seq_num, ThreadID tid);
- inline void squashAfterInst(DynInstPtr inst, int stage_num, unsigned tid);
+ inline void squashAfterInst(DynInstPtr inst, int stage_num, ThreadID tid);
protected:
unsigned instSize;
lastCycleGrad(0), numCycleGrad(0)
{
- for (int tid = 0; tid < ThePipeline::MaxThreads; tid++) {
+ for (ThreadID tid = 0; tid < ThePipeline::MaxThreads; tid++) {
nonSpecInstActive[tid] = &cpu->nonSpecInstActive[tid];
nonSpecSeqNum[tid] = &cpu->nonSpecSeqNum[tid];
}
ResourceRequest* grad_req = reqMap[slot_num];
DynInstPtr inst = reqMap[slot_num]->inst;
Fault fault = reqMap[slot_num]->fault;
- int tid, seq_num;
-
- tid = inst->readTid();
- seq_num = inst->seqNum;
+ ThreadID tid = inst->readTid();
int stage_num = inst->resSched.top()->stageNum;
grad_req->fault = NoFault;
lastCycleGrad = curTick;
numCycleGrad = 0;
} else if (numCycleGrad > width) {
- DPRINTF(InOrderGraduation, "Graduation bandwidth reached for this cycle.\n");
+ DPRINTF(InOrderGraduation,
+ "Graduation bandwidth reached for this cycle.\n");
return;
}
// Make sure this is the last thing on the resource schedule
assert(inst->resSched.size() == 1);
- DPRINTF(InOrderGraduation, "[tid:%i] Graduating instruction [sn:%i].\n",
- tid, seq_num);
+ DPRINTF(InOrderGraduation,
+ "[tid:%i] Graduating instruction [sn:%i].\n",
+ tid, inst->seqNum);
DPRINTF(RefCount, "Refcount = %i.\n", 0/*inst->curCount()*/);
// @TODO: Fix this functionality. Probably too conservative.
if (inst->isNonSpeculative()) {
*nonSpecInstActive[tid] = false;
- DPRINTF(InOrderGraduation, "[tid:%i] Non-speculative instruction [sn:%i] has graduated.\n",
- tid, seq_num);
+ DPRINTF(InOrderGraduation,
+ "[tid:%i] Non-speculative inst [sn:%i] graduated\n",
+ tid, inst->seqNum);
}
if (inst->traceData) {
{
ResReqPtr ib_req = reqMap[slot_idx];
DynInstPtr inst = ib_req->inst;
- int tid, seq_num, stage_num;
+ ThreadID tid = inst->readTid();
+ int stage_num = ib_req->getStageNum();
- tid = inst->readTid();
- seq_num = inst->seqNum;
- stage_num = ib_req->getStageNum();
ib_req->fault = NoFault;
switch (ib_req->cmd)
if (instList.size() < width) {
DPRINTF(InOrderInstBuffer, "[tid:%i]: Inserting [sn:%i] into buffer.\n",
- tid, seq_num);
+ tid, inst->seqNum);
insert(inst);
inserted = true;
} else {
DPRINTF(InOrderInstBuffer, "[tid:%i]: Denying [sn:%i] request because "
- "buffer is full.\n", tid, seq_num);
+ "buffer is full.\n", tid, inst->seqNum);
std::list<DynInstPtr>::iterator list_it = instList.begin();
case RemoveInst:
{
DPRINTF(InOrderInstBuffer, "[tid:%i]: Removing [sn:%i] from buffer.\n",
- tid, seq_num);
+ tid, inst->seqNum);
remove(inst);
ib_req->done();
}
}
void
-InstBuffer::pop(unsigned tid)
+InstBuffer::pop(ThreadID tid)
{
instList.pop_front();
}
ThePipeline::DynInstPtr
-InstBuffer::top(unsigned tid)
+InstBuffer::top(ThreadID tid)
{
return instList.front();
}
void
InstBuffer::squash(DynInstPtr inst, int stage_num,
- InstSeqNum squash_seq_num, unsigned tid)
+ InstSeqNum squash_seq_num, ThreadID tid)
{
queue<list<DynInstPtr>::iterator> remove_list;
list<DynInstPtr>::iterator list_it = instList.begin();
virtual void remove(DynInstPtr inst);
- virtual void pop(unsigned tid);
+ virtual void pop(ThreadID tid);
- virtual DynInstPtr top(unsigned tid);
+ virtual DynInstPtr top(ThreadID tid);
virtual void squash(DynInstPtr inst, int stage_num,
- InstSeqNum squash_seq_num, unsigned tid);
+ InstSeqNum squash_seq_num, ThreadID tid);
protected:
/** List of instructions this resource is currently
* processing.
assert(ib_req);
DynInstPtr inst = ib_req->inst;
- int tid = inst->readTid();
+ ThreadID tid = inst->readTid();
int seq_num = inst->seqNum;
ib_req->fault = NoFault;
{ return instList.front(); }
void
-InstBuffer::squash(InstSeqNum squash_seq_num, unsigned tid)
+InstBuffer::squash(InstSeqNum squash_seq_num, ThreadID tid)
{
list<DynInstPtr>::iterator list_it = instList.begin();
list<DynInstPtr>::iterator list_end = instList.end();
virtual DynInstPtr top();
- virtual void squash(InstSeqNum squash_seq_num, unsigned tid);
+ virtual void squash(InstSeqNum squash_seq_num, ThreadID tid);
protected:
/** List of instructions this resource is currently
DynInstPtr inst = reqMap[slot_num]->inst;
Fault fault = reqMap[slot_num]->fault;
- //int tid = inst->readTid();
+ //ThreadID tid = inst->readTid();
//int seq_num = inst->seqNum;
switch (mult_div_req->cmd)
ResourceRequest* mult_div_req = reqMap[slot_num];
DynInstPtr inst = reqMap[slot_num]->inst;
Fault fault = reqMap[slot_num]->fault;
- int tid = inst->readTid();
+ ThreadID tid = inst->readTid();
int seq_num = inst->seqNum;
fault = inst->execute();
assert(tlb_req != 0x0);
DynInstPtr inst = tlb_req->inst;
- int tid, seq_num, stage_num;
-
- tid = inst->readTid();
- seq_num = inst->seqNum;
- stage_num = tlb_req->getStageNum();
+ ThreadID tid = inst->readTid();
+ int seq_num = inst->seqNum;
+ int stage_num = tlb_req->getStageNum();
tlb_req->fault = NoFault;
{
DynInstPtr inst = resource->reqMap[slotIdx]->inst;
int stage_num = resource->reqMap[slotIdx]->getStageNum();
- int tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
DPRINTF(InOrderTLB, "Waking up from TLB Miss caused by [sn:%i].\n",
inst->seqNum);
void
TLBUnit::squash(DynInstPtr inst, int stage_num,
- InstSeqNum squash_seq_num, unsigned tid)
+ InstSeqNum squash_seq_num, ThreadID tid)
{
//@TODO: Figure out a way to consolidate common parts
// of this squash code
virtual void execute(int slot_num);
- void squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, unsigned tid);
+ void squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
+ ThreadID tid);
bool tlbBlocked[ThePipeline::MaxThreads];
: Resource(res_name, res_id, res_width, res_latency, _cpu),
maxSeqNum((InstSeqNum)-1)
{
- for (int tid = 0; tid < ThePipeline::MaxThreads; tid++) {
+ for (ThreadID tid = 0; tid < ThePipeline::MaxThreads; tid++) {
nonSpecInstActive[tid] = &cpu->nonSpecInstActive[tid];
nonSpecSeqNum[tid] = &cpu->nonSpecSeqNum[tid];
assert(ud_req);
DynInstPtr inst = ud_req->inst;
- int tid = inst->readTid();
+ ThreadID tid = inst->readTid();
int seq_num = inst->seqNum;
int ud_idx = ud_req->useDefIdx;
}
void
-UseDefUnit::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, unsigned tid)
+UseDefUnit::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
+ ThreadID tid)
{
DPRINTF(InOrderUseDef, "[tid:%i]: Updating Due To Squash After [sn:%i].\n",
tid, squash_seq_num);
virtual void execute(int slot_num);
- virtual void squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, unsigned tid);
+ virtual void squash(DynInstPtr inst, int stage_num,
+ InstSeqNum squash_seq_num, ThreadID tid);
const InstSeqNum maxSeqNum;
}
uint64_t
-InOrderThreadContext::readRegOtherThread(int reg_idx, unsigned tid)
+InOrderThreadContext::readRegOtherThread(int reg_idx, ThreadID tid)
{
return cpu->readRegOtherThread(reg_idx, tid);
}
}
void
-InOrderThreadContext::setRegOtherThread(int misc_reg, const MiscReg &val, unsigned tid)
+InOrderThreadContext::setRegOtherThread(int misc_reg, const MiscReg &val,
+ ThreadID tid)
{
cpu->setRegOtherThread(misc_reg, val, tid);
}
virtual FloatRegBits readFloatRegBits(int reg_idx);
- virtual uint64_t readRegOtherThread(int misc_reg, unsigned tid);
+ virtual uint64_t readRegOtherThread(int misc_reg, ThreadID tid);
/** Sets an integer register to a value. */
virtual void setIntReg(int reg_idx, uint64_t val);
virtual void setFloatRegBits(int reg_idx, FloatRegBits val);
- virtual void setRegOtherThread(int misc_reg, const MiscReg &val, unsigned tid);
+ virtual void setRegOtherThread(int misc_reg, const MiscReg &val,
+ ThreadID tid);
/** Reads this thread's PC. */
virtual uint64_t readPC()
bool trapPending;
- InOrderThreadState(InOrderCPU *_cpu, int _thread_num, Process *_process, int _asid)
- : ThreadState(reinterpret_cast<BaseCPU*>(_cpu), 0/*_thread_num*/, _process, 0/*_asid*/),
+ InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num,
+ Process *_process, int _asid)
+ : ThreadState(reinterpret_cast<BaseCPU*>(_cpu), 0/*_thread_num*/,
+ _process, 0/*_asid*/),
cpu(_cpu), inSyscall(0), trapPending(0)
{ }
* @param tid The thread id.
* @return Returns if the branch is taken or not.
*/
- bool predict(DynInstPtr &inst, Addr &PC, unsigned tid);
+ bool predict(DynInstPtr &inst, Addr &PC, ThreadID tid);
// @todo: Rename this function.
void BPUncond(void * &bp_history);
* @param done_sn The sequence number to commit any older updates up until.
* @param tid The thread id.
*/
- void update(const InstSeqNum &done_sn, unsigned tid);
+ void update(const InstSeqNum &done_sn, ThreadID tid);
/**
* Squashes all outstanding updates until a given sequence number.
* until.
* @param tid The thread id.
*/
- void squash(const InstSeqNum &squashed_sn, unsigned tid);
+ void squash(const InstSeqNum &squashed_sn, ThreadID tid);
/**
* Squashes all outstanding updates until a given sequence number, and
* @param tid The thread id.
*/
void squash(const InstSeqNum &squashed_sn, const Addr &corr_target,
- bool actually_taken, unsigned tid);
+ bool actually_taken, ThreadID tid);
/**
* @param bp_history Pointer to the history object. The predictor
* information needed to update the predictor, BTB, and RAS.
*/
PredictorHistory(const InstSeqNum &seq_num, const Addr &inst_PC,
- const bool pred_taken, void *bp_history,
- const unsigned _tid)
+ bool pred_taken, void *bp_history,
+ ThreadID _tid)
: seqNum(seq_num), PC(inst_PC), RASTarget(0),
RASIndex(0), tid(_tid), predTaken(pred_taken), usedRAS(0),
wasCall(0), bpHistory(bp_history)
unsigned RASIndex;
/** The thread id. */
- unsigned tid;
+ ThreadID tid;
/** Whether or not it was predicted taken. */
bool predTaken;
template <class Impl>
bool
-BPredUnit<Impl>::predict(DynInstPtr &inst, Addr &PC, unsigned tid)
+BPredUnit<Impl>::predict(DynInstPtr &inst, Addr &PC, ThreadID tid)
{
// See if branch predictor predicts taken.
// If so, get its target addr either from the BTB or the RAS.
template <class Impl>
void
-BPredUnit<Impl>::update(const InstSeqNum &done_sn, unsigned tid)
+BPredUnit<Impl>::update(const InstSeqNum &done_sn, ThreadID tid)
{
DPRINTF(Fetch, "BranchPred: [tid:%i]: Committing branches until "
"[sn:%lli].\n", tid, done_sn);
template <class Impl>
void
-BPredUnit<Impl>::squash(const InstSeqNum &squashed_sn, unsigned tid)
+BPredUnit<Impl>::squash(const InstSeqNum &squashed_sn, ThreadID tid)
{
History &pred_hist = predHist[tid];
void
BPredUnit<Impl>::squash(const InstSeqNum &squashed_sn,
const Addr &corr_target,
- const bool actually_taken,
- unsigned tid)
+ bool actually_taken,
+ ThreadID tid)
{
// Now that we know that a branch was mispredicted, we need to undo
// all the branches that have been seen up until this branch and
Addr target;
/** The entry's thread id. */
- unsigned tid;
+ ThreadID tid;
/** Whether or not the entry is valid. */
bool valid;
* @param tid The thread id.
* @return Returns the target of the branch.
*/
- Addr lookup(const Addr &inst_PC, unsigned tid);
+ Addr lookup(const Addr &inst_PC, ThreadID tid);
/** Checks if a branch is in the BTB.
* @param inst_PC The address of the branch to look up.
* @param tid The thread id.
* @return Whether or not the branch exists in the BTB.
*/
- bool valid(const Addr &inst_PC, unsigned tid);
+ bool valid(const Addr &inst_PC, ThreadID tid);
/** Updates the BTB with the target of a branch.
* @param inst_PC The address of the branch being updated.
* @param tid The thread id.
*/
void update(const Addr &inst_PC, const Addr &target_PC,
- unsigned tid);
+ ThreadID tid);
private:
/** Returns the index into the BTB, based on the branch's PC.
class TrapEvent : public Event {
private:
DefaultCommit<Impl> *commit;
- unsigned tid;
+ ThreadID tid;
public:
- TrapEvent(DefaultCommit<Impl> *_commit, unsigned _tid);
+ TrapEvent(DefaultCommit<Impl> *_commit, ThreadID _tid);
void process();
const char *description() const;
IEW *iewStage;
/** Sets pointer to list of active threads. */
- void setActiveThreads(std::list<unsigned> *at_ptr);
+ void setActiveThreads(std::list<ThreadID> *at_ptr);
/** Sets pointer to the commited state rename map. */
void setRenameMap(RenameMap rm_ptr[Impl::MaxThreads]);
void commit();
/** Returns the number of free ROB entries for a specific thread. */
- unsigned numROBFreeEntries(unsigned tid);
+ size_t numROBFreeEntries(ThreadID tid);
/** Generates an event to schedule a squash due to a trap. */
- void generateTrapEvent(unsigned tid);
+ void generateTrapEvent(ThreadID tid);
/** Records that commit needs to initiate a squash due to an
* external state update through the TC.
*/
- void generateTCEvent(unsigned tid);
+ void generateTCEvent(ThreadID tid);
private:
/** Updates the overall status of commit with the nextStatus, and
bool changedROBEntries();
/** Squashes all in flight instructions. */
- void squashAll(unsigned tid);
+ void squashAll(ThreadID tid);
/** Handles squashing due to a trap. */
- void squashFromTrap(unsigned tid);
+ void squashFromTrap(ThreadID tid);
/** Handles squashing due to an TC write. */
- void squashFromTC(unsigned tid);
+ void squashFromTC(ThreadID tid);
#if FULL_SYSTEM
/** Handles processing an interrupt. */
void markCompletedInsts();
/** Gets the thread to commit, based on the SMT policy. */
- int getCommittingThread();
+ ThreadID getCommittingThread();
/** Returns the thread ID to use based on a round robin policy. */
- int roundRobin();
+ ThreadID roundRobin();
/** Returns the thread ID to use based on an oldest instruction policy. */
- int oldestReady();
+ ThreadID oldestReady();
public:
/** Returns the PC of the head instruction of the ROB.
Addr readPC() { return PC[0]; }
/** Returns the PC of a specific thread. */
- Addr readPC(unsigned tid) { return PC[tid]; }
+ Addr readPC(ThreadID tid) { return PC[tid]; }
/** Sets the PC of a specific thread. */
- void setPC(Addr val, unsigned tid) { PC[tid] = val; }
+ void setPC(Addr val, ThreadID tid) { PC[tid] = val; }
/** Reads the micro PC of a specific thread. */
- Addr readMicroPC(unsigned tid) { return microPC[tid]; }
+ Addr readMicroPC(ThreadID tid) { return microPC[tid]; }
/** Sets the micro PC of a specific thread */
- void setMicroPC(Addr val, unsigned tid) { microPC[tid] = val; }
+ void setMicroPC(Addr val, ThreadID tid) { microPC[tid] = val; }
/** Reads the next PC of a specific thread. */
- Addr readNextPC(unsigned tid) { return nextPC[tid]; }
+ Addr readNextPC(ThreadID tid) { return nextPC[tid]; }
/** Sets the next PC of a specific thread. */
- void setNextPC(Addr val, unsigned tid) { nextPC[tid] = val; }
+ void setNextPC(Addr val, ThreadID tid) { nextPC[tid] = val; }
/** Reads the next NPC of a specific thread. */
- Addr readNextNPC(unsigned tid) { return nextNPC[tid]; }
+ Addr readNextNPC(ThreadID tid) { return nextNPC[tid]; }
/** Sets the next NPC of a specific thread. */
- void setNextNPC(Addr val, unsigned tid) { nextNPC[tid] = val; }
+ void setNextNPC(Addr val, ThreadID tid) { nextNPC[tid] = val; }
/** Reads the micro PC of a specific thread. */
- Addr readNextMicroPC(unsigned tid) { return nextMicroPC[tid]; }
+ Addr readNextMicroPC(ThreadID tid) { return nextMicroPC[tid]; }
/** Sets the micro PC of a specific thread */
- void setNextMicroPC(Addr val, unsigned tid) { nextMicroPC[tid] = val; }
+ void setNextMicroPC(Addr val, ThreadID tid) { nextMicroPC[tid] = val; }
private:
/** Time buffer interface. */
bool changedROBNumEntries[Impl::MaxThreads];
/** A counter of how many threads are currently squashing. */
- int squashCounter;
+ ThreadID squashCounter;
/** Records if a thread has to squash this cycle due to a trap. */
bool trapSquash[Impl::MaxThreads];
bool tcSquash[Impl::MaxThreads];
/** Priority List used for Commit Policy */
- std::list<unsigned> priority_list;
+ std::list<ThreadID> priority_list;
/** IEW to Commit delay, in ticks. */
unsigned iewToCommitDelay;
unsigned numRobs;
/** Number of Active Threads */
- unsigned numThreads;
+ ThreadID numThreads;
/** Is a drain pending. */
bool drainPending;
bool checkEmptyROB[Impl::MaxThreads];
/** Pointer to the list of active threads. */
- std::list<unsigned> *activeThreads;
+ std::list<ThreadID> *activeThreads;
/** Rename map interface. */
RenameMap *renameMap[Impl::MaxThreads];
* Korey Sewell
*/
-#include "config/full_system.hh"
-#include "config/use_checker.hh"
-
#include <algorithm>
#include <string>
#include "base/cp_annotate.hh"
#include "base/loader/symtab.hh"
#include "base/timebuf.hh"
+#include "config/full_system.hh"
+#include "config/use_checker.hh"
#include "cpu/exetrace.hh"
#include "cpu/o3/commit.hh"
#include "cpu/o3/thread_state.hh"
+#include "params/DerivO3CPU.hh"
#if USE_CHECKER
#include "cpu/checker/cpu.hh"
#endif
-#include "params/DerivO3CPU.hh"
+using namespace std;
template <class Impl>
DefaultCommit<Impl>::TrapEvent::TrapEvent(DefaultCommit<Impl> *_commit,
- unsigned _tid)
+ ThreadID _tid)
: Event(CPU_Tick_Pri), commit(_commit), tid(_tid)
{
this->setFlags(AutoDelete);
commitPolicy = RoundRobin;
//Set-Up Priority List
- for (int tid=0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
priority_list.push_back(tid);
}
"RoundRobin,OldestReady}");
}
- for (int i=0; i < numThreads; i++) {
- commitStatus[i] = Idle;
- changedROBNumEntries[i] = false;
- checkEmptyROB[i] = false;
- trapInFlight[i] = false;
- committedStores[i] = false;
- trapSquash[i] = false;
- tcSquash[i] = false;
- microPC[i] = nextMicroPC[i] = PC[i] = nextPC[i] = nextNPC[i] = 0;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ commitStatus[tid] = Idle;
+ changedROBNumEntries[tid] = false;
+ checkEmptyROB[tid] = false;
+ trapInFlight[tid] = false;
+ committedStores[tid] = false;
+ trapSquash[tid] = false;
+ tcSquash[tid] = false;
+ microPC[tid] = 0;
+ nextMicroPC[tid] = 0;
+ PC[tid] = 0;
+ nextPC[tid] = 0;
+ nextNPC[tid] = 0;
}
#if FULL_SYSTEM
interrupt = NoFault;
;
statComInst
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:count")
.desc("Number of instructions committed")
.flags(total)
;
statComSwp
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:swp_count")
.desc("Number of s/w prefetches committed")
.flags(total)
;
statComRefs
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:refs")
.desc("Number of memory references committed")
.flags(total)
;
statComLoads
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:loads")
.desc("Number of loads committed")
.flags(total)
;
statComMembars
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:membars")
.desc("Number of memory barriers committed")
.flags(total)
;
statComBranches
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:branches")
.desc("Number of branches committed")
.flags(total)
;
commitEligible
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:bw_limited")
.desc("number of insts not committed due to BW limits")
.flags(total)
template<class Impl>
void
-DefaultCommit<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
+DefaultCommit<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
{
activeThreads = at_ptr;
}
void
DefaultCommit<Impl>::setRenameMap(RenameMap rm_ptr[])
{
- for (int i=0; i < numThreads; i++) {
- renameMap[i] = &rm_ptr[i];
- }
+ for (ThreadID tid = 0; tid < numThreads; tid++)
+ renameMap[tid] = &rm_ptr[tid];
}
template <class Impl>
rob->resetEntries();
// Broadcast the number of free entries.
- for (int i=0; i < numThreads; i++) {
- toIEW->commitInfo[i].usedROB = true;
- toIEW->commitInfo[i].freeROBEntries = rob->numFreeEntries(i);
- toIEW->commitInfo[i].emptyROB = true;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ toIEW->commitInfo[tid].usedROB = true;
+ toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
+ toIEW->commitInfo[tid].emptyROB = true;
}
// Commit must broadcast the number of free entries it has at the
switchedOut = false;
_status = Active;
_nextStatus = Inactive;
- for (int i=0; i < numThreads; i++) {
- commitStatus[i] = Idle;
- changedROBNumEntries[i] = false;
- trapSquash[i] = false;
- tcSquash[i] = false;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ commitStatus[tid] = Idle;
+ changedROBNumEntries[tid] = false;
+ trapSquash[tid] = false;
+ tcSquash[tid] = false;
}
squashCounter = 0;
rob->takeOverFrom();
DefaultCommit<Impl>::updateStatus()
{
// reset ROB changed variable
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
changedROBNumEntries[tid] = false;
{
int squashes = 0;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (commitStatus[tid] == ROBSquashing) {
squashes++;
bool
DefaultCommit<Impl>::changedROBEntries()
{
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (changedROBNumEntries[tid]) {
return true;
}
template <class Impl>
-unsigned
-DefaultCommit<Impl>::numROBFreeEntries(unsigned tid)
+size_t
+DefaultCommit<Impl>::numROBFreeEntries(ThreadID tid)
{
return rob->numFreeEntries(tid);
}
template <class Impl>
void
-DefaultCommit<Impl>::generateTrapEvent(unsigned tid)
+DefaultCommit<Impl>::generateTrapEvent(ThreadID tid)
{
DPRINTF(Commit, "Generating trap event for [tid:%i]\n", tid);
template <class Impl>
void
-DefaultCommit<Impl>::generateTCEvent(unsigned tid)
+DefaultCommit<Impl>::generateTCEvent(ThreadID tid)
{
assert(!trapInFlight[tid]);
DPRINTF(Commit, "Generating TC squash event for [tid:%i]\n", tid);
template <class Impl>
void
-DefaultCommit<Impl>::squashAll(unsigned tid)
+DefaultCommit<Impl>::squashAll(ThreadID tid)
{
// If we want to include the squashing instruction in the squash,
// then use one older sequence number.
template <class Impl>
void
-DefaultCommit<Impl>::squashFromTrap(unsigned tid)
+DefaultCommit<Impl>::squashFromTrap(ThreadID tid)
{
squashAll(tid);
template <class Impl>
void
-DefaultCommit<Impl>::squashFromTC(unsigned tid)
+DefaultCommit<Impl>::squashFromTC(ThreadID tid)
{
squashAll(tid);
if (activeThreads->empty())
return;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
// Check if any of the threads are done squashing. Change the
// status if they are done.
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
// Clear the bit saying if the thread has committed stores
// this cycle.
threads = activeThreads->begin();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (!rob->isEmpty(tid) && rob->readHeadInst(tid)->readyToCommit()) {
// The ROB has more instructions it can commit. Its next status
////////////////////////////////////
// Check for any possible squashes, handle them first
////////////////////////////////////
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
// Not sure which one takes priority. I think if we have
// both, that's a bad sign.
threads = activeThreads->begin();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (changedROBNumEntries[tid]) {
toIEW->commitInfo[tid].usedROB = true;
head_inst = rob->readHeadInst(commit_thread);
- int tid = head_inst->threadNumber;
+ ThreadID tid = head_inst->threadNumber;
assert(tid == commit_thread);
{
assert(head_inst);
- int tid = head_inst->threadNumber;
+ ThreadID tid = head_inst->threadNumber;
// If the instruction is not executed yet, then it will need extra
// handling. Signal backwards that it should be executed.
DynInstPtr inst;
inst = fromRename->insts[inst_num];
- int tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
if (!inst->isSquashed() &&
commitStatus[tid] != ROBSquashing &&
bool
DefaultCommit<Impl>::robDoneSquashing()
{
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (!rob->isDoneSquashing(tid))
return false;
void
DefaultCommit<Impl>::updateComInstStats(DynInstPtr &inst)
{
- unsigned thread = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
//
// Pick off the software prefetches
//
#ifdef TARGET_ALPHA
if (inst->isDataPrefetch()) {
- statComSwp[thread]++;
+ statComSwp[tid]++;
} else {
- statComInst[thread]++;
+ statComInst[tid]++;
}
#else
- statComInst[thread]++;
+ statComInst[tid]++;
#endif
//
// Control Instructions
//
if (inst->isControl())
- statComBranches[thread]++;
+ statComBranches[tid]++;
//
// Memory references
//
if (inst->isMemRef()) {
- statComRefs[thread]++;
+ statComRefs[tid]++;
if (inst->isLoad()) {
- statComLoads[thread]++;
+ statComLoads[tid]++;
}
}
if (inst->isMemBarrier()) {
- statComMembars[thread]++;
+ statComMembars[tid]++;
}
}
// //
////////////////////////////////////////
template <class Impl>
-int
+ThreadID
DefaultCommit<Impl>::getCommittingThread()
{
if (numThreads > 1) {
return oldestReady();
default:
- return -1;
+ return InvalidThreadID;
}
} else {
assert(!activeThreads->empty());
- int tid = activeThreads->front();
+ ThreadID tid = activeThreads->front();
if (commitStatus[tid] == Running ||
commitStatus[tid] == Idle ||
commitStatus[tid] == FetchTrapPending) {
return tid;
} else {
- return -1;
+ return InvalidThreadID;
}
}
}
template<class Impl>
-int
+ThreadID
DefaultCommit<Impl>::roundRobin()
{
- std::list<unsigned>::iterator pri_iter = priority_list.begin();
- std::list<unsigned>::iterator end = priority_list.end();
+ list<ThreadID>::iterator pri_iter = priority_list.begin();
+ list<ThreadID>::iterator end = priority_list.end();
while (pri_iter != end) {
- unsigned tid = *pri_iter;
+ ThreadID tid = *pri_iter;
if (commitStatus[tid] == Running ||
commitStatus[tid] == Idle ||
pri_iter++;
}
- return -1;
+ return InvalidThreadID;
}
template<class Impl>
-int
+ThreadID
DefaultCommit<Impl>::oldestReady()
{
unsigned oldest = 0;
bool first = true;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (!rob->isEmpty(tid) &&
(commitStatus[tid] == Running ||
if (!first) {
return oldest;
} else {
- return -1;
+ return InvalidThreadID;
}
}
class BaseCPUParams;
using namespace TheISA;
+using namespace std;
BaseO3CPU::BaseO3CPU(BaseCPUParams *params)
: BaseCPU(params)
scoreboard(params->numThreads,
TheISA::NumIntRegs, params->numPhysIntRegs,
TheISA::NumFloatRegs, params->numPhysFloatRegs,
- TheISA::NumMiscRegs * number_of_threads,
+ TheISA::NumMiscRegs * numThreads,
TheISA::ZeroReg),
timeBuffer(params->backComSize, params->forwardComSize),
physmem(system->physmem),
#endif // FULL_SYSTEM
drainCount(0),
- deferRegistration(params->defer_registration),
- numThreads(number_of_threads)
+ deferRegistration(params->defer_registration)
{
if (!deferRegistration) {
_status = Running;
#endif // USE_CHECKER
#if !FULL_SYSTEM
- thread.resize(number_of_threads);
- tids.resize(number_of_threads);
+ thread.resize(numThreads);
+ tids.resize(numThreads);
#endif
// The stages also need their CPU pointer setup. However this
rename.setCommitStage(&commit);
#if !FULL_SYSTEM
- int active_threads = params->workload.size();
+ ThreadID active_threads = params->workload.size();
if (active_threads > Impl::MaxThreads) {
panic("Workload Size too large. Increase the 'MaxThreads'"
"edit your workload size.");
}
#else
- int active_threads = 1;
+ ThreadID active_threads = 1;
#endif
//Make Sure That this a Valid Architeture
PhysRegIndex lreg_idx = 0;
PhysRegIndex freg_idx = params->numPhysIntRegs; //Index to 1 after int regs
- for (int tid=0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
bool bindRegs = (tid <= active_threads - 1);
commitRenameMap[tid].init(TheISA::NumIntRegs,
commit.setRenameMap(commitRenameMap);
// Give renameMap & rename stage access to the freeList;
- for (int i=0; i < numThreads; i++) {
- renameMap[i].setFreeList(&freeList);
- }
+ for (ThreadID tid = 0; tid < numThreads; tid++)
+ renameMap[tid].setFreeList(&freeList);
rename.setFreeList(&freeList);
// Setup the ROB for whichever stages need it.
lastRunningCycle = curTick;
lastActivatedCycle = -1;
-
+#if 0
// Give renameMap & rename stage access to the freeList;
- //for (int i=0; i < numThreads; i++) {
- //globalSeqNum[i] = 1;
- //}
+ for (ThreadID tid = 0; tid < numThreads; tid++)
+ globalSeqNum[tid] = 1;
+#endif
contextSwitch = false;
DPRINTF(O3CPU, "Creating O3CPU object.\n");
// Setup any thread state.
this->thread.resize(this->numThreads);
- for (int i = 0; i < this->numThreads; ++i) {
+ for (ThreadID tid = 0; tid < this->numThreads; ++tid) {
#if FULL_SYSTEM
// SMT is not supported in FS mode yet.
assert(this->numThreads == 1);
- this->thread[i] = new Thread(this, 0);
+ this->thread[tid] = new Thread(this, 0);
#else
- if (i < params->workload.size()) {
+ if (tid < params->workload.size()) {
DPRINTF(O3CPU, "Workload[%i] process is %#x",
- i, this->thread[i]);
- this->thread[i] = new typename FullO3CPU<Impl>::Thread(
+ tid, this->thread[tid]);
+ this->thread[tid] = new typename FullO3CPU<Impl>::Thread(
(typename Impl::O3CPU *)(this),
- i, params->workload[i], i);
+ tid, params->workload[tid], tid);
- //usedTids[i] = true;
- //threadMap[i] = i;
+ //usedTids[tid] = true;
+ //threadMap[tid] = tid;
} else {
//Allocate Empty thread so M5 can use later
//when scheduling threads to CPU
Process* dummy_proc = NULL;
- this->thread[i] = new typename FullO3CPU<Impl>::Thread(
+ this->thread[tid] = new typename FullO3CPU<Impl>::Thread(
(typename Impl::O3CPU *)(this),
- i, dummy_proc, i);
- //usedTids[i] = false;
+ tid, dummy_proc, tid);
+ //usedTids[tid] = false;
}
#endif // !FULL_SYSTEM
o3_tc->cpu = (typename Impl::O3CPU *)(this);
assert(o3_tc->cpu);
- o3_tc->thread = this->thread[i];
+ o3_tc->thread = this->thread[tid];
#if FULL_SYSTEM
// Setup quiesce event.
- this->thread[i]->quiesceEvent = new EndQuiesceEvent(tc);
+ this->thread[tid]->quiesceEvent = new EndQuiesceEvent(tc);
#endif
// Give the thread the TC.
- this->thread[i]->tc = tc;
+ this->thread[tid]->tc = tc;
// Add the TC to the CPU's list of TC's.
this->threadContexts.push_back(tc);
}
- for (int i=0; i < this->numThreads; i++) {
- this->thread[i]->setFuncExeInst(0);
- }
+ for (ThreadID tid = 0; tid < this->numThreads; tid++)
+ this->thread[tid]->setFuncExeInst(0);
lockAddr = 0;
lockFlag = false;
// Set inSyscall so that the CPU doesn't squash when initially
// setting up registers.
- for (int i = 0; i < number_of_threads; ++i)
- thread[i]->inSyscall = true;
+ for (ThreadID tid = 0; tid < numThreads; ++tid)
+ thread[tid]->inSyscall = true;
#if FULL_SYSTEM
- for (int tid=0; tid < number_of_threads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
ThreadContext *src_tc = threadContexts[tid];
TheISA::initCPU(src_tc, src_tc->contextId());
}
#endif
// Clear inSyscall.
- for (int i = 0; i < number_of_threads; ++i)
- thread[i]->inSyscall = false;
+ for (int tid = 0; tid < numThreads; ++tid)
+ thread[tid]->inSyscall = false;
// Initialize stages.
fetch.initStage();
template <class Impl>
void
-FullO3CPU<Impl>::activateThread(unsigned tid)
+FullO3CPU<Impl>::activateThread(ThreadID tid)
{
- std::list<unsigned>::iterator isActive =
+ list<ThreadID>::iterator isActive =
std::find(activeThreads.begin(), activeThreads.end(), tid);
DPRINTF(O3CPU, "[tid:%i]: Calling activate thread.\n", tid);
template <class Impl>
void
-FullO3CPU<Impl>::deactivateThread(unsigned tid)
+FullO3CPU<Impl>::deactivateThread(ThreadID tid)
{
//Remove From Active List, if Active
- std::list<unsigned>::iterator thread_it =
+ list<ThreadID>::iterator thread_it =
std::find(activeThreads.begin(), activeThreads.end(), tid);
DPRINTF(O3CPU, "[tid:%i]: Calling deactivate thread.\n", tid);
}
}
+template <class Impl>
+Counter
+FullO3CPU<Impl>::totalInstructions() const
+{
+ Counter total(0);
+
+ ThreadID size = thread.size();
+ for (ThreadID i = 0; i < size; i++)
+ total += thread[i]->numInst;
+
+ return total;
+}
+
template <class Impl>
void
-FullO3CPU<Impl>::activateContext(int tid, int delay)
+FullO3CPU<Impl>::activateContext(ThreadID tid, int delay)
{
// Needs to set each stage to running as well.
if (delay){
template <class Impl>
bool
-FullO3CPU<Impl>::deallocateContext(int tid, bool remove, int delay)
+FullO3CPU<Impl>::deallocateContext(ThreadID tid, bool remove, int delay)
{
// Schedule removal of thread data from CPU
if (delay){
template <class Impl>
void
-FullO3CPU<Impl>::suspendContext(int tid)
+FullO3CPU<Impl>::suspendContext(ThreadID tid)
{
DPRINTF(O3CPU,"[tid: %i]: Suspending Thread Context.\n", tid);
bool deallocated = deallocateContext(tid, false, 1);
template <class Impl>
void
-FullO3CPU<Impl>::haltContext(int tid)
+FullO3CPU<Impl>::haltContext(ThreadID tid)
{
//For now, this is the same as deallocate
DPRINTF(O3CPU,"[tid:%i]: Halt Context called. Deallocating", tid);
template <class Impl>
void
-FullO3CPU<Impl>::insertThread(unsigned tid)
+FullO3CPU<Impl>::insertThread(ThreadID tid)
{
DPRINTF(O3CPU,"[tid:%i] Initializing thread into CPU");
// Will change now that the PC and thread state is internal to the CPU
template <class Impl>
void
-FullO3CPU<Impl>::removeThread(unsigned tid)
+FullO3CPU<Impl>::removeThread(ThreadID tid)
{
DPRINTF(O3CPU,"[tid:%i] Removing thread context from CPU.\n", tid);
template <class Impl>
void
-FullO3CPU<Impl>::activateWhenReady(int tid)
+FullO3CPU<Impl>::activateWhenReady(ThreadID tid)
{
DPRINTF(O3CPU,"[tid:%i]: Checking if resources are available for incoming"
"(e.g. PhysRegs/ROB/IQ/LSQ) \n",
#if FULL_SYSTEM
template <class Impl>
Fault
-FullO3CPU<Impl>::hwrei(unsigned tid)
+FullO3CPU<Impl>::hwrei(ThreadID tid)
{
#if THE_ISA == ALPHA_ISA
// Need to clear the lock flag upon returning from an interrupt.
template <class Impl>
bool
-FullO3CPU<Impl>::simPalCheck(int palFunc, unsigned tid)
+FullO3CPU<Impl>::simPalCheck(int palFunc, ThreadID tid)
{
#if THE_ISA == ALPHA_ISA
if (this->thread[tid]->kernelStats)
{
// Update all ThreadContext's memory ports (Functional/Virtual
// Ports)
- for (int i = 0; i < thread.size(); ++i)
+ ThreadID size = thread.size();
+ for (ThreadID i = 0; i < size; ++i)
thread[i]->connectMemPorts(thread[i]->getTC());
}
#endif
template <class Impl>
void
-FullO3CPU<Impl>::trap(Fault fault, unsigned tid)
+FullO3CPU<Impl>::trap(Fault fault, ThreadID tid)
{
// Pass the thread's TC into the invoke method.
fault->invoke(this->threadContexts[tid]);
template <class Impl>
void
-FullO3CPU<Impl>::syscall(int64_t callnum, int tid)
+FullO3CPU<Impl>::syscall(int64_t callnum, ThreadID tid)
{
DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid);
// get instantiated multiple times (causes a panic in statistics).
static SimpleThread temp;
- for (int i = 0; i < thread.size(); i++) {
+ ThreadID size = thread.size();
+ for (ThreadID i = 0; i < size; i++) {
nameOut(os, csprintf("%s.xc.%i", name(), i));
temp.copyTC(thread[i]->getTC());
temp.serialize(os);
// get instantiated multiple times (causes a panic in statistics).
static SimpleThread temp;
- for (int i = 0; i < thread.size(); i++) {
+ ThreadID size = thread.size();
+ for (ThreadID i = 0; i < size; i++) {
temp.copyTC(thread[i]->getTC());
temp.unserialize(cp, csprintf("%s.xc.%i", section, i));
thread[i]->getTC()->copyArchRegs(temp.getTC());
// @todo: Figure out how to properly select the tid to put onto
// the active threads list.
- int tid = 0;
+ ThreadID tid = 0;
- std::list<unsigned>::iterator isActive =
+ list<ThreadID>::iterator isActive =
std::find(activeThreads.begin(), activeThreads.end(), tid);
if (isActive == activeThreads.end()) {
// Set all statuses to active, schedule the CPU's tick event.
// @todo: Fix up statuses so this is handled properly
- for (int i = 0; i < threadContexts.size(); ++i) {
+ ThreadID size = threadContexts.size();
+ for (ThreadID i = 0; i < size; ++i) {
ThreadContext *tc = threadContexts[i];
if (tc->status() == ThreadContext::Active && _status != Running) {
_status = Running;
template <class Impl>
TheISA::MiscReg
-FullO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, unsigned tid)
+FullO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, ThreadID tid)
{
return this->regFile.readMiscRegNoEffect(misc_reg, tid);
}
template <class Impl>
TheISA::MiscReg
-FullO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
+FullO3CPU<Impl>::readMiscReg(int misc_reg, ThreadID tid)
{
return this->regFile.readMiscReg(misc_reg, tid);
}
template <class Impl>
void
FullO3CPU<Impl>::setMiscRegNoEffect(int misc_reg,
- const TheISA::MiscReg &val, unsigned tid)
+ const TheISA::MiscReg &val, ThreadID tid)
{
this->regFile.setMiscRegNoEffect(misc_reg, val, tid);
}
template <class Impl>
void
FullO3CPU<Impl>::setMiscReg(int misc_reg,
- const TheISA::MiscReg &val, unsigned tid)
+ const TheISA::MiscReg &val, ThreadID tid)
{
this->regFile.setMiscReg(misc_reg, val, tid);
}
template <class Impl>
uint64_t
-FullO3CPU<Impl>::readArchIntReg(int reg_idx, unsigned tid)
+FullO3CPU<Impl>::readArchIntReg(int reg_idx, ThreadID tid)
{
PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
template <class Impl>
float
-FullO3CPU<Impl>::readArchFloatRegSingle(int reg_idx, unsigned tid)
+FullO3CPU<Impl>::readArchFloatRegSingle(int reg_idx, ThreadID tid)
{
int idx = reg_idx + TheISA::NumIntRegs;
PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
template <class Impl>
double
-FullO3CPU<Impl>::readArchFloatRegDouble(int reg_idx, unsigned tid)
+FullO3CPU<Impl>::readArchFloatRegDouble(int reg_idx, ThreadID tid)
{
int idx = reg_idx + TheISA::NumIntRegs;
PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
template <class Impl>
uint64_t
-FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, unsigned tid)
+FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, ThreadID tid)
{
int idx = reg_idx + TheISA::NumIntRegs;
PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
template <class Impl>
void
-FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, unsigned tid)
+FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, ThreadID tid)
{
PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
template <class Impl>
void
-FullO3CPU<Impl>::setArchFloatRegSingle(int reg_idx, float val, unsigned tid)
+FullO3CPU<Impl>::setArchFloatRegSingle(int reg_idx, float val, ThreadID tid)
{
int idx = reg_idx + TheISA::NumIntRegs;
PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
template <class Impl>
void
-FullO3CPU<Impl>::setArchFloatRegDouble(int reg_idx, double val, unsigned tid)
+FullO3CPU<Impl>::setArchFloatRegDouble(int reg_idx, double val, ThreadID tid)
{
int idx = reg_idx + TheISA::NumIntRegs;
PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
template <class Impl>
void
-FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid)
+FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid)
{
int idx = reg_idx + TheISA::NumIntRegs;
PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
template <class Impl>
uint64_t
-FullO3CPU<Impl>::readPC(unsigned tid)
+FullO3CPU<Impl>::readPC(ThreadID tid)
{
return commit.readPC(tid);
}
template <class Impl>
void
-FullO3CPU<Impl>::setPC(Addr new_PC,unsigned tid)
+FullO3CPU<Impl>::setPC(Addr new_PC, ThreadID tid)
{
commit.setPC(new_PC, tid);
}
template <class Impl>
uint64_t
-FullO3CPU<Impl>::readMicroPC(unsigned tid)
+FullO3CPU<Impl>::readMicroPC(ThreadID tid)
{
return commit.readMicroPC(tid);
}
template <class Impl>
void
-FullO3CPU<Impl>::setMicroPC(Addr new_PC,unsigned tid)
+FullO3CPU<Impl>::setMicroPC(Addr new_PC, ThreadID tid)
{
commit.setMicroPC(new_PC, tid);
}
template <class Impl>
uint64_t
-FullO3CPU<Impl>::readNextPC(unsigned tid)
+FullO3CPU<Impl>::readNextPC(ThreadID tid)
{
return commit.readNextPC(tid);
}
template <class Impl>
void
-FullO3CPU<Impl>::setNextPC(uint64_t val,unsigned tid)
+FullO3CPU<Impl>::setNextPC(uint64_t val, ThreadID tid)
{
commit.setNextPC(val, tid);
}
template <class Impl>
uint64_t
-FullO3CPU<Impl>::readNextNPC(unsigned tid)
+FullO3CPU<Impl>::readNextNPC(ThreadID tid)
{
return commit.readNextNPC(tid);
}
template <class Impl>
void
-FullO3CPU<Impl>::setNextNPC(uint64_t val,unsigned tid)
+FullO3CPU<Impl>::setNextNPC(uint64_t val, ThreadID tid)
{
commit.setNextNPC(val, tid);
}
template <class Impl>
uint64_t
-FullO3CPU<Impl>::readNextMicroPC(unsigned tid)
+FullO3CPU<Impl>::readNextMicroPC(ThreadID tid)
{
return commit.readNextMicroPC(tid);
}
template <class Impl>
void
-FullO3CPU<Impl>::setNextMicroPC(Addr new_PC,unsigned tid)
+FullO3CPU<Impl>::setNextMicroPC(Addr new_PC, ThreadID tid)
{
commit.setNextMicroPC(new_PC, tid);
}
template <class Impl>
void
-FullO3CPU<Impl>::squashFromTC(unsigned tid)
+FullO3CPU<Impl>::squashFromTC(ThreadID tid)
{
this->thread[tid]->inSyscall = true;
this->commit.generateTCEvent(tid);
template <class Impl>
void
-FullO3CPU<Impl>::instDone(unsigned tid)
+FullO3CPU<Impl>::instDone(ThreadID tid)
{
// Keep an instruction count.
thread[tid]->numInst++;
template <class Impl>
void
-FullO3CPU<Impl>::removeInstsNotInROB(unsigned tid)
+FullO3CPU<Impl>::removeInstsNotInROB(ThreadID tid)
{
DPRINTF(O3CPU, "Thread %i: Deleting instructions from instruction"
" list.\n", tid);
template <class Impl>
void
-FullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num,
- unsigned tid)
+FullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid)
{
assert(!instList.empty());
template <class Impl>
inline void
-FullO3CPU<Impl>::squashInstIt(const ListIt &instIt, const unsigned &tid)
+FullO3CPU<Impl>::squashInstIt(const ListIt &instIt, ThreadID tid)
{
if ((*instIt)->threadNumber == tid) {
DPRINTF(O3CPU, "Squashing instruction, "
#endif
template <class Impl>
-int
+ThreadID
FullO3CPU<Impl>::getFreeTid()
{
- for (int i=0; i < numThreads; i++) {
- if (!tids[i]) {
- tids[i] = true;
- return i;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ if (!tids[tid]) {
+ tids[tid] = true;
+ return tid;
}
}
- return -1;
+ return InvalidThreadID;
}
template <class Impl>
//ADD CODE TO DEACTIVE THREAD HERE (???)
- for (int tid=0; tid < cpuWaitList.size(); tid++) {
+ ThreadID size = cpuWaitList.size();
+ for (ThreadID tid = 0; tid < size; tid++) {
activateWhenReady(tid);
}
void
FullO3CPU<Impl>::updateThreadPriority()
{
- if (activeThreads.size() > 1)
- {
+ if (activeThreads.size() > 1) {
//DEFAULT TO ROUND ROBIN SCHEME
//e.g. Move highest priority to end of thread list
- std::list<unsigned>::iterator list_begin = activeThreads.begin();
- std::list<unsigned>::iterator list_end = activeThreads.end();
+ list<ThreadID>::iterator list_begin = activeThreads.begin();
+ list<ThreadID>::iterator list_end = activeThreads.end();
unsigned high_thread = *list_begin;
{
private:
/** Number of Thread to Activate */
- int tid;
+ ThreadID tid;
/** Pointer to the CPU. */
FullO3CPU<Impl> *cpu;
};
/** Schedule thread to activate , regardless of its current state. */
- void scheduleActivateThreadEvent(int tid, int delay)
+ void
+ scheduleActivateThreadEvent(ThreadID tid, int delay)
{
// Schedule thread to activate, regardless of its current state.
if (activateThreadEvent[tid].squashed())
}
/** Unschedule actiavte thread event, regardless of its current state. */
- void unscheduleActivateThreadEvent(int tid)
+ void
+ unscheduleActivateThreadEvent(ThreadID tid)
{
if (activateThreadEvent[tid].scheduled())
activateThreadEvent[tid].squash();
{
private:
/** Number of Thread to deactivate */
- int tid;
+ ThreadID tid;
/** Should the thread be removed from the CPU? */
bool remove;
};
/** Schedule cpu to deallocate thread context.*/
- void scheduleDeallocateContextEvent(int tid, bool remove, int delay)
+ void
+ scheduleDeallocateContextEvent(ThreadID tid, bool remove, int delay)
{
// Schedule thread to activate, regardless of its current state.
if (deallocateContextEvent[tid].squashed())
}
/** Unschedule thread deallocation in CPU */
- void unscheduleDeallocateContextEvent(int tid)
+ void
+ unscheduleDeallocateContextEvent(ThreadID tid)
{
if (deallocateContextEvent[tid].scheduled())
deallocateContextEvent[tid].squash();
{ return activeThreads.size(); }
/** Add Thread to Active Threads List */
- void activateThread(unsigned tid);
+ void activateThread(ThreadID tid);
/** Remove Thread from Active Threads List */
- void deactivateThread(unsigned tid);
+ void deactivateThread(ThreadID tid);
/** Setup CPU to insert a thread's context */
- void insertThread(unsigned tid);
+ void insertThread(ThreadID tid);
/** Remove all of a thread's context from CPU */
- void removeThread(unsigned tid);
+ void removeThread(ThreadID tid);
/** Count the Total Instructions Committed in the CPU. */
- virtual Counter totalInstructions() const
- {
- Counter total(0);
-
- for (int i=0; i < thread.size(); i++)
- total += thread[i]->numInst;
-
- return total;
- }
+ virtual Counter totalInstructions() const;
/** Add Thread to Active Threads List. */
- void activateContext(int tid, int delay);
+ void activateContext(ThreadID tid, int delay);
/** Remove Thread from Active Threads List */
- void suspendContext(int tid);
+ void suspendContext(ThreadID tid);
/** Remove Thread from Active Threads List &&
* Possibly Remove Thread Context from CPU.
*/
- bool deallocateContext(int tid, bool remove, int delay = 1);
+ bool deallocateContext(ThreadID tid, bool remove, int delay = 1);
/** Remove Thread from Active Threads List &&
* Remove Thread Context from CPU.
*/
- void haltContext(int tid);
+ void haltContext(ThreadID tid);
/** Activate a Thread When CPU Resources are Available. */
- void activateWhenReady(int tid);
+ void activateWhenReady(ThreadID tid);
/** Add or Remove a Thread Context in the CPU. */
void doContextSwitch();
/** Executes a syscall.
* @todo: Determine if this needs to be virtual.
*/
- void syscall(int64_t callnum, int tid);
+ void syscall(int64_t callnum, ThreadID tid);
#endif
/** Starts draining the CPU's pipeline of all instructions in
{ return globalSeqNum++; }
/** Traps to handle given fault. */
- void trap(Fault fault, unsigned tid);
+ void trap(Fault fault, ThreadID tid);
#if FULL_SYSTEM
/** HW return from error interrupt. */
- Fault hwrei(unsigned tid);
+ Fault hwrei(ThreadID tid);
- bool simPalCheck(int palFunc, unsigned tid);
+ bool simPalCheck(int palFunc, ThreadID tid);
/** Returns the Fault for any valid interrupt. */
Fault getInterrupts();
bool validDataAddr(Addr addr) { return true; }
/** Get instruction asid. */
- int getInstAsid(unsigned tid)
+ int getInstAsid(ThreadID tid)
{ return regFile.miscRegs[tid].getInstAsid(); }
/** Get data asid. */
- int getDataAsid(unsigned tid)
+ int getDataAsid(ThreadID tid)
{ return regFile.miscRegs[tid].getDataAsid(); }
#else
/** Get instruction asid. */
- int getInstAsid(unsigned tid)
+ int getInstAsid(ThreadID tid)
{ return thread[tid]->getInstAsid(); }
/** Get data asid. */
- int getDataAsid(unsigned tid)
+ int getDataAsid(ThreadID tid)
{ return thread[tid]->getDataAsid(); }
#endif
/** Register accessors. Index refers to the physical register index. */
/** Reads a miscellaneous register. */
- TheISA::MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscRegNoEffect(int misc_reg, ThreadID tid);
/** Reads a misc. register, including any side effects the read
* might have as defined by the architecture.
*/
- TheISA::MiscReg readMiscReg(int misc_reg, unsigned tid);
+ TheISA::MiscReg readMiscReg(int misc_reg, ThreadID tid);
/** Sets a miscellaneous register. */
- void setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val, unsigned tid);
+ void setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val,
+ ThreadID tid);
/** Sets a misc. register, including any side effects the write
* might have as defined by the architecture.
*/
void setMiscReg(int misc_reg, const TheISA::MiscReg &val,
- unsigned tid);
+ ThreadID tid);
uint64_t readIntReg(int reg_idx);
void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val, int width);
- uint64_t readArchIntReg(int reg_idx, unsigned tid);
+ uint64_t readArchIntReg(int reg_idx, ThreadID tid);
- float readArchFloatRegSingle(int reg_idx, unsigned tid);
+ float readArchFloatRegSingle(int reg_idx, ThreadID tid);
- double readArchFloatRegDouble(int reg_idx, unsigned tid);
+ double readArchFloatRegDouble(int reg_idx, ThreadID tid);
- uint64_t readArchFloatRegInt(int reg_idx, unsigned tid);
+ uint64_t readArchFloatRegInt(int reg_idx, ThreadID tid);
/** Architectural register accessors. Looks up in the commit
* rename table to obtain the true physical index of the
* architected register first, then accesses that physical
* register.
*/
- void setArchIntReg(int reg_idx, uint64_t val, unsigned tid);
+ void setArchIntReg(int reg_idx, uint64_t val, ThreadID tid);
- void setArchFloatRegSingle(int reg_idx, float val, unsigned tid);
+ void setArchFloatRegSingle(int reg_idx, float val, ThreadID tid);
- void setArchFloatRegDouble(int reg_idx, double val, unsigned tid);
+ void setArchFloatRegDouble(int reg_idx, double val, ThreadID tid);
- void setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid);
+ void setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid);
/** Reads the commit PC of a specific thread. */
- Addr readPC(unsigned tid);
+ Addr readPC(ThreadID tid);
/** Sets the commit PC of a specific thread. */
- void setPC(Addr new_PC, unsigned tid);
+ void setPC(Addr new_PC, ThreadID tid);
/** Reads the commit micro PC of a specific thread. */
- Addr readMicroPC(unsigned tid);
+ Addr readMicroPC(ThreadID tid);
/** Sets the commmit micro PC of a specific thread. */
- void setMicroPC(Addr new_microPC, unsigned tid);
+ void setMicroPC(Addr new_microPC, ThreadID tid);
/** Reads the next PC of a specific thread. */
- Addr readNextPC(unsigned tid);
+ Addr readNextPC(ThreadID tid);
/** Sets the next PC of a specific thread. */
- void setNextPC(Addr val, unsigned tid);
+ void setNextPC(Addr val, ThreadID tid);
/** Reads the next NPC of a specific thread. */
- Addr readNextNPC(unsigned tid);
+ Addr readNextNPC(ThreadID tid);
/** Sets the next NPC of a specific thread. */
- void setNextNPC(Addr val, unsigned tid);
+ void setNextNPC(Addr val, ThreadID tid);
/** Reads the commit next micro PC of a specific thread. */
- Addr readNextMicroPC(unsigned tid);
+ Addr readNextMicroPC(ThreadID tid);
/** Sets the commit next micro PC of a specific thread. */
- void setNextMicroPC(Addr val, unsigned tid);
+ void setNextMicroPC(Addr val, ThreadID tid);
/** Initiates a squash of all in-flight instructions for a given
* thread. The source of the squash is an external update of
* state through the TC.
*/
- void squashFromTC(unsigned tid);
+ void squashFromTC(ThreadID tid);
/** Function to add instruction onto the head of the list of the
* instructions. Used when new instructions are fetched.
ListIt addInst(DynInstPtr &inst);
/** Function to tell the CPU that an instruction has completed. */
- void instDone(unsigned tid);
+ void instDone(ThreadID tid);
/** Add Instructions to the CPU Remove List*/
void addToRemoveList(DynInstPtr &inst);
/** Remove all instructions that are not currently in the ROB.
* There's also an option to not squash delay slot instructions.*/
- void removeInstsNotInROB(unsigned tid);
+ void removeInstsNotInROB(ThreadID tid);
/** Remove all instructions younger than the given sequence number. */
- void removeInstsUntil(const InstSeqNum &seq_num,unsigned tid);
+ void removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid);
/** Removes the instruction pointed to by the iterator. */
- inline void squashInstIt(const ListIt &instIt, const unsigned &tid);
+ inline void squashInstIt(const ListIt &instIt, ThreadID tid);
/** Cleans up all instructions on the remove list. */
void cleanUpRemovedInsts();
typename CPUPolicy::ROB rob;
/** Active Threads List */
- std::list<unsigned> activeThreads;
+ std::list<ThreadID> activeThreads;
/** Integer Register Scoreboard */
Scoreboard scoreboard;
#endif
/** Gets a free thread id. Use if thread ids change across system. */
- int getFreeTid();
+ ThreadID getFreeTid();
public:
/** Returns a pointer to a thread context. */
- ThreadContext *tcBase(unsigned tid)
+ ThreadContext *
+ tcBase(ThreadID tid)
{
return thread[tid]->getTC();
}
/** The cycle that the CPU was last activated by a new thread*/
Tick lastActivatedCycle;
- /** Number of Threads CPU can process */
- unsigned numThreads;
-
/** Mapping for system thread id to cpu id */
- std::map<unsigned,unsigned> threadMap;
+ std::map<ThreadID, unsigned> threadMap;
/** Available thread ids in the cpu*/
- std::vector<unsigned> tids;
+ std::vector<ThreadID> tids;
/** CPU read function, forwards read to LSQ. */
template <class T>
{
#if FULL_SYSTEM
// Full-system only supports a single thread for the moment.
- int actual_num_threads = 1;
+ ThreadID actual_num_threads = 1;
#else
// In non-full-system mode, we infer the number of threads from
// the workload if it's not explicitly specified.
- int actual_num_threads =
+ ThreadID actual_num_threads =
(numThreads >= workload.size()) ? numThreads : workload.size();
if (workload.size() == 0) {
void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);
/** Sets pointer to list of active threads. */
- void setActiveThreads(std::list<unsigned> *at_ptr);
+ void setActiveThreads(std::list<ThreadID> *at_ptr);
/** Drains the decode stage. */
bool drain();
* change (ie switching from from blocking to unblocking).
* @param tid Thread id to decode instructions from.
*/
- void decode(bool &status_change, unsigned tid);
+ void decode(bool &status_change, ThreadID tid);
/** Processes instructions from fetch and passes them on to rename.
* Decoding of instructions actually happens when they are created in
* fetch, so this function mostly checks if PC-relative branches are
* correct.
*/
- void decodeInsts(unsigned tid);
+ void decodeInsts(ThreadID tid);
private:
/** Inserts a thread's instructions into the skid buffer, to be decoded
* once decode unblocks.
*/
- void skidInsert(unsigned tid);
+ void skidInsert(ThreadID tid);
/** Returns if all of the skid buffers are empty. */
bool skidsEmpty();
void sortInsts();
/** Reads all stall signals from the backwards communication timebuffer. */
- void readStallSignals(unsigned tid);
+ void readStallSignals(ThreadID tid);
/** Checks all input signals and updates decode's status appropriately. */
- bool checkSignalsAndUpdate(unsigned tid);
+ bool checkSignalsAndUpdate(ThreadID tid);
/** Checks all stall signals, and returns if any are true. */
- bool checkStall(unsigned tid) const;
+ bool checkStall(ThreadID tid) const;
/** Returns if there any instructions from fetch on this cycle. */
inline bool fetchInstsValid();
* become blocked.
* @return Returns true if there is a status change.
*/
- bool block(unsigned tid);
+ bool block(ThreadID tid);
/** Switches decode to unblocking if the skid buffer is empty, and
* signals back that decode has unblocked.
* @return Returns true if there is a status change.
*/
- bool unblock(unsigned tid);
+ bool unblock(ThreadID tid);
/** Squashes if there is a PC-relative branch that was predicted
* incorrectly. Sends squash information back to fetch.
*/
- void squash(DynInstPtr &inst, unsigned tid);
+ void squash(DynInstPtr &inst, ThreadID tid);
public:
/** Squashes due to commit signalling a squash. Changes status to
* squashing and clears block/unblock signals as needed.
*/
- unsigned squash(unsigned tid);
+ unsigned squash(ThreadID tid);
private:
// Interfaces to objects outside of decode.
unsigned toRenameIndex;
/** number of Active Threads*/
- unsigned numThreads;
+ ThreadID numThreads;
/** List of active thread ids */
- std::list<unsigned> *activeThreads;
+ std::list<ThreadID> *activeThreads;
/** Number of branches in flight. */
unsigned branchCount[Impl::MaxThreads];
*/
#include "cpu/o3/decode.hh"
-
#include "params/DerivO3CPU.hh"
+using namespace std;
+
template<class Impl>
DefaultDecode<Impl>::DefaultDecode(O3CPU *_cpu, DerivO3CPUParams *params)
: cpu(_cpu),
_status = Inactive;
// Setup status, make sure stall signals are clear.
- for (int i = 0; i < numThreads; ++i) {
- decodeStatus[i] = Idle;
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
+ decodeStatus[tid] = Idle;
- stalls[i].rename = false;
- stalls[i].iew = false;
- stalls[i].commit = false;
+ stalls[tid].rename = false;
+ stalls[tid].iew = false;
+ stalls[tid].commit = false;
}
// @todo: Make into a parameter
template<class Impl>
void
-DefaultDecode<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
+DefaultDecode<Impl>::setActiveThreads(std::list<ThreadID> *at_ptr)
{
activeThreads = at_ptr;
}
_status = Inactive;
// Be sure to reset state and clear out any old instructions.
- for (int i = 0; i < numThreads; ++i) {
- decodeStatus[i] = Idle;
-
- stalls[i].rename = false;
- stalls[i].iew = false;
- stalls[i].commit = false;
- while (!insts[i].empty())
- insts[i].pop();
- while (!skidBuffer[i].empty())
- skidBuffer[i].pop();
- branchCount[i] = 0;
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
+ decodeStatus[tid] = Idle;
+
+ stalls[tid].rename = false;
+ stalls[tid].iew = false;
+ stalls[tid].commit = false;
+ while (!insts[tid].empty())
+ insts[tid].pop();
+ while (!skidBuffer[tid].empty())
+ skidBuffer[tid].pop();
+ branchCount[tid] = 0;
}
wroteToTimeBuffer = false;
}
template<class Impl>
bool
-DefaultDecode<Impl>::checkStall(unsigned tid) const
+DefaultDecode<Impl>::checkStall(ThreadID tid) const
{
bool ret_val = false;
template<class Impl>
bool
-DefaultDecode<Impl>::block(unsigned tid)
+DefaultDecode<Impl>::block(ThreadID tid)
{
DPRINTF(Decode, "[tid:%u]: Blocking.\n", tid);
template<class Impl>
bool
-DefaultDecode<Impl>::unblock(unsigned tid)
+DefaultDecode<Impl>::unblock(ThreadID tid)
{
// Decode is done unblocking only if the skid buffer is empty.
if (skidBuffer[tid].empty()) {
template<class Impl>
void
-DefaultDecode<Impl>::squash(DynInstPtr &inst, unsigned tid)
+DefaultDecode<Impl>::squash(DynInstPtr &inst, ThreadID tid)
{
DPRINTF(Decode, "[tid:%i]: [sn:%i] Squashing due to incorrect branch prediction "
"detected at decode.\n", tid, inst->seqNum);
template<class Impl>
unsigned
-DefaultDecode<Impl>::squash(unsigned tid)
+DefaultDecode<Impl>::squash(ThreadID tid)
{
DPRINTF(Decode, "[tid:%i]: Squashing.\n",tid);
template<class Impl>
void
-DefaultDecode<Impl>::skidInsert(unsigned tid)
+DefaultDecode<Impl>::skidInsert(ThreadID tid)
{
DynInstPtr inst = NULL;
bool
DefaultDecode<Impl>::skidsEmpty()
{
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (!skidBuffer[tid].empty())
return false;
}
{
bool any_unblocking = false;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (decodeStatus[tid] == Unblocking) {
any_unblocking = true;
{
int insts_from_fetch = fromFetch->size;
#ifdef DEBUG
- for (int i=0; i < numThreads; i++)
- assert(insts[i].empty());
+ for (ThreadID tid = 0; tid < numThreads; tid++)
+ assert(insts[tid].empty());
#endif
for (int i = 0; i < insts_from_fetch; ++i) {
insts[fromFetch->insts[i]->threadNumber].push(fromFetch->insts[i]);
template<class Impl>
void
-DefaultDecode<Impl>::readStallSignals(unsigned tid)
+DefaultDecode<Impl>::readStallSignals(ThreadID tid)
{
if (fromRename->renameBlock[tid]) {
stalls[tid].rename = true;
template <class Impl>
bool
-DefaultDecode<Impl>::checkSignalsAndUpdate(unsigned tid)
+DefaultDecode<Impl>::checkSignalsAndUpdate(ThreadID tid)
{
// Check if there's a squash signal, squash if there is.
// Check stall signals, block if necessary.
toRenameIndex = 0;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
sortInsts();
//Check stall and squash signals.
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
DPRINTF(Decode,"Processing [tid:%i]\n",tid);
status_change = checkSignalsAndUpdate(tid) || status_change;
template<class Impl>
void
-DefaultDecode<Impl>::decode(bool &status_change, unsigned tid)
+DefaultDecode<Impl>::decode(bool &status_change, ThreadID tid)
{
// If status is Running or idle,
// call decodeInsts()
template <class Impl>
void
-DefaultDecode<Impl>::decodeInsts(unsigned tid)
+DefaultDecode<Impl>::decodeInsts(ThreadID tid)
{
// Instructions can come either from the skid buffer or the list of
// instructions coming from fetch, depending on decode's status.
FetchPriority fetchPolicy;
/** List that has the threads organized by priority. */
- std::list<unsigned> priorityList;
+ std::list<ThreadID> priorityList;
public:
/** DefaultFetch constructor. */
void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);
/** Sets pointer to list of active threads. */
- void setActiveThreads(std::list<unsigned> *at_ptr);
+ void setActiveThreads(std::list<ThreadID> *at_ptr);
/** Sets pointer to time buffer used to communicate to the next stage. */
void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);
* @param tid Thread id.
* @return Any fault that occured.
*/
- bool fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid);
+ bool fetchCacheLine(Addr fetch_PC, Fault &ret_fault, ThreadID tid);
/** Squashes a specific thread and resets the PC. */
inline void doSquash(const Addr &new_PC, const Addr &new_NPC,
- const Addr &new_MicroPC, unsigned tid);
+ const Addr &new_MicroPC, ThreadID tid);
/** Squashes a specific thread and resets the PC. Also tells the CPU to
* remove any instructions between fetch and decode that should be sqaushed.
*/
void squashFromDecode(const Addr &new_PC, const Addr &new_NPC,
const Addr &new_MicroPC,
- const InstSeqNum &seq_num, unsigned tid);
+ const InstSeqNum &seq_num, ThreadID tid);
/** Checks if a thread is stalled. */
- bool checkStall(unsigned tid) const;
+ bool checkStall(ThreadID tid) const;
/** Updates overall fetch stage status; to be called at the end of each
* cycle. */
*/
void squash(const Addr &new_PC, const Addr &new_NPC,
const Addr &new_MicroPC,
- const InstSeqNum &seq_num, unsigned tid);
+ const InstSeqNum &seq_num, ThreadID tid);
/** Ticks the fetch stage, processing all inputs signals and fetching
* as many instructions as possible.
/** Checks all input signals and updates the status as necessary.
* @return: Returns if the status has changed due to input signals.
*/
- bool checkSignalsAndUpdate(unsigned tid);
+ bool checkSignalsAndUpdate(ThreadID tid);
/** Does the actual fetching of instructions and passing them on to the
* next stage.
void recvRetry();
/** Returns the appropriate thread to fetch, given the fetch policy. */
- int getFetchingThread(FetchPriority &fetch_priority);
+ ThreadID getFetchingThread(FetchPriority &fetch_priority);
/** Returns the appropriate thread to fetch using a round robin policy. */
- int roundRobin();
+ ThreadID roundRobin();
/** Returns the appropriate thread to fetch using the IQ count policy. */
- int iqCount();
+ ThreadID iqCount();
/** Returns the appropriate thread to fetch using the LSQ count policy. */
- int lsqCount();
+ ThreadID lsqCount();
- /** Returns the appropriate thread to fetch using the branch count policy. */
- int branchCount();
+ /** Returns the appropriate thread to fetch using the branch count
+ * policy. */
+ ThreadID branchCount();
private:
/** Pointer to the O3CPU. */
PacketPtr retryPkt;
/** The thread that is waiting on the cache to tell fetch to retry. */
- int retryTid;
+ ThreadID retryTid;
/** Cache block size. */
int cacheBlkSize;
Counter lastIcacheStall[Impl::MaxThreads];
/** List of Active Threads */
- std::list<unsigned> *activeThreads;
+ std::list<ThreadID> *activeThreads;
/** Number of threads. */
- unsigned numThreads;
+ ThreadID numThreads;
/** Number of threads that are actively fetching. */
- unsigned numFetchingThreads;
+ ThreadID numFetchingThreads;
/** Thread ID being fetched. */
- int threadFetched;
+ ThreadID threadFetched;
/** Checks if there is an interrupt pending. If there is, fetch
* must stop once it is not fetching PAL instructions.
#include "sim/system.hh"
#endif // FULL_SYSTEM
+using namespace std;
+
template<class Impl>
void
DefaultFetch<Impl>::IcachePort::setPeer(Port *port)
fetchWidth(params->fetchWidth),
cacheBlocked(false),
retryPkt(NULL),
- retryTid(-1),
+ retryTid(InvalidThreadID),
numThreads(params->numThreads),
numFetchingThreads(params->smtNumFetchingThreads),
interruptPending(false),
template<class Impl>
void
-DefaultFetch<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
+DefaultFetch<Impl>::setActiveThreads(std::list<ThreadID> *at_ptr)
{
activeThreads = at_ptr;
}
DefaultFetch<Impl>::initStage()
{
// Setup PC and nextPC with initial state.
- for (int tid = 0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
PC[tid] = cpu->readPC(tid);
nextPC[tid] = cpu->readNextPC(tid);
microPC[tid] = cpu->readMicroPC(tid);
}
- for (int tid=0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
fetchStatus[tid] = Running;
// Create mask to get rid of offset bits.
cacheBlkMask = (cacheBlkSize - 1);
- for (int tid=0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
// Create space to store a cache line.
cacheData[tid] = new uint8_t[cacheBlkSize];
cacheDataPC[tid] = 0;
void
DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
{
- unsigned tid = pkt->req->threadId();
+ ThreadID tid = pkt->req->threadId();
DPRINTF(Fetch, "[tid:%u] Waking up from cache miss.\n",tid);
DefaultFetch<Impl>::takeOverFrom()
{
// Reset all state
- for (int i = 0; i < Impl::MaxThreads; ++i) {
+ for (ThreadID i = 0; i < Impl::MaxThreads; ++i) {
stalls[i].decode = 0;
stalls[i].rename = 0;
stalls[i].iew = 0;
//would reset the micro pc to 0.
next_MicroPC = 0;
- int tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
Addr pred_PC = next_PC;
predict_taken = branchPred.predict(inst, pred_PC, tid);
template <class Impl>
bool
-DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid)
+DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, ThreadID tid)
{
Fault fault = NoFault;
// exists within the cache.
if (!icachePort->sendTiming(data_pkt)) {
assert(retryPkt == NULL);
- assert(retryTid == -1);
+ assert(retryTid == InvalidThreadID);
DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid);
fetchStatus[tid] = IcacheWaitRetry;
retryPkt = data_pkt;
template <class Impl>
inline void
DefaultFetch<Impl>::doSquash(const Addr &new_PC,
- const Addr &new_NPC, const Addr &new_microPC, unsigned tid)
+ const Addr &new_NPC, const Addr &new_microPC, ThreadID tid)
{
DPRINTF(Fetch, "[tid:%i]: Squashing, setting PC to: %#x, NPC to: %#x.\n",
tid, new_PC, new_NPC);
delete retryPkt;
}
retryPkt = NULL;
- retryTid = -1;
+ retryTid = InvalidThreadID;
}
fetchStatus[tid] = Squashing;
void
DefaultFetch<Impl>::squashFromDecode(const Addr &new_PC, const Addr &new_NPC,
const Addr &new_MicroPC,
- const InstSeqNum &seq_num, unsigned tid)
+ const InstSeqNum &seq_num, ThreadID tid)
{
DPRINTF(Fetch, "[tid:%i]: Squashing from decode.\n",tid);
template<class Impl>
bool
-DefaultFetch<Impl>::checkStall(unsigned tid) const
+DefaultFetch<Impl>::checkStall(ThreadID tid) const
{
bool ret_val = false;
DefaultFetch<Impl>::updateFetchStatus()
{
//Check Running
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (fetchStatus[tid] == Running ||
fetchStatus[tid] == Squashing ||
void
DefaultFetch<Impl>::squash(const Addr &new_PC, const Addr &new_NPC,
const Addr &new_MicroPC,
- const InstSeqNum &seq_num, unsigned tid)
+ const InstSeqNum &seq_num, ThreadID tid)
{
DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n",tid);
void
DefaultFetch<Impl>::tick()
{
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
bool status_change = false;
wroteToTimeBuffer = false;
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
// Check the signals for each thread to determine the proper status
// for each thread.
template <class Impl>
bool
-DefaultFetch<Impl>::checkSignalsAndUpdate(unsigned tid)
+DefaultFetch<Impl>::checkSignalsAndUpdate(ThreadID tid)
{
// Update the per thread stall statuses.
if (fromDecode->decodeBlock[tid]) {
//////////////////////////////////////////
// Start actual fetch
//////////////////////////////////////////
- int tid = getFetchingThread(fetchPolicy);
+ ThreadID tid = getFetchingThread(fetchPolicy);
- if (tid == -1 || drainPending) {
+ if (tid == InvalidThreadID || drainPending) {
DPRINTF(Fetch,"There are no more threads available to fetch from.\n");
// Breaks looping condition in tick()
{
if (retryPkt != NULL) {
assert(cacheBlocked);
- assert(retryTid != -1);
+ assert(retryTid != InvalidThreadID);
assert(fetchStatus[retryTid] == IcacheWaitRetry);
if (icachePort->sendTiming(retryPkt)) {
fetchStatus[retryTid] = IcacheWaitResponse;
retryPkt = NULL;
- retryTid = -1;
+ retryTid = InvalidThreadID;
cacheBlocked = false;
}
} else {
- assert(retryTid == -1);
+ assert(retryTid == InvalidThreadID);
// Access has been squashed since it was sent out. Just clear
// the cache being blocked.
cacheBlocked = false;
// //
///////////////////////////////////////
template<class Impl>
-int
+ThreadID
DefaultFetch<Impl>::getFetchingThread(FetchPriority &fetch_priority)
{
if (numThreads > 1) {
return branchCount();
default:
- return -1;
+ return InvalidThreadID;
}
} else {
- std::list<unsigned>::iterator thread = activeThreads->begin();
+ list<ThreadID>::iterator thread = activeThreads->begin();
if (thread == activeThreads->end()) {
- return -1;
+ return InvalidThreadID;
}
- int tid = *thread;
+ ThreadID tid = *thread;
if (fetchStatus[tid] == Running ||
fetchStatus[tid] == IcacheAccessComplete ||
fetchStatus[tid] == Idle) {
return tid;
} else {
- return -1;
+ return InvalidThreadID;
}
}
-
}
template<class Impl>
-int
+ThreadID
DefaultFetch<Impl>::roundRobin()
{
- std::list<unsigned>::iterator pri_iter = priorityList.begin();
- std::list<unsigned>::iterator end = priorityList.end();
+ list<ThreadID>::iterator pri_iter = priorityList.begin();
+ list<ThreadID>::iterator end = priorityList.end();
- int high_pri;
+ ThreadID high_pri;
while (pri_iter != end) {
high_pri = *pri_iter;
pri_iter++;
}
- return -1;
+ return InvalidThreadID;
}
template<class Impl>
-int
+ThreadID
DefaultFetch<Impl>::iqCount()
{
- std::priority_queue<unsigned> PQ;
+ std::priority_queue<ThreadID> PQ;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
PQ.push(fromIEW->iewInfo[tid].iqCount);
}
while (!PQ.empty()) {
-
- unsigned high_pri = PQ.top();
+ ThreadID high_pri = PQ.top();
if (fetchStatus[high_pri] == Running ||
fetchStatus[high_pri] == IcacheAccessComplete ||
}
- return -1;
+ return InvalidThreadID;
}
template<class Impl>
-int
+ThreadID
DefaultFetch<Impl>::lsqCount()
{
- std::priority_queue<unsigned> PQ;
+ std::priority_queue<ThreadID> PQ;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
PQ.push(fromIEW->iewInfo[tid].ldstqCount);
}
while (!PQ.empty()) {
-
- unsigned high_pri = PQ.top();
+ ThreadID high_pri = PQ.top();
if (fetchStatus[high_pri] == Running ||
fetchStatus[high_pri] == IcacheAccessComplete ||
return high_pri;
else
PQ.pop();
-
}
- return -1;
+ return InvalidThreadID;
}
template<class Impl>
-int
+ThreadID
DefaultFetch<Impl>::branchCount()
{
- std::list<unsigned>::iterator thread = activeThreads->begin();
+#if 0
+ list<ThreadID>::iterator thread = activeThreads->begin();
assert(thread != activeThreads->end());
- unsigned tid = *thread;
+ ThreadID tid = *thread;
+#endif
panic("Branch Count Fetch policy unimplemented\n");
- return 0 * tid;
+ return InvalidThreadID;
}
#include "cpu/o3/free_list.hh"
-SimpleFreeList::SimpleFreeList(unsigned activeThreads,
+SimpleFreeList::SimpleFreeList(ThreadID activeThreads,
unsigned _numLogicalIntRegs,
unsigned _numPhysicalIntRegs,
unsigned _numLogicalFloatRegs,
* @param _numLogicalFloatRegs Number of logical fp registers.
* @param _numPhysicalFloatRegs Number of physical fp registers.
*/
- SimpleFreeList(unsigned activeThreads,
+ SimpleFreeList(ThreadID activeThreads,
unsigned _numLogicalIntRegs,
unsigned _numPhysicalIntRegs,
unsigned _numLogicalFloatRegs,
#ifndef __CPU_O3_IEW_HH__
#define __CPU_O3_IEW_HH__
-#include "config/full_system.hh"
-
#include <queue>
#include "base/statistics.hh"
#include "base/timebuf.hh"
+#include "config/full_system.hh"
#include "cpu/o3/comm.hh"
#include "cpu/o3/scoreboard.hh"
#include "cpu/o3/lsq.hh"
void setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr);
/** Sets pointer to list of active threads. */
- void setActiveThreads(std::list<unsigned> *at_ptr);
+ void setActiveThreads(std::list<ThreadID> *at_ptr);
/** Sets pointer to the scoreboard. */
void setScoreboard(Scoreboard *sb_ptr);
bool isSwitchedOut() { return switchedOut; }
/** Squashes instructions in IEW for a specific thread. */
- void squash(unsigned tid);
+ void squash(ThreadID tid);
/** Wakes all dependents of a completed instruction. */
void wakeDependents(DynInstPtr &inst);
void instToCommit(DynInstPtr &inst);
/** Inserts unused instructions of a thread into the skid buffer. */
- void skidInsert(unsigned tid);
+ void skidInsert(ThreadID tid);
/** Returns the max of the number of entries in all of the skid buffers. */
int skidCount();
bool hasStoresToWB() { return ldstQueue.hasStoresToWB(); }
/** Returns if the LSQ has any stores to writeback. */
- bool hasStoresToWB(unsigned tid) { return ldstQueue.hasStoresToWB(tid); }
+ bool hasStoresToWB(ThreadID tid) { return ldstQueue.hasStoresToWB(tid); }
void incrWb(InstSeqNum &sn)
{
/** Sends commit proper information for a squash due to a branch
* mispredict.
*/
- void squashDueToBranch(DynInstPtr &inst, unsigned thread_id);
+ void squashDueToBranch(DynInstPtr &inst, ThreadID tid);
/** Sends commit proper information for a squash due to a memory order
* violation.
*/
- void squashDueToMemOrder(DynInstPtr &inst, unsigned thread_id);
+ void squashDueToMemOrder(DynInstPtr &inst, ThreadID tid);
/** Sends commit proper information for a squash due to memory becoming
* blocked (younger issued instructions must be retried).
*/
- void squashDueToMemBlocked(DynInstPtr &inst, unsigned thread_id);
+ void squashDueToMemBlocked(DynInstPtr &inst, ThreadID tid);
/** Sets Dispatch to blocked, and signals back to other stages to block. */
- void block(unsigned thread_id);
+ void block(ThreadID tid);
/** Unblocks Dispatch if the skid buffer is empty, and signals back to
* other stages to unblock.
*/
- void unblock(unsigned thread_id);
+ void unblock(ThreadID tid);
/** Determines proper actions to take given Dispatch's status. */
- void dispatch(unsigned tid);
+ void dispatch(ThreadID tid);
/** Dispatches instructions to IQ and LSQ. */
- void dispatchInsts(unsigned tid);
+ void dispatchInsts(ThreadID tid);
/** Executes instructions. In the case of memory operations, it informs the
* LSQ to execute the instructions. Also handles any redirects that occur
unsigned validInstsFromRename();
/** Reads the stall signals. */
- void readStallSignals(unsigned tid);
+ void readStallSignals(ThreadID tid);
/** Checks if any of the stall conditions are currently true. */
- bool checkStall(unsigned tid);
+ bool checkStall(ThreadID tid);
/** Processes inputs and changes state accordingly. */
- void checkSignalsAndUpdate(unsigned tid);
+ void checkSignalsAndUpdate(ThreadID tid);
/** Removes instructions from rename from a thread's instruction list. */
- void emptyRenameInsts(unsigned tid);
+ void emptyRenameInsts(ThreadID tid);
/** Sorts instructions coming from rename into lists separated by thread. */
void sortInsts();
unsigned wbMax;
/** Number of active threads. */
- unsigned numThreads;
+ ThreadID numThreads;
/** Pointer to list of active threads. */
- std::list<unsigned> *activeThreads;
+ std::list<ThreadID> *activeThreads;
/** Maximum size of the skid buffer. */
unsigned skidBufferMax;
#include "cpu/o3/iew.hh"
#include "params/DerivO3CPU.hh"
+using namespace std;
+
template<class Impl>
DefaultIEW<Impl>::DefaultIEW(O3CPU *_cpu, DerivO3CPUParams *params)
: issueToExecQueue(params->backComSize, params->forwardComSize),
// Instruction queue needs the queue between issue and execute.
instQueue.setIssueToExecuteQueue(&issueToExecQueue);
- for (int i=0; i < numThreads; i++) {
- dispatchStatus[i] = Running;
- stalls[i].commit = false;
- fetchRedirect[i] = false;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ dispatchStatus[tid] = Running;
+ stalls[tid].commit = false;
+ fetchRedirect[tid] = false;
}
wbMax = wbWidth * params->wbDepth;
.desc("Number of executed instructions");
iewExecLoadInsts
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".iewExecLoadInsts")
.desc("Number of load instructions executed")
.flags(total);
.desc("Number of squashed instructions skipped in execute");
iewExecutedSwp
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".EXEC:swp")
.desc("number of swp insts executed")
.flags(total);
iewExecutedNop
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".EXEC:nop")
.desc("number of nop insts executed")
.flags(total);
iewExecutedRefs
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".EXEC:refs")
.desc("number of memory reference insts executed")
.flags(total);
iewExecutedBranches
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".EXEC:branches")
.desc("Number of branches executed")
.flags(total);
iewExecRate = iewExecutedInsts / cpu->numCycles;
iewInstsToCommit
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".WB:sent")
.desc("cumulative count of insts sent to commit")
.flags(total);
writebackCount
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".WB:count")
.desc("cumulative count of insts written-back")
.flags(total);
producerInst
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".WB:producers")
.desc("num instructions producing a value")
.flags(total);
consumerInst
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".WB:consumers")
.desc("num instructions consuming a value")
.flags(total);
wbPenalized
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".WB:penalized")
.desc("number of instrctions required to write to 'other' IQ")
.flags(total);
void
DefaultIEW<Impl>::initStage()
{
- for (int tid=0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
toRename->iewInfo[tid].usedIQ = true;
toRename->iewInfo[tid].freeIQEntries =
instQueue.numFreeEntries(tid);
template<class Impl>
void
-DefaultIEW<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
+DefaultIEW<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
{
activeThreads = at_ptr;
ldstQueue.switchOut();
fuPool->switchOut();
- for (int i = 0; i < numThreads; i++) {
- while (!insts[i].empty())
- insts[i].pop();
- while (!skidBuffer[i].empty())
- skidBuffer[i].pop();
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ while (!insts[tid].empty())
+ insts[tid].pop();
+ while (!skidBuffer[tid].empty())
+ skidBuffer[tid].pop();
}
}
initStage();
cpu->activityThisCycle();
- for (int i=0; i < numThreads; i++) {
- dispatchStatus[i] = Running;
- stalls[i].commit = false;
- fetchRedirect[i] = false;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ dispatchStatus[tid] = Running;
+ stalls[tid].commit = false;
+ fetchRedirect[tid] = false;
}
updateLSQNextCycle = false;
template<class Impl>
void
-DefaultIEW<Impl>::squash(unsigned tid)
+DefaultIEW<Impl>::squash(ThreadID tid)
{
- DPRINTF(IEW, "[tid:%i]: Squashing all instructions.\n",
- tid);
+ DPRINTF(IEW, "[tid:%i]: Squashing all instructions.\n", tid);
// Tell the IQ to start squashing.
instQueue.squash(tid);
template<class Impl>
void
-DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, unsigned tid)
+DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, ThreadID tid)
{
DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %#x "
"[sn:%i].\n", tid, inst->readPC(), inst->seqNum);
template<class Impl>
void
-DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid)
+DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, ThreadID tid)
{
DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, "
"PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
template<class Impl>
void
-DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid)
+DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, ThreadID tid)
{
DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, "
"PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
template<class Impl>
void
-DefaultIEW<Impl>::block(unsigned tid)
+DefaultIEW<Impl>::block(ThreadID tid)
{
DPRINTF(IEW, "[tid:%u]: Blocking.\n", tid);
template<class Impl>
void
-DefaultIEW<Impl>::unblock(unsigned tid)
+DefaultIEW<Impl>::unblock(ThreadID tid)
{
DPRINTF(IEW, "[tid:%i]: Reading instructions out of the skid "
"buffer %u.\n",tid, tid);
template<class Impl>
void
-DefaultIEW<Impl>::skidInsert(unsigned tid)
+DefaultIEW<Impl>::skidInsert(ThreadID tid)
{
DynInstPtr inst = NULL;
{
int max=0;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
unsigned thread_count = skidBuffer[tid].size();
if (max < thread_count)
max = thread_count;
bool
DefaultIEW<Impl>::skidsEmpty()
{
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (!skidBuffer[tid].empty())
return false;
{
bool any_unblocking = false;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (dispatchStatus[tid] == Unblocking) {
any_unblocking = true;
template <class Impl>
void
-DefaultIEW<Impl>::readStallSignals(unsigned tid)
+DefaultIEW<Impl>::readStallSignals(ThreadID tid)
{
if (fromCommit->commitBlock[tid]) {
stalls[tid].commit = true;
template <class Impl>
bool
-DefaultIEW<Impl>::checkStall(unsigned tid)
+DefaultIEW<Impl>::checkStall(ThreadID tid)
{
bool ret_val(false);
template <class Impl>
void
-DefaultIEW<Impl>::checkSignalsAndUpdate(unsigned tid)
+DefaultIEW<Impl>::checkSignalsAndUpdate(ThreadID tid)
{
// Check if there's a squash signal, squash if there is
// Check stall signals, block if there is.
{
int insts_from_rename = fromRename->size;
#ifdef DEBUG
- for (int i = 0; i < numThreads; i++)
- assert(insts[i].empty());
+ for (ThreadID tid = 0; tid < numThreads; tid++)
+ assert(insts[tid].empty());
#endif
for (int i = 0; i < insts_from_rename; ++i) {
insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]);
template <class Impl>
void
-DefaultIEW<Impl>::emptyRenameInsts(unsigned tid)
+DefaultIEW<Impl>::emptyRenameInsts(ThreadID tid)
{
DPRINTF(IEW, "[tid:%i]: Removing incoming rename instructions\n", tid);
template<class Impl>
void
-DefaultIEW<Impl>::dispatch(unsigned tid)
+DefaultIEW<Impl>::dispatch(ThreadID tid)
{
// If status is Running or idle,
// call dispatchInsts()
template <class Impl>
void
-DefaultIEW<Impl>::dispatchInsts(unsigned tid)
+DefaultIEW<Impl>::dispatchInsts(ThreadID tid)
{
// Obtain instructions from skid buffer if unblocking, or queue from rename
// otherwise.
wbNumInst = 0;
wbCycle = 0;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
fetchRedirect[tid] = false;
}
// This probably needs to prioritize the redirects if a different
// scheduler is used. Currently the scheduler schedules the oldest
// instruction first, so the branch resolution order will be correct.
- unsigned tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
if (!fetchRedirect[tid] ||
toCommit->squashedSeqNum[tid] > inst->seqNum) {
for (int inst_num = 0; inst_num < wbWidth &&
toCommit->insts[inst_num]; inst_num++) {
DynInstPtr inst = toCommit->insts[inst_num];
- int tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
DPRINTF(IEW, "Sending instructions to commit, [sn:%lli] PC %#x.\n",
inst->seqNum, inst->readPC());
// Free function units marked as being freed this cycle.
fuPool->processFreeUnits();
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
// Check stall and squash signals, dispatch any instructions.
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid);
threads = activeThreads->begin();
while (threads != end) {
- unsigned tid = (*threads++);
+ ThreadID tid = (*threads++);
DPRINTF(IEW,"Processing [tid:%i]\n",tid);
void
DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst)
{
- int thread_number = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
//
// Pick off the software prefetches
//
#ifdef TARGET_ALPHA
if (inst->isDataPrefetch())
- iewExecutedSwp[thread_number]++;
+ iewExecutedSwp[tid]++;
else
iewIewExecutedcutedInsts++;
#else
// Control operations
//
if (inst->isControl())
- iewExecutedBranches[thread_number]++;
+ iewExecutedBranches[tid]++;
//
// Memory operations
//
if (inst->isMemRef()) {
- iewExecutedRefs[thread_number]++;
+ iewExecutedRefs[tid]++;
if (inst->isLoad()) {
- iewExecLoadInsts[thread_number]++;
+ iewExecLoadInsts[tid]++;
}
}
}
void resetState();
/** Sets active threads list. */
- void setActiveThreads(std::list<unsigned> *at_ptr);
+ void setActiveThreads(std::list<ThreadID> *at_ptr);
/** Sets the timer buffer between issue and execute. */
void setIssueToExecuteQueue(TimeBuffer<IssueStruct> *i2eQueue);
bool isSwitchedOut() { return switchedOut; }
/** Number of entries needed for given amount of threads. */
- int entryAmount(int num_threads);
+ int entryAmount(ThreadID num_threads);
/** Resets max entries for all threads. */
void resetEntries();
unsigned numFreeEntries();
/** Returns number of free entries for a thread. */
- unsigned numFreeEntries(unsigned tid);
+ unsigned numFreeEntries(ThreadID tid);
/** Returns whether or not the IQ is full. */
bool isFull();
/** Returns whether or not the IQ is full for a specific thread. */
- bool isFull(unsigned tid);
+ bool isFull(ThreadID tid);
/** Returns if there are any ready instructions in the IQ. */
bool hasReadyInsts();
* Commits all instructions up to and including the given sequence number,
* for a specific thread.
*/
- void commit(const InstSeqNum &inst, unsigned tid = 0);
+ void commit(const InstSeqNum &inst, ThreadID tid = 0);
/** Wakes all dependents of a completed instruction. */
int wakeDependents(DynInstPtr &completed_inst);
* Squashes instructions for a thread. Squashing information is obtained
* from the time buffer.
*/
- void squash(unsigned tid);
+ void squash(ThreadID tid);
/** Returns the number of used entries for a thread. */
- unsigned getCount(unsigned tid) { return count[tid]; };
+ unsigned getCount(ThreadID tid) { return count[tid]; };
/** Debug function to print all instructions. */
void printInsts();
private:
/** Does the actual squashing. */
- void doSquash(unsigned tid);
+ void doSquash(ThreadID tid);
/////////////////////////
// Various pointers
IQPolicy iqPolicy;
/** Number of Total Threads*/
- unsigned numThreads;
+ ThreadID numThreads;
/** Pointer to list of active threads. */
- std::list<unsigned> *activeThreads;
+ std::list<ThreadID> *activeThreads;
/** Per Thread IQ count */
unsigned count[Impl::MaxThreads];
#include "cpu/o3/fu_pool.hh"
#include "cpu/o3/inst_queue.hh"
#include "enums/OpClass.hh"
+#include "params/DerivO3CPU.hh"
#include "sim/core.hh"
-#include "params/DerivO3CPU.hh"
+using namespace std;
template <class Impl>
InstructionQueue<Impl>::FUCompletion::FUCompletion(DynInstPtr &_inst,
regScoreboard.resize(numPhysRegs);
//Initialize Mem Dependence Units
- for (int i = 0; i < numThreads; i++) {
- memDepUnit[i].init(params,i);
- memDepUnit[i].setIQ(this);
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ memDepUnit[tid].init(params, tid);
+ memDepUnit[tid].setIQ(this);
}
resetState();
iqPolicy = Dynamic;
//Set Max Entries to Total ROB Capacity
- for (int i = 0; i < numThreads; i++) {
- maxEntries[i] = numEntries;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ maxEntries[tid] = numEntries;
}
} else if (policy == "partitioned") {
int part_amt = numEntries / numThreads;
//Divide ROB up evenly
- for (int i = 0; i < numThreads; i++) {
- maxEntries[i] = part_amt;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ maxEntries[tid] = part_amt;
}
DPRINTF(IQ, "IQ sharing policy set to Partitioned:"
int thresholdIQ = (int)((double)threshold * numEntries);
//Divide up by threshold amount
- for (int i = 0; i < numThreads; i++) {
- maxEntries[i] = thresholdIQ;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ maxEntries[tid] = thresholdIQ;
}
DPRINTF(IQ, "IQ sharing policy set to Threshold:"
;
fuBusyRate = fuBusy / iqInstsIssued;
- for ( int i=0; i < numThreads; i++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
// Tell mem dependence unit to reg stats as well.
- memDepUnit[i].regStats();
+ memDepUnit[tid].regStats();
}
}
InstructionQueue<Impl>::resetState()
{
//Initialize thread IQ counts
- for (int i = 0; i <numThreads; i++) {
- count[i] = 0;
- instList[i].clear();
+ for (ThreadID tid = 0; tid <numThreads; tid++) {
+ count[tid] = 0;
+ instList[tid].clear();
}
// Initialize the number of free IQ entries.
regScoreboard[i] = false;
}
- for (int i = 0; i < numThreads; ++i) {
- squashedSeqNum[i] = 0;
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
+ squashedSeqNum[tid] = 0;
}
for (int i = 0; i < Num_OpClasses; ++i) {
template <class Impl>
void
-InstructionQueue<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
+InstructionQueue<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
{
activeThreads = at_ptr;
}
dependGraph.reset();
instsToExecute.clear();
switchedOut = true;
- for (int i = 0; i < numThreads; ++i) {
- memDepUnit[i].switchOut();
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
+ memDepUnit[tid].switchOut();
}
}
template <class Impl>
int
-InstructionQueue<Impl>::entryAmount(int num_threads)
+InstructionQueue<Impl>::entryAmount(ThreadID num_threads)
{
if (iqPolicy == Partitioned) {
return numEntries / num_threads;
if (iqPolicy != Dynamic || numThreads > 1) {
int active_threads = activeThreads->size();
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (iqPolicy == Partitioned) {
maxEntries[tid] = numEntries / active_threads;
template <class Impl>
unsigned
-InstructionQueue<Impl>::numFreeEntries(unsigned tid)
+InstructionQueue<Impl>::numFreeEntries(ThreadID tid)
{
return maxEntries[tid] - count[tid];
}
template <class Impl>
bool
-InstructionQueue<Impl>::isFull(unsigned tid)
+InstructionQueue<Impl>::isFull(ThreadID tid)
{
if (numFreeEntries(tid) == 0) {
return(true);
int idx = -2;
int op_latency = 1;
- int tid = issuing_inst->threadNumber;
+ ThreadID tid = issuing_inst->threadNumber;
if (op_class != No_OpClass) {
idx = fuPool->getUnit(op_class);
assert(inst_it != nonSpecInsts.end());
- unsigned tid = (*inst_it).second->threadNumber;
+ ThreadID tid = (*inst_it).second->threadNumber;
(*inst_it).second->setAtCommit();
template <class Impl>
void
-InstructionQueue<Impl>::commit(const InstSeqNum &inst, unsigned tid)
+InstructionQueue<Impl>::commit(const InstSeqNum &inst, ThreadID tid)
{
DPRINTF(IQ, "[tid:%i]: Committing instructions older than [sn:%i]\n",
tid,inst);
void
InstructionQueue<Impl>::completeMemInst(DynInstPtr &completed_inst)
{
- int tid = completed_inst->threadNumber;
+ ThreadID tid = completed_inst->threadNumber;
DPRINTF(IQ, "Completing mem instruction PC:%#x [sn:%lli]\n",
completed_inst->readPC(), completed_inst->seqNum);
template <class Impl>
void
-InstructionQueue<Impl>::squash(unsigned tid)
+InstructionQueue<Impl>::squash(ThreadID tid)
{
DPRINTF(IQ, "[tid:%i]: Starting to squash instructions in "
"the IQ.\n", tid);
template <class Impl>
void
-InstructionQueue<Impl>::doSquash(unsigned tid)
+InstructionQueue<Impl>::doSquash(ThreadID tid)
{
// Start at the tail.
ListIt squash_it = instList[tid].end();
// Change the #if if you want to use this method.
int total_insts = 0;
- for (int i = 0; i < numThreads; ++i) {
- ListIt count_it = instList[i].begin();
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
+ ListIt count_it = instList[tid].begin();
- while (count_it != instList[i].end()) {
+ while (count_it != instList[tid].end()) {
if (!(*count_it)->isSquashed() && !(*count_it)->isSquashedInIQ()) {
if (!(*count_it)->isIssued()) {
++total_insts;
void
InstructionQueue<Impl>::dumpInsts()
{
- for (int i = 0; i < numThreads; ++i) {
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
int num = 0;
int valid_num = 0;
- ListIt inst_list_it = instList[i].begin();
+ ListIt inst_list_it = instList[tid].begin();
- while (inst_list_it != instList[i].end())
- {
- cprintf("Instruction:%i\n",
- num);
+ while (inst_list_it != instList[tid].end()) {
+ cprintf("Instruction:%i\n", num);
if (!(*inst_list_it)->isSquashed()) {
if (!(*inst_list_it)->isIssued()) {
++valid_num;
Port *getDcachePort() { return &dcachePort; }
/** Sets the pointer to the list of active threads. */
- void setActiveThreads(std::list<unsigned> *at_ptr);
+ void setActiveThreads(std::list<ThreadID> *at_ptr);
/** Switches out the LSQ. */
void switchOut();
/** Takes over execution from another CPU's thread. */
void takeOverFrom();
/** Number of entries needed for the given amount of threads.*/
- int entryAmount(int num_threads);
- void removeEntries(unsigned tid);
+ int entryAmount(ThreadID num_threads);
+ void removeEntries(ThreadID tid);
/** Reset the max entries for each thread. */
void resetEntries();
/** Resize the max entries for a thread. */
- void resizeEntries(unsigned size, unsigned tid);
+ void resizeEntries(unsigned size, ThreadID tid);
/** Ticks the LSQ. */
void tick();
/** Ticks a specific LSQ Unit. */
- void tick(unsigned tid)
+ void tick(ThreadID tid)
{ thread[tid].tick(); }
/** Inserts a load into the LSQ. */
/**
* Commits loads up until the given sequence number for a specific thread.
*/
- void commitLoads(InstSeqNum &youngest_inst, unsigned tid)
+ void commitLoads(InstSeqNum &youngest_inst, ThreadID tid)
{ thread[tid].commitLoads(youngest_inst); }
/**
* Commits stores up until the given sequence number for a specific thread.
*/
- void commitStores(InstSeqNum &youngest_inst, unsigned tid)
+ void commitStores(InstSeqNum &youngest_inst, ThreadID tid)
{ thread[tid].commitStores(youngest_inst); }
/**
*/
void writebackStores();
/** Same as above, but only for one thread. */
- void writebackStores(unsigned tid);
+ void writebackStores(ThreadID tid);
/**
* Squash instructions from a thread until the specified sequence number.
*/
- void squash(const InstSeqNum &squashed_num, unsigned tid)
+ void squash(const InstSeqNum &squashed_num, ThreadID tid)
{ thread[tid].squash(squashed_num); }
/** Returns whether or not there was a memory ordering violation. */
* Returns whether or not there was a memory ordering violation for a
* specific thread.
*/
- bool violation(unsigned tid)
+ bool violation(ThreadID tid)
{ return thread[tid].violation(); }
/** Returns if a load is blocked due to the memory system for a specific
* thread.
*/
- bool loadBlocked(unsigned tid)
+ bool loadBlocked(ThreadID tid)
{ return thread[tid].loadBlocked(); }
- bool isLoadBlockedHandled(unsigned tid)
+ bool isLoadBlockedHandled(ThreadID tid)
{ return thread[tid].isLoadBlockedHandled(); }
- void setLoadBlockedHandled(unsigned tid)
+ void setLoadBlockedHandled(ThreadID tid)
{ thread[tid].setLoadBlockedHandled(); }
/** Gets the instruction that caused the memory ordering violation. */
- DynInstPtr getMemDepViolator(unsigned tid)
+ DynInstPtr getMemDepViolator(ThreadID tid)
{ return thread[tid].getMemDepViolator(); }
/** Returns the head index of the load queue for a specific thread. */
- int getLoadHead(unsigned tid)
+ int getLoadHead(ThreadID tid)
{ return thread[tid].getLoadHead(); }
/** Returns the sequence number of the head of the load queue. */
- InstSeqNum getLoadHeadSeqNum(unsigned tid)
+ InstSeqNum getLoadHeadSeqNum(ThreadID tid)
{
return thread[tid].getLoadHeadSeqNum();
}
/** Returns the head index of the store queue. */
- int getStoreHead(unsigned tid)
+ int getStoreHead(ThreadID tid)
{ return thread[tid].getStoreHead(); }
/** Returns the sequence number of the head of the store queue. */
- InstSeqNum getStoreHeadSeqNum(unsigned tid)
+ InstSeqNum getStoreHeadSeqNum(ThreadID tid)
{
return thread[tid].getStoreHeadSeqNum();
}
/** Returns the number of instructions in all of the queues. */
int getCount();
/** Returns the number of instructions in the queues of one thread. */
- int getCount(unsigned tid)
+ int getCount(ThreadID tid)
{ return thread[tid].getCount(); }
/** Returns the total number of loads in the load queue. */
int numLoads();
/** Returns the total number of loads for a single thread. */
- int numLoads(unsigned tid)
+ int numLoads(ThreadID tid)
{ return thread[tid].numLoads(); }
/** Returns the total number of stores in the store queue. */
int numStores();
/** Returns the total number of stores for a single thread. */
- int numStores(unsigned tid)
+ int numStores(ThreadID tid)
{ return thread[tid].numStores(); }
/** Returns the total number of loads that are ready. */
int numLoadsReady();
/** Returns the number of loads that are ready for a single thread. */
- int numLoadsReady(unsigned tid)
+ int numLoadsReady(ThreadID tid)
{ return thread[tid].numLoadsReady(); }
/** Returns the number of free entries. */
unsigned numFreeEntries();
/** Returns the number of free entries for a specific thread. */
- unsigned numFreeEntries(unsigned tid);
+ unsigned numFreeEntries(ThreadID tid);
/** Returns if the LSQ is full (either LQ or SQ is full). */
bool isFull();
* Returns if the LSQ is full for a specific thread (either LQ or SQ is
* full).
*/
- bool isFull(unsigned tid);
+ bool isFull(ThreadID tid);
/** Returns if any of the LQs are full. */
bool lqFull();
/** Returns if the LQ of a given thread is full. */
- bool lqFull(unsigned tid);
+ bool lqFull(ThreadID tid);
/** Returns if any of the SQs are full. */
bool sqFull();
/** Returns if the SQ of a given thread is full. */
- bool sqFull(unsigned tid);
+ bool sqFull(ThreadID tid);
/**
* Returns if the LSQ is stalled due to a memory operation that must be
* Returns if the LSQ of a specific thread is stalled due to a memory
* operation that must be replayed.
*/
- bool isStalled(unsigned tid);
+ bool isStalled(ThreadID tid);
/** Returns whether or not there are any stores to write back to memory. */
bool hasStoresToWB();
/** Returns whether or not a specific thread has any stores to write back
* to memory.
*/
- bool hasStoresToWB(unsigned tid)
+ bool hasStoresToWB(ThreadID tid)
{ return thread[tid].hasStoresToWB(); }
/** Returns the number of stores a specific thread has to write back. */
- int numStoresToWB(unsigned tid)
+ int numStoresToWB(ThreadID tid)
{ return thread[tid].numStoresToWB(); }
/** Returns if the LSQ will write back to memory this cycle. */
/** Returns if the LSQ of a specific thread will write back to memory this
* cycle.
*/
- bool willWB(unsigned tid)
+ bool willWB(ThreadID tid)
{ return thread[tid].willWB(); }
/** Returns if the cache is currently blocked. */
bool cacheBlocked()
- { return retryTid != -1; }
+ { return retryTid != InvalidThreadID; }
/** Sets the retry thread id, indicating that one of the LSQUnits
* tried to access the cache but the cache was blocked. */
- void setRetryTid(int tid)
+ void setRetryTid(ThreadID tid)
{ retryTid = tid; }
/** Debugging function to print out all instructions. */
void dumpInsts();
/** Debugging function to print out instructions from a specific thread. */
- void dumpInsts(unsigned tid)
+ void dumpInsts(ThreadID tid)
{ thread[tid].dumpInsts(); }
/** Executes a read operation, using the load specified at the load index. */
LSQUnit thread[Impl::MaxThreads];
/** List of Active Threads in System. */
- std::list<unsigned> *activeThreads;
+ std::list<ThreadID> *activeThreads;
/** Total Size of LQ Entries. */
unsigned LQEntries;
unsigned maxSQEntries;
/** Number of Threads. */
- unsigned numThreads;
+ ThreadID numThreads;
/** The thread id of the LSQ Unit that is currently waiting for a
* retry. */
- int retryTid;
+ ThreadID retryTid;
};
template <class Impl>
Fault
LSQ<Impl>::read(RequestPtr req, T &data, int load_idx)
{
- unsigned tid = req->threadId();
+ ThreadID tid = req->threadId();
return thread[tid].read(req, data, load_idx);
}
Fault
LSQ<Impl>::write(RequestPtr req, T &data, int store_idx)
{
- unsigned tid = req->threadId();
+ ThreadID tid = req->threadId();
return thread[tid].write(req, data, store_idx);
}
#include <string>
#include "cpu/o3/lsq.hh"
-
#include "params/DerivO3CPU.hh"
+using namespace std;
+
template<class Impl>
void
LSQ<Impl>::DcachePort::setPeer(Port *port)
}
//Initialize LSQs
- for (int tid=0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
thread[tid].init(cpu, iew_ptr, params, this,
maxLQEntries, maxSQEntries, tid);
thread[tid].setDcachePort(&dcachePort);
LSQ<Impl>::regStats()
{
//Initialize LSQs
- for (int tid=0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
thread[tid].regStats();
}
}
template<class Impl>
void
-LSQ<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
+LSQ<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
{
activeThreads = at_ptr;
assert(activeThreads != 0);
void
LSQ<Impl>::switchOut()
{
- for (int tid = 0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
thread[tid].switchOut();
}
}
void
LSQ<Impl>::takeOverFrom()
{
- for (int tid = 0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
thread[tid].takeOverFrom();
}
}
template <class Impl>
int
-LSQ<Impl>::entryAmount(int num_threads)
+LSQ<Impl>::entryAmount(ThreadID num_threads)
{
if (lsqPolicy == Partitioned) {
return LQEntries / num_threads;
maxEntries = LQEntries;
}
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
resizeEntries(maxEntries, tid);
}
template<class Impl>
void
-LSQ<Impl>::removeEntries(unsigned tid)
+LSQ<Impl>::removeEntries(ThreadID tid)
{
thread[tid].clearLQ();
thread[tid].clearSQ();
template<class Impl>
void
-LSQ<Impl>::resizeEntries(unsigned size,unsigned tid)
+LSQ<Impl>::resizeEntries(unsigned size, ThreadID tid)
{
thread[tid].resizeLQ(size);
thread[tid].resizeSQ(size);
void
LSQ<Impl>::tick()
{
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
thread[tid].tick();
}
void
LSQ<Impl>::insertLoad(DynInstPtr &load_inst)
{
- unsigned tid = load_inst->threadNumber;
+ ThreadID tid = load_inst->threadNumber;
thread[tid].insertLoad(load_inst);
}
void
LSQ<Impl>::insertStore(DynInstPtr &store_inst)
{
- unsigned tid = store_inst->threadNumber;
+ ThreadID tid = store_inst->threadNumber;
thread[tid].insertStore(store_inst);
}
Fault
LSQ<Impl>::executeLoad(DynInstPtr &inst)
{
- unsigned tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
return thread[tid].executeLoad(inst);
}
Fault
LSQ<Impl>::executeStore(DynInstPtr &inst)
{
- unsigned tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
return thread[tid].executeStore(inst);
}
void
LSQ<Impl>::writebackStores()
{
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (numStoresToWB(tid) > 0) {
DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores "
LSQ<Impl>::violation()
{
/* Answers: Does Anybody Have a Violation?*/
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (thread[tid].violation())
return true;
{
unsigned total = 0;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
total += getCount(tid);
}
{
unsigned total = 0;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
total += numLoads(tid);
}
{
unsigned total = 0;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
total += thread[tid].numStores();
}
{
unsigned total = 0;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
total += thread[tid].numLoadsReady();
}
{
unsigned total = 0;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
total += thread[tid].numFreeEntries();
}
template<class Impl>
unsigned
-LSQ<Impl>::numFreeEntries(unsigned tid)
+LSQ<Impl>::numFreeEntries(ThreadID tid)
{
//if (lsqPolicy == Dynamic)
//return numFreeEntries();
bool
LSQ<Impl>::isFull()
{
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (!(thread[tid].lqFull() || thread[tid].sqFull()))
return false;
template<class Impl>
bool
-LSQ<Impl>::isFull(unsigned tid)
+LSQ<Impl>::isFull(ThreadID tid)
{
//@todo: Change to Calculate All Entries for
//Dynamic Policy
bool
LSQ<Impl>::lqFull()
{
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (!thread[tid].lqFull())
return false;
template<class Impl>
bool
-LSQ<Impl>::lqFull(unsigned tid)
+LSQ<Impl>::lqFull(ThreadID tid)
{
//@todo: Change to Calculate All Entries for
//Dynamic Policy
bool
LSQ<Impl>::sqFull()
{
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (!sqFull(tid))
return false;
template<class Impl>
bool
-LSQ<Impl>::sqFull(unsigned tid)
+LSQ<Impl>::sqFull(ThreadID tid)
{
//@todo: Change to Calculate All Entries for
//Dynamic Policy
bool
LSQ<Impl>::isStalled()
{
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (!thread[tid].isStalled())
return false;
template<class Impl>
bool
-LSQ<Impl>::isStalled(unsigned tid)
+LSQ<Impl>::isStalled(ThreadID tid)
{
if (lsqPolicy == Dynamic)
return isStalled();
bool
LSQ<Impl>::hasStoresToWB()
{
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (hasStoresToWB(tid))
return true;
bool
LSQ<Impl>::willWB()
{
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (willWB(tid))
return true;
void
LSQ<Impl>::dumpInsts()
{
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
thread[tid].dumpInsts();
}
private:
/** The LSQUnit thread id. */
- unsigned lsqID;
+ ThreadID lsqID;
/** The store queue. */
std::vector<SQEntry> storeQueue;
storePostSend(retryPkt);
retryPkt = NULL;
isStoreBlocked = false;
- lsq->setRetryTid(-1);
+ lsq->setRetryTid(InvalidThreadID);
} else {
// Still blocked!
++lsqCacheBlocked;
std::string name() const { return _name; }
/** Initializes the unit with parameters and a thread id. */
- void init(DerivO3CPUParams *params, int tid);
+ void init(DerivO3CPUParams *params, ThreadID tid);
/** Registers statistics. */
void regStats();
/** Squashes all instructions up until a given sequence number for a
* specific thread.
*/
- void squash(const InstSeqNum &squashed_num, unsigned tid);
+ void squash(const InstSeqNum &squashed_num, ThreadID tid);
/** Indicates an ordering violation between a store and a younger load. */
void violation(DynInstPtr &store_inst, DynInstPtr &violating_load);
template <class MemDepPred, class Impl>
MemDepUnit<MemDepPred, Impl>::~MemDepUnit()
{
- for (int tid=0; tid < Impl::MaxThreads; tid++) {
+ for (ThreadID tid = 0; tid < Impl::MaxThreads; tid++) {
ListIt inst_list_it = instList[tid].begin();
template <class MemDepPred, class Impl>
void
-MemDepUnit<MemDepPred, Impl>::init(DerivO3CPUParams *params, int tid)
+MemDepUnit<MemDepPred, Impl>::init(DerivO3CPUParams *params, ThreadID tid)
{
DPRINTF(MemDepUnit, "Creating MemDepUnit %i object.\n",tid);
void
MemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst)
{
- unsigned tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
MemDepEntryPtr inst_entry = new MemDepEntry(inst);
void
MemDepUnit<MemDepPred, Impl>::insertNonSpec(DynInstPtr &inst)
{
- unsigned tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
MemDepEntryPtr inst_entry = new MemDepEntry(inst);
DPRINTF(MemDepUnit, "Inserted a write barrier\n");
}
- unsigned tid = barr_inst->threadNumber;
+ ThreadID tid = barr_inst->threadNumber;
MemDepEntryPtr inst_entry = new MemDepEntry(barr_inst);
"[sn:%lli].\n",
inst->readPC(), inst->seqNum);
- unsigned tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
// Remove the instruction from the hash and the list.
MemDepHashIt hash_it = memDepHash.find(inst->seqNum);
template <class MemDepPred, class Impl>
void
MemDepUnit<MemDepPred, Impl>::squash(const InstSeqNum &squashed_num,
- unsigned tid)
+ ThreadID tid)
{
if (!instsToReplay.empty()) {
ListIt replay_it = instsToReplay.begin();
void
MemDepUnit<MemDepPred, Impl>::dumpLists()
{
- for (unsigned tid=0; tid < Impl::MaxThreads; tid++) {
+ for (ThreadID tid = 0; tid < Impl::MaxThreads; tid++) {
cprintf("Instruction list %i size: %i\n",
tid, instList[tid].size());
floatRegFile[reg_idx].q = val;
}
- MiscReg readMiscRegNoEffect(int misc_reg, unsigned thread_id)
+ MiscReg
+ readMiscRegNoEffect(int misc_reg, ThreadID tid)
{
- return miscRegs[thread_id].readRegNoEffect(misc_reg);
+ return miscRegs[tid].readRegNoEffect(misc_reg);
}
- MiscReg readMiscReg(int misc_reg, unsigned thread_id)
+ MiscReg
+ readMiscReg(int misc_reg, ThreadID tid)
{
- return miscRegs[thread_id].readReg(misc_reg, cpu->tcBase(thread_id));
+ return miscRegs[tid].readReg(misc_reg, cpu->tcBase(tid));
}
- void setMiscRegNoEffect(int misc_reg,
- const MiscReg &val, unsigned thread_id)
+ void
+ setMiscRegNoEffect(int misc_reg, const MiscReg &val, ThreadID tid)
{
- miscRegs[thread_id].setRegNoEffect(misc_reg, val);
+ miscRegs[tid].setRegNoEffect(misc_reg, val);
}
- void setMiscReg(int misc_reg, const MiscReg &val,
- unsigned thread_id)
+ void
+ setMiscReg(int misc_reg, const MiscReg &val, ThreadID tid)
{
- miscRegs[thread_id].setReg(misc_reg, val,
- cpu->tcBase(thread_id));
+ miscRegs[tid].setReg(misc_reg, val, cpu->tcBase(tid));
}
public:
void initStage();
/** Sets pointer to list of active threads. */
- void setActiveThreads(std::list<unsigned> *at_ptr);
+ void setActiveThreads(std::list<ThreadID> *at_ptr);
/** Sets pointer to rename maps (per-thread structures). */
void setRenameMap(RenameMap rm_ptr[Impl::MaxThreads]);
void takeOverFrom();
/** Squashes all instructions in a thread. */
- void squash(const InstSeqNum &squash_seq_num, unsigned tid);
+ void squash(const InstSeqNum &squash_seq_num, ThreadID tid);
/** Ticks rename, which processes all input signals and attempts to rename
* as many instructions as possible.
* change (ie switching from blocking to unblocking).
* @param tid Thread id to rename instructions from.
*/
- void rename(bool &status_change, unsigned tid);
+ void rename(bool &status_change, ThreadID tid);
/** Renames instructions for the given thread. Also handles serializing
* instructions.
*/
- void renameInsts(unsigned tid);
+ void renameInsts(ThreadID tid);
/** Inserts unused instructions from a given thread into the skid buffer,
* to be renamed once rename unblocks.
*/
- void skidInsert(unsigned tid);
+ void skidInsert(ThreadID tid);
/** Separates instructions from decode into individual lists of instructions
* sorted by thread.
* blocked.
* @return Returns true if there is a status change.
*/
- bool block(unsigned tid);
+ bool block(ThreadID tid);
/** Switches rename to unblocking if the skid buffer is empty, and signals
* back that rename has unblocked.
* @return Returns true if there is a status change.
*/
- bool unblock(unsigned tid);
+ bool unblock(ThreadID tid);
/** Executes actual squash, removing squashed instructions. */
- void doSquash(const InstSeqNum &squash_seq_num, unsigned tid);
+ void doSquash(const InstSeqNum &squash_seq_num, ThreadID tid);
/** Removes a committed instruction's rename history. */
- void removeFromHistory(InstSeqNum inst_seq_num, unsigned tid);
+ void removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid);
/** Renames the source registers of an instruction. */
- inline void renameSrcRegs(DynInstPtr &inst, unsigned tid);
+ inline void renameSrcRegs(DynInstPtr &inst, ThreadID tid);
/** Renames the destination registers of an instruction. */
- inline void renameDestRegs(DynInstPtr &inst, unsigned tid);
+ inline void renameDestRegs(DynInstPtr &inst, ThreadID tid);
/** Calculates the number of free ROB entries for a specific thread. */
- inline int calcFreeROBEntries(unsigned tid);
+ inline int calcFreeROBEntries(ThreadID tid);
/** Calculates the number of free IQ entries for a specific thread. */
- inline int calcFreeIQEntries(unsigned tid);
+ inline int calcFreeIQEntries(ThreadID tid);
/** Calculates the number of free LSQ entries for a specific thread. */
- inline int calcFreeLSQEntries(unsigned tid);
+ inline int calcFreeLSQEntries(ThreadID tid);
/** Returns the number of valid instructions coming from decode. */
unsigned validInsts();
/** Reads signals telling rename to block/unblock. */
- void readStallSignals(unsigned tid);
+ void readStallSignals(ThreadID tid);
/** Checks if any stages are telling rename to block. */
- bool checkStall(unsigned tid);
+ bool checkStall(ThreadID tid);
/** Gets the number of free entries for a specific thread. */
- void readFreeEntries(unsigned tid);
+ void readFreeEntries(ThreadID tid);
/** Checks the signals and updates the status. */
- bool checkSignalsAndUpdate(unsigned tid);
+ bool checkSignalsAndUpdate(ThreadID tid);
/** Either serializes on the next instruction available in the InstQueue,
* or records that it must serialize on the next instruction to enter
* thread that has the serializeAfter instruction.
* @param tid The thread id.
*/
- void serializeAfter(InstQueue &inst_list, unsigned tid);
+ void serializeAfter(InstQueue &inst_list, ThreadID tid);
/** Holds the information for each destination register rename. It holds
* the instruction's sequence number, the arch register, the old physical
FreeList *freeList;
/** Pointer to the list of active threads. */
- std::list<unsigned> *activeThreads;
+ std::list<ThreadID> *activeThreads;
/** Pointer to the scoreboard. */
Scoreboard *scoreboard;
bool resumeUnblocking;
/** The number of threads active in rename. */
- unsigned numThreads;
+ ThreadID numThreads;
/** The maximum skid buffer size. */
unsigned skidBufferMax;
#include "cpu/o3/rename.hh"
#include "params/DerivO3CPU.hh"
+using namespace std;
+
template <class Impl>
DefaultRename<Impl>::DefaultRename(O3CPU *_cpu, DerivO3CPUParams *params)
: cpu(_cpu),
{
_status = Inactive;
- for (int i=0; i< numThreads; i++) {
- renameStatus[i] = Idle;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ renameStatus[tid] = Idle;
- freeEntries[i].iqEntries = 0;
- freeEntries[i].lsqEntries = 0;
- freeEntries[i].robEntries = 0;
+ freeEntries[tid].iqEntries = 0;
+ freeEntries[tid].lsqEntries = 0;
+ freeEntries[tid].robEntries = 0;
- stalls[i].iew = false;
- stalls[i].commit = false;
- serializeInst[i] = NULL;
+ stalls[tid].iew = false;
+ stalls[tid].commit = false;
+ serializeInst[tid] = NULL;
- instsInProgress[i] = 0;
+ instsInProgress[tid] = 0;
- emptyROB[i] = true;
+ emptyROB[tid] = true;
- serializeOnNextInst[i] = false;
+ serializeOnNextInst[tid] = false;
}
// @todo: Make into a parameter.
DefaultRename<Impl>::initStage()
{
// Grab the number of free entries directly from the stages.
- for (int tid=0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
freeEntries[tid].iqEntries = iew_ptr->instQueue.numFreeEntries(tid);
freeEntries[tid].lsqEntries = iew_ptr->ldstQueue.numFreeEntries(tid);
freeEntries[tid].robEntries = commit_ptr->numROBFreeEntries(tid);
template<class Impl>
void
-DefaultRename<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
+DefaultRename<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
{
activeThreads = at_ptr;
}
void
DefaultRename<Impl>::setRenameMap(RenameMap rm_ptr[])
{
- for (int i=0; i<numThreads; i++) {
- renameMap[i] = &rm_ptr[i];
- }
+ for (ThreadID tid = 0; tid < numThreads; tid++)
+ renameMap[tid] = &rm_ptr[tid];
}
template <class Impl>
DefaultRename<Impl>::switchOut()
{
// Clear any state, fix up the rename map.
- for (int i = 0; i < numThreads; i++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
typename std::list<RenameHistory>::iterator hb_it =
- historyBuffer[i].begin();
+ historyBuffer[tid].begin();
- while (!historyBuffer[i].empty()) {
- assert(hb_it != historyBuffer[i].end());
+ while (!historyBuffer[tid].empty()) {
+ assert(hb_it != historyBuffer[tid].end());
DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence "
- "number %i.\n", i, (*hb_it).instSeqNum);
+ "number %i.\n", tid, (*hb_it).instSeqNum);
// Tell the rename map to set the architected register to the
// previous physical register that it was renamed to.
- renameMap[i]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
+ renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
// Put the renamed physical register back on the free list.
freeList->addReg(hb_it->newPhysReg);
scoreboard->setReg(hb_it->newPhysReg);
}
- historyBuffer[i].erase(hb_it++);
+ historyBuffer[tid].erase(hb_it++);
}
- insts[i].clear();
- skidBuffer[i].clear();
+ insts[tid].clear();
+ skidBuffer[tid].clear();
}
}
initStage();
// Reset all state prior to taking over from the other CPU.
- for (int i=0; i< numThreads; i++) {
- renameStatus[i] = Idle;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ renameStatus[tid] = Idle;
- stalls[i].iew = false;
- stalls[i].commit = false;
- serializeInst[i] = NULL;
+ stalls[tid].iew = false;
+ stalls[tid].commit = false;
+ serializeInst[tid] = NULL;
- instsInProgress[i] = 0;
+ instsInProgress[tid] = 0;
- emptyROB[i] = true;
+ emptyROB[tid] = true;
- serializeOnNextInst[i] = false;
+ serializeOnNextInst[tid] = false;
}
}
template <class Impl>
void
-DefaultRename<Impl>::squash(const InstSeqNum &squash_seq_num, unsigned tid)
+DefaultRename<Impl>::squash(const InstSeqNum &squash_seq_num, ThreadID tid)
{
DPRINTF(Rename, "[tid:%u]: Squashing instructions.\n",tid);
sortInsts();
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
// Check stall and squash signals.
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
DPRINTF(Rename, "Processing [tid:%i]\n", tid);
threads = activeThreads->begin();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
// If we committed this cycle then doneSeqNum will be > 0
if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
}
// @todo: make into updateProgress function
- for (int tid=0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
instsInProgress[tid] -= fromIEW->iewInfo[tid].dispatched;
assert(instsInProgress[tid] >=0);
template<class Impl>
void
-DefaultRename<Impl>::rename(bool &status_change, unsigned tid)
+DefaultRename<Impl>::rename(bool &status_change, ThreadID tid)
{
// If status is Running or idle,
// call renameInsts()
template <class Impl>
void
-DefaultRename<Impl>::renameInsts(unsigned tid)
+DefaultRename<Impl>::renameInsts(ThreadID tid)
{
// Instructions can be either in the skid buffer or the queue of
// instructions coming from decode, depending on the status.
template<class Impl>
void
-DefaultRename<Impl>::skidInsert(unsigned tid)
+DefaultRename<Impl>::skidInsert(ThreadID tid)
{
DynInstPtr inst = NULL;
{
int insts_from_decode = fromDecode->size;
#ifdef DEBUG
- for (int i=0; i < numThreads; i++)
- assert(insts[i].empty());
+ for (ThreadID tid = 0; tid < numThreads; tid++)
+ assert(insts[tid].empty());
#endif
for (int i = 0; i < insts_from_decode; ++i) {
DynInstPtr inst = fromDecode->insts[i];
bool
DefaultRename<Impl>::skidsEmpty()
{
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (!skidBuffer[tid].empty())
return false;
{
bool any_unblocking = false;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (renameStatus[tid] == Unblocking) {
any_unblocking = true;
template <class Impl>
bool
-DefaultRename<Impl>::block(unsigned tid)
+DefaultRename<Impl>::block(ThreadID tid)
{
DPRINTF(Rename, "[tid:%u]: Blocking.\n", tid);
template <class Impl>
bool
-DefaultRename<Impl>::unblock(unsigned tid)
+DefaultRename<Impl>::unblock(ThreadID tid)
{
DPRINTF(Rename, "[tid:%u]: Trying to unblock.\n", tid);
template <class Impl>
void
-DefaultRename<Impl>::doSquash(const InstSeqNum &squashed_seq_num, unsigned tid)
+DefaultRename<Impl>::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid)
{
typename std::list<RenameHistory>::iterator hb_it =
historyBuffer[tid].begin();
template<class Impl>
void
-DefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, unsigned tid)
+DefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid)
{
DPRINTF(Rename, "[tid:%u]: Removing a committed instruction from the "
"history buffer %u (size=%i), until [sn:%lli].\n",
template <class Impl>
inline void
-DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst,unsigned tid)
+DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
{
assert(renameMap[tid] != 0);
template <class Impl>
inline void
-DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst,unsigned tid)
+DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid)
{
typename RenameMap::RenameInfo rename_result;
template <class Impl>
inline int
-DefaultRename<Impl>::calcFreeROBEntries(unsigned tid)
+DefaultRename<Impl>::calcFreeROBEntries(ThreadID tid)
{
int num_free = freeEntries[tid].robEntries -
(instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
template <class Impl>
inline int
-DefaultRename<Impl>::calcFreeIQEntries(unsigned tid)
+DefaultRename<Impl>::calcFreeIQEntries(ThreadID tid)
{
int num_free = freeEntries[tid].iqEntries -
(instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
template <class Impl>
inline int
-DefaultRename<Impl>::calcFreeLSQEntries(unsigned tid)
+DefaultRename<Impl>::calcFreeLSQEntries(ThreadID tid)
{
int num_free = freeEntries[tid].lsqEntries -
(instsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLSQ);
template <class Impl>
void
-DefaultRename<Impl>::readStallSignals(unsigned tid)
+DefaultRename<Impl>::readStallSignals(ThreadID tid)
{
if (fromIEW->iewBlock[tid]) {
stalls[tid].iew = true;
template <class Impl>
bool
-DefaultRename<Impl>::checkStall(unsigned tid)
+DefaultRename<Impl>::checkStall(ThreadID tid)
{
bool ret_val = false;
template <class Impl>
void
-DefaultRename<Impl>::readFreeEntries(unsigned tid)
+DefaultRename<Impl>::readFreeEntries(ThreadID tid)
{
bool updated = false;
if (fromIEW->iewInfo[tid].usedIQ) {
template <class Impl>
bool
-DefaultRename<Impl>::checkSignalsAndUpdate(unsigned tid)
+DefaultRename<Impl>::checkSignalsAndUpdate(ThreadID tid)
{
// Check if there's a squash signal, squash if there is
// Check stall signals, block if necessary.
template<class Impl>
void
-DefaultRename<Impl>::serializeAfter(InstQueue &inst_list,
- unsigned tid)
+DefaultRename<Impl>::serializeAfter(InstQueue &inst_list, ThreadID tid)
{
if (inst_list.empty()) {
// Mark a bit to say that I must serialize on the next instruction.
{
typename std::list<RenameHistory>::iterator buf_it;
- for (int i = 0; i < numThreads; i++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
- buf_it = historyBuffer[i].begin();
+ buf_it = historyBuffer[tid].begin();
- while (buf_it != historyBuffer[i].end()) {
+ while (buf_it != historyBuffer[tid].end()) {
cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys "
"reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg,
(int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg);
*/
ROB(O3CPU *_cpu, unsigned _numEntries, unsigned _squashWidth,
std::string smtROBPolicy, unsigned _smtROBThreshold,
- unsigned _numThreads);
+ ThreadID _numThreads);
std::string name() const;
/** Sets pointer to the list of active threads.
* @param at_ptr Pointer to the list of active threads.
*/
- void setActiveThreads(std::list<unsigned>* at_ptr);
+ void setActiveThreads(std::list<ThreadID> *at_ptr);
/** Switches out the ROB. */
void switchOut();
* the ROB.
* @return Pointer to the DynInst that is at the head of the ROB.
*/
- DynInstPtr readHeadInst(unsigned tid);
+ DynInstPtr readHeadInst(ThreadID tid);
/** Returns pointer to the tail instruction within the ROB. There is
* no guarantee as to the return value if the ROB is empty.
* the ROB.
* @return Pointer to the DynInst that is at the tail of the ROB.
*/
- DynInstPtr readTailInst(unsigned tid);
+ DynInstPtr readTailInst(ThreadID tid);
/** Retires the head instruction, removing it from the ROB. */
// void retireHead();
/** Retires the head instruction of a specific thread, removing it from the
* ROB.
*/
- void retireHead(unsigned tid);
+ void retireHead(ThreadID tid);
/** Is the oldest instruction across all threads ready. */
// bool isHeadReady();
/** Is the oldest instruction across a particular thread ready. */
- bool isHeadReady(unsigned tid);
+ bool isHeadReady(ThreadID tid);
/** Is there any commitable head instruction across all threads ready. */
bool canCommit();
void resetEntries();
/** Number of entries needed For 'num_threads' amount of threads. */
- int entryAmount(int num_threads);
+ int entryAmount(ThreadID num_threads);
/** Returns the number of total free entries in the ROB. */
unsigned numFreeEntries();
/** Returns the number of free entries in a specific ROB paritition. */
- unsigned numFreeEntries(unsigned tid);
+ unsigned numFreeEntries(ThreadID tid);
/** Returns the maximum number of entries for a specific thread. */
- unsigned getMaxEntries(unsigned tid)
+ unsigned getMaxEntries(ThreadID tid)
{ return maxEntries[tid]; }
/** Returns the number of entries being used by a specific thread. */
- unsigned getThreadEntries(unsigned tid)
+ unsigned getThreadEntries(ThreadID tid)
{ return threadEntries[tid]; }
/** Returns if the ROB is full. */
{ return numInstsInROB == numEntries; }
/** Returns if a specific thread's partition is full. */
- bool isFull(unsigned tid)
+ bool isFull(ThreadID tid)
{ return threadEntries[tid] == numEntries; }
/** Returns if the ROB is empty. */
{ return numInstsInROB == 0; }
/** Returns if a specific thread's partition is empty. */
- bool isEmpty(unsigned tid)
+ bool isEmpty(ThreadID tid)
{ return threadEntries[tid] == 0; }
/** Executes the squash, marking squashed instructions. */
- void doSquash(unsigned tid);
+ void doSquash(ThreadID tid);
/** Squashes all instructions younger than the given sequence number for
* the specific thread.
*/
- void squash(InstSeqNum squash_num, unsigned tid);
+ void squash(InstSeqNum squash_num, ThreadID tid);
/** Updates the head instruction with the new oldest instruction. */
void updateHead();
// uint64_t readHeadPC();
/** Reads the PC of the head instruction of a specific thread. */
-// uint64_t readHeadPC(unsigned tid);
+// uint64_t readHeadPC(ThreadID tid);
/** Reads the next PC of the oldest head instruction. */
// uint64_t readHeadNextPC();
/** Reads the next PC of the head instruction of a specific thread. */
-// uint64_t readHeadNextPC(unsigned tid);
+// uint64_t readHeadNextPC(ThreadID tid);
/** Reads the sequence number of the oldest head instruction. */
// InstSeqNum readHeadSeqNum();
/** Reads the sequence number of the head instruction of a specific thread.
*/
-// InstSeqNum readHeadSeqNum(unsigned tid);
+// InstSeqNum readHeadSeqNum(ThreadID tid);
/** Reads the PC of the youngest tail instruction. */
// uint64_t readTailPC();
/** Reads the PC of the tail instruction of a specific thread. */
-// uint64_t readTailPC(unsigned tid);
+// uint64_t readTailPC(ThreadID tid);
/** Reads the sequence number of the youngest tail instruction. */
// InstSeqNum readTailSeqNum();
/** Reads the sequence number of tail instruction of a specific thread. */
-// InstSeqNum readTailSeqNum(unsigned tid);
+// InstSeqNum readTailSeqNum(ThreadID tid);
/** Checks if the ROB is still in the process of squashing instructions.
* @retval Whether or not the ROB is done squashing.
*/
- bool isDoneSquashing(unsigned tid) const
+ bool isDoneSquashing(ThreadID tid) const
{ return doneSquashing[tid]; }
/** Checks if the ROB is still in the process of squashing instructions for
* threadEntries to get the instructions in the ROB unless you are
* double checking that variable.
*/
- int countInsts(unsigned tid);
+ int countInsts(ThreadID tid);
private:
/** Pointer to the CPU. */
O3CPU *cpu;
/** Active Threads in CPU */
- std::list<unsigned>* activeThreads;
+ std::list<ThreadID> *activeThreads;
/** Number of instructions in the ROB. */
unsigned numEntries;
bool doneSquashing[Impl::MaxThreads];
/** Number of active threads. */
- unsigned numThreads;
+ ThreadID numThreads;
};
#endif //__CPU_O3_ROB_HH__
* Korey Sewell
*/
+#include <list>
+
#include "config/full_system.hh"
#include "cpu/o3/rob.hh"
-#include <list>
+using namespace std;
template <class Impl>
ROB<Impl>::ROB(O3CPU *_cpu, unsigned _numEntries, unsigned _squashWidth,
std::string _smtROBPolicy, unsigned _smtROBThreshold,
- unsigned _numThreads)
+ ThreadID _numThreads)
: cpu(_cpu),
numEntries(_numEntries),
squashWidth(_squashWidth),
numInstsInROB(0),
numThreads(_numThreads)
{
- for (int tid=0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
squashedSeqNum[tid] = 0;
doneSquashing[tid] = true;
threadEntries[tid] = 0;
robPolicy = Dynamic;
//Set Max Entries to Total ROB Capacity
- for (int i = 0; i < numThreads; i++) {
- maxEntries[i]=numEntries;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ maxEntries[tid] = numEntries;
}
} else if (policy == "partitioned") {
int part_amt = numEntries / numThreads;
//Divide ROB up evenly
- for (int i = 0; i < numThreads; i++) {
- maxEntries[i]=part_amt;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ maxEntries[tid] = part_amt;
}
} else if (policy == "threshold") {
int threshold = _smtROBThreshold;;
//Divide up by threshold amount
- for (int i = 0; i < numThreads; i++) {
- maxEntries[i]=threshold;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ maxEntries[tid] = threshold;
}
} else {
assert(0 && "Invalid ROB Sharing Policy.Options Are:{Dynamic,"
}
// Set the per-thread iterators to the end of the instruction list.
- for (int i=0; i < numThreads;i++) {
- squashIt[i] = instList[i].end();
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ squashIt[tid] = instList[tid].end();
}
// Initialize the "universal" ROB head & tail point to invalid
template <class Impl>
void
-ROB<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
+ROB<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
{
DPRINTF(ROB, "Setting active threads list pointer.\n");
activeThreads = at_ptr;
void
ROB<Impl>::switchOut()
{
- for (int tid = 0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
instList[tid].clear();
}
}
void
ROB<Impl>::takeOverFrom()
{
- for (int tid=0; tid < numThreads; tid++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
doneSquashing[tid] = true;
threadEntries[tid] = 0;
squashIt[tid] = instList[tid].end();
if (robPolicy != Dynamic || numThreads > 1) {
int active_threads = activeThreads->size();
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (robPolicy == Partitioned) {
maxEntries[tid] = numEntries / active_threads;
template <class Impl>
int
-ROB<Impl>::entryAmount(int num_threads)
+ROB<Impl>::entryAmount(ThreadID num_threads)
{
if (robPolicy == Partitioned) {
return numEntries / num_threads;
int
ROB<Impl>::countInsts()
{
- int total=0;
+ int total = 0;
- for (int i=0;i < numThreads;i++)
- total += countInsts(i);
+ for (ThreadID tid = 0; tid < numThreads; tid++)
+ total += countInsts(tid);
return total;
}
template <class Impl>
int
-ROB<Impl>::countInsts(unsigned tid)
+ROB<Impl>::countInsts(ThreadID tid)
{
return instList[tid].size();
}
assert(numInstsInROB != numEntries);
- int tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
instList[tid].push_back(inst);
//assert(numInstsInROB == countInsts());
assert(numInstsInROB > 0);
- int tid = (*head)->threadNumber;
+ ThreadID tid = (*head)->threadNumber;
retireHead(tid);
template <class Impl>
void
-ROB<Impl>::retireHead(unsigned tid)
+ROB<Impl>::retireHead(ThreadID tid)
{
//assert(numInstsInROB == countInsts());
assert(numInstsInROB > 0);
*/
template <class Impl>
bool
-ROB<Impl>::isHeadReady(unsigned tid)
+ROB<Impl>::isHeadReady(ThreadID tid)
{
if (threadEntries[tid] != 0) {
return instList[tid].front()->readyToCommit();
ROB<Impl>::canCommit()
{
//@todo: set ActiveThreads through ROB or CPU
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (isHeadReady(tid)) {
return true;
template <class Impl>
unsigned
-ROB<Impl>::numFreeEntries(unsigned tid)
+ROB<Impl>::numFreeEntries(ThreadID tid)
{
return maxEntries[tid] - threadEntries[tid];
}
template <class Impl>
void
-ROB<Impl>::doSquash(unsigned tid)
+ROB<Impl>::doSquash(ThreadID tid)
{
DPRINTF(ROB, "[tid:%u]: Squashing instructions until [sn:%i].\n",
tid, squashedSeqNum[tid]);
bool first_valid = true;
// @todo: set ActiveThreads through ROB or CPU
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (instList[tid].empty())
continue;
tail = instList[0].end();
bool first_valid = true;
- std::list<unsigned>::iterator threads = activeThreads->begin();
- std::list<unsigned>::iterator end = activeThreads->end();
+ list<ThreadID>::iterator threads = activeThreads->begin();
+ list<ThreadID>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (instList[tid].empty()) {
continue;
template <class Impl>
void
-ROB<Impl>::squash(InstSeqNum squash_num,unsigned tid)
+ROB<Impl>::squash(InstSeqNum squash_num, ThreadID tid)
{
if (isEmpty()) {
DPRINTF(ROB, "Does not need to squash due to being empty "
template <class Impl>
typename Impl::DynInstPtr
-ROB<Impl>::readHeadInst(unsigned tid)
+ROB<Impl>::readHeadInst(ThreadID tid)
{
if (threadEntries[tid] != 0) {
InstIt head_thread = instList[tid].begin();
template <class Impl>
uint64_t
-ROB<Impl>::readHeadPC(unsigned tid)
+ROB<Impl>::readHeadPC(ThreadID tid)
{
//assert(numInstsInROB == countInsts());
InstIt head_thread = instList[tid].begin();
template <class Impl>
uint64_t
-ROB<Impl>::readHeadNextPC(unsigned tid)
+ROB<Impl>::readHeadNextPC(ThreadID tid)
{
//assert(numInstsInROB == countInsts());
InstIt head_thread = instList[tid].begin();
template <class Impl>
InstSeqNum
-ROB<Impl>::readHeadSeqNum(unsigned tid)
+ROB<Impl>::readHeadSeqNum(ThreadID tid)
{
InstIt head_thread = instList[tid].begin();
*/
template <class Impl>
typename Impl::DynInstPtr
-ROB<Impl>::readTailInst(unsigned tid)
+ROB<Impl>::readTailInst(ThreadID tid)
{
//assert(tail_thread[tid] != instList[tid].end());
template <class Impl>
uint64_t
-ROB<Impl>::readTailPC(unsigned tid)
+ROB<Impl>::readTailPC(ThreadID tid)
{
//assert(tail_thread[tid] != instList[tid].end());
template <class Impl>
InstSeqNum
-ROB<Impl>::readTailSeqNum(unsigned tid)
+ROB<Impl>::readTailSeqNum(ThreadID tid)
{
// Return the last sequence number that has not been squashed. Other
// stages can use it to squash any instructions younger than the current
}
void
-StoreSet::insertStore(Addr store_PC, InstSeqNum store_seq_num,
- unsigned tid)
+StoreSet::insertStore(Addr store_PC, InstSeqNum store_seq_num, ThreadID tid)
{
int index = calcIndex(store_PC);
}
void
-StoreSet::squash(InstSeqNum squashed_num, unsigned tid)
+StoreSet::squash(InstSeqNum squashed_num, ThreadID tid)
{
DPRINTF(StoreSet, "StoreSet: Squashing until inum %i\n",
squashed_num);
/** Inserts a store into the store set predictor. Updates the
* LFST if the store has a valid SSID. */
- void insertStore(Addr store_PC, InstSeqNum store_seq_num,
- unsigned tid);
+ void insertStore(Addr store_PC, InstSeqNum store_seq_num, ThreadID tid);
/** Checks if the instruction with the given PC is dependent upon
* any store. @return Returns the sequence number of the store
void issued(Addr issued_PC, InstSeqNum issued_seq_num, bool is_store);
/** Squashes for a specific thread until the given sequence number. */
- void squash(InstSeqNum squashed_num, unsigned tid);
+ void squash(InstSeqNum squashed_num, ThreadID tid);
/** Resets all tables. */
void clear();
{
// This function will mess things up unless the ROB is empty and
// there are no instructions in the pipeline.
- unsigned tid = thread->threadId();
+ ThreadID tid = thread->threadId();
PhysRegIndex renamed_reg;
// First loop through the integer registers.
{
using namespace Stats;
rob_cap_events
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ROB:cap_events")
.desc("number of cycles where ROB cap was active")
.flags(total)
;
rob_cap_inst_count
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ROB:cap_inst")
.desc("number of instructions held up by ROB cap")
.flags(total)
;
iq_cap_events
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() +".IQ:cap_events" )
.desc("number of cycles where IQ cap was active")
.flags(total)
;
iq_cap_inst_count
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".IQ:cap_inst")
.desc("number of instructions held up by IQ cap")
.flags(total)
exe_inst
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:count")
.desc("number of insts issued")
.flags(total)
;
exe_swp
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:swp")
.desc("number of swp insts issued")
.flags(total)
;
exe_nop
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:nop")
.desc("number of nop insts issued")
.flags(total)
;
exe_refs
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:refs")
.desc("number of memory reference insts issued")
.flags(total)
;
exe_loads
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:loads")
.desc("number of load insts issued")
.flags(total)
;
exe_branches
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:branches")
.desc("Number of branches issued")
.flags(total)
;
issued_ops
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:op_count")
.desc("number of insts issued")
.flags(total)
// Other stats
//
lsq_forw_loads
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".LSQ:forw_loads")
.desc("number of loads forwarded via LSQ")
.flags(total)
;
inv_addr_loads
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:addr_loads")
.desc("number of invalid-address loads")
.flags(total)
;
inv_addr_swpfs
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:addr_swpfs")
.desc("number of invalid-address SW prefetches")
.flags(total)
;
lsq_blocked_loads
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".LSQ:blocked_loads")
.desc("number of ready loads not issued due to memory disambiguation")
.flags(total)
}
writeback_count
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".WB:count")
.desc("cumulative count of insts written-back")
.flags(total)
;
producer_inst
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".WB:producers")
.desc("num instructions producing a value")
.flags(total)
;
consumer_inst
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".WB:consumers")
.desc("num instructions consuming a value")
.flags(total)
;
wb_penalized
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".WB:penalized")
.desc("number of instrctions required to write to 'other' IQ")
.flags(total)
wb_rate = writeback_count / cpu->numCycles;
stat_com_inst
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:count")
.desc("Number of instructions committed")
.flags(total)
;
stat_com_swp
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:swp_count")
.desc("Number of s/w prefetches committed")
.flags(total)
;
stat_com_refs
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:refs")
.desc("Number of memory references committed")
.flags(total)
;
stat_com_loads
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:loads")
.desc("Number of loads committed")
.flags(total)
;
stat_com_membars
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:membars")
.desc("Number of memory barriers committed")
.flags(total)
;
stat_com_branches
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:branches")
.desc("Number of branches committed")
.flags(total)
// we reached the BW limit
//
commit_eligible
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:bw_limited")
.desc("number of insts not committed due to BW limits")
.flags(total)
;
ROB_count
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ROB:occupancy")
.desc(name() + ".ROB occupancy (cumulative)")
.flags(total)
ROB_occ_rate = ROB_count / cpu->numCycles;
ROB_occ_dist
- .init(cpu->number_of_threads,0,numROBEntries,2)
+ .init(cpu->numThreads, 0, numROBEntries, 2)
.name(name() + ".ROB:occ_dist")
.desc("ROB Occupancy per cycle")
.flags(total | cdf)
// This probably needs to prioritize the redirects if a different
// scheduler is used. Currently the scheduler schedules the oldest
// instruction first, so the branch resolution order will be correct.
- unsigned tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
if (!fetchRedirect[tid]) {
void
BackEnd<Impl>::updateExeInstStats(DynInstPtr &inst)
{
- int thread_number = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
//
// Pick off the software prefetches
//
#ifdef TARGET_ALPHA
if (inst->isDataPrefetch())
- exe_swp[thread_number]++;
+ exe_swp[tid]++;
else
- exe_inst[thread_number]++;
+ exe_inst[tid]++;
#else
- exe_inst[thread_number]++;
+ exe_inst[tid]++;
#endif
//
// Control operations
//
if (inst->isControl())
- exe_branches[thread_number]++;
+ exe_branches[tid]++;
//
// Memory operations
//
if (inst->isMemRef()) {
- exe_refs[thread_number]++;
+ exe_refs[tid]++;
if (inst->isLoad())
- exe_loads[thread_number]++;
+ exe_loads[tid]++;
}
}
void
BackEnd<Impl>::updateComInstStats(DynInstPtr &inst)
{
- unsigned thread = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
//
// Pick off the software prefetches
//
#ifdef TARGET_ALPHA
if (inst->isDataPrefetch()) {
- stat_com_swp[thread]++;
+ stat_com_swp[tid]++;
} else {
- stat_com_inst[thread]++;
+ stat_com_inst[tid]++;
}
#else
- stat_com_inst[thread]++;
+ stat_com_inst[tid]++;
#endif
//
// Control Instructions
//
if (inst->isControl())
- stat_com_branches[thread]++;
+ stat_com_branches[tid]++;
//
// Memory references
//
if (inst->isMemRef()) {
- stat_com_refs[thread]++;
+ stat_com_refs[tid]++;
if (inst->isLoad()) {
- stat_com_loads[thread]++;
+ stat_com_loads[tid]++;
}
}
if (inst->isMemBarrier()) {
- stat_com_membars[thread]++;
+ stat_com_membars[tid]++;
}
}
#if FULL_SYSTEM
// Full-system only supports a single thread for the moment.
- int actual_num_threads = 1;
+ ThreadID actual_num_threads = 1;
#else
// In non-full-system mode, we infer the number of threads from
// the workload if it's not explicitly specified.
- int actual_num_threads =
+ ThreadID actual_num_threads =
numThreads.isValid() ? numThreads : workload.size();
if (workload.size() == 0) {
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
/** Number of entries needed for given amount of threads. */
- int entryAmount(int num_threads);
+ int entryAmount(ThreadID num_threads);
/** Resets max entries for all threads. */
void resetEntries();
unsigned numFreeEntries();
/** Returns number of free entries for a thread. */
- unsigned numFreeEntries(unsigned tid);
+ unsigned numFreeEntries(ThreadID tid);
/** Returns whether or not the IQ is full. */
bool isFull();
/** Returns whether or not the IQ is full for a specific thread. */
- bool isFull(unsigned tid);
+ bool isFull(ThreadID tid);
/** Returns if there are any ready instructions in the IQ. */
bool hasReadyInsts();
* Commits all instructions up to and including the given sequence number,
* for a specific thread.
*/
- void commit(const InstSeqNum &inst, unsigned tid = 0);
+ void commit(const InstSeqNum &inst, ThreadID tid = 0);
/** Wakes all dependents of a completed instruction. */
void wakeDependents(DynInstPtr &completed_inst);
* Squashes instructions for a thread. Squashing information is obtained
* from the time buffer.
*/
- void squash(unsigned tid); // Probably want the ISN
+ void squash(ThreadID tid); // Probably want the ISN
/** Returns the number of used entries for a thread. */
- unsigned getCount(unsigned tid) { return count[tid]; };
+ unsigned getCount(ThreadID tid) { return count[tid]; };
/** Updates the number of free entries. */
void updateFreeEntries(int num) { freeEntries += num; }
private:
/** Does the actual squashing. */
- void doSquash(unsigned tid);
+ void doSquash(ThreadID tid);
/////////////////////////
// Various pointers
numThreads = 1;
//Initialize thread IQ counts
- for (int i = 0; i <numThreads; i++) {
- count[i] = 0;
+ for (ThreadID tid = 0; tid <numThreads; tid++) {
+ count[tid] = 0;
}
// Initialize the number of free IQ entries.
// regScoreboard.resize(numPhysRegs);
/*
//Initialize Mem Dependence Units
- for (int i = 0; i < numThreads; i++) {
- memDepUnit[i].init(params,i);
- memDepUnit[i].setIQ(this);
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ memDepUnit[tid].init(params, tid);
+ memDepUnit[tid].setIQ(this);
}
// Initialize all the head pointers to point to NULL, and all the
regScoreboard[i] = false;
}
*/
- for (int i = 0; i < numThreads; ++i) {
- squashedSeqNum[i] = 0;
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
+ squashedSeqNum[tid] = 0;
}
/*
for (int i = 0; i < Num_OpClasses; ++i) {
iqPolicy = Dynamic;
//Set Max Entries to Total ROB Capacity
- for (int i = 0; i < numThreads; i++) {
- maxEntries[i] = numEntries;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ maxEntries[tid] = numEntries;
}
} else if (policy == "partitioned") {
int part_amt = numEntries / numThreads;
//Divide ROB up evenly
- for (int i = 0; i < numThreads; i++) {
- maxEntries[i] = part_amt;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ maxEntries[tid] = part_amt;
}
DPRINTF(Fetch, "IQ sharing policy set to Partitioned:"
int thresholdIQ = (int)((double)threshold * numEntries);
//Divide up by threshold amount
- for (int i = 0; i < numThreads; i++) {
- maxEntries[i] = thresholdIQ;
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ maxEntries[tid] = thresholdIQ;
}
DPRINTF(Fetch, "IQ sharing policy set to Threshold:"
.desc("Number of squashed non-spec instructions that were removed")
.prereq(iqSquashedNonSpecRemoved);
/*
- for ( int i=0; i < numThreads; i++) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
// Tell mem dependence unit to reg stats as well.
- memDepUnit[i].regStats();
+ memDepUnit[tid].regStats();
}
*/
}
template <class Impl>
int
-InstQueue<Impl>::entryAmount(int num_threads)
+InstQueue<Impl>::entryAmount(ThreadID num_threads)
{
if (iqPolicy == Partitioned) {
return numEntries / num_threads;
std::list<unsigned>::iterator end = activeThreads->end();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (iqPolicy == Partitioned) {
maxEntries[tid] = numEntries / active_threads;
template <class Impl>
unsigned
-InstQueue<Impl>::numFreeEntries(unsigned tid)
+InstQueue<Impl>::numFreeEntries(ThreadID tid)
{
return maxEntries[tid] - count[tid];
}
template <class Impl>
bool
-InstQueue<Impl>::isFull(unsigned tid)
+InstQueue<Impl>::isFull(ThreadID tid)
{
if (numFreeEntries(tid) == 0) {
return(true);
assert(inst_it != nonSpecInsts.end());
-// unsigned tid = (*inst_it).second->threadNumber;
+// ThreadID tid = (*inst_it).second->threadNumber;
// Mark this instruction as ready to issue.
(*inst_it).second->setCanIssue();
template <class Impl>
void
-InstQueue<Impl>::commit(const InstSeqNum &inst, unsigned tid)
+InstQueue<Impl>::commit(const InstSeqNum &inst, ThreadID tid)
{
/*Need to go through each thread??*/
DPRINTF(IQ, "[tid:%i]: Committing instructions older than [sn:%i]\n",
void
InstQueue<Impl>::completeMemInst(DynInstPtr &completed_inst)
{
- int tid = completed_inst->threadNumber;
+ ThreadID tid = completed_inst->threadNumber;
DPRINTF(IQ, "Completing mem instruction PC:%#x [sn:%lli]\n",
completed_inst->readPC(), completed_inst->seqNum);
*/
template <class Impl>
void
-InstQueue<Impl>::squash(unsigned tid)
+InstQueue<Impl>::squash(ThreadID tid)
{
DPRINTF(IQ, "[tid:%i]: Starting to squash instructions in "
"the IQ.\n", tid);
template <class Impl>
void
-InstQueue<Impl>::doSquash(unsigned tid)
+InstQueue<Impl>::doSquash(ThreadID tid)
{
// Make sure the squashed sequence number is valid.
assert(squashedSeqNum[tid] != 0);
#if 0
int total_insts = 0;
- for (int i = 0; i < numThreads; ++i) {
- ListIt count_it = instList[i].begin();
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
+ ListIt count_it = instList[tid].begin();
- while (count_it != instList[i].end()) {
+ while (count_it != instList[tid].end()) {
if (!(*count_it)->isSquashed() && !(*count_it)->isSquashedInIQ()) {
if (!(*count_it)->isIssued()) {
++total_insts;
void
InstQueue<Impl>::dumpInsts()
{
- for (int i = 0; i < numThreads; ++i) {
+ for (ThreadID tid = 0; tid < numThreads; ++tid) {
// int num = 0;
// int valid_num = 0;
/*
- ListIt inst_list_it = instList[i].begin();
+ ListIt inst_list_it = instList[tid].begin();
- while (inst_list_it != instList[i].end())
+ while (inst_list_it != instList[tid].end())
{
cprintf("Instruction:%i\n",
num);
LSQ.regStats();
robCapEvents
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ROB:cap_events")
.desc("number of cycles where ROB cap was active")
.flags(total)
;
robCapInstCount
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ROB:cap_inst")
.desc("number of instructions held up by ROB cap")
.flags(total)
;
iqCapEvents
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() +".IQ:cap_events" )
.desc("number of cycles where IQ cap was active")
.flags(total)
;
iqCapInstCount
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".IQ:cap_inst")
.desc("number of instructions held up by IQ cap")
.flags(total)
;
exeInst
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:count")
.desc("number of insts issued")
.flags(total)
;
exeSwp
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:swp")
.desc("number of swp insts issued")
.flags(total)
;
exeNop
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:nop")
.desc("number of nop insts issued")
.flags(total)
;
exeRefs
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:refs")
.desc("number of memory reference insts issued")
.flags(total)
;
exeLoads
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:loads")
.desc("number of load insts issued")
.flags(total)
;
exeBranches
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:branches")
.desc("Number of branches issued")
.flags(total)
;
issuedOps
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:op_count")
.desc("number of insts issued")
.flags(total)
// Other stats
//
lsqForwLoads
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".LSQ:forw_loads")
.desc("number of loads forwarded via LSQ")
.flags(total)
;
invAddrLoads
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:addr_loads")
.desc("number of invalid-address loads")
.flags(total)
;
invAddrSwpfs
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ISSUE:addr_swpfs")
.desc("number of invalid-address SW prefetches")
.flags(total)
;
lsqBlockedLoads
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".LSQ:blocked_loads")
.desc("number of ready loads not issued due to memory disambiguation")
.flags(total)
}
*/
writebackCount
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".WB:count")
.desc("cumulative count of insts written-back")
.flags(total)
;
producerInst
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".WB:producers")
.desc("num instructions producing a value")
.flags(total)
;
consumerInst
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".WB:consumers")
.desc("num instructions consuming a value")
.flags(total)
;
wbPenalized
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".WB:penalized")
.desc("number of instrctions required to write to 'other' IQ")
.flags(total)
wbRate = writebackCount / cpu->numCycles;
statComInst
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:count")
.desc("Number of instructions committed")
.flags(total)
;
statComSwp
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:swp_count")
.desc("Number of s/w prefetches committed")
.flags(total)
;
statComRefs
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:refs")
.desc("Number of memory references committed")
.flags(total)
;
statComLoads
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:loads")
.desc("Number of loads committed")
.flags(total)
;
statComMembars
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:membars")
.desc("Number of memory barriers committed")
.flags(total)
;
statComBranches
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:branches")
.desc("Number of branches committed")
.flags(total)
// we reached the BW limit
//
commitEligible
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:bw_limited")
.desc("number of insts not committed due to BW limits")
.flags(total)
;
squashedInsts
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:squashed_insts")
.desc("Number of instructions removed from inst list")
;
ROBSquashedInsts
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".COM:rob_squashed_insts")
.desc("Number of instructions removed from inst list when they reached the head of the ROB")
;
;
ROBCount
- .init(cpu->number_of_threads)
+ .init(cpu->numThreads)
.name(name() + ".ROB:occupancy")
.desc(name() + ".ROB occupancy (cumulative)")
.flags(total)
ROBOccRate = ROBCount / cpu->numCycles;
/*
ROBOccDist
- .init(cpu->number_of_threads,0,numROBEntries,2)
+ .init(cpu->numThreads, 0, numROBEntries, 2)
.name(name() + ".ROB:occ_dist")
.desc("ROB Occupancy per cycle")
.flags(total | cdf)
void
LWBackEnd<Impl>::updateExeInstStats(DynInstPtr &inst)
{
- int thread_number = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
//
// Pick off the software prefetches
//
#ifdef TARGET_ALPHA
if (inst->isDataPrefetch())
- exeSwp[thread_number]++;
+ exeSwp[tid]++;
else
- exeInst[thread_number]++;
+ exeInst[tid]++;
#else
- exeInst[thread_number]++;
+ exeInst[tid]++;
#endif
//
// Control operations
//
if (inst->isControl())
- exeBranches[thread_number]++;
+ exeBranches[tid]++;
//
// Memory operations
//
if (inst->isMemRef()) {
- exeRefs[thread_number]++;
+ exeRefs[tid]++;
if (inst->isLoad())
- exeLoads[thread_number]++;
+ exeLoads[tid]++;
}
}
void
LWBackEnd<Impl>::updateComInstStats(DynInstPtr &inst)
{
- unsigned tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
// keep an instruction count
thread->numInst++;
* @param tid The thread id.
* @return Returns if the branch is taken or not.
*/
- bool predict(DynInstPtr &inst, Addr &PC, unsigned tid)
+ bool predict(DynInstPtr &inst, Addr &PC, ThreadID tid)
{ return false; }
/**
* @param done_sn The sequence number to commit any older updates up until.
* @param tid The thread id.
*/
- void update(const InstSeqNum &done_sn, unsigned tid) { }
+ void update(const InstSeqNum &done_sn, ThreadID tid) { }
/**
* Squashes all outstanding updates until a given sequence number.
* until.
* @param tid The thread id.
*/
- void squash(const InstSeqNum &squashed_sn, unsigned tid) { }
+ void squash(const InstSeqNum &squashed_sn, ThreadID tid) { }
/**
* Squashes all outstanding updates until a given sequence number, and
* @param tid The thread id.
*/
void squash(const InstSeqNum &squashed_sn, const Addr &corr_target,
- bool actually_taken, unsigned tid)
+ bool actually_taken, ThreadID tid)
{ }
};
#if FULL_SYSTEM
// Full-system only supports a single thread for the moment.
- int actual_num_threads = 1;
+ ThreadID actual_num_threads = 1;
#else
// In non-full-system mode, we infer the number of threads from
// the workload if it's not explicitly specified.
- int actual_num_threads =
+ ThreadID actual_num_threads =
numThreads.isValid() ? numThreads : workload.size();
if (workload.size() == 0) {
{
BaseCPU::init();
#if FULL_SYSTEM
- for (int i = 0; i < threadContexts.size(); ++i) {
+ ThreadID size = threadContexts.size();
+ for (ThreadID i = 0; i < size; ++i) {
ThreadContext *tc = threadContexts[i];
// initialize CPU, including PC
// if any of this CPU's ThreadContexts are active, mark the CPU as
// running and schedule its tick event.
- for (int i = 0; i < threadContexts.size(); ++i) {
+ ThreadID size = threadContexts.size();
+ for (ThreadID i = 0; i < size; ++i) {
ThreadContext *tc = threadContexts[i];
if (tc->status() == ThreadContext::Active && _status != Running) {
_status = Running;
}
void
-change_thread_state(int thread_number, int activate, int priority)
+change_thread_state(ThreadID tid, int activate, int priority)
{
}
thread->setStCondFailures(sc_failures);
}
- MiscReg readRegOtherThread(int regIdx, int tid = -1)
+ MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID)
{
panic("Simple CPU models do not support multithreaded "
"register access.\n");
}
- void setRegOtherThread(int regIdx, const MiscReg &val, int tid = -1)
+ void setRegOtherThread(int regIdx, const MiscReg &val,
+ ThreadID tid = InvalidThreadID)
{
panic("Simple CPU models do not support multithreaded "
"register access.\n");
{
Fault fault;
const int asid = 0;
- const int thread_id = 0;
+ const ThreadID tid = 0;
const Addr pc = thread->readPC();
int block_size = dcachePort.peerBlockSize();
int data_size = sizeof(T);
RequestPtr req = new Request(asid, addr, data_size,
- flags, pc, _cpuId, thread_id);
+ flags, pc, _cpuId, tid);
Addr split_addr = roundDown(addr + data_size - 1, block_size);
assert(split_addr <= addr || split_addr - addr < block_size);
TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
const int asid = 0;
- const int thread_id = 0;
+ const ThreadID tid = 0;
const Addr pc = thread->readPC();
int block_size = dcachePort.peerBlockSize();
int data_size = sizeof(T);
RequestPtr req = new Request(asid, addr, data_size,
- flags, pc, _cpuId, thread_id);
+ flags, pc, _cpuId, tid);
Addr split_addr = roundDown(addr + data_size - 1, block_size);
assert(split_addr <= addr || split_addr - addr < block_size);
regs.setNextNPC(val);
}
- MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid = 0)
+ MiscReg
+ readMiscRegNoEffect(int misc_reg, ThreadID tid = 0)
{
return regs.readMiscRegNoEffect(misc_reg);
}
- MiscReg readMiscReg(int misc_reg, unsigned tid = 0)
+ MiscReg
+ readMiscReg(int misc_reg, ThreadID tid = 0)
{
return regs.readMiscReg(misc_reg, tc);
}
- void setMiscRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid = 0)
+ void
+ setMiscRegNoEffect(int misc_reg, const MiscReg &val, ThreadID tid = 0)
{
return regs.setMiscRegNoEffect(misc_reg, val);
}
- void setMiscReg(int misc_reg, const MiscReg &val, unsigned tid = 0)
+ void
+ setMiscReg(int misc_reg, const MiscReg &val, ThreadID tid = 0)
{
return regs.setMiscReg(misc_reg, val, tc);
}
/**
* Changes the status and priority of the thread with the given number.
- * @param thread_number The thread to change.
+ * @param tid The thread to change.
* @param activate The new active status.
* @param priority The new priority.
*/
-void change_thread_state(int thread_number, int activate, int priority);
+void change_thread_state(ThreadID tid, int activate, int priority);
#endif // __SMT_HH__
virtual void setMiscReg(int misc_reg, const MiscReg &val) = 0;
- virtual uint64_t readRegOtherThread(int misc_reg, unsigned tid) { return 0; }
+ virtual uint64_t
+ readRegOtherThread(int misc_reg, ThreadID tid)
+ {
+ return 0;
+ }
- virtual void setRegOtherThread(int misc_reg, const MiscReg &val, unsigned tid) { };
+ virtual void
+ setRegOtherThread(int misc_reg, const MiscReg &val, ThreadID tid)
+ {
+ }
// Also not necessarily the best location for these two. Hopefully will go
// away once we decide upon where st cond failures goes.
#endif
#if FULL_SYSTEM
-ThreadState::ThreadState(BaseCPU *cpu, int _tid)
+ThreadState::ThreadState(BaseCPU *cpu, ThreadID _tid)
#else
-ThreadState::ThreadState(BaseCPU *cpu, int _tid,
+ThreadState::ThreadState(BaseCPU *cpu, ThreadID _tid,
Process *_process, short _asid)
#endif
: numInst(0), numLoad(0), _status(ThreadContext::Halted),
typedef ThreadContext::Status Status;
#if FULL_SYSTEM
- ThreadState(BaseCPU *cpu, int _tid);
+ ThreadState(BaseCPU *cpu, ThreadID _tid);
#else
- ThreadState(BaseCPU *cpu, int _tid, Process *_process, short _asid);
+ ThreadState(BaseCPU *cpu, ThreadID _tid, Process *_process, short _asid);
#endif
~ThreadState();
void setContextId(int id) { _contextId = id; }
- void setThreadId(int id) { _threadId = id; }
+ void setThreadId(ThreadID id) { _threadId = id; }
- int threadId() { return _threadId; }
+ ThreadID threadId() { return _threadId; }
Tick readLastActivate() { return lastActivate; }
int _contextId;
// Index of hardware thread context on the CPU that this represents.
- int _threadId;
+ ThreadID _threadId;
public:
/** Last time activate was called on this thread. */
{
inService = false;
ntargets = 0;
- threadNum = -1;
+ threadNum = InvalidThreadID;
targets = new TargetList();
deferredTargets = new TargetList();
}
bool pendingShared;
/** Thread number of the miss. */
- short threadNum;
+ ThreadID threadNum;
/** The number of currently allocated targets. */
short ntargets;
}
Request(int asid, Addr vaddr, int size, Flags flags, Addr pc,
- int cid, int tid)
+ int cid, ThreadID tid)
{
setVirt(asid, vaddr, size, flags, pc);
setThreadContext(cid, tid);
* Set up CPU and thread numbers.
*/
void
- setThreadContext(int context_id, int thread_id)
+ setThreadContext(int context_id, ThreadID tid)
{
_contextId = context_id;
- _threadId = thread_id;
+ _threadId = tid;
privateFlags.set(VALID_CONTEXT_ID|VALID_THREAD_ID);
}
// cout << "Before setting trans address list size" << endl;
//create a trans address for each SMT thread
// m_trans_address_list.setSize(numThreads);
-// for(int i=0; i < numThreads; ++i){
-// cout << "Setting list size for list " << i << endl;
-// m_trans_address_list[i].setSize(30);
+// for(ThreadID tid = 0; tid < numThreads; ++tid){
+// cout << "Setting list size for list " << tid << endl;
+// m_trans_address_list[tid].setSize(30);
// }
//cout << "CacheMemory constructor finished" << endl;
}
std::vector<ThreadContext *> threadContexts;
int _numContexts;
- ThreadContext *getThreadContext(int tid)
+ ThreadContext *getThreadContext(ThreadID tid)
{
return threadContexts[tid];
}