diff options
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r-- | target-mips/translate.c | 170 |
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; } |