From: Yongbok Kim <yongbok.kim@imgtec.com>
To: Leon Alrae <leon.alrae@imgtec.com>, qemu-devel@nongnu.org
Cc: aurelien@aurel32.net
Subject: Re: [Qemu-devel] [PATCH 5/6] target-mips: correctly handle access to unimplemented CP0 register
Date: Mon, 20 Oct 2014 11:49:19 +0100 [thread overview]
Message-ID: <5444E8AF.2080305@imgtec.com> (raw)
In-Reply-To: <1405354795-25884-6-git-send-email-leon.alrae@imgtec.com>
On 14/07/2014 17:19, Leon Alrae wrote:
> Release 6 limits the number of cases where software can cause UNDEFINED or
> UNPREDICTABLE behaviour. In this case, when accessing reserved / unimplemented
> CP0 register, writes are ignored and reads return 0.
>
> In pre-R6 the behaviour is not specified, but generating RI exception is not
> what the real HW does.
>
> Additionally, remove CP0 Random register as it became reserved in Release 6.
>
> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
> ---
> target-mips/translate.c | 546 +++++++++++++++++++++++------------------------
> 1 files changed, 264 insertions(+), 282 deletions(-)
>
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 4ed81fe..cd20f35 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -4627,6 +4627,13 @@ static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
> }
> }
>
> +#define CP0_CHECK(c) \
> + do { \
> + if (!(c)) { \
> + goto cp0_unimplemented; \
> + } \
> + } while (0)
> +
> static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> {
> const char *rn = "invalid";
> @@ -4642,67 +4649,68 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Index";
> break;
> case 1:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mfc0_mvpcontrol(arg, cpu_env);
> rn = "MVPControl";
> break;
> case 2:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mfc0_mvpconf0(arg, cpu_env);
> rn = "MVPConf0";
> break;
> case 3:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mfc0_mvpconf1(arg, cpu_env);
> rn = "MVPConf1";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 1:
> switch (sel) {
> case 0:
> + CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
> gen_helper_mfc0_random(arg, cpu_env);
> rn = "Random";
> break;
> case 1:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
> rn = "VPEControl";
> break;
> case 2:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
> rn = "VPEConf0";
> break;
> case 3:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
> rn = "VPEConf1";
> break;
> case 4:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
> rn = "YQMask";
> break;
> case 5:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
> rn = "VPESchedule";
> break;
> case 6:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
> rn = "VPEScheFBack";
> break;
> case 7:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
> rn = "VPEOpt";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 2:
> @@ -4722,42 +4730,42 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EntryLo0";
> break;
> case 1:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mfc0_tcstatus(arg, cpu_env);
> rn = "TCStatus";
> break;
> case 2:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mfc0_tcbind(arg, cpu_env);
> rn = "TCBind";
> break;
> case 3:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mfc0_tcrestart(arg, cpu_env);
> rn = "TCRestart";
> break;
> case 4:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mfc0_tchalt(arg, cpu_env);
> rn = "TCHalt";
> break;
> case 5:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mfc0_tccontext(arg, cpu_env);
> rn = "TCContext";
> break;
> case 6:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mfc0_tcschedule(arg, cpu_env);
> rn = "TCSchedule";
> break;
> case 7:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mfc0_tcschefback(arg, cpu_env);
> rn = "TCScheFBack";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 3:
> @@ -4777,7 +4785,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EntryLo1";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 4:
> @@ -4790,20 +4798,16 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> case 1:
> // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
> rn = "ContextConfig";
> - goto die;
> + goto cp0_unimplemented;
> // break;
> case 2:
> - if (ctx->ulri) {
> - tcg_gen_ld32s_tl(arg, cpu_env,
> - offsetof(CPUMIPSState,
> - active_tc.CP0_UserLocal));
> - rn = "UserLocal";
> - } else {
> - tcg_gen_movi_tl(arg, 0);
> - }
> + CP0_CHECK(ctx->ulri);
> + tcg_gen_ld32s_tl(arg, cpu_env,
> + offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
> + rn = "UserLocal";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 5:
> @@ -4818,7 +4822,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "PageGrain";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 6:
> @@ -4853,7 +4857,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "SRSConf4";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 7:
> @@ -4864,7 +4868,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "HWREna";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 8:
> @@ -4875,25 +4879,19 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "BadVAddr";
> break;
> case 1:
> - if (ctx->bi) {
> - gen_mfc0_load32(arg, offsetof(CPUMIPSState,
> - active_tc.CP0_BadInstr));
> - rn = "BadInstr";
> - } else {
> - gen_mfc0_unimplemented(ctx, arg);
> - }
> + CP0_CHECK(ctx->bi);
> + gen_mfc0_load32(arg, offsetof(CPUMIPSState,
> + active_tc.CP0_BadInstr));
> + rn = "BadInstr";
> break;
> case 2:
> - if (ctx->bp) {
> - gen_mfc0_load32(arg, offsetof(CPUMIPSState,
> - active_tc.CP0_BadInstrP));
> - rn = "BadInstrP";
> - } else {
> - gen_mfc0_unimplemented(ctx, arg);
> - }
> + CP0_CHECK(ctx->bp);
> + gen_mfc0_load32(arg, offsetof(CPUMIPSState,
> + active_tc.CP0_BadInstrP));
> + rn = "BadInstrP";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 9:
> @@ -4913,7 +4911,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> break;
> /* 6,7 are implementation dependent */
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 10:
> @@ -4924,7 +4922,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EntryHi";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 11:
> @@ -4935,7 +4933,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> break;
> /* 6,7 are implementation dependent */
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 12:
> @@ -4960,7 +4958,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "SRSMap";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 13:
> @@ -4970,7 +4968,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Cause";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 14:
> @@ -4981,7 +4979,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EPC";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 15:
> @@ -4996,7 +4994,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EBase";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 16:
> @@ -5035,7 +5033,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Config7";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 17:
> @@ -5045,7 +5043,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "LLAddr";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 18:
> @@ -5055,7 +5053,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "WatchLo";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 19:
> @@ -5065,7 +5063,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "WatchHi";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 20:
> @@ -5079,18 +5077,19 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> break;
> #endif
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 21:
> /* Officially reserved, but sel 0 is used for R1x000 framemask */
> + CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
> switch (sel) {
> case 0:
> gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
> rn = "Framemask";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 22:
> @@ -5120,7 +5119,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "TraceBPC";
> // break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 24:
> @@ -5132,7 +5131,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "DEPC";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 25:
> @@ -5170,7 +5169,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Performance7";
> // break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 26:
> @@ -5184,7 +5183,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "CacheErr";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 28:
> @@ -5204,7 +5203,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "DataLo";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 29:
> @@ -5224,7 +5223,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "DataHi";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 30:
> @@ -5235,7 +5234,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "ErrorEPC";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 31:
> @@ -5246,29 +5245,26 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "DESAVE";
> break;
> case 2 ... 7:
> - if (ctx->kscrexist & (1 << sel)) {
> - tcg_gen_ld_tl(arg, cpu_env,
> - offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
> - tcg_gen_ext32s_tl(arg, arg);
> - rn = "KScratch";
> - } else {
> - gen_mfc0_unimplemented(ctx, arg);
> - }
> + CP0_CHECK(ctx->kscrexist & (1 << sel));
> + tcg_gen_ld_tl(arg, cpu_env,
> + offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
> + tcg_gen_ext32s_tl(arg, arg);
> + rn = "KScratch";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> (void)rn; /* avoid a compiler warning */
> LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
> return;
>
> -die:
> +cp0_unimplemented:
> LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
> - generate_exception(ctx, EXCP_RI);
> + gen_mfc0_unimplemented(ctx, arg);
> }
>
> static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> @@ -5289,22 +5285,22 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Index";
> break;
> case 1:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_mvpcontrol(cpu_env, arg);
> rn = "MVPControl";
> break;
> case 2:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> /* ignored */
> rn = "MVPConf0";
> break;
> case 3:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> /* ignored */
> rn = "MVPConf1";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 1:
> @@ -5314,42 +5310,42 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Random";
> break;
> case 1:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_vpecontrol(cpu_env, arg);
> rn = "VPEControl";
> break;
> case 2:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_vpeconf0(cpu_env, arg);
> rn = "VPEConf0";
> break;
> case 3:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_vpeconf1(cpu_env, arg);
> rn = "VPEConf1";
> break;
> case 4:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_yqmask(cpu_env, arg);
> rn = "YQMask";
> break;
> case 5:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
> rn = "VPESchedule";
> break;
> case 6:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
> rn = "VPEScheFBack";
> break;
> case 7:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_vpeopt(cpu_env, arg);
> rn = "VPEOpt";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 2:
> @@ -5359,42 +5355,42 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EntryLo0";
> break;
> case 1:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_tcstatus(cpu_env, arg);
> rn = "TCStatus";
> break;
> case 2:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_tcbind(cpu_env, arg);
> rn = "TCBind";
> break;
> case 3:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_tcrestart(cpu_env, arg);
> rn = "TCRestart";
> break;
> case 4:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_tchalt(cpu_env, arg);
> rn = "TCHalt";
> break;
> case 5:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_tccontext(cpu_env, arg);
> rn = "TCContext";
> break;
> case 6:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_tcschedule(cpu_env, arg);
> rn = "TCSchedule";
> break;
> case 7:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_tcschefback(cpu_env, arg);
> rn = "TCScheFBack";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 3:
> @@ -5404,7 +5400,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EntryLo1";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 4:
> @@ -5416,17 +5412,16 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> case 1:
> // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
> rn = "ContextConfig";
> - goto die;
> + goto cp0_unimplemented;
> // break;
> case 2:
> - if (ctx->ulri) {
> - tcg_gen_st_tl(arg, cpu_env,
> - offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
> - rn = "UserLocal";
> - }
> + CP0_CHECK(ctx->ulri);
> + tcg_gen_st_tl(arg, cpu_env,
> + offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
> + rn = "UserLocal";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 5:
> @@ -5441,7 +5436,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "PageGrain";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 6:
> @@ -5476,7 +5471,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "SRSConf4";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 7:
> @@ -5488,7 +5483,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "HWREna";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 8:
> @@ -5506,7 +5501,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "BadInstrP";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 9:
> @@ -5517,7 +5512,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> break;
> /* 6,7 are implementation dependent */
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 10:
> @@ -5527,7 +5522,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EntryHi";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 11:
> @@ -5538,7 +5533,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> break;
> /* 6,7 are implementation dependent */
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 12:
> @@ -5573,7 +5568,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "SRSMap";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 13:
> @@ -5584,7 +5579,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Cause";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 14:
> @@ -5594,7 +5589,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EPC";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 15:
> @@ -5609,7 +5604,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EBase";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 16:
> @@ -5656,7 +5651,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> break;
> default:
> rn = "Invalid config selector";
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 17:
> @@ -5666,7 +5661,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "LLAddr";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 18:
> @@ -5676,7 +5671,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "WatchLo";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 19:
> @@ -5686,7 +5681,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "WatchHi";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 20:
> @@ -5699,18 +5694,19 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> break;
> #endif
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 21:
> /* Officially reserved, but sel 0 is used for R1x000 framemask */
> + CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
> switch (sel) {
> case 0:
> gen_helper_mtc0_framemask(cpu_env, arg);
> rn = "Framemask";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 22:
> @@ -5753,7 +5749,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "TraceBPC";
> // break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 24:
> @@ -5764,7 +5760,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "DEPC";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 25:
> @@ -5802,7 +5798,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Performance7";
> // break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 26:
> @@ -5816,7 +5812,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "CacheErr";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 28:
> @@ -5836,7 +5832,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "DataLo";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 29:
> @@ -5857,7 +5853,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> break;
> default:
> rn = "invalid sel";
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 30:
> @@ -5867,7 +5863,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "ErrorEPC";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 31:
> @@ -5878,20 +5874,19 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "DESAVE";
> break;
> case 2 ... 7:
> - if (ctx->kscrexist & (1 << sel)) {
> - tcg_gen_st_tl(arg, cpu_env,
> - offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
> - rn = "KScratch";
> - }
> + CP0_CHECK(ctx->kscrexist & (1 << sel));
> + tcg_gen_st_tl(arg, cpu_env,
> + offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
> + rn = "KScratch";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> /* Stop translation as we may have switched the execution mode */
> ctx->bstate = BS_STOP;
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> (void)rn; /* avoid a compiler warning */
> LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
> @@ -5902,9 +5897,8 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> }
> return;
>
> -die:
> +cp0_unimplemented:
> LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
> - generate_exception(ctx, EXCP_RI);
> }
>
> #if defined(TARGET_MIPS64)
> @@ -5923,67 +5917,68 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Index";
> break;
> case 1:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mfc0_mvpcontrol(arg, cpu_env);
> rn = "MVPControl";
> break;
> case 2:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mfc0_mvpconf0(arg, cpu_env);
> rn = "MVPConf0";
> break;
> case 3:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mfc0_mvpconf1(arg, cpu_env);
> rn = "MVPConf1";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 1:
> switch (sel) {
> case 0:
> + CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
> gen_helper_mfc0_random(arg, cpu_env);
> rn = "Random";
> break;
> case 1:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
> rn = "VPEControl";
> break;
> case 2:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
> rn = "VPEConf0";
> break;
> case 3:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
> rn = "VPEConf1";
> break;
> case 4:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
> rn = "YQMask";
> break;
> case 5:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
> rn = "VPESchedule";
> break;
> case 6:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
> rn = "VPEScheFBack";
> break;
> case 7:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
> rn = "VPEOpt";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 2:
> @@ -5993,42 +5988,42 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EntryLo0";
> break;
> case 1:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mfc0_tcstatus(arg, cpu_env);
> rn = "TCStatus";
> break;
> case 2:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mfc0_tcbind(arg, cpu_env);
> rn = "TCBind";
> break;
> case 3:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_dmfc0_tcrestart(arg, cpu_env);
> rn = "TCRestart";
> break;
> case 4:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_dmfc0_tchalt(arg, cpu_env);
> rn = "TCHalt";
> break;
> case 5:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_dmfc0_tccontext(arg, cpu_env);
> rn = "TCContext";
> break;
> case 6:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_dmfc0_tcschedule(arg, cpu_env);
> rn = "TCSchedule";
> break;
> case 7:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_dmfc0_tcschefback(arg, cpu_env);
> rn = "TCScheFBack";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 3:
> @@ -6038,7 +6033,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EntryLo1";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 4:
> @@ -6050,19 +6045,16 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> case 1:
> // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
> rn = "ContextConfig";
> - goto die;
> + goto cp0_unimplemented;
> // break;
> case 2:
> - if (ctx->ulri) {
> - tcg_gen_ld_tl(arg, cpu_env,
> - offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
> - rn = "UserLocal";
> - } else {
> - tcg_gen_movi_tl(arg, 0);
> - }
> + CP0_CHECK(ctx->ulri);
> + tcg_gen_ld_tl(arg, cpu_env,
> + offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
> + rn = "UserLocal";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 5:
> @@ -6077,7 +6069,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "PageGrain";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 6:
> @@ -6112,7 +6104,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "SRSConf4";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 7:
> @@ -6123,7 +6115,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "HWREna";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 8:
> @@ -6133,25 +6125,19 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "BadVAddr";
> break;
> case 1:
> - if (ctx->bi) {
> - gen_mfc0_load32(arg, offsetof(CPUMIPSState,
> - active_tc.CP0_BadInstr));
> - rn = "BadInstr";
> - } else {
> - gen_mfc0_unimplemented(ctx, arg);
> - }
> + CP0_CHECK(ctx->bi);
> + gen_mfc0_load32(arg, offsetof(CPUMIPSState,
> + active_tc.CP0_BadInstr));
> + rn = "BadInstr";
> break;
> case 2:
> - if (ctx->bp) {
> - gen_mfc0_load32(arg, offsetof(CPUMIPSState,
> - active_tc.CP0_BadInstrP));
> - rn = "BadInstrP";
> - } else {
> - gen_mfc0_unimplemented(ctx, arg);
> - }
> + CP0_CHECK(ctx->bp);
> + gen_mfc0_load32(arg, offsetof(CPUMIPSState,
> + active_tc.CP0_BadInstrP));
> + rn = "BadInstrP";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 9:
> @@ -6171,7 +6157,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> break;
> /* 6,7 are implementation dependent */
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 10:
> @@ -6181,7 +6167,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EntryHi";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 11:
> @@ -6192,7 +6178,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> break;
> /* 6,7 are implementation dependent */
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 12:
> @@ -6217,7 +6203,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "SRSMap";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 13:
> @@ -6227,7 +6213,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Cause";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 14:
> @@ -6237,7 +6223,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EPC";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 15:
> @@ -6252,7 +6238,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EBase";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 16:
> @@ -6291,7 +6277,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Config7";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 17:
> @@ -6301,7 +6287,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "LLAddr";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 18:
> @@ -6311,7 +6297,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "WatchLo";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 19:
> @@ -6321,7 +6307,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "WatchHi";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 20:
> @@ -6332,18 +6318,19 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "XContext";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 21:
> /* Officially reserved, but sel 0 is used for R1x000 framemask */
> + CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
> switch (sel) {
> case 0:
> gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
> rn = "Framemask";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 22:
> @@ -6373,7 +6360,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "TraceBPC";
> // break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 24:
> @@ -6384,7 +6371,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "DEPC";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 25:
> @@ -6422,7 +6409,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Performance7";
> // break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 26:
> @@ -6437,7 +6424,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "CacheErr";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 28:
> @@ -6457,7 +6444,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "DataLo";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 29:
> @@ -6477,7 +6464,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "DataHi";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 30:
> @@ -6487,7 +6474,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "ErrorEPC";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 31:
> @@ -6498,28 +6485,25 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "DESAVE";
> break;
> case 2 ... 7:
> - if (ctx->kscrexist & (1 << sel)) {
> - tcg_gen_ld_tl(arg, cpu_env,
> - offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
> - rn = "KScratch";
> - } else {
> - gen_mfc0_unimplemented(ctx, arg);
> - }
> + CP0_CHECK(ctx->kscrexist & (1 << sel));
> + tcg_gen_ld_tl(arg, cpu_env,
> + offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
> + rn = "KScratch";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> (void)rn; /* avoid a compiler warning */
> LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
> return;
>
> -die:
> +cp0_unimplemented:
> LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
> - generate_exception(ctx, EXCP_RI);
> + gen_mfc0_unimplemented(ctx, arg);
> }
>
> static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> @@ -6540,22 +6524,22 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Index";
> break;
> case 1:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_mvpcontrol(cpu_env, arg);
> rn = "MVPControl";
> break;
> case 2:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> /* ignored */
> rn = "MVPConf0";
> break;
> case 3:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> /* ignored */
> rn = "MVPConf1";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 1:
> @@ -6565,42 +6549,42 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Random";
> break;
> case 1:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_vpecontrol(cpu_env, arg);
> rn = "VPEControl";
> break;
> case 2:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_vpeconf0(cpu_env, arg);
> rn = "VPEConf0";
> break;
> case 3:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_vpeconf1(cpu_env, arg);
> rn = "VPEConf1";
> break;
> case 4:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_yqmask(cpu_env, arg);
> rn = "YQMask";
> break;
> case 5:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
> rn = "VPESchedule";
> break;
> case 6:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
> rn = "VPEScheFBack";
> break;
> case 7:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_vpeopt(cpu_env, arg);
> rn = "VPEOpt";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 2:
> @@ -6610,42 +6594,42 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EntryLo0";
> break;
> case 1:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_tcstatus(cpu_env, arg);
> rn = "TCStatus";
> break;
> case 2:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_tcbind(cpu_env, arg);
> rn = "TCBind";
> break;
> case 3:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_tcrestart(cpu_env, arg);
> rn = "TCRestart";
> break;
> case 4:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_tchalt(cpu_env, arg);
> rn = "TCHalt";
> break;
> case 5:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_tccontext(cpu_env, arg);
> rn = "TCContext";
> break;
> case 6:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_tcschedule(cpu_env, arg);
> rn = "TCSchedule";
> break;
> case 7:
> - check_insn(ctx, ASE_MT);
> + CP0_CHECK(ctx->insn_flags & ASE_MT);
> gen_helper_mtc0_tcschefback(cpu_env, arg);
> rn = "TCScheFBack";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 3:
> @@ -6655,7 +6639,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EntryLo1";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 4:
> @@ -6667,17 +6651,16 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> case 1:
> // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
> rn = "ContextConfig";
> - goto die;
> + goto cp0_unimplemented;
> // break;
> case 2:
> - if (ctx->ulri) {
> - tcg_gen_st_tl(arg, cpu_env,
> - offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
> - rn = "UserLocal";
> - }
> + CP0_CHECK(ctx->ulri);
> + tcg_gen_st_tl(arg, cpu_env,
> + offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
> + rn = "UserLocal";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 5:
> @@ -6692,7 +6675,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "PageGrain";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 6:
> @@ -6727,7 +6710,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "SRSConf4";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 7:
> @@ -6739,7 +6722,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "HWREna";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 8:
> @@ -6757,7 +6740,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "BadInstrP";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 9:
> @@ -6768,7 +6751,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> break;
> /* 6,7 are implementation dependent */
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> /* Stop translation as we may have switched the execution mode */
> ctx->bstate = BS_STOP;
> @@ -6780,7 +6763,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EntryHi";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 11:
> @@ -6791,7 +6774,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> break;
> /* 6,7 are implementation dependent */
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> /* Stop translation as we may have switched the execution mode */
> ctx->bstate = BS_STOP;
> @@ -6828,7 +6811,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "SRSMap";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 13:
> @@ -6849,7 +6832,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Cause";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 14:
> @@ -6859,7 +6842,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EPC";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 15:
> @@ -6874,7 +6857,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "EBase";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 16:
> @@ -6912,7 +6895,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> /* 6,7 are implementation dependent */
> default:
> rn = "Invalid config selector";
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 17:
> @@ -6922,7 +6905,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "LLAddr";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 18:
> @@ -6932,7 +6915,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "WatchLo";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 19:
> @@ -6942,7 +6925,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "WatchHi";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 20:
> @@ -6953,18 +6936,19 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "XContext";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 21:
> /* Officially reserved, but sel 0 is used for R1x000 framemask */
> + CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
> switch (sel) {
> case 0:
> gen_helper_mtc0_framemask(cpu_env, arg);
> rn = "Framemask";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 22:
> @@ -7005,7 +6989,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "TraceBPC";
> // break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 24:
> @@ -7016,7 +7000,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "DEPC";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 25:
> @@ -7054,7 +7038,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "Performance7";
> // break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 26:
> @@ -7068,7 +7052,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "CacheErr";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 28:
> @@ -7088,7 +7072,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "DataLo";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 29:
> @@ -7109,7 +7093,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> break;
> default:
> rn = "invalid sel";
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 30:
> @@ -7119,7 +7103,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "ErrorEPC";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> break;
> case 31:
> @@ -7130,20 +7114,19 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> rn = "DESAVE";
> break;
> case 2 ... 7:
> - if (ctx->kscrexist & (1 << sel)) {
> - tcg_gen_st_tl(arg, cpu_env,
> - offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
> - rn = "KScratch";
> - }
> + CP0_CHECK(ctx->kscrexist & (1 << sel));
> + tcg_gen_st_tl(arg, cpu_env,
> + offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
> + rn = "KScratch";
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> /* Stop translation as we may have switched the execution mode */
> ctx->bstate = BS_STOP;
> break;
> default:
> - goto die;
> + goto cp0_unimplemented;
> }
> (void)rn; /* avoid a compiler warning */
> LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
> @@ -7154,9 +7137,8 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> }
> return;
>
> -die:
> +cp0_unimplemented:
> LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
> - generate_exception(ctx, EXCP_RI);
> }
> #endif /* TARGET_MIPS64 */
>
Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>
Regards,
Yongbok
next prev parent reply other threads:[~2014-10-20 10:49 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-14 16:19 [Qemu-devel] [PATCH 0/6] target-mips: implement new MIPS64 Release 6 features Leon Alrae
2014-07-14 16:19 ` [Qemu-devel] [PATCH 1/6] target-mips: add Config5.SBRI Leon Alrae
2014-10-16 14:32 ` Yongbok Kim
2014-07-14 16:19 ` [Qemu-devel] [PATCH 2/6] target-mips: implement forbidden slot Leon Alrae
2014-10-20 11:10 ` Yongbok Kim
2014-07-14 16:19 ` [Qemu-devel] [PATCH 3/6] target-mips: CP0_Status.CU0 no longer allows the user to access CP0 Leon Alrae
2014-10-17 9:58 ` Yongbok Kim
2014-07-14 16:19 ` [Qemu-devel] [PATCH 4/6] target-mips: add restrictions for possible values in registers Leon Alrae
2014-10-20 10:19 ` Yongbok Kim
2014-10-21 13:54 ` Leon Alrae
2014-07-14 16:19 ` [Qemu-devel] [PATCH 5/6] target-mips: correctly handle access to unimplemented CP0 register Leon Alrae
2014-10-20 10:49 ` Yongbok Kim [this message]
2014-07-14 16:19 ` [Qemu-devel] [PATCH 6/6] target-mips: enable features in MIPS64R6-generic CPU Leon Alrae
2014-10-20 14:23 ` Yongbok Kim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5444E8AF.2080305@imgtec.com \
--to=yongbok.kim@imgtec.com \
--cc=aurelien@aurel32.net \
--cc=leon.alrae@imgtec.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.