Commit 36d239587370c6ccfc53d7f6acc624ce5d61fe84
1 parent
54d43f70
MIPS FPU dynamic activation, part 1, by Herve Poussineau.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2463 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
10 changed files
with
95 additions
and
130 deletions
exec-all.h
@@ -581,13 +581,12 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) | @@ -581,13 +581,12 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) | ||
581 | } | 581 | } |
582 | pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK; | 582 | pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK; |
583 | if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { | 583 | if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { |
584 | - cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x%08lx\n", addr); | 584 | + cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr); |
585 | } | 585 | } |
586 | return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base; | 586 | return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base; |
587 | } | 587 | } |
588 | #endif | 588 | #endif |
589 | 589 | ||
590 | - | ||
591 | #ifdef USE_KQEMU | 590 | #ifdef USE_KQEMU |
592 | #define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG)) | 591 | #define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG)) |
593 | 592 |
gdbstub.c
@@ -568,19 +568,20 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) | @@ -568,19 +568,20 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) | ||
568 | *(uint32_t *)ptr = tswapl(env->PC); | 568 | *(uint32_t *)ptr = tswapl(env->PC); |
569 | ptr += 4; | 569 | ptr += 4; |
570 | 570 | ||
571 | -#ifdef MIPS_USES_FPU | ||
572 | - for (i = 0; i < 32; i++) | 571 | + if (env->CP0_Config1 & (1 << CP0C1_FP)) |
573 | { | 572 | { |
574 | - *(uint32_t *)ptr = tswapl(FPR_W (env, i)); | ||
575 | - ptr += 4; | ||
576 | - } | 573 | + for (i = 0; i < 32; i++) |
574 | + { | ||
575 | + *(uint32_t *)ptr = tswapl(FPR_W (env, i)); | ||
576 | + ptr += 4; | ||
577 | + } | ||
577 | 578 | ||
578 | - *(uint32_t *)ptr = tswapl(env->fcr31); | ||
579 | - ptr += 4; | 579 | + *(uint32_t *)ptr = tswapl(env->fcr31); |
580 | + ptr += 4; | ||
580 | 581 | ||
581 | - *(uint32_t *)ptr = tswapl(env->fcr0); | ||
582 | - ptr += 4; | ||
583 | -#endif | 582 | + *(uint32_t *)ptr = tswapl(env->fcr0); |
583 | + ptr += 4; | ||
584 | + } | ||
584 | 585 | ||
585 | /* 32 FP registers, fsr, fir, fp. Not yet implemented. */ | 586 | /* 32 FP registers, fsr, fir, fp. Not yet implemented. */ |
586 | /* what's 'fp' mean here? */ | 587 | /* what's 'fp' mean here? */ |
@@ -629,27 +630,28 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) | @@ -629,27 +630,28 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) | ||
629 | env->PC = tswapl(*(uint32_t *)ptr); | 630 | env->PC = tswapl(*(uint32_t *)ptr); |
630 | ptr += 4; | 631 | ptr += 4; |
631 | 632 | ||
632 | -#ifdef MIPS_USES_FPU | ||
633 | - for (i = 0; i < 32; i++) | 633 | + if (env->CP0_Config1 & (1 << CP0C1_FP)) |
634 | { | 634 | { |
635 | - FPR_W (env, i) = tswapl(*(uint32_t *)ptr); | ||
636 | - ptr += 4; | ||
637 | - } | 635 | + for (i = 0; i < 32; i++) |
636 | + { | ||
637 | + FPR_W (env, i) = tswapl(*(uint32_t *)ptr); | ||
638 | + ptr += 4; | ||
639 | + } | ||
638 | 640 | ||
639 | - env->fcr31 = tswapl(*(uint32_t *)ptr) & 0x0183FFFF; | ||
640 | - ptr += 4; | 641 | + env->fcr31 = tswapl(*(uint32_t *)ptr) & 0x0183FFFF; |
642 | + ptr += 4; | ||
641 | 643 | ||
642 | - env->fcr0 = tswapl(*(uint32_t *)ptr); | ||
643 | - ptr += 4; | 644 | + env->fcr0 = tswapl(*(uint32_t *)ptr); |
645 | + ptr += 4; | ||
644 | 646 | ||
645 | - /* set rounding mode */ | ||
646 | - RESTORE_ROUNDING_MODE; | 647 | + /* set rounding mode */ |
648 | + RESTORE_ROUNDING_MODE; | ||
647 | 649 | ||
648 | #ifndef CONFIG_SOFTFLOAT | 650 | #ifndef CONFIG_SOFTFLOAT |
649 | - /* no floating point exception for native float */ | ||
650 | - SET_FP_ENABLE(env->fcr31, 0); | ||
651 | -#endif | 651 | + /* no floating point exception for native float */ |
652 | + SET_FP_ENABLE(env->fcr31, 0); | ||
652 | #endif | 653 | #endif |
654 | + } | ||
653 | } | 655 | } |
654 | #elif defined (TARGET_SH4) | 656 | #elif defined (TARGET_SH4) |
655 | static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) | 657 | static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) |
linux-user/main.c
@@ -1838,9 +1838,9 @@ int main(int argc, char **argv) | @@ -1838,9 +1838,9 @@ int main(int argc, char **argv) | ||
1838 | env->gpr[i] = regs->regs[i]; | 1838 | env->gpr[i] = regs->regs[i]; |
1839 | } | 1839 | } |
1840 | env->PC = regs->cp0_epc; | 1840 | env->PC = regs->cp0_epc; |
1841 | -#ifdef MIPS_USES_FPU | ||
1842 | - env->CP0_Status |= (1 << CP0St_CU1); | ||
1843 | -#endif | 1841 | + if (env->CP0_Config1 & (1 << CP0C1_FP)) { |
1842 | + env->CP0_Status |= (1 << CP0St_CU1); | ||
1843 | + } | ||
1844 | } | 1844 | } |
1845 | #elif defined(TARGET_SH4) | 1845 | #elif defined(TARGET_SH4) |
1846 | { | 1846 | { |
target-mips/cpu.h
@@ -63,7 +63,6 @@ struct CPUMIPSState { | @@ -63,7 +63,6 @@ struct CPUMIPSState { | ||
63 | #endif | 63 | #endif |
64 | target_ulong HI, LO; | 64 | target_ulong HI, LO; |
65 | uint32_t DCR; /* ? */ | 65 | uint32_t DCR; /* ? */ |
66 | -#if defined(MIPS_USES_FPU) | ||
67 | /* Floating point registers */ | 66 | /* Floating point registers */ |
68 | fpr_t fpr[16]; | 67 | fpr_t fpr[16]; |
69 | #define FPR(cpu, n) ((fpr_t*)&(cpu)->fpr[(n) / 2]) | 68 | #define FPR(cpu, n) ((fpr_t*)&(cpu)->fpr[(n) / 2]) |
@@ -97,8 +96,7 @@ struct CPUMIPSState { | @@ -97,8 +96,7 @@ struct CPUMIPSState { | ||
97 | #define FP_DIV0 8 | 96 | #define FP_DIV0 8 |
98 | #define FP_INVALID 16 | 97 | #define FP_INVALID 16 |
99 | #define FP_UNIMPLEMENTED 32 | 98 | #define FP_UNIMPLEMENTED 32 |
100 | - | ||
101 | -#endif | 99 | + |
102 | #if defined(MIPS_USES_R4K_TLB) | 100 | #if defined(MIPS_USES_R4K_TLB) |
103 | tlb_t tlb[MIPS_TLB_MAX]; | 101 | tlb_t tlb[MIPS_TLB_MAX]; |
104 | uint32_t tlb_in_use; | 102 | uint32_t tlb_in_use; |
target-mips/exec.h
@@ -115,12 +115,10 @@ void do_tlbwi (void); | @@ -115,12 +115,10 @@ void do_tlbwi (void); | ||
115 | void do_tlbwr (void); | 115 | void do_tlbwr (void); |
116 | void do_tlbp (void); | 116 | void do_tlbp (void); |
117 | void do_tlbr (void); | 117 | void do_tlbr (void); |
118 | -#ifdef MIPS_USES_FPU | ||
119 | void dump_fpu(CPUState *env); | 118 | void dump_fpu(CPUState *env); |
120 | void fpu_dump_state(CPUState *env, FILE *f, | 119 | void fpu_dump_state(CPUState *env, FILE *f, |
121 | int (*fpu_fprintf)(FILE *f, const char *fmt, ...), | 120 | int (*fpu_fprintf)(FILE *f, const char *fmt, ...), |
122 | int flags); | 121 | int flags); |
123 | -#endif | ||
124 | void dump_sc (void); | 122 | void dump_sc (void); |
125 | void do_lwl_raw (uint32_t); | 123 | void do_lwl_raw (uint32_t); |
126 | void do_lwr_raw (uint32_t); | 124 | void do_lwr_raw (uint32_t); |
target-mips/mips-defs.h
@@ -45,19 +45,14 @@ | @@ -45,19 +45,14 @@ | ||
45 | 2-way Icache, 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache, | 45 | 2-way Icache, 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache, |
46 | no coprocessor2 attached, no MDMX support attached, | 46 | no coprocessor2 attached, no MDMX support attached, |
47 | no performance counters, watch registers present, | 47 | no performance counters, watch registers present, |
48 | - no code compression, EJTAG present, FPU enable bit depending on | ||
49 | - MIPS_USES_FPU */ | ||
50 | -#define MIPS_CONFIG1_1 \ | 48 | + no code compression, EJTAG present, no FPU */ |
49 | +#define MIPS_CONFIG1 \ | ||
51 | ((1 << CP0C1_M) | ((MIPS_TLB_NB - 1) << CP0C1_MMU) | \ | 50 | ((1 << CP0C1_M) | ((MIPS_TLB_NB - 1) << CP0C1_MMU) | \ |
52 | (0x0 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x1 << CP0C1_IA) | \ | 51 | (0x0 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x1 << CP0C1_IA) | \ |
53 | (0x0 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x1 << CP0C1_DA) | \ | 52 | (0x0 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x1 << CP0C1_DA) | \ |
54 | (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \ | 53 | (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \ |
55 | - (1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP)) | ||
56 | -#ifdef MIPS_USES_FPU | ||
57 | -#define MIPS_CONFIG1 (MIPS_CONFIG1_1 | (1 << CP0C1_FP)) | ||
58 | -#else | ||
59 | -#define MIPS_CONFIG1 (MIPS_CONFIG1_1 | (0 << CP0C1_FP)) | ||
60 | -#endif | 54 | + (1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP) | \ |
55 | + (0 << CP0C1_FP)) | ||
61 | /* Have config3, no tertiary/secondary caches implemented */ | 56 | /* Have config3, no tertiary/secondary caches implemented */ |
62 | #define MIPS_CONFIG2 \ | 57 | #define MIPS_CONFIG2 \ |
63 | ((1 << CP0C2_M)) | 58 | ((1 << CP0C2_M)) |
target-mips/op.c
@@ -144,8 +144,6 @@ CALL_FROM_TB2(func, arg0, arg1); | @@ -144,8 +144,6 @@ CALL_FROM_TB2(func, arg0, arg1); | ||
144 | #include "op_template.c" | 144 | #include "op_template.c" |
145 | #undef TN | 145 | #undef TN |
146 | 146 | ||
147 | -#ifdef MIPS_USES_FPU | ||
148 | - | ||
149 | #define SFREG 0 | 147 | #define SFREG 0 |
150 | #define DFREG 0 | 148 | #define DFREG 0 |
151 | #include "fop_template.c" | 149 | #include "fop_template.c" |
@@ -279,8 +277,6 @@ CALL_FROM_TB2(func, arg0, arg1); | @@ -279,8 +277,6 @@ CALL_FROM_TB2(func, arg0, arg1); | ||
279 | #include "fop_template.c" | 277 | #include "fop_template.c" |
280 | #undef FTN | 278 | #undef FTN |
281 | 279 | ||
282 | -#endif | ||
283 | - | ||
284 | void op_dup_T0 (void) | 280 | void op_dup_T0 (void) |
285 | { | 281 | { |
286 | T2 = T0; | 282 | T2 = T0; |
@@ -924,7 +920,6 @@ void op_movz (void) | @@ -924,7 +920,6 @@ void op_movz (void) | ||
924 | RETURN(); | 920 | RETURN(); |
925 | } | 921 | } |
926 | 922 | ||
927 | -#ifdef MIPS_USES_FPU | ||
928 | void op_movf (void) | 923 | void op_movf (void) |
929 | { | 924 | { |
930 | if (!(env->fcr31 & PARAM1)) | 925 | if (!(env->fcr31 & PARAM1)) |
@@ -938,7 +933,6 @@ void op_movt (void) | @@ -938,7 +933,6 @@ void op_movt (void) | ||
938 | env->gpr[PARAM2] = env->gpr[PARAM3]; | 933 | env->gpr[PARAM2] = env->gpr[PARAM3]; |
939 | RETURN(); | 934 | RETURN(); |
940 | } | 935 | } |
941 | -#endif | ||
942 | 936 | ||
943 | /* Tests */ | 937 | /* Tests */ |
944 | #define OP_COND(name, cond) \ | 938 | #define OP_COND(name, cond) \ |
@@ -1645,8 +1639,6 @@ void op_dmtc0_errorepc (void) | @@ -1645,8 +1639,6 @@ void op_dmtc0_errorepc (void) | ||
1645 | RETURN(); | 1639 | RETURN(); |
1646 | } | 1640 | } |
1647 | 1641 | ||
1648 | -#ifdef MIPS_USES_FPU | ||
1649 | - | ||
1650 | #if 0 | 1642 | #if 0 |
1651 | # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env) | 1643 | # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env) |
1652 | #else | 1644 | #else |
@@ -2001,7 +1993,6 @@ void op_bc1t (void) | @@ -2001,7 +1993,6 @@ void op_bc1t (void) | ||
2001 | DEBUG_FPU_STATE(); | 1993 | DEBUG_FPU_STATE(); |
2002 | RETURN(); | 1994 | RETURN(); |
2003 | } | 1995 | } |
2004 | -#endif /* MIPS_USES_FPU */ | ||
2005 | 1996 | ||
2006 | #if defined(MIPS_USES_R4K_TLB) | 1997 | #if defined(MIPS_USES_R4K_TLB) |
2007 | void op_tlbwi (void) | 1998 | void op_tlbwi (void) |
target-mips/op_helper.c
@@ -331,7 +331,6 @@ void do_mtc0_status_irqraise_debug(void) | @@ -331,7 +331,6 @@ void do_mtc0_status_irqraise_debug(void) | ||
331 | fprintf(logfile, "Raise pending IRQs\n"); | 331 | fprintf(logfile, "Raise pending IRQs\n"); |
332 | } | 332 | } |
333 | 333 | ||
334 | -#ifdef MIPS_USES_FPU | ||
335 | #include "softfloat.h" | 334 | #include "softfloat.h" |
336 | 335 | ||
337 | void fpu_handle_exception(void) | 336 | void fpu_handle_exception(void) |
@@ -370,7 +369,6 @@ void fpu_handle_exception(void) | @@ -370,7 +369,6 @@ void fpu_handle_exception(void) | ||
370 | SET_FP_CAUSE(env->fcr31, 0); | 369 | SET_FP_CAUSE(env->fcr31, 0); |
371 | #endif | 370 | #endif |
372 | } | 371 | } |
373 | -#endif /* MIPS_USES_FPU */ | ||
374 | 372 | ||
375 | /* TLB management */ | 373 | /* TLB management */ |
376 | #if defined(MIPS_USES_R4K_TLB) | 374 | #if defined(MIPS_USES_R4K_TLB) |
target-mips/op_mem.c
@@ -192,7 +192,6 @@ void glue(op_scd, MEMSUFFIX) (void) | @@ -192,7 +192,6 @@ void glue(op_scd, MEMSUFFIX) (void) | ||
192 | } | 192 | } |
193 | #endif /* MIPS_HAS_MIPS64 */ | 193 | #endif /* MIPS_HAS_MIPS64 */ |
194 | 194 | ||
195 | -#ifdef MIPS_USES_FPU | ||
196 | void glue(op_lwc1, MEMSUFFIX) (void) | 195 | void glue(op_lwc1, MEMSUFFIX) (void) |
197 | { | 196 | { |
198 | WT0 = glue(ldl, MEMSUFFIX)(T0); | 197 | WT0 = glue(ldl, MEMSUFFIX)(T0); |
@@ -213,4 +212,3 @@ void glue(op_sdc1, MEMSUFFIX) (void) | @@ -213,4 +212,3 @@ void glue(op_sdc1, MEMSUFFIX) (void) | ||
213 | glue(stq, MEMSUFFIX)(T0, DT0); | 212 | glue(stq, MEMSUFFIX)(T0, DT0); |
214 | RETURN(); | 213 | RETURN(); |
215 | } | 214 | } |
216 | -#endif |
target-mips/translate.c
@@ -391,8 +391,6 @@ GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr); | @@ -391,8 +391,6 @@ GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr); | ||
391 | GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr); | 391 | GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr); |
392 | GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr); | 392 | GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr); |
393 | 393 | ||
394 | -#ifdef MIPS_USES_FPU | ||
395 | - | ||
396 | static const char *fregnames[] = | 394 | static const char *fregnames[] = |
397 | { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", | 395 | { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", |
398 | "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", | 396 | "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", |
@@ -476,8 +474,6 @@ static inline void gen_cmp_ ## fmt(int n) \ | @@ -476,8 +474,6 @@ static inline void gen_cmp_ ## fmt(int n) \ | ||
476 | FOP_CONDS(d) | 474 | FOP_CONDS(d) |
477 | FOP_CONDS(s) | 475 | FOP_CONDS(s) |
478 | 476 | ||
479 | -#endif /* MIPS_USES_FPU */ | ||
480 | - | ||
481 | typedef struct DisasContext { | 477 | typedef struct DisasContext { |
482 | struct TranslationBlock *tb; | 478 | struct TranslationBlock *tb; |
483 | target_ulong pc, saved_pc; | 479 | target_ulong pc, saved_pc; |
@@ -640,12 +636,10 @@ OP_LD_TABLE(bu); | @@ -640,12 +636,10 @@ OP_LD_TABLE(bu); | ||
640 | OP_ST_TABLE(b); | 636 | OP_ST_TABLE(b); |
641 | OP_LD_TABLE(l); | 637 | OP_LD_TABLE(l); |
642 | OP_ST_TABLE(c); | 638 | OP_ST_TABLE(c); |
643 | -#ifdef MIPS_USES_FPU | ||
644 | OP_LD_TABLE(wc1); | 639 | OP_LD_TABLE(wc1); |
645 | OP_ST_TABLE(wc1); | 640 | OP_ST_TABLE(wc1); |
646 | OP_LD_TABLE(dc1); | 641 | OP_LD_TABLE(dc1); |
647 | OP_ST_TABLE(dc1); | 642 | OP_ST_TABLE(dc1); |
648 | -#endif | ||
649 | 643 | ||
650 | /* Load and store */ | 644 | /* Load and store */ |
651 | static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, | 645 | static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, |
@@ -794,8 +788,6 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, | @@ -794,8 +788,6 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, | ||
794 | MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]); | 788 | MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]); |
795 | } | 789 | } |
796 | 790 | ||
797 | -#ifdef MIPS_USES_FPU | ||
798 | - | ||
799 | /* Load and store */ | 791 | /* Load and store */ |
800 | static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, | 792 | static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, |
801 | int base, int16_t offset) | 793 | int base, int16_t offset) |
@@ -843,8 +835,6 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, | @@ -843,8 +835,6 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, | ||
843 | MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]); | 835 | MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]); |
844 | } | 836 | } |
845 | 837 | ||
846 | -#endif /* MIPS_USES_FPU */ | ||
847 | - | ||
848 | /* Arithmetic with immediate operand */ | 838 | /* Arithmetic with immediate operand */ |
849 | static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt, | 839 | static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt, |
850 | int rs, int16_t imm) | 840 | int rs, int16_t imm) |
@@ -4111,8 +4101,6 @@ static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd) | @@ -4111,8 +4101,6 @@ static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd) | ||
4111 | MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd); | 4101 | MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd); |
4112 | } | 4102 | } |
4113 | 4103 | ||
4114 | -#ifdef MIPS_USES_FPU | ||
4115 | - | ||
4116 | /* CP1 Branches (before delay slot) */ | 4104 | /* CP1 Branches (before delay slot) */ |
4117 | static void gen_compute_branch1 (DisasContext *ctx, uint32_t op, | 4105 | static void gen_compute_branch1 (DisasContext *ctx, uint32_t op, |
4118 | int32_t offset) | 4106 | int32_t offset) |
@@ -4531,8 +4519,6 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) | @@ -4531,8 +4519,6 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) | ||
4531 | gen_op_movt(ccbit, rd, rs); | 4519 | gen_op_movt(ccbit, rd, rs); |
4532 | } | 4520 | } |
4533 | 4521 | ||
4534 | -#endif /* MIPS_USES_FPU */ | ||
4535 | - | ||
4536 | /* ISA extensions (ASEs) */ | 4522 | /* ISA extensions (ASEs) */ |
4537 | /* MIPS16 extension to MIPS32 */ | 4523 | /* MIPS16 extension to MIPS32 */ |
4538 | /* SmartMIPS extension to MIPS32 */ | 4524 | /* SmartMIPS extension to MIPS32 */ |
@@ -4555,7 +4541,7 @@ static void gen_blikely(DisasContext *ctx) | @@ -4555,7 +4541,7 @@ static void gen_blikely(DisasContext *ctx) | ||
4555 | gen_set_label(l1); | 4541 | gen_set_label(l1); |
4556 | } | 4542 | } |
4557 | 4543 | ||
4558 | -static void decode_opc (DisasContext *ctx) | 4544 | +static void decode_opc (CPUState *env, DisasContext *ctx) |
4559 | { | 4545 | { |
4560 | int32_t offset; | 4546 | int32_t offset; |
4561 | int rs, rt, rd, sa; | 4547 | int rs, rt, rd, sa; |
@@ -4631,13 +4617,15 @@ static void decode_opc (DisasContext *ctx) | @@ -4631,13 +4617,15 @@ static void decode_opc (DisasContext *ctx) | ||
4631 | /* Treat as a noop. */ | 4617 | /* Treat as a noop. */ |
4632 | break; | 4618 | break; |
4633 | 4619 | ||
4634 | -#ifdef MIPS_USES_FPU | ||
4635 | case OPC_MOVCI: | 4620 | case OPC_MOVCI: |
4636 | - gen_op_cp1_enabled(); | ||
4637 | - gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, | ||
4638 | - (ctx->opcode >> 16) & 1); | 4621 | + if (env->CP0_Config1 & (1 << CP0C1_FP)) { |
4622 | + gen_op_cp1_enabled(); | ||
4623 | + gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, | ||
4624 | + (ctx->opcode >> 16) & 1); | ||
4625 | + } else { | ||
4626 | + generate_exception(ctx, EXCP_RI); | ||
4627 | + } | ||
4639 | break; | 4628 | break; |
4640 | -#endif | ||
4641 | 4629 | ||
4642 | #ifdef MIPS_HAS_MIPS64 | 4630 | #ifdef MIPS_HAS_MIPS64 |
4643 | /* MIPS64 specific opcodes */ | 4631 | /* MIPS64 specific opcodes */ |
@@ -4868,47 +4856,47 @@ static void decode_opc (DisasContext *ctx) | @@ -4868,47 +4856,47 @@ static void decode_opc (DisasContext *ctx) | ||
4868 | case OPC_LDC1: | 4856 | case OPC_LDC1: |
4869 | case OPC_SWC1: | 4857 | case OPC_SWC1: |
4870 | case OPC_SDC1: | 4858 | case OPC_SDC1: |
4871 | -#if defined(MIPS_USES_FPU) | ||
4872 | - save_cpu_state(ctx, 1); | ||
4873 | - gen_op_cp1_enabled(); | ||
4874 | - gen_flt_ldst(ctx, op, rt, rs, imm); | ||
4875 | -#else | ||
4876 | - generate_exception_err(ctx, EXCP_CpU, 1); | ||
4877 | -#endif | 4859 | + if (env->CP0_Config1 & (1 << CP0C1_FP)) { |
4860 | + save_cpu_state(ctx, 1); | ||
4861 | + gen_op_cp1_enabled(); | ||
4862 | + gen_flt_ldst(ctx, op, rt, rs, imm); | ||
4863 | + } else { | ||
4864 | + generate_exception_err(ctx, EXCP_CpU, 1); | ||
4865 | + } | ||
4878 | break; | 4866 | break; |
4879 | 4867 | ||
4880 | case OPC_CP1: | 4868 | case OPC_CP1: |
4881 | -#if defined(MIPS_USES_FPU) | ||
4882 | - save_cpu_state(ctx, 1); | ||
4883 | - gen_op_cp1_enabled(); | ||
4884 | - op1 = MASK_CP1(ctx->opcode); | ||
4885 | - switch (op1) { | ||
4886 | - case OPC_MFC1: | ||
4887 | - case OPC_CFC1: | ||
4888 | - case OPC_MTC1: | ||
4889 | - case OPC_CTC1: | 4869 | + if (env->CP0_Config1 & (1 << CP0C1_FP)) { |
4870 | + save_cpu_state(ctx, 1); | ||
4871 | + gen_op_cp1_enabled(); | ||
4872 | + op1 = MASK_CP1(ctx->opcode); | ||
4873 | + switch (op1) { | ||
4874 | + case OPC_MFC1: | ||
4875 | + case OPC_CFC1: | ||
4876 | + case OPC_MTC1: | ||
4877 | + case OPC_CTC1: | ||
4890 | #ifdef MIPS_HAS_MIPS64 | 4878 | #ifdef MIPS_HAS_MIPS64 |
4891 | - case OPC_DMFC1: | ||
4892 | - case OPC_DMTC1: | 4879 | + case OPC_DMFC1: |
4880 | + case OPC_DMTC1: | ||
4893 | #endif | 4881 | #endif |
4894 | - gen_cp1(ctx, op1, rt, rd); | ||
4895 | - break; | ||
4896 | - case OPC_BC1: | ||
4897 | - gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2); | ||
4898 | - return; | ||
4899 | - case OPC_S_FMT: | ||
4900 | - case OPC_D_FMT: | ||
4901 | - case OPC_W_FMT: | ||
4902 | - case OPC_L_FMT: | ||
4903 | - gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa); | ||
4904 | - break; | ||
4905 | - default: | ||
4906 | - generate_exception_err(ctx, EXCP_RI, 1); | ||
4907 | - break; | 4882 | + gen_cp1(ctx, op1, rt, rd); |
4883 | + break; | ||
4884 | + case OPC_BC1: | ||
4885 | + gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2); | ||
4886 | + return; | ||
4887 | + case OPC_S_FMT: | ||
4888 | + case OPC_D_FMT: | ||
4889 | + case OPC_W_FMT: | ||
4890 | + case OPC_L_FMT: | ||
4891 | + gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa); | ||
4892 | + break; | ||
4893 | + default: | ||
4894 | + generate_exception_err(ctx, EXCP_RI, 1); | ||
4895 | + break; | ||
4896 | + } | ||
4897 | + } else { | ||
4898 | + generate_exception_err(ctx, EXCP_CpU, 1); | ||
4908 | } | 4899 | } |
4909 | -#else | ||
4910 | - generate_exception_err(ctx, EXCP_CpU, 1); | ||
4911 | -#endif | ||
4912 | break; | 4900 | break; |
4913 | 4901 | ||
4914 | /* COP2. */ | 4902 | /* COP2. */ |
@@ -4921,18 +4909,20 @@ static void decode_opc (DisasContext *ctx) | @@ -4921,18 +4909,20 @@ static void decode_opc (DisasContext *ctx) | ||
4921 | generate_exception_err(ctx, EXCP_CpU, 2); | 4909 | generate_exception_err(ctx, EXCP_CpU, 2); |
4922 | break; | 4910 | break; |
4923 | 4911 | ||
4924 | -#ifdef MIPS_USES_FPU | ||
4925 | case OPC_CP3: | 4912 | case OPC_CP3: |
4926 | - gen_op_cp1_enabled(); | ||
4927 | - op1 = MASK_CP3(ctx->opcode); | ||
4928 | - switch (op1) { | ||
4929 | - /* Not implemented */ | ||
4930 | - default: | ||
4931 | - generate_exception_err(ctx, EXCP_RI, 1); | ||
4932 | - break; | 4913 | + if (env->CP0_Config1 & (1 << CP0C1_FP)) { |
4914 | + gen_op_cp1_enabled(); | ||
4915 | + op1 = MASK_CP3(ctx->opcode); | ||
4916 | + switch (op1) { | ||
4917 | + /* Not implemented */ | ||
4918 | + default: | ||
4919 | + generate_exception_err(ctx, EXCP_RI, 1); | ||
4920 | + break; | ||
4921 | + } | ||
4922 | + } else { | ||
4923 | + generate_exception(ctx, EXCP_RI); | ||
4933 | } | 4924 | } |
4934 | break; | 4925 | break; |
4935 | -#endif | ||
4936 | 4926 | ||
4937 | #ifdef MIPS_HAS_MIPS64 | 4927 | #ifdef MIPS_HAS_MIPS64 |
4938 | /* MIPS64 opcodes */ | 4928 | /* MIPS64 opcodes */ |
@@ -5079,7 +5069,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | @@ -5079,7 +5069,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | ||
5079 | gen_opc_instr_start[lj] = 1; | 5069 | gen_opc_instr_start[lj] = 1; |
5080 | } | 5070 | } |
5081 | ctx.opcode = ldl_code(ctx.pc); | 5071 | ctx.opcode = ldl_code(ctx.pc); |
5082 | - decode_opc(&ctx); | 5072 | + decode_opc(env, &ctx); |
5083 | ctx.pc += 4; | 5073 | ctx.pc += 4; |
5084 | 5074 | ||
5085 | if (env->singlestep_enabled) | 5075 | if (env->singlestep_enabled) |
@@ -5148,8 +5138,6 @@ int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) | @@ -5148,8 +5138,6 @@ int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) | ||
5148 | return gen_intermediate_code_internal(env, tb, 1); | 5138 | return gen_intermediate_code_internal(env, tb, 1); |
5149 | } | 5139 | } |
5150 | 5140 | ||
5151 | -#ifdef MIPS_USES_FPU | ||
5152 | - | ||
5153 | void fpu_dump_state(CPUState *env, FILE *f, | 5141 | void fpu_dump_state(CPUState *env, FILE *f, |
5154 | int (*fpu_fprintf)(FILE *f, const char *fmt, ...), | 5142 | int (*fpu_fprintf)(FILE *f, const char *fmt, ...), |
5155 | int flags) | 5143 | int flags) |
@@ -5184,8 +5172,6 @@ void dump_fpu (CPUState *env) | @@ -5184,8 +5172,6 @@ void dump_fpu (CPUState *env) | ||
5184 | } | 5172 | } |
5185 | } | 5173 | } |
5186 | 5174 | ||
5187 | -#endif /* MIPS_USES_FPU */ | ||
5188 | - | ||
5189 | #if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS) | 5175 | #if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS) |
5190 | /* Debug help: The architecture requires 32bit code to maintain proper | 5176 | /* Debug help: The architecture requires 32bit code to maintain proper |
5191 | sign-extened values on 64bit machines. */ | 5177 | sign-extened values on 64bit machines. */ |
@@ -5248,10 +5234,8 @@ void cpu_dump_state (CPUState *env, FILE *f, | @@ -5248,10 +5234,8 @@ void cpu_dump_state (CPUState *env, FILE *f, | ||
5248 | c0_status, env->CP0_Cause, env->CP0_EPC); | 5234 | c0_status, env->CP0_Cause, env->CP0_EPC); |
5249 | cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n", | 5235 | cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n", |
5250 | env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr); | 5236 | env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr); |
5251 | -#ifdef MIPS_USES_FPU | ||
5252 | if (c0_status & (1 << CP0St_CU1)) | 5237 | if (c0_status & (1 << CP0St_CU1)) |
5253 | fpu_dump_state(env, f, cpu_fprintf, flags); | 5238 | fpu_dump_state(env, f, cpu_fprintf, flags); |
5254 | -#endif | ||
5255 | #if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS) | 5239 | #if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS) |
5256 | cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags); | 5240 | cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags); |
5257 | #endif | 5241 | #endif |
@@ -5295,6 +5279,10 @@ void cpu_reset (CPUMIPSState *env) | @@ -5295,6 +5279,10 @@ void cpu_reset (CPUMIPSState *env) | ||
5295 | env->CP0_EBase = 0x80000000; | 5279 | env->CP0_EBase = 0x80000000; |
5296 | env->CP0_Config0 = MIPS_CONFIG0; | 5280 | env->CP0_Config0 = MIPS_CONFIG0; |
5297 | env->CP0_Config1 = MIPS_CONFIG1; | 5281 | env->CP0_Config1 = MIPS_CONFIG1; |
5282 | +#ifdef MIPS_USES_FPU | ||
5283 | + /* basic FPU register support */ | ||
5284 | + env->CP0_Config1 |= (1 << CP0C1_FP); | ||
5285 | +#endif | ||
5298 | env->CP0_Config2 = MIPS_CONFIG2; | 5286 | env->CP0_Config2 = MIPS_CONFIG2; |
5299 | env->CP0_Config3 = MIPS_CONFIG3; | 5287 | env->CP0_Config3 = MIPS_CONFIG3; |
5300 | env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); | 5288 | env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); |
@@ -5309,9 +5297,7 @@ void cpu_reset (CPUMIPSState *env) | @@ -5309,9 +5297,7 @@ void cpu_reset (CPUMIPSState *env) | ||
5309 | env->hflags |= MIPS_HFLAG_UM; | 5297 | env->hflags |= MIPS_HFLAG_UM; |
5310 | env->user_mode_only = 1; | 5298 | env->user_mode_only = 1; |
5311 | #endif | 5299 | #endif |
5312 | -#ifdef MIPS_USES_FPU | ||
5313 | - env->fcr0 = MIPS_FCR0; | ||
5314 | -#endif | 5300 | + env->fcr0 = MIPS_FCR0; |
5315 | /* XXX some guesswork here, values are CPU specific */ | 5301 | /* XXX some guesswork here, values are CPU specific */ |
5316 | env->SYNCI_Step = 16; | 5302 | env->SYNCI_Step = 16; |
5317 | env->CCRes = 2; | 5303 | env->CCRes = 2; |