|  | /* | 
|  | * 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; | 
|  | } | 
|  |  | 
|  | }; |