📄 op.c
字号:
CALL_FROM_TB1(compute_hflags, env); if (loglevel & CPU_LOG_EXEC) CALL_FROM_TB2(do_mtc0_status_debug, old, val); CALL_FROM_TB1(cpu_mips_update_irq, env); FORCE_RET();}void op_mttc0_status(void){ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); uint32_t tcstatus = env->CP0_TCStatus[other_tc]; env->CP0_Status = T0 & ~0xf1000018; tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0)); tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX)); tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU)); env->CP0_TCStatus[other_tc] = tcstatus; FORCE_RET();}void op_mtc0_intctl (void){ /* vectored interrupts not implemented, no performance counters. */ env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0); FORCE_RET();}void op_mtc0_srsctl (void){ uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS); env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask); FORCE_RET();}void op_mtc0_srsmap (void){ env->CP0_SRSMap = T0; FORCE_RET();}void op_mtc0_cause (void){ uint32_t mask = 0x00C00300; uint32_t old = env->CP0_Cause; if (env->insn_flags & ISA_MIPS32R2) mask |= 1 << CP0Ca_DC; env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask); if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) { if (env->CP0_Cause & (1 << CP0Ca_DC)) CALL_FROM_TB1(cpu_mips_stop_count, env); else CALL_FROM_TB1(cpu_mips_start_count, env); } /* Handle the software interrupt as an hardware one, as they are very similar */ if (T0 & CP0Ca_IP_mask) { CALL_FROM_TB1(cpu_mips_update_irq, env); } FORCE_RET();}void op_mtc0_epc (void){ env->CP0_EPC = T0; FORCE_RET();}void op_mtc0_ebase (void){ /* vectored interrupts not implemented */ /* Multi-CPU not implemented */ env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000); FORCE_RET();}void op_mtc0_config0 (void){ env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007); FORCE_RET();}void op_mtc0_config2 (void){ /* tertiary/secondary caches not implemented */ env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF); FORCE_RET();}void op_mtc0_watchlo (void){ /* Watch exceptions for instructions, data loads, data stores not implemented. */ env->CP0_WatchLo[PARAM1] = (T0 & ~0x7); FORCE_RET();}void op_mtc0_watchhi (void){ env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8); env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7); FORCE_RET();}void op_mtc0_xcontext (void){ target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1; env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask); FORCE_RET();}void op_mtc0_framemask (void){ env->CP0_Framemask = T0; /* XXX */ FORCE_RET();}void op_mtc0_debug (void){ env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120); if (T0 & (1 << CP0DB_DM)) env->hflags |= MIPS_HFLAG_DM; else env->hflags &= ~MIPS_HFLAG_DM; FORCE_RET();}void op_mttc0_debug(void){ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); /* XXX: Might be wrong, check with EJTAG spec. */ env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)); env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); FORCE_RET();}void op_mtc0_depc (void){ env->CP0_DEPC = T0; FORCE_RET();}void op_mtc0_performance0 (void){ env->CP0_Performance0 = T0 & 0x000007ff; FORCE_RET();}void op_mtc0_taglo (void){ env->CP0_TagLo = T0 & 0xFFFFFCF6; FORCE_RET();}void op_mtc0_datalo (void){ env->CP0_DataLo = T0; /* XXX */ FORCE_RET();}void op_mtc0_taghi (void){ env->CP0_TagHi = T0; /* XXX */ FORCE_RET();}void op_mtc0_datahi (void){ env->CP0_DataHi = T0; /* XXX */ FORCE_RET();}void op_mtc0_errorepc (void){ env->CP0_ErrorEPC = T0; FORCE_RET();}void op_mtc0_desave (void){ env->CP0_DESAVE = T0; FORCE_RET();}#if defined(TARGET_MIPS64)void op_dmfc0_yqmask (void){ T0 = env->CP0_YQMask; FORCE_RET();}void op_dmfc0_vpeschedule (void){ T0 = env->CP0_VPESchedule; FORCE_RET();}void op_dmfc0_vpeschefback (void){ T0 = env->CP0_VPEScheFBack; FORCE_RET();}void op_dmfc0_entrylo0 (void){ T0 = env->CP0_EntryLo0; FORCE_RET();}void op_dmfc0_tcrestart (void){ T0 = env->PC[env->current_tc]; FORCE_RET();}void op_dmfc0_tchalt (void){ T0 = env->CP0_TCHalt[env->current_tc]; FORCE_RET();}void op_dmfc0_tccontext (void){ T0 = env->CP0_TCContext[env->current_tc]; FORCE_RET();}void op_dmfc0_tcschedule (void){ T0 = env->CP0_TCSchedule[env->current_tc]; FORCE_RET();}void op_dmfc0_tcschefback (void){ T0 = env->CP0_TCScheFBack[env->current_tc]; FORCE_RET();}void op_dmfc0_entrylo1 (void){ T0 = env->CP0_EntryLo1; FORCE_RET();}void op_dmfc0_context (void){ T0 = env->CP0_Context; FORCE_RET();}void op_dmfc0_badvaddr (void){ T0 = env->CP0_BadVAddr; FORCE_RET();}void op_dmfc0_entryhi (void){ T0 = env->CP0_EntryHi; FORCE_RET();}void op_dmfc0_epc (void){ T0 = env->CP0_EPC; FORCE_RET();}void op_dmfc0_lladdr (void){ T0 = env->CP0_LLAddr >> 4; FORCE_RET();}void op_dmfc0_watchlo (void){ T0 = env->CP0_WatchLo[PARAM1]; FORCE_RET();}void op_dmfc0_xcontext (void){ T0 = env->CP0_XContext; FORCE_RET();}void op_dmfc0_depc (void){ T0 = env->CP0_DEPC; FORCE_RET();}void op_dmfc0_errorepc (void){ T0 = env->CP0_ErrorEPC; FORCE_RET();}#endif /* TARGET_MIPS64 *//* MIPS MT functions */void op_mftgpr(void){ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); T0 = env->gpr[PARAM1][other_tc]; FORCE_RET();}void op_mftlo(void){ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); T0 = env->LO[PARAM1][other_tc]; FORCE_RET();}void op_mfthi(void){ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); T0 = env->HI[PARAM1][other_tc]; FORCE_RET();}void op_mftacx(void){ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); T0 = env->ACX[PARAM1][other_tc]; FORCE_RET();}void op_mftdsp(void){ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); T0 = env->DSPControl[other_tc]; FORCE_RET();}void op_mttgpr(void){ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); T0 = env->gpr[PARAM1][other_tc]; FORCE_RET();}void op_mttlo(void){ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); T0 = env->LO[PARAM1][other_tc]; FORCE_RET();}void op_mtthi(void){ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); T0 = env->HI[PARAM1][other_tc]; FORCE_RET();}void op_mttacx(void){ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); T0 = env->ACX[PARAM1][other_tc]; FORCE_RET();}void op_mttdsp(void){ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); T0 = env->DSPControl[other_tc]; FORCE_RET();}void op_dmt(void){ // TODO T0 = 0; // rt = T0 FORCE_RET();}void op_emt(void){ // TODO T0 = 0; // rt = T0 FORCE_RET();}void op_dvpe(void){ // TODO T0 = 0; // rt = T0 FORCE_RET();}void op_evpe(void){ // TODO T0 = 0; // rt = T0 FORCE_RET();}void op_fork(void){ // T0 = rt, T1 = rs T0 = 0; // TODO: store to TC register FORCE_RET();}void op_yield(void){ if (T0 < 0) { /* No scheduling policy implemented. */ if (T0 != -2) { if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) && env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) { env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT); env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT; CALL_FROM_TB1(do_raise_exception, EXCP_THREAD); } } } else if (T0 == 0) { if (0 /* TODO: TC underflow */) { env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT); CALL_FROM_TB1(do_raise_exception, EXCP_THREAD); } else { // TODO: Deallocate TC } } else if (T0 > 0) { /* Yield qualifier inputs not implemented. */ env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT); env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT; CALL_FROM_TB1(do_raise_exception, EXCP_THREAD); } T0 = env->CP0_YQMask; FORCE_RET();}/* CP1 functions */#if 0# define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)#else# define DEBUG_FPU_STATE() do { } while(0)#endifvoid op_cfc1 (void){ CALL_FROM_TB1(do_cfc1, PARAM1); DEBUG_FPU_STATE(); FORCE_RET();}void op_ctc1 (void){ CALL_FROM_TB1(do_ctc1, PARAM1); DEBUG_FPU_STATE(); FORCE_RET();}void op_mfc1 (void){ T0 = (int32_t)WT0; DEBUG_FPU_STATE(); FORCE_RET();}void op_mtc1 (void){ WT0 = T0; DEBUG_FPU_STATE(); FORCE_RET();}void op_dmfc1 (void){ T0 = DT0; DEBUG_FPU_STATE(); FORCE_RET();}void op_dmtc1 (void){ DT0 = T0; DEBUG_FPU_STATE(); FORCE_RET();}void op_mfhc1 (void){ T0 = (int32_t)WTH0; DEBUG_FPU_STATE(); FORCE_RET();}void op_mthc1 (void){ WTH0 = T0; DEBUG_FPU_STATE(); FORCE_RET();}/* Float support. Single precition routines have a "s" suffix, double precision a "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps", paired single lowwer "pl", paired single upper "pu". */#define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)FLOAT_OP(cvtd, s){ CALL_FROM_TB0(do_float_cvtd_s); DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(cvtd, w){ CALL_FROM_TB0(do_float_cvtd_w); DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(cvtd, l){ CALL_FROM_TB0(do_float_cvtd_l); DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(cvtl, d){ CALL_FROM_TB0(do_float_cvtl_d); DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(cvtl, s){ CALL_FROM_TB0(do_float_cvtl_s); DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(cvtps, s){ WT2 = WT0; WTH2 = WT1; DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(cvtps, pw){ CALL_FROM_TB0(do_float_cvtps_pw); DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(cvtpw, ps){ CALL_FROM_TB0(do_float_cvtpw_ps); DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(cvts, d){ CALL_FROM_TB0(do_float_cvts_d); DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(cvts, w){ CALL_FROM_TB0(do_float_cvts_w); DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(cvts, l){ CALL_FROM_TB0(do_float_cvts_l); DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(cvts, pl){ CALL_FROM_TB0(do_float_cvts_pl); DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(cvts, pu){ CALL_FROM_TB0(do_float_cvts_pu); DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(cvtw, s){ CALL_FROM_TB0(do_float_cvtw_s); DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(cvtw, d){ CALL_FROM_TB0(do_float_cvtw_d); DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(pll, ps){ DT2 = ((uint64_t)WT0 << 32) | WT1; DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(plu, ps){ DT2 = ((uint64_t)WT0 << 32) | WTH1; DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(pul, ps){ DT2 = ((uint64_t)WTH0 << 32) | WT1; DEBUG_FPU_STATE(); FORCE_RET();}FLOAT_OP(puu, ps){ DT2 = ((uint64_t)WTH0 << 32) | WTH1; DEBUG_FPU_STATE(); FORCE_RET();}#define FLOAT_ROUNDOP(op, ttype, stype) \FLOAT_OP(op ## ttype, stype) \{ \ CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \ DEBUG_FPU_STATE(); \ FORCE_RET(); \}FLOAT_ROUNDOP(round, l, d)FLOAT_ROUNDOP(round, l, s)FLOAT_ROUNDOP(round, w, d)FLOAT_ROUNDOP(round, w, s)FLOAT_ROUNDOP(trunc, l, d)FLOAT_ROUNDOP(trunc, l, s)FLOAT_ROUNDOP(trunc, w, d)FLOAT_ROUNDOP(trunc, w, s)FLOAT_ROUNDOP(ceil, l, d)FLOAT_ROUNDOP(ceil, l, s)FLOAT_ROUNDOP(ceil, w, d)FLOAT_ROUNDOP(ceil, w, s)FLOAT_ROUNDOP(floor, l, d)FLOAT_ROUNDOP(floor, l, s)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -