diff options
Diffstat (limited to 'src/cpu/inorder/pipeline_traits.cc')
-rw-r--r-- | src/cpu/inorder/pipeline_traits.cc | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/src/cpu/inorder/pipeline_traits.cc b/src/cpu/inorder/pipeline_traits.cc new file mode 100644 index 000000000..eb899452a --- /dev/null +++ b/src/cpu/inorder/pipeline_traits.cc @@ -0,0 +1,153 @@ +/* + * 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(ITLB, TLBUnit::FetchLookup); + 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() ) { + E->needs(AGEN, AGENUnit::GenerateAddr); + if ( inst->isLoad() ) { + E->needs(DTLB, TLBUnit::DataLookup); + E->needs(DCache, CacheUnit::InitiateReadData); + } + } else if (inst->opClass() == IntMultOp || inst->opClass() == IntDivOp) { + E->needs(MDU, MultDivUnit::StartMultDiv); + + // ZERO-LATENCY Multiply: + // E->needs(MDU, MultDivUnit::MultDiv); + } 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(DTLB, TLBUnit::DataLookup); + 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; +} + +}; |