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

📄 run.c

📁 用汇编语言编程源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	    case Y_OR_OP:	      R[RD (inst)] = R[RS (inst)] | R[RT (inst)];	      break;	    case Y_ORI_OP:	      R[RT (inst)] = R[RS (inst)] | (0xffff & IMM (inst));	      break;	    case Y_RFE_OP:	      Status_Reg = (Status_Reg & 0xfffffff0) | ((Status_Reg & 0x3c) >> 2);	      break;	    case Y_SB_OP:	      SET_MEM_BYTE (R[BASE (inst)] + IOFFSET (inst), R[RT (inst)]);	      break;	    case Y_SH_OP:	      SET_MEM_HALF (R[BASE (inst)] + IOFFSET (inst), R[RT (inst)]);	      break;	    case Y_SLL_OP:	      {		int shamt = SHAMT (inst);		if (shamt >= 0 && shamt < 32)		  R[RD (inst)] = R[RT (inst)] << shamt;		else		  R[RD (inst)] = R[RT (inst)];		break;	      }	    case Y_SLLV_OP:	      {		int shamt = (R[RS (inst)] & 0x1f);		if (shamt >= 0 && shamt < 32)		  R[RD (inst)] = R[RT (inst)] << shamt;		else		  R[RD (inst)] = R[RT (inst)];		break;	      }	    case Y_SLT_OP:	      if (R[RS (inst)] < R[RT (inst)])		R[RD (inst)] = 1;	      else		R[RD (inst)] = 0;	      break;	    case Y_SLTI_OP:	      if (R[RS (inst)] < (short) IMM (inst))		R[RT (inst)] = 1;	      else		R[RT (inst)] = 0;	      break;	    case Y_SLTIU_OP:	      {		int x = (short) IMM (inst);		if ((u_reg_word) R[RS (inst)] < (u_reg_word) x)		  R[RT (inst)] = 1;		else		  R[RT (inst)] = 0;		break;	      }	    case Y_SLTU_OP:	      if ((u_reg_word) R[RS (inst)] < (u_reg_word) R[RT (inst)])		R[RD (inst)] = 1;	      else		R[RD (inst)] = 0;	      break;	    case Y_SRA_OP:	      {		int shamt = SHAMT (inst);		reg_word val = R[RT (inst)];		if (shamt >= 0 && shamt < 32)		  R[RD (inst)] = val >> shamt;		else		  R[RD (inst)] = val;		break;	      }	    case Y_SRAV_OP:	      {		int shamt = R[RS (inst)] & 0x1f;		reg_word val = R[RT (inst)];		if (shamt >= 0 && shamt < 32)		  R[RD (inst)] = val >> shamt;		else		  R[RD (inst)] = val;		break;	      }	    case Y_SRL_OP:	      {		int shamt = SHAMT (inst);		u_reg_word val = R[RT (inst)];		if (shamt >= 0 && shamt < 32)		  R[RD (inst)] = val >> shamt;		else		  R[RD (inst)] = val;		break;	      }	    case Y_SRLV_OP:	      {		int shamt = R[RS (inst)] & 0x1f;		u_reg_word val = R[RT (inst)];		if (shamt >= 0 && shamt < 32)		  R[RD (inst)] = val >> shamt;		else		  R[RD (inst)] = val;		break;	      }	    case Y_SUB_OP:	      {		register reg_word vs = R[RS (inst)], vt = R[RT (inst)];		register reg_word diff = vs - vt;		if (SIGN_BIT (vs) != SIGN_BIT (vt)		    && SIGN_BIT (vs) != SIGN_BIT (diff))		  RAISE_EXCEPTION (OVF_EXCPT, break);		R[RD (inst)] = diff;		break;	      }	    case Y_SUBU_OP:	      R[RD (inst)] = (u_reg_word)R[RS (inst)]-(u_reg_word)R[RT (inst)];	      break;	    case Y_SW_OP:	      SET_MEM_WORD (R[BASE (inst)] + IOFFSET (inst), R[RT (inst)]);	      break;	    case Y_SWC0_OP:	    case Y_SWC2_OP:	    case Y_SWC3_OP:	      SET_MEM_WORD (R[BASE (inst)] + IOFFSET (inst),			    CPR[OPCODE (inst) - Y_SWC0_OP][RT (inst)]);	      break;	    case Y_SWL_OP:	      {		register mem_addr addr = R[BASE (inst)] + IOFFSET (inst);		mem_word data;		reg_word reg = R[RT (inst)];		register int byte = addr & 0x3;		READ_MEM_WORD (data, (addr & 0xfffffffc));#ifdef BIGENDIAN		switch (byte)		  {		  case 0:		    data = reg;		    break;		  case 1:		    data = (data & 0xff000000) | (reg >> 8 & 0xffffff);		    break;		  case 2:		    data = (data & 0xffff0000) | (reg >> 16 & 0xffff);		    break;		  case 3:		    data = (data & 0xffffff00) | (reg >> 24 & 0xff);		    break;		  }#else		switch (byte)		  {		  case 0:		    data = (data & 0xffffff00) | (reg >> 24 & 0xff);		    break;		  case 1:		    data = (data & 0xffff0000) | (reg >> 16 & 0xffff);		    break;		  case 2:		    data = (data & 0xff000000) | (reg >> 8 & 0xffffff);		    break;		  case 3:		    data = reg;		    break;		  }#endif		SET_MEM_WORD (addr & 0xfffffffc, data);		break;	      }	    case Y_SWR_OP:	      {		register mem_addr addr = R[BASE (inst)] + IOFFSET (inst);		mem_word data;		reg_word reg = R[RT (inst)];		register int byte = addr & 0x3;		READ_MEM_WORD (data, (addr & 0xfffffffc));#ifdef BIGENDIAN		switch (byte)		  {		  case 0:		    data = ((reg << 24) & 0xff000000) | (data & 0xffffff);		    break;		  case 1:		    data = ((reg << 16) & 0xffff0000) | (data & 0xffff);		    break;		  case 2:		    data = ((reg << 8) & 0xffffff00) | (data & 0xff) ;		    break;		  case 3:		    data = reg;		    break;		  }#else		switch (byte)		  {		  case 0:		    data = reg;		    break;		  case 1:		    data = ((reg << 8) & 0xffffff00) | (data & 0xff) ;		    break;		  case 2:		    data = ((reg << 16) & 0xffff0000) | (data & 0xffff);		    break;		  case 3:		    data = ((reg << 24) & 0xff000000) | (data & 0xffffff);		    break;		  }#endif		SET_MEM_WORD (addr & 0xfffffffc, data);		break;	      }	    case Y_SYSCALL_OP:	      if (!do_syscall ())		return (0);	      break;	    case Y_TLBP_OP:	    case Y_TLBR_OP:	    case Y_TLBWI_OP:	    case Y_TLBWR_OP:	      fatal_error ("Unimplemented operation\n");	      break;	    case Y_XOR_OP:	      R[RD (inst)] = R[RS (inst)] ^ R[RT (inst)];	      break;	    case Y_XORI_OP:	      R[RT (inst)] = R[RS (inst)] ^ (0xffff & IMM (inst));	      break;	      /* FPA Operations */	    case Y_ABS_S_OP:	      SET_FPR_S (FD (inst), fabs (FPR_S (FS (inst))));	      break;	    case Y_ABS_D_OP:	      SET_FPR_D (FD (inst), fabs (FPR_D (FS (inst))));	      break;	    case Y_ADD_S_OP:	      SET_FPR_S (FD (inst), FPR_S (FS (inst)) + FPR_S (FT (inst)));	      /* Should trap on inexact/overflow/underflow */	      break;	    case Y_ADD_D_OP:	      SET_FPR_D (FD (inst), FPR_D (FS (inst)) + FPR_D (FT (inst)));	      /* Should trap on inexact/overflow/underflow */	      break;	    case Y_BC1F_OP:	      BRANCH_INST (FpCond == 0,			   PC + IDISP (inst));	      break;	    case Y_BC1T_OP:	      BRANCH_INST (FpCond == 1,			   PC + IDISP (inst));	      break;	    case Y_C_F_S_OP:	    case Y_C_UN_S_OP:	    case Y_C_EQ_S_OP:	    case Y_C_UEQ_S_OP:	    case Y_C_OLT_S_OP:	    case Y_C_OLE_S_OP:	    case Y_C_ULT_S_OP:	    case Y_C_ULE_S_OP:	    case Y_C_SF_S_OP:	    case Y_C_NGLE_S_OP:	    case Y_C_SEQ_S_OP:	    case Y_C_NGL_S_OP:	    case Y_C_LT_S_OP:	    case Y_C_NGE_S_OP:	    case Y_C_LE_S_OP:	    case Y_C_NGT_S_OP:	      {		float v1 = FPR_S (FS (inst)), v2 = FPR_S (FT (inst));		double dv1 = v1, dv2 = v2;		int less, equal, unordered;		int cond = COND (inst);		if (NaN (dv1) || NaN (dv2))		  {		    less = 0;		    equal = 0;		    unordered = 1;		    if (cond & COND_IN)		      RAISE_EXCEPTION (INVALID_EXCEPT, break);		  }		else		  {		    less = v1 < v2;		    equal = v1 == v2;		    unordered = 0;		  }		FpCond = 0;		if (cond & COND_LT)		  FpCond |= less;		if (cond & COND_EQ)		  FpCond |= equal;		if (cond & COND_UN)		  FpCond |= unordered;	      }	      break;	    case Y_C_F_D_OP:	    case Y_C_UN_D_OP:	    case Y_C_EQ_D_OP:	    case Y_C_UEQ_D_OP:	    case Y_C_OLT_D_OP:	    case Y_C_OLE_D_OP:	    case Y_C_ULT_D_OP:	    case Y_C_ULE_D_OP:	    case Y_C_SF_D_OP:	    case Y_C_NGLE_D_OP:	    case Y_C_SEQ_D_OP:	    case Y_C_NGL_D_OP:	    case Y_C_LT_D_OP:	    case Y_C_NGE_D_OP:	    case Y_C_LE_D_OP:	    case Y_C_NGT_D_OP:	      {		double v1 = FPR_D (FS (inst)), v2 = FPR_D (FT (inst));		int less, equal, unordered;		int cond = COND (inst);		if (NaN (v1) || NaN (v2))		  {		    less = 0;		    equal = 0;		    unordered = 1;		    if (cond & COND_IN)		      RAISE_EXCEPTION (INVALID_EXCEPT, break);		  }		else		  {		    less = v1 < v2;		    equal = v1 == v2;		    unordered = 0;		  }		FpCond = 0;		if (cond & COND_LT)		  FpCond |= less;		if (cond & COND_EQ)		  FpCond |= equal;		if (cond & COND_UN)		  FpCond |= unordered;	      }	      break;	    case Y_CFC1_OP:	      R[RT (inst)] = FCR[RD (inst)]; /* RD not FS */	      break;	    case Y_CTC1_OP:	      FCR[RD (inst)] = R[RT (inst)]; /* RD not FS */	      break;	    case Y_CVT_D_S_OP:	      {		double val = FPR_S (FS (inst));		SET_FPR_D (FD (inst), val);		break;	      }	    case Y_CVT_D_W_OP:	      {		double val = FPR_W (FS (inst));		SET_FPR_D (FD (inst), val);		break;	      }	    case Y_CVT_S_D_OP:	      {		float val = (float)FPR_D (FS (inst));		SET_FPR_S (FD (inst), val);		break;	      }	    case Y_CVT_S_W_OP:	      {		float val = (float)FPR_W (FS (inst));		SET_FPR_S (FD (inst), val);		break;	      }	    case Y_CVT_W_D_OP:	      {		int val = (int)FPR_D (FS (inst));		SET_FPR_W (FD (inst), val);		break;	      }	    case Y_CVT_W_S_OP:	      {		int val = (int)FPR_S (FS (inst));		SET_FPR_W (FD (inst), val);		break;	      }	    case Y_DIV_S_OP:	      SET_FPR_S (FD (inst), FPR_S (FS (inst)) / FPR_S (FT (inst)));	      break;	    case Y_DIV_D_OP:	      SET_FPR_D (FD (inst), FPR_D (FS (inst)) / FPR_D (FT (inst)));	      break;	    case Y_LWC1_OP:	      {		reg_word *wp = (reg_word *) &FGR[FT (inst)];		LOAD_INST (READ_MEM_WORD, R[BASE (inst)] + IOFFSET (inst), wp,			   0xffffffff);		break;	      }	    case Y_MFC1_OP:	      {		float val = FGR[RD (inst)]; /* RD not FS */		reg_word *vp = (reg_word *) &val;		R[RT (inst)] = *vp; /* Fool coercion */		break;	      }	    case Y_MOV_S_OP:	      SET_FPR_S (FD (inst), FPR_S (FS (inst)));	      break;	    case Y_MOV_D_OP:	      SET_FPR_D (FD (inst), FPR_D (FS (inst)));	      break;	    case Y_MTC1_OP:	      {		reg_word word = R[RT (inst)];		float *wp = (float *) &word;		FGR[RD (inst)] = *wp; /* RD not FS, fool coercion */		break;	      }	    case Y_MUL_S_OP:	      SET_FPR_S (FD (inst), FPR_S (FS (inst)) * FPR_S (FT (inst)));	      break;	    case Y_MUL_D_OP:	      SET_FPR_D (FD (inst), FPR_D (FS (inst)) * FPR_D (FT (inst)));	      break;	    case Y_NEG_S_OP:	      SET_FPR_S (FD (inst), -FPR_S (FS (inst)));	      break;	    case Y_NEG_D_OP:	      SET_FPR_D (FD (inst), -FPR_D (FS (inst)));	      break;	    case Y_SUB_S_OP:	      SET_FPR_S (FD (inst), FPR_S (FS (inst)) - FPR_S (FT (inst)));	      break;	    case Y_SUB_D_OP:	      SET_FPR_D (FD (inst), FPR_D (FS (inst)) - FPR_D (FT (inst)));	      break;	    case Y_SWC1_OP:	      {		float val = FGR[RT (inst)];		reg_word *vp = (reg_word *) &val;		SET_MEM_WORD (R[BASE (inst)] + IOFFSET (inst), *vp);		break;	      }	    default:	      fatal_error ("Unknown instruction type: %d\n", OPCODE (inst));	      break;	    }	  /* After instruction executes: */	  PC += BYTES_PER_WORD;	  if (exception_occurred)	    {	      if ((Cause >> 2) > LAST_REAL_EXCEPT)		EPC = PC - BYTES_PER_WORD;	      handle_exception ();	    }	}			/* End: for (step = 0; ... */    }				/* End: for ( ; steps_to_run > 0 ... */  /* Executed enought steps, return, but are able to continue. */  return (1);}/* Multiply two 32-bit numbers, V1 and V2, to produce a 64 bit result in   the HI/LO registers.	 The algorithm is high-school math:	 A B       x C D       ------       AD || BD AC || CB || 0 where A and B are the high and low short words of V1, C and D are the short words of V2, AD is the product of A and D, and X || Y is (X << 16) + Y. Since the algorithm is programmed in C, we need to be careful not to overflow. */#ifdef __STDC__static voidlong_multiply (reg_word v1, reg_word v2)#elsestatic voidlong_multiply (v1, v2)     reg_word v1, v2;#endif{  register u_reg_word a, b, c, d;  register u_reg_word bd, ad, cb, ac;  register u_reg_word mid, mid2, carry_mid = 0;  a = (v1 >> 16) & 0xffff;  b = v1 & 0xffff;  c = (v2 >> 16) & 0xffff;  d = v2 & 0xffff;  bd = b * d;  ad = a * d;  cb = c * b;  ac = a * c;  mid = ad + cb;  if (mid < ad || mid < cb)    /* Arithmetic overflow or carry-out */    carry_mid = 1;  mid2 = mid + ((bd >> 16) & 0xffff);  if (mid2 < mid || mid2 < ((bd >> 16) & 0xffff))    /* Arithmetic overflow or carry-out */    carry_mid += 1;  LO = (bd & 0xffff) | ((mid2 & 0xffff) << 16);  HI = ac + (carry_mid << 16) + ((mid2 >> 16) & 0xffff);}

⌨️ 快捷键说明

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