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

📄 exec.cc

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 CC
📖 第 1 页 / 共 4 页
字号:
  if (STALL_ON_FULL)    {      proc->active_instr[inst->unit_type]++;    }   if (proc->stall_the_rest == inst->tag)    {      // we don't call unstall the rest, because we don't want      // stalledeff getting set to 0 for no obvious reason, as we are      // still fetching instructions      proc->stall_the_rest = 0;      proc->type_of_stall_rest = eNOEFF_LOSS;    }     // CHECK FOR BRANCH STRUCTURAL DEPENDENCIES HERE  if (inst->branchdep == 2)    {      // This means we are in a place where state has to      // be saved, either at a branch or at a delay slot.      // (That work has been done by decode_instruction already!)      // So all we have to do is to save the shadow mapper      // Try to copy into mappers      if (AddBranchQ(inst->tag, proc) != 0)        {          // out of speculations ! stall future instructions until          // we get some speculations freed          inst->stallqs++;          proc->stall_the_rest = inst->tag;          proc->type_of_stall_rest = eSHADOW;#ifdef COREFILE          if (proc->curr_cycle > DEBUG_TIME)            fprintf(corefile,"Branch %d failed to get shadow mapper\n",inst->tag);#endif          inst->branchdep = 2;          proc->BranchDepQ.AddElt(inst,proc);          // Don't return, go ahead and issue it, we will          // take care of the shadow mapping in the update cycle.        }      else        {          // successful!! #ifdef COREFILE          if(proc->curr_cycle > DEBUG_TIME)            fprintf(corefile,"Branch %d got shadow mapper\n",inst->tag);#endif           inst->branchdep = 0;        }    }    if (proc->unpredbranch && ((inst->branchdep != 1) || inst->code.annul))    {      // the processor has some branch that could not be predicted, and      // either we are that annulled branch itself or we are the      // delay slot of the delayed branch. Now we need to do a stall the      // rest. BTW, this _really_ will not like a branch in a delay slot.      // We should probable serialize in such a case.       proc->stall_the_rest = inst->tag;      proc->type_of_stall_rest = eBADBR; #ifdef COREFILE      if(proc->curr_cycle > DEBUG_TIME)        fprintf(corefile,"Stalling the rest for unpredicted branch at %d\n",inst->tag);#endif    }     int oldaddrdep = inst->addrdep;                    // Used for disambiguate      /************************************/  /* check for data dependencies next */  /************************************/  // check RAW (true) dependencies for rs1 and rs2  if (inst->truedep == 1)    {      inst->truedep = 0;      inst->addrdep = 0;            // check for rs1      if (inst->code.rs1_regtype == REG_INT ||	  inst->code.rs1_regtype == REG_INT64)        {          if (proc->intregbusy[inst->prs1] == 1)            {              inst->busybits |= BUSY_SETRS1;              proc->dist_stallq_int[inst->prs1].AddElt(inst, proc, BUSY_CLEARRS1);              inst->truedep = 1;            }        }       else if (inst->code.rs1_regtype == REG_FP ||	       inst->code.rs1_regtype == REG_FPHALF)        {          if (proc->fpregbusy[inst->prs1] == 1)            {              inst->busybits |= BUSY_SETRS1;              proc->dist_stallq_fp[inst->prs1].AddElt(inst, proc, BUSY_CLEARRS1);              inst->truedep = 1;            }        }       else if (inst->code.rs1_regtype == REG_INTPAIR)        {          if (proc->intregbusy[inst->prs1] == 1)            {              inst->busybits |= BUSY_SETRS1;              proc->dist_stallq_int[inst->prs1].AddElt(inst, proc, BUSY_CLEARRS1);              inst->truedep = 1;            }           if (proc->intregbusy[inst->prs1p] == 1)            {              inst->busybits |= BUSY_SETRS1P;              proc->dist_stallq_int[inst->prs1p].AddElt(inst, proc, BUSY_CLEARRS1P);              inst->truedep = 1;            }        }             // check for rs2      if (inst->code.rs2_regtype == REG_INT ||	  inst->code.rs2_regtype == REG_INT64)        {          if (proc->intregbusy[inst->prs2] == 1)            {              inst->busybits |= BUSY_SETRS2;              proc->dist_stallq_int[inst->prs2].AddElt(inst, proc, BUSY_CLEARRS2);              inst->truedep = 1;              inst->addrdep = 1;            }        }       else if (inst->code.rs2_regtype == REG_FP ||	       inst->code.rs2_regtype == REG_FPHALF)        {          if (proc->fpregbusy[inst->prs2] == 1)            {              inst->busybits |= BUSY_SETRS2;              proc->dist_stallq_fp[inst->prs2].AddElt(inst,proc,BUSY_CLEARRS2);              inst->truedep = 1;              inst->addrdep = 1;            }        }             // check for rscc      if (proc->intregbusy[inst->prscc] == 1)        {          inst->busybits |= BUSY_SETRSCC;          proc->dist_stallq_int[inst->prscc].AddElt(inst,proc,BUSY_CLEARRSCC);          inst->truedep = 1;          inst->addrdep = 1;        }      // If dest. is a FPHALF, then writing dest. register is effectively an      // RMW. In this case, we need to make sure that register is also available      if (inst->code.rd_regtype == REG_FPHALF &&	  proc->fpregbusy[inst->prsd] == 1)        {          inst->busybits |= BUSY_SETRSD;          proc->dist_stallq_fp[inst->prsd].AddElt(inst, proc, BUSY_CLEARRSD);          inst->truedep = 1;        }    }      /**************************************/  /* check for address dependences next */  /**************************************/  if (inst->addrdep == 0 && inst->unit_type == uMEM)    {      inst->rs2vali = proc->phy_int_reg_file[inst->prs2];      inst->rsccvali = proc->phy_int_reg_file[inst->prscc];      if (oldaddrdep && inst->strucdep == 0)	// already in memory system, but ambiguous        CalculateAddress(inst, proc);    }  if (inst->strucdep == 10)                      // not yet in memory system    {//      if (NumInMemorySystem(proc) < MAX_MEM_OPS)        {          AddToMemorySystem(inst, proc);          inst->strucdep = 0;        }/* @@     else        {          proc->UnitQ[uMEM].AddElt(inst, proc);          inst->stallqs++;          inst->strucdep = 10;          if (STALL_ON_FULL)            {              // in this type of processor (probably more realistic),              // the processor fetch/etc. stalls when the memory queue              // is filled up (by default, we'll keep fetching later              // instructions and just make this one wait for its resource              // (hold it in its active list space)               proc->stall_the_rest = inst->tag;              proc->type_of_stall_rest = eMEMQFULL;            }        } */    }   proc->sync = inst->code.sync;  if (inst->truedep == 0)    // Now we are ready to issue, but do we have the resources?    SendToFU(inst, proc);  return (0);} /*** End of check_dependencies ***//* * Handle issue once all dependences (other than structural dependences  * for functional units) are taken care of. */int SendToFU(instance * inst, ProcState * proc){  /* We have crossed all hazards, ISSUE IT!! */  /* But, first copy the values of the phy regs into the instance */#ifdef COREFILE  if (proc->curr_cycle > DEBUG_TIME)    {      fprintf(corefile, "pc = %d, tag = %d, %s \n", inst->pc,               inst->tag, inames[inst->code.instruction]);      fprintf(corefile, "lrs1 = %d, prs1 = %d \n", inst->lrs1, inst->prs1);      fprintf(corefile, "lrs2 = %d, prs2 = %d \n", inst->lrs2, inst->prs2);      fprintf(corefile, "lrd = %d, prd = %d \n", inst->lrd, inst->prd);    }#endif  switch (inst->code.rs1_regtype)    {    case REG_FSR:      // raise serialize exception if any FP ops are ahead of us (instruction      // will be retried immediately), otherwise gather data to store      if (proc->active_list.fp_ahead(inst->tag, proc))	{	  inst->exception_code = SERIALIZE;          proc->active_list.flag_exception(inst->tag, SERIALIZE);          proc->active_list.mark_done_in_active_list(inst->tag, SERIALIZE,						     proc->curr_cycle);	}      else	get_fsr(proc, inst);      break;          case REG_INT:      inst->rs1vali = proc->phy_int_reg_file[inst->prs1];#ifdef COREFILE      if (proc->curr_cycle > DEBUG_TIME)	fprintf(corefile, "rs1i = %d, ", inst->rs1vali);#endif      break;          case REG_INT64:      inst->rs1valll = proc->phy_int_reg_file[inst->prs1];#ifdef COREFILE      if (proc->curr_cycle > DEBUG_TIME)	fprintf(corefile, "rs1i = %lld, ", inst->rs1valll);#endif      break;          case REG_FP:      inst->rs1valf = proc->phy_fp_reg_file[inst->prs1];#ifdef COREFILE      if (proc->curr_cycle > DEBUG_TIME)	fprintf(corefile, "rs1f = %f, ", inst->rs1valf);#endif      break;          case REG_FPHALF:      {	float *address = (float *) (&proc->phy_fp_reg_file[inst->prs1]);#ifdef ENDIAN_SWAP	if (!(inst->code.rs1 & 1))  /* the odd half */	    address += 1;#else	if (inst->code.rs1 & 1)     /* the odd half */	    address += 1;#endif	 inst->rs1valfh = *address;#ifdef COREFILE	 if (proc->curr_cycle > DEBUG_TIME)	   fprintf(corefile, "rs1fh = %f, ", inst->rs1valfh);#endif	 break;      }        case REG_INTPAIR:      inst->rs1valipair.a = proc->phy_int_reg_file[inst->prs1];      inst->rs1valipair.b = proc->phy_int_reg_file[inst->prs1p];#ifdef COREFILE      if (proc->curr_cycle > DEBUG_TIME)	fprintf(corefile, "rs1i = %d/%d, ", inst->rs1valipair.a, 		inst->rs1valipair.b);#endif      break;    default:      YS__errmsg(proc->proc_id / ARCH_cpus,		 "Unexpected regtype %i\n",		 inst->code.rs1_regtype);    }  //-------------------------------------------------------------------------    switch (inst->code.rs2_regtype)    {    case REG_INT:      inst->rs2vali = proc->phy_int_reg_file[inst->prs2];#ifdef COREFILE      if (proc->curr_cycle > DEBUG_TIME)	fprintf(corefile, "rs2i = %d, ", inst->rs2vali);#endif      break;          case REG_INT64:      inst->rs2valll = proc->phy_int_reg_file[inst->prs2];#ifdef COREFILE      if (proc->curr_cycle > DEBUG_TIME)	fprintf(corefile, "rs2i = %lld, ", inst->rs2valll);#endif      break;    case REG_FP:      inst->rs2valf = proc->phy_fp_reg_file[inst->prs2];#ifdef COREFILE      if (proc->curr_cycle > DEBUG_TIME)	fprintf(corefile, "rs2f = %f, ", inst->rs2valf);#endif      break;    case REG_FPHALF:      {	float *address = (float *) (&proc->phy_fp_reg_file[inst->prs2]);#ifdef ENDIAN_SWAP	if (!(inst->code.rs2 & 1))   /* the odd half */	    address += 1;#else	if (inst->code.rs2 & 1)      /* the odd half */	    address += 1;#endif		inst->rs2valfh = *address;#ifdef COREFILE	if (proc->curr_cycle > DEBUG_TIME)	  fprintf(corefile, "rs2fh = %f, ", inst->rs2valfh);#endif	break;      }          default:      YS__errmsg(proc->proc_id / ARCH_cpus,		 "Unexpected regtype %i",		 inst->code.rs2_regtype);    }  inst->rsccvali = proc->phy_int_reg_file[inst->prscc];  if (inst->code.rd_regtype == REG_FPHALF)    {      inst->rsdvalf = proc->phy_fp_reg_file[inst->prsd];#ifdef COREFILE      if (proc->curr_cycle > DEBUG_TIME)	fprintf(corefile, "rsdf = %f, ", inst->rsdvalf);#endif    }  #ifdef COREFILE  if (proc->curr_cycle > DEBUG_TIME)    fprintf(corefile, "rsccvali = %d \n", inst->rsccvali);#endif    if (inst->unit_type == uMEM)    return 0;  if (proc->UnitsFree[inst->unit_type] == 0)    {      proc->UnitQ[inst->unit_type].AddElt(inst, proc);      inst->stallqs++;      return 7;    }  else    {      issue(inst, proc);      return 0;    }}/* * Handle the issue once _all_ dependences are taken care of. */void issue(instance * inst, ProcState * proc){  tagged_inst insttagged(inst);  inst->strucdep = 0;    //-------------------------------------------------------------------------  // issue regular instructions    if (inst->unit_type != uMEM)    {                                         // uMEM doesn't use this ReadyQ      proc->ReadyQueues[inst->unit_type].Insert(insttagged);  

⌨️ 快捷键说明

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