+RSkedPtr
+InOrderCPU::createBackEndSked(DynInstPtr inst)
+{
+ RSkedPtr res_sked = lookupSked(inst);
+ if (res_sked != NULL) {
+ DPRINTF(SkedCache, "Found %s in sked cache.\n",
+ inst->instName());
+ return res_sked;
+ } else {
+ res_sked = new ResourceSked();
+ }
+
+ int stage_num = ThePipeline::BackEndStartStage;
+ StageScheduler X(res_sked, stage_num++);
+ StageScheduler M(res_sked, stage_num++);
+ StageScheduler W(res_sked, stage_num++);
+
+ if (!inst->staticInst) {
+ warn_once("Static Instruction Object Not Set. Can't Create"
+ " Back End Schedule");
+ return NULL;
+ }
+
+ // EXECUTE
+ X.needs(RegManager, UseDefUnit::MarkDestRegs);
+ for (int idx=0; idx < inst->numSrcRegs(); idx++) {
+ if (!idx || !inst->isStore()) {
+ X.needs(RegManager, UseDefUnit::ReadSrcReg, idx);
+ }
+ }
+
+ //@todo: schedule non-spec insts to operate on this cycle
+ // as long as all previous insts are done
+ if ( inst->isNonSpeculative() ) {
+ // skip execution of non speculative insts until later
+ } else if ( inst->isMemRef() ) {
+ if ( inst->isLoad() ) {
+ X.needs(AGEN, AGENUnit::GenerateAddr);
+ }
+ } else if (inst->opClass() == IntMultOp || inst->opClass() == IntDivOp) {
+ X.needs(MDU, MultDivUnit::StartMultDiv);
+ } else {
+ X.needs(ExecUnit, ExecutionUnit::ExecuteInst);
+ }
+
+ // MEMORY
+ if (!inst->isNonSpeculative()) {
+ if (inst->opClass() == IntMultOp || inst->opClass() == IntDivOp) {
+ M.needs(MDU, MultDivUnit::EndMultDiv);
+ }
+
+ if ( inst->isLoad() ) {
+ M.needs(DCache, CacheUnit::InitiateReadData);
+ if (inst->splitInst)
+ M.needs(DCache, CacheUnit::InitSecondSplitRead);
+ } else if ( inst->isStore() ) {
+ for (int i = 1; i < inst->numSrcRegs(); i++ ) {
+ M.needs(RegManager, UseDefUnit::ReadSrcReg, i);
+ }
+ M.needs(AGEN, AGENUnit::GenerateAddr);
+ M.needs(DCache, CacheUnit::InitiateWriteData);
+ if (inst->splitInst)
+ M.needs(DCache, CacheUnit::InitSecondSplitWrite);
+ }
+ }
+
+ // WRITEBACK
+ if (!inst->isNonSpeculative()) {
+ if ( inst->isLoad() ) {
+ W.needs(DCache, CacheUnit::CompleteReadData);
+ if (inst->splitInst)
+ W.needs(DCache, CacheUnit::CompleteSecondSplitRead);
+ } else if ( inst->isStore() ) {
+ W.needs(DCache, CacheUnit::CompleteWriteData);
+ if (inst->splitInst)
+ W.needs(DCache, CacheUnit::CompleteSecondSplitWrite);
+ }
+ } else {
+ // Finally, Execute Speculative Data
+ if (inst->isMemRef()) {
+ if (inst->isLoad()) {
+ W.needs(AGEN, AGENUnit::GenerateAddr);
+ W.needs(DCache, CacheUnit::InitiateReadData);
+ if (inst->splitInst)
+ W.needs(DCache, CacheUnit::InitSecondSplitRead);
+ W.needs(DCache, CacheUnit::CompleteReadData);
+ if (inst->splitInst)
+ W.needs(DCache, CacheUnit::CompleteSecondSplitRead);
+ } else if (inst->isStore()) {
+ if ( inst->numSrcRegs() >= 2 ) {
+ W.needs(RegManager, UseDefUnit::ReadSrcReg, 1);
+ }
+ W.needs(AGEN, AGENUnit::GenerateAddr);
+ W.needs(DCache, CacheUnit::InitiateWriteData);
+ if (inst->splitInst)
+ W.needs(DCache, CacheUnit::InitSecondSplitWrite);
+ W.needs(DCache, CacheUnit::CompleteWriteData);
+ if (inst->splitInst)
+ W.needs(DCache, CacheUnit::CompleteSecondSplitWrite);
+ }
+ } else {
+ W.needs(ExecUnit, ExecutionUnit::ExecuteInst);
+ }
+ }
+
+ W.needs(Grad, GraduationUnit::CheckFault);
+
+ for (int idx=0; idx < inst->numDestRegs(); idx++) {
+ W.needs(RegManager, UseDefUnit::WriteDestReg, idx);
+ }
+
+ if (inst->isControl())
+ W.needs(BPred, BranchPredictor::UpdatePredictor);
+
+ W.needs(Grad, GraduationUnit::GraduateInst);
+
+ // Insert Back Schedule into our cache of
+ // resource schedules
+ addToSkedCache(inst, res_sked);
+
+ DPRINTF(SkedCache, "Back End Sked Created for instruction: %s (%08p)\n",
+ inst->instName(), inst->getMachInst());
+ res_sked->print();
+
+ return res_sked;
+}