From 61d95de4c886911fa0b7dc9d587ffe5b292b739e Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 3 May 2005 10:56:47 -0400 Subject: Large update of several parts of my code. The most notable change is the inclusion of a full-fledged load/store queue. At the moment it still has some issues running, but most of the code is hopefully close to the final version. SConscript: arch/isa_parser.py: cpu/base_dyn_inst.cc: Remove OOO CPU stuff. arch/alpha/faults.hh: Add fake memory fault. This will be removed eventually. arch/alpha/isa_desc: Change EA comp and Mem accessor to be const StaticInstPtrs. cpu/base_dyn_inst.hh: Update read/write calls to use load queue and store queue indices. cpu/beta_cpu/alpha_dyn_inst.hh: Change to const StaticInst in the register accessors. cpu/beta_cpu/alpha_dyn_inst_impl.hh: Update syscall code with thread numbers. cpu/beta_cpu/alpha_full_cpu.hh: Alter some of the full system code so it will compile without errors. cpu/beta_cpu/alpha_full_cpu_builder.cc: Created a DerivAlphaFullCPU class so I can instantiate different CPUs that have different template parameters. cpu/beta_cpu/alpha_full_cpu_impl.hh: Update some of the full system code so it compiles. cpu/beta_cpu/alpha_params.hh: cpu/beta_cpu/fetch_impl.hh: Remove asid. cpu/beta_cpu/comm.hh: Remove global history field. cpu/beta_cpu/commit.hh: Comment out rename map. cpu/beta_cpu/commit_impl.hh: Update some of the full system code so it compiles. Also change it so that it handles memory instructions properly. cpu/beta_cpu/cpu_policy.hh: Removed IQ from the IEW template parameter to make it more uniform. cpu/beta_cpu/decode.hh: Add debug function. cpu/beta_cpu/decode_impl.hh: Slight updates for decode in the case where it causes a squash. cpu/beta_cpu/fetch.hh: cpu/beta_cpu/rob.hh: Comment out unneccessary code. cpu/beta_cpu/full_cpu.cc: Changed some of the full system code so it compiles. Updated exec contexts and so forth to hopefully make multithreading easier. cpu/beta_cpu/full_cpu.hh: Updated some of the full system code to make it compile. cpu/beta_cpu/iew.cc: Removed IQ from template parameter to IEW. cpu/beta_cpu/iew.hh: Removed IQ from template parameter to IEW. Updated IEW to recognize the Load/Store queue. cpu/beta_cpu/iew_impl.hh: New handling of memory instructions through the Load/Store queue. cpu/beta_cpu/inst_queue.hh: Updated comment. cpu/beta_cpu/inst_queue_impl.hh: Slightly different handling of memory instructions due to Load/Store queue. cpu/beta_cpu/regfile.hh: Updated full system code so it compiles. cpu/beta_cpu/rob_impl.hh: Moved some code around; no major functional changes. cpu/ooo_cpu/ooo_cpu.hh: Slight updates to OOO CPU; still does not work. cpu/static_inst.hh: Remove OOO CPU stuff. Change ea comp and mem acc to return const StaticInst. kern/kernel_stats.hh: Extra forward declares added due to compile error. --HG-- extra : convert_revision : 594a7cdbe57f6c2bda7d08856fcd864604a6238e --- cpu/beta_cpu/inst_queue_impl.hh | 125 +++++++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 48 deletions(-) (limited to 'cpu/beta_cpu/inst_queue_impl.hh') 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::InstructionQueue(Params ¶ms) 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::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::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::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::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::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::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::doSquash() --squashIt; ++iqSquashedInstsExamined; } + + assert(freeEntries <= numEntries); + + if (freeEntries == numEntries) { + tail = cpu->instList.end(); + } + } template @@ -739,8 +753,6 @@ InstructionQueue::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::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::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::wakeDependents(DynInstPtr &completed_inst) DependencyEntry::mem_alloc_counter--; + curr->inst = NULL; + delete curr; } @@ -874,7 +888,10 @@ InstructionQueue::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::DependencyEntry::remove(DynInstPtr &inst_to_remove) --mem_alloc_counter; - delete curr; -} - -template -void -InstructionQueue::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 @@ -1024,6 +1017,12 @@ InstructionQueue::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 int InstructionQueue::countInsts() @@ -1031,6 +1030,9 @@ InstructionQueue::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; @@ -1051,6 +1053,33 @@ InstructionQueue::countInsts() return total_insts; } +template +void +InstructionQueue::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 void InstructionQueue::dumpLists() -- cgit v1.2.3