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 | 581 | } |
| 582 | 582 | pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK; |
| 583 | 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 | 586 | return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base; |
| 587 | 587 | } |
| 588 | 588 | #endif |
| 589 | 589 | |
| 590 | - | |
| 591 | 590 | #ifdef USE_KQEMU |
| 592 | 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 | 568 | *(uint32_t *)ptr = tswapl(env->PC); |
| 569 | 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 | 586 | /* 32 FP registers, fsr, fir, fp. Not yet implemented. */ |
| 586 | 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 | 630 | env->PC = tswapl(*(uint32_t *)ptr); |
| 630 | 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 | 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 | 653 | #endif |
| 654 | + } | |
| 653 | 655 | } |
| 654 | 656 | #elif defined (TARGET_SH4) |
| 655 | 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 | 1838 | env->gpr[i] = regs->regs[i]; |
| 1839 | 1839 | } |
| 1840 | 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 | 1845 | #elif defined(TARGET_SH4) |
| 1846 | 1846 | { | ... | ... |
target-mips/cpu.h
| ... | ... | @@ -63,7 +63,6 @@ struct CPUMIPSState { |
| 63 | 63 | #endif |
| 64 | 64 | target_ulong HI, LO; |
| 65 | 65 | uint32_t DCR; /* ? */ |
| 66 | -#if defined(MIPS_USES_FPU) | |
| 67 | 66 | /* Floating point registers */ |
| 68 | 67 | fpr_t fpr[16]; |
| 69 | 68 | #define FPR(cpu, n) ((fpr_t*)&(cpu)->fpr[(n) / 2]) |
| ... | ... | @@ -97,8 +96,7 @@ struct CPUMIPSState { |
| 97 | 96 | #define FP_DIV0 8 |
| 98 | 97 | #define FP_INVALID 16 |
| 99 | 98 | #define FP_UNIMPLEMENTED 32 |
| 100 | - | |
| 101 | -#endif | |
| 99 | + | |
| 102 | 100 | #if defined(MIPS_USES_R4K_TLB) |
| 103 | 101 | tlb_t tlb[MIPS_TLB_MAX]; |
| 104 | 102 | uint32_t tlb_in_use; | ... | ... |
target-mips/exec.h
| ... | ... | @@ -115,12 +115,10 @@ void do_tlbwi (void); |
| 115 | 115 | void do_tlbwr (void); |
| 116 | 116 | void do_tlbp (void); |
| 117 | 117 | void do_tlbr (void); |
| 118 | -#ifdef MIPS_USES_FPU | |
| 119 | 118 | void dump_fpu(CPUState *env); |
| 120 | 119 | void fpu_dump_state(CPUState *env, FILE *f, |
| 121 | 120 | int (*fpu_fprintf)(FILE *f, const char *fmt, ...), |
| 122 | 121 | int flags); |
| 123 | -#endif | |
| 124 | 122 | void dump_sc (void); |
| 125 | 123 | void do_lwl_raw (uint32_t); |
| 126 | 124 | void do_lwr_raw (uint32_t); | ... | ... |
target-mips/mips-defs.h
| ... | ... | @@ -45,19 +45,14 @@ |
| 45 | 45 | 2-way Icache, 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache, |
| 46 | 46 | no coprocessor2 attached, no MDMX support attached, |
| 47 | 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 | 50 | ((1 << CP0C1_M) | ((MIPS_TLB_NB - 1) << CP0C1_MMU) | \ |
| 52 | 51 | (0x0 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x1 << CP0C1_IA) | \ |
| 53 | 52 | (0x0 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x1 << CP0C1_DA) | \ |
| 54 | 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 | 56 | /* Have config3, no tertiary/secondary caches implemented */ |
| 62 | 57 | #define MIPS_CONFIG2 \ |
| 63 | 58 | ((1 << CP0C2_M)) | ... | ... |
target-mips/op.c
| ... | ... | @@ -144,8 +144,6 @@ CALL_FROM_TB2(func, arg0, arg1); |
| 144 | 144 | #include "op_template.c" |
| 145 | 145 | #undef TN |
| 146 | 146 | |
| 147 | -#ifdef MIPS_USES_FPU | |
| 148 | - | |
| 149 | 147 | #define SFREG 0 |
| 150 | 148 | #define DFREG 0 |
| 151 | 149 | #include "fop_template.c" |
| ... | ... | @@ -279,8 +277,6 @@ CALL_FROM_TB2(func, arg0, arg1); |
| 279 | 277 | #include "fop_template.c" |
| 280 | 278 | #undef FTN |
| 281 | 279 | |
| 282 | -#endif | |
| 283 | - | |
| 284 | 280 | void op_dup_T0 (void) |
| 285 | 281 | { |
| 286 | 282 | T2 = T0; |
| ... | ... | @@ -924,7 +920,6 @@ void op_movz (void) |
| 924 | 920 | RETURN(); |
| 925 | 921 | } |
| 926 | 922 | |
| 927 | -#ifdef MIPS_USES_FPU | |
| 928 | 923 | void op_movf (void) |
| 929 | 924 | { |
| 930 | 925 | if (!(env->fcr31 & PARAM1)) |
| ... | ... | @@ -938,7 +933,6 @@ void op_movt (void) |
| 938 | 933 | env->gpr[PARAM2] = env->gpr[PARAM3]; |
| 939 | 934 | RETURN(); |
| 940 | 935 | } |
| 941 | -#endif | |
| 942 | 936 | |
| 943 | 937 | /* Tests */ |
| 944 | 938 | #define OP_COND(name, cond) \ |
| ... | ... | @@ -1645,8 +1639,6 @@ void op_dmtc0_errorepc (void) |
| 1645 | 1639 | RETURN(); |
| 1646 | 1640 | } |
| 1647 | 1641 | |
| 1648 | -#ifdef MIPS_USES_FPU | |
| 1649 | - | |
| 1650 | 1642 | #if 0 |
| 1651 | 1643 | # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env) |
| 1652 | 1644 | #else |
| ... | ... | @@ -2001,7 +1993,6 @@ void op_bc1t (void) |
| 2001 | 1993 | DEBUG_FPU_STATE(); |
| 2002 | 1994 | RETURN(); |
| 2003 | 1995 | } |
| 2004 | -#endif /* MIPS_USES_FPU */ | |
| 2005 | 1996 | |
| 2006 | 1997 | #if defined(MIPS_USES_R4K_TLB) |
| 2007 | 1998 | void op_tlbwi (void) | ... | ... |
target-mips/op_helper.c
| ... | ... | @@ -331,7 +331,6 @@ void do_mtc0_status_irqraise_debug(void) |
| 331 | 331 | fprintf(logfile, "Raise pending IRQs\n"); |
| 332 | 332 | } |
| 333 | 333 | |
| 334 | -#ifdef MIPS_USES_FPU | |
| 335 | 334 | #include "softfloat.h" |
| 336 | 335 | |
| 337 | 336 | void fpu_handle_exception(void) |
| ... | ... | @@ -370,7 +369,6 @@ void fpu_handle_exception(void) |
| 370 | 369 | SET_FP_CAUSE(env->fcr31, 0); |
| 371 | 370 | #endif |
| 372 | 371 | } |
| 373 | -#endif /* MIPS_USES_FPU */ | |
| 374 | 372 | |
| 375 | 373 | /* TLB management */ |
| 376 | 374 | #if defined(MIPS_USES_R4K_TLB) | ... | ... |
target-mips/op_mem.c
| ... | ... | @@ -192,7 +192,6 @@ void glue(op_scd, MEMSUFFIX) (void) |
| 192 | 192 | } |
| 193 | 193 | #endif /* MIPS_HAS_MIPS64 */ |
| 194 | 194 | |
| 195 | -#ifdef MIPS_USES_FPU | |
| 196 | 195 | void glue(op_lwc1, MEMSUFFIX) (void) |
| 197 | 196 | { |
| 198 | 197 | WT0 = glue(ldl, MEMSUFFIX)(T0); |
| ... | ... | @@ -213,4 +212,3 @@ void glue(op_sdc1, MEMSUFFIX) (void) |
| 213 | 212 | glue(stq, MEMSUFFIX)(T0, DT0); |
| 214 | 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 | 391 | GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr); |
| 392 | 392 | GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr); |
| 393 | 393 | |
| 394 | -#ifdef MIPS_USES_FPU | |
| 395 | - | |
| 396 | 394 | static const char *fregnames[] = |
| 397 | 395 | { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", |
| 398 | 396 | "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", |
| ... | ... | @@ -476,8 +474,6 @@ static inline void gen_cmp_ ## fmt(int n) \ |
| 476 | 474 | FOP_CONDS(d) |
| 477 | 475 | FOP_CONDS(s) |
| 478 | 476 | |
| 479 | -#endif /* MIPS_USES_FPU */ | |
| 480 | - | |
| 481 | 477 | typedef struct DisasContext { |
| 482 | 478 | struct TranslationBlock *tb; |
| 483 | 479 | target_ulong pc, saved_pc; |
| ... | ... | @@ -640,12 +636,10 @@ OP_LD_TABLE(bu); |
| 640 | 636 | OP_ST_TABLE(b); |
| 641 | 637 | OP_LD_TABLE(l); |
| 642 | 638 | OP_ST_TABLE(c); |
| 643 | -#ifdef MIPS_USES_FPU | |
| 644 | 639 | OP_LD_TABLE(wc1); |
| 645 | 640 | OP_ST_TABLE(wc1); |
| 646 | 641 | OP_LD_TABLE(dc1); |
| 647 | 642 | OP_ST_TABLE(dc1); |
| 648 | -#endif | |
| 649 | 643 | |
| 650 | 644 | /* Load and store */ |
| 651 | 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 | 788 | MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]); |
| 795 | 789 | } |
| 796 | 790 | |
| 797 | -#ifdef MIPS_USES_FPU | |
| 798 | - | |
| 799 | 791 | /* Load and store */ |
| 800 | 792 | static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, |
| 801 | 793 | int base, int16_t offset) |
| ... | ... | @@ -843,8 +835,6 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, |
| 843 | 835 | MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]); |
| 844 | 836 | } |
| 845 | 837 | |
| 846 | -#endif /* MIPS_USES_FPU */ | |
| 847 | - | |
| 848 | 838 | /* Arithmetic with immediate operand */ |
| 849 | 839 | static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt, |
| 850 | 840 | int rs, int16_t imm) |
| ... | ... | @@ -4111,8 +4101,6 @@ static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd) |
| 4111 | 4101 | MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd); |
| 4112 | 4102 | } |
| 4113 | 4103 | |
| 4114 | -#ifdef MIPS_USES_FPU | |
| 4115 | - | |
| 4116 | 4104 | /* CP1 Branches (before delay slot) */ |
| 4117 | 4105 | static void gen_compute_branch1 (DisasContext *ctx, uint32_t op, |
| 4118 | 4106 | int32_t offset) |
| ... | ... | @@ -4531,8 +4519,6 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) |
| 4531 | 4519 | gen_op_movt(ccbit, rd, rs); |
| 4532 | 4520 | } |
| 4533 | 4521 | |
| 4534 | -#endif /* MIPS_USES_FPU */ | |
| 4535 | - | |
| 4536 | 4522 | /* ISA extensions (ASEs) */ |
| 4537 | 4523 | /* MIPS16 extension to MIPS32 */ |
| 4538 | 4524 | /* SmartMIPS extension to MIPS32 */ |
| ... | ... | @@ -4555,7 +4541,7 @@ static void gen_blikely(DisasContext *ctx) |
| 4555 | 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 | 4546 | int32_t offset; |
| 4561 | 4547 | int rs, rt, rd, sa; |
| ... | ... | @@ -4631,13 +4617,15 @@ static void decode_opc (DisasContext *ctx) |
| 4631 | 4617 | /* Treat as a noop. */ |
| 4632 | 4618 | break; |
| 4633 | 4619 | |
| 4634 | -#ifdef MIPS_USES_FPU | |
| 4635 | 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 | 4628 | break; |
| 4640 | -#endif | |
| 4641 | 4629 | |
| 4642 | 4630 | #ifdef MIPS_HAS_MIPS64 |
| 4643 | 4631 | /* MIPS64 specific opcodes */ |
| ... | ... | @@ -4868,47 +4856,47 @@ static void decode_opc (DisasContext *ctx) |
| 4868 | 4856 | case OPC_LDC1: |
| 4869 | 4857 | case OPC_SWC1: |
| 4870 | 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 | 4866 | break; |
| 4879 | 4867 | |
| 4880 | 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 | 4878 | #ifdef MIPS_HAS_MIPS64 |
| 4891 | - case OPC_DMFC1: | |
| 4892 | - case OPC_DMTC1: | |
| 4879 | + case OPC_DMFC1: | |
| 4880 | + case OPC_DMTC1: | |
| 4893 | 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 | 4900 | break; |
| 4913 | 4901 | |
| 4914 | 4902 | /* COP2. */ |
| ... | ... | @@ -4921,18 +4909,20 @@ static void decode_opc (DisasContext *ctx) |
| 4921 | 4909 | generate_exception_err(ctx, EXCP_CpU, 2); |
| 4922 | 4910 | break; |
| 4923 | 4911 | |
| 4924 | -#ifdef MIPS_USES_FPU | |
| 4925 | 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 | 4925 | break; |
| 4935 | -#endif | |
| 4936 | 4926 | |
| 4937 | 4927 | #ifdef MIPS_HAS_MIPS64 |
| 4938 | 4928 | /* MIPS64 opcodes */ |
| ... | ... | @@ -5079,7 +5069,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, |
| 5079 | 5069 | gen_opc_instr_start[lj] = 1; |
| 5080 | 5070 | } |
| 5081 | 5071 | ctx.opcode = ldl_code(ctx.pc); |
| 5082 | - decode_opc(&ctx); | |
| 5072 | + decode_opc(env, &ctx); | |
| 5083 | 5073 | ctx.pc += 4; |
| 5084 | 5074 | |
| 5085 | 5075 | if (env->singlestep_enabled) |
| ... | ... | @@ -5148,8 +5138,6 @@ int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) |
| 5148 | 5138 | return gen_intermediate_code_internal(env, tb, 1); |
| 5149 | 5139 | } |
| 5150 | 5140 | |
| 5151 | -#ifdef MIPS_USES_FPU | |
| 5152 | - | |
| 5153 | 5141 | void fpu_dump_state(CPUState *env, FILE *f, |
| 5154 | 5142 | int (*fpu_fprintf)(FILE *f, const char *fmt, ...), |
| 5155 | 5143 | int flags) |
| ... | ... | @@ -5184,8 +5172,6 @@ void dump_fpu (CPUState *env) |
| 5184 | 5172 | } |
| 5185 | 5173 | } |
| 5186 | 5174 | |
| 5187 | -#endif /* MIPS_USES_FPU */ | |
| 5188 | - | |
| 5189 | 5175 | #if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS) |
| 5190 | 5176 | /* Debug help: The architecture requires 32bit code to maintain proper |
| 5191 | 5177 | sign-extened values on 64bit machines. */ |
| ... | ... | @@ -5248,10 +5234,8 @@ void cpu_dump_state (CPUState *env, FILE *f, |
| 5248 | 5234 | c0_status, env->CP0_Cause, env->CP0_EPC); |
| 5249 | 5235 | cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n", |
| 5250 | 5236 | env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr); |
| 5251 | -#ifdef MIPS_USES_FPU | |
| 5252 | 5237 | if (c0_status & (1 << CP0St_CU1)) |
| 5253 | 5238 | fpu_dump_state(env, f, cpu_fprintf, flags); |
| 5254 | -#endif | |
| 5255 | 5239 | #if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS) |
| 5256 | 5240 | cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags); |
| 5257 | 5241 | #endif |
| ... | ... | @@ -5295,6 +5279,10 @@ void cpu_reset (CPUMIPSState *env) |
| 5295 | 5279 | env->CP0_EBase = 0x80000000; |
| 5296 | 5280 | env->CP0_Config0 = MIPS_CONFIG0; |
| 5297 | 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 | 5286 | env->CP0_Config2 = MIPS_CONFIG2; |
| 5299 | 5287 | env->CP0_Config3 = MIPS_CONFIG3; |
| 5300 | 5288 | env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); |
| ... | ... | @@ -5309,9 +5297,7 @@ void cpu_reset (CPUMIPSState *env) |
| 5309 | 5297 | env->hflags |= MIPS_HFLAG_UM; |
| 5310 | 5298 | env->user_mode_only = 1; |
| 5311 | 5299 | #endif |
| 5312 | -#ifdef MIPS_USES_FPU | |
| 5313 | - env->fcr0 = MIPS_FCR0; | |
| 5314 | -#endif | |
| 5300 | + env->fcr0 = MIPS_FCR0; | |
| 5315 | 5301 | /* XXX some guesswork here, values are CPU specific */ |
| 5316 | 5302 | env->SYNCI_Step = 16; |
| 5317 | 5303 | env->CCRes = 2; | ... | ... |