diff options
author | Avi Kivity <avi@redhat.com> | 2012-09-09 16:21:39 +0300 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2012-09-09 16:21:39 +0300 |
commit | 3505aa6bec1a3bb474d81c495515b44654659a38 (patch) | |
tree | bf0f5f9e1a76159752047cdb239c62cbbd1f2ace /target-mips/translate.c | |
parent | 7fa12eb15f95c269f488fce4096093c96dbaffab (diff) | |
parent | 4ce5bc2dd1914a706725186c6563e8f92eedfc84 (diff) |
Merge tag 'v1.1.2' into stable-1.1qemu-kvm-1.1.2stable-1.1
* tag 'v1.1.2': (74 commits)
update VERSION for 1.1.2
console: bounds check whenever changing the cursor due to an escape code
qemu-timer: properly arm alarm timer for timers set by device initialization
target-xtensa: return ENOSYS for unimplemented simcalls
target-xtensa: fix big-endian BBS/BBC implementation
ehci: Fix NULL ptr deref when unplugging an USB dev with an iso stream active
msix: make [un]use vectors on reset/load optional
reset PMBA and PMREGMISC PIIX4 registers.
qemu_rearm_alarm_timer: do not call rearm if the next deadline is INT64_MAX
qemu-ga: Fix null pointer passed to unlink in failure branch
memory: Fix copy&paste mistake in memory_region_iorange_write
ivshmem: remove redundant ioeventfd configuration
hw/arm_gic.c: Define .class_size in arm_gic_info TypeInfo
tcg/mips: fix broken CONFIG_TCG_PASS_AREG0 code
audio/winwave: previous audio buffer should be flushed
target-mips: allow microMIPS SWP and SDP to have RD equal to BASE
target-mips: add privilege level check to several Cop0 instructions
mips-linux-user: Always support rdhwr.
target-mips: Streamline indexed cp1 memory addressing.
Fix order of CVT.PS.S operands
...
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r-- | target-mips/translate.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c index 0c563eedf..5ed58f65e 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -5933,6 +5933,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, { const char *opn = "ldst"; + check_cp0_enabled(ctx); switch (opc) { case OPC_MFC0: if (rt == 0) { @@ -6805,7 +6806,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, TCGv_i32 fp1 = tcg_temp_new_i32(); gen_load_fpr32(fp0, fs); - gen_load_fpr32(fp1, fd); + gen_load_fpr32(fp1, ft); gen_helper_float_recip2_s(fp0, fp0, fp1); tcg_temp_free_i32(fp1); gen_store_fpr32(fp0, fd); @@ -6900,7 +6901,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, gen_load_fpr32(fp32_0, fs); gen_load_fpr32(fp32_1, ft); - tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1); + tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); tcg_temp_free_i32(fp32_1); tcg_temp_free_i32(fp32_0); gen_store_fpr64(ctx, fp64, fd); @@ -7543,7 +7544,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, TCGv_i64 fp1 = tcg_temp_new_i64(); gen_load_fpr64(ctx, fp0, fs); - gen_load_fpr64(ctx, fp1, fd); + gen_load_fpr64(ctx, fp1, ft); gen_helper_float_recip2_ps(fp0, fp0, fp1); tcg_temp_free_i64(fp1); gen_store_fpr64(ctx, fp0, fd); @@ -7742,8 +7743,7 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, } else if (index == 0) { gen_load_gpr(t0, base); } else { - gen_load_gpr(t0, index); - gen_op_addr_add(ctx, t0, cpu_gpr[base], t0); + gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); } /* Don't do NOP if destination is zero: we must perform the actual memory access. */ @@ -8112,7 +8112,11 @@ gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd) { TCGv t0; +#if !defined(CONFIG_USER_ONLY) + /* The Linux kernel will emulate rdhwr if it's not supported natively. + Therefore only check the ISA in system mode. */ check_insn(env, ctx, ISA_MIPS32R2); +#endif t0 = tcg_temp_new(); switch (rd) { @@ -10027,7 +10031,7 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd, const char *opn = "ldst_pair"; TCGv t0, t1; - if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) { + if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) { generate_exception(ctx, EXCP_RI); return; } @@ -10039,6 +10043,10 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd, switch (opc) { case LWP: + if (rd == base) { + generate_exception(ctx, EXCP_RI); + return; + } save_cpu_state(ctx, 0); op_ld_lw(t1, t0, ctx); gen_store_gpr(t1, rd); @@ -10060,6 +10068,10 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd, break; #ifdef TARGET_MIPS64 case LDP: + if (rd == base) { + generate_exception(ctx, EXCP_RI); + return; + } save_cpu_state(ctx, 0); op_ld_ld(t1, t0, ctx); gen_store_gpr(t1, rd); @@ -10118,6 +10130,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs, #ifndef CONFIG_USER_ONLY case MFC0: case MFC0 + 32: + check_cp0_enabled(ctx); if (rt == 0) { /* Treat as NOP. */ break; @@ -10126,6 +10139,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs, break; case MTC0: case MTC0 + 32: + check_cp0_enabled(ctx); { TCGv t0 = tcg_temp_new(); @@ -10222,10 +10236,12 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs, case 0x05: switch (minor) { case RDPGPR: + check_cp0_enabled(ctx); check_insn(env, ctx, ISA_MIPS32R2); gen_load_srsgpr(rt, rs); break; case WRPGPR: + check_cp0_enabled(ctx); check_insn(env, ctx, ISA_MIPS32R2); gen_store_srsgpr(rt, rs); break; @@ -10266,6 +10282,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs, case 0x1d: switch (minor) { case DI: + check_cp0_enabled(ctx); { TCGv t0 = tcg_temp_new(); @@ -10278,6 +10295,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs, } break; case EI: + check_cp0_enabled(ctx); { TCGv t0 = tcg_temp_new(); @@ -10758,6 +10776,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx, minor = (ctx->opcode >> 12) & 0xf; switch (minor) { case CACHE: + check_cp0_enabled(ctx); /* Treat as no-op. */ break; case LWC2: @@ -12208,6 +12227,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) gen_st_cond(ctx, op, rt, rs, imm); break; case OPC_CACHE: + check_cp0_enabled(ctx); check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32); /* Treat as NOP. */ break; @@ -12767,8 +12787,9 @@ void cpu_state_reset(CPUMIPSState *env) #if defined(CONFIG_USER_ONLY) env->hflags = MIPS_HFLAG_UM; - /* Enable access to the SYNCI_Step register. */ - env->CP0_HWREna |= (1 << 1); + /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR + hardware registers. */ + env->CP0_HWREna |= 0x0000000F; if (env->CP0_Config1 & (1 << CP0C1_FP)) { env->hflags |= MIPS_HFLAG_FPU; } |