| /* |
| * Copyright (c) 2007 MIPS Technologies, Inc. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer; |
| * redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution; |
| * neither the name of the copyright holders nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| * Authors: Korey Sewell |
| * |
| */ |
| |
| #include "cpu/inorder/pipeline_traits.hh" |
| #include "cpu/inorder/inorder_dyn_inst.hh" |
| #include "cpu/inorder/resources/resource_list.hh" |
| |
| using namespace std; |
| |
| namespace ThePipeline { |
| |
| //@TODO: create my own Instruction Schedule Class |
| //that operates as a Priority QUEUE |
| int getNextPriority(DynInstPtr &inst, int stage_num) |
| { |
| int cur_pri = 20; |
| |
| /* |
| std::priority_queue<ScheduleEntry*, std::vector<ScheduleEntry*>, |
| entryCompare>::iterator sked_it = inst->resSched.begin(); |
| |
| std::priority_queue<ScheduleEntry*, std::vector<ScheduleEntry*>, |
| entryCompare>::iterator sked_end = inst->resSched.end(); |
| |
| while (sked_it != sked_end) { |
| |
| if (sked_it.top()->stageNum == stage_num) { |
| cur_pri = sked_it.top()->priority; |
| } |
| |
| sked_it++; |
| } |
| */ |
| |
| return cur_pri; |
| } |
| |
| void createFrontEndSchedule(DynInstPtr &inst) |
| { |
| InstStage *I = inst->addStage(); |
| InstStage *E = inst->addStage(); |
| |
| I->needs(FetchSeq, FetchSeqUnit::AssignNextPC); |
| I->needs(ICache, CacheUnit::InitiateFetch); |
| |
| E->needs(ICache, CacheUnit::CompleteFetch); |
| E->needs(Decode, DecodeUnit::DecodeInst); |
| E->needs(BPred, BranchPredictor::PredictBranch); |
| E->needs(FetchSeq, FetchSeqUnit::UpdateTargetPC); |
| } |
| |
| bool createBackEndSchedule(DynInstPtr &inst) |
| { |
| if (!inst->staticInst) { |
| return false; |
| } |
| |
| InstStage *E = inst->currentStage(); |
| InstStage *M = inst->addStage(); |
| InstStage *A = inst->addStage(); |
| InstStage *W = inst->addStage(); |
| |
| for (int idx=0; idx < inst->numSrcRegs(); idx++) { |
| if (!idx || !inst->isStore()) { |
| E->needs(RegManager, UseDefUnit::ReadSrcReg, idx); |
| } |
| } |
| |
| |
| if ( inst->isNonSpeculative() ) { |
| // skip execution of non speculative insts until later |
| } else if ( inst->isMemRef() ) { |
| if ( inst->isLoad() ) { |
| E->needs(AGEN, AGENUnit::GenerateAddr); |
| E->needs(DCache, CacheUnit::InitiateReadData); |
| } |
| } else if (inst->opClass() == IntMultOp || inst->opClass() == IntDivOp) { |
| E->needs(MDU, MultDivUnit::StartMultDiv); |
| } else { |
| E->needs(ExecUnit, ExecutionUnit::ExecuteInst); |
| } |
| |
| if (inst->opClass() == IntMultOp || inst->opClass() == IntDivOp) { |
| M->needs(MDU, MultDivUnit::EndMultDiv); |
| } |
| |
| if ( inst->isLoad() ) { |
| M->needs(DCache, CacheUnit::CompleteReadData); |
| } else if ( inst->isStore() ) { |
| M->needs(RegManager, UseDefUnit::ReadSrcReg, 1); |
| M->needs(AGEN, AGENUnit::GenerateAddr); |
| M->needs(DCache, CacheUnit::InitiateWriteData); |
| } |
| |
| if ( inst->isStore() ) { |
| A->needs(DCache, CacheUnit::CompleteWriteData); |
| } |
| |
| if ( inst->isNonSpeculative() ) { |
| if ( inst->isMemRef() ) fatal("Non-Speculative Memory Instruction"); |
| W->needs(ExecUnit, ExecutionUnit::ExecuteInst); |
| } |
| |
| for (int idx=0; idx < inst->numDestRegs(); idx++) { |
| W->needs(RegManager, UseDefUnit::WriteDestReg, idx); |
| } |
| |
| W->needs(Grad, GraduationUnit::GraduateInst); |
| |
| return true; |
| } |
| |
| InstStage::InstStage(DynInstPtr inst, int stage_num) |
| { |
| stageNum = stage_num; |
| nextTaskPriority = 0; |
| instSched = &inst->resSched; |
| } |
| |
| }; |