summaryrefslogtreecommitdiff
path: root/cpu/beta_cpu/inst_queue_impl.hh
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/beta_cpu/inst_queue_impl.hh')
-rw-r--r--cpu/beta_cpu/inst_queue_impl.hh509
1 files changed, 386 insertions, 123 deletions
diff --git a/cpu/beta_cpu/inst_queue_impl.hh b/cpu/beta_cpu/inst_queue_impl.hh
index 6f1f06858..03e3fed33 100644
--- a/cpu/beta_cpu/inst_queue_impl.hh
+++ b/cpu/beta_cpu/inst_queue_impl.hh
@@ -1,11 +1,8 @@
#ifndef __INST_QUEUE_IMPL_HH__
#define __INST_QUEUE_IMPL_HH__
-// Todo: Fix up consistency errors about back of the ready list being
-// the oldest instructions in the queue. When woken up from the dependency
-// graph they will be the oldest, but when they are immediately executable
-// newer instructions will mistakenly get inserted onto the back. Also
-// current ordering allows for 0 cycle added-to-scheduled. Could maybe fake
+// Todo:
+// Current ordering allows for 0 cycle added-to-scheduled. Could maybe fake
// it; either do in reverse order, or have added instructions put into a
// different ready queue that, in scheduleRreadyInsts(), gets put onto the
// normal ready queue. This would however give only a one cycle delay,
@@ -21,18 +18,21 @@
// Blatant hack to avoid compile warnings.
const InstSeqNum MaxInstSeqNum = 0 - 1;
-template<class Impl>
+template <class Impl>
InstructionQueue<Impl>::InstructionQueue(Params &params)
- : numEntries(params.numIQEntries),
+ : memDepUnit(params),
+ numEntries(params.numIQEntries),
intWidth(params.executeIntWidth),
floatWidth(params.executeFloatWidth),
+ totalWidth(params.issueWidth),
numPhysIntRegs(params.numPhysIntRegs),
numPhysFloatRegs(params.numPhysFloatRegs),
commitToIEWDelay(params.commitToIEWDelay)
{
// HACK: HARDCODED NUMBER. REMOVE LATER AND ADD TO PARAMETER.
- totalWidth = 1;
branchWidth = 1;
+ memoryWidth = 1;
+
DPRINTF(IQ, "IQ: Int width is %i.\n", params.executeIntWidth);
// Initialize the number of free IQ entries.
@@ -66,7 +66,7 @@ InstructionQueue<Impl>::InstructionQueue(Params &params)
}
-template<class Impl>
+template <class Impl>
void
InstructionQueue<Impl>::setCPU(FullCPU *cpu_ptr)
{
@@ -75,7 +75,7 @@ InstructionQueue<Impl>::setCPU(FullCPU *cpu_ptr)
tail = cpu->instList.begin();
}
-template<class Impl>
+template <class Impl>
void
InstructionQueue<Impl>::setIssueToExecuteQueue(
TimeBuffer<IssueStruct> *i2e_ptr)
@@ -84,7 +84,7 @@ InstructionQueue<Impl>::setIssueToExecuteQueue(
issueToExecuteQueue = i2e_ptr;
}
-template<class Impl>
+template <class Impl>
void
InstructionQueue<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
{
@@ -96,7 +96,7 @@ InstructionQueue<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
// Might want to do something more complex if it knows how many instructions
// will be issued this cycle.
-template<class Impl>
+template <class Impl>
bool
InstructionQueue<Impl>::isFull()
{
@@ -107,16 +107,16 @@ InstructionQueue<Impl>::isFull()
}
}
-template<class Impl>
+template <class Impl>
unsigned
InstructionQueue<Impl>::numFreeEntries()
{
return freeEntries;
}
-template<class Impl>
+template <class Impl>
void
-InstructionQueue<Impl>::insert(DynInst *new_inst)
+InstructionQueue<Impl>::insert(DynInstPtr &new_inst)
{
// Make sure the instruction is valid
assert(new_inst);
@@ -157,18 +157,78 @@ InstructionQueue<Impl>::insert(DynInst *new_inst)
// register(s).
createDependency(new_inst);
+ // If it's a memory instruction, add it to the memory dependency
+ // unit.
+ if (new_inst->isMemRef()) {
+ memDepUnit.insert(new_inst);
+ }
+
// If the instruction is ready then add it to the ready list.
addIfReady(new_inst);
assert(freeEntries == (numEntries - countInsts()));
}
+template <class Impl>
+void
+InstructionQueue<Impl>::insertNonSpec(DynInstPtr &inst)
+{
+ nonSpecInsts[inst->seqNum] = inst;
+
+ // @todo: Clean up this code; can do it by setting inst as unable
+ // to issue, then calling normal insert on the inst.
+
+ // Make sure the instruction is valid
+ assert(inst);
+
+ DPRINTF(IQ, "IQ: Adding instruction PC %#x to the IQ.\n",
+ inst->readPC());
+
+ // Check if there are any free entries. Panic if there are none.
+ // Might want to have this return a fault in the future instead of
+ // panicing.
+ assert(freeEntries != 0);
+
+ // If the IQ currently has nothing in it, then there's a possibility
+ // that the tail iterator is invalid (might have been pointing at an
+ // instruction that was retired). Reset the tail iterator.
+ if (freeEntries == numEntries) {
+ tail = cpu->instList.begin();
+ }
+
+ // Move the tail iterator. Instructions may not have been issued
+ // to the IQ, so we may have to increment the iterator more than once.
+ while ((*tail) != inst) {
+ tail++;
+
+ // Make sure the tail iterator points at something legal.
+ assert(tail != cpu->instList.end());
+ }
+
+ // Decrease the number of free entries.
+ --freeEntries;
+
+ // Look through its source registers (physical regs), and mark any
+ // dependencies.
+// addToDependents(inst);
+
+ // Have this instruction set itself as the producer of its destination
+ // register(s).
+ createDependency(inst);
+
+ // If it's a memory instruction, add it to the memory dependency
+ // unit.
+ if (inst->isMemRef()) {
+ memDepUnit.insert(inst);
+ }
+}
+
// Slightly hack function to advance the tail iterator in the case that
// the IEW stage issues an instruction that is not added to the IQ. This
// is needed in case a long chain of such instructions occurs.
-template<class Impl>
+template <class Impl>
void
-InstructionQueue<Impl>::advanceTail(DynInst *inst)
+InstructionQueue<Impl>::advanceTail(DynInstPtr &inst)
{
// Make sure the instruction is valid
assert(inst);
@@ -205,10 +265,11 @@ InstructionQueue<Impl>::advanceTail(DynInst *inst)
}
// Need to make sure the number of float and integer instructions
-// issued does not exceed the total issue bandwidth. Probably should
-// have some sort of limit of total number of branches that can be issued
-// as well.
-template<class Impl>
+// issued does not exceed the total issue bandwidth.
+// @todo: Figure out a better way to remove the squashed items from the
+// lists. Checking the top item of each list to see if it's squashed
+// wastes time and forces jumps.
+template <class Impl>
void
InstructionQueue<Impl>::scheduleReadyInsts()
{
@@ -218,6 +279,7 @@ InstructionQueue<Impl>::scheduleReadyInsts()
int int_issued = 0;
int float_issued = 0;
int branch_issued = 0;
+ int memory_issued = 0;
int squashed_issued = 0;
int total_issued = 0;
@@ -226,6 +288,8 @@ InstructionQueue<Impl>::scheduleReadyInsts()
bool insts_available = !readyBranchInsts.empty() ||
!readyIntInsts.empty() ||
!readyFloatInsts.empty() ||
+ !readyMemInsts.empty() ||
+ !readyMiscInsts.empty() ||
!squashedInsts.empty();
// Note: Requires a globally defined constant.
@@ -233,10 +297,12 @@ InstructionQueue<Impl>::scheduleReadyInsts()
InstList list_with_oldest = None;
// Temporary values.
- DynInst *int_head_inst;
- DynInst *float_head_inst;
- DynInst *branch_head_inst;
- DynInst *squashed_head_inst;
+ DynInstPtr int_head_inst;
+ DynInstPtr float_head_inst;
+ DynInstPtr branch_head_inst;
+ DynInstPtr mem_head_inst;
+ DynInstPtr misc_head_inst;
+ DynInstPtr squashed_head_inst;
// Somewhat nasty code to look at all of the lists where issuable
// instructions are located, and choose the oldest instruction among
@@ -257,7 +323,7 @@ InstructionQueue<Impl>::scheduleReadyInsts()
insts_available = true;
- int_head_inst = readyIntInsts.top().inst;
+ int_head_inst = readyIntInsts.top();
if (int_head_inst->isSquashed()) {
readyIntInsts.pop();
@@ -274,7 +340,7 @@ InstructionQueue<Impl>::scheduleReadyInsts()
insts_available = true;
- float_head_inst = readyFloatInsts.top().inst;
+ float_head_inst = readyFloatInsts.top();
if (float_head_inst->isSquashed()) {
readyFloatInsts.pop();
@@ -291,7 +357,7 @@ InstructionQueue<Impl>::scheduleReadyInsts()
insts_available = true;
- branch_head_inst = readyBranchInsts.top().inst;
+ branch_head_inst = readyBranchInsts.top();
if (branch_head_inst->isSquashed()) {
readyBranchInsts.pop();
@@ -304,11 +370,44 @@ InstructionQueue<Impl>::scheduleReadyInsts()
}
+ if (!readyMemInsts.empty() &&
+ memory_issued < memoryWidth) {
+
+ insts_available = true;
+
+ mem_head_inst = readyMemInsts.top();
+
+ if (mem_head_inst->isSquashed()) {
+ readyMemInsts.pop();
+ continue;
+ } else if (mem_head_inst->seqNum < oldest_inst) {
+ oldest_inst = mem_head_inst->seqNum;
+
+ list_with_oldest = Memory;
+ }
+ }
+
+ if (!readyMiscInsts.empty()) {
+
+ insts_available = true;
+
+ misc_head_inst = readyMiscInsts.top();
+
+ if (misc_head_inst->isSquashed()) {
+ readyMiscInsts.pop();
+ continue;
+ } else if (misc_head_inst->seqNum < oldest_inst) {
+ oldest_inst = misc_head_inst->seqNum;
+
+ list_with_oldest = Misc;
+ }
+ }
+
if (!squashedInsts.empty()) {
insts_available = true;
- squashed_head_inst = squashedInsts.top().inst;
+ squashed_head_inst = squashedInsts.top();
if (squashed_head_inst->seqNum < oldest_inst) {
list_with_oldest = Squashed;
@@ -316,13 +415,14 @@ InstructionQueue<Impl>::scheduleReadyInsts()
}
- DynInst *issuing_inst = NULL;
+ DynInstPtr issuing_inst = NULL;
switch (list_with_oldest) {
case None:
DPRINTF(IQ, "IQ: Not able to schedule any instructions. Issuing "
"inst is %#x.\n", issuing_inst);
break;
+
case Int:
issuing_inst = int_head_inst;
readyIntInsts.pop();
@@ -330,6 +430,7 @@ InstructionQueue<Impl>::scheduleReadyInsts()
DPRINTF(IQ, "IQ: Issuing integer instruction PC %#x.\n",
issuing_inst->readPC());
break;
+
case Float:
issuing_inst = float_head_inst;
readyFloatInsts.pop();
@@ -337,6 +438,7 @@ InstructionQueue<Impl>::scheduleReadyInsts()
DPRINTF(IQ, "IQ: Issuing float instruction PC %#x.\n",
issuing_inst->readPC());
break;
+
case Branch:
issuing_inst = branch_head_inst;
readyBranchInsts.pop();
@@ -344,6 +446,25 @@ InstructionQueue<Impl>::scheduleReadyInsts()
DPRINTF(IQ, "IQ: Issuing branch instruction PC %#x.\n",
issuing_inst->readPC());
break;
+
+ case Memory:
+ issuing_inst = mem_head_inst;
+
+ memDepUnit.issue(mem_head_inst);
+
+ readyMemInsts.pop();
+ ++memory_issued;
+ DPRINTF(IQ, "IQ: Issuing memory instruction PC %#x.\n",
+ issuing_inst->readPC());
+ break;
+
+ case Misc:
+ issuing_inst = misc_head_inst;
+ readyMiscInsts.pop();
+ DPRINTF(IQ, "IQ: Issuing a miscellaneous instruction PC %#x.\n",
+ issuing_inst->readPC());
+ break;
+
case Squashed:
issuing_inst = squashed_head_inst;
squashedInsts.pop();
@@ -366,7 +487,52 @@ InstructionQueue<Impl>::scheduleReadyInsts()
}
}
-template<class Impl>
+template <class Impl>
+void
+InstructionQueue<Impl>::scheduleNonSpec(const InstSeqNum &inst)
+{
+ non_spec_it_t inst_it = nonSpecInsts.find(inst);
+
+ assert(inst_it != nonSpecInsts.end());
+
+ // Mark this instruction as ready to issue.
+ (*inst_it).second->setCanIssue();
+
+ // Now schedule the instruction.
+ addIfReady((*inst_it).second);
+
+ nonSpecInsts.erase(inst_it);
+}
+
+template <class Impl>
+void
+InstructionQueue<Impl>::violation(DynInstPtr &store,
+ DynInstPtr &faulting_load)
+{
+ memDepUnit.violation(store, faulting_load);
+}
+
+template <class Impl>
+void
+InstructionQueue<Impl>::squash()
+{
+ DPRINTF(IQ, "IQ: Starting to squash instructions in the IQ.\n");
+
+ // Read instruction sequence number of last instruction out of the
+ // time buffer.
+ squashedSeqNum = fromCommit->commitInfo.doneSeqNum;
+
+ // Setup the squash iterator to point to the tail.
+ squashIt = tail;
+
+ // Call doSquash.
+ doSquash();
+
+ // Also tell the memory dependence unit to squash.
+ memDepUnit.squash(squashedSeqNum);
+}
+
+template <class Impl>
void
InstructionQueue<Impl>::doSquash()
{
@@ -380,64 +546,59 @@ InstructionQueue<Impl>::doSquash()
// Squash any instructions younger than the squashed sequence number
// given.
while ((*squashIt)->seqNum > squashedSeqNum) {
- DynInst *squashed_inst = (*squashIt);
+ DynInstPtr squashed_inst = (*squashIt);
// Only handle the instruction if it actually is in the IQ and
// hasn't already been squashed in the IQ.
if (!squashed_inst->isIssued() &&
!squashed_inst->isSquashedInIQ()) {
// Remove the instruction from the dependency list.
- int8_t total_src_regs = squashed_inst->numSrcRegs();
-
- for (int src_reg_idx = 0;
- src_reg_idx < total_src_regs;
- src_reg_idx++)
- {
- // Only remove it from the dependency graph if it was
- // placed there in the first place.
- // HACK: This assumes that instructions woken up from the
- // dependency chain aren't informed that a specific src
- // register has become ready. This may not always be true
- // in the future.
- if (!squashed_inst->isReadySrcRegIdx(src_reg_idx)) {
- int8_t src_reg =
+ // Hack for now: These below don't add themselves to the
+ // dependency list, so don't try to remove them.
+ if (!squashed_inst->isNonSpeculative() &&
+ !squashed_inst->isStore()) {
+ int8_t total_src_regs = squashed_inst->numSrcRegs();
+
+ for (int src_reg_idx = 0;
+ src_reg_idx < total_src_regs;
+ src_reg_idx++)
+ {
+ PhysRegIndex src_reg =
squashed_inst->renamedSrcRegIdx(src_reg_idx);
- dependGraph[src_reg].remove(squashed_inst);
+
+ // Only remove it from the dependency graph if it was
+ // placed there in the first place.
+ // HACK: This assumes that instructions woken up from the
+ // dependency chain aren't informed that a specific src
+ // register has become ready. This may not always be true
+ // in the future.
+ if (!squashed_inst->isReadySrcRegIdx(src_reg_idx) &&
+ src_reg < numPhysRegs) {
+ dependGraph[src_reg].remove(squashed_inst);
+ }
}
}
+ // Might want to also clear out the head of the dependency graph.
+
// Mark it as squashed within the IQ.
squashed_inst->setSquashedInIQ();
- ReadyEntry temp(squashed_inst);
-
- squashedInsts.push(temp);
+ squashedInsts.push(squashed_inst);
DPRINTF(IQ, "IQ: Instruction PC %#x squashed.\n",
squashed_inst->readPC());
}
- squashIt--;
- }
-}
-
-template<class Impl>
-void
-InstructionQueue<Impl>::squash()
-{
- DPRINTF(IQ, "IQ: Starting to squash instructions in the IQ.\n");
- // Read instruction sequence number of last instruction out of the
- // time buffer.
- squashedSeqNum = fromCommit->commitInfo.doneSeqNum;
-
- // Setup the squash iterator to point to the tail.
- squashIt = tail;
+ if (squashed_inst->isNonSpeculative() || squashed_inst->isStore()) {
+ nonSpecInsts.erase(squashed_inst->seqNum);
+ }
- // Call doSquash.
- doSquash();
+ --squashIt;
+ }
}
-template<class Impl>
+template <class Impl>
void
InstructionQueue<Impl>::stopSquash()
{
@@ -448,36 +609,9 @@ InstructionQueue<Impl>::stopSquash()
squashIt = cpu->instList.end();
}
-template<class Impl>
-int
-InstructionQueue<Impl>::countInsts()
-{
- ListIt count_it = cpu->instList.begin();
- int total_insts = 0;
-
- while (count_it != tail) {
- if (!(*count_it)->isIssued()) {
- ++total_insts;
- }
-
- count_it++;
-
- assert(count_it != cpu->instList.end());
- }
-
- // Need to count the tail iterator as well.
- if (count_it != cpu->instList.end() &&
- (*count_it) != NULL &&
- !(*count_it)->isIssued()) {
- ++total_insts;
- }
-
- return total_insts;
-}
-
-template<class Impl>
+template <class Impl>
void
-InstructionQueue<Impl>::wakeDependents(DynInst *completed_inst)
+InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
{
DPRINTF(IQ, "IQ: Waking dependents of completed instruction.\n");
//Look at the physical destination register of the DynInst
@@ -487,6 +621,13 @@ InstructionQueue<Impl>::wakeDependents(DynInst *completed_inst)
DependencyEntry *curr;
+ // Tell the memory dependence unit to wake any dependents on this
+ // instruction if it is a memory instruction.
+
+ if (completed_inst->isMemRef()) {
+ memDepUnit.wakeDependents(completed_inst);
+ }
+
for (int dest_reg_idx = 0;
dest_reg_idx < total_dest_regs;
dest_reg_idx++)
@@ -507,7 +648,7 @@ InstructionQueue<Impl>::wakeDependents(DynInst *completed_inst)
//Maybe abstract this part into a function.
//Go through the dependency chain, marking the registers as ready
//within the waiting instructions.
- while (dependGraph[dest_reg].next != NULL) {
+ while (dependGraph[dest_reg].next) {
curr = dependGraph[dest_reg].next;
@@ -537,9 +678,9 @@ InstructionQueue<Impl>::wakeDependents(DynInst *completed_inst)
}
}
-template<class Impl>
+template <class Impl>
bool
-InstructionQueue<Impl>::addToDependents(DynInst *new_inst)
+InstructionQueue<Impl>::addToDependents(DynInstPtr &new_inst)
{
// Loop through the instruction's source registers, adding
// them to the dependency list if they are not ready.
@@ -558,7 +699,9 @@ InstructionQueue<Impl>::addToDependents(DynInst *new_inst)
// hasn't become ready while the instruction was in flight
// between stages. Only if it really isn't ready should
// it be added to the dependency graph.
- if (regScoreboard[src_reg] == false) {
+ if (src_reg >= numPhysRegs) {
+ continue;
+ } else if (regScoreboard[src_reg] == false) {
DPRINTF(IQ, "IQ: Instruction PC %#x has src reg %i that "
"is being added to the dependency chain.\n",
new_inst->readPC(), src_reg);
@@ -581,9 +724,9 @@ InstructionQueue<Impl>::addToDependents(DynInst *new_inst)
return return_val;
}
-template<class Impl>
+template <class Impl>
void
-InstructionQueue<Impl>::createDependency(DynInst *new_inst)
+InstructionQueue<Impl>::createDependency(DynInstPtr &new_inst)
{
//Actually nothing really needs to be marked when an
//instruction becomes the producer of a register's value,
@@ -595,20 +738,32 @@ InstructionQueue<Impl>::createDependency(DynInst *new_inst)
dest_reg_idx < total_dest_regs;
dest_reg_idx++)
{
- int8_t dest_reg = new_inst->renamedDestRegIdx(dest_reg_idx);
- dependGraph[dest_reg].inst = new_inst;
- if (dependGraph[dest_reg].next != NULL) {
- panic("Dependency chain is not empty.\n");
+ PhysRegIndex dest_reg = new_inst->renamedDestRegIdx(dest_reg_idx);
+
+ // Instructions that use the misc regs will have a reg number
+ // higher than the normal physical registers. In this case these
+ // registers are not renamed, and there is no need to track
+ // dependencies as these instructions must be executed at commit.
+ if (dest_reg >= numPhysRegs) {
+ continue;
}
+ dependGraph[dest_reg].inst = new_inst;
+#if 0
+ if (dependGraph[dest_reg].next) {
+ panic("Dependency chain of dest reg %i is not empty.\n",
+ dest_reg);
+ }
+#endif
+ assert(!dependGraph[dest_reg].next);
// Mark the scoreboard to say it's not yet ready.
regScoreboard[dest_reg] = false;
}
}
-template<class Impl>
+template <class Impl>
void
-InstructionQueue<Impl>::DependencyEntry::insert(DynInst *new_inst)
+InstructionQueue<Impl>::DependencyEntry::insert(DynInstPtr &new_inst)
{
//Add this new, dependent instruction at the head of the dependency
//chain.
@@ -623,9 +778,9 @@ InstructionQueue<Impl>::DependencyEntry::insert(DynInst *new_inst)
this->next = new_entry;
}
-template<class Impl>
+template <class Impl>
void
-InstructionQueue<Impl>::DependencyEntry::remove(DynInst *inst_to_remove)
+InstructionQueue<Impl>::DependencyEntry::remove(DynInstPtr &inst_to_remove)
{
DependencyEntry *prev = this;
DependencyEntry *curr = this->next;
@@ -643,6 +798,8 @@ InstructionQueue<Impl>::DependencyEntry::remove(DynInst *inst_to_remove)
{
prev = curr;
curr = curr->next;
+
+ assert(curr != NULL);
}
// Now remove this instruction from the list.
@@ -651,34 +808,140 @@ InstructionQueue<Impl>::DependencyEntry::remove(DynInst *inst_to_remove)
delete curr;
}
-template<class Impl>
+template <class Impl>
+void
+InstructionQueue<Impl>::dumpDependGraph()
+{
+ DependencyEntry *curr;
+
+ for (int i = 0; i < numPhysRegs; ++i)
+ {
+ curr = &dependGraph[i];
+
+ if (curr->inst) {
+ cprintf("dependGraph[%i]: producer: %#x consumer: ", i,
+ curr->inst->readPC());
+ } else {
+ cprintf("dependGraph[%i]: No producer. consumer: ", i);
+ }
+
+ while (curr->next != NULL) {
+ curr = curr->next;
+
+ cprintf("%#x ", curr->inst->readPC());
+ }
+
+ cprintf("\n");
+ }
+}
+
+template <class Impl>
void
-InstructionQueue<Impl>::addIfReady(DynInst *inst)
+InstructionQueue<Impl>::addIfReady(DynInstPtr &inst)
{
//If the instruction now has all of its source registers
// available, then add it to the list of ready instructions.
if (inst->readyToIssue()) {
- ReadyEntry to_add(inst);
+
//Add the instruction to the proper ready list.
- if (inst->isInteger()) {
+ if (inst->isControl()) {
+
+ DPRINTF(IQ, "IQ: Branch instruction is ready to issue, "
+ "putting it onto the ready list, PC %#x.\n",
+ inst->readPC());
+ readyBranchInsts.push(inst);
+
+ } else if (inst->isMemRef()) {
+
+ DPRINTF(IQ, "IQ: Checking if memory instruction can issue.\n");
+
+ if (memDepUnit.readyToIssue(inst)) {
+ DPRINTF(IQ, "IQ: Memory instruction is ready to issue, "
+ "putting it onto the ready list, PC %#x.\n",
+ inst->readPC());
+ readyMemInsts.push(inst);
+ }
+
+ } else if (inst->isInteger()) {
+
DPRINTF(IQ, "IQ: Integer instruction is ready to issue, "
"putting it onto the ready list, PC %#x.\n",
inst->readPC());
- readyIntInsts.push(to_add);
+ readyIntInsts.push(inst);
+
} else if (inst->isFloating()) {
+
DPRINTF(IQ, "IQ: Floating instruction is ready to issue, "
"putting it onto the ready list, PC %#x.\n",
inst->readPC());
- readyFloatInsts.push(to_add);
- } else if (inst->isControl()) {
- DPRINTF(IQ, "IQ: Branch instruction is ready to issue, "
- "putting it onto the ready list, PC %#x.\n",
- inst->readPC());
- readyBranchInsts.push(to_add);
+ readyFloatInsts.push(inst);
+
} else {
- panic("IQ: Instruction not an expected type.\n");
+ DPRINTF(IQ, "IQ: Miscellaneous instruction is ready to issue, "
+ "putting it onto the ready list, PC %#x..\n",
+ inst->readPC());
+
+ readyMiscInsts.push(inst);
}
}
}
+template <class Impl>
+int
+InstructionQueue<Impl>::countInsts()
+{
+ ListIt count_it = cpu->instList.begin();
+ int total_insts = 0;
+
+ while (count_it != tail) {
+ if (!(*count_it)->isIssued()) {
+ ++total_insts;
+ }
+
+ ++count_it;
+
+ assert(count_it != cpu->instList.end());
+ }
+
+ // Need to count the tail iterator as well.
+ if (count_it != cpu->instList.end() &&
+ (*count_it) &&
+ !(*count_it)->isIssued()) {
+ ++total_insts;
+ }
+
+ return total_insts;
+}
+
+template <class Impl>
+void
+InstructionQueue<Impl>::dumpLists()
+{
+ cprintf("Ready integer list size: %i\n", readyIntInsts.size());
+
+ cprintf("Ready float list size: %i\n", readyFloatInsts.size());
+
+ cprintf("Ready branch list size: %i\n", readyBranchInsts.size());
+
+ cprintf("Ready memory list size: %i\n", readyMemInsts.size());
+
+ cprintf("Ready misc list size: %i\n", readyMiscInsts.size());
+
+ cprintf("Squashed list size: %i\n", squashedInsts.size());
+
+ cprintf("Non speculative list size: %i\n", nonSpecInsts.size());
+
+ non_spec_it_t non_spec_it = nonSpecInsts.begin();
+
+ cprintf("Non speculative list: ");
+
+ while (non_spec_it != nonSpecInsts.end()) {
+ cprintf("%#x ", (*non_spec_it).second->readPC());
+ ++non_spec_it;
+ }
+
+ cprintf("\n");
+
+}
+
#endif // __INST_QUEUE_IMPL_HH__