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; |