Loading target-mips/exec.h +2 −1 Original line number Diff line number Diff line Loading @@ -66,7 +66,8 @@ void do_maddu (void); void do_msub (void); void do_msubu (void); #endif void do_mfc0(int reg, int sel); void do_mfc0_random(void); void do_mfc0_count(void); void do_mtc0(int reg, int sel); void do_tlbwi (void); void do_tlbwr (void); Loading target-mips/op.c +160 −2 Original line number Diff line number Diff line Loading @@ -688,9 +688,167 @@ void op_jnz_T2 (void) } /* CP0 functions */ void op_mfc0 (void) void op_mfc0_index (void) { CALL_FROM_TB2(do_mfc0, PARAM1, PARAM2); T0 = env->CP0_index; RETURN(); } void op_mfc0_random (void) { CALL_FROM_TB0(do_mfc0_random); RETURN(); } void op_mfc0_entrylo0 (void) { T0 = env->CP0_EntryLo0; RETURN(); } void op_mfc0_entrylo1 (void) { T0 = env->CP0_EntryLo1; RETURN(); } void op_mfc0_context (void) { T0 = env->CP0_Context; RETURN(); } void op_mfc0_pagemask (void) { T0 = env->CP0_PageMask; RETURN(); } void op_mfc0_wired (void) { T0 = env->CP0_Wired; RETURN(); } void op_mfc0_badvaddr (void) { T0 = env->CP0_BadVAddr; RETURN(); } void op_mfc0_count (void) { CALL_FROM_TB0(do_mfc0_count); RETURN(); } void op_mfc0_entryhi (void) { T0 = env->CP0_EntryHi; RETURN(); } void op_mfc0_compare (void) { T0 = env->CP0_Compare; RETURN(); } void op_mfc0_status (void) { T0 = env->CP0_Status; if (env->hflags & MIPS_HFLAG_UM) T0 |= (1 << CP0St_UM); if (env->hflags & MIPS_HFLAG_ERL) T0 |= (1 << CP0St_ERL); if (env->hflags & MIPS_HFLAG_EXL) T0 |= (1 << CP0St_EXL); RETURN(); } void op_mfc0_cause (void) { T0 = env->CP0_Cause; RETURN(); } void op_mfc0_epc (void) { T0 = env->CP0_EPC; RETURN(); } void op_mfc0_prid (void) { T0 = env->CP0_PRid; RETURN(); } void op_mfc0_config0 (void) { T0 = env->CP0_Config0; RETURN(); } void op_mfc0_config1 (void) { T0 = env->CP0_Config1; RETURN(); } void op_mfc0_lladdr (void) { T0 = env->CP0_LLAddr >> 4; RETURN(); } void op_mfc0_watchlo (void) { T0 = env->CP0_WatchLo; RETURN(); } void op_mfc0_watchhi (void) { T0 = env->CP0_WatchHi; RETURN(); } void op_mfc0_debug (void) { T0 = env->CP0_Debug; if (env->hflags & MIPS_HFLAG_DM) T0 |= 1 << CP0DB_DM; RETURN(); } void op_mfc0_depc (void) { T0 = env->CP0_DEPC; RETURN(); } void op_mfc0_taglo (void) { T0 = env->CP0_TagLo; RETURN(); } void op_mfc0_datalo (void) { T0 = env->CP0_DataLo; RETURN(); } void op_mfc0_errorepc (void) { T0 = env->CP0_ErrorEPC; RETURN(); } void op_mfc0_desave (void) { T0 = env->CP0_DESAVE; RETURN(); } Loading target-mips/op_helper.c +15 −143 Original line number Diff line number Diff line Loading @@ -131,10 +131,16 @@ void do_msubu (void) #endif #if defined(CONFIG_USER_ONLY) void do_mfc0 (int reg, int sel) void do_mfc0_random (void) { cpu_abort(env, "mfc0 reg=%d sel=%d\n", reg, sel); cpu_abort(env, "mfc0 random\n"); } void do_mfc0_count (void) { cpu_abort(env, "mfc0 count\n"); } void do_mtc0 (int reg, int sel) { cpu_abort(env, "mtc0 reg=%d sel=%d\n", reg, sel); Loading @@ -159,152 +165,18 @@ void do_tlbr (void) { cpu_abort(env, "tlbr\n"); } #else /* CP0 helpers */ void do_mfc0 (int reg, int sel) void do_mfc0_random (void) { const unsigned char *rn; if (sel != 0 && reg != 16 && reg != 28) { rn = "invalid"; goto print; } switch (reg) { case 0: T0 = env->CP0_index; rn = "Index"; break; case 1: T0 = cpu_mips_get_random(env); rn = "Random"; break; case 2: T0 = env->CP0_EntryLo0; rn = "EntryLo0"; break; case 3: T0 = env->CP0_EntryLo1; rn = "EntryLo1"; break; case 4: T0 = env->CP0_Context; rn = "Context"; break; case 5: T0 = env->CP0_PageMask; rn = "PageMask"; break; case 6: T0 = env->CP0_Wired; rn = "Wired"; break; case 8: T0 = env->CP0_BadVAddr; rn = "BadVaddr"; break; case 9: T0 = cpu_mips_get_count(env); rn = "Count"; break; case 10: T0 = env->CP0_EntryHi; rn = "EntryHi"; break; case 11: T0 = env->CP0_Compare; rn = "Compare"; break; case 12: T0 = env->CP0_Status; if (env->hflags & MIPS_HFLAG_UM) T0 |= (1 << CP0St_UM); rn = "Status"; break; case 13: T0 = env->CP0_Cause; rn = "Cause"; break; case 14: T0 = env->CP0_EPC; rn = "EPC"; break; case 15: T0 = env->CP0_PRid; rn = "PRid"; break; case 16: switch (sel) { case 0: T0 = env->CP0_Config0; rn = "Config"; break; case 1: T0 = env->CP0_Config1; rn = "Config1"; break; default: rn = "Unknown config register"; break; } break; case 17: T0 = env->CP0_LLAddr >> 4; rn = "LLAddr"; break; case 18: T0 = env->CP0_WatchLo; rn = "WatchLo"; break; case 19: T0 = env->CP0_WatchHi; rn = "WatchHi"; break; case 23: T0 = env->CP0_Debug; if (env->hflags & MIPS_HFLAG_DM) T0 |= 1 << CP0DB_DM; rn = "Debug"; break; case 24: T0 = env->CP0_DEPC; rn = "DEPC"; break; case 28: switch (sel) { case 0: T0 = env->CP0_TagLo; rn = "TagLo"; break; case 1: T0 = env->CP0_DataLo; rn = "DataLo"; break; default: rn = "unknown sel"; break; } break; case 30: T0 = env->CP0_ErrorEPC; rn = "ErrorEPC"; break; case 31: T0 = env->CP0_DESAVE; rn = "DESAVE"; break; default: rn = "unknown"; break; } print: #if defined MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "%08x mfc0 %s => %08x (%d %d)\n", env->PC, rn, T0, reg, sel); } #endif return; void do_mfc0_count (void) { T0 = cpu_mips_get_count(env); } void do_mtc0 (int reg, int sel) Loading target-mips/translate.c +150 −1 Original line number Diff line number Diff line Loading @@ -1349,6 +1349,155 @@ static void gen_compute_branch (DisasContext *ctx, uint16_t opc, } /* CP0 (MMU and control) */ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) { const unsigned char *rn; if (sel != 0 && reg != 16 && reg != 28) { rn = "invalid"; goto die; } switch (reg) { case 0: gen_op_mfc0_index(); rn = "Index"; break; case 1: gen_op_mfc0_random(); rn = "Random"; break; case 2: gen_op_mfc0_entrylo0(); rn = "EntryLo0"; break; case 3: gen_op_mfc0_entrylo1(); rn = "EntryLo1"; break; case 4: gen_op_mfc0_context(); rn = "Context"; break; case 5: gen_op_mfc0_pagemask(); rn = "PageMask"; break; case 6: gen_op_mfc0_wired(); rn = "Wired"; break; case 8: gen_op_mfc0_badvaddr(); rn = "BadVaddr"; break; case 9: gen_op_mfc0_count(); rn = "Count"; break; case 10: gen_op_mfc0_entryhi(); rn = "EntryHi"; break; case 11: gen_op_mfc0_compare(); rn = "Compare"; break; case 12: gen_op_mfc0_status(); rn = "Status"; break; case 13: gen_op_mfc0_cause(); rn = "Cause"; break; case 14: gen_op_mfc0_epc(); rn = "EPC"; break; case 15: gen_op_mfc0_prid(); rn = "PRid"; break; case 16: switch (sel) { case 0: gen_op_mfc0_config0(); rn = "Config"; break; case 1: gen_op_mfc0_config1(); rn = "Config1"; break; default: rn = "Unknown config register"; goto die; } break; case 17: gen_op_mfc0_lladdr(); rn = "LLAddr"; break; case 18: gen_op_mfc0_watchlo(); rn = "WatchLo"; break; case 19: gen_op_mfc0_watchhi(); rn = "WatchHi"; break; case 23: gen_op_mfc0_debug(); rn = "Debug"; break; case 24: gen_op_mfc0_depc(); rn = "DEPC"; break; case 28: switch (sel) { case 0: gen_op_mfc0_taglo(); rn = "TagLo"; break; case 1: gen_op_mfc0_datalo(); rn = "DataLo"; break; default: rn = "unknown sel"; goto die; } break; case 30: gen_op_mfc0_errorepc(); rn = "ErrorEPC"; break; case 31: gen_op_mfc0_desave(); rn = "DESAVE"; break; default: rn = "unknown"; goto die; } #if defined MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "%08x mfc0 %s => %08x (%d %d)\n", env->PC, rn, T0, reg, sel); } #endif return; die: #if defined MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "%08x mfc0 %s => %08x (%d %d)\n", env->PC, rn, T0, reg, sel); } #endif generate_exception(ctx, EXCP_RI); } static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd) { const unsigned char *opn = "unk"; Loading @@ -1370,7 +1519,7 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd) /* Treat as NOP */ return; } gen_op_mfc0(rd, ctx->opcode & 0x7); gen_mfc0(ctx, rd, ctx->opcode & 0x7); gen_op_store_T0_gpr(rt); opn = "mfc0"; break; Loading Loading
target-mips/exec.h +2 −1 Original line number Diff line number Diff line Loading @@ -66,7 +66,8 @@ void do_maddu (void); void do_msub (void); void do_msubu (void); #endif void do_mfc0(int reg, int sel); void do_mfc0_random(void); void do_mfc0_count(void); void do_mtc0(int reg, int sel); void do_tlbwi (void); void do_tlbwr (void); Loading
target-mips/op.c +160 −2 Original line number Diff line number Diff line Loading @@ -688,9 +688,167 @@ void op_jnz_T2 (void) } /* CP0 functions */ void op_mfc0 (void) void op_mfc0_index (void) { CALL_FROM_TB2(do_mfc0, PARAM1, PARAM2); T0 = env->CP0_index; RETURN(); } void op_mfc0_random (void) { CALL_FROM_TB0(do_mfc0_random); RETURN(); } void op_mfc0_entrylo0 (void) { T0 = env->CP0_EntryLo0; RETURN(); } void op_mfc0_entrylo1 (void) { T0 = env->CP0_EntryLo1; RETURN(); } void op_mfc0_context (void) { T0 = env->CP0_Context; RETURN(); } void op_mfc0_pagemask (void) { T0 = env->CP0_PageMask; RETURN(); } void op_mfc0_wired (void) { T0 = env->CP0_Wired; RETURN(); } void op_mfc0_badvaddr (void) { T0 = env->CP0_BadVAddr; RETURN(); } void op_mfc0_count (void) { CALL_FROM_TB0(do_mfc0_count); RETURN(); } void op_mfc0_entryhi (void) { T0 = env->CP0_EntryHi; RETURN(); } void op_mfc0_compare (void) { T0 = env->CP0_Compare; RETURN(); } void op_mfc0_status (void) { T0 = env->CP0_Status; if (env->hflags & MIPS_HFLAG_UM) T0 |= (1 << CP0St_UM); if (env->hflags & MIPS_HFLAG_ERL) T0 |= (1 << CP0St_ERL); if (env->hflags & MIPS_HFLAG_EXL) T0 |= (1 << CP0St_EXL); RETURN(); } void op_mfc0_cause (void) { T0 = env->CP0_Cause; RETURN(); } void op_mfc0_epc (void) { T0 = env->CP0_EPC; RETURN(); } void op_mfc0_prid (void) { T0 = env->CP0_PRid; RETURN(); } void op_mfc0_config0 (void) { T0 = env->CP0_Config0; RETURN(); } void op_mfc0_config1 (void) { T0 = env->CP0_Config1; RETURN(); } void op_mfc0_lladdr (void) { T0 = env->CP0_LLAddr >> 4; RETURN(); } void op_mfc0_watchlo (void) { T0 = env->CP0_WatchLo; RETURN(); } void op_mfc0_watchhi (void) { T0 = env->CP0_WatchHi; RETURN(); } void op_mfc0_debug (void) { T0 = env->CP0_Debug; if (env->hflags & MIPS_HFLAG_DM) T0 |= 1 << CP0DB_DM; RETURN(); } void op_mfc0_depc (void) { T0 = env->CP0_DEPC; RETURN(); } void op_mfc0_taglo (void) { T0 = env->CP0_TagLo; RETURN(); } void op_mfc0_datalo (void) { T0 = env->CP0_DataLo; RETURN(); } void op_mfc0_errorepc (void) { T0 = env->CP0_ErrorEPC; RETURN(); } void op_mfc0_desave (void) { T0 = env->CP0_DESAVE; RETURN(); } Loading
target-mips/op_helper.c +15 −143 Original line number Diff line number Diff line Loading @@ -131,10 +131,16 @@ void do_msubu (void) #endif #if defined(CONFIG_USER_ONLY) void do_mfc0 (int reg, int sel) void do_mfc0_random (void) { cpu_abort(env, "mfc0 reg=%d sel=%d\n", reg, sel); cpu_abort(env, "mfc0 random\n"); } void do_mfc0_count (void) { cpu_abort(env, "mfc0 count\n"); } void do_mtc0 (int reg, int sel) { cpu_abort(env, "mtc0 reg=%d sel=%d\n", reg, sel); Loading @@ -159,152 +165,18 @@ void do_tlbr (void) { cpu_abort(env, "tlbr\n"); } #else /* CP0 helpers */ void do_mfc0 (int reg, int sel) void do_mfc0_random (void) { const unsigned char *rn; if (sel != 0 && reg != 16 && reg != 28) { rn = "invalid"; goto print; } switch (reg) { case 0: T0 = env->CP0_index; rn = "Index"; break; case 1: T0 = cpu_mips_get_random(env); rn = "Random"; break; case 2: T0 = env->CP0_EntryLo0; rn = "EntryLo0"; break; case 3: T0 = env->CP0_EntryLo1; rn = "EntryLo1"; break; case 4: T0 = env->CP0_Context; rn = "Context"; break; case 5: T0 = env->CP0_PageMask; rn = "PageMask"; break; case 6: T0 = env->CP0_Wired; rn = "Wired"; break; case 8: T0 = env->CP0_BadVAddr; rn = "BadVaddr"; break; case 9: T0 = cpu_mips_get_count(env); rn = "Count"; break; case 10: T0 = env->CP0_EntryHi; rn = "EntryHi"; break; case 11: T0 = env->CP0_Compare; rn = "Compare"; break; case 12: T0 = env->CP0_Status; if (env->hflags & MIPS_HFLAG_UM) T0 |= (1 << CP0St_UM); rn = "Status"; break; case 13: T0 = env->CP0_Cause; rn = "Cause"; break; case 14: T0 = env->CP0_EPC; rn = "EPC"; break; case 15: T0 = env->CP0_PRid; rn = "PRid"; break; case 16: switch (sel) { case 0: T0 = env->CP0_Config0; rn = "Config"; break; case 1: T0 = env->CP0_Config1; rn = "Config1"; break; default: rn = "Unknown config register"; break; } break; case 17: T0 = env->CP0_LLAddr >> 4; rn = "LLAddr"; break; case 18: T0 = env->CP0_WatchLo; rn = "WatchLo"; break; case 19: T0 = env->CP0_WatchHi; rn = "WatchHi"; break; case 23: T0 = env->CP0_Debug; if (env->hflags & MIPS_HFLAG_DM) T0 |= 1 << CP0DB_DM; rn = "Debug"; break; case 24: T0 = env->CP0_DEPC; rn = "DEPC"; break; case 28: switch (sel) { case 0: T0 = env->CP0_TagLo; rn = "TagLo"; break; case 1: T0 = env->CP0_DataLo; rn = "DataLo"; break; default: rn = "unknown sel"; break; } break; case 30: T0 = env->CP0_ErrorEPC; rn = "ErrorEPC"; break; case 31: T0 = env->CP0_DESAVE; rn = "DESAVE"; break; default: rn = "unknown"; break; } print: #if defined MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "%08x mfc0 %s => %08x (%d %d)\n", env->PC, rn, T0, reg, sel); } #endif return; void do_mfc0_count (void) { T0 = cpu_mips_get_count(env); } void do_mtc0 (int reg, int sel) Loading
target-mips/translate.c +150 −1 Original line number Diff line number Diff line Loading @@ -1349,6 +1349,155 @@ static void gen_compute_branch (DisasContext *ctx, uint16_t opc, } /* CP0 (MMU and control) */ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) { const unsigned char *rn; if (sel != 0 && reg != 16 && reg != 28) { rn = "invalid"; goto die; } switch (reg) { case 0: gen_op_mfc0_index(); rn = "Index"; break; case 1: gen_op_mfc0_random(); rn = "Random"; break; case 2: gen_op_mfc0_entrylo0(); rn = "EntryLo0"; break; case 3: gen_op_mfc0_entrylo1(); rn = "EntryLo1"; break; case 4: gen_op_mfc0_context(); rn = "Context"; break; case 5: gen_op_mfc0_pagemask(); rn = "PageMask"; break; case 6: gen_op_mfc0_wired(); rn = "Wired"; break; case 8: gen_op_mfc0_badvaddr(); rn = "BadVaddr"; break; case 9: gen_op_mfc0_count(); rn = "Count"; break; case 10: gen_op_mfc0_entryhi(); rn = "EntryHi"; break; case 11: gen_op_mfc0_compare(); rn = "Compare"; break; case 12: gen_op_mfc0_status(); rn = "Status"; break; case 13: gen_op_mfc0_cause(); rn = "Cause"; break; case 14: gen_op_mfc0_epc(); rn = "EPC"; break; case 15: gen_op_mfc0_prid(); rn = "PRid"; break; case 16: switch (sel) { case 0: gen_op_mfc0_config0(); rn = "Config"; break; case 1: gen_op_mfc0_config1(); rn = "Config1"; break; default: rn = "Unknown config register"; goto die; } break; case 17: gen_op_mfc0_lladdr(); rn = "LLAddr"; break; case 18: gen_op_mfc0_watchlo(); rn = "WatchLo"; break; case 19: gen_op_mfc0_watchhi(); rn = "WatchHi"; break; case 23: gen_op_mfc0_debug(); rn = "Debug"; break; case 24: gen_op_mfc0_depc(); rn = "DEPC"; break; case 28: switch (sel) { case 0: gen_op_mfc0_taglo(); rn = "TagLo"; break; case 1: gen_op_mfc0_datalo(); rn = "DataLo"; break; default: rn = "unknown sel"; goto die; } break; case 30: gen_op_mfc0_errorepc(); rn = "ErrorEPC"; break; case 31: gen_op_mfc0_desave(); rn = "DESAVE"; break; default: rn = "unknown"; goto die; } #if defined MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "%08x mfc0 %s => %08x (%d %d)\n", env->PC, rn, T0, reg, sel); } #endif return; die: #if defined MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "%08x mfc0 %s => %08x (%d %d)\n", env->PC, rn, T0, reg, sel); } #endif generate_exception(ctx, EXCP_RI); } static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd) { const unsigned char *opn = "unk"; Loading @@ -1370,7 +1519,7 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd) /* Treat as NOP */ return; } gen_op_mfc0(rd, ctx->opcode & 0x7); gen_mfc0(ctx, rd, ctx->opcode & 0x7); gen_op_store_T0_gpr(rt); opn = "mfc0"; break; Loading