/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Korey Sewell
*/
-#include "config/full_system.hh"
-#include "config/use_checker.hh"
-
#include <algorithm>
#include <string>
#include "arch/utility.hh"
+#include "base/cp_annotate.hh"
#include "base/loader/symtab.hh"
-#include "base/timebuf.hh"
+#include "cpu/timebuf.hh"
+#include "config/full_system.hh"
+#include "config/the_isa.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
+using namespace std;
+
template <class Impl>
DefaultCommit<Impl>::TrapEvent::TrapEvent(DefaultCommit<Impl> *_commit,
- unsigned _tid)
- : Event(&mainEventQueue, CPU_Tick_Pri), commit(_commit), tid(_tid)
+ ThreadID _tid)
+ : Event(CPU_Tick_Pri), commit(_commit), tid(_tid)
{
- this->setFlags(Event::AutoDelete);
+ this->setFlags(AutoDelete);
}
template <class Impl>
template <class Impl>
const char *
-DefaultCommit<Impl>::TrapEvent::description()
+DefaultCommit<Impl>::TrapEvent::description() const
{
return "Trap";
}
template <class Impl>
-DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, Params *params)
+DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, DerivO3CPUParams *params)
: cpu(_cpu),
squashCounter(0),
iewToCommitDelay(params->iewToCommitDelay),
fetchToCommitDelay(params->commitToFetchDelay),
renameWidth(params->renameWidth),
commitWidth(params->commitWidth),
- numThreads(params->numberOfThreads),
+ numThreads(params->numThreads),
drainPending(false),
switchedOut(false),
trapLatency(params->trapLatency)
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;
+ pc[tid].set(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
cpu->activateStage(O3CPU::CommitIdx);
cpu->activityThisCycle();
- trapLatency = cpu->cycles(trapLatency);
+ trapLatency = cpu->ticks(trapLatency);
}
template <class Impl>
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);
TrapEvent *trap = new TrapEvent(this, tid);
- trap->schedule(curTick + trapLatency);
+ cpu->schedule(trap, curTick() + trapLatency);
trapInFlight[tid] = true;
}
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.
toIEW->commitInfo[tid].branchMispredict = false;
- toIEW->commitInfo[tid].nextPC = PC[tid];
- toIEW->commitInfo[tid].nextNPC = nextPC[tid];
- toIEW->commitInfo[tid].nextMicroPC = nextMicroPC[tid];
+ toIEW->commitInfo[tid].pc = pc[tid];
}
template <class Impl>
void
-DefaultCommit<Impl>::squashFromTrap(unsigned tid)
+DefaultCommit<Impl>::squashFromTrap(ThreadID tid)
{
squashAll(tid);
- DPRINTF(Commit, "Squashing from trap, restarting at PC %#x\n", PC[tid]);
+ DPRINTF(Commit, "Squashing from trap, restarting at PC %s\n", pc[tid]);
thread[tid]->trapPending = false;
thread[tid]->inSyscall = false;
template <class Impl>
void
-DefaultCommit<Impl>::squashFromTC(unsigned tid)
+DefaultCommit<Impl>::squashFromTC(ThreadID tid)
{
squashAll(tid);
- DPRINTF(Commit, "Squashing from TC, restarting at PC %#x\n", PC[tid]);
+ DPRINTF(Commit, "Squashing from TC, restarting at PC %s\n", pc[tid]);
thread[tid]->inSyscall = false;
assert(!thread[tid]->trapPending);
tcSquash[tid] = false;
}
+template <class Impl>
+void
+DefaultCommit<Impl>::squashAfter(ThreadID tid, uint64_t squash_after_seq_num)
+{
+ youngestSeqNum[tid] = squash_after_seq_num;
+
+ rob->squash(squash_after_seq_num, tid);
+ changedROBNumEntries[tid] = true;
+
+ // Send back the sequence number of the squashed instruction.
+ toIEW->commitInfo[tid].doneSeqNum = squash_after_seq_num;
+
+ // Send back the squash signal to tell stages that they should squash.
+ toIEW->commitInfo[tid].squash = true;
+
+ // Send back the rob squashing signal so other stages know that
+ // the ROB is in the process of squashing.
+ toIEW->commitInfo[tid].robSquashing = true;
+
+ toIEW->commitInfo[tid].branchMispredict = false;
+
+ toIEW->commitInfo[tid].pc = pc[tid];
+ DPRINTF(Commit, "Executing squash after for [tid:%i] inst [sn:%lli]\n",
+ tid, squash_after_seq_num);
+ commitStatus[tid] = ROBSquashing;
+}
+
template <class Impl>
void
DefaultCommit<Impl>::tick()
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
DynInstPtr inst = rob->readHeadInst(tid);
- DPRINTF(Commit,"[tid:%i]: Instruction [sn:%lli] PC %#x is head of"
+ DPRINTF(Commit,"[tid:%i]: Instruction [sn:%lli] PC %s is head of"
" ROB and ready to commit\n",
- tid, inst->seqNum, inst->readPC());
+ tid, inst->seqNum, inst->pcState());
} else if (!rob->isEmpty(tid)) {
DynInstPtr inst = rob->readHeadInst(tid);
DPRINTF(Commit,"[tid:%i]: Can't commit, Instruction [sn:%lli] PC "
- "%#x is head of ROB and not ready\n",
- tid, inst->seqNum, inst->readPC());
+ "%s is head of ROB and not ready\n",
+ tid, inst->seqNum, inst->pcState());
}
DPRINTF(Commit, "[tid:%i]: ROB has %d insts & %d free entries.\n",
DPRINTF(Commit, "Interrupt pending, waiting for ROB to empty.\n");
}
} else if (commitStatus[0] != TrapPending &&
- cpu->check_interrupts(cpu->tcBase(0)) &&
+ cpu->checkInterrupts(cpu->tcBase(0)) &&
!trapSquash[0] &&
!tcSquash[0]) {
// Process interrupts if interrupts are enabled, not in PAL
// Check for any interrupt, and start processing it. Or if we
// have an outstanding interrupt and are at a point when it is
// valid to take an interrupt, process it.
- if (cpu->check_interrupts(cpu->tcBase(0))) {
+ if (cpu->checkInterrupts(cpu->tcBase(0))) {
handleInterrupt();
}
#endif // FULL_SYSTEM
////////////////////////////////////
// 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.
DPRINTF(Commit, "[tid:%i]: Redirecting to PC %#x\n",
tid,
- fromIEW->nextPC[tid]);
+ fromIEW->pc[tid].nextInstAddr());
commitStatus[tid] = ROBSquashing;
toIEW->commitInfo[tid].branchTaken =
fromIEW->branchTaken[tid];
- toIEW->commitInfo[tid].nextPC = fromIEW->nextPC[tid];
- toIEW->commitInfo[tid].nextNPC = fromIEW->nextNPC[tid];
- toIEW->commitInfo[tid].nextMicroPC = fromIEW->nextMicroPC[tid];
+ toIEW->commitInfo[tid].pc = fromIEW->pc[tid];
toIEW->commitInfo[tid].mispredPC = fromIEW->mispredPC[tid];
threads = activeThreads->begin();
while (threads != end) {
- unsigned tid = *threads++;
+ ThreadID tid = *threads++;
if (changedROBNumEntries[tid]) {
toIEW->commitInfo[tid].usedROB = true;
// @todo: Make this handle multi-cycle communication between
// commit and IEW.
if (checkEmptyROB[tid] && rob->isEmpty(tid) &&
- !iewStage->hasStoresToWB() && !committedStores[tid]) {
+ !iewStage->hasStoresToWB(tid) && !committedStores[tid]) {
checkEmptyROB[tid] = false;
toIEW->commitInfo[tid].usedROB = true;
toIEW->commitInfo[tid].emptyROB = true;
head_inst = rob->readHeadInst(commit_thread);
- int tid = head_inst->threadNumber;
+ ThreadID tid = head_inst->threadNumber;
assert(tid == commit_thread);
// Record that the number of ROB entries has changed.
changedROBNumEntries[tid] = true;
} else {
- PC[tid] = head_inst->readPC();
- nextPC[tid] = head_inst->readNextPC();
- nextNPC[tid] = head_inst->readNextNPC();
- nextMicroPC[tid] = head_inst->readNextMicroPC();
+ pc[tid] = head_inst->pcState();
// Increment the total number of non-speculative instructions
// executed.
cpu->instDone(tid);
}
- PC[tid] = nextPC[tid];
- nextPC[tid] = nextNPC[tid];
- nextNPC[tid] = nextNPC[tid] + sizeof(TheISA::MachInst);
- microPC[tid] = nextMicroPC[tid];
- nextMicroPC[tid] = microPC[tid] + 1;
+ // Updates misc. registers.
+ head_inst->updateMiscRegs();
+
+ TheISA::advancePC(pc[tid], head_inst->staticInst);
+
+ // If this is an instruction that doesn't play nicely with
+ // others squash everything and restart fetch
+ if (head_inst->isSquashAfter())
+ squashAfter(tid, head_inst->seqNum);
-#if FULL_SYSTEM
int count = 0;
Addr oldpc;
+ // Debug statement. Checks to make sure we're not
+ // currently updating state while handling PC events.
+ assert(!thread[tid]->inSyscall && !thread[tid]->trapPending);
do {
- // Debug statement. Checks to make sure we're not
- // currently updating state while handling PC events.
- if (count == 0)
- assert(!thread[tid]->inSyscall &&
- !thread[tid]->trapPending);
- oldpc = PC[tid];
- cpu->system->pcEventQueue.service(
- thread[tid]->getTC());
+ oldpc = pc[tid].instAddr();
+ cpu->system->pcEventQueue.service(thread[tid]->getTC());
count++;
- } while (oldpc != PC[tid]);
+ } while (oldpc != pc[tid].instAddr());
if (count > 1) {
- DPRINTF(Commit, "PC skip function event, stopping commit\n");
+ DPRINTF(Commit,
+ "PC skip function event, stopping commit\n");
break;
}
-#endif
} else {
- DPRINTF(Commit, "Unable to commit head instruction PC:%#x "
+ DPRINTF(Commit, "Unable to commit head instruction PC:%s "
"[tid:%i] [sn:%i].\n",
- head_inst->readPC(), tid ,head_inst->seqNum);
+ head_inst->pcState(), tid ,head_inst->seqNum);
break;
}
}
{
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.
head_inst->isWriteBarrier()) {
DPRINTF(Commit, "Encountered a barrier or non-speculative "
- "instruction [sn:%lli] at the head of the ROB, PC %#x.\n",
- head_inst->seqNum, head_inst->readPC());
+ "instruction [sn:%lli] at the head of the ROB, PC %s.\n",
+ head_inst->seqNum, head_inst->pcState());
- if (inst_num > 0 || iewStage->hasStoresToWB()) {
+ if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
DPRINTF(Commit, "Waiting for all stores to writeback.\n");
return false;
}
return false;
} else if (head_inst->isLoad()) {
- if (inst_num > 0 || iewStage->hasStoresToWB()) {
+ if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
DPRINTF(Commit, "Waiting for all stores to writeback.\n");
return false;
}
assert(head_inst->uncacheable());
- DPRINTF(Commit, "[sn:%lli]: Uncached load, PC %#x.\n",
- head_inst->seqNum, head_inst->readPC());
+ DPRINTF(Commit, "[sn:%lli]: Uncached load, PC %s.\n",
+ head_inst->seqNum, head_inst->pcState());
// Send back the non-speculative instruction's sequence
// number. Tell the lsq to re-execute the load.
}
#endif
- // DTB will sometimes need the machine instruction for when
- // faults happen. So we will set it here, prior to the DTB
- // possibly needing it for its fault.
- thread[tid]->setInst(
- static_cast<TheISA::MachInst>(head_inst->staticInst->machInst));
-
if (inst_fault != NoFault) {
- DPRINTF(Commit, "Inst [sn:%lli] PC %#x has a fault\n",
- head_inst->seqNum, head_inst->readPC());
+ DPRINTF(Commit, "Inst [sn:%lli] PC %s has a fault\n",
+ head_inst->seqNum, head_inst->pcState());
- if (iewStage->hasStoresToWB() || inst_num > 0) {
+ if (iewStage->hasStoresToWB(tid) || inst_num > 0) {
DPRINTF(Commit, "Stores outstanding, fault must wait.\n");
return false;
}
// needed to update the state as soon as possible. This
// prevents external agents from changing any specific state
// that the trap need.
- cpu->trap(inst_fault, tid);
+ cpu->trap(inst_fault, tid, head_inst->staticInst);
// Exit state update mode to avoid accidental updating.
thread[tid]->inSyscall = false;
commitStatus[tid] = TrapPending;
if (head_inst->traceData) {
- head_inst->traceData->setFetchSeq(head_inst->seqNum);
- head_inst->traceData->setCPSeq(thread[tid]->numInst);
- head_inst->traceData->dump();
+ if (DTRACE(ExecFaulting)) {
+ head_inst->traceData->setFetchSeq(head_inst->seqNum);
+ head_inst->traceData->setCPSeq(thread[tid]->numInst);
+ head_inst->traceData->dump();
+ }
delete head_inst->traceData;
head_inst->traceData = NULL;
}
// Generate trap squash event.
generateTrapEvent(tid);
-// warn("%lli fault (%d) handled @ PC %08p", curTick, inst_fault->name(), head_inst->readPC());
return false;
}
#if FULL_SYSTEM
if (thread[tid]->profile) {
-// bool usermode = TheISA::inUserMode(thread[tid]->getTC());
-// thread[tid]->profilePC = usermode ? 1 : head_inst->readPC();
- thread[tid]->profilePC = head_inst->readPC();
+ thread[tid]->profilePC = head_inst->instAddr();
ProfileNode *node = thread[tid]->profile->consume(thread[tid]->getTC(),
head_inst->staticInst);
if (node)
thread[tid]->profileNode = node;
}
+ if (CPA::available()) {
+ if (head_inst->isControl()) {
+ ThreadContext *tc = thread[tid]->getTC();
+ CPA::cpa()->swAutoBegin(tc, head_inst->nextInstAddr());
+ }
+ }
#endif
if (head_inst->traceData) {
DynInstPtr inst;
inst = fromRename->insts[inst_num];
- int tid = inst->threadNumber;
+ ThreadID tid = inst->threadNumber;
if (!inst->isSquashed() &&
commitStatus[tid] != ROBSquashing &&
commitStatus[tid] != TrapPending) {
changedROBNumEntries[tid] = true;
- DPRINTF(Commit, "Inserting PC %#x [sn:%i] [tid:%i] into ROB.\n",
- inst->readPC(), inst->seqNum, tid);
+ DPRINTF(Commit, "Inserting PC %s [sn:%i] [tid:%i] into ROB.\n",
+ inst->pcState(), inst->seqNum, tid);
rob->insertInst(inst);
youngestSeqNum[tid] = inst->seqNum;
} else {
- DPRINTF(Commit, "Instruction PC %#x [sn:%i] [tid:%i] was "
+ DPRINTF(Commit, "Instruction PC %s [sn:%i] [tid:%i] was "
"squashed, skipping.\n",
- inst->readPC(), inst->seqNum, tid);
+ inst->pcState(), inst->seqNum, tid);
}
}
}
DynInstPtr inst = fromRename->insts[inst_num];
if (!inst->isSquashed()) {
- DPRINTF(Commit, "Inserting PC %#x [sn:%i] [tid:%i] into ",
- "skidBuffer.\n", inst->readPC(), inst->seqNum,
+ DPRINTF(Commit, "Inserting PC %s [sn:%i] [tid:%i] into ",
+ "skidBuffer.\n", inst->pcState(), inst->seqNum,
inst->threadNumber);
skidBuffer.push(inst);
} else {
- DPRINTF(Commit, "Instruction PC %#x [sn:%i] [tid:%i] was "
+ DPRINTF(Commit, "Instruction PC %s [sn:%i] [tid:%i] was "
"squashed, skipping.\n",
- inst->readPC(), inst->seqNum, inst->threadNumber);
+ inst->pcState(), inst->seqNum, inst->threadNumber);
}
}
}
++inst_num)
{
if (!fromIEW->insts[inst_num]->isSquashed()) {
- DPRINTF(Commit, "[tid:%i]: Marking PC %#x, [sn:%lli] ready "
+ DPRINTF(Commit, "[tid:%i]: Marking PC %s, [sn:%lli] ready "
"within ROB.\n",
fromIEW->insts[inst_num]->threadNumber,
- fromIEW->insts[inst_num]->readPC(),
+ fromIEW->insts[inst_num]->pcState(),
fromIEW->insts[inst_num]->seqNum);
// Mark the instruction as ready to commit.
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;
}
}