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

📄 ms_inst.m4

📁 一个用在mips体系结构中的操作系统
💻 M4
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * */	/*	 *  ms_inst  -  All the code for executing instructions for the	 *		R4000 like processor	 *	 *	Jim Bennett	 *	1993, 1994, 1995	 */#include <stdlib.h>#include <math.h>#include "ms.h"#ifdef MIPSY_MXS#include "cp0.h"#include "simmisc.h"#include "sim_error.h"#include "sim.h"#define EXC_FPE EXC_CODE(15)   /* Need for R4000 */#elsetypedef	int	bool;#endif#define	SP_NEAR_ONE	0.999999#define	DP_NEAR_ONE	0.9999999999999	/*	 *  CHECKFP handles the exception that all floating point	 *	operations can potentially cause:  the coprocessor	 *	unusable exception.	 */define(CHECKFP, `	if (!FPusable(st)) {   	    int _inum = ip - st->iwin; 	    st->iwin_except [_inum] = GetLastException(st); 	    st->iwin_flags [_inum] |= IWIN_FAULT; 	    CheckSquash (st,ip); 	    th->stall_except = 1; 	    UpdateStallFetch (th); 	    return; 	} ' )	/*	 *  LS_EXC - is the common code for handling exceptions in load	 *	and store instructions.	 */define(LS_EXC, ` {#ifdef MIPSY_MXS	CPUState *P = (CPUState *)st->mipsyPtr;	RECORD_EXCEPTION(P,$1,E_VEC, st->iwin_addr[inum], 				P->CP0[C0_TLBHI],P->CP0[C0_CTXT],                             P->CP0[C0_XCTXT]);    st->iwin_except [inum] = GetLastException(st);	st->iwin_flags[inum] |= IWIN_FAULT;#endif	} ' )	/*	 *  opBRANCH and opCALL define the processing common to branch	 *  and call instructions.  The only difference between most of	 *  these instructions is the condition under which the branch	 *  is taken.  The first argument to the macro is the condition,	 *  the second is a flag indicating if it's a floating point	 *  branch, and the third is a flag indicating if it's a branch	 *  likely instruction.	 */define(opBRANCH, ` {	int	inum, ix;	BrTREE	*br, *right;	WorkDecls;	if ($2) { CHECKFP }	inum = ip - st->iwin;	br = &st->branch_tree [st->iwin_br_node[inum]];	right = &st->branch_tree [br->rchild];	ix = bp_pc_to_index(st->iwin_pc [inum]);	if ($1)		{		st->bp_bits[ix]++;		if (st->bp_bits[ix] > BP_MAX_VAL)			st->bp_bits[ix] = BP_MAX_VAL;		if (PredictTaken (right->condition, $3))			br->resolution = PRUNE_LEFT;		else			br->resolution = PRUNE_RIGHT;		st->iwin_branch_pc [inum] = ip->imm;                st->iwin_flags[inum] |= IWIN_TAKENBR;		if (br->lchild == -1)			{			th->pc = ip->imm;			th->debugpc = cadr_to_addr (st, th->pc);#ifdef BREAKPOINT			if (jmpbrk && (th->pc == jmpbrk))			    ms_break (st, &st->iwin[st->iwin_curi], "JMPBRK");#endif			}		}	else		{		st->bp_bits[ix]--;		if (st->bp_bits[ix] < 0)			st->bp_bits[ix] = 0;		if (PredictTaken (right->condition, $3))			br->resolution = PRUNE_RIGHT;		else			br->resolution = PRUNE_LEFT;		st->iwin_branch_pc [inum] = st->iwin_pc [inum] +						(PC_INC*(1+BRANCH_SLOTS));		}#if BRANCH_LATENCY > 1	Add_to_worklist (st, BRANCH_LATENCY, finish_branch, (void *)ip);#else	th->stall_branch = 0;	UpdateStallFetch (th);	prune_branch (st, st->iwin_br_node[inum]);#endif	} ')define(opCALL, ` {	int	inum, ix;	BrTREE	*br, *right;	WorkDecls;		inum = ip - st->iwin;	br = &st->branch_tree [st->iwin_br_node[inum]];	right = &st->branch_tree [br->rchild];	ix = bp_pc_to_index(st->iwin_pc [inum]);	if ($1)		{		Ireg(ip->r1) = cadr_to_addr (st, th->returnpc);		st->bp_bits[ix]++;		if (st->bp_bits[ix] > BP_MAX_VAL)			st->bp_bits[ix] = BP_MAX_VAL;		if (PredictTaken (right->condition, $3))			br->resolution = PRUNE_LEFT;		else			br->resolution = PRUNE_RIGHT;		st->iwin_branch_pc [inum] = ip->imm;#ifdef PROCSTATS		push_stats (st, th->pc);#endif		if (br->lchild == -1)			{			th->pc = ip->imm;			th->debugpc = cadr_to_addr (st, th->pc);#ifdef BREAKPOINT			if (jmpbrk && (th->pc == jmpbrk))			    ms_break (st, &st->iwin[st->iwin_curi], "JMPBRK");#endif			}		}	else		{		st->bp_bits[ix]--;		if (st->bp_bits[ix] < 0)			st->bp_bits[ix] = 0;		if (PredictTaken (right->condition, $3))			br->resolution = PRUNE_RIGHT;		else			br->resolution = PRUNE_LEFT;		st->iwin_branch_pc [inum] = st->iwin_pc [inum] +						(PC_INC*(1+BRANCH_SLOTS));		}#if BRANCH_LATENCY > 1	Add_to_worklist (st, BRANCH_LATENCY, finish_call, (void *)ip);#else	th->stall_branch = 0;	UpdateStallFetch (th);	prune_branch (st, st->iwin_br_node[inum]);#endif	} ')	/*	 *  LoadStats  -  Common routine in loads for updating statistics	 *		  related information.	 */define(LoadStats, ` if (!st->stall_issue)#if PC_LATENCY > 1	{ st->reg_excuse[ip->r1>>1] = ST_PC_DLY;	  st->new_excuse[ip->r1>>1] = ST_CACHE_LSQ;	  Add_to_worklist (st, PC_LATENCY, update_excuse, (void *)(ip->r1)); }#else	st->reg_excuse[ip->r1>>1] = ST_CACHE_LSQ;	st->new_excuse[ip->r1>>1] = ST_NO_EXCUSE;#endif	' )static void clear_fpc_stall(struct s_cpu_state *st, THREAD *th, int inum);static int alls_quiet(struct s_cpu_state *st, INST *ip, int excuse);void opILL (struct s_cpu_state *st, INST *ip, THREAD *th) {    int inum = ip - st->iwin;#ifdef MIPSY_MXS    CPUState *P = (CPUState *)st->mipsyPtr;    RECORD_EXCEPTION(P,EXC_II,E_VEC, P->CP0[C0_BADVADDR],				P->CP0[C0_TLBHI],P->CP0[C0_CTXT],P->CP0[C0_XCTXT]);    st->iwin_except [inum] = GetLastException(st);    st->iwin_flags[inum] |= IWIN_FAULT;#endif    CheckSquash (st,ip);    th->stall_except = 1;    UpdateStallFetch (th);	}void opJ (struct s_cpu_state *st, INST *ip, THREAD *th) {	int	inum;	WorkDecls;	th->pc = ip->imm;#if BRANCH_LATENCY > 1	Add_to_worklist (st, BRANCH_LATENCY, finish_branch, (void *)ip);#else	inum = ip - st->iwin;	th->stall_branch = 0;	UpdateStallFetch (th);	prune_branch (st, st->iwin_br_node[inum]);#endif	th->debugpc = cadr_to_addr (st, th->pc);#ifdef BREAKPOINT	if (jmpbrk && (th->pc == jmpbrk))		ms_break (st, &st->iwin[st->iwin_curi], "JMPBRK");#endif	}void opJAL (struct s_cpu_state *st, INST *ip, THREAD *th) {	int	inum;	BrTREE	*br;	WorkDecls;	inum = ip - st->iwin;	br = &st->branch_tree [st->iwin_br_node[inum]];	Ireg(ip->r1) = cadr_to_addr (st, th->returnpc);	br->resolution = PRUNE_LEFT;	st->iwin_branch_pc [inum] = ip->imm;#ifdef PROCSTATS	push_stats (st, th->pc);#endif	if (br->lchild == -1)		{		th->pc = ip->imm;		th->debugpc = cadr_to_addr (st, th->pc);#ifdef BREAKPOINT		if (jmpbrk && (th->pc == jmpbrk))			ms_break (st, &st->iwin[st->iwin_curi], "JMPBRK");#endif		}#if BRANCH_LATENCY > 1	Add_to_worklist (st, BRANCH_LATENCY, finish_call, (void *)ip);#else	th->stall_branch = 0;	UpdateStallFetch (th);	prune_branch (st, st->iwin_br_node[inum]);#endif	}void opBEQ (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH(Ireg(ip->r2) == Ireg(ip->r3),0,0)void opBNE (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH(Ireg(ip->r2) != Ireg(ip->r3),0,0)void opBLEZ (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH(Ireg(ip->r2) <= 0,0,0)void opBGTZ (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH(Ireg(ip->r2) > 0,0,0)void opBLTZ (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH(Ireg(ip->r2) < 0,0,0)void opBGEZ (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH(Ireg(ip->r2) >= 0,0,0)void opBC1F (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH((Ireg(ip->r2) & CONDBIT) == 0,1,0)void opBC1T (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH(Ireg(ip->r2) & CONDBIT,1,0)void opBEQL (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH(Ireg(ip->r2) == Ireg(ip->r3),0, 1)void opBNEL (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH(Ireg(ip->r2) != Ireg(ip->r3),0, 1)void opBLEZL (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH(Ireg(ip->r2) <= 0,0, 1)void opBGTZL (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH(Ireg(ip->r2) > 0,0, 1)void opBLTZL (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH(Ireg(ip->r2) < 0,0, 1)void opBGEZL (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH(Ireg(ip->r2) >= 0,0, 1)void opBC1FL (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH((Ireg(ip->r2) & CONDBIT) == 0,1, 1)void opBC1TL (struct s_cpu_state *st, INST *ip, THREAD *th)	opBRANCH(Ireg(ip->r2) & CONDBIT,1, 1)void opBLTZAL (struct s_cpu_state *st, INST *ip, THREAD *th)	opCALL(Ireg(ip->r2) < 0,0,0)void opBGEZAL (struct s_cpu_state *st, INST *ip, THREAD *th)	opCALL(Ireg(ip->r2) >= 0,0,0)void opBLTZALL (struct s_cpu_state *st, INST *ip, THREAD *th)	opCALL(Ireg(ip->r2) < 0,0,1)void opBGEZALL (struct s_cpu_state *st, INST *ip, THREAD *th)	opCALL(Ireg(ip->r2) >= 0,0,1)void opADDI (struct s_cpu_state *st, INST *ip, THREAD *th) {	Ireg(ip->r1) = Ireg(ip->r2) + ip->imm;	}void opADDIU (struct s_cpu_state *st, INST *ip, THREAD *th) {	Ureg(ip->r1) = Ureg(ip->r2) + ip->imm;	}void opSLTI (struct s_cpu_state *st, INST *ip, THREAD *th) {	Ireg(ip->r1) = (Ireg(ip->r2) < ip->imm ? 1 : 0);	}void opSLTIU (struct s_cpu_state *st, INST *ip, THREAD *th) {	Ireg(ip->r1) = (Ureg(ip->r2) < 			(unsigned)ip->imm ? 1 : 0);	}void opANDI (struct s_cpu_state *st, INST *ip, THREAD *th) {	Ireg(ip->r1) = Ireg(ip->r2) & ip->imm;	}void opORI (struct s_cpu_state *st, INST *ip, THREAD *th) {	Ireg(ip->r1) = Ireg(ip->r2) | ip->imm;	}void opXORI (struct s_cpu_state *st, INST *ip, THREAD *th) {	Ireg(ip->r1) = Ireg(ip->r2) ^ ip->imm;	}void opHCPY (struct s_cpu_state *st, INST *ip, THREAD *th) {	if (ip->op == OPHCPYC1) {		CHECKFP()	}	if ((ip->r1 & (~0x01)) != ip->r3)		{		Dreg(ip->r1) = Dreg(ip->r3);		}	Ireg(ip->r1) = Ireg(ip->r2);	}void opLB (struct s_cpu_state *st, INST *ip, THREAD *th) {	int inum;	WorkDecls;	inum = ip - st->iwin;	    	if (st->iwin_flags[inum] & IWIN_TLBFAULT) {	    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_B, ip - st->iwin);	LoadStats()	}void opPREF (struct s_cpu_state *st, INST *ip, THREAD *th) {	WorkDecls;	ms_lsq (st, Ireg(ip->r2) + ip->imm, ip->r1, 0,				PREFETCH, ip - st->iwin);	LoadStats()	}void opLH (struct s_cpu_state *st, INST *ip, THREAD *th) {	int inum;	WorkDecls;	inum = ip - st->iwin;	if (st->iwin_addr[inum] & 0x1) {	    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_H, ip - st->iwin);	LoadStats()	}void opLWL (struct s_cpu_state *st, INST *ip, THREAD *th) {	int inum = ip - st->iwin;	WorkDecls;	if (st->iwin_flags[inum] & IWIN_TLBFAULT) {	    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, ip->r3,				LD_UNSIGNED_L, ip - st->iwin);	LoadStats()	}void opLW (struct s_cpu_state *st, INST *ip, THREAD *th) {	int inum;	WorkDecls;	inum = ip - st->iwin;	if (st->iwin_addr[inum] & 0x3) {	    #ifdef R3KLOCKSUPPORT	    extern void *lockCAShackAddr;	    if ((ip->imm == 1) && 		(st->iwin_pc[inum] == *(int *) lockCAShackAddr)) {		goto out;	    }#endif	    LS_EXC(EXC_RADE)	} else if (st->iwin_flags[inum] & IWIN_TLBFAULT) {	    st->iwin_flags[inum] |= IWIN_FAULT;	}#ifdef R3KLOCKSUPPORT  out:#endif	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_W, ip - st->iwin);	LoadStats()	}void opLBU (struct s_cpu_state *st, INST *ip, THREAD *th) {	int inum = ip - st->iwin;	WorkDecls;	if (st->iwin_flags[inum] & IWIN_TLBFAULT) {	    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_UNSIGNED_B, ip - st->iwin);	LoadStats()	}void opLHU (struct s_cpu_state *st, INST *ip, THREAD *th) {	int inum;	WorkDecls;	inum = ip - st->iwin;	if (st->iwin_addr[inum] & 0x1) {	    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_UNSIGNED_H, ip - st->iwin);	LoadStats()	}void opLWR (struct s_cpu_state *st, INST *ip, THREAD *th) {	int inum;	WorkDecls;	inum = ip - st->iwin;	if (st->iwin_flags[inum] & IWIN_TLBFAULT) {	    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, ip->r3,				LD_UNSIGNED_R, ip - st->iwin);	LoadStats()	}void opSB (struct s_cpu_state *st, INST *ip, THREAD *th) {	int inum;	inum = ip - st->iwin;	if (st->iwin_flags[inum] & IWIN_TLBFAULT) {	    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->r3, 0,				ST_INTEGER_B, ip - st->iwin);	if (st->stall_issue) return;#ifdef BREAKPOINT	if (membrk && ((Ireg(ip->r2) + ip->imm) == membrk))		ms_break (st, &st->iwin[st->iwin_curi], "MEMBRK");#endif	}void opSH (struct s_cpu_state *st, INST *ip, THREAD *th) {	int inum;	inum = ip - st->iwin;	if (st->iwin_addr[inum] & 0x1) {	    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;	    UpdateStallFetch (th);	    return;	}	ms_lsq (st, Ireg(ip->r2) + ip->imm, ip->r3, 0,				ST_INTEGER_H, ip - st->iwin);	if (st->stall_issue) return;#ifdef BREAKPOINT	if (membrk && ((Ireg(ip->r2) + ip->imm) == membrk))		ms_break (st, &st->iwin[st->iwin_curi], "MEMBRK");#endif	}void opSWL (struct s_cpu_state *st, INST *ip, THREAD *th) {	int inum;	inum = ip - st->iwin;	if (st->iwin_flags[inum] & IWIN_TLBFAULT) {	    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->r3, 0,				ST_INTEGER_L, ip - st->iwin);	if (st->stall_issue) return;#ifdef BREAKPOINT	if (membrk && ((Ireg(ip->r2) + ip->imm) == membrk))		ms_break (st, &st->iwin[st->iwin_curi], "MEMBRK");#endif	}void opSW (struct s_cpu_state *st, INST *ip, THREAD *th) {	int inum;	inum = ip - st->iwin;	if (st->iwin_addr[inum] & 0x3) {	    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);

⌨️ 快捷键说明

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