summaryrefslogtreecommitdiff
path: root/cpu/beta_cpu/inst_queue_impl.hh
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2005-05-19 01:28:25 -0400
committerKevin Lim <ktlim@umich.edu>2005-05-19 01:28:25 -0400
commitc2fcac7c0dd8dff182cb262bdf35d5c67117aa42 (patch)
treefc8804bfbe1aa820c8afa446622b9ec8c658b75e /cpu/beta_cpu/inst_queue_impl.hh
parente5721ce6777726fa54aee49be414233656bd98d1 (diff)
downloadgem5-c2fcac7c0dd8dff182cb262bdf35d5c67117aa42.tar.xz
Fix up code for initial release. The main bug that remains is properly forwarding data from stores to loads, specifically when they are of differing sizes.
cpu/base_dyn_inst.cc: Remove unused commented out code. cpu/base_dyn_inst.hh: Fix up comments. cpu/beta_cpu/2bit_local_pred.cc: Reorder code to match header file. cpu/beta_cpu/2bit_local_pred.hh: Update comments. cpu/beta_cpu/alpha_dyn_inst.hh: Remove useless comments. cpu/beta_cpu/alpha_dyn_inst_impl.hh: cpu/beta_cpu/alpha_full_cpu_impl.hh: cpu/beta_cpu/comm.hh: cpu/beta_cpu/iew_impl.hh: Remove unused commented code. cpu/beta_cpu/alpha_full_cpu.hh: Remove obsolete comment. cpu/beta_cpu/alpha_impl.hh: cpu/beta_cpu/full_cpu.hh: Alphabetize includes. cpu/beta_cpu/bpred_unit.hh: Remove unused global history code. cpu/beta_cpu/btb.hh: cpu/beta_cpu/free_list.hh: Use full path in #defines. cpu/beta_cpu/commit.hh: cpu/beta_cpu/decode.hh: Reorder functions. cpu/beta_cpu/commit_impl.hh: Remove obsolete commented code. cpu/beta_cpu/fetch.hh: Remove obsolete comments. cpu/beta_cpu/fetch_impl.hh: cpu/beta_cpu/rename_impl.hh: Remove commented code. cpu/beta_cpu/full_cpu.cc: Remove useless defines. cpu/beta_cpu/inst_queue.hh: Use full path for #defines. cpu/beta_cpu/inst_queue_impl.hh: Reorder functions to match header file. cpu/beta_cpu/mem_dep_unit.hh: Use full path name for #defines. cpu/beta_cpu/ras.hh: Use full path names for #defines. Remove mod operation. cpu/beta_cpu/regfile.hh: Remove unused commented code, fix up current comments. cpu/beta_cpu/tournament_pred.cc: cpu/beta_cpu/tournament_pred.hh: Update programming style. --HG-- extra : convert_revision : fb9d18a853f58a1108ff827e3c123d5b52a0608a
Diffstat (limited to 'cpu/beta_cpu/inst_queue_impl.hh')
-rw-r--r--cpu/beta_cpu/inst_queue_impl.hh240
1 files changed, 116 insertions, 124 deletions
diff --git a/cpu/beta_cpu/inst_queue_impl.hh b/cpu/beta_cpu/inst_queue_impl.hh
index d4e3939cf..9f7f13387 100644
--- a/cpu/beta_cpu/inst_queue_impl.hh
+++ b/cpu/beta_cpu/inst_queue_impl.hh
@@ -1,6 +1,3 @@
-#ifndef __INST_QUEUE_IMPL_HH__
-#define __INST_QUEUE_IMPL_HH__
-
// 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
@@ -171,6 +168,13 @@ InstructionQueue<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
fromCommit = timeBuffer->getWire(-commitToIEWDelay);
}
+template <class Impl>
+unsigned
+InstructionQueue<Impl>::numFreeEntries()
+{
+ return freeEntries;
+}
+
// Might want to do something more complex if it knows how many instructions
// will be issued this cycle.
template <class Impl>
@@ -185,13 +189,6 @@ InstructionQueue<Impl>::isFull()
}
template <class Impl>
-unsigned
-InstructionQueue<Impl>::numFreeEntries()
-{
- return freeEntries;
-}
-
-template <class Impl>
void
InstructionQueue<Impl>::insert(DynInstPtr &new_inst)
{
@@ -562,7 +559,6 @@ InstructionQueue<Impl>::scheduleReadyInsts()
break;
case Squashed:
-// 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
@@ -621,6 +617,77 @@ InstructionQueue<Impl>::scheduleNonSpec(const InstSeqNum &inst)
template <class Impl>
void
+InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
+{
+ DPRINTF(IQ, "IQ: Waking dependents of completed instruction.\n");
+ //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.
+ 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 < completed_inst->numDestRegs();
+ dest_reg_idx++)
+ {
+ PhysRegIndex dest_reg =
+ completed_inst->renamedDestRegIdx(dest_reg_idx);
+
+ // 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 this.
+ if (dest_reg >= numPhysRegs) {
+ continue;
+ }
+
+ DPRINTF(IQ, "IQ: Waking any dependents on register %i.\n",
+ (int) dest_reg);
+
+ //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) {
+
+ curr = dependGraph[dest_reg].next;
+
+ DPRINTF(IQ, "IQ: Waking up a dependent instruction, PC%#x.\n",
+ curr->inst->readPC());
+
+ // Might want to give more information to the instruction
+ // so that it knows which of its source registers is ready.
+ // However that would mean that the dependency graph entries
+ // would need to hold the src_reg_idx.
+ curr->inst->markSrcRegReady();
+
+ addIfReady(curr->inst);
+
+ dependGraph[dest_reg].next = curr->next;
+
+ DependencyEntry::mem_alloc_counter--;
+
+ curr->inst = NULL;
+
+ delete curr;
+ }
+
+ // Reset the head node now that all of its dependents have been woken
+ // up.
+ dependGraph[dest_reg].next = NULL;
+ dependGraph[dest_reg].inst = NULL;
+
+ // Mark the scoreboard as having that register ready.
+ regScoreboard[dest_reg] = true;
+ }
+}
+
+template <class Impl>
+void
InstructionQueue<Impl>::violation(DynInstPtr &store,
DynInstPtr &faulting_load)
{
@@ -747,73 +814,56 @@ InstructionQueue<Impl>::stopSquash()
template <class Impl>
void
-InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
+InstructionQueue<Impl>::DependencyEntry::insert(DynInstPtr &new_inst)
{
- DPRINTF(IQ, "IQ: Waking dependents of completed instruction.\n");
- //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.
- 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 < completed_inst->numDestRegs();
- dest_reg_idx++)
- {
- PhysRegIndex dest_reg =
- completed_inst->renamedDestRegIdx(dest_reg_idx);
-
- // 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 this.
- if (dest_reg >= numPhysRegs) {
- continue;
- }
-
- DPRINTF(IQ, "IQ: Waking any dependents on register %i.\n",
- (int) dest_reg);
+ //Add this new, dependent instruction at the head of the dependency
+ //chain.
- //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) {
+ // First create the entry that will be added to the head of the
+ // dependency chain.
+ DependencyEntry *new_entry = new DependencyEntry;
+ new_entry->next = this->next;
+ new_entry->inst = new_inst;
- curr = dependGraph[dest_reg].next;
+ // Then actually add it to the chain.
+ this->next = new_entry;
- DPRINTF(IQ, "IQ: Waking up a dependent instruction, PC%#x.\n",
- curr->inst->readPC());
+ ++mem_alloc_counter;
+}
- // Might want to give more information to the instruction
- // so that it knows which of its source registers is ready.
- // However that would mean that the dependency graph entries
- // would need to hold the src_reg_idx.
- curr->inst->markSrcRegReady();
+template <class Impl>
+void
+InstructionQueue<Impl>::DependencyEntry::remove(DynInstPtr &inst_to_remove)
+{
+ DependencyEntry *prev = this;
+ DependencyEntry *curr = this->next;
- addIfReady(curr->inst);
+ // Make sure curr isn't NULL. Because this instruction is being
+ // removed from a dependency list, it must have been placed there at
+ // an earlier time. The dependency chain should not be empty,
+ // unless the instruction dependent upon it is already ready.
+ if (curr == NULL) {
+ return;
+ }
- dependGraph[dest_reg].next = curr->next;
+ // Find the instruction to remove within the dependency linked list.
+ while(curr->inst != inst_to_remove)
+ {
+ prev = curr;
+ curr = curr->next;
- DependencyEntry::mem_alloc_counter--;
+ assert(curr != NULL);
+ }
- curr->inst = NULL;
+ // Now remove this instruction from the list.
+ prev->next = curr->next;
- delete curr;
- }
+ --mem_alloc_counter;
- // Reset the head node now that all of its dependents have been woken
- // up.
- dependGraph[dest_reg].next = NULL;
- dependGraph[dest_reg].inst = NULL;
+ // Could push this off to the destructor of DependencyEntry
+ curr->inst = NULL;
- // Mark the scoreboard as having that register ready.
- regScoreboard[dest_reg] = true;
- }
+ delete curr;
}
template <class Impl>
@@ -900,60 +950,6 @@ InstructionQueue<Impl>::createDependency(DynInstPtr &new_inst)
template <class Impl>
void
-InstructionQueue<Impl>::DependencyEntry::insert(DynInstPtr &new_inst)
-{
- //Add this new, dependent instruction at the head of the dependency
- //chain.
-
- // First create the entry that will be added to the head of the
- // dependency chain.
- DependencyEntry *new_entry = new DependencyEntry;
- new_entry->next = this->next;
- new_entry->inst = new_inst;
-
- // Then actually add it to the chain.
- this->next = new_entry;
-
- ++mem_alloc_counter;
-}
-
-template <class Impl>
-void
-InstructionQueue<Impl>::DependencyEntry::remove(DynInstPtr &inst_to_remove)
-{
- DependencyEntry *prev = this;
- DependencyEntry *curr = this->next;
-
- // Make sure curr isn't NULL. Because this instruction is being
- // removed from a dependency list, it must have been placed there at
- // an earlier time. The dependency chain should not be empty,
- // unless the instruction dependent upon it is already ready.
- if (curr == NULL) {
- return;
- }
-
- // Find the instruction to remove within the dependency linked list.
- while(curr->inst != inst_to_remove)
- {
- prev = curr;
- curr = curr->next;
-
- assert(curr != NULL);
- }
-
- // Now remove this instruction from the list.
- prev->next = curr->next;
-
- --mem_alloc_counter;
-
- // Could push this off to the destructor of DependencyEntry
- curr->inst = NULL;
-
- delete curr;
-}
-
-template <class Impl>
-void
InstructionQueue<Impl>::addIfReady(DynInstPtr &inst)
{
//If the instruction now has all of its source registers
@@ -1090,8 +1086,6 @@ InstructionQueue<Impl>::dumpLists()
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());
@@ -1110,5 +1104,3 @@ InstructionQueue<Impl>::dumpLists()
cprintf("\n");
}
-
-#endif // __INST_QUEUE_IMPL_HH__