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

📄 exec.cc

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 CC
📖 第 1 页 / 共 4 页
字号:
/* * 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.  */#include <sys/time.h>#include <limits.h>extern "C"{#include "sim_main/simsys.h"}                    #include "Processor/procstate.h"#include "Processor/branchpred.h"#include "Processor/memunit.h"#include "Processor/mainsim.h"#include "Processor/exec.h"#include "Processor/fetch_queue.h"#include "Processor/simio.h"#include "Processor/fastnews.h"#include "Processor/fsr.h"#include "Processor/tagcvt.hh"#include "Processor/active.hh"#include "Processor/procstate.hh"#include "Processor/memunit.hh"#include "Processor/stallq.hh"#include "Processor/exec.hh"#ifdef sgi#define LLONG_MAX LONGLONG_MAX#endif#if !defined(LLONG_MAX)#  define LLONG_MAX 9223372036854775807LL#endif#ifdef sparc#pragma align 8 (TheBadPC)#endifinstr *TheBadPC = new instr(iSETHI);#ifdef sgi#pragma align_symbol (TheBadPC, 8)#endif#define min(a, b)               ((a) > (b) ? (b) : (a))/***************************************************************************//***************************************************************************/int fetch_cycle(ProcState * proc){  instr                    *instrn;  int                       rc, attributes, count;  unsigned                  phys_pc;  Queue<fetch_queue_entry> *fetch_queue = proc->fetch_queue;  fetch_queue_entry         fqe;  if ((proc->interrupt_pending) &&      (PSTATE_GET_IE(proc->pstate) &&       (fetch_queue->NumItems() < proc->fetch_queue_size)))    {      int n = 31;      while (((proc->interrupt_pending & (0x00000001 << n)) == 0) &&	     (n > 0))	n--;      if (n > proc->pil)	{	  fqe.exception_code = (enum except)(INTERRUPT_00 - n);	  fqe.inst = NewInstance(TheBadPC, proc); // TLB miss or prot. fault	  fqe.pc   = proc->fetch_pc;         // insert NOP with exception set	  fetch_queue->Enqueue(fqe);	  return(0);	}    }    if ((!proc->fetch_done) || (L1IQ_FULL[proc->proc_id]))    return(0);  count = min(proc->fetch_rate,	      (ARCH_linesz1i - (proc->fetch_pc % ARCH_linesz1i)) /	      SIZE_OF_SPARC_INSTRUCTION);  //-------------------------------------------------------------------------  // do one TLB access if I-TLB is enabled  phys_pc = proc->fetch_pc;  attributes = 0;  if (PSTATE_GET_ITE(proc->pstate))    {      rc = proc->itlb->	LookUp(&phys_pc, &attributes,	       proc->log_int_reg_file[arch_to_log(proc,						  proc->cwp,						  PRIV_TLB_CONTEXT)],	       0, PSTATE_GET_PRIV(proc->pstate), LLONG_MAX);      if (rc != TLB_HIT)	{	  if (fetch_queue->NumItems() < proc->fetch_queue_size)	    {	      if (rc == TLB_MISS)		fqe.exception_code = ITLB_MISS;	      if (rc == TLB_FAULT)		fqe.exception_code = INSTR_FAULT;	      fqe.inst = NewInstance(TheBadPC, proc);	      fqe.pc   = proc->fetch_pc;       // insert NOP with exception set	      fetch_queue->Enqueue(fqe);	    }	  	  return(0);	}    }  ICache_recv_addr(proc->proc_id, proc->fetch_pc, phys_pc,		   count, attributes,		   proc->pstate);  proc->fetch_done = 0;    return 0;}/*************************************************************************//* decode_cycle :  brings new instructions into active list              *//*************************************************************************/ /* decode_cycle() --  The decode routine called every cycle              *//* This is organized into two main parts -                               *//* 1. Check the stall queue for instructions stalled from previous       *//*    cycles.                                                            *//* 2. Check the instructions for this cycle.                             *//*************************************************************************/int decode_cycle(ProcState * proc){#ifdef COREFILE  if (proc->curr_cycle > DEBUG_TIME)    fprintf(corefile, "ENTERING DECODE CYCLE-CYCLE NUMBER %d. UnitsFree: "	    "%d %d %d %d\n", proc->curr_cycle, proc->UnitsFree[uALU], 	    proc->UnitsFree[uFP], proc->UnitsFree[uADDR], 	    proc->UnitsFree[uMEM]);#endif  instance         *inst;  Queue<fetch_queue_entry> *fetch_queue = proc->fetch_queue;  fetch_queue_entry fqe;  int brk        = 0;  int badpc      = 0;  int count      = 0;  int decoderate = proc->decode_rate;    /* DECODE THIS CYCLE'S INSTRUCTIONS. */  if (proc->inst_save)    {      count++;      if (check_dependencies(proc->inst_save, proc) != 0)	brk = 1;      else	proc->inst_save = NULL;    }  if (proc->stall_the_rest)    brk = 1;  if (proc->stall_the_rest == -1ll)    unstall_the_rest(proc);#ifdef DEBUG  if (brk)    return(0);    if (proc->inst_save)    YS__errmsg(proc->proc_id / ARCH_cpus,	       "proc->inst_save == %lld\n", proc->inst_save->tag);#endif  /* Read in more instructions only if there are no branch stalls (or if      there is a branch stall and the delay slot has to be read in) */  while ((count < decoderate) && (brk == 0) && !proc->sync)    {      /* get the instruction from the fetch queue */      if (fetch_queue->Empty())	{	  if (proc->fetch_pc != proc->pc)	    {	      proc->fetch_pc = proc->pc;              proc->fetch_done = 1;	    }	  return -1;	}#if 0#ifdef COREFILE      instrn->print();#endif#endif      fetch_queue->GetHead(fqe);      fetch_queue->Dequeue();      inst = fqe.inst;      if (fqe.pc != proc->pc)	{	  DeleteInstance(inst, proc);	  continue;	}      count++;      inst->decode_instruction(proc);      AddtoTagConverter(inst->tag, inst, proc);      if (fqe.exception_code != OK)      	{	  inst->exception_code = fqe.exception_code;      	  proc->stall_the_rest = inst->tag;      	  proc->type_of_stall_rest = eBADBR;      	}            /* If there are dependencies, put it in the stall queue.         check_dependencies takes care of issuing it if there are no         dependencies */      if (check_dependencies(inst, proc) != 0)	{          proc->inst_save = inst;          brk = 1;	}      /* If a pipeline bubble has to be inserted, then... */      if (proc->stall_the_rest)        brk = 1;      if (proc->stall_the_rest == -1ll)        unstall_the_rest(proc); // this is just a xfer, not a real stall    }    return 0;}/**************************************************************************** * This functions reads in an instruction and converts to an instance. It * converts the static instruction to the dynamic instance.  Initializes the * elements of instance and also does a preliminary check for hazards.   ***************************************************************************/int instance::decode_instruction(ProcState * proc){  /* INITIALIZE DATA ELEMENTS OF INST */  tag = proc->instruction_count;   /* Our instruction id henceforth! */  proc->instruction_count++;       /* Increment Global variable */  unit_type        = unit[code.instruction];  win_num          = proc->cwp; /* before any change in this instruction. */  addr             = 0;  addr_ready       = 0;  mem_ready        = 0;  stallqs          = 0;  busybits         = 0;  in_memunit       = 0;  partial_overlap  = 0;  limbo            = 0;  kill             = 0;  vsbfwd           = 0;  miss             = L1DHIT;  latepf           = 0;  rs1valf          = rs2valf = 0;  rsccvali         = 0;  rsdvalf          = 0;  rccvali          = rdvali = 0;  time_active_list = YS__Simtime;  issuetime        = LLONG_MAX;  // start it out as high as possible  addrissuetime    = LLONG_MAX;  // used only in static sched; start out high  /* Set up default dependency values */  truedep          = 1;  addrdep          = 1;  strucdep         = 0;  branchdep        = 0;  /* Make all other values zero */  completion       = 0;  newpc            = 0;  exception_code   = OK;  mispredicted     = 0;  taken            = 0;  memprogress      = 0;  proc->stall_the_rest     = 0;  proc->type_of_stall_rest = eNOEFF_LOSS;    /* This is the first time the instruction is being processed, we will have     to convert the window pointer, register number combination to a logical     number and then allocate physical registers, etc.. */    /* Source register 1 */  switch (code.rs1_regtype)    {    case REG_FSR:    case REG_INT:    case REG_INT64:      lrs1 = arch_to_log(proc, win_num, code.rs1);      prs1 = proc->intmapper[lrs1];      break;          case REG_FP:      lrs1 = code.rs1;      prs1 = proc->fpmapper[lrs1];      break;    case REG_FPHALF:      lrs1 = code.rs1;      prs1 = proc->fpmapper[unsigned (lrs1) & ~1U];      break;    case REG_INTPAIR:      if (code.rs1 & 1)	{    /* odd source reg. */	  exception_code = ILLEGAL;	  lrs1 = prs1 = prs1p = 0;	}      else	{	  lrs1  = arch_to_log(proc, win_num, code.rs1);	  prs1  = proc->intmapper[lrs1];	  prs1p = proc->intmapper[lrs1 + 1];	}      break;    default:      break;    }  /* Source register 2 */  switch (code.rs2_regtype)    {    case REG_INT:    case REG_INT64:      lrs2 = arch_to_log(proc, win_num, code.rs2);      prs2 = proc->intmapper[lrs2];      break;    case REG_FP:      lrs2 = code.rs2;      prs2 = proc->fpmapper[lrs2];      break;    case REG_FPHALF:      lrs2 = code.rs2;      prs2 = proc->fpmapper[unsigned (lrs2) & ~1U];      break;    default:      break;    }  /* Conditon code as a source register rscc */  lrscc = arch_to_log(proc, win_num, code.rscc);  prscc = proc->intmapper[lrscc];  if (code.rd_regtype == REG_FPHALF)    {      /* Since FPs are mapped/renamed by doubles, we need to make the 	 destination register as source also in this case */      lrsd = code.rd;      prsd = proc->fpmapper[unsigned (lrsd) & ~1U];    }  /*************************************************************/  /***************** Register window operations ****************/  /*************************************************************/    // Lets us NOW bump up or bring down the cwp if its a save/restore  // instruction. Note that the source registers do not see the effect   // of the change in the cwp while the destination registers do  

⌨️ 快捷键说明

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