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

📄 ms.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif               			ms_ldst_dequeue (st, pri);			ms_pri_dequeue (st, pri);			IncStat (ST_EXECUTED);			issues++;#ifdef ONE_PHASE_LS				/* Update store count and set flag to	*/				/* force update of load/store status.	*/			if (st->iwin_flags [pri] & IWIN_STORE)				st->iwin_nstores--;#endif			}		    else			{				/* Don't count Phase A as issue	*/			IncStat (ST_PHASE_A);			}		    }		else		    {		    ms_pri_dequeue (st, pri);		    IncStat (ST_EXECUTED);		    issues++;		    }		}		/* Special check for flush instructions (not issued	*/		/* until all preceeding instructions have issued).	*/	if (ex_count == 0)		{			/* If there is exactly one instruction in the	*/			/* buffer, and it is waiting for the window to	*/			/* flush, and it belongs to branch node 0 (=>	*/			/* it is no longer speculative), and it has no	*/			/* unresolved dependencies, then issue it.	*/		pri = st->iwin_headpri;		if ((pri >= 0) && (st->iwin_flags [pri] & IWIN_FLUSH) &&		    (pri == st->iwin_tailpri) &&#ifdef PRECISE		    (pri == st->iwin_headgrad) &&#endif		    (st->iwin_br_node [pri] == 0) &&		    (!(st->iwin_flags [pri] & (IWIN_DEP2 | IWIN_DEP3))) )			{			st->ex [ex_count++] = pri;			st->iwin_flags [pri] |= IWIN_ISSUED;			if (st->iwin_flags [pri] & IWIN_LDST)				ms_ldst_dequeue (st, pri);			ms_pri_dequeue (st, pri);			IncStat (ST_EXECUTED);			issues++;			}		}		/* Update statistics of successful and unsuccessful	*/		/* instruction issue tries.				*/	for (pri = st->iwin_headpri; issues<ISSUE_WIDTH;					pri = st->iwin_pri [pri] )		{		if (pri < 0)			{			AddToStat (ST_IWIN_EMPTY, ISSUE_WIDTH-issues);			break;			}		if (!(st->iwin_flags [pri] & IWIN_ISSUED) ||		     (st->iwin_flags [pri] & IWIN_LDST_DEP)) 			{				/* If it isn't issued because it	*/				/* depends on an inst still in the	*/				/* window, skip it.			*/			if (st->iwin_flags [pri] & IWIN_DEP2)				{				reg_ix = st->iwin [pri] .r2 >> 1;				if (st->reg_excuse [reg_ix] == ST_NOT_ISSUED)					continue;				}			if (st->iwin_flags [pri] & IWIN_DEP3)				{				reg_ix = st->iwin [pri] .r3 >> 1;				if (st->reg_excuse [reg_ix] == ST_NOT_ISSUED)					continue;				}			issues++;			IncStat (ST_INST_STALLED);			if (st->iwin_flags [pri] & IWIN_LDST_DEP)				{				IncStat (ST_LDST_DEP);				}			else			if (st->iwin_flags [pri] & IWIN_DEP2)				{				IncStat (ST_REG_DEP);				reg_ix = st->iwin [pri] .r2 >> 1;				IncStat (st->reg_excuse [reg_ix]);#ifdef DEBUG_CHECKS				if (st->reg_excuse [reg_ix] == ST_NO_EXCUSE)					{			fprintf (stderr,  "Register absent without excuse\r\n");					ms_break (st, NULL, "ERR");					}#endif				}			else			if (st->iwin_flags [pri] & IWIN_DEP3)				{				IncStat (ST_REG_DEP);				reg_ix = st->iwin [pri] .r3 >> 1;				IncStat (st->reg_excuse [reg_ix]);#ifdef DEBUG_CHECKS				if (st->reg_excuse [reg_ix] == ST_NO_EXCUSE)					{			fprintf (stderr,  "Register absent without excuse\r\n");					ms_break (st, NULL, "ERR");					}#endif				}			else			if (st->iwin_flags [pri] & IWIN_FLUSH)				{				IncStat (ST_IWIN_FLUSH);				}			else			if (st->iwin_flags [pri] & IWIN_BRDLY)				{				IncStat (ST_BR_DLY);				}			else			if ((st->iwin_flags [pri] & (IWIN_SPEC | IWIN_CTL)) ==						(IWIN_SPEC | IWIN_CTL))				{				IncStat (ST_SPEC_CTL);				}			else			if (st->iwin_flags [pri] & IWIN_LDST)				{				if (ldst_buffer_reserve (st) >= 0)					{					ldst_buffer_release (st);					IncStat (ST_NO_EXCUSE);					}				else					{					IncStat (ST_LDST_FULL);					}				}			else				{				IncStat (ST_NO_EXCUSE);#ifdef DEBUG_CHECKS				if ((ex_count<(2*ISSUE_WIDTH)) &&				    (st->stall_type == ST_NO_EXCUSE))					{		fprintf (stderr,  "No excuse for unissued instruction\r\n");					ms_break (st, NULL, "ERR");					}#endif				}			}		}	st->ex_count = ex_count;	}	/*	 *  ms_pri_dequeue  -  Remove instruction from priority queue	 */void ms_pri_dequeue (struct s_cpu_state *st, int pri)	{	int	inum;	st->iwin_ninst--;	if ((inum = st->iwin_bpri [pri]) >= 0)		st->iwin_pri [inum] = st->iwin_pri [pri];	else		st->iwin_headpri = st->iwin_pri [pri];	if ((inum = st->iwin_pri [pri]) >= 0)		st->iwin_bpri [inum] = st->iwin_bpri [pri];	else		st->iwin_tailpri = st->iwin_bpri [pri];	}	/*	 *  ms_pri_enqueue  -  Add instruction to priority queue	 */void ms_pri_enqueue (struct s_cpu_state *st, int pri)	{	st->iwin_ninst++;	if (st->iwin_tailpri >= 0)		{		st->iwin_pri [st->iwin_tailpri] = pri;		st->iwin_bpri [pri] = st->iwin_tailpri;		st->iwin_pri [pri] = -1;		st->iwin_tailpri = pri;		}	else		{		st->iwin_headpri = pri;		st->iwin_tailpri = pri;		st->iwin_bpri [pri] = -1;		st->iwin_pri [pri] = -1;		}	}	/*	 *  ms_ldst_dequeue  -  Remove instruction from load/store queue	 */void ms_ldst_dequeue (struct s_cpu_state *st, int inum)	{	int	tmpi;#ifdef DEBUG_CHECKS	st->iwin_nldst--;	if (st->iwin_nldst < 0)		{		fprintf (stderr, "Underflow in load/store queue\r\n");		ms_break (st, NULL, "ERR");		}#endif	if ((tmpi = st->iwin_bldst [inum]) >= 0)		st->iwin_ldst [tmpi] = st->iwin_ldst [inum];	else		st->iwin_head_ldst = st->iwin_ldst [inum];	if ((tmpi = st->iwin_ldst [inum]) >= 0)		st->iwin_bldst [tmpi] = st->iwin_bldst [inum];	else		st->iwin_tail_ldst = st->iwin_bldst [inum];	}	/*	 *  ms_ldst_enqueue  -  Add instruction to load/store queue	 */void ms_ldst_enqueue (struct s_cpu_state *st, int inum)	{#ifdef DEBUG_CHECKS	st->iwin_nldst++;	if (st->iwin_nldst > IWIN_SIZE)		{		fprintf (stderr, "Overflow in load/store queue\r\n");		ms_break (st, NULL, "ERR");		}#endif	st->iwin_flags [inum] |= IWIN_LDST;	if (st->iwin_tail_ldst >= 0)		{		st->iwin_ldst [st->iwin_tail_ldst] = inum;		st->iwin_bldst [inum] = st->iwin_tail_ldst;		st->iwin_ldst [inum] = -1;		st->iwin_tail_ldst = inum;		}	else		{		st->iwin_head_ldst = inum;		st->iwin_tail_ldst = inum;		st->iwin_bldst [inum] = -1;		st->iwin_ldst [inum] = -1;		}	}	/*	 *  ms_execute  -  EXECUTE the instructions in the execution unit.	 */ void ms_execute (struct s_cpu_state *st)	{	INST	*ip;	BrTREE	*br;	THREAD	*th;	int	exi, ex_count, inum;	ex_count = st->ex_count;	exi = (st->stall_issue ? st->stall_issue-1 : 0);	for (; exi < ex_count; exi++)		{		st->stall_issue = 0;		st->stall_type = ST_NO_EXCUSE;		inum = st->ex [exi];		ip = &st->iwin [inum];		if (st->iwin_flags [inum] & IWIN_SQUASH)			{			if (st->iwin_flags [inum] & IWIN_LDST)			    {			    if (PhaseA(inum))				{				ms_ldst_dequeue (st, inum);				ms_pri_dequeue (st, inum);				IncStat (ST_PRUNED);				}			    else				ldst_buffer_release (st);			    }			free_spec_inst (st, inum);			continue;			}		br = &st->branch_tree [st->iwin_br_node[inum]];		th = &st->threads [br->thread];#ifdef BREAKPOINT		st->iwin_curi = inum;#endif		if (PhaseA (inum))			{	/* Special case for Phase A issue of	*/				/* load/store instructions.		*/				/* Do the address computation		*/#ifndef ONE_PHASE_LS			st->iwin_addr [inum] = Ireg(ip->r2) + ip->imm;			if (!is_prefetch(ip->op) && (ip->r1 >= 0))				st->reg_excuse[ip->r1>>1] = ST_PC_DLY;#ifdef MIPSY_MXS		        {			    PA paddr;			    uint tlbFlavor;			    Result ret;             if (is_store(ip->op))                tlbFlavor = TLB_WRITING;             else                tlbFlavor = TLB_READING;             if (is_prefetch(ip->op)) {                ret = TranslateVirtualNoSideeffect((CPUState *)st->mipsyPtr,                                                   (VA) st->iwin_addr[inum],                                                   &paddr);                if (ret != SUCCESS)                   st->iwin_paddr[inum] = (PA) -1;                else                   st->iwin_paddr[inum] = paddr;                st->iwin_flags [inum] |=                   (IWIN_ADDR_VALID | IWIN_LDST_DEP);                st->iwin_flags [inum] &= ~IWIN_AVAIL;             }             else {                   void *bdoorAddr = 0;			    ret = TranslateVirtual((CPUState *)st->mipsyPtr,						   (VA) st->iwin_addr[inum],						   &paddr, &tlbFlavor, &bdoorAddr);			    if (ret != SUCCESS) {				st->iwin_except [inum] = GetLastException(st);				st->iwin_paddr[inum] = (PA) -1;				st->iwin_flags [inum] |=			(IWIN_TLBFAULT | IWIN_ADDR_VALID | IWIN_LDST_DEP);				st->iwin_flags [inum] &= ~IWIN_AVAIL;			    } else {				st->iwin_paddr[inum] = paddr;				st->iwin_flags [inum] |=					(IWIN_ADDR_VALID | IWIN_LDST_DEP);				st->iwin_flags [inum] &= ~IWIN_AVAIL;				if (tlbFlavor) {				   st->iwin_flags[inum] |= IWIN_UNCACHED; 				}			    }             }			}#else /* MIPSY_MXS */			st->iwin_paddr [inum] = st->iwin_addr [inum];			st->iwin_flags [inum] |=				(IWIN_ADDR_VALID | IWIN_LDST_DEP);			st->iwin_flags [inum] &= ~(IWIN_AVAIL | IWIN_ISSUED);#endif /* MIPSY_MXS */#endif /* !ONE_PHASE_LS */			}		else			{			(*optab[ip->op])(st, ip, th);			Ireg(0) = 0;  /* Keep r0 == 0 */				/* If stalled, remember where.		*/			if (st->stall_issue)				{				st->stall_issue = exi+1;				break;				}				/* Writeback reg if single cycle inst	*/				/* and free up instruction slot.	*/			        /* No need or want to writeback faulted inst or				 * load/store instructions . */			if ((lat_tab [ip->op] <= 1) && 			    !(st->iwin_flags[inum] & (IWIN_FAULT+IWIN_LDST)))				{				if (ip->r1 > 0)				    reg_writeback ((void *)st, (void *)ip->r1);				else				    free_inst (st, inum);				}			}		}	if (exi == st->ex_count)	    st->ex_count = 0;	}#ifdef BREAKPOINTvoid ms_break (struct s_cpu_state *st, INST *ip, char *typ)	{	int  t, flagp, inum;	int	branch_node;	BrTREE	*br;	THREAD	*th;		/* If no instruction specified for the breakpoint, then	*/		/* pick a recent instruction of some current thread.	*/	if (ip == NULL)		{		br = &st->branch_tree[0];		while (br->lchild >= 0)			{			if (st->branch_tree[br->lchild].iwin_tail_th >= 0)				br = &st->branch_tree[br->lchild];			else				break;			}		inum = br->iwin_tail_th;		ip = &st->iwin[inum];		}	else		{		inum = ip - st->iwin;		branch_node = st->iwin_br_node [inum];		br = &st->branch_tree[branch_node];		}	th = &st->threads[br->thread];	printf ("%s:", typ);	printf ("% 7d%0.5d @0x%8.8x: ",		st->work_ticks, st->work_cycle, th->debugpc);	print_inst (stdout, ip);	flagp = 0;	if ((ip->r2 > 0) && (ip->r2  < MAX_VAR))		{		t = th->regnames[ip->r2];		printf (" [");		print_reg_contents (stdout, ip->r2, &st->regs[t]);		flagp = 1;		}	if ((ip->r3 > 0) && (ip->r3  < MAX_VAR))		{		t = th->regnames[ip->r3];		if (flagp)			printf (", ");		else			printf (" [");		print_reg_contents (stdout, ip->r3, &st->regs[t]);		flagp = 1;		}	if (flagp)		printf ("]\r\n");	else		printf ("\r\n");	}#endif

⌨️ 快捷键说明

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