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

📄 ms_inst.m4

📁 一个用在mips体系结构中的操作系统
💻 M4
📖 第 1 页 / 共 3 页
字号:
	}void opCNGTS (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()	if (Freg(ip->r2) <= Freg(ip->r3))		Ireg(ip->r1) |= CONDBIT;	else		Ireg(ip->r1) &= ~CONDBIT;#if FPCMP_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPCMP;	Add_to_worklist (st, FPCMP_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}void opFADDD (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()	Dreg(ip->r1) = Dreg(ip->r2) + Dreg(ip->r3);#if FPADD_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPADD;	Add_to_worklist (st, FPADD_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}void opFSUBD (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()	Dreg(ip->r1) = Dreg(ip->r2) - Dreg(ip->r3);#if FPADD_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPADD;	Add_to_worklist (st, FPADD_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}void opFMULD (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()	Dreg(ip->r1) = Dreg(ip->r2) * Dreg(ip->r3);#if FPMULD_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPMUL;	Add_to_worklist (st, FPMULD_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}void opFDIVD (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()	if (Dreg(ip->r3) == 0.0)		{		int	inum = ip - st->iwin;#ifdef MIPSY_MXS		CPUState *P = (CPUState *)st->mipsyPtr;          CPUWarning("MXS:ms_inst:: EXC_FPE (division by zero) at PC=0x%x\n",                  P->PC);		RECORD_EXCEPTION (P, EXC_FPE, E_VEC, 0,				P->CP0[C0_TLBHI],P->CP0[C0_CTXT],P->CP0[C0_XCTXT]);		st->iwin_except [inum] = GetLastException(st);#else		st->reg_rstat[ip->r1 >> 1].reg_status |= REG_ERROR;#endif		st->iwin_flags[inum] |= IWIN_FAULT;		CheckSquash (st, ip);		th->stall_except = 1;		UpdateStallFetch (th);		return;		}	Dreg(ip->r1) = Dreg(ip->r2) / Dreg(ip->r3);#if FPDIVD_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPDIV;	Add_to_worklist (st, FPDIVD_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}void opFSQRTD (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()#ifdef MIPSY_MXS	fprintf(stderr, "Hit a FSQRTS inst\n");#else	Dreg(ip->r1) = sqrt (Dreg(ip->r2));#endif#if FPSQRTD_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPSQRT;	Add_to_worklist (st, FPSQRTD_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}void opFABSD (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()	Dreg(ip->r1) = (Dreg(ip->r2) >= 0 ? Dreg(ip->r2) : -Dreg(ip->r2) );#if FPABS_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPABS;	Add_to_worklist (st, FPABS_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}void opFMOVD (struct s_cpu_state *st, INST *ip, THREAD *th) {	CHECKFP()	Dreg(ip->r1) = Dreg(ip->r2);	}void opFNEGD (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()	Dreg(ip->r1) = -Dreg(ip->r2);#if FPNEG_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPNEG;	Add_to_worklist (st, FPNEG_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}void opFROUNDD (struct s_cpu_state *st, INST *ip, THREAD *th) {	CHECKFP()	Ireg(ip->r1) = (Dreg(ip->r2) > 0.0 ? Dreg(ip->r2) + 0.5 :						Dreg(ip->r2) - 0.5 );	}void opFTRUNCD (struct s_cpu_state *st, INST *ip, THREAD *th) {	CHECKFP()	Ireg(ip->r1) = Dreg(ip->r2);	}void opFCEILD (struct s_cpu_state *st, INST *ip, THREAD *th) {	CHECKFP()	Ireg(ip->r1) = (Dreg(ip->r2) >= 0.0 ? Dreg(ip->r2) + DP_NEAR_ONE :						Dreg(ip->r2) );	}void opFFLOORD (struct s_cpu_state *st, INST *ip, THREAD *th) {	CHECKFP();	Ireg(ip->r1) = (Dreg(ip->r2) >= 0.0 ? Dreg(ip->r2) :					Dreg(ip->r2) - DP_NEAR_ONE );	}void opCVTSD (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()	if ((ip->r1 & (~0x01)) != ip->r3)		Dreg(ip->r1) = Dreg(ip->r3);	Freg(ip->r1) = Dreg(ip->r2);#if FPCVT_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPCVT;	Add_to_worklist (st, FPCVT_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}void opCVTWD (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()	if ((ip->r1 & (~0x01)) != ip->r3)		Dreg(ip->r1) = Dreg(ip->r3);	switch (st->round_mode)		{		case 0:			/* RN: Round to nearest		*/			Ireg(ip->r1) = (Dreg(ip->r2) > 0.0 ?						Dreg(ip->r2) + 0.5 :						Dreg(ip->r2) - 0.5 );			break;		case 1:			/* RZ: Round toward 0		*/			Ireg(ip->r1) = Dreg(ip->r2);			break;		case 2:			/* RP: Round to +infinity	*/			Ireg(ip->r1) = (Dreg(ip->r2) >= 0.0 ?						Dreg(ip->r2) + DP_NEAR_ONE :						Dreg(ip->r2) );			break;		case 3:			/* RM: Round to -infinity	*/			Ireg(ip->r1) = (Dreg(ip->r2) >= 0.0 ?						Dreg(ip->r2) :						Dreg(ip->r2) - DP_NEAR_ONE );			break;		}#if FPCVT_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPCVT;	Add_to_worklist (st, FPCVT_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}void opCUEQD (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()	if (Dreg(ip->r2) == Dreg(ip->r3))		Ireg(ip->r1) |= CONDBIT;	else		Ireg(ip->r1) &= ~CONDBIT;#if FPCMP_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPCMP;	Add_to_worklist (st, FPCMP_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}void opCULTD (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()	if (Dreg(ip->r2) < Dreg(ip->r3))		Ireg(ip->r1) |= CONDBIT;	else		Ireg(ip->r1) &= ~CONDBIT;#if FPCMP_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPCMP;	Add_to_worklist (st, FPCMP_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}void opCULED (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()	if (Dreg(ip->r2) <= Dreg(ip->r3))		Ireg(ip->r1) |= CONDBIT;	else		Ireg(ip->r1) &= ~CONDBIT;#if FPCMP_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPCMP;	Add_to_worklist (st, FPCMP_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}/* Trap if unordered, but otherwise the same as above	*/void opCNGLD (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()	if (Dreg(ip->r2) == Dreg(ip->r3))		Ireg(ip->r1) |= CONDBIT;	else		Ireg(ip->r1) &= ~CONDBIT;#if FPCMP_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPCMP;	Add_to_worklist (st, FPCMP_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}void opCNGED (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()	if (Dreg(ip->r2) < Dreg(ip->r3))		Ireg(ip->r1) |= CONDBIT;	else		Ireg(ip->r1) &= ~CONDBIT;#if FPCMP_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPCMP;	Add_to_worklist (st, FPCMP_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}void opCNGTD (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	CHECKFP()	if (Dreg(ip->r2) <= Dreg(ip->r3))		Ireg(ip->r1) |= CONDBIT;	else		Ireg(ip->r1) &= ~CONDBIT;#if FPCMP_LATENCY > 1	st->reg_excuse[ip->r1>>1] = ST_FPCMP;	Add_to_worklist (st, FPCMP_LATENCY,		reg_writeback, (void *)(ip->r1));#endif	}			/* Set floating point unit control word		*/void opCTL_FPC (struct s_cpu_state *st, INST *ip, THREAD *th) {	int	inum;	CHECKFP()	if (!alls_quiet (st, ip, ST_FPC))		return;	inum = ip - st->iwin;	Ireg(ip->r1) = Ireg(ip->r2);	st->regs[th->regnames[CNDREG]] = CONDBIT & Ireg(ip->r2);	st->round_mode = Ireg(ip->r2) & 0x03;	set_rm (st->round_mode);	clear_fpc_stall(st,th,inum);	}static void clear_fpc_stall(struct s_cpu_state *st,THREAD *th, int inum) {	BrTREE	*br;			/* Now can start fetching new instructions	*/	th->stall_fpc = 0;	UpdateStallFetch (th);			/* Unstall children, too			*/	br = &st->branch_tree [st->iwin_br_node[inum]];	if (br->rchild >= 0)		{		br = &st->branch_tree [br->rchild];		th = &st->threads [br->thread];		th->stall_fpc = 0;		UpdateStallFetch (th);		}	}			/* Read floating point unit control word	*/void opCTL_CFC(struct s_cpu_state *st, INST *ip, THREAD *th) {	CHECKFP()	Ireg(ip->r1) = Ireg(ip->r2) | (CONDBIT & Ireg(ip->r3));	}			/* Control instruction: branch delay cycle	*/void opCTL_DLY (struct s_cpu_state *st, INST *ip, THREAD *th) {	IncStat(ST_BR_NOP);	}void opCP0 (struct s_cpu_state *st, INST *ip, THREAD *th) {    uint srcreg, dstreg;    bool hack, err;    int inum = ip - st->iwin;    if (ip->op == OPCP0) { 	if (!alls_quiet (st, ip, ST_SYSCALL))	   return;#ifdef PRECISE	if (st->iwin_headgrad != (ip - st->iwin)) {   	    st->stall_type = ST_SYSCALL;	    st->stall_issue = 1;	    return;	}#endif    }    srcreg = (ip->r2 > 0) ? Ureg(ip->r2) : 0;    err = DoPrivInst(st, ip->imm, srcreg, &dstreg, &hack);    if (err) {	st->iwin_except [inum] = GetLastException(st);	st->iwin_flags[inum] |= IWIN_FAULT;	CheckSquash (st, ip);	th->stall_except = 1;	UpdateStallFetch (th);	return;    }#ifndef R3K    if (hack) {	CPUState *P = (CPUState *)st->mipsyPtr;        st->iwin_branch_pc[inum] = P->PC;        th->pc = P->PC;    }        #endif    if (ip->r1 > 0) {	Ureg(ip->r1) = dstreg;    }    if (ip->op == OPCP0) { 	th->stall_cp0 = 0;		clear_fpc_stall(st,th, inum);    }}void opBDOOR (struct s_cpu_state *st, INST *ip, THREAD *th) {	if (!alls_quiet (st, ip, ST_SYSCALL))		return;#ifdef MIPSY_MXS	{	   /* Assume this is a call. Execute it on the real CPU. This */	   /* assumes that all backdoor calls take less than 4 */	   /* arguments. The prom stuff is a way for the simulated cpu to */	   /* actually run the code in simbootprom.c */	   CPUState *P = (CPUState *)st->mipsyPtr;	   int64 bdoorRetval;            PA pAddr;           Result ret;           ret = TranslateVirtualNoSideeffect(P,                                              (VA) th->pc-4,                                             &pAddr);           ASSERT(ret==SUCCESS);/* BASEM watch this! */	   bdoorRetval = ((int64 (*)(int,int,int,int))(pAddr))		(st->regs[th->regnames[4]], st->regs[th->regnames[5]], 		st->regs[th->regnames[6]], st->regs[th->regnames[7]]);	   st->regs[th->regnames[2]] = bdoorRetval >> 32;	   st->regs[th->regnames[3]] = bdoorRetval & 0xffffffff;	   th->pc = st->regs[th->regnames[31]];	}#endif	th->stall_sys = 0;	clear_fpc_stall(st,th, ip - st->iwin);	}void opLL (struct s_cpu_state *st, INST *ip, THREAD *th) {	int inum;	WorkDecls;	inum = ip - st->iwin;	if ((st->iwin_addr[inum] & 0x3) || 	    (st->iwin_flags[inum] & IWIN_UNCACHED)) {	    	    LS_EXC(EXC_RADE)	} else if (st->iwin_flags[inum] & IWIN_TLBFAULT) {	    st->iwin_flags[inum] |= IWIN_FAULT;	}	if (st->iwin_flags[inum] & IWIN_FAULT) {	    CheckSquash (st,ip);	    th->stall_except = 1;	    UpdateStallFetch (th);	    return;	    	}		ms_lsq (st, Ireg(ip->r2) + ip->imm, ip->r1, 0,					LD_INTEGER_LL, inum);	LoadStats()	}void opSC (struct s_cpu_state *st, INST *ip, THREAD *th) {	int inum;	WorkDecls;		inum = ip - st->iwin;	if ((st->iwin_addr[inum] & 0x3) || 	    (st->iwin_flags[inum] & IWIN_UNCACHED)) {	    	    LS_EXC(EXC_WADE)	} else if (st->iwin_flags[inum] & IWIN_TLBFAULT) {	    st->iwin_flags[inum] |= IWIN_FAULT;	}	if (st->iwin_flags[inum] & IWIN_FAULT) {	    CheckSquash (st,ip);	    th->stall_except = 1;	    th->stall_fpc = 0;	    UpdateStallFetch (th);	    return;	}		ms_lsq (st, Ireg(ip->r2) + ip->imm, ip->r3, ip->r1,					ST_INTEGER_SC, inum);	LoadStats()	}/* * Hacked LD and SD instruction execution.  */void opLDHACK (struct s_cpu_state *st, INST *ip, THREAD *th) {        uint tlbFlavor;        uint vAddr, pAddr = 0;        int inst, rt, rt2, rs, imm, ret;        CPUState *P = (CPUState *)st->mipsyPtr;        uint64 val;        int err;        void *bdoor = 0;        /*         * Need to single thread the processor for these hacked          * isntructions.          */	if (!alls_quiet (st, ip, ST_SYSCALL))		return;        inst = ip->imm;         tlbFlavor = TLB_READING;        rs = th->regnames[(inst>>21)&0x1f];        rt = th->regnames[(inst>>16)&0x1f];        rt2 = th->regnames[((inst>>16)&0x1f)+1];        imm = ((inst&0x8000)?(inst&0x0000ffff)-0x10000:(inst&0x0000ffff));        vAddr = Ireg(rs) + imm;             ret = TranslateVirtual(P, vAddr, &pAddr, &tlbFlavor, &bdoor);                if (ret != SUCCESS) {#ifdef HWBCOPY           if (tlbFlavor & TLB_MSG_SPACE) err = SUCCESS;           else {#else            {#endif              ms_break (st, &st->iwin[st->iwin_curi], "LDHACK");                err = FAILURE;           }        } else {           /* 64bit load into registers rt and rt+1 */           err = DoUncachedRead(st, vAddr, pAddr, 8, &val);           if (err == 0) {              Ureg(rt) = val>>32;              Ureg(rt2) = (uint)val;           }        }        if (err == 0) {            /* Worked - clear stall and continue */            th->stall_sys = 0;	    clear_fpc_stall(st,th, ip - st->iwin);        } else {           /* Retry instruction until the memory system can take it. */  	   st->stall_type = ST_SYSCALL;	   st->stall_issue = 1;	   return;        }	}void opSDHACK (struct s_cpu_state *st, INST *ip, THREAD *th) {        uint tlbFlavor;        uint vAddr, pAddr = 0;        int inst, rt, rt2, rs, imm, ret;        CPUState *P = (CPUState *)st->mipsyPtr;        uint64 val;        int err;        void *bdoor = 0;        /*         * Need to single thread the processor for these hacked          * isntructions.          */	if (!alls_quiet (st, ip, ST_SYSCALL))		return;        inst = ip->imm;         tlbFlavor = TLB_WRITING;        rs = th->regnames[(inst>>21)&0x1f];        rt = th->regnames[(inst>>16)&0x1f];        rt2 = th->regnames[((inst>>16)&0x1f)+1];        imm = ((inst&0x8000)?(inst&0x0000ffff)-0x10000:(inst&0x0000ffff));        vAddr = Ireg(rs) + imm;             ret = TranslateVirtual(P, vAddr, &pAddr, &tlbFlavor, &bdoor);                if (ret != SUCCESS) {#ifdef HWBCOPY           if (tlbFlavor & TLB_MSG_SPACE) err = SUCCESS;           else {#else            {#endif              ms_break (st, &st->iwin[st->iwin_curi], "SDHACK");                err = FAILURE;           }        } else {           /* 64bit store from registers rt and rt+1 */           val = Ureg(rt);           val <<= 32;           val |= Ureg(rt2);           err = DoUncachedWrite(st,vAddr, pAddr, 8,                              tlbFlavor & TLB_ACCELERATED, &val);        }        if (err == 0) {            /* Worked - clear stall and continue */            th->stall_sys = 0;	    clear_fpc_stall(st,th, ip - st->iwin);        } else {           /* Retry instruction until the memory system can take it. */  	   st->stall_type = ST_SYSCALL;	   st->stall_issue = 1;	   return;        }	}	/*	 *  alls_quiet  -  A utility routine for instructions that	 *			need to wait until all outstanding	 *			instructions are completed.	 *	 *	Returns TRUE if everything is quiet,	 *	otherwise returns FALSE.	 */static int alls_quiet(struct s_cpu_state *st, INST *ip, int excuse)	{	int	i;		/* Force in order issue around this instruction	*/		/* by stalling until all work has been done	*/		/* and all registers have been written.		*/	if (st->work_head) goto return_false;	if ((st->ldst_head) || (st->ldst_nextReserved)) goto return_false;#ifndef MIPSY_MXS	if (ms_bus_busy ()) goto return_false;#endif	for (i=0; i<MAX_PREG/2; i++)		{		if (st->reg_rstat[i].reg_status & REG_IN_WIN)			{			if ((ip->r1 < 0) || (i != (ip->r1>>1)))				goto return_false;			}		}	return (1);return_false:	st->stall_type = excuse;	st->stall_issue = 1;	return (0);	}

⌨️ 快捷键说明

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