diff options
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r-- | target-mips/translate.c | 213 |
1 files changed, 212 insertions, 1 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c index e1c8bd4c70..6880667109 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -1371,6 +1371,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) rn = "EntryLo0"; break; case 3: + /* also CONF */ gen_op_mfc0_entrylo1(); rn = "EntryLo1"; break; @@ -1386,6 +1387,10 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) gen_op_mfc0_wired(); rn = "Wired"; break; + case 7: +// gen_op_mfc0_info(); + rn = "Info"; + break; case 8: gen_op_mfc0_badvaddr(); rn = "BadVaddr"; @@ -1445,6 +1450,19 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) gen_op_mfc0_watchhi(); rn = "WatchHi"; break; + case 20: + /* 64 bit only */ +// gen_op_mfc0_xcontext(); + rn = "XContext"; + break; + case 21: +// gen_op_mfc0_framemask(); + rn = "Framemask"; + break; + case 22: +// gen_op_mfc0_diagnostic(); + rn = "'Diagnostic"; + break; case 23: gen_op_mfc0_debug(); rn = "Debug"; @@ -1453,6 +1471,18 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) gen_op_mfc0_depc(); rn = "DEPC"; break; + case 25: +// gen_op_mfc0_performance(); + rn = "Performance"; + break; + case 26: +// gen_op_mfc0_ecc(); + rn = "ECC"; + break; + case 27: +// gen_op_mfc0_cacheerr(); + rn = "CacheErr"; + break; case 28: switch (sel) { case 0: @@ -1468,6 +1498,10 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) goto die; } break; + case 29: +// gen_op_mfc0_taghi(); + rn = "TagHi"; + break; case 30: gen_op_mfc0_errorepc(); rn = "ErrorEPC"; @@ -1498,6 +1532,183 @@ die: generate_exception(ctx, EXCP_RI); } +static void gen_mtc0 (DisasContext *ctx, int reg, int sel) +{ + const unsigned char *rn; + uint32_t val, old; + + if (sel != 0 && reg != 16 && reg != 28) { + val = -1; + old = -1; + rn = "invalid"; + goto die; + } + switch (reg) { + case 0: + gen_op_mtc0_index(); + rn = "Index"; + break; + case 1: +// ignore or except? + rn = "Random"; + break; + case 2: + gen_op_mtc0_entrylo0(); + rn = "EntryLo0"; + break; + case 3: + gen_op_mtc0_entrylo1(); + rn = "EntryLo1"; + break; + case 4: + gen_op_mtc0_context(); + rn = "Context"; + break; + case 5: + gen_op_mtc0_pagemask(); + rn = "PageMask"; + break; + case 6: + gen_op_mtc0_wired(); + rn = "Wired"; + break; + case 7: +// ignore or except? + rn = "Info"; + break; + case 8: +// ignore or except? + rn = "BadVaddr"; + break; + case 9: + gen_op_mtc0_count(); + rn = "Count"; + break; + case 10: + gen_op_mtc0_entryhi(); + rn = "EntryHi"; + break; + case 11: + gen_op_mtc0_compare(); + rn = "Compare"; + break; + case 12: + gen_op_mtc0_status(); + rn = "Status"; + break; + case 13: + gen_op_mtc0_cause(); + rn = "Cause"; + break; + case 14: + gen_op_mtc0_epc(); + rn = "EPC"; + break; + case 15: +// ignore or except? + rn = "PRid"; + break; + case 16: + switch (sel) { + case 0: + gen_op_mtc0_config0(); + rn = "Config0"; + break; + default: + rn = "Invalid config selector"; + goto die; + } + break; + case 17: +// ignore or except? + rn = "LLaddr"; + break; + case 18: + gen_op_mtc0_watchlo(); + rn = "WatchLo"; + break; + case 19: + gen_op_mtc0_watchhi(); + rn = "WatchHi"; + break; + case 20: + /* 64 bit only */ +// gen_op_mtc0_xcontext(); + rn = "XContext"; + break; + case 21: +// gen_op_mtc0_framemask(); + rn = "Framemask"; + break; + case 22: +// ignore or except? + rn = "Diagnostic"; + break; + case 23: + gen_op_mtc0_debug(); + rn = "Debug"; + break; + case 24: + gen_op_mtc0_depc(); + rn = "DEPC"; + break; + case 25: +// ignore or except? + rn = "Performance"; + break; + case 26: +// ignore or except? + rn = "ECC"; + break; + case 27: +// ignore or except? + rn = "CacheErr"; + break; + case 28: + switch (sel) { + case 0: + gen_op_mtc0_taglo(); + rn = "TagLo"; + break; + default: + rn = "invalid sel"; + goto die; + } + break; + case 29: +// gen_op_mtc0_taghi(); + rn = "TagHi"; + break; + case 30: + gen_op_mtc0_errorepc(); + rn = "ErrorEPC"; + break; + case 31: + gen_op_mtc0_desave(); + rn = "DESAVE"; + break; + default: + rn = "unknown"; + goto die; + } +#if defined MIPS_DEBUG_DISAS + if (loglevel & CPU_LOG_TB_IN_ASM) { + fprintf(logfile, "%08x mtc0 %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 mtc0 %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"; @@ -1529,7 +1740,7 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd) save_cpu_state(ctx, 1); ctx->pc -= 4; GEN_LOAD_REG_TN(T0, rt); - gen_op_mtc0(rd, ctx->opcode & 0x7); + gen_mtc0(ctx, rd, ctx->opcode & 0x7); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; opn = "mtc0"; |