⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exec.cc

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 CC
📖 第 1 页 / 共 4 页
字号:
      (proc->UnitsFree[inst->unit_type])--;   // uMEM doesn't use this here      if (STALL_ON_FULL)        {	  proc->active_instr[inst->unit_type]--;          inst->issuetime = proc->curr_cycle;         }    }    //-------------------------------------------------------------------------  /// issue memory instruction  else    {      // do it based on uADDR instead      proc->ReadyQueues[uADDR].Insert(insttagged);       (proc->UnitsFree[uADDR])--;      if (stat_sched)                   // uADDR is also statically scheduled        {          inst->addrissuetime = proc->curr_cycle;        }    }}/* * Simulate the time spent in execution;move instructions from the  * ReadyQueues to the Running queues, and similarly, move functional  * units off  FreeingUnits. */void IssueQueues(ProcState * proc){  tagged_inst instt;  instance *inst;  UTYPE unit_type;#ifdef COREFILE  if (proc->curr_cycle > DEBUG_TIME)    fprintf(corefile, "Issuing cycle %d\n", proc->curr_cycle);#endif  for (unit_type = UTYPE(0);       unit_type < uMEM;       unit_type = UTYPE(int(unit_type)+1))    {      circq<tagged_inst> *q = &(proc->ReadyQueues[unit_type]);      while (q->NumInQueue())    // we have already checked proc->UnitsFree[unit_type]	{	  q->Delete(instt);              	  if (!instt.ok())	    { #ifdef COREFILE	      if (proc->curr_cycle > DEBUG_TIME)		fprintf(corefile,			"Nonmatching entry in ReadyQueue -- was %d, now %d\n",			instt.inst_tag,			instt.inst->tag);#endif                  	      LetOneUnitStalledGuyGo(proc, unit_type);	      continue;	    } 	  inst = instt.inst;	  if (repeat[unit_type])	    proc->FreeingUnits.insert(proc->curr_cycle + repeat[unit_type],unit_type);	  else	    (*(repfuncs[unit_type]))(inst,proc);              	  if (latencies[unit_type])              // deterministic latency	    proc->Running.insert(proc->curr_cycle + latencies[unit_type],				 inst,				 inst->tag);	  else	    (*(latfuncs[unit_type]))(inst,proc);	}    }}/* * Move things from Running queues to Done heap, also issue instructions  * for units that are freed up. Take off the heap of running instructions * that completed in time for the next cycle. Also free up the  * appropriate units  */void CompleteQueues(ProcState * proc){  long long cycle = proc->curr_cycle;  UTYPE     func_unit;  instance *inst;  long long inst_tag;  while (proc->Running.num() != 0 && proc->Running.PeekMin() <= cycle)    {      proc->Running.GetMin(inst, inst_tag);       // first check to see if it's been flushed       if (inst_tag != inst->tag)	{	  // it's been flushed #ifdef COREFILE	  if (proc->curr_cycle > DEBUG_TIME)	    fprintf(corefile,		    "Got nonmatching tag %d off Running\n",		    inst_tag);#endif	  continue;	}        if (inst->unit_type != uMEM)        {          (*(instr_func[inst->code.instruction]))(inst,proc);#if 0 #ifdef COREFILE          if (inst->unit_type != uMEM || !IsStore(inst) || IsRMW(inst) )            {              if (proc->curr_cycle > DEBUG_TIME)                InstCompletionMessage(inst,proc);            }#endif#endif          proc->DoneHeap.insert(cycle, inst, inst->tag);        }       else        {          // if it's a uMEM, it must just be an address generation thing#ifdef COREFILE          if (proc->curr_cycle > DEBUG_TIME)            fprintf(corefile,"Address generated for tag %d\n",inst->tag);#endif          Disambiguate(inst, proc);        }    }   while (proc->FreeingUnits.num() != 0 &&	 proc->FreeingUnits.PeekMin() <= cycle)    {      proc->FreeingUnits.GetMin(func_unit);      LetOneUnitStalledGuyGo(proc, func_unit);    }}/* * Updates the result registers/branch prediction tables that are changed  * as a result of the instruction. */int update_cycle(ProcState * proc){  instance *inst;  long long inst_tag;   // Let us first check for the case when the branch was the last  // instruction of the previous cycle, it may have completed  // by now, so we need to look at this NOW!      int over = 0;  // Get everything corresponding to this cycle  while (over != 1)    {      if ((proc->DoneHeap.num() == 0) ||          (proc->DoneHeap.PeekMin() > proc->curr_cycle))	return 0;#ifdef DEBUG      if (proc->DoneHeap.GetMin(inst,inst_tag) != proc->curr_cycle)        {          // don't flag it otherwise, as that would just be a flush on	  // exception or some such....          if (inst->tag == inst_tag)            {#ifdef COREFILE              if (proc->curr_cycle > DEBUG_TIME)                fprintf(corefile,                        "<decode.cc>Something is wrong! We have ignored some executions \for several cycles -- tag %d at %d!\n",                        inst->tag,                        proc->curr_cycle); #endif              YS__errmsg(proc->proc_id / ARCH_cpus,			 " Ignored executions in %s\n", __FILE__);              continue;            }        }#else      proc->DoneHeap.GetMin(inst, inst_tag);#endif      // if inst->tag != inst_tag, then it is an instruction that has      // already been flushed out and we can ignore it      if (inst->tag == inst_tag)        {#ifdef COREFILE          if (proc->curr_cycle > DEBUG_TIME)            {              fprintf(corefile, "INST %p - \n", inst);              fprintf(corefile,"Marking tag %d as done\n", inst->tag);            }#endif          if (proc->stall_the_rest == inst->tag &&              !inst->branchdep &&              !proc->unpredbranch)            unstall_the_rest(proc);              // the instruction completed                     // Check if it is a branch instruction          if (inst->code.cond_branch != 0 || inst->code.uncond_branch != 0)            {              if (inst->branchdep == 1)        // used for unpredicted branches                {                  // This is most probably an unconditional branch                  // This is an instruction because of which the rest of                  // the other instructions are stalled and waiting,                  // lets update the pc                   if (inst->code.annul || inst->tag+1 != proc->instruction_count)                    // no delay slot remaining                    {                      proc->pc = inst->newpc;   // This would have been filled		                                // at execution time                      proc->npc = proc->pc + SIZE_OF_SPARC_INSTRUCTION;                    }                  else                    // delay slot still waiting to issue                    {                      proc->pc = inst->pc+SIZE_OF_SPARC_INSTRUCTION;		      // should have already been set this way                      proc->npc = inst->newpc;                    }		                    // Note: if there was a delay slot, we also need to fill in                  // that one's NPC value...                   HandleUnPredicted(inst, proc);                  proc->unpredbranch = 0;         // go back to normal fetching, etc                   if (proc->stall_the_rest == inst->tag ||                      proc->type_of_stall_rest == eBADBR)                    {                      // either on this tag itself or on the delay slot                      // but for this tag                      unstall_the_rest(proc);                    }                }                // Check if we did any fancy predictions              if (inst->code.uncond_branch != 2 &&                  inst->code.uncond_branch != 3 &&                  inst->branchdep != 1)                {                  // YES                  if (inst->mispredicted == 0)                    {#ifdef COREFILE                      if (proc->curr_cycle > DEBUG_TIME)                        fprintf(corefile,                                "Predicted branch correctly - tag %d\n",                                inst->tag);#endif                      // No error in our prediction                      // Delete the corresponding mapper table                       GoodPrediction(inst, proc);                                            // Go on and graduate it as usual                    }                   else                    {                      // Error in prediction #ifdef COREFILE                      if (proc->curr_cycle > DEBUG_TIME)                        fprintf(corefile,                                "Mispredicted %s - tag %d\n",                                (inst->code.uncond_branch == 4)? "return" : "branch",                                inst->tag);#endif                                            int origpred = inst->taken;                                    // Now set pc and npc appropriately                       if (proc->copymappernext && inst->tag+1==proc->instruction_count)                        {                          // in this case, we have decoded and                          // completed the branch, but still haven't                          // gotten the delay slot instruction. So, we                          // need to set pc for the delay slot and set                          // npc for the branch target                          proc->pc = inst->pc+SIZE_OF_SPARC_INSTRUCTION;			  // this should have already been that			  // way, but anyway...                          proc->npc = inst->newpc;                        }                                            else if (inst->code.annul &&			       inst->code.cond_branch && !origpred)                        {                          // In this case, we had originally predicted                          // an annulled branch to be not-taken, but                          // it ended up being taken.  In this case,                          // the upcoming pc needs to go to the delay                          // slot, while the npc needs to point to the                          // branch target                          proc->pc = inst->pc + SIZE_OF_SPARC_INSTRUCTION;                          proc->npc = inst->newpc;                        }                                            else                        {                          // in any other circumstance, we go to the                          // branch target and continue execution from                          // there                          proc->pc = inst->newpc;                          proc->npc = proc->pc+SIZE_OF_SPARC_INSTRUCTION;                        }                                            BadPrediction(inst, proc);                      // continue;  // return (0);                    }                 }                               // End of if for predictions                          }          	  //-----------------------------------------------------------------	  // do not clear dependencies if instruction triggers a hard	  // exception since the exception handler might change global state	  if ((inst->exception_code != OK) &&	      (inst->exception_code != SOFT_LIMBO) &&	      (inst->exception_code != SOFT_SL_COHE) &&	      (inst->exception_code != SOFT_SL_REPL))	    {	      proc->active_list.mark_done_in_active_list(inst->tag,							 inst->exception_code,							 proc->curr_cycle);	      continue;	    }	            //-------------------------------------------------------------------          // Look at destination registers          // make them not busy          // Update physical register file                    if (inst->code.rd_regtype == REG_INT ||	      inst->code.rd_regtype == REG_INT64)            {              if (inst->prd != 0)                proc->phy_int_reg_file[inst->prd] = inst->rdvali;              proc->intregbusy[inst->prd] = 0;              proc->dist_stallq_int[inst->prd].ClearAll(proc);            }           else if (inst->code.rd_regtype == REG_FP)            {              proc->phy_fp_reg_file[inst->prd] = inst->rdvalf;              proc->fpregbusy[inst->prd] = 0;              proc->dist_stallq_fp[inst->prd].ClearAll(proc);	      proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc,							proc->cwp,							STATE_FPRS)]] |=		inst->code.rd >= 32 ? FPRS_DU : FPRS_DL;            }                    else if (inst->code.rd_regtype == REG_FPHALF)            {              proc->phy_fp_reg_file[inst->prd] = inst->rsdvalf;              float *address = (float *) (&proc->phy_fp_reg_file[inst->prd]);#ifdef ENDIAN_SWAP              if (!(inst->code.rd & 1))                       // the odd half                address += 1;#else              if (inst->code.rd & 1)                          // the odd half                address += 1;#endif                    *address = inst->rdvalfh;              proc->fpregbusy[inst->prd] = 0;              proc->dist_stallq_fp[inst->prd].ClearAll(proc);	      proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc,							proc->cwp,							STATE_FPRS)]] |=		FPRS_DL;	    }           else if (inst->code.rd_regtype == REG_INTPAIR)            {              if (inst->prd != 0)                proc->phy_int_reg_file[inst->prd] = inst->rdvalipair.a;              proc->phy_int_reg_file[inst->prdp] = inst->rdvalipair.b;              proc->intregbusy[inst->prd] = 0;              proc->intregbusy[inst->prdp] = 0;              proc->dist_stallq_int[inst->prd].ClearAll(proc);              proc->dist_stallq_int[inst->prdp].ClearAll(proc);            }           // Do the same for rcc too.          if (inst->prcc != 0)            proc->phy_int_reg_file[inst->prcc] = inst->rccvali;          proc->intregbusy[inst->prcc] = 0;          proc->dist_stallq_int[inst->prcc].ClearAll(proc);                    // Update active list to show done and exception          proc->active_list.mark_done_in_active_list(inst->tag,						     inst->exception_code,						     proc->curr_cycle);        }            else // the instruction has already been killed in some way        { #ifdef COREFILE          if (proc->curr_cycle > DEBUG_TIME)            fprintf(corefile,"Got nonmatching tag %d off Doneheap\n",inst_tag);#endif         }    }    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -