📄 run.c
字号:
case 2: word = ((word & 0xffff) << 16) | (reg_val & 0xffff); break; case 3: word = ((word & 0xff) << 24) | (reg_val & 0xffffff); break; }#else switch (byte) { case 0: word = ((word & 0xff) << 24) | (reg_val & 0xffffff); break; case 1: word = ((word & 0xffff) << 16) | (reg_val & 0xffff); break; case 2: word = ((word & 0xffffff) << 8) | (reg_val & 0xff); break; case 3: word = word; break; }#endif LOAD_INST_BASE (&R[RT (inst)], word); break; } case Y_LWR_OP: { mem_addr addr = R[BASE (inst)] + IOFFSET (inst); reg_word word; /* Can't be register */ int byte = addr & 0x3; reg_word reg_val = R[RT (inst)]; word = read_mem_word (addr & 0xfffffffc); if (!exception_occurred)#ifdef BIGENDIAN switch (byte) { case 0: word = (reg_val & 0xffffff00) | ((unsigned)(word & 0xff000000) >> 24); break; case 1: word = (reg_val & 0xffff0000) | ((unsigned)(word & 0xffff0000) >> 16); break; case 2: word = (reg_val & 0xff000000) | ((unsigned)(word & 0xffffff00) >> 8); break; case 3: word = word; break; }#else switch (byte) { case 0: word = word; break; case 1: word = (reg_val & 0xff000000) | ((word & 0xffffff00) >> 8); break; case 2: word = (reg_val & 0xffff0000) | ((word & 0xffff0000) >> 16); break; case 3: word = (reg_val & 0xffffff00) | ((word & 0xff000000) >> 24); break; }#endif LOAD_INST_BASE (&R[RT (inst)], word); break; } case Y_MADD_OP: { reg_word lo = LO, hi = HI; reg_word tmp; signed_multiply(R[RS (inst)], R[RT (inst)]); tmp = lo + LO; if (tmp < LO || tmp < lo) /* Overflow */ hi += 1; LO = tmp; HI = hi + HI; break; } case Y_MADDU_OP: { reg_word lo = LO, hi = HI; reg_word tmp; unsigned_multiply(R[RS (inst)], R[RT (inst)]); tmp = lo + LO; if (tmp < LO || tmp < lo) /* Overflow */ hi += 1; LO = tmp; HI = hi + HI; break; } case Y_MFC0_OP: R[RT (inst)] = CPR[0][FS (inst)]; break; case Y_MFC2_OP: RAISE_EXCEPTION (ExcCode_CpU, {}); /* No Coprocessor 2 */ break; case Y_MFHI_OP: R[RD (inst)] = HI; break; case Y_MFLO_OP: R[RD (inst)] = LO; break; case Y_MOVN_OP: if (R[RT (inst)] != 0) R[RD (inst)] = R[RS (inst)]; break; case Y_MOVZ_OP: if (R[RT (inst)] == 0) R[RD (inst)] = R[RS (inst)]; break; case Y_MSUB_OP: { reg_word lo = LO, hi = HI; reg_word tmp; signed_multiply(R[RS (inst)], R[RT (inst)]); tmp = lo - LO; if (tmp < LO || tmp < lo) /* Underflow */ hi -= 1; LO = tmp; HI = hi - HI; break; } case Y_MSUBU_OP: { reg_word lo = LO, hi = HI; reg_word tmp; unsigned_multiply(R[RS (inst)], R[RT (inst)]); tmp = lo - LO; if (tmp < LO || tmp < lo) /* Underflow */ hi -= 1; LO = tmp; HI = hi - HI; break; } case Y_MTC0_OP: CPR[0][FS (inst)] = R[RT (inst)]; switch (FS (inst)) { case CP0_Compare_Reg: CP0_Cause &= ~CP0_Cause_IP7; /* Writing clears HW interrupt 5 */ break; case CP0_Status_Reg: CP0_Status &= CP0_Status_Mask; CP0_Status |= ((CP0_Status_CU & 0x30000000) | CP0_Status_UM); break; case CP0_Cause_Reg: CPR[0][FS (inst)] &= CP0_Cause_Mask; break; case CP0_Config_Reg: CPR[0][FS (inst)] &= CP0_Config_Mask; break; default: break; } break; case Y_MTC2_OP: RAISE_EXCEPTION (ExcCode_CpU, {}); /* No Coprocessor 2 */ break; case Y_MTHI_OP: HI = R[RS (inst)]; break; case Y_MTLO_OP: LO = R[RS (inst)]; break; case Y_MUL_OP: signed_multiply(R[RS (inst)], R[RT (inst)]); R[RD (inst)] = LO; break; case Y_MULT_OP: signed_multiply(R[RS (inst)], R[RT (inst)]); break; case Y_MULTU_OP: unsigned_multiply (R[RS (inst)], R[RT (inst)]); break; case Y_NOR_OP: R[RD (inst)] = ~ (R[RS (inst)] | R[RT (inst)]); break; 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_PREF_OP: break; /* Memory details not implemented */ case Y_RFE_OP:#ifdef MIPS1 /* This is MIPS-I, not compatible with MIPS32 or the definition of the bits in the CP0 Status register in that architecture. */ CP0_Status = (CP0_Status & 0xfffffff0) | ((CP0_Status & 0x3c) >> 2);#else RAISE_EXCEPTION (ExcCode_RI, {}); /* Not MIPS32 instruction */#endif break; case Y_SB_OP: set_mem_byte (R[BASE (inst)] + IOFFSET (inst), R[RT (inst)]); break; case Y_SC_OP: /* Uniprocessor, so instruction is just a store */ set_mem_word (R[BASE (inst)] + IOFFSET (inst), R[RT (inst)]); break; case Y_SDC2_OP: RAISE_EXCEPTION (ExcCode_CpU, {}); /* No Coprocessor 2 */ 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: { reg_word vs = R[RS (inst)], vt = R[RT (inst)]; reg_word diff = vs - vt; if (SIGN_BIT (vs) != SIGN_BIT (vt) && SIGN_BIT (vs) != SIGN_BIT (diff)) RAISE_EXCEPTION (ExcCode_Ov, 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_SWC2_OP: RAISE_EXCEPTION (ExcCode_CpU, {}); /* No Coprocessor 2 */ break; case Y_SWL_OP: { mem_addr addr = R[BASE (inst)] + IOFFSET (inst); mem_word data; reg_word reg = R[RT (inst)]; int byte = addr & 0x3; data = read_mem_word (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: { mem_addr addr = R[BASE (inst)] + IOFFSET (inst); mem_word data; reg_word reg = R[RT (inst)]; int byte = addr & 0x3; data = read_mem_word (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_SYNC_OP: break; /* Memory details not implemented */ case Y_SYSCALL_OP: if (!do_syscall ()) return (0); break; case Y_TEQ_OP: if (R[RS (inst)] == R[RT (inst)]) RAISE_EXCEPTION(ExcCode_Tr, {}); break; case Y_TEQI_OP: if (R[RS (inst)] == IMM (inst)) RAISE_EXCEPTION(ExcCode_Tr, {}); break; case Y_TGE_OP: if (R[RS (inst)] >= R[RT (inst)]) RAISE_EXCEPTION(ExcCode_Tr, {}); break; case Y_TGEI_OP: if (R[RS (inst)] >= IMM (inst)) RAISE_EXCEPTION(ExcCode_Tr, {}); break; case Y_TGEIU_OP: if ((u_reg_word)R[RS (inst)] >= (u_reg_word)IMM (inst)) RAISE_EXCEPTION(ExcCode_Tr, {}); break; case Y_TGEU_OP: if ((u_reg_word)R[RS (inst)] >= (u_reg_word)R[RT (inst)]) RAISE_EXCEPTION(ExcCode_Tr, {}); break; case Y_TLBP_OP: RAISE_EXCEPTION(ExcCode_RI, {}); /* TLB not implemented */ break; case Y_TLBR_OP: RAISE_EXCEPTION(ExcCode_RI, {}); /* TLB not implemented */ break; case Y_TLBWI_OP: RAISE_EXCEPTION(ExcCode_RI, {}); /* TLB not implemented */ break; case Y_TLBWR_OP: RAISE_EXCEPTION(ExcCode_RI, {}); /* TLB not implemented */ break; case Y_TLT_OP: if (R[RS (inst)] < R[RT (inst)]) RAISE_EXCEPTION(ExcCode_Tr, {}); break; case Y_TLTI_OP: if (R[RS (inst)] < IMM (inst)) RAISE_EXCEPTION(ExcCode_Tr, {}); break; case Y_TLTIU_OP: if ((u_reg_word)R[RS (inst)] < (u_reg_word)IMM (inst)) RAISE_EXCEPTION(ExcCode_Tr, {}); break; case Y_TLTU_OP: if ((u_reg_word)R[RS (inst)] < (u_reg_word)R[RT (inst)]) RAISE_EXCEPTION(ExcCode_Tr, {}); break; case Y_TNE_OP: if (R[RS (inst)] != R[RT (inst)]) RAISE_EXCEPTION(ExcCode_Tr, {}); break; case Y_TNEI_OP: if (R[RS (inst)] != IMM (inst)) RAISE_EXCEPTION(ExcCode_Tr, {}); 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: case Y_BC1FL_OP: case Y_BC1T_OP: case Y_BC1TL_OP: { int cc = CC (inst); int nd = ND (inst); /* 1 => nullify */ int tf = TF (inst); /* 0 => BC1F, 1 => BC1T */ BRANCH_INST ((FCCR & (1 << cc)) == (tf << cc), PC + IDISP (inst), nd); 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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -