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

📄 branchpred.cc

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 CC
📖 第 1 页 / 共 2 页
字号:
  inst2->npc = proc->pc;         if (inst2->branchdep == 2)    {#ifdef DEBUG      if (proc->stall_the_rest != inst2->tag)	YS__errmsg(proc->proc_id / ARCH_cpus,		   "BRANCH STALLING ERROR P%d(%lld/%d) %s:%d!!", 		   proc->proc_id, inst->tag, inst->pc, __FILE__, __LINE__);#endif            if (!STALL_ON_FULL || proc->type_of_stall_rest != eMEMQFULL)	unstall_the_rest(proc);      inst2->branchdep = 0;      instance *inst3 = proc->BranchDepQ.GetNext(proc);   #ifdef DEBUG      // result should be inst2 itself, if anything      if (inst3 && inst3->tag != inst2->tag)	/* wouldn't have been in branchq on renaming stall */	YS__errmsg(proc->proc_id / ARCH_cpus,		   "BRANCH STALLING ERROR P%d(%lld/%d) %s:%d!!", 		   proc->proc_id, inst->tag, inst->pc, __FILE__, __LINE__);#endif            if (inst3)	inst3->stallqs--;    }  else    // Copy the corresponding mapper entry to the original mappers    // Also copy the busy state of the integers at that instant    CopyBranchQ(tag_to_use, proc);  // Flush the mapper tables to remove this and later branches if any  FlushBranchQ(tag_to_use, proc);  // We should flush the memory queue too so that the loads and stores dont  // keep waiting to verify that the branch is done or not...  FlushMems(tag_to_use, proc);  // Flush all entries in the stallQ which were sent in after the branch.  // Must be flushed before active list since some entries in stallQ are not  // in active list.  FlushStallQ(tag_to_use, proc);  FlushFetchQ(proc);    // Flush the active list to remove any entries after the branch   // While flushing, put back the registers in the free list  int pre = proc->active_list.NumElements();  FlushActiveList(tag_to_use, proc);  int post = proc->active_list.NumElements();#ifndef NOSTAT  StatrecUpdate(proc->BadPredFlushes, pre - post, 1);#endif    return;}/* * we assume that proc->pc and proc->npc have been set properly before * calling HandleUnPredicted  */void HandleUnPredicted(instance * inst, ProcState * proc){  long long tag_to_use = inst->tag;  instance *inst2;  if (inst->code.annul == 0)    {      tag_to_use = inst->tag + 1;      inst2 = convert_tag_to_inst(tag_to_use, proc);    }  else    inst2 = inst;  if (tag_to_use == proc->instruction_count)    // The delay slot has not been issued yet!    return;  // to indicate that the next instruction after this one is the point from  // which the processor will be fetching after this misprediction  inst2->npc = proc->pc;  inst2->branchdep = 0;}/* * FlushBranchQ : Flush all elements (shadow mappers) in the branchq */void FlushBranchQ(long long tag, ProcState *proc){  BranchQElement *junk;  while (proc->branchq.NumItems())    {      proc->branchq.GetTail(junk);      if (junk->tag >= tag)	{	  proc->branchq.RemoveTail();	  DeleteMapTable(junk->specmap, proc);	  DeleteBranchQElement(junk, proc);	}      else	break;    }}void FlushFetchQ(ProcState *proc){  Queue<fetch_queue_entry> *fetch_queue = proc->fetch_queue;  fetch_queue_entry fqe;  while (!fetch_queue->Empty())    {      fetch_queue->GetHead(fqe);      DeleteInstance(fqe.inst, proc);      fetch_queue->Dequeue();    }}/* * GetElement : Get branch queue element that matches given tag  */BranchQElement *GetElement(long long tag, ProcState * proc){  MemQLink<BranchQElement *> *stepper = NULL;  BranchQElement *junk = NULL;  while ((stepper = proc->branchq.GetNext(stepper)) != NULL)    {      junk = stepper->d;      if (junk->tag == tag)	return junk;    }  return NULL;}/* * RemoveFromBranchQ : Remove entry specified by tag from branch queue  *                     for successful predictions */int RemoveFromBranchQ(long long tag, ProcState * proc)        {  // this part is like the way we handle memory system  BranchQElement *junk = GetElement(tag, proc);  if (junk == NULL)    return -1;  junk->done = 1;  proc->branchq.Remove(junk);  DeleteMapTable(junk->specmap, proc);  DeleteBranchQElement(junk, proc);    instance *i = proc->BranchDepQ.GetNext(proc);  if (i != NULL)    {      i->stallqs--;      if (AddBranchQ(i->tag, proc) != 0)	YS__errmsg(proc->proc_id / ARCH_cpus,		   "SERIOUS ERROR IN REVIVING A SLEPT BRANCH!!!"		   " P%d(%lld/%d) %s:%d!!\n", proc->proc_id, i->tag, 		   i->pc, __FILE__, __LINE__);      i->branchdep = 0;#ifdef COREFILE      if (YS__Simtime > DEBUG_TIME)	fprintf(corefile, "shadow mapper allocated for tag %lld\n", i->tag);#endif      #ifdef DEBUG      if (proc->stall_the_rest != i->tag)	YS__errmsg(proc->proc_id / ARCH_cpus,		   "SERIOUS ERROR IN REVIVING A SLEPT BRANCH!!!"		   " P%d(%lld/%d) %s:%d!!\n", proc->proc_id, i->tag, 		   i->pc, __FILE__, __LINE__);#endif            if (!STALL_ON_FULL || proc->type_of_stall_rest != eMEMQFULL)	unstall_the_rest(proc);    }  return 0;}/* * AddBranchQ: Initialize shadow mappers and add to list of outstanding *             branches. return -1 if out of shadow mappers */int AddBranchQ(long long tag, ProcState * proc){  if (proc->branchq.NumItems() >= MAX_SPEC)    {      /* out of speculations */#ifdef COREFILE      if (proc->curr_cycle > DEBUG_TIME)	fprintf(corefile, "Out of shadow mappers !\n");#endif      return (-1);    }  MapTable *specmap = NewMapTable(proc);#ifdef DEBUG  if (specmap == NULL)    YS__errmsg(proc->proc_id / ARCH_cpus,	       "Got a NULL map table entry!!");#endif  int n;  long long *src, *dest;  src  = (long long*)proc->intmapper;  dest = (long long*)specmap->imap;  for (n = 0; n < (sizeof(short)*NO_OF_LOG_INT_REGS) / sizeof(long long); n++)    dest[n] = src[n];      src  = (long long*)proc->fpmapper;  dest = (long long*)specmap->fmap;  for (n = 0; n < (sizeof(short)*NO_OF_LOG_FP_REGS) / sizeof(long long); n++)    dest[n] = src[n];  /* Add it into our Branch List */  proc->branchq.Insert(NewBranchQElement(tag, specmap, proc));  return (0);}/* * CopyBranchQ : Set up the state after a branch misprediction */int CopyBranchQ(long long tag, ProcState * proc){  /* Let us get the entry corresponding to this tag */  BranchQElement *entry = GetElement(tag, proc);  if (entry == NULL)    {#ifdef COREFILE      if (proc->curr_cycle > DEBUG_TIME)	fprintf(corefile, "<branchspec.cc> Error : Shadow mapper not "		"found for tag %lld\n", tag);#endif      return (-1);    }  /* Change the mappers to point to the right ones */  MapTable *tmpmap = proc->activemaptable;  proc->activemaptable = entry->specmap;  entry->specmap = tmpmap;  proc->intmapper = proc->activemaptable->imap;  proc->fpmapper = proc->activemaptable->fmap;  return (0);}/* * FlushActiveList : Flush the active list on a branch misprediction */int FlushActiveList(long long tag, ProcState * proc){  proc->copymappernext = 0;  proc->unpredbranch = 0;  unstall_the_rest(proc);  /* Flush out the active list suitable freeing the physical registers used     too. */  return (proc->active_list.flush_active_list(tag, proc));}/* * Flush stall queue elements on branch misprediction */int FlushStallQ(long long tag, ProcState * proc){  instance *tmpinst;  if (proc->inst_save != NULL && proc->inst_save->tag > tag)    {      /* Check for tag > tagof our valid instructions */      tmpinst = proc->inst_save;      if (tmpinst->code.wpchange &&	  !(tmpinst->strucdep > 0 && 	    tmpinst->strucdep < 5) &&          tmpinst->exception_code != WINOVERFLOW &&          tmpinst->exception_code != WINUNDERFLOW &&	  tmpinst->exception_code != CLEANWINDOW)	{	  if (tmpinst->code.wpchange != WPC_FLUSHW)	    {	      /* unupdate CWP that has been changed */	      proc->cwp = (proc->cwp + NUM_WINS -			   tmpinst->code.wpchange) % NUM_WINS;	      proc->cansave += tmpinst->code.wpchange;	      proc->canrestore -= tmpinst->code.wpchange;	    }	}	        if (tmpinst->strucdep > 0 && tmpinst->strucdep < 7)	{	  // renaming only partially done	  FlushTagConverter(tmpinst->tag, proc);	  DeleteInstance(tmpinst, proc);          proc->inst_save = NULL;	}      else	tmpinst->tag = -1;    }  return (0);}

⌨️ 快捷键说明

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