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

📄 active.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.  */#include <limits.h>#include <sys/time.h>extern "C"{#include "sim_main/simsys.h"}#include "Processor/procstate.h"#include "Processor/mainsim.h"#include "Processor/memunit.h"#include "Processor/exec.h"#include "Processor/simio.h"#include "Processor/branchpred.h"#include "Processor/fastnews.h"#include "Processor/tagcvt.hh"#include "Processor/stallq.hh"#include "Processor/memunit.hh"#include "Processor/procstate.hh"#include "Processor/active.hh"#ifdef sgi#define LLONG_MAX LONGLONG_MAX#endif#if !defined(LLONG_MAX)#  define LLONG_MAX 9223372036854775807LL#endif/* * mark_stores_ready : This function makes sure that stores are marked * ready to issue only when they are ready to graduate in the next * cycle -- namely, the store must be one of the first 4 (or whatever * the graduation rate is) instructions in the active list and each * instructions before it must have completed without excepting. In * cases with non-blocking stores (RC, PC, SC with the "-N" option), * stores can leave the active list after being marked ready. */void activelist::mark_memops_ready(long long cycle, ProcState * proc){  activelistelement *ptr, *ptr2;  int numelts;  int ind, actind;  numelts = q->NumInQueue();   // abort loop when it finds one of the following  // 1) an instruction that isn't done in the active list  //    (or, with non-blocking writes, a store that doesn't have it's  //    address ready)  // 2) an instruction that has its exception code set  // 3) a mispredicted branch whose following hasn't yet been flushed  //    (in our case, no such thing exists, so we don't do this check)    for (ind = 0, actind = 0;       (ind < proc->graduate_rate) && (actind < numelts);       ind++, actind += 2)    // 2 accounts for two active list "elements" for each entry    {#ifdef DEBUG      if (!q->PeekElt(ptr, actind))	YS__errmsg(proc->proc_id / ARCH_cpus,		   "PeekElt gave invalid value in mark_memops_ready.\n");#else      q->PeekElt(ptr, actind);#endif            instance *tmpinst = GetTagCvtByPosn(ptr->tag, ind, proc);      //---------------------------------------------------------------------      // detect stores      if (tmpinst->unit_type == uMEM &&          IsStore(tmpinst) &&          !tmpinst->mem_ready &&          !tmpinst->stallqs &&          tmpinst->strucdep == 0 &&          tmpinst->addr_ready &&	  proc->ReadyUnissuedStores < MAX_STORE_BUF)        // no true dependence is possible; only struct dep can be a problem        {          tmpinst->mem_ready = 1;          proc->ReadyUnissuedStores++;#ifdef COREFILE          if (YS__Simtime > DEBUG_TIME)            fprintf(corefile,"Marking store %lld as ready to issue\n",		    tmpinst->tag);#endif          if (!IsRMW(tmpinst)#ifdef STORE_ORDERING              && (Processor_Consistency || SC_NBWrites)#endif              )            {              if (tmpinst->exception_code == OK)                {                  tmpinst->in_memunit = 0;		  instance *memop = NewInstance(tmpinst, proc);                  memop->mem_ready = 1;#ifndef STORE_ORDERING		  proc->StoreQueue.Replace(tmpinst, memop);#else		  proc->MemQueue.Replace(tmpinst, memop);#endif		  q->PeekElt(ptr2, actind+1); 		  mark_done_in_active_list(ptr, ptr2,					   tmpinst->exception_code, cycle);                }              else                {                  tmpinst->in_memunit = 0;                  proc->ReadyUnissuedStores--;#ifndef STORE_ORDERING                  proc->StoreQueue.Remove(tmpinst);                  proc->st_tags.Remove(tmpinst->tag);#else                  proc->MemQueue.Remove(tmpinst);#endif                }               // a STORE in RC, PC, or SC w/non-blocking writes is              // actually "done" when its address is ready, but we              // should be careful in PC or SC w/non-blocking writes              // not to let such a store issue unless it is at the top              // of the memory unit, even if mem_ready is set.            }         }         //---------------------------------------------------------------------      // mark uncached loads      if (tmpinst->unit_type == uMEM &&          !IsStore(tmpinst) &&          IsUncached(tmpinst) &&          !tmpinst->mem_ready &&          !tmpinst->stallqs &&          tmpinst->strucdep == 0 &&          tmpinst->addr_ready)        // no true dependence is possible; only struct dep can be a problem        {          tmpinst->mem_ready = 1; #ifdef COREFILE          if (YS__Simtime > DEBUG_TIME)            fprintf(corefile,"Marking uncached load %lld as ready to issue\n",		    tmpinst->tag);#endif           if (tmpinst->exception_code == OK)            {              tmpinst->in_memunit = 0;	      tmpinst->mem_ready = 1;            }          else            {              tmpinst->in_memunit = 0;#ifndef STORE_ORDERING              proc->LoadQueue.Remove(tmpinst);              proc->st_tags.Remove(tmpinst->tag);#else              proc->MemQueue.Remove(tmpinst);#endif            }            // a STORE in RC, PC, or SC w/non-blocking writes is          // actually "done" when its address is ready, but we          // should be careful in PC or SC w/non-blocking writes          // not to let such a store issue unless it is at the top          // of the memory unit, even if mem_ready is set.        }      if (ptr->done == 0 || ptr->exception != OK)        break;    }}/***************************************************************************//* remove_from_active_list : handles removal of instructions from active   *//*                           list.                                         *//*                           Also computes components of execution time.   *//***************************************************************************//*  * Remove tagged elements from the active list if exception status is OK.  *   return 0 on success,  *   return tag causing problems, otherwise. */instance *activelist::remove_from_active_list(long long cycle,					      ProcState * proc){  activelistelement *ptr;  instance *tmpinst;  int gradded = 0, busy = 0;    ptr = q->PeekHead();  if ((ptr == NULL) ||      ((!ptr->done) && (!ptr->exception)) ||      (ptr->cycledone + simulate_ilp > cycle))    return(NULL);  do    {      tmpinst = TagCvtHead(ptr->tag, proc);#ifdef DEBUG      if (tmpinst == NULL)	YS__errmsg(proc->proc_id / ARCH_cpus,		   "Something is wrong: no translation for this TAG %lld!\n",		   ptr->tag);#endif            if (tmpinst->in_memunit && tmpinst->exception_code == OK)         break;      q->Delete(ptr);      if (ptr->exception)        {          // Exception is set, we are in trouble          UpdateTaghead(ptr->tag, proc);          // THIS WILL BE CAUGHT THE FIRST TIME          Deleteactivelistelement(ptr, proc);           // cwp, etc. will get set through flushactivelist, etc.          return tmpinst;        }                     // No exception, we can free the active list entry      // Also free the old physical register for later use       if (ptr->regtype == REG_FP)        proc->free_fp_list->addfreereg(ptr->phyreg);      else        if (ptr->phyreg != 0)          proc->free_int_list->addfreereg(ptr->phyreg);        UpdateTaghead(ptr->tag, proc);            if (tmpinst->code.sync && proc->sync)	{	  if (tmpinst->code.instruction == iMEMBAR)	    {	      proc->membar_tags.RemoveTail();	      ComputeMembarQueue(proc);	    }	  proc->sync = 0;	}                // We should also check to make sure that destinations      // are indeed not busy (this is an easy mistake to make      // when modifying code). At the same time, we'll now      // update the logical register file (simulator abstraction)      if (tmpinst->code.rd_regtype == REG_FP ||	  tmpinst->code.rd_regtype == REG_FPHALF)	{	  int logreg; 	  if (tmpinst->code.rd_regtype == REG_FP)	    logreg = tmpinst->lrd;	  else if (tmpinst->code.rd_regtype == REG_FPHALF)	    logreg = unsigned(tmpinst->lrd)&~1U; 	  // the logical register is really the double, not the half... 	  proc->log_fp_reg_file[logreg] =	    proc->phy_fp_reg_file[tmpinst->prd];#ifdef DEBUG	  if (proc->fpregbusy[tmpinst->prd])	    YS__errmsg(proc->proc_id / ARCH_cpus,		       "BUSY FP DESTINATION REGISTER AT GRAD!!\n");#endif	}      else	{	  proc->log_int_reg_file[tmpinst->lrd] =	    proc->phy_int_reg_file[tmpinst->prd]; 	  if (tmpinst->code.rd_regtype == REG_INTPAIR)	    proc->log_int_reg_file[tmpinst->lrd+1] =	      proc->phy_int_reg_file[tmpinst->prdp];#ifdef DEBUG	  if (proc->intregbusy[tmpinst->prdp])	    YS__errmsg(proc->proc_id / ARCH_cpus,		       "BUSY INT DESTINATION REGISTER AT GRAD!!\n");#endif	}       proc->log_int_reg_file[tmpinst->lrcc] =	proc->phy_int_reg_file[tmpinst->prcc];#ifdef DEBUG      if (proc->intregbusy[tmpinst->prcc])	YS__errmsg(proc->proc_id / ARCH_cpus,		   "BUSY CC DESTINATION REGISTER AT GRAD (Instr: %s; PC: 0x%08X)\n",		   inames[tmpinst->code.instruction], tmpinst->pc);#endif      //---------------------------------------------------------------------      Deleteactivelistelement(ptr, proc);      ptr = q->PeekHead();      tmpinst = TagCvtHead(ptr->tag, proc);      q->Delete(ptr);      if (ptr->exception)	{	  // Exception is set, we are in trouble	  UpdateTaghead(ptr->tag, proc);	  // THIS WILL BE CAUGHT THE FIRST TIME	  Deleteactivelistelement(ptr, proc); 	  // cwp, etc. will get set through flushactivelist, etc.	  return tmpinst;	}                     // No exception, we can free the active list entry      // Also free the old physical register for later use       if (ptr->regtype == REG_FP)	proc->free_fp_list->addfreereg(ptr->phyreg);      else	if (ptr->phyreg != 0)	  proc->free_int_list->addfreereg(ptr->phyreg);      UpdateTaghead(ptr->tag, proc);#ifdef TRACE      if (YS__Simtime > TRACE)	{	  unsigned char *dp;	  if (PSTATE_GET_PRIV(proc->pstate))	    YS__logmsg(proc->proc_id / ARCH_cpus, "    ");	  	  if (tmpinst->unit_type == uMEM)	    {	      if (IsStore(tmpinst))		{		  YS__logmsg(proc->proc_id / ARCH_cpus,			     "[%i] %9.2f: %5x\t%s\t[%08x]=",			     proc->proc_id,			     YS__Simtime,			     tmpinst->pc,			     inames[tmpinst->code.instruction],			     tmpinst->addr);		  if (tmpinst->code.rs1_regtype == REG_INT)		    YS__logmsg(proc->proc_id / ARCH_cpus,			       "%08X",			       tmpinst->rs1vali);		  if (tmpinst->code.rs1_regtype == REG_FSR)		    YS__logmsg(proc->proc_id / ARCH_cpus,			       "%08X",			       tmpinst->rs1vali);		  else if (tmpinst->code.rs1_regtype == REG_INTPAIR)		    YS__logmsg(proc->proc_id / ARCH_cpus,			       "%08X %08X",			       tmpinst->rs1valipair.a,			       tmpinst->rs1valipair.b);		  else if (tmpinst->code.rs1_regtype == REG_INT64)		    YS__logmsg(proc->proc_id / ARCH_cpus,			       "%016llX",			       tmpinst->rs1valll);		  else if (tmpinst->code.rs1_regtype == REG_FP)		    {		      dp = (unsigned char*)(&tmpinst->rdvalf);		      YS__logmsg(proc->proc_id / ARCH_cpus,				 "%f (%02X%02X%02X%02X%02X%02X%02X%02X)",				 tmpinst->rdvalf, *dp++, *dp++, *dp++, *dp++,				 *dp++, *dp++, *dp++, *dp++);		    }		  else if (tmpinst->code.rs1_regtype == REG_FPPAIR)		    YS__logmsg(proc->proc_id / ARCH_cpus,			       "%f",			       tmpinst->rs1valf);		  else if (tmpinst->code.rs1_regtype == REG_FPHALF)		    {		      dp = (unsigned char*)(&tmpinst->rdvalfh);		      YS__logmsg(proc->proc_id / ARCH_cpus,				 "%f (%02X%02X%02X%02X)",				 tmpinst->rdvalfh, *dp++, *dp++, *dp++, *dp++);		    }		  if ((tmpinst->code.rs1_regtype == REG_INT) ||		      (tmpinst->code.rs1_regtype == REG_INTPAIR) ||		      (tmpinst->code.rs1_regtype == REG_INT64))		    YS__logmsg(proc->proc_id / ARCH_cpus,			       " (R%02i)\t",			       tmpinst->code.rs1);		  else		    YS__logmsg(proc->proc_id / ARCH_cpus,			       " (F%02i)\t",			       tmpinst->code.rs1);		}	      else     // uMEM & !store => load		{

⌨️ 快捷键说明

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