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

📄 ms_grad.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
                      AddToStat (ST_GRAD_EMPTYSTALL, GRAD_WIDTH-i);                   }                } else if ((st->iwin_flags[inum] & IWIN_LDST) &&                           (st->iwin_flags[inum] & IWIN_LDSTBUF) &&                           (st->inum2ldst[inum]->ls->status & LS_ST_STALL)) {                   record_ldst_stall(st, inum, GRAD_WIDTH-i);                   if (st->iwin_flags[inum] & IWIN_STORE)  {                      AddToStat (ST_GRAD_STSTALL, GRAD_WIDTH-i);                   } else {                       AddToStat (ST_GRAD_LDSTALL, GRAD_WIDTH-i);                   }                } else {                   record_pipeline_stall(st, th->pc,GRAD_WIDTH-i);                   if (!(st->iwin_flags[inum] & IWIN_ISSUED)) {                       if (st->iwin_flags[inum] & IWIN_FLUSH) {                          AddToStat(ST_GRAD_FLUSHSTALL, GRAD_WIDTH-i);                      } else {                         AddToStat(ST_GRAD_ISSUESTALL, GRAD_WIDTH-i);                      }                   } else if (st->iwin_flags[inum] & IWIN_LDST) {                      AddToStat(ST_GRAD_PHASEASTALL, GRAD_WIDTH-i);                   } else {                      AddToStat(ST_GRAD_MISCSTALL, GRAD_WIDTH-i);                   }                }		break;		/* Rest of instructions not eligible	*/		}		/* for graduation, quit.		*/#endif /* PRECISE */	}	/*	 *  ms_grad_dequeue  -  Remove instruction from graduation queue	 *	 *	Also update the status of the destination register and	 *	put the instruction slot on the free list.	 */void ms_grad_dequeue (struct s_cpu_state *st, int inum)	{#ifdef PRECISE	int	tmpi, regname, reg_ix;	REGSTAT	*rs;	tmpi = st->iwin_bgrd [inum];#ifdef DEBUG_CHECKS	if ((st->iwin_flags [inum] & IWIN_FREED) == 0)		{		fprintf (stderr, "Attempt to graduate a live instruction\r\n");		ms_break (st, NULL, "ERR");		}	if ((inum != st->iwin_headgrad) || (tmpi >= 0))		{		fprintf (stderr, "Out of order graduation\r\n");		ms_break (st, NULL, "ERR");		}#endif /* DEBUG_CHECKS */	if (tmpi >= 0)		st->iwin_grad [tmpi] = st->iwin_grad [inum];	else		st->iwin_headgrad = st->iwin_grad [inum];	if ((tmpi = st->iwin_grad [inum]) >= 0)		st->iwin_bgrd [tmpi] = st->iwin_bgrd [inum];	else		st->iwin_tailgrad = st->iwin_bgrd [inum];	regname = 0;	if (st->iwin_flags [inum] & IWIN_DEFINE)	    {	    /* On graduation of a non-speculative redefinition of a	*/	    /* register, the previous name for the register should	*/	    /* be freed.						*/	    if (st->iwin_br_node [inum] == 0)		regname = st->grad.regnames [st->iwin_lr1 [inum]];	    /* On graduation of a speculative redefinition of a		*/	    /* register, the current name should be freed.		*/	    else		{		regname = st->iwin [inum] .r1;			/* If another instruction will complete this	*/			/* definition, then hold off on freeing the	*/			/* register until then.				*/		for ( tmpi = st->iwin_grad[inum];			(tmpi >= 0) && (st->iwin_flags[tmpi] & IWIN_SQUASH);			tmpi = st->iwin_grad[tmpi] )		    {		    if (st->iwin [tmpi] .r1 == (regname ^ 0x01))			{			st->iwin_flags [tmpi] |= IWIN_DEFINE;			regname = 0;			break;			}		    }		}	    }	if (regname > 0)		{		reg_ix = regname >> 1;		rs = &st->reg_rstat [reg_ix];		rs->reg_status |= REG_FREED;		CheckRegFree (st, rs, reg_ix);		}	UnthreadInst (st, inum);#endif /* PRECISE */	}	/*	 *  ms_grad_enqueue  -  Add instruction to graduation queue	 */void ms_grad_enqueue (struct s_cpu_state *st, int inum)	{#ifdef PRECISE	if (st->iwin_tailgrad >= 0)		{		st->iwin_grad [st->iwin_tailgrad] = inum;		st->iwin_bgrd [inum] = st->iwin_tailgrad;		st->iwin_grad [inum] = -1;		st->iwin_tailgrad = inum;		}	else		{		st->iwin_headgrad = inum;		st->iwin_tailgrad = inum;		st->iwin_bgrd [inum] = -1;		st->iwin_grad [inum] = -1;		}#endif /* PRECISE */	}#ifdef MIPSY_MXSstatic int pipeline_empty (struct s_cpu_state *st);	/*	 *  ms_except  -  Check for exceptions, and handle them for MXS	 */void ms_except (struct s_cpu_state *st)	{	THREAD	*th;	int	inum;/* Have we got an ITLB miss?  Can recognize this when the graduation	*//* queue is empty and the thread corresponding to the root of the	*//* branch tree is stalled on an ITLB miss.				*/	inum = st->iwin_headgrad;	if (inum < 0)		{		th = &st->threads [st->branch_tree [0].thread];		if ((!st->exception_pending) && th->stall_itlbmiss)			{			st->exception_pending = 1;			st->except = th->except;			IncStat(ST_EXCEPT_ITLB);			}		}	else if (!st->exception_pending) 	        {		    /* Check for the case of a ITLB miss in the delay slot of a                      * branch.                      */	        th = &st->threads [st->branch_tree [0].thread];		if (th->stall_itlbmiss && (st->iwin_br_node[inum] == 0) && 		    (st->iwin_flags[inum] & IWIN_BRANCH)) 		    {		    st->exception_pending = 1;		    st->except = th->except;		    IncStat(ST_EXCEPT_ITLB);		    }		} /* Is there an interrupt hanging around?  If so, recognize it.		*/	if (!st->exception_pending && InterruptIsPending (st) &&            InstIsInterruptable(st))		{		CPUState *P = (CPUState *) (st->mipsyPtr);		RECORD_EXCEPTION(P, EXC_INT, E_VEC, 0, 			     P->CP0[C0_TLBHI],P->CP0[C0_CTXT],P->CP0[C0_XCTXT]);		st->exception_pending = 1;		st->except = GetLastException (st);		IncStat(ST_EXCEPT_INTR);		}	th = &st->grad;	if (((CPUState *)(st->mipsyPtr))->switchToMIPSY &&	    !st->exception_pending) {	    if ((st->grad.pc < (K2BASE + K2SIZE)) && 	       (!(th->thread_st & TH_BRANCH)) ) { 		st->exception_pending = 1;		st->except = SWITCH2MIPSY_EXCEPTION;	    }	}	if (st->exception_pending && pipeline_empty (st))		{                RecordExceptionStats(st);		HandleException(st, st->except, (th->thread_st & TH_BRANCH) );#ifdef PRINT_INST 		if (enable_eprint)  			{			PrintException(st, st->except);			}#endif		st->exception_pending = 0;		}	        else if (st->exception_pending) {		    IncStat(ST_EXCEPT_WAIT);               }	}	/*	 *  pipeline_empty  -  Return TRUE if there are no outstanding	 *			operations in the pipeline.	 */static int pipeline_empty (struct s_cpu_state *st)	{	if ((st->ex_count > 0) || (st->work_head))		return (0);	return (1);	}static int InstIsInterruptable(struct s_cpu_state *st) {     int inum = st->iwin_headgrad ;     if (inum >= 0) {         if (((st->iwin_flags[inum] &            (IWIN_LDST|IWIN_UNCACHED|IWIN_LDSTBUF)) ==          (IWIN_LDST|IWIN_UNCACHED|IWIN_LDSTBUF)) &&         IsLoad(st->inum2ldst[inum]->ls->lstype) &&         st->inum2ldst[inum]->dataPtr) {           return 0; /* Don't abort unfinished uncached reads */        }        if (((st->iwin[inum].op == OPLDHACK) ||             (st->iwin[inum].op == OPSDHACK)) &&            (st->iwin_flags[inum] & IWIN_ISSUED)) {           return 0; /* Handle ld/sd hack instruction */        }     }     return 1;}         static void RecordExceptionStats(struct s_cpu_state *st)        {            int inum, inwin = 0, ldst = 0, squashed = 0;            for (inum = st->iwin_headgrad; inum >= 0; inum = st->iwin_grad[inum]) {                inwin++;                if (st->iwin_flags[inum] & IWIN_LDST)                    ldst++;                if (st->iwin_flags[inum] & IWIN_SQUASH)                    squashed++;            }	    IncStat(ST_EXCEPT_TAKEN)     	    if (st->except == COHERENCY_EXCEPTION) {		   IncStat(ST_EXCEPT_COHERENCY);                   AddToStat(ST_EXCEPT_COHER_INST, inwin);                   AddToStat(ST_EXCEPT_COHER_SQUASH, squashed);                   AddToStat(ST_EXCEPT_COHER_LDST, ldst);	    } else if (st->except == SWITCH2MIPSY_EXCEPTION)  {		   IncStat(ST_EXCEPT_SWITCH);                   AddToStat(ST_EXCEPT_SWITCH_INST, inwin);                   AddToStat(ST_EXCEPT_SQUASH, squashed);                   AddToStat(ST_EXCEPT_LDST, ldst);            } else {                   AddToStat(ST_EXCEPT_INST, inwin);                   AddToStat(ST_EXCEPT_SQUASH, squashed);                   AddToStat(ST_EXCEPT_LDST, ldst);            }        }#endif /* MIPSY_MXS */

⌨️ 快捷键说明

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