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

📄 exec.cc

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 CC
📖 第 1 页 / 共 4 页
字号:
  int dests = 1;  if (code.wpchange != WPC_NONE)    {      if (code.wpchange == WPC_SAVE)	{	  if (proc->cansave)	    {	      if (proc->cleanwin - proc->canrestore != 0)		win_num = unsigned (win_num + 1) % NUM_WINS;	      else		{		  exception_code = CLEANWINDOW;		  dests = 0;		  lrd = lrcc = 0;		  strucdep = 2;		}	    }	  else	    { // SAVE EXCEPTION. Do not let this instruction act properly.	      exception_code = WINOVERFLOW;	      dests = 0;	      lrd = lrcc = 0;	      strucdep = 2;	    }	}      else if (code.wpchange == WPC_RESTORE)	{	  if (proc->canrestore)	    win_num = unsigned(win_num + NUM_WINS - 1) % NUM_WINS;	  else 	    {	      // RESTORE EXCEPTION.	      exception_code = WINUNDERFLOW;	      dests = 0;	      lrd = lrcc = 0;	      strucdep = 2;	    }	}      else if ((code.wpchange == WPC_FLUSHW) &&	       (proc->cansave != NUM_WINS-2))	{	  exception_code = WINOVERFLOW;	  dests = 0;	  lrd = lrcc = 0;	  strucdep = 2;	}    }	      if (dests)    {  // ALWAYS, except for win exceptions      /* Convert the destination condition code register */      lrcc = arch_to_log(proc, win_num, code.rcc);      /* Convert the Destination Register */      if (code.rd_regtype == REG_FP || code.rd_regtype == REG_FPHALF)	{	  lrd = code.rd;	  strucdep = 1;  /* To go to the right place in check_dependencies */	}      else	{	  lrd = arch_to_log(proc, win_num, code.rd);	  strucdep = 2;  /* To go to the right place in check_dependencies */	}    }  /***************************************************************/  /******************* Memory barrier instructions ***************/  /***************************************************************/#ifndef STORE_ORDERING  if (code.instruction == iMEMBAR && code.rs1 == STATE_MEMBAR)    {      // decode a membar and put it in its queue      MembarInfo mb;      mb.tag = tag;      mb.SS       = (code.aux2 & MB_StoreStore) != 0;      mb.LS       = (code.aux2 & MB_LoadStore) != 0;      mb.SL       = (code.aux2 & MB_StoreLoad) != 0;      mb.LL       = (code.aux2 & MB_LoadLoad) != 0;      mb.MEMISSUE = (code.aux1 & MB_MEMISSUE) != 0;      mb.SYNC     = (code.aux1 & MB_SYNC) != 0;      ComputeMembarInfo(proc, mb);      proc->membar_tags.Insert(mb);    }#endif  // Check if we are a delay slot  if (proc->copymappernext == 1)    {      /* There is a message for me by the previous branch to take care of         copying the shadow mapping, Let me store this information. */      branchdep = 2;      proc->copymappernext = 0;     /* We don't want the next instruction                                       to do the same thing */    }  pc  = proc->pc;  npc = proc->npc;  int tmppc = proc->pc; /* We need this to check if we are having a			   jump in the instruction addressing */  // Check if we are getting into a branch instruction. At the end of this  // and the next stage, we would have got the pc and npc for the next  // instruction, and also identified if there are any branch dependencies  if (code.cond_branch || code.uncond_branch)    decode_branch_instruction(&code, this, proc);  else    { /* For all non control transfer instructions */      proc->pc  = proc->npc;      proc->npc = proc->pc + SIZE_OF_SPARC_INSTRUCTION;    }  if ((proc->pc != tmppc + SIZE_OF_SPARC_INSTRUCTION &&       proc->pc != tmppc + 2 * SIZE_OF_SPARC_INSTRUCTION) &&      !proc->stall_the_rest)    { // not taken branch with no DELAYs      /* We are doing a jump at this stage to a different portion of the         address space, next fetch should begin only in the next cycle, so         stall the rest of fetches this cycle */      proc->stall_the_rest = -1;      proc->type_of_stall_rest = eBR;    }  // Note that if we are starting a new cycle, this will get reset anyway, so  // we needn't bother about this instruction being the last one of a cycle!  return (0);}/*=========================================================================== * check_dependencies() implements the dependecy checking logic of the * processor. */int check_dependencies(instance * inst, ProcState * proc){  short next_free_phys_reg = 0;  proc->intmapper[ZEROREG]    = 0;  proc->intregbusy[proc->intmapper[ZEROREG]]   = 0;  // NOTE: INT_PAIR takes the standard INT route except that it maps  // the second dest register where other instructions would map  // "rcc".  This is OK in the SPARC since the only instructions (LDD,  // LDDA) with an INT_PAIR destination do not have a CC destination  // in stat_sched, addr. gen is also lumped in with these  if (STALL_ON_FULL && inst->strucdep)    {      if (stat_sched ||	  (proc->active_instr[inst->unit_type] >=	   proc->max_active_instr[inst->unit_type]))	{	  // Make sure there's space in the issue queue before	  // even trying to get renaming registers, etc.	  proc->stall_the_rest = inst->tag;	  proc->type_of_stall_rest = eISSUEQFULL;	  return 11;	}    }     /*************************************/  /* Check for structural stalls first */  /*************************************/  if (inst->strucdep != 0)    {      switch(inst->strucdep)        {        case 1:                 // FP destination register                    // No free memory for rd fp          next_free_phys_reg = proc->free_fp_list->getfreereg();          if (next_free_phys_reg == -1)            {              proc->stall_the_rest = inst->tag;              proc->type_of_stall_rest = eRENAME;              inst->strucdep = 1;              return (1);            }          inst->prd = next_free_phys_reg;          // Note: no break here, we have to do the next step too	          case 3:          // Copy old mapping to active list          if (proc->active_list.NumEntries() == proc->max_active_list)            {              // No space in active list for fp              inst->strucdep = 1;              proc->free_fp_list->addfreereg(inst->prd);              inst->prd = 0;              proc->stall_the_rest = inst->tag;              proc->type_of_stall_rest = eNOEFF_LOSS;              return (3);            }          // NOTE: This code is used for both FP and FPHALF          if (inst->code.rd_regtype == REG_FP)            proc->active_list.add_to_active_list(inst,						 inst->lrd,						 proc->fpmapper[inst->lrd],						 REG_FP,						 proc);          else                  // FPHALF            proc->active_list.add_to_active_list(inst,						 unsigned(inst->lrd)&~1U,						 proc->fpmapper[unsigned(inst->lrd)&~1U],						 REG_FP,proc);                      // NOW, change the mapper to point to the new mapping          proc->cwp = inst->win_num;           if (((inst->code.wpchange == WPC_SAVE) ||	       (inst->code.wpchange == WPC_RESTORE)) &&              (inst->exception_code != WINOVERFLOW) &&              (inst->exception_code != WINUNDERFLOW))            {              proc->cansave -= inst->code.wpchange;              proc->canrestore += inst->code.wpchange; #ifdef COREFILE              if (YS__Simtime > DEBUG_TIME)                fprintf(corefile,                        "Changing cwp. Now CANSAVE %d, CANRESTORE %d\n",                        proc->cansave,                        proc->canrestore);#endif            }            if (inst->code.rd_regtype == REG_FP)            proc->fpmapper[inst->lrd] = inst->prd;          else                                      // REG_FPHALF            proc->fpmapper[unsigned(inst->lrd)&~1U] = inst->prd;                    // Update busy register table          proc->fpregbusy[inst->prd] = 1;           inst->strucdep = 5;          break;                   case 2:                        // Int destination register          if (inst->lrd == ZEROREG)            {              inst->strucdep = 4;              inst->prd = proc->intmapper[ZEROREG];            }          else            {              // No free memory for rd int              next_free_phys_reg = proc->free_int_list->getfreereg();              if (next_free_phys_reg == -1)                {                  proc->stall_the_rest = inst->tag;                  proc->type_of_stall_rest = eRENAME;                  inst->strucdep = 2;                  return (2);                }              inst->prd = next_free_phys_reg;              // Note: no break	    }                  case 4:          // Copy old mapping to active list          if (proc->active_list.NumEntries() == proc->max_active_list)            {              if (inst->prd != proc->intmapper[ZEROREG])                {                  inst->strucdep = 2;                  proc->free_int_list->addfreereg(inst->prd);                  inst->prd = proc->intmapper[ZEROREG];                }              proc->stall_the_rest = inst->tag;              proc->type_of_stall_rest = eNOEFF_LOSS;              return (4);            }          proc->active_list.add_to_active_list(inst,					       inst->lrd,					       proc->intmapper[inst->lrd],					       REG_INT, proc);          // NOW, change the mapper to point to the new mapping          proc->cwp = inst->win_num;          if (((inst->code.wpchange == WPC_SAVE) ||	       (inst->code.wpchange == WPC_RESTORE)) &&              (inst->exception_code != WINOVERFLOW) &&              (inst->exception_code != WINUNDERFLOW))            {              proc->cansave -= inst->code.wpchange;              proc->canrestore += inst->code.wpchange;#ifdef COREFILE              if (YS__Simtime > DEBUG_TIME)                fprintf(corefile,                        "Changing cwp. Now CANSAVE %d, CANRESTORE %d\n",                        proc->cansave,                        proc->canrestore);#endif            }          proc->intmapper[inst->lrd] = inst->prd;                     // Update busy register table          if (inst->prd != proc->intmapper[ZEROREG])            proc->intregbusy[inst->prd] = 1;          inst->strucdep = 5;          break ;                  default:          break;        }              switch(inst->strucdep)        {        case 5:          if (inst->code.rd_regtype == REG_INTPAIR)            {              // in this case, we need to map the second register              // of the pair rather than the cc register              inst->prcc = proc->intmapper[ZEROREG];         // cc not used              if (inst->code.rd & 1)              // odd destination register                {                  inst->exception_code = ILLEGAL;                  inst->prdp = 0;                }              else                {                  next_free_phys_reg = proc->free_int_list->getfreereg();                  if (next_free_phys_reg == -1)                    {                      proc->stall_the_rest = inst->tag;                      proc->type_of_stall_rest = eRENAME;                      inst->strucdep = 5;                      return (5);                    }                  inst->prdp = next_free_phys_reg;                }              // No break here as we have to do the next part anyway            }          else            {              inst->prdp = proc->intmapper[ZEROREG];       // pair not used              if (inst->lrcc == ZEROREG)                {                  inst->strucdep = 6;                  inst->prcc = proc->intmapper[ZEROREG];                }              else                {                                 // rcc no free list register                  next_free_phys_reg = proc->free_int_list->getfreereg();                  if (next_free_phys_reg == -1)                    {                      proc->stall_the_rest = inst->tag;                      proc->type_of_stall_rest = eRENAME;                      inst->strucdep = 5;                      return (5);                    }                  inst->prcc = next_free_phys_reg;                  // No break here as we have to do the next part anyway                }            }          case 6:          // active list full#ifdef DEBUG          // Copy old mapping to active list          if (proc->active_list.NumEntries() == proc->max_active_list)            {              // THIS CASE SHOULD NEVER HAPPEN SINCE ACTIVE LIST IS IN PAIRS              YS__errmsg(proc->proc_id / ARCH_cpus,			 "Tag %lld: Active list full in case 6 -- that should never happen.",			 inst->tag);                            inst->strucdep = 6;              proc->stall_the_rest = inst->tag;   // rest of the instructions should                                                  // not be decoded              proc->type_of_stall_rest = eNOEFF_LOSS;              return (6);            }#endif	          if (inst->code.rd_regtype == REG_INTPAIR)            {              proc->active_list.add_to_active_list(inst,						   inst->lrd + 1,						   proc->intmapper[inst->lrd + 1],						   REG_INT,						   proc);               // NOW, change the mapper to point to the new mapping              proc->intmapper[inst->lrd+1] = inst->prdp;                            // Update busy register table              proc->intregbusy[inst->prdp] = 1;            }          else            {              proc->active_list.add_to_active_list(inst,						   inst->lrcc,						   proc->intmapper[inst->lrcc],						   REG_INT,						   proc);                            // NOW, change the mapper to point to the new mapping              proc->intmapper[inst->lrcc] = inst->prcc;              // Update busy register table              if (inst->prcc != proc->intmapper[ZEROREG])                proc->intregbusy[inst->prcc] = 1;            }          proc->stalledeff--;          // it made it into active list, so it's                                       // no longer an eff problem!            #ifdef COREFILE          if (proc->stalledeff < 0)            YS__errmsg(proc->proc_id / ARCH_cpus,		       "STALLED EFFICIENCY DROPS BELOW 0\n");#endif                    inst->strucdep = (inst->unit_type == uMEM) ? 10 : 0;          break;          default :          break;        }    }     //-------------------------------------------------------------------------  // Check for branch dependencies here  // If branchdep = 1, then that means we do not know what to  // fetch next(maybe other than the delay slot, things will  // stall automatically after the branch as the next pc will  // be -1 till this gets done, so nothing we need to do. 

⌨️ 快捷键说明

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