|
@@ -902,8 +902,21 @@ enum {
|
|
OPC_MTTR = (0x0C << 21) | OPC_CP0,
|
|
OPC_MTTR = (0x0C << 21) | OPC_CP0,
|
|
OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
|
|
OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
|
|
OPC_C0 = (0x10 << 21) | OPC_CP0,
|
|
OPC_C0 = (0x10 << 21) | OPC_CP0,
|
|
- OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
|
|
|
|
- OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
|
|
|
|
|
|
+ OPC_C0_1 = (0x11 << 21) | OPC_CP0,
|
|
|
|
+ OPC_C0_2 = (0x12 << 21) | OPC_CP0,
|
|
|
|
+ OPC_C0_3 = (0x13 << 21) | OPC_CP0,
|
|
|
|
+ OPC_C0_4 = (0x14 << 21) | OPC_CP0,
|
|
|
|
+ OPC_C0_5 = (0x15 << 21) | OPC_CP0,
|
|
|
|
+ OPC_C0_6 = (0x16 << 21) | OPC_CP0,
|
|
|
|
+ OPC_C0_7 = (0x17 << 21) | OPC_CP0,
|
|
|
|
+ OPC_C0_8 = (0x18 << 21) | OPC_CP0,
|
|
|
|
+ OPC_C0_9 = (0x19 << 21) | OPC_CP0,
|
|
|
|
+ OPC_C0_A = (0x1A << 21) | OPC_CP0,
|
|
|
|
+ OPC_C0_B = (0x1B << 21) | OPC_CP0,
|
|
|
|
+ OPC_C0_C = (0x1C << 21) | OPC_CP0,
|
|
|
|
+ OPC_C0_D = (0x1D << 21) | OPC_CP0,
|
|
|
|
+ OPC_C0_E = (0x1E << 21) | OPC_CP0,
|
|
|
|
+ OPC_C0_F = (0x1F << 21) | OPC_CP0,
|
|
};
|
|
};
|
|
|
|
|
|
/* MFMC0 opcodes */
|
|
/* MFMC0 opcodes */
|
|
@@ -4884,12 +4897,11 @@ static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
{
|
|
{
|
|
const char *rn = "invalid";
|
|
const char *rn = "invalid";
|
|
|
|
|
|
- CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
|
|
|
|
-
|
|
|
|
switch (reg) {
|
|
switch (reg) {
|
|
case 2:
|
|
case 2:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
case 0:
|
|
case 0:
|
|
|
|
+ CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
|
|
gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
|
|
gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
|
|
rn = "EntryLo0";
|
|
rn = "EntryLo0";
|
|
break;
|
|
break;
|
|
@@ -4900,6 +4912,7 @@ static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
case 3:
|
|
case 3:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
case 0:
|
|
case 0:
|
|
|
|
+ CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
|
|
gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
|
|
gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
|
|
rn = "EntryLo1";
|
|
rn = "EntryLo1";
|
|
break;
|
|
break;
|
|
@@ -4952,12 +4965,11 @@ static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
const char *rn = "invalid";
|
|
const char *rn = "invalid";
|
|
uint64_t mask = ctx->PAMask >> 36;
|
|
uint64_t mask = ctx->PAMask >> 36;
|
|
|
|
|
|
- CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
|
|
|
|
-
|
|
|
|
switch (reg) {
|
|
switch (reg) {
|
|
case 2:
|
|
case 2:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
case 0:
|
|
case 0:
|
|
|
|
+ CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
|
|
tcg_gen_andi_tl(arg, arg, mask);
|
|
tcg_gen_andi_tl(arg, arg, mask);
|
|
gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
|
|
gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
|
|
rn = "EntryLo0";
|
|
rn = "EntryLo0";
|
|
@@ -4969,6 +4981,7 @@ static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
case 3:
|
|
case 3:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
case 0:
|
|
case 0:
|
|
|
|
+ CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
|
|
tcg_gen_andi_tl(arg, arg, mask);
|
|
tcg_gen_andi_tl(arg, arg, mask);
|
|
gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
|
|
gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
|
|
rn = "EntryLo1";
|
|
rn = "EntryLo1";
|
|
@@ -5315,7 +5328,13 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
|
|
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
|
|
rn = "BadInstrP";
|
|
rn = "BadInstrP";
|
|
break;
|
|
break;
|
|
- default:
|
|
|
|
|
|
+ case 3:
|
|
|
|
+ CP0_CHECK(ctx->bi);
|
|
|
|
+ gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
|
|
|
|
+ tcg_gen_andi_tl(arg, arg, ~0xffff);
|
|
|
|
+ rn = "BadInstrX";
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
goto cp0_unimplemented;
|
|
goto cp0_unimplemented;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -5494,7 +5513,15 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
break;
|
|
break;
|
|
case 18:
|
|
case 18:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
- case 0 ... 7:
|
|
|
|
|
|
+ case 0:
|
|
|
|
+ case 1:
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
|
|
+ case 4:
|
|
|
|
+ case 5:
|
|
|
|
+ case 6:
|
|
|
|
+ case 7:
|
|
|
|
+ CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
|
|
gen_helper_1e0i(mfc0_watchlo, arg, sel);
|
|
gen_helper_1e0i(mfc0_watchlo, arg, sel);
|
|
rn = "WatchLo";
|
|
rn = "WatchLo";
|
|
break;
|
|
break;
|
|
@@ -5504,7 +5531,15 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
break;
|
|
break;
|
|
case 19:
|
|
case 19:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
- case 0 ...7:
|
|
|
|
|
|
+ case 0:
|
|
|
|
+ case 1:
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
|
|
+ case 4:
|
|
|
|
+ case 5:
|
|
|
|
+ case 6:
|
|
|
|
+ case 7:
|
|
|
|
+ CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
|
|
gen_helper_1e0i(mfc0_watchhi, arg, sel);
|
|
gen_helper_1e0i(mfc0_watchhi, arg, sel);
|
|
rn = "WatchHi";
|
|
rn = "WatchHi";
|
|
break;
|
|
break;
|
|
@@ -5630,7 +5665,10 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
break;
|
|
break;
|
|
case 27:
|
|
case 27:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
- case 0 ... 3:
|
|
|
|
|
|
+ case 0:
|
|
|
|
+ case 1:
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
tcg_gen_movi_tl(arg, 0); /* unimplemented */
|
|
tcg_gen_movi_tl(arg, 0); /* unimplemented */
|
|
rn = "CacheErr";
|
|
rn = "CacheErr";
|
|
break;
|
|
break;
|
|
@@ -5701,7 +5739,12 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
|
|
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
|
|
rn = "DESAVE";
|
|
rn = "DESAVE";
|
|
break;
|
|
break;
|
|
- case 2 ... 7:
|
|
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
|
|
+ case 4:
|
|
|
|
+ case 5:
|
|
|
|
+ case 6:
|
|
|
|
+ case 7:
|
|
CP0_CHECK(ctx->kscrexist & (1 << sel));
|
|
CP0_CHECK(ctx->kscrexist & (1 << sel));
|
|
tcg_gen_ld_tl(arg, cpu_env,
|
|
tcg_gen_ld_tl(arg, cpu_env,
|
|
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
|
|
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
|
|
@@ -5984,6 +6027,10 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
/* ignored */
|
|
/* ignored */
|
|
rn = "BadInstrP";
|
|
rn = "BadInstrP";
|
|
break;
|
|
break;
|
|
|
|
+ case 3:
|
|
|
|
+ /* ignored */
|
|
|
|
+ rn = "BadInstrX";
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
goto cp0_unimplemented;
|
|
goto cp0_unimplemented;
|
|
}
|
|
}
|
|
@@ -6167,7 +6214,15 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
break;
|
|
break;
|
|
case 18:
|
|
case 18:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
- case 0 ... 7:
|
|
|
|
|
|
+ case 0:
|
|
|
|
+ case 1:
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
|
|
+ case 4:
|
|
|
|
+ case 5:
|
|
|
|
+ case 6:
|
|
|
|
+ case 7:
|
|
|
|
+ CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
|
|
gen_helper_0e1i(mtc0_watchlo, arg, sel);
|
|
gen_helper_0e1i(mtc0_watchlo, arg, sel);
|
|
rn = "WatchLo";
|
|
rn = "WatchLo";
|
|
break;
|
|
break;
|
|
@@ -6177,7 +6232,15 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
break;
|
|
break;
|
|
case 19:
|
|
case 19:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
- case 0 ... 7:
|
|
|
|
|
|
+ case 0:
|
|
|
|
+ case 1:
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
|
|
+ case 4:
|
|
|
|
+ case 5:
|
|
|
|
+ case 6:
|
|
|
|
+ case 7:
|
|
|
|
+ CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
|
|
gen_helper_0e1i(mtc0_watchhi, arg, sel);
|
|
gen_helper_0e1i(mtc0_watchhi, arg, sel);
|
|
rn = "WatchHi";
|
|
rn = "WatchHi";
|
|
break;
|
|
break;
|
|
@@ -6315,7 +6378,10 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
break;
|
|
break;
|
|
case 27:
|
|
case 27:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
- case 0 ... 3:
|
|
|
|
|
|
+ case 0:
|
|
|
|
+ case 1:
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
/* ignored */
|
|
/* ignored */
|
|
rn = "CacheErr";
|
|
rn = "CacheErr";
|
|
break;
|
|
break;
|
|
@@ -6381,7 +6447,12 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
|
|
gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
|
|
rn = "DESAVE";
|
|
rn = "DESAVE";
|
|
break;
|
|
break;
|
|
- case 2 ... 7:
|
|
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
|
|
+ case 4:
|
|
|
|
+ case 5:
|
|
|
|
+ case 6:
|
|
|
|
+ case 7:
|
|
CP0_CHECK(ctx->kscrexist & (1 << sel));
|
|
CP0_CHECK(ctx->kscrexist & (1 << sel));
|
|
tcg_gen_st_tl(arg, cpu_env,
|
|
tcg_gen_st_tl(arg, cpu_env,
|
|
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
|
|
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
|
|
@@ -6667,6 +6738,12 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
|
|
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
|
|
rn = "BadInstrP";
|
|
rn = "BadInstrP";
|
|
break;
|
|
break;
|
|
|
|
+ case 3:
|
|
|
|
+ CP0_CHECK(ctx->bi);
|
|
|
|
+ gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
|
|
|
|
+ tcg_gen_andi_tl(arg, arg, ~0xffff);
|
|
|
|
+ rn = "BadInstrX";
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
goto cp0_unimplemented;
|
|
goto cp0_unimplemented;
|
|
}
|
|
}
|
|
@@ -6842,7 +6919,15 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
break;
|
|
break;
|
|
case 18:
|
|
case 18:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
- case 0 ... 7:
|
|
|
|
|
|
+ case 0:
|
|
|
|
+ case 1:
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
|
|
+ case 4:
|
|
|
|
+ case 5:
|
|
|
|
+ case 6:
|
|
|
|
+ case 7:
|
|
|
|
+ CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
|
|
gen_helper_1e0i(dmfc0_watchlo, arg, sel);
|
|
gen_helper_1e0i(dmfc0_watchlo, arg, sel);
|
|
rn = "WatchLo";
|
|
rn = "WatchLo";
|
|
break;
|
|
break;
|
|
@@ -6852,7 +6937,15 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
break;
|
|
break;
|
|
case 19:
|
|
case 19:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
- case 0 ... 7:
|
|
|
|
|
|
+ case 0:
|
|
|
|
+ case 1:
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
|
|
+ case 4:
|
|
|
|
+ case 5:
|
|
|
|
+ case 6:
|
|
|
|
+ case 7:
|
|
|
|
+ CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
|
|
gen_helper_1e0i(mfc0_watchhi, arg, sel);
|
|
gen_helper_1e0i(mfc0_watchhi, arg, sel);
|
|
rn = "WatchHi";
|
|
rn = "WatchHi";
|
|
break;
|
|
break;
|
|
@@ -6975,7 +7068,10 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
case 27:
|
|
case 27:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
/* ignored */
|
|
/* ignored */
|
|
- case 0 ... 3:
|
|
|
|
|
|
+ case 0:
|
|
|
|
+ case 1:
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
tcg_gen_movi_tl(arg, 0); /* unimplemented */
|
|
tcg_gen_movi_tl(arg, 0); /* unimplemented */
|
|
rn = "CacheErr";
|
|
rn = "CacheErr";
|
|
break;
|
|
break;
|
|
@@ -7040,7 +7136,12 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
|
|
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
|
|
rn = "DESAVE";
|
|
rn = "DESAVE";
|
|
break;
|
|
break;
|
|
- case 2 ... 7:
|
|
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
|
|
+ case 4:
|
|
|
|
+ case 5:
|
|
|
|
+ case 6:
|
|
|
|
+ case 7:
|
|
CP0_CHECK(ctx->kscrexist & (1 << sel));
|
|
CP0_CHECK(ctx->kscrexist & (1 << sel));
|
|
tcg_gen_ld_tl(arg, cpu_env,
|
|
tcg_gen_ld_tl(arg, cpu_env,
|
|
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
|
|
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
|
|
@@ -7319,6 +7420,10 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
/* ignored */
|
|
/* ignored */
|
|
rn = "BadInstrP";
|
|
rn = "BadInstrP";
|
|
break;
|
|
break;
|
|
|
|
+ case 3:
|
|
|
|
+ /* ignored */
|
|
|
|
+ rn = "BadInstrX";
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
goto cp0_unimplemented;
|
|
goto cp0_unimplemented;
|
|
}
|
|
}
|
|
@@ -7497,7 +7602,15 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
break;
|
|
break;
|
|
case 18:
|
|
case 18:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
- case 0 ... 7:
|
|
|
|
|
|
+ case 0:
|
|
|
|
+ case 1:
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
|
|
+ case 4:
|
|
|
|
+ case 5:
|
|
|
|
+ case 6:
|
|
|
|
+ case 7:
|
|
|
|
+ CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
|
|
gen_helper_0e1i(mtc0_watchlo, arg, sel);
|
|
gen_helper_0e1i(mtc0_watchlo, arg, sel);
|
|
rn = "WatchLo";
|
|
rn = "WatchLo";
|
|
break;
|
|
break;
|
|
@@ -7507,7 +7620,15 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
break;
|
|
break;
|
|
case 19:
|
|
case 19:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
- case 0 ... 7:
|
|
|
|
|
|
+ case 0:
|
|
|
|
+ case 1:
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
|
|
+ case 4:
|
|
|
|
+ case 5:
|
|
|
|
+ case 6:
|
|
|
|
+ case 7:
|
|
|
|
+ CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
|
|
gen_helper_0e1i(mtc0_watchhi, arg, sel);
|
|
gen_helper_0e1i(mtc0_watchhi, arg, sel);
|
|
rn = "WatchHi";
|
|
rn = "WatchHi";
|
|
break;
|
|
break;
|
|
@@ -7641,7 +7762,10 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
break;
|
|
break;
|
|
case 27:
|
|
case 27:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
- case 0 ... 3:
|
|
|
|
|
|
+ case 0:
|
|
|
|
+ case 1:
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
/* ignored */
|
|
/* ignored */
|
|
rn = "CacheErr";
|
|
rn = "CacheErr";
|
|
break;
|
|
break;
|
|
@@ -7707,7 +7831,12 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
|
|
gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
|
|
gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
|
|
rn = "DESAVE";
|
|
rn = "DESAVE";
|
|
break;
|
|
break;
|
|
- case 2 ... 7:
|
|
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
|
|
+ case 4:
|
|
|
|
+ case 5:
|
|
|
|
+ case 6:
|
|
|
|
+ case 7:
|
|
CP0_CHECK(ctx->kscrexist & (1 << sel));
|
|
CP0_CHECK(ctx->kscrexist & (1 << sel));
|
|
tcg_gen_st_tl(arg, cpu_env,
|
|
tcg_gen_st_tl(arg, cpu_env,
|
|
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
|
|
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
|
|
@@ -7843,7 +7972,14 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
|
|
break;
|
|
break;
|
|
case 16:
|
|
case 16:
|
|
switch (sel) {
|
|
switch (sel) {
|
|
- case 0 ... 7:
|
|
|
|
|
|
+ case 0:
|
|
|
|
+ case 1:
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
|
|
+ case 4:
|
|
|
|
+ case 5:
|
|
|
|
+ case 6:
|
|
|
|
+ case 7:
|
|
gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
|
|
gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
@@ -12395,10 +12531,22 @@ enum {
|
|
/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
|
|
/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
|
|
enum {
|
|
enum {
|
|
ADDIUPC_00 = 0x00,
|
|
ADDIUPC_00 = 0x00,
|
|
|
|
+ ADDIUPC_01 = 0x01,
|
|
|
|
+ ADDIUPC_02 = 0x02,
|
|
|
|
+ ADDIUPC_03 = 0x03,
|
|
|
|
+ ADDIUPC_04 = 0x04,
|
|
|
|
+ ADDIUPC_05 = 0x05,
|
|
|
|
+ ADDIUPC_06 = 0x06,
|
|
ADDIUPC_07 = 0x07,
|
|
ADDIUPC_07 = 0x07,
|
|
AUIPC = 0x1e,
|
|
AUIPC = 0x1e,
|
|
ALUIPC = 0x1f,
|
|
ALUIPC = 0x1f,
|
|
LWPC_08 = 0x08,
|
|
LWPC_08 = 0x08,
|
|
|
|
+ LWPC_09 = 0x09,
|
|
|
|
+ LWPC_0A = 0x0A,
|
|
|
|
+ LWPC_0B = 0x0B,
|
|
|
|
+ LWPC_0C = 0x0C,
|
|
|
|
+ LWPC_0D = 0x0D,
|
|
|
|
+ LWPC_0E = 0x0E,
|
|
LWPC_0F = 0x0F,
|
|
LWPC_0F = 0x0F,
|
|
};
|
|
};
|
|
|
|
|
|
@@ -12833,12 +12981,16 @@ enum {
|
|
R6_LWM16 = 0x02,
|
|
R6_LWM16 = 0x02,
|
|
R6_JRC16 = 0x03,
|
|
R6_JRC16 = 0x03,
|
|
MOVEP = 0x04,
|
|
MOVEP = 0x04,
|
|
|
|
+ MOVEP_05 = 0x05,
|
|
|
|
+ MOVEP_06 = 0x06,
|
|
MOVEP_07 = 0x07,
|
|
MOVEP_07 = 0x07,
|
|
R6_XOR16 = 0x08,
|
|
R6_XOR16 = 0x08,
|
|
R6_OR16 = 0x09,
|
|
R6_OR16 = 0x09,
|
|
R6_SWM16 = 0x0a,
|
|
R6_SWM16 = 0x0a,
|
|
JALRC16 = 0x0b,
|
|
JALRC16 = 0x0b,
|
|
MOVEP_0C = 0x0c,
|
|
MOVEP_0C = 0x0c,
|
|
|
|
+ MOVEP_0D = 0x0d,
|
|
|
|
+ MOVEP_0E = 0x0e,
|
|
MOVEP_0F = 0x0f,
|
|
MOVEP_0F = 0x0f,
|
|
JRCADDIUSP = 0x13,
|
|
JRCADDIUSP = 0x13,
|
|
R6_BREAK16 = 0x1b,
|
|
R6_BREAK16 = 0x1b,
|
|
@@ -13152,12 +13304,18 @@ static void gen_pool16c_r6_insn(DisasContext *ctx)
|
|
gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
|
|
gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
|
|
} else {
|
|
} else {
|
|
/* JRC16 */
|
|
/* JRC16 */
|
|
- int rs = extract32(ctx->opcode, 5, 5);
|
|
|
|
|
|
+ rs = extract32(ctx->opcode, 5, 5);
|
|
gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
|
|
gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
- case MOVEP ... MOVEP_07:
|
|
|
|
- case MOVEP_0C ... MOVEP_0F:
|
|
|
|
|
|
+ case MOVEP:
|
|
|
|
+ case MOVEP_05:
|
|
|
|
+ case MOVEP_06:
|
|
|
|
+ case MOVEP_07:
|
|
|
|
+ case MOVEP_0C:
|
|
|
|
+ case MOVEP_0D:
|
|
|
|
+ case MOVEP_0E:
|
|
|
|
+ case MOVEP_0F:
|
|
{
|
|
{
|
|
int enc_dest = uMIPS_RD(ctx->opcode);
|
|
int enc_dest = uMIPS_RD(ctx->opcode);
|
|
int enc_rt = uMIPS_RS2(ctx->opcode);
|
|
int enc_rt = uMIPS_RS2(ctx->opcode);
|
|
@@ -14160,8 +14318,8 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
|
|
case SDP:
|
|
case SDP:
|
|
check_insn(ctx, ISA_MIPS3);
|
|
check_insn(ctx, ISA_MIPS3);
|
|
check_mips_64(ctx);
|
|
check_mips_64(ctx);
|
|
- /* Fallthrough */
|
|
|
|
#endif
|
|
#endif
|
|
|
|
+ /* fall through */
|
|
case LWP:
|
|
case LWP:
|
|
case SWP:
|
|
case SWP:
|
|
gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
|
|
gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
|
|
@@ -14171,8 +14329,8 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
|
|
case SDM:
|
|
case SDM:
|
|
check_insn(ctx, ISA_MIPS3);
|
|
check_insn(ctx, ISA_MIPS3);
|
|
check_mips_64(ctx);
|
|
check_mips_64(ctx);
|
|
- /* Fallthrough */
|
|
|
|
#endif
|
|
#endif
|
|
|
|
+ /* fall through */
|
|
case LWM32:
|
|
case LWM32:
|
|
case SWM32:
|
|
case SWM32:
|
|
gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
|
|
gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
|
|
@@ -15135,7 +15293,14 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
|
|
if (ctx->insn_flags & ISA_MIPS32R6) {
|
|
if (ctx->insn_flags & ISA_MIPS32R6) {
|
|
/* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
|
|
/* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
|
|
switch ((ctx->opcode >> 16) & 0x1f) {
|
|
switch ((ctx->opcode >> 16) & 0x1f) {
|
|
- case ADDIUPC_00 ... ADDIUPC_07:
|
|
|
|
|
|
+ case ADDIUPC_00:
|
|
|
|
+ case ADDIUPC_01:
|
|
|
|
+ case ADDIUPC_02:
|
|
|
|
+ case ADDIUPC_03:
|
|
|
|
+ case ADDIUPC_04:
|
|
|
|
+ case ADDIUPC_05:
|
|
|
|
+ case ADDIUPC_06:
|
|
|
|
+ case ADDIUPC_07:
|
|
gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
|
|
gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
|
|
break;
|
|
break;
|
|
case AUIPC:
|
|
case AUIPC:
|
|
@@ -15144,7 +15309,14 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
|
|
case ALUIPC:
|
|
case ALUIPC:
|
|
gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
|
|
gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
|
|
break;
|
|
break;
|
|
- case LWPC_08 ... LWPC_0F:
|
|
|
|
|
|
+ case LWPC_08:
|
|
|
|
+ case LWPC_09:
|
|
|
|
+ case LWPC_0A:
|
|
|
|
+ case LWPC_0B:
|
|
|
|
+ case LWPC_0C:
|
|
|
|
+ case LWPC_0D:
|
|
|
|
+ case LWPC_0E:
|
|
|
|
+ case LWPC_0F:
|
|
gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
|
|
gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
@@ -15154,7 +15326,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
|
|
} else {
|
|
} else {
|
|
/* ADDIUPC */
|
|
/* ADDIUPC */
|
|
int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
|
|
int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
|
|
- int offset = SIMM(ctx->opcode, 0, 23) << 2;
|
|
|
|
|
|
+ offset = SIMM(ctx->opcode, 0, 23) << 2;
|
|
|
|
|
|
gen_addiupc(ctx, reg, offset, 0, 0);
|
|
gen_addiupc(ctx, reg, offset, 0, 0);
|
|
}
|
|
}
|
|
@@ -17231,7 +17403,10 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
|
|
case OPC_LSA:
|
|
case OPC_LSA:
|
|
gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
|
|
gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
|
|
break;
|
|
break;
|
|
- case OPC_MULT ... OPC_DIVU:
|
|
|
|
|
|
+ case OPC_MULT:
|
|
|
|
+ case OPC_MULTU:
|
|
|
|
+ case OPC_DIV:
|
|
|
|
+ case OPC_DIVU:
|
|
op2 = MASK_R6_MULDIV(ctx->opcode);
|
|
op2 = MASK_R6_MULDIV(ctx->opcode);
|
|
switch (op2) {
|
|
switch (op2) {
|
|
case R6_OPC_MUL:
|
|
case R6_OPC_MUL:
|
|
@@ -17291,7 +17466,11 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
|
|
generate_exception_end(ctx, EXCP_RI);
|
|
generate_exception_end(ctx, EXCP_RI);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
- case OPC_DMULT ... OPC_DDIVU:
|
|
|
|
|
|
+ case OPC_DMULT:
|
|
|
|
+ case OPC_DMULTU:
|
|
|
|
+ case OPC_DDIV:
|
|
|
|
+ case OPC_DDIVU:
|
|
|
|
+
|
|
op2 = MASK_R6_MULDIV(ctx->opcode);
|
|
op2 = MASK_R6_MULDIV(ctx->opcode);
|
|
switch (op2) {
|
|
switch (op2) {
|
|
case R6_OPC_DMUL:
|
|
case R6_OPC_DMUL:
|
|
@@ -17370,7 +17549,10 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
|
|
gen_muldiv(ctx, op1, 0, rs, rt);
|
|
gen_muldiv(ctx, op1, 0, rs, rt);
|
|
break;
|
|
break;
|
|
#if defined(TARGET_MIPS64)
|
|
#if defined(TARGET_MIPS64)
|
|
- case OPC_DMULT ... OPC_DDIVU:
|
|
|
|
|
|
+ case OPC_DMULT:
|
|
|
|
+ case OPC_DMULTU:
|
|
|
|
+ case OPC_DDIV:
|
|
|
|
+ case OPC_DDIVU:
|
|
check_insn(ctx, ISA_MIPS3);
|
|
check_insn(ctx, ISA_MIPS3);
|
|
check_mips_64(ctx);
|
|
check_mips_64(ctx);
|
|
gen_muldiv(ctx, op1, 0, rs, rt);
|
|
gen_muldiv(ctx, op1, 0, rs, rt);
|
|
@@ -17437,7 +17619,10 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
- case OPC_ADD ... OPC_SUBU:
|
|
|
|
|
|
+ case OPC_ADD:
|
|
|
|
+ case OPC_ADDU:
|
|
|
|
+ case OPC_SUB:
|
|
|
|
+ case OPC_SUBU:
|
|
gen_arith(ctx, op1, rd, rs, rt);
|
|
gen_arith(ctx, op1, rd, rs, rt);
|
|
break;
|
|
break;
|
|
case OPC_SLLV: /* Shifts */
|
|
case OPC_SLLV: /* Shifts */
|
|
@@ -17473,7 +17658,11 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
|
|
case OPC_JALR:
|
|
case OPC_JALR:
|
|
gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
|
|
gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
|
|
break;
|
|
break;
|
|
- case OPC_TGE ... OPC_TEQ: /* Traps */
|
|
|
|
|
|
+ case OPC_TGE: /* Traps */
|
|
|
|
+ case OPC_TGEU:
|
|
|
|
+ case OPC_TLT:
|
|
|
|
+ case OPC_TLTU:
|
|
|
|
+ case OPC_TEQ:
|
|
case OPC_TNE:
|
|
case OPC_TNE:
|
|
check_insn(ctx, ISA_MIPS2);
|
|
check_insn(ctx, ISA_MIPS2);
|
|
gen_trap(ctx, op1, rs, rt, -1);
|
|
gen_trap(ctx, op1, rs, rt, -1);
|
|
@@ -17549,7 +17738,10 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
- case OPC_DADD ... OPC_DSUBU:
|
|
|
|
|
|
+ case OPC_DADD:
|
|
|
|
+ case OPC_DADDU:
|
|
|
|
+ case OPC_DSUB:
|
|
|
|
+ case OPC_DSUBU:
|
|
check_insn(ctx, ISA_MIPS3);
|
|
check_insn(ctx, ISA_MIPS3);
|
|
check_mips_64(ctx);
|
|
check_mips_64(ctx);
|
|
gen_arith(ctx, op1, rd, rs, rt);
|
|
gen_arith(ctx, op1, rd, rs, rt);
|
|
@@ -17607,8 +17799,10 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
|
|
|
|
|
|
op1 = MASK_SPECIAL2(ctx->opcode);
|
|
op1 = MASK_SPECIAL2(ctx->opcode);
|
|
switch (op1) {
|
|
switch (op1) {
|
|
- case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
|
|
|
|
- case OPC_MSUB ... OPC_MSUBU:
|
|
|
|
|
|
+ case OPC_MADD: /* Multiply and add/sub */
|
|
|
|
+ case OPC_MADDU:
|
|
|
|
+ case OPC_MSUB:
|
|
|
|
+ case OPC_MSUBU:
|
|
check_insn(ctx, ISA_MIPS32);
|
|
check_insn(ctx, ISA_MIPS32);
|
|
gen_muldiv(ctx, op1, rd & 3, rs, rt);
|
|
gen_muldiv(ctx, op1, rd & 3, rs, rt);
|
|
break;
|
|
break;
|
|
@@ -17705,7 +17899,8 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
|
|
}
|
|
}
|
|
op2 = MASK_BSHFL(ctx->opcode);
|
|
op2 = MASK_BSHFL(ctx->opcode);
|
|
switch (op2) {
|
|
switch (op2) {
|
|
- case OPC_ALIGN ... OPC_ALIGN_END:
|
|
|
|
|
|
+ case OPC_ALIGN:
|
|
|
|
+ case OPC_ALIGN_END:
|
|
gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
|
|
gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
|
|
break;
|
|
break;
|
|
case OPC_BITSWAP:
|
|
case OPC_BITSWAP:
|
|
@@ -17730,7 +17925,8 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
|
|
}
|
|
}
|
|
op2 = MASK_DBSHFL(ctx->opcode);
|
|
op2 = MASK_DBSHFL(ctx->opcode);
|
|
switch (op2) {
|
|
switch (op2) {
|
|
- case OPC_DALIGN ... OPC_DALIGN_END:
|
|
|
|
|
|
+ case OPC_DALIGN:
|
|
|
|
+ case OPC_DALIGN_END:
|
|
gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
|
|
gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
|
|
break;
|
|
break;
|
|
case OPC_DBITSWAP:
|
|
case OPC_DBITSWAP:
|
|
@@ -17759,9 +17955,12 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
|
|
|
|
|
|
op1 = MASK_SPECIAL3(ctx->opcode);
|
|
op1 = MASK_SPECIAL3(ctx->opcode);
|
|
switch (op1) {
|
|
switch (op1) {
|
|
- case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
|
|
|
|
- case OPC_MOD_G_2E ... OPC_MODU_G_2E:
|
|
|
|
- case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
|
|
|
|
|
|
+ case OPC_DIV_G_2E:
|
|
|
|
+ case OPC_DIVU_G_2E:
|
|
|
|
+ case OPC_MOD_G_2E:
|
|
|
|
+ case OPC_MODU_G_2E:
|
|
|
|
+ case OPC_MULT_G_2E:
|
|
|
|
+ case OPC_MULTU_G_2E:
|
|
/* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
|
|
/* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
|
|
* the same mask and op1. */
|
|
* the same mask and op1. */
|
|
if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
|
|
if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
|
|
@@ -18025,9 +18224,12 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
#if defined(TARGET_MIPS64)
|
|
#if defined(TARGET_MIPS64)
|
|
- case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
|
|
|
|
- case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
|
|
|
|
- case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
|
|
|
|
|
|
+ case OPC_DDIV_G_2E:
|
|
|
|
+ case OPC_DDIVU_G_2E:
|
|
|
|
+ case OPC_DMULT_G_2E:
|
|
|
|
+ case OPC_DMULTU_G_2E:
|
|
|
|
+ case OPC_DMOD_G_2E:
|
|
|
|
+ case OPC_DMODU_G_2E:
|
|
check_insn(ctx, INSN_LOONGSON2E);
|
|
check_insn(ctx, INSN_LOONGSON2E);
|
|
gen_loongson_integer(ctx, op1, rd, rs, rt);
|
|
gen_loongson_integer(ctx, op1, rd, rs, rt);
|
|
break;
|
|
break;
|
|
@@ -18289,18 +18491,25 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
|
|
*/
|
|
*/
|
|
if (ctx->eva) {
|
|
if (ctx->eva) {
|
|
switch (op1) {
|
|
switch (op1) {
|
|
- case OPC_LWLE ... OPC_LWRE:
|
|
|
|
|
|
+ case OPC_LWLE:
|
|
|
|
+ case OPC_LWRE:
|
|
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
|
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
|
/* fall through */
|
|
/* fall through */
|
|
- case OPC_LBUE ... OPC_LHUE:
|
|
|
|
- case OPC_LBE ... OPC_LWE:
|
|
|
|
|
|
+ case OPC_LBUE:
|
|
|
|
+ case OPC_LHUE:
|
|
|
|
+ case OPC_LBE:
|
|
|
|
+ case OPC_LHE:
|
|
|
|
+ case OPC_LLE:
|
|
|
|
+ case OPC_LWE:
|
|
check_cp0_enabled(ctx);
|
|
check_cp0_enabled(ctx);
|
|
gen_ld(ctx, op1, rt, rs, imm);
|
|
gen_ld(ctx, op1, rt, rs, imm);
|
|
return;
|
|
return;
|
|
- case OPC_SWLE ... OPC_SWRE:
|
|
|
|
|
|
+ case OPC_SWLE:
|
|
|
|
+ case OPC_SWRE:
|
|
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
|
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
|
/* fall through */
|
|
/* fall through */
|
|
- case OPC_SBE ... OPC_SHE:
|
|
|
|
|
|
+ case OPC_SBE:
|
|
|
|
+ case OPC_SHE:
|
|
case OPC_SWE:
|
|
case OPC_SWE:
|
|
check_cp0_enabled(ctx);
|
|
check_cp0_enabled(ctx);
|
|
gen_st(ctx, op1, rt, rs, imm);
|
|
gen_st(ctx, op1, rt, rs, imm);
|
|
@@ -18332,7 +18541,8 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
|
|
case OPC_BSHFL:
|
|
case OPC_BSHFL:
|
|
op2 = MASK_BSHFL(ctx->opcode);
|
|
op2 = MASK_BSHFL(ctx->opcode);
|
|
switch (op2) {
|
|
switch (op2) {
|
|
- case OPC_ALIGN ... OPC_ALIGN_END:
|
|
|
|
|
|
+ case OPC_ALIGN:
|
|
|
|
+ case OPC_ALIGN_END:
|
|
case OPC_BITSWAP:
|
|
case OPC_BITSWAP:
|
|
check_insn(ctx, ISA_MIPS32R6);
|
|
check_insn(ctx, ISA_MIPS32R6);
|
|
decode_opc_special3_r6(env, ctx);
|
|
decode_opc_special3_r6(env, ctx);
|
|
@@ -18344,8 +18554,12 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
#if defined(TARGET_MIPS64)
|
|
#if defined(TARGET_MIPS64)
|
|
- case OPC_DEXTM ... OPC_DEXT:
|
|
|
|
- case OPC_DINSM ... OPC_DINS:
|
|
|
|
|
|
+ case OPC_DEXTM:
|
|
|
|
+ case OPC_DEXTU:
|
|
|
|
+ case OPC_DEXT:
|
|
|
|
+ case OPC_DINSM:
|
|
|
|
+ case OPC_DINSU:
|
|
|
|
+ case OPC_DINS:
|
|
check_insn(ctx, ISA_MIPS64R2);
|
|
check_insn(ctx, ISA_MIPS64R2);
|
|
check_mips_64(ctx);
|
|
check_mips_64(ctx);
|
|
gen_bitops(ctx, op1, rt, rs, sa, rd);
|
|
gen_bitops(ctx, op1, rt, rs, sa, rd);
|
|
@@ -18353,7 +18567,8 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
|
|
case OPC_DBSHFL:
|
|
case OPC_DBSHFL:
|
|
op2 = MASK_DBSHFL(ctx->opcode);
|
|
op2 = MASK_DBSHFL(ctx->opcode);
|
|
switch (op2) {
|
|
switch (op2) {
|
|
- case OPC_DALIGN ... OPC_DALIGN_END:
|
|
|
|
|
|
+ case OPC_DALIGN:
|
|
|
|
+ case OPC_DALIGN_END:
|
|
case OPC_DBITSWAP:
|
|
case OPC_DBITSWAP:
|
|
check_insn(ctx, ISA_MIPS32R6);
|
|
check_insn(ctx, ISA_MIPS32R6);
|
|
decode_opc_special3_r6(env, ctx);
|
|
decode_opc_special3_r6(env, ctx);
|
|
@@ -19584,7 +19799,12 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
|
|
gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
|
|
gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
- case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
|
|
|
|
|
|
+ case OPC_TGEI: /* REGIMM traps */
|
|
|
|
+ case OPC_TGEIU:
|
|
|
|
+ case OPC_TLTI:
|
|
|
|
+ case OPC_TLTIU:
|
|
|
|
+ case OPC_TEQI:
|
|
|
|
+
|
|
case OPC_TNEI:
|
|
case OPC_TNEI:
|
|
check_insn(ctx, ISA_MIPS2);
|
|
check_insn(ctx, ISA_MIPS2);
|
|
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
|
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
|
@@ -19647,7 +19867,22 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
|
|
gen_cp0(env, ctx, op1, rt, rd);
|
|
gen_cp0(env, ctx, op1, rt, rd);
|
|
#endif /* !CONFIG_USER_ONLY */
|
|
#endif /* !CONFIG_USER_ONLY */
|
|
break;
|
|
break;
|
|
- case OPC_C0_FIRST ... OPC_C0_LAST:
|
|
|
|
|
|
+ case OPC_C0:
|
|
|
|
+ case OPC_C0_1:
|
|
|
|
+ case OPC_C0_2:
|
|
|
|
+ case OPC_C0_3:
|
|
|
|
+ case OPC_C0_4:
|
|
|
|
+ case OPC_C0_5:
|
|
|
|
+ case OPC_C0_6:
|
|
|
|
+ case OPC_C0_7:
|
|
|
|
+ case OPC_C0_8:
|
|
|
|
+ case OPC_C0_9:
|
|
|
|
+ case OPC_C0_A:
|
|
|
|
+ case OPC_C0_B:
|
|
|
|
+ case OPC_C0_C:
|
|
|
|
+ case OPC_C0_D:
|
|
|
|
+ case OPC_C0_E:
|
|
|
|
+ case OPC_C0_F:
|
|
#ifndef CONFIG_USER_ONLY
|
|
#ifndef CONFIG_USER_ONLY
|
|
gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
|
|
gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
|
|
#endif /* !CONFIG_USER_ONLY */
|
|
#endif /* !CONFIG_USER_ONLY */
|
|
@@ -19759,7 +19994,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
|
|
case OPC_XORI:
|
|
case OPC_XORI:
|
|
gen_logic_imm(ctx, op, rt, rs, imm);
|
|
gen_logic_imm(ctx, op, rt, rs, imm);
|
|
break;
|
|
break;
|
|
- case OPC_J ... OPC_JAL: /* Jump */
|
|
|
|
|
|
+ case OPC_J: /* Jump */
|
|
|
|
+ case OPC_JAL:
|
|
offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
|
|
offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
|
|
gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
|
|
gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
|
|
break;
|
|
break;
|
|
@@ -19826,15 +20062,20 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
|
|
case OPC_LWR:
|
|
case OPC_LWR:
|
|
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
|
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
|
/* Fallthrough */
|
|
/* Fallthrough */
|
|
- case OPC_LB ... OPC_LH:
|
|
|
|
- case OPC_LW ... OPC_LHU:
|
|
|
|
|
|
+ case OPC_LB:
|
|
|
|
+ case OPC_LH:
|
|
|
|
+ case OPC_LW:
|
|
|
|
+ case OPC_LWPC:
|
|
|
|
+ case OPC_LBU:
|
|
|
|
+ case OPC_LHU:
|
|
gen_ld(ctx, op, rt, rs, imm);
|
|
gen_ld(ctx, op, rt, rs, imm);
|
|
break;
|
|
break;
|
|
case OPC_SWL:
|
|
case OPC_SWL:
|
|
case OPC_SWR:
|
|
case OPC_SWR:
|
|
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
|
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
|
/* fall through */
|
|
/* fall through */
|
|
- case OPC_SB ... OPC_SH:
|
|
|
|
|
|
+ case OPC_SB:
|
|
|
|
+ case OPC_SH:
|
|
case OPC_SW:
|
|
case OPC_SW:
|
|
gen_st(ctx, op, rt, rs, imm);
|
|
gen_st(ctx, op, rt, rs, imm);
|
|
break;
|
|
break;
|
|
@@ -19874,6 +20115,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
|
|
case OPC_MTHC1:
|
|
case OPC_MTHC1:
|
|
check_cp1_enabled(ctx);
|
|
check_cp1_enabled(ctx);
|
|
check_insn(ctx, ISA_MIPS32R2);
|
|
check_insn(ctx, ISA_MIPS32R2);
|
|
|
|
+ /* fall through */
|
|
case OPC_MFC1:
|
|
case OPC_MFC1:
|
|
case OPC_CFC1:
|
|
case OPC_CFC1:
|
|
case OPC_MTC1:
|
|
case OPC_MTC1:
|
|
@@ -20105,7 +20347,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
|
|
|
|
|
|
#if defined(TARGET_MIPS64)
|
|
#if defined(TARGET_MIPS64)
|
|
/* MIPS64 opcodes */
|
|
/* MIPS64 opcodes */
|
|
- case OPC_LDL ... OPC_LDR:
|
|
|
|
|
|
+ case OPC_LDL:
|
|
|
|
+ case OPC_LDR:
|
|
case OPC_LLD:
|
|
case OPC_LLD:
|
|
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
|
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
|
/* fall through */
|
|
/* fall through */
|
|
@@ -20115,7 +20358,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
|
|
check_mips_64(ctx);
|
|
check_mips_64(ctx);
|
|
gen_ld(ctx, op, rt, rs, imm);
|
|
gen_ld(ctx, op, rt, rs, imm);
|
|
break;
|
|
break;
|
|
- case OPC_SDL ... OPC_SDR:
|
|
|
|
|
|
+ case OPC_SDL:
|
|
|
|
+ case OPC_SDR:
|
|
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
|
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
|
/* fall through */
|
|
/* fall through */
|
|
case OPC_SD:
|
|
case OPC_SD:
|