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.hh125
1 files changed, 77 insertions, 48 deletions
diff --git a/cpu/beta_cpu/inst_queue_impl.hh b/cpu/beta_cpu/inst_queue_impl.hh
index c688181ed..d4e3939cf 100644
--- a/cpu/beta_cpu/inst_queue_impl.hh
+++ b/cpu/beta_cpu/inst_queue_impl.hh
@@ -31,8 +31,6 @@ InstructionQueue<Impl>::InstructionQueue(Params &params)
numPhysFloatRegs(params.numPhysFloatRegs),
commitToIEWDelay(params.commitToIEWDelay)
{
- DPRINTF(IQ, "IQ: Int width is %i.\n", params.executeIntWidth);
-
// Initialize the number of free IQ entries.
freeEntries = numEntries;
@@ -291,10 +289,6 @@ InstructionQueue<Impl>::insertNonSpec(DynInstPtr &inst)
// 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);
@@ -568,15 +562,20 @@ InstructionQueue<Impl>::scheduleReadyInsts()
break;
case Squashed:
- issuing_inst = squashed_head_inst;
+// issuing_inst = squashed_head_inst;
+ assert(0 && "Squashed insts should not issue any more!");
squashedInsts.pop();
+ // Set the squashed instruction as able to commit so that commit
+ // can just drop it from the ROB. This is a bit faked.
++squashed_issued;
+ ++freeEntries;
+
DPRINTF(IQ, "IQ: Issuing squashed instruction PC %#x.\n",
- issuing_inst->readPC());
+ squashed_head_inst->readPC());
break;
}
- if (list_with_oldest != None) {
+ if (list_with_oldest != None && list_with_oldest != Squashed) {
i2e_info->insts[total_issued] = issuing_inst;
i2e_info->size++;
@@ -641,8 +640,10 @@ InstructionQueue<Impl>::squash()
// Setup the squash iterator to point to the tail.
squashIt = tail;
- // Call doSquash.
- doSquash();
+ // Call doSquash if there are insts in the IQ
+ if (freeEntries != numEntries) {
+ doSquash();
+ }
// Also tell the memory dependence unit to squash.
memDepUnit.squash(squashedSeqNum);
@@ -672,12 +673,12 @@ InstructionQueue<Impl>::doSquash()
// Remove the instruction from the dependency list.
// 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();
+ if (!squashed_inst->isNonSpeculative()/* &&
+ !squashed_inst->isStore()*/
+ ) {
for (int src_reg_idx = 0;
- src_reg_idx < total_src_regs;
+ src_reg_idx < squashed_inst->numSrcRegs();
src_reg_idx++)
{
PhysRegIndex src_reg =
@@ -699,6 +700,8 @@ InstructionQueue<Impl>::doSquash()
// Might want to remove producers as well.
} else {
+ nonSpecInsts[squashed_inst->seqNum] = NULL;
+
nonSpecInsts.erase(squashed_inst->seqNum);
++iqSquashedNonSpecRemoved;
@@ -709,7 +712,11 @@ InstructionQueue<Impl>::doSquash()
// Mark it as squashed within the IQ.
squashed_inst->setSquashedInIQ();
- squashedInsts.push(squashed_inst);
+// squashedInsts.push(squashed_inst);
+ squashed_inst->setIssued();
+ squashed_inst->setCanCommit();
+
+ ++freeEntries;
DPRINTF(IQ, "IQ: Instruction PC %#x squashed.\n",
squashed_inst->readPC());
@@ -718,6 +725,13 @@ InstructionQueue<Impl>::doSquash()
--squashIt;
++iqSquashedInstsExamined;
}
+
+ assert(freeEntries <= numEntries);
+
+ if (freeEntries == numEntries) {
+ tail = cpu->instList.end();
+ }
+
}
template <class Impl>
@@ -739,8 +753,6 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
//Look at the physical destination register of the DynInst
//and look it up on the dependency graph. Then mark as ready
//any instructions within the instruction queue.
- int8_t total_dest_regs = completed_inst->numDestRegs();
-
DependencyEntry *curr;
// Tell the memory dependence unit to wake any dependents on this
@@ -751,7 +763,7 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
}
for (int dest_reg_idx = 0;
- dest_reg_idx < total_dest_regs;
+ dest_reg_idx < completed_inst->numDestRegs();
dest_reg_idx++)
{
PhysRegIndex dest_reg =
@@ -759,7 +771,7 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
// Special case of uniq or control registers. They are not
// handled by the IQ and thus have no dependency graph entry.
- // @todo Figure out a cleaner way to handle thie.
+ // @todo Figure out a cleaner way to handle this.
if (dest_reg >= numPhysRegs) {
continue;
}
@@ -789,6 +801,8 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
DependencyEntry::mem_alloc_counter--;
+ curr->inst = NULL;
+
delete curr;
}
@@ -874,7 +888,10 @@ InstructionQueue<Impl>::createDependency(DynInstPtr &new_inst)
dependGraph[dest_reg].inst = new_inst;
- assert(!dependGraph[dest_reg].next);
+ if (dependGraph[dest_reg].next) {
+ dumpDependGraph();
+ panic("IQ: Dependency graph not empty!");
+ }
// Mark the scoreboard to say it's not yet ready.
regScoreboard[dest_reg] = false;
@@ -929,34 +946,10 @@ InstructionQueue<Impl>::DependencyEntry::remove(DynInstPtr &inst_to_remove)
--mem_alloc_counter;
- delete curr;
-}
-
-template <class Impl>
-void
-InstructionQueue<Impl>::dumpDependGraph()
-{
- DependencyEntry *curr;
+ // Could push this off to the destructor of DependencyEntry
+ curr->inst = NULL;
- 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");
- }
+ delete curr;
}
template <class Impl>
@@ -1024,6 +1017,12 @@ InstructionQueue<Impl>::addIfReady(DynInstPtr &inst)
}
}
+/*
+ * Caution, this function must not be called prior to tail being updated at
+ * least once, otherwise it will fail the assertion. This is because
+ * instList.begin() actually changes upon the insertion of an element into the
+ * list when the list is empty.
+ */
template <class Impl>
int
InstructionQueue<Impl>::countInsts()
@@ -1031,6 +1030,9 @@ InstructionQueue<Impl>::countInsts()
ListIt count_it = cpu->instList.begin();
int total_insts = 0;
+ if (tail == cpu->instList.end())
+ return 0;
+
while (count_it != tail) {
if (!(*count_it)->isIssued()) {
++total_insts;
@@ -1053,6 +1055,33 @@ InstructionQueue<Impl>::countInsts()
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>::dumpLists()
{
cprintf("Ready integer list size: %i\n", readyIntInsts.size());