📄 exec.cc
字号:
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 + -