📄 run.c
字号:
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 + -