aboutsummaryrefslogtreecommitdiff
path: root/target-mips/translate.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r--target-mips/translate.c170
1 files changed, 140 insertions, 30 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c
index f0b8e6ffe4..1205909f78 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -1882,10 +1882,8 @@ static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
{ \
TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
- switch (ifmt) { \
- case FMT_D: \
+ if (ifmt == FMT_D) { \
check_cp1_registers(ctx, fs | ft | fd); \
- break; \
} \
gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
@@ -2398,7 +2396,14 @@ static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
{
if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
check_cp1_enabled(ctx);
- gen_flt_ldst(ctx, op, rt, rs, imm);
+ switch (op) {
+ case OPC_LDC1:
+ case OPC_SDC1:
+ check_insn(ctx, ISA_MIPS2);
+ /* Fallthrough */
+ default:
+ gen_flt_ldst(ctx, op, rt, rs, imm);
+ }
} else {
generate_exception_err(ctx, EXCP_CpU, 1);
}
@@ -5846,8 +5851,10 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
ctx->bstate = BS_STOP;
break;
case 3:
- /* ignored, read only */
+ gen_helper_mtc0_config3(cpu_env, arg);
rn = "Config3";
+ /* Stop translation as we may have switched the execution mode */
+ ctx->bstate = BS_STOP;
break;
case 4:
gen_helper_mtc0_config4(cpu_env, arg);
@@ -7097,8 +7104,10 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
ctx->bstate = BS_STOP;
break;
case 3:
- /* ignored */
+ gen_helper_mtc0_config3(cpu_env, arg);
rn = "Config3";
+ /* Stop translation as we may have switched the execution mode */
+ ctx->bstate = BS_STOP;
break;
case 4:
/* currently ignored */
@@ -10717,6 +10726,7 @@ static void gen_mips16_save (DisasContext *ctx,
{
TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
+ TCGv t2 = tcg_temp_new();
int args, astatic;
switch (aregs) {
@@ -10775,7 +10785,8 @@ static void gen_mips16_save (DisasContext *ctx,
gen_load_gpr(t0, 29);
#define DECR_AND_STORE(reg) do { \
- tcg_gen_subi_tl(t0, t0, 4); \
+ tcg_gen_movi_tl(t2, -4); \
+ gen_op_addr_add(ctx, t0, t0, t2); \
gen_load_gpr(t1, reg); \
tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
} while (0)
@@ -10859,9 +10870,11 @@ static void gen_mips16_save (DisasContext *ctx,
}
#undef DECR_AND_STORE
- tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
+ tcg_gen_movi_tl(t2, -framesize);
+ gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
tcg_temp_free(t0);
tcg_temp_free(t1);
+ tcg_temp_free(t2);
}
static void gen_mips16_restore (DisasContext *ctx,
@@ -10872,11 +10885,14 @@ static void gen_mips16_restore (DisasContext *ctx,
int astatic;
TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
+ TCGv t2 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
+ tcg_gen_movi_tl(t2, framesize);
+ gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
#define DECR_AND_LOAD(reg) do { \
- tcg_gen_subi_tl(t0, t0, 4); \
+ tcg_gen_movi_tl(t2, -4); \
+ gen_op_addr_add(ctx, t0, t0, t2); \
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
gen_store_gpr(t1, reg); \
} while (0)
@@ -10960,9 +10976,11 @@ static void gen_mips16_restore (DisasContext *ctx,
}
#undef DECR_AND_LOAD
- tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
+ tcg_gen_movi_tl(t2, framesize);
+ gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
tcg_temp_free(t0);
tcg_temp_free(t1);
+ tcg_temp_free(t2);
}
static void gen_addiupc (DisasContext *ctx, int rx, int imm,
@@ -10993,26 +11011,32 @@ static void decode_i64_mips16 (DisasContext *ctx,
{
switch (funct) {
case I64_LDSP:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
offset = extended ? offset : offset << 3;
gen_ld(ctx, OPC_LD, ry, 29, offset);
break;
case I64_SDSP:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
offset = extended ? offset : offset << 3;
gen_st(ctx, OPC_SD, ry, 29, offset);
break;
case I64_SDRASP:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
offset = extended ? offset : (ctx->opcode & 0xff) << 3;
gen_st(ctx, OPC_SD, 31, 29, offset);
break;
case I64_DADJSP:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
break;
case I64_LDPC:
+ check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
generate_exception(ctx, EXCP_RI);
} else {
@@ -11021,16 +11045,19 @@ static void decode_i64_mips16 (DisasContext *ctx,
}
break;
case I64_DADDIU5:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
break;
case I64_DADDIUPC:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
offset = extended ? offset : offset << 2;
gen_addiupc(ctx, ry, offset, 1, extended);
break;
case I64_DADDIUSP:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
offset = extended ? offset : offset << 2;
gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
@@ -11099,7 +11126,8 @@ static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
break;
#if defined(TARGET_MIPS64)
case M16_OPC_LD:
- check_mips_64(ctx);
+ check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
gen_ld(ctx, OPC_LD, ry, rx, offset);
break;
#endif
@@ -11143,6 +11171,7 @@ static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
break;
case I8_SVRS:
+ check_insn(ctx, ISA_MIPS32);
{
int xsregs = (ctx->opcode >> 24) & 0x7;
int aregs = (ctx->opcode >> 16) & 0xf;
@@ -11176,6 +11205,8 @@ static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
break;
#if defined(TARGET_MIPS64)
case M16_OPC_SD:
+ check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
gen_st(ctx, OPC_SD, ry, rx, offset);
break;
#endif
@@ -11202,6 +11233,8 @@ static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
break;
#if defined(TARGET_MIPS64)
case M16_OPC_LWU:
+ check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
gen_ld(ctx, OPC_LWU, ry, rx, offset);
break;
#endif
@@ -11291,6 +11324,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
break;
case 0x1:
#if defined(TARGET_MIPS64)
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
#else
@@ -11307,6 +11341,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
break;
#if defined(TARGET_MIPS64)
case M16_OPC_LD:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
break;
@@ -11317,6 +11352,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
if ((ctx->opcode >> 4) & 1) {
#if defined(TARGET_MIPS64)
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
#else
@@ -11368,6 +11404,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
((int8_t)ctx->opcode) << 3);
break;
case I8_SVRS:
+ check_insn(ctx, ISA_MIPS32);
{
int do_ra = ctx->opcode & (1 << 6);
int do_s0 = ctx->opcode & (1 << 5);
@@ -11423,6 +11460,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
break;
#if defined(TARGET_MIPS64)
case M16_OPC_SD:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
gen_st(ctx, OPC_SD, ry, rx, offset << 3);
break;
@@ -11450,6 +11488,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
break;
#if defined (TARGET_MIPS64)
case M16_OPC_LWU:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
break;
@@ -11481,10 +11520,12 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
#if defined(TARGET_MIPS64)
case RRR_DADDU:
mips32_op = OPC_DADDU;
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
break;
case RRR_DSUBU:
mips32_op = OPC_DSUBU;
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
break;
#endif
@@ -11506,6 +11547,10 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
int link = (ctx->opcode >> 6) & 0x1;
int ra = (ctx->opcode >> 5) & 0x1;
+ if (nd) {
+ check_insn(ctx, ISA_MIPS32);
+ }
+
if (link) {
op = OPC_JALR;
} else {
@@ -11547,6 +11592,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
break;
#if defined (TARGET_MIPS64)
case RR_DSRL:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
break;
@@ -11573,6 +11619,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
gen_HILO(ctx, OPC_MFHI, 0, rx);
break;
case RR_CNVT:
+ check_insn(ctx, ISA_MIPS32);
switch (cnvt_op) {
case RR_RY_CNVT_ZEB:
tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
@@ -11588,10 +11635,12 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
break;
#if defined (TARGET_MIPS64)
case RR_RY_CNVT_ZEW:
+ check_insn(ctx, ISA_MIPS64);
check_mips_64(ctx);
tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
break;
case RR_RY_CNVT_SEW:
+ check_insn(ctx, ISA_MIPS64);
check_mips_64(ctx);
tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
break;
@@ -11606,18 +11655,22 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
break;
#if defined (TARGET_MIPS64)
case RR_DSRA:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
break;
case RR_DSLLV:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
break;
case RR_DSRLV:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
break;
case RR_DSRAV:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
break;
@@ -11636,18 +11689,22 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
break;
#if defined (TARGET_MIPS64)
case RR_DMULT:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
break;
case RR_DMULTU:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
break;
case RR_DDIV:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
break;
case RR_DDIVU:
+ check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
break;
@@ -13212,20 +13269,26 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
/* COP2: Not implemented. */
generate_exception_err(ctx, EXCP_CpU, 2);
break;
- case LWP:
- case SWP:
#ifdef TARGET_MIPS64
case LDP:
case SDP:
+ check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
+ /* Fallthrough */
#endif
+ case LWP:
+ case SWP:
gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
break;
- case LWM32:
- case SWM32:
#ifdef TARGET_MIPS64
case LDM:
case SDM:
+ check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
+ /* Fallthrough */
#endif
+ case LWM32:
+ case SWM32:
gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
break;
default:
@@ -13649,21 +13712,33 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
goto do_st_lr;
#if defined(TARGET_MIPS64)
case LDL:
+ check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
mips32_op = OPC_LDL;
goto do_ld_lr;
case SDL:
+ check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
mips32_op = OPC_SDL;
goto do_st_lr;
case LDR:
+ check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
mips32_op = OPC_LDR;
goto do_ld_lr;
case SDR:
+ check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
mips32_op = OPC_SDR;
goto do_st_lr;
case LWU:
+ check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
mips32_op = OPC_LWU;
goto do_ld_lr;
case LLD:
+ check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
mips32_op = OPC_LLD;
goto do_ld_lr;
#endif
@@ -13681,6 +13756,8 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
break;
#if defined(TARGET_MIPS64)
case SCD:
+ check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
break;
#endif
@@ -13790,9 +13867,13 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
goto do_ld;
#ifdef TARGET_MIPS64
case LD32:
+ check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
mips32_op = OPC_LD;
goto do_ld;
case SD32:
+ check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
mips32_op = OPC_SD;
goto do_st;
#endif
@@ -13936,8 +14017,8 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
rs = rs_rt_enc[enc_rs];
rt = rs_rt_enc[enc_rt];
- gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
- gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
+ gen_arith(ctx, OPC_ADDU, rd, rs, 0);
+ gen_arith(ctx, OPC_ADDU, re, rt, 0);
}
break;
case LBU16:
@@ -14018,7 +14099,7 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
int rd = uMIPS_RD5(ctx->opcode);
int rs = uMIPS_RS5(ctx->opcode);
- gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
+ gen_arith(ctx, OPC_ADDU, rd, rs, 0);
}
break;
case ANDI16:
@@ -16322,6 +16403,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
break;
case OPC_TGE ... OPC_TEQ: /* Traps */
case OPC_TNE:
+ check_insn(ctx, ISA_MIPS2);
gen_trap(ctx, op1, rs, rt, -1);
break;
case OPC_LSA: /* OPC_PMON */
@@ -16346,6 +16428,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
generate_exception(ctx, EXCP_BREAK);
break;
case OPC_SYNC:
+ check_insn(ctx, ISA_MIPS2);
/* Treat as NOP. */
break;
@@ -18340,7 +18423,7 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
}
-static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
+static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
{
int32_t offset;
int rs, rt, rd, sa;
@@ -18392,7 +18475,9 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
case OPC_BGEZL:
case OPC_BLTZALL:
case OPC_BGEZALL:
+ check_insn(ctx, ISA_MIPS2);
check_insn_opc_removed(ctx, ISA_MIPS32R6);
+ /* Fallthrough */
case OPC_BLTZ:
case OPC_BGEZ:
gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
@@ -18412,6 +18497,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
break;
case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
case OPC_TNEI:
+ check_insn(ctx, ISA_MIPS2);
check_insn_opc_removed(ctx, ISA_MIPS32R6);
gen_trap(ctx, op1, rs, -1, imm);
break;
@@ -18506,7 +18592,8 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
save_cpu_state(ctx, 1);
gen_helper_di(t0, cpu_env);
gen_store_gpr(t0, rt);
- /* Stop translation as we may have switched the execution mode */
+ /* Stop translation as we may have switched
+ the execution mode. */
ctx->bstate = BS_STOP;
break;
case OPC_EI:
@@ -18514,7 +18601,8 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
save_cpu_state(ctx, 1);
gen_helper_ei(t0, cpu_env);
gen_store_gpr(t0, rt);
- /* Stop translation as we may have switched the execution mode */
+ /* Stop translation as we may have switched
+ the execution mode. */
ctx->bstate = BS_STOP;
break;
default: /* Invalid */
@@ -18616,15 +18704,20 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
break;
case OPC_BEQL:
case OPC_BNEL:
+ check_insn(ctx, ISA_MIPS2);
check_insn_opc_removed(ctx, ISA_MIPS32R6);
+ /* Fallthrough */
case OPC_BEQ:
case OPC_BNE:
gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
break;
- case OPC_LWL: /* Load and stores */
+ case OPC_LL: /* Load and stores */
+ check_insn(ctx, ISA_MIPS2);
+ /* Fallthrough */
+ case OPC_LWL:
case OPC_LWR:
- case OPC_LL:
check_insn_opc_removed(ctx, ISA_MIPS32R6);
+ /* Fallthrough */
case OPC_LB ... OPC_LH:
case OPC_LW ... OPC_LHU:
gen_ld(ctx, op, rt, rs, imm);
@@ -18637,6 +18730,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
gen_st(ctx, op, rt, rs, imm);
break;
case OPC_SC:
+ check_insn(ctx, ISA_MIPS2);
check_insn_opc_removed(ctx, ISA_MIPS32R6);
gen_st_cond(ctx, op, rt, rs, imm);
break;
@@ -18680,6 +18774,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
case OPC_DMTC1:
check_cp1_enabled(ctx);
check_insn(ctx, ISA_MIPS3);
+ check_mips_64(ctx);
gen_cp1(ctx, op1, rt, rd);
break;
#endif
@@ -18780,8 +18875,9 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
break;
default:
- gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
- (imm >> 8) & 0x7);
+ gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
+ rt, rd, sa, (imm >> 8) & 0x7);
+
break;
}
} else {
@@ -18852,18 +18948,24 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
check_cp1_enabled(ctx);
op1 = MASK_CP3(ctx->opcode);
switch (op1) {
+ case OPC_LUXC1:
+ case OPC_SUXC1:
+ check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
+ /* Fallthrough */
case OPC_LWXC1:
case OPC_LDXC1:
- case OPC_LUXC1:
case OPC_SWXC1:
case OPC_SDXC1:
- case OPC_SUXC1:
+ check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
break;
case OPC_PREFX:
+ check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
/* Treat as NOP. */
break;
case OPC_ALNV_PS:
+ check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
+ /* Fallthrough */
case OPC_MADD_S:
case OPC_MADD_D:
case OPC_MADD_PS:
@@ -18876,6 +18978,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
case OPC_NMSUB_S:
case OPC_NMSUB_D:
case OPC_NMSUB_PS:
+ check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
break;
default:
@@ -19011,7 +19114,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
/* Restore delay slot state from the tb context. */
ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
- ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
+ ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
restore_cpu_state(env, &ctx);
#ifdef CONFIG_USER_ONLY
ctx.mem_idx = MIPS_HFLAG_UM;
@@ -19261,6 +19364,10 @@ void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
env->CP0_Config0, env->CP0_Config1, env->lladdr);
+ cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
+ env->CP0_Config2, env->CP0_Config3);
+ cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
+ env->CP0_Config4, env->CP0_Config5);
if (env->hflags & MIPS_HFLAG_FPU)
fpu_dump_state(env, f, cpu_fprintf, flags);
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
@@ -19436,7 +19543,8 @@ void cpu_state_reset(CPUMIPSState *env)
if (env->hflags & MIPS_HFLAG_BMASK) {
/* If the exception was raised from a delay slot,
come back to the jump. */
- env->CP0_ErrorEPC = env->active_tc.PC - 4;
+ env->CP0_ErrorEPC = (env->active_tc.PC
+ - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
} else {
env->CP0_ErrorEPC = env->active_tc.PC;
}
@@ -19507,6 +19615,8 @@ void cpu_state_reset(CPUMIPSState *env)
}
compute_hflags(env);
+ restore_rounding_mode(env);
+ restore_flush_mode(env);
cs->exception_index = EXCP_NONE;
}