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

📄 branchpred.cc

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2002 The Board of Trustees of the University of Illinois and *                    William Marsh Rice University * Copyright (c) 2002 The University of Utah * Copyright (c) 2002 The University of Notre Dame du Lac * * All rights reserved. * * Based on RSIM 1.0, developed by: *   Professor Sarita Adve's RSIM research group *   University of Illinois at Urbana-Champaign and     William Marsh Rice University *   http://www.cs.uiuc.edu/rsim and http://www.ece.rice.edu/~rsim/dist.html * ML-RSIM/URSIM extensions by: *   The Impulse Research Group, University of Utah *   http://www.cs.utah.edu/impulse *   Lambert Schaelicke, University of Utah and University of Notre Dame du Lac *   http://www.cse.nd.edu/~lambert *   Mike Parker, University of Utah *   http://www.cs.utah.edu/~map * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal with the Software without restriction, including without * limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to * whom the Software is furnished to do so, subject to the following * conditions: * * 1. Redistributions of source code must retain the above copyright notice, *    this list of conditions and the following disclaimers.  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimers in the *    documentation and/or other materials provided with the distribution. * 3. Neither the names of Professor Sarita Adve's RSIM research group, *    the University of Illinois at Urbana-Champaign, William Marsh Rice *    University, nor the names of its contributors may be used to endorse *    or promote products derived from this Software without specific prior *    written permission.  * 4. Neither the names of the ML-RSIM project, the URSIM project, the *    Impulse research group, the University of Utah, the University of *    Notre Dame du Lac, nor the names of its contributors may be used to *    endorse or promote products derived from this software without specific *    prior written permission.  * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS WITH THE SOFTWARE.  */extern "C"{#include "sim_main/simsys.h"}                    #include "Processor/procstate.h"#include "Processor/mainsim.h"#include "Processor/branchpred.h"#include "Processor/simio.h"#include "Processor/fastnews.h"#include "Processor/tagcvt.hh"#include "Processor/active.hh"#include "Processor/procstate.hh"#include "Processor/memunit.h"#include "Processor/exec.h"#include "Processor/stallq.hh"#include "Processor/branchpred.hh"#include "Processor/memunit.hh"bptype BPB_TYPE  = TWOBIT;int    BPB_SIZE  = 512;int    RAS_STKSZ = 4;/* * decode_branch_instruction : called the first time a branch instruction  *                           : is encountered, sets all the relevant fields */int decode_branch_instruction(instr * instrn,			      instance * inst,			      ProcState * proc){  // Translate this branch instruction, sets inst->branch_pred & inst->taken  StartCtlXfer(inst, proc);      if (instrn->uncond_branch)    {      // This is an unconditional branch.  For unconditional branches,      // if Annul bit is 0, Instruction in delay slot is executed always;      // if Annul bit is 1, Instruction in delay slot is not executed.      if (instrn->annul == 0)	{	  // Non anulled unconditional branches	  switch (inst->taken)	    {	    case 1:                             // speculatively taken	      proc->copymappernext = 1;	      // NO break here	    case 2:     // non-speculatively taken; no need to copy mappers	      proc->pc  = proc->npc;	      proc->npc = inst->branch_pred;              break;	    case 3:     // non-predictable, so not speculated	      proc->pc = proc->npc;	      proc->npc = inst->branch_pred;      // will be -1	      inst->branchdep = 1;	      proc->unpredbranch = 1;	      return 1;	    case 0:     // speculatively not taken	    default:	      YS__errmsg(proc->proc_id / ARCH_cpus,			 "decode_branch_instr: bad case %d for uncond branch"			 " P %d, tag %lld, time %d\n",			 inst->taken,			 proc->proc_id, 			 inst->tag,			 proc->curr_cycle);	    }	}      else	{	  // Anulled unconditional branches	  switch (inst->taken)	    {	    case 1:     // speculatively taken	      inst->branchdep = 2;        // shadow mapping again	      // Note no break	    case 2:     // non-speculatively taken	      proc->pc  = inst->branch_pred;	      proc->npc = proc->pc + SIZE_OF_SPARC_INSTRUCTION;	      break;	    case 3:     // I do not know what to do	      proc->pc = inst->branch_pred;    // it will be -1	      inst->branchdep = 1;	      proc->unpredbranch = 1;	      break;	    case 0:     // speculatively not taken	    default:	      YS__errmsg(proc->proc_id / ARCH_cpus,			 "decode_branch_instr: bad case %d for uncond branch"			 " P %d, tag %lld, time %d\n",			 inst->taken,			 proc->proc_id, 			 inst->tag,			 proc->curr_cycle);	    }	}    }  else    {      // This is a conditional branch      // If annul bit is 0, instruction in delay slot executed always.      // If annul bit is 1, delay slot not executed unless branch is taken.      if (instrn->annul == 0)	{	  // Non annulled conditional branches	  // The shadow mapping will have to be done in the next instruction	  // ie, at the delay slot. lets make a note of it.	  proc->copymappernext = 1;	  proc->pc = proc->npc; 	  switch (inst->taken)	    {	    case 0:     // speculatively not-taken	      proc->npc = proc->npc + SIZE_OF_SPARC_INSTRUCTION;	      break;	    case 1:     // speculatively taken	      proc->npc = inst->branch_pred;	      break;	    case 2:     // This should not occur here.	                // This means taken for sure 	    case 3:     // This should not occur here. This means unpredicted	    default:	      YS__errmsg(proc->proc_id / ARCH_cpus,			 "decode_branch_instr: case %d for cond branch "			 " P%d, tag %lld, time %d\n",			 inst->taken,			 proc->proc_id, 			 inst->tag,			 proc->curr_cycle);	    }	}      else	{	  // Anulled conditional branches	  switch (inst->taken)	    {	    case 0:     // Speculatively not taken	      proc->pc = proc->npc + SIZE_OF_SPARC_INSTRUCTION;	      // delay slot not taken	      proc->npc = proc->pc + SIZE_OF_SPARC_INSTRUCTION;	      inst->branchdep = 2;	      break;	    case 1:     // Speculatively taken	      proc->pc = proc->npc;	      proc->npc = inst->branch_pred;	      // We copy the shadow map here because of the possibility of 	      // the delay slot getting squashed	      inst->branchdep = 2;        	      break;	    case 2:  // This should not occur here. This means taken for sure	    case 3:  // This should not occur here. This means unpredicted	    default:	      YS__errmsg(proc->proc_id / ARCH_cpus,			 "decode_branch_instr: case %d for cond branch P %d,"			 " tag %lld, time %d\n",			 inst->taken,			 proc->proc_id, 			 inst->tag,			 proc->curr_cycle);	    }              // End of switch	}                  // End of is annulled or not    }                      // End of is unconditional or not?  return 0;}/* * GoodPrediction : Free up shadow mapper and update processor speculation  *                : level once we know that the prediction was correct       */void GoodPrediction(instance * inst, ProcState * proc){  if (inst->code.uncond_branch == 4)                  // if it's a RAS access    proc->ras_good_predicts++;  else    proc->bpb_good_predicts++;  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 == GetTailInst(proc)->tag + 1)    {      // We havent issued the delay slot yet!      proc->copymappernext = 0;  // We dont need to copy the mappers now      return;    }  // Remove the entry from the Branch Q  if (RemoveFromBranchQ(tag_to_use, proc) != 0)    {      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/0x%08X) != (%lld)!!",                        proc->proc_id,		       inst->tag, inst->pc,		       proc->stall_the_rest);#endif	  	  if (!STALL_ON_FULL || proc->type_of_stall_rest != eMEMQFULL)	    // we might have had later memq full problems if stall_on_full	    unstall_the_rest(proc);     	  inst2->branchdep = 0;	  instance *inst3;	  inst3 = proc->BranchDepQ.GetNext(proc); // this should be inst2 itself#ifdef DEBUG	  if (inst3 && inst3->tag != inst2->tag)	    // it wouldn't have been in the branchdepq if it stalled in rename	    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)     /* if it was in the branch depq */            inst3->stallqs--;	}    }}/* * BadPrediction : Steps to be taken on event of a branch misprediction  */void BadPrediction(instance * inst, ProcState * proc){  // we assume that proc->pc and proc->npc have been set properly before  // calling BadPrediction  if (inst->code.uncond_branch == 4)  // if it's a RAS access    proc->ras_bad_predicts++;  else    proc->bpb_bad_predicts++;  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 == GetTailInst(proc)->tag + 1)    {      // The delay slot (and things after it) have not been issued yet!      proc->copymappernext = 0; // We are saved the touble of saving mappers      return;    }  // to indicate that the next instruction after this one is the point from  // which the processor will be fetching after this misprediction

⌨️ 快捷键说明

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