diff options
author | Fathi Boudra <fathi.boudra@linaro.org> | 2013-08-05 10:19:49 +0300 |
---|---|---|
committer | Fathi Boudra <fathi.boudra@linaro.org> | 2013-08-05 10:19:49 +0300 |
commit | 86342dcc9b73eac8310b9dc5fd1356bbfa5b9c8e (patch) | |
tree | c9987b94bab825a920990236234da4747d565f37 /target-mips | |
parent | 050a840ead5e51a1a9f3bffe89cc89077b2f35ed (diff) |
Imported Upstream version 1.5.0-2013.06+git74+20130802+ef1b0aeupstream
Diffstat (limited to 'target-mips')
-rw-r--r-- | target-mips/cpu-qom.h | 5 | ||||
-rw-r--r-- | target-mips/cpu.c | 23 | ||||
-rw-r--r-- | target-mips/cpu.h | 9 | ||||
-rw-r--r-- | target-mips/dsp_helper.c | 201 | ||||
-rw-r--r-- | target-mips/helper.c | 5 | ||||
-rw-r--r-- | target-mips/helper.h | 2 | ||||
-rw-r--r-- | target-mips/op_helper.c | 35 | ||||
-rw-r--r-- | target-mips/translate.c | 221 |
8 files changed, 244 insertions, 257 deletions
diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h index 2a4b812..32e3cad 100644 --- a/target-mips/cpu-qom.h +++ b/target-mips/cpu-qom.h @@ -37,6 +37,7 @@ /** * MIPSCPUClass: + * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * * A MIPS CPU model. @@ -46,6 +47,7 @@ typedef struct MIPSCPUClass { CPUClass parent_class; /*< public >*/ + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); } MIPSCPUClass; @@ -70,5 +72,8 @@ static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env) #define ENV_GET_CPU(e) CPU(mips_env_get_cpu(e)) +#define ENV_OFFSET offsetof(MIPSCPU, env) + +void mips_cpu_do_interrupt(CPUState *cpu); #endif diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 10ff46d..5315f7b 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -42,21 +42,44 @@ static void mips_cpu_reset(CPUState *s) cpu_state_reset(env); } +static void mips_cpu_realizefn(DeviceState *dev, Error **errp) +{ + MIPSCPU *cpu = MIPS_CPU(dev); + MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(dev); + + cpu_reset(CPU(cpu)); + qemu_init_vcpu(&cpu->env); + + mcc->parent_realize(dev, errp); +} + static void mips_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); MIPSCPU *cpu = MIPS_CPU(obj); CPUMIPSState *env = &cpu->env; + cs->env_ptr = env; cpu_exec_init(env); + + if (tcg_enabled()) { + mips_tcg_init(); + } } static void mips_cpu_class_init(ObjectClass *c, void *data) { MIPSCPUClass *mcc = MIPS_CPU_CLASS(c); CPUClass *cc = CPU_CLASS(c); + DeviceClass *dc = DEVICE_CLASS(c); + + mcc->parent_realize = dc->realize; + dc->realize = mips_cpu_realizefn; mcc->parent_reset = cc->reset; cc->reset = mips_cpu_reset; + + cc->do_interrupt = mips_cpu_do_interrupt; } static const TypeInfo mips_cpu_type_info = { diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 5963d62..cedf03d 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -504,6 +504,9 @@ void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf); #define cpu_signal_handler cpu_mips_signal_handler #define cpu_list mips_cpu_list +extern void cpu_wrdsp(uint32_t rs, uint32_t mask_num, CPUMIPSState *env); +extern uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env); + #define CPU_SAVE_VERSION 3 /* MMU modes definitions. We carefully match the indices with our @@ -629,6 +632,7 @@ enum { #define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0 int cpu_mips_exec(CPUMIPSState *s); +void mips_tcg_init(void); MIPSCPU *cpu_mips_init(const char *cpu_model); int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc); @@ -659,7 +663,6 @@ void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int level); int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw, int mmu_idx); #define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault -void do_interrupt (CPUMIPSState *env); #if !defined(CONFIG_USER_ONLY) void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra); hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong address, @@ -718,7 +721,7 @@ static inline bool cpu_has_work(CPUState *cpu) /* It is implementation dependent if non-enabled interrupts wake-up the CPU, however most of the implementations only check for interrupts that can be taken. */ - if ((env->interrupt_request & CPU_INTERRUPT_HARD) && + if ((cpu->interrupt_request & CPU_INTERRUPT_HARD) && cpu_mips_hw_interrupts_pending(env)) { has_work = true; } @@ -727,7 +730,7 @@ static inline bool cpu_has_work(CPUState *cpu) if (env->CP0_Config3 & (1 << CP0C3_MT)) { /* The QEMU model will issue an _WAKE request whenever the CPUs should be woken up. */ - if (env->interrupt_request & CPU_INTERRUPT_WAKE) { + if (cpu->interrupt_request & CPU_INTERRUPT_WAKE) { has_work = true; } diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c index 96cb044..918a898 100644 --- a/target-mips/dsp_helper.c +++ b/target-mips/dsp_helper.c @@ -19,6 +19,7 @@ #include "cpu.h" #include "helper.h" +#include "qemu/bitops.h" /* As the byte ordering doesn't matter, i.e. all columns are treated identically, these unions can be used directly. */ @@ -44,7 +45,8 @@ typedef union { /*** MIPS DSP internal functions begin ***/ #define MIPSDSP_ABS(x) (((x) >= 0) ? x : -x) -#define MIPSDSP_OVERFLOW(a, b, c, d) (!(!((a ^ b ^ -1) & (a ^ c) & d))) +#define MIPSDSP_OVERFLOW_ADD(a, b, c, d) (~(a ^ b) & (a ^ c) & d) +#define MIPSDSP_OVERFLOW_SUB(a, b, c, d) ((a ^ b) & (a ^ c) & d) static inline void set_DSPControl_overflow_flag(uint32_t flag, int position, CPUMIPSState *env) @@ -52,9 +54,10 @@ static inline void set_DSPControl_overflow_flag(uint32_t flag, int position, env->active_tc.DSPControl |= (target_ulong)flag << position; } -static inline void set_DSPControl_carryflag(uint32_t flag, CPUMIPSState *env) +static inline void set_DSPControl_carryflag(bool flag, CPUMIPSState *env) { - env->active_tc.DSPControl |= (target_ulong)flag << 13; + env->active_tc.DSPControl &= ~(1 << 13); + env->active_tc.DSPControl |= flag << 13; } static inline uint32_t get_DSPControl_carryflag(CPUMIPSState *env) @@ -89,10 +92,10 @@ static inline void set_DSPControl_pos(uint32_t pos, CPUMIPSState *env) dspc = env->active_tc.DSPControl; #ifndef TARGET_MIPS64 dspc = dspc & 0xFFFFFFC0; - dspc |= pos; + dspc |= (pos & 0x3F); #else dspc = dspc & 0xFFFFFF80; - dspc |= pos; + dspc |= (pos & 0x7F); #endif env->active_tc.DSPControl = dspc; } @@ -142,7 +145,7 @@ static inline int16_t mipsdsp_add_i16(int16_t a, int16_t b, CPUMIPSState *env) tempI = a + b; - if (MIPSDSP_OVERFLOW(a, b, tempI, 0x8000)) { + if (MIPSDSP_OVERFLOW_ADD(a, b, tempI, 0x8000)) { set_DSPControl_overflow_flag(1, 20, env); } @@ -156,7 +159,7 @@ static inline int16_t mipsdsp_sat_add_i16(int16_t a, int16_t b, tempS = a + b; - if (MIPSDSP_OVERFLOW(a, b, tempS, 0x8000)) { + if (MIPSDSP_OVERFLOW_ADD(a, b, tempS, 0x8000)) { if (a > 0) { tempS = 0x7FFF; } else { @@ -175,7 +178,7 @@ static inline int32_t mipsdsp_sat_add_i32(int32_t a, int32_t b, tempI = a + b; - if (MIPSDSP_OVERFLOW(a, b, tempI, 0x80000000)) { + if (MIPSDSP_OVERFLOW_ADD(a, b, tempI, 0x80000000)) { if (a > 0) { tempI = 0x7FFFFFFF; } else { @@ -268,18 +271,6 @@ static inline int32_t mipsdsp_sat32_acc_q31(int32_t acc, int32_t a, temp31 = (temp_sum >> 31) & 0x01; result = temp_sum & 0xFFFFFFFF; - /* FIXME - This sat function may wrong, because user manual wrote: - temp127..0 ← temp + ( (signA) || a31..0 - if ( temp32 ≠ temp31 ) then - if ( temp32 = 0 ) then - temp31..0 ← 0x80000000 - else - temp31..0 ← 0x7FFFFFFF - endif - DSPControlouflag:16+acc ← 1 - endif - */ if (temp32 != temp31) { if (temp32 == 0) { result = 0x7FFFFFFF; @@ -516,13 +507,8 @@ static inline void mipsdsp_rndrashift_short_acc(int64_t *p, acc = ((int64_t)env->active_tc.HI[ac] << 32) | ((int64_t)env->active_tc.LO[ac] & 0xFFFFFFFF); - if (shift == 0) { - p[0] = acc << 1; - p[1] = (acc >> 63) & 0x01; - } else { - p[0] = acc >> (shift - 1); - p[1] = 0; - } + p[0] = (shift == 0) ? (acc << 1) : (acc >> (shift - 1)); + p[1] = (acc >> 63) & 0x01; } /* 128 bits long. p[0] is LO, p[1] is HI */ @@ -582,7 +568,7 @@ static inline int32_t mipsdsp_mul_q15_q15(int32_t ac, uint16_t a, uint16_t b, temp = 0x7FFFFFFF; set_DSPControl_overflow_flag(1, 16 + ac, env); } else { - temp = ((uint32_t)a * (uint32_t)b) << 1; + temp = ((int16_t)a * (int16_t)b) << 1; } return temp; @@ -652,7 +638,7 @@ static inline int32_t mipsdsp_sat16_mul_q15_q15(uint16_t a, uint16_t b, temp = 0x7FFF0000; set_DSPControl_overflow_flag(1, 21, env); } else { - temp = ((uint32_t)a * (uint32_t)b); + temp = (int16_t)a * (int16_t)b; temp = temp << 1; } @@ -698,49 +684,31 @@ static inline uint8_t mipsdsp_sat8_reduce_precision(uint16_t a, static inline uint8_t mipsdsp_lshift8(uint8_t a, uint8_t s, CPUMIPSState *env) { - uint8_t sign; uint8_t discard; - if (s == 0) { - return a; - } else { - sign = (a >> 7) & 0x01; - if (sign != 0) { - discard = (((0x01 << (8 - s)) - 1) << s) | - ((a >> (6 - (s - 1))) & ((0x01 << s) - 1)); - } else { - discard = a >> (6 - (s - 1)); - } + if (s != 0) { + discard = a >> (8 - s); if (discard != 0x00) { set_DSPControl_overflow_flag(1, 22, env); } - return a << s; } + return a << s; } static inline uint16_t mipsdsp_lshift16(uint16_t a, uint8_t s, CPUMIPSState *env) { - uint8_t sign; uint16_t discard; - if (s == 0) { - return a; - } else { - sign = (a >> 15) & 0x01; - if (sign != 0) { - discard = (((0x01 << (16 - s)) - 1) << s) | - ((a >> (14 - (s - 1))) & ((0x01 << s) - 1)); - } else { - discard = a >> (14 - (s - 1)); - } + if (s != 0) { + discard = (int16_t)a >> (15 - s); if ((discard != 0x0000) && (discard != 0xFFFF)) { set_DSPControl_overflow_flag(1, 22, env); } - return a << s; } + return a << s; } @@ -858,7 +826,7 @@ static inline uint16_t mipsdsp_sub_i16(int16_t a, int16_t b, CPUMIPSState *env) int16_t temp; temp = a - b; - if (MIPSDSP_OVERFLOW(a, -b, temp, 0x8000)) { + if (MIPSDSP_OVERFLOW_SUB(a, b, temp, 0x8000)) { set_DSPControl_overflow_flag(1, 20, env); } @@ -871,8 +839,8 @@ static inline uint16_t mipsdsp_sat16_sub(int16_t a, int16_t b, int16_t temp; temp = a - b; - if (MIPSDSP_OVERFLOW(a, -b, temp, 0x8000)) { - if (a > 0) { + if (MIPSDSP_OVERFLOW_SUB(a, b, temp, 0x8000)) { + if (a >= 0) { temp = 0x7FFF; } else { temp = 0x8000; @@ -889,8 +857,8 @@ static inline uint32_t mipsdsp_sat32_sub(int32_t a, int32_t b, int32_t temp; temp = a - b; - if (MIPSDSP_OVERFLOW(a, -b, temp, 0x80000000)) { - if (a > 0) { + if (MIPSDSP_OVERFLOW_SUB(a, b, temp, 0x80000000)) { + if (a >= 0) { temp = 0x7FFFFFFF; } else { temp = 0x80000000; @@ -1004,7 +972,7 @@ static inline uint32_t mipsdsp_sub32(int32_t a, int32_t b, CPUMIPSState *env) int32_t temp; temp = a - b; - if (MIPSDSP_OVERFLOW(a, -b, temp, 0x80000000)) { + if (MIPSDSP_OVERFLOW_SUB(a, b, temp, 0x80000000)) { set_DSPControl_overflow_flag(1, 20, env); } @@ -1017,7 +985,7 @@ static inline int32_t mipsdsp_add_i32(int32_t a, int32_t b, CPUMIPSState *env) temp = a + b; - if (MIPSDSP_OVERFLOW(a, b, temp, 0x80000000)) { + if (MIPSDSP_OVERFLOW_ADD(a, b, temp, 0x80000000)) { set_DSPControl_overflow_flag(1, 20, env); } @@ -1300,7 +1268,7 @@ SUBUH_QB(subuh_r, 1); target_ulong helper_addsc(target_ulong rs, target_ulong rt, CPUMIPSState *env) { uint64_t temp, tempRs, tempRt; - int32_t flag; + bool flag; tempRs = (uint64_t)rs & MIPSDSP_LLO; tempRt = (uint64_t)rt & MIPSDSP_LLO; @@ -2488,37 +2456,42 @@ DP_QH(dpsq_s_w_qh, 0, 1); #endif #define DP_L_W(name, is_add) \ -void helper_##name(uint32_t ac, target_ulong rs, target_ulong rt, \ - CPUMIPSState *env) \ -{ \ - int32_t temp63; \ - int64_t dotp, acc; \ - uint64_t temp; \ - \ - dotp = mipsdsp_mul_q31_q31(ac, rs, rt, env); \ - acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \ - ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO); \ - if (!is_add) { \ - dotp = -dotp; \ - } \ - \ - temp = acc + dotp; \ - if (MIPSDSP_OVERFLOW((uint64_t)acc, (uint64_t)dotp, temp, \ - (0x01ull << 63))) { \ - temp63 = (temp >> 63) & 0x01; \ - if (temp63 == 1) { \ - temp = (0x01ull << 63) - 1; \ - } else { \ - temp = 0x01ull << 63; \ - } \ - \ - set_DSPControl_overflow_flag(1, 16 + ac, env); \ - } \ - \ - env->active_tc.HI[ac] = (target_long)(int32_t) \ - ((temp & MIPSDSP_LHI) >> 32); \ - env->active_tc.LO[ac] = (target_long)(int32_t) \ - (temp & MIPSDSP_LLO); \ +void helper_##name(uint32_t ac, target_ulong rs, target_ulong rt, \ + CPUMIPSState *env) \ +{ \ + int32_t temp63; \ + int64_t dotp, acc; \ + uint64_t temp; \ + bool overflow; \ + \ + dotp = mipsdsp_mul_q31_q31(ac, rs, rt, env); \ + acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \ + ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO); \ + if (is_add) { \ + temp = acc + dotp; \ + overflow = MIPSDSP_OVERFLOW_ADD((uint64_t)acc, (uint64_t)dotp, \ + temp, (0x01ull << 63)); \ + } else { \ + temp = acc - dotp; \ + overflow = MIPSDSP_OVERFLOW_SUB((uint64_t)acc, (uint64_t)dotp, \ + temp, (0x01ull << 63)); \ + } \ + \ + if (overflow) { \ + temp63 = (temp >> 63) & 0x01; \ + if (temp63 == 1) { \ + temp = (0x01ull << 63) - 1; \ + } else { \ + temp = 0x01ull << 63; \ + } \ + \ + set_DSPControl_overflow_flag(1, 16 + ac, env); \ + } \ + \ + env->active_tc.HI[ac] = (target_long)(int32_t) \ + ((temp & MIPSDSP_LHI) >> 32); \ + env->active_tc.LO[ac] = (target_long)(int32_t) \ + (temp & MIPSDSP_LLO); \ } DP_L_W(dpaq_sa_l_w, 1); @@ -2689,7 +2662,7 @@ MAQ_SA_W(maq_sa_w_phr, 0); target_ulong helper_##name(target_ulong rs, target_ulong rt, \ CPUMIPSState *env) \ { \ - uint32_t rs_t, rt_t; \ + int32_t rs_t, rt_t; \ int32_t tempI; \ int64_t tempL; \ \ @@ -2950,7 +2923,7 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong rs, \ return rt; \ } \ \ - filter = ((int32_t)0x01 << size) - 1; \ + filter = ((int64_t)0x01 << size) - 1; \ filter = filter << pos; \ temprs = (rs << pos) & filter; \ temprt = rt & ~filter; \ @@ -2959,7 +2932,7 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong rs, \ return (target_long)(ret_type)temp; \ } -BIT_INSV(insv, 0x1F, 0x1F, int32_t); +BIT_INSV(insv, 0x1F, 0x3F, int32_t); #ifdef TARGET_MIPS64 BIT_INSV(dinsv, 0x7F, 0x3F, target_long); #endif @@ -3155,8 +3128,8 @@ target_ulong helper_extr_w(target_ulong ac, target_ulong shift, tempDL[1] += 1; } - if ((!(tempDL[1] == 0 && (tempDL[0] & MIPSDSP_LHI) == 0x00)) && - (!(tempDL[1] == 1 && (tempDL[0] & MIPSDSP_LHI) == MIPSDSP_LHI))) { + if (((tempDL[1] & 0x01) != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && + ((tempDL[1] & 0x01) != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { set_DSPControl_overflow_flag(1, 23, env); } @@ -3181,8 +3154,8 @@ target_ulong helper_extr_r_w(target_ulong ac, target_ulong shift, tempDL[1] += 1; } - if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && - (tempDL[1] != 1 && (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { + if (((tempDL[1] & 0x01) != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && + ((tempDL[1] & 0x01) != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { set_DSPControl_overflow_flag(1, 23, env); } @@ -3208,9 +3181,9 @@ target_ulong helper_extr_rs_w(target_ulong ac, target_ulong shift, } tempI = tempDL[0] >> 1; - if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && - (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { - temp64 = tempDL[1]; + if (((tempDL[1] & 0x01) != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && + ((tempDL[1] & 0x01) != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { + temp64 = tempDL[1] & 0x01; if (temp64 == 0) { tempI = 0x7FFFFFFF; } else { @@ -3444,8 +3417,7 @@ target_ulong helper_extp(target_ulong ac, target_ulong size, CPUMIPSState *env) if (sub >= -1) { acc = ((uint64_t)env->active_tc.HI[ac] << 32) | ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO); - temp = (acc >> (start_pos - size)) & - (((uint32_t)0x01 << (size + 1)) - 1); + temp = (acc >> (start_pos - size)) & (~0U >> (31 - size)); set_DSPControl_efi(0, env); } else { set_DSPControl_efi(1, env); @@ -3469,10 +3441,9 @@ target_ulong helper_extpdp(target_ulong ac, target_ulong size, if (sub >= -1) { acc = ((uint64_t)env->active_tc.HI[ac] << 32) | ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO); - temp = (acc >> (start_pos - size)) & - (((uint32_t)0x01 << (size + 1)) - 1); + temp = extract64(acc, start_pos - size, size + 1); - set_DSPControl_pos(start_pos - (size + 1), env); + set_DSPControl_pos(sub, env); set_DSPControl_efi(0, env); } else { set_DSPControl_efi(1, env); @@ -3637,7 +3608,7 @@ void helper_dmthlip(target_ulong rs, target_ulong ac, CPUMIPSState *env) } #endif -void helper_wrdsp(target_ulong rs, target_ulong mask_num, CPUMIPSState *env) +void cpu_wrdsp(uint32_t rs, uint32_t mask_num, CPUMIPSState *env) { uint8_t mask[6]; uint8_t i; @@ -3703,7 +3674,12 @@ void helper_wrdsp(target_ulong rs, target_ulong mask_num, CPUMIPSState *env) env->active_tc.DSPControl = dsp; } -target_ulong helper_rddsp(target_ulong masknum, CPUMIPSState *env) +void helper_wrdsp(target_ulong rs, target_ulong mask_num, CPUMIPSState *env) +{ + return cpu_wrdsp(rs, mask_num, env); +} + +uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env) { uint8_t mask[6]; uint32_t ruler, i; @@ -3712,7 +3688,7 @@ target_ulong helper_rddsp(target_ulong masknum, CPUMIPSState *env) ruler = 0x01; for (i = 0; i < 6; i++) { - mask[i] = (masknum & ruler) >> i ; + mask[i] = (mask_num & ruler) >> i ; ruler = ruler << 1; } @@ -3754,6 +3730,11 @@ target_ulong helper_rddsp(target_ulong masknum, CPUMIPSState *env) return temp; } +target_ulong helper_rddsp(target_ulong mask_num, CPUMIPSState *env) +{ + return cpu_rddsp(mask_num, env); +} + #undef MIPSDSP_LHI #undef MIPSDSP_LLO diff --git a/target-mips/helper.c b/target-mips/helper.c index e877b8d..3a54acf 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -396,10 +396,11 @@ static void set_hflags_for_handler (CPUMIPSState *env) } #endif -void do_interrupt (CPUMIPSState *env) +void mips_cpu_do_interrupt(CPUState *cs) { + MIPSCPU *cpu = MIPS_CPU(cs); + CPUMIPSState *env = &cpu->env; #if !defined(CONFIG_USER_ONLY) - MIPSCPU *cpu = mips_env_get_cpu(env); target_ulong offset; int cause = -1; const char *name; diff --git a/target-mips/helper.h b/target-mips/helper.h index cd48738..ed75e2c 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -24,8 +24,6 @@ DEF_HELPER_FLAGS_1(clz, TCG_CALL_NO_RWG_SE, tl, tl) #ifdef TARGET_MIPS64 DEF_HELPER_FLAGS_1(dclo, TCG_CALL_NO_RWG_SE, tl, tl) DEF_HELPER_FLAGS_1(dclz, TCG_CALL_NO_RWG_SE, tl, tl) -DEF_HELPER_3(dmult, void, env, tl, tl) -DEF_HELPER_3(dmultu, void, env, tl, tl) #endif DEF_HELPER_3(muls, tl, env, tl, tl) diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 526f84f..3fa0d00 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -267,18 +267,6 @@ target_ulong helper_mulshiu(CPUMIPSState *env, target_ulong arg1, (uint64_t)(uint32_t)arg2); } -#ifdef TARGET_MIPS64 -void helper_dmult(CPUMIPSState *env, target_ulong arg1, target_ulong arg2) -{ - muls64(&(env->active_tc.LO[0]), &(env->active_tc.HI[0]), arg1, arg2); -} - -void helper_dmultu(CPUMIPSState *env, target_ulong arg1, target_ulong arg2) -{ - mulu64(&(env->active_tc.LO[0]), &(env->active_tc.HI[0]), arg1, arg2); -} -#endif - #ifndef CONFIG_USER_ONLY static inline hwaddr do_translate_address(CPUMIPSState *env, @@ -527,29 +515,30 @@ void helper_sdm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, /* SMP helpers. */ static bool mips_vpe_is_wfi(MIPSCPU *c) { + CPUState *cpu = CPU(c); CPUMIPSState *env = &c->env; /* If the VPE is halted but otherwise active, it means it's waiting for an interrupt. */ - return env->halted && mips_vpe_active(env); + return cpu->halted && mips_vpe_active(env); } -static inline void mips_vpe_wake(CPUMIPSState *c) +static inline void mips_vpe_wake(MIPSCPU *c) { /* Dont set ->halted = 0 directly, let it be done via cpu_has_work because there might be other conditions that state that c should be sleeping. */ - cpu_interrupt(c, CPU_INTERRUPT_WAKE); + cpu_interrupt(CPU(c), CPU_INTERRUPT_WAKE); } static inline void mips_vpe_sleep(MIPSCPU *cpu) { - CPUMIPSState *c = &cpu->env; + CPUState *cs = CPU(cpu); /* The VPE was shut off, really go to bed. Reset any old _WAKE requests. */ - c->halted = 1; - cpu_reset_interrupt(c, CPU_INTERRUPT_WAKE); + cs->halted = 1; + cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE); } static inline void mips_tc_wake(MIPSCPU *cpu, int tc) @@ -558,7 +547,7 @@ static inline void mips_tc_wake(MIPSCPU *cpu, int tc) /* FIXME: TC reschedule. */ if (mips_vpe_active(c) && !mips_vpe_is_wfi(cpu)) { - mips_vpe_wake(c); + mips_vpe_wake(cpu); } } @@ -1736,7 +1725,7 @@ target_ulong helper_evpe(CPUMIPSState *env) && !mips_vpe_is_wfi(other_cpu)) { /* Enable the VPE. */ other_cpu_env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP); - mips_vpe_wake(other_cpu_env); /* And wake it up. */ + mips_vpe_wake(other_cpu); /* And wake it up. */ } other_cpu_env = other_cpu_env->next_cpu; } while (other_cpu_env); @@ -2111,8 +2100,10 @@ void helper_pmon(CPUMIPSState *env, int function) void helper_wait(CPUMIPSState *env) { - env->halted = 1; - cpu_reset_interrupt(env, CPU_INTERRUPT_WAKE); + CPUState *cs = CPU(mips_env_get_cpu(env)); + + cs->halted = 1; + cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE); helper_raise_exception(env, EXCP_HLT); } diff --git a/target-mips/translate.c b/target-mips/translate.c index 3b77b53..0a53203 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -2582,10 +2582,9 @@ static void gen_shift(DisasContext *ctx, uint32_t opc, } /* Arithmetic on HI/LO registers */ -static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg) +static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) { const char *opn = "hilo"; - unsigned int acc; if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { /* Treat as NOP. */ @@ -2593,12 +2592,6 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg) return; } - if (opc == OPC_MFHI || opc == OPC_MFLO) { - acc = ((ctx->opcode) >> 21) & 0x03; - } else { - acc = ((ctx->opcode) >> 11) & 0x03; - } - if (acc != 0) { check_dsp(ctx); } @@ -2661,12 +2654,11 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg) MIPS_DEBUG("%s %s", opn, regnames[reg]); } -static void gen_muldiv (DisasContext *ctx, uint32_t opc, - int rs, int rt) +static void gen_muldiv(DisasContext *ctx, uint32_t opc, + int acc, int rs, int rt) { const char *opn = "mul/div"; TCGv t0, t1; - unsigned int acc; t0 = tcg_temp_new(); t1 = tcg_temp_new(); @@ -2674,6 +2666,10 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, gen_load_gpr(t0, rs); gen_load_gpr(t1, rt); + if (acc != 0) { + check_dsp(ctx); + } + switch (opc) { case OPC_DIV: { @@ -2688,10 +2684,10 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, tcg_gen_or_tl(t2, t2, t3); tcg_gen_movi_tl(t3, 0); tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); - tcg_gen_div_tl(cpu_LO[0], t0, t1); - tcg_gen_rem_tl(cpu_HI[0], t0, t1); - tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]); - tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]); + tcg_gen_div_tl(cpu_LO[acc], t0, t1); + tcg_gen_rem_tl(cpu_HI[acc], t0, t1); + tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); + tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); tcg_temp_free(t3); tcg_temp_free(t2); } @@ -2704,10 +2700,10 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, tcg_gen_ext32u_tl(t0, t0); tcg_gen_ext32u_tl(t1, t1); tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); - tcg_gen_divu_tl(cpu_LO[0], t0, t1); - tcg_gen_remu_tl(cpu_HI[0], t0, t1); - tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]); - tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]); + tcg_gen_divu_tl(cpu_LO[acc], t0, t1); + tcg_gen_remu_tl(cpu_HI[acc], t0, t1); + tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); + tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); tcg_temp_free(t3); tcg_temp_free(t2); } @@ -2715,47 +2711,29 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, break; case OPC_MULT: { - TCGv_i64 t2 = tcg_temp_new_i64(); - TCGv_i64 t3 = tcg_temp_new_i64(); - acc = ((ctx->opcode) >> 11) & 0x03; - if (acc != 0) { - check_dsp(ctx); - } - - tcg_gen_ext_tl_i64(t2, t0); - tcg_gen_ext_tl_i64(t3, t1); - tcg_gen_mul_i64(t2, t2, t3); - tcg_temp_free_i64(t3); - tcg_gen_trunc_i64_tl(t0, t2); - tcg_gen_shri_i64(t2, t2, 32); - tcg_gen_trunc_i64_tl(t1, t2); - tcg_temp_free_i64(t2); - tcg_gen_ext32s_tl(cpu_LO[acc], t0); - tcg_gen_ext32s_tl(cpu_HI[acc], t1); + TCGv_i32 t2 = tcg_temp_new_i32(); + TCGv_i32 t3 = tcg_temp_new_i32(); + tcg_gen_trunc_tl_i32(t2, t0); + tcg_gen_trunc_tl_i32(t3, t1); + tcg_gen_muls2_i32(t2, t3, t2, t3); + tcg_gen_ext_i32_tl(cpu_LO[acc], t2); + tcg_gen_ext_i32_tl(cpu_HI[acc], t3); + tcg_temp_free_i32(t2); + tcg_temp_free_i32(t3); } opn = "mult"; break; case OPC_MULTU: { - TCGv_i64 t2 = tcg_temp_new_i64(); - TCGv_i64 t3 = tcg_temp_new_i64(); - acc = ((ctx->opcode) >> 11) & 0x03; - if (acc != 0) { - check_dsp(ctx); - } - - tcg_gen_ext32u_tl(t0, t0); - tcg_gen_ext32u_tl(t1, t1); - tcg_gen_extu_tl_i64(t2, t0); - tcg_gen_extu_tl_i64(t3, t1); - tcg_gen_mul_i64(t2, t2, t3); - tcg_temp_free_i64(t3); - tcg_gen_trunc_i64_tl(t0, t2); - tcg_gen_shri_i64(t2, t2, 32); - tcg_gen_trunc_i64_tl(t1, t2); - tcg_temp_free_i64(t2); - tcg_gen_ext32s_tl(cpu_LO[acc], t0); - tcg_gen_ext32s_tl(cpu_HI[acc], t1); + TCGv_i32 t2 = tcg_temp_new_i32(); + TCGv_i32 t3 = tcg_temp_new_i32(); + tcg_gen_trunc_tl_i32(t2, t0); + tcg_gen_trunc_tl_i32(t3, t1); + tcg_gen_mulu2_i32(t2, t3, t2, t3); + tcg_gen_ext_i32_tl(cpu_LO[acc], t2); + tcg_gen_ext_i32_tl(cpu_HI[acc], t3); + tcg_temp_free_i32(t2); + tcg_temp_free_i32(t3); } opn = "multu"; break; @@ -2771,8 +2749,8 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, tcg_gen_or_tl(t2, t2, t3); tcg_gen_movi_tl(t3, 0); tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); - tcg_gen_div_tl(cpu_LO[0], t0, t1); - tcg_gen_rem_tl(cpu_HI[0], t0, t1); + tcg_gen_div_tl(cpu_LO[acc], t0, t1); + tcg_gen_rem_tl(cpu_HI[acc], t0, t1); tcg_temp_free(t3); tcg_temp_free(t2); } @@ -2783,19 +2761,19 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, TCGv t2 = tcg_const_tl(0); TCGv t3 = tcg_const_tl(1); tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); - tcg_gen_divu_i64(cpu_LO[0], t0, t1); - tcg_gen_remu_i64(cpu_HI[0], t0, t1); + tcg_gen_divu_i64(cpu_LO[acc], t0, t1); + tcg_gen_remu_i64(cpu_HI[acc], t0, t1); tcg_temp_free(t3); tcg_temp_free(t2); } opn = "ddivu"; break; case OPC_DMULT: - gen_helper_dmult(cpu_env, t0, t1); + tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); opn = "dmult"; break; case OPC_DMULTU: - gen_helper_dmultu(cpu_env, t0, t1); + tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); opn = "dmultu"; break; #endif @@ -2803,10 +2781,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, { TCGv_i64 t2 = tcg_temp_new_i64(); TCGv_i64 t3 = tcg_temp_new_i64(); - acc = ((ctx->opcode) >> 11) & 0x03; - if (acc != 0) { - check_dsp(ctx); - } tcg_gen_ext_tl_i64(t2, t0); tcg_gen_ext_tl_i64(t3, t1); @@ -2827,10 +2801,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, { TCGv_i64 t2 = tcg_temp_new_i64(); TCGv_i64 t3 = tcg_temp_new_i64(); - acc = ((ctx->opcode) >> 11) & 0x03; - if (acc != 0) { - check_dsp(ctx); - } tcg_gen_ext32u_tl(t0, t0); tcg_gen_ext32u_tl(t1, t1); @@ -2853,10 +2823,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, { TCGv_i64 t2 = tcg_temp_new_i64(); TCGv_i64 t3 = tcg_temp_new_i64(); - acc = ((ctx->opcode) >> 11) & 0x03; - if (acc != 0) { - check_dsp(ctx); - } tcg_gen_ext_tl_i64(t2, t0); tcg_gen_ext_tl_i64(t3, t1); @@ -2877,10 +2843,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, { TCGv_i64 t2 = tcg_temp_new_i64(); TCGv_i64 t3 = tcg_temp_new_i64(); - acc = ((ctx->opcode) >> 11) & 0x03; - if (acc != 0) { - check_dsp(ctx); - } tcg_gen_ext32u_tl(t0, t0); tcg_gen_ext32u_tl(t1, t1); @@ -10143,7 +10105,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, gen_logic(ctx, OPC_NOR, rx, ry, 0); break; case RR_MFHI: - gen_HILO(ctx, OPC_MFHI, rx); + gen_HILO(ctx, OPC_MFHI, 0, rx); break; case RR_CNVT: switch (cnvt_op) { @@ -10175,7 +10137,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, } break; case RR_MFLO: - gen_HILO(ctx, OPC_MFLO, rx); + gen_HILO(ctx, OPC_MFLO, 0, rx); break; #if defined (TARGET_MIPS64) case RR_DSRA: @@ -10196,33 +10158,33 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, break; #endif case RR_MULT: - gen_muldiv(ctx, OPC_MULT, rx, ry); + gen_muldiv(ctx, OPC_MULT, 0, rx, ry); break; case RR_MULTU: - gen_muldiv(ctx, OPC_MULTU, rx, ry); + gen_muldiv(ctx, OPC_MULTU, 0, rx, ry); break; case RR_DIV: - gen_muldiv(ctx, OPC_DIV, rx, ry); + gen_muldiv(ctx, OPC_DIV, 0, rx, ry); break; case RR_DIVU: - gen_muldiv(ctx, OPC_DIVU, rx, ry); + gen_muldiv(ctx, OPC_DIVU, 0, rx, ry); break; #if defined (TARGET_MIPS64) case RR_DMULT: check_mips_64(ctx); - gen_muldiv(ctx, OPC_DMULT, rx, ry); + gen_muldiv(ctx, OPC_DMULT, 0, rx, ry); break; case RR_DMULTU: check_mips_64(ctx); - gen_muldiv(ctx, OPC_DMULTU, rx, ry); + gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry); break; case RR_DDIV: check_mips_64(ctx); - gen_muldiv(ctx, OPC_DDIV, rx, ry); + gen_muldiv(ctx, OPC_DDIV, 0, rx, ry); break; case RR_DDIVU: check_mips_64(ctx); - gen_muldiv(ctx, OPC_DDIVU, rx, ry); + gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry); break; #endif default: @@ -10931,11 +10893,11 @@ static void gen_pool16c_insn(DisasContext *ctx, int *is_branch) break; case MFHI16 + 0: case MFHI16 + 1: - gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode)); + gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode)); break; case MFLO16 + 0: case MFLO16 + 1: - gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode)); + gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode)); break; case BREAK16: generate_exception(ctx, EXCP_BREAK); @@ -11133,30 +11095,34 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs, break; case MULT: mips32_op = OPC_MULT; - goto do_muldiv; + goto do_mul; case MULTU: mips32_op = OPC_MULTU; - goto do_muldiv; + goto do_mul; case DIV: mips32_op = OPC_DIV; - goto do_muldiv; + goto do_div; case DIVU: mips32_op = OPC_DIVU; - goto do_muldiv; + goto do_div; + do_div: + check_insn(ctx, ISA_MIPS32); + gen_muldiv(ctx, mips32_op, 0, rs, rt); + break; case MADD: mips32_op = OPC_MADD; - goto do_muldiv; + goto do_mul; case MADDU: mips32_op = OPC_MADDU; - goto do_muldiv; + goto do_mul; case MSUB: mips32_op = OPC_MSUB; - goto do_muldiv; + goto do_mul; case MSUBU: mips32_op = OPC_MSUBU; - do_muldiv: + do_mul: check_insn(ctx, ISA_MIPS32); - gen_muldiv(ctx, mips32_op, rs, rt); + gen_muldiv(ctx, mips32_op, (ctx->opcode >> 14) & 3, rs, rt); break; default: goto pool32axf_invalid; @@ -11293,18 +11259,18 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs, } break; case 0x35: - switch (minor) { + switch (minor & 3) { case MFHI32: - gen_HILO(ctx, OPC_MFHI, rs); + gen_HILO(ctx, OPC_MFHI, minor >> 2, rs); break; case MFLO32: - gen_HILO(ctx, OPC_MFLO, rs); + gen_HILO(ctx, OPC_MFLO, minor >> 2, rs); break; case MTHI32: - gen_HILO(ctx, OPC_MTHI, rs); + gen_HILO(ctx, OPC_MTHI, minor >> 2, rs); break; case MTLO32: - gen_HILO(ctx, OPC_MTLO, rs); + gen_HILO(ctx, OPC_MTLO, minor >> 2, rs); break; default: goto pool32axf_invalid; @@ -13434,6 +13400,7 @@ static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2, /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have * the same mask and op1. */ case OPC_MULT_G_2E: + check_dspr2(ctx); switch (op2) { case OPC_MUL_PH: gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); @@ -14477,13 +14444,19 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) case OPC_XOR: gen_logic(ctx, op1, rd, rs, rt); break; - case OPC_MULT ... OPC_DIVU: + case OPC_MULT: + case OPC_MULTU: if (sa) { check_insn(ctx, INSN_VR54XX); op1 = MASK_MUL_VR54XX(ctx->opcode); gen_mul_vr54xx(ctx, op1, rd, rs, rt); - } else - gen_muldiv(ctx, op1, rs, rt); + } else { + gen_muldiv(ctx, op1, rd & 3, rs, rt); + } + break; + case OPC_DIV: + case OPC_DIVU: + gen_muldiv(ctx, op1, 0, rs, rt); break; case OPC_JR ... OPC_JALR: gen_compute_branch(ctx, op1, 4, rs, rd, sa); @@ -14495,11 +14468,11 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) break; case OPC_MFHI: /* Move from HI/LO */ case OPC_MFLO: - gen_HILO(ctx, op1, rd); + gen_HILO(ctx, op1, rs & 3, rd); break; case OPC_MTHI: case OPC_MTLO: /* Move to HI/LO */ - gen_HILO(ctx, op1, rs); + gen_HILO(ctx, op1, rd & 3, rs); break; case OPC_PMON: /* Pmon entry point, also R4010 selsl */ #ifdef MIPS_STRICT_STANDARD @@ -14619,7 +14592,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) case OPC_DMULT ... OPC_DDIVU: check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); - gen_muldiv(ctx, op1, rs, rt); + gen_muldiv(ctx, op1, 0, rs, rt); break; #endif default: /* Invalid */ @@ -14634,7 +14607,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */ case OPC_MSUB ... OPC_MSUBU: check_insn(ctx, ISA_MIPS32); - gen_muldiv(ctx, op1, rs, rt); + gen_muldiv(ctx, op1, rd & 3, rs, rt); break; case OPC_MUL: gen_arith(ctx, op1, rd, rs, rt); @@ -15604,7 +15577,7 @@ gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb, if (max_insns == 0) max_insns = CF_COUNT_MASK; LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags); - gen_icount_start(); + gen_tb_start(); while (ctx.bstate == BS_NONE) { if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) { QTAILQ_FOREACH(bp, &env->breakpoints, entry) { @@ -15702,7 +15675,7 @@ gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb, } } done_generating: - gen_icount_end(tb, num_insns); + gen_tb_end(tb, num_insns); *tcg_ctx.gen_opc_ptr = INDEX_op_end; if (search_pc) { j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf; @@ -15836,7 +15809,7 @@ void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf, #endif } -static void mips_tcg_init(void) +void mips_tcg_init(void) { int i; static int inited; @@ -15915,9 +15888,9 @@ MIPSCPU *cpu_mips_init(const char *cpu_model) #endif fpu_init(env, def); mvp_init(env, def); - mips_tcg_init(); - cpu_reset(CPU(cpu)); - qemu_init_vcpu(env); + + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); + return cpu; } @@ -15972,6 +15945,14 @@ void cpu_state_reset(CPUMIPSState *env) #if defined(CONFIG_USER_ONLY) env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU); +# ifdef TARGET_MIPS64 + /* Enable 64-bit register mode. */ + env->CP0_Status |= (1 << CP0St_PX); +# endif +# ifdef TARGET_ABI_MIPSN64 + /* Enable 64-bit address mode. */ + env->CP0_Status |= (1 << CP0St_UX); +# endif /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR hardware registers. */ env->CP0_HWREna |= 0x0000000F; @@ -15981,6 +15962,10 @@ void cpu_state_reset(CPUMIPSState *env) if (env->CP0_Config3 & (1 << CP0C3_DSPP)) { env->CP0_Status |= (1 << CP0St_MX); } + /* Enable 64-bit FPU if the target cpu supports it. */ + if (env->active_fpu.fcr0 & (1 << FCR0_F64)) { + env->CP0_Status |= (1 << CP0St_FR); + } #else if (env->hflags & MIPS_HFLAG_BMASK) { /* If the exception was raised from a delay slot, @@ -16020,7 +16005,7 @@ void cpu_state_reset(CPUMIPSState *env) env->tcs[i].CP0_TCHalt = 1; } env->active_tc.CP0_TCHalt = 1; - env->halted = 1; + cs->halted = 1; if (cs->cpu_index == 0) { /* VPE0 starts up enabled. */ @@ -16028,7 +16013,7 @@ void cpu_state_reset(CPUMIPSState *env) env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA); /* TC0 starts up unhalted. */ - env->halted = 0; + cs->halted = 0; env->active_tc.CP0_TCHalt = 0; env->tcs[0].CP0_TCHalt = 0; /* With thread 0 active. */ |