diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 17ac4ac875..2736614cd4 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -258,9 +258,11 @@ struct CPUMIPSState { #define MIPS_HFLAG_TMASK 0x007F #define MIPS_HFLAG_MODE 0x001F /* execution modes */ #define MIPS_HFLAG_UM 0x0001 /* user mode */ -#define MIPS_HFLAG_DM 0x0008 /* Debug mode */ -#define MIPS_HFLAG_SM 0x0010 /* Supervisor mode */ -#define MIPS_HFLAG_64 0x0020 /* 64-bit instructions enabled */ +#define MIPS_HFLAG_DM 0x0002 /* Debug mode */ +#define MIPS_HFLAG_SM 0x0004 /* Supervisor mode */ +#define MIPS_HFLAG_64 0x0008 /* 64-bit instructions enabled */ +#define MIPS_HFLAG_FPU 0x0010 /* FPU enabled */ +#define MIPS_HFLAG_F64 0x0020 /* 64-bit FPU enabled */ #define MIPS_HFLAG_RE 0x0040 /* Reversed endianness */ /* If translation is interrupted between the branch instruction and * the delay slot, record what type of branch it is so that we can diff --git a/target-mips/fop_template.c b/target-mips/fop_template.c index bb288f11ee..0f1595ff87 100644 --- a/target-mips/fop_template.c +++ b/target-mips/fop_template.c @@ -49,7 +49,7 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG) #define OP_DLOAD_FREG(treg, tregname, FREG) \ void glue(glue(op_load_fpr_,tregname), FREG) (void) \ { \ - if (env->CP0_Status & (1 << CP0St_FR)) \ + if (env->hflags & MIPS_HFLAG_F64) \ treg = env->fpr[FREG].fd; \ else \ treg = (uint64_t)(env->fpr[FREG | 1].fs[FP_ENDIAN_IDX]) << 32 | \ @@ -60,7 +60,7 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG) #define OP_DSTORE_FREG(treg, tregname, FREG) \ void glue(glue(op_store_fpr_,tregname), FREG) (void) \ { \ - if (env->CP0_Status & (1 << CP0St_FR)) \ + if (env->hflags & MIPS_HFLAG_F64) \ env->fpr[FREG].fd = treg; \ else { \ env->fpr[FREG | 1].fs[FP_ENDIAN_IDX] = treg >> 32; \ diff --git a/target-mips/op.c b/target-mips/op.c index bc4d51a8f8..a65977af4c 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -1349,8 +1349,7 @@ void op_mtc0_status (void) uint32_t val, old; uint32_t mask = env->Status_rw_bitmask; - /* No reverse endianness, no MDMX/DSP, no 64bit ops - implemented. */ + /* No reverse endianness, no MDMX/DSP implemented. */ val = T0 & mask; old = env->CP0_Status; if (!(val & (1 << CP0St_EXL)) && @@ -1364,6 +1363,14 @@ void op_mtc0_status (void) !(val & (1 << CP0St_UX))) env->hflags &= ~MIPS_HFLAG_64; #endif + if (val & (1 << CP0St_CU1)) + env->hflags |= MIPS_HFLAG_FPU; + else + env->hflags &= ~MIPS_HFLAG_FPU; + if (val & (1 << CP0St_FR)) + env->hflags |= MIPS_HFLAG_F64; + else + env->hflags &= ~MIPS_HFLAG_F64; env->CP0_Status = (env->CP0_Status & ~mask) | val; if (loglevel & CPU_LOG_EXEC) CALL_FROM_TB2(do_mtc0_status_debug, old, val); @@ -1606,41 +1613,6 @@ void op_cp0_enabled(void) RETURN(); } -void op_cp1_enabled(void) -{ - if (!(env->CP0_Status & (1 << CP0St_CU1))) { - CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1); - } - RETURN(); -} - -void op_cp1_64bitmode(void) -{ - if (!(env->CP0_Status & (1 << CP0St_FR))) { - CALL_FROM_TB1(do_raise_exception, EXCP_RI); - } - RETURN(); -} - -/* - * Verify if floating point register is valid; an operation is not defined - * if bit 0 of any register specification is set and the FR bit in the - * Status register equals zero, since the register numbers specify an - * even-odd pair of adjacent coprocessor general registers. When the FR bit - * in the Status register equals one, both even and odd register numbers - * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. - * - * Multiple 64 bit wide registers can be checked by calling - * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); - */ -void op_cp1_registers(void) -{ - if (!(env->CP0_Status & (1 << CP0St_FR)) && (PARAM1 & 1)) { - CALL_FROM_TB1(do_raise_exception, EXCP_RI); - } - RETURN(); -} - void op_cfc1 (void) { switch (T1) { diff --git a/target-mips/translate.c b/target-mips/translate.c index c0f2b81229..e092439cfb 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -703,6 +703,35 @@ static inline void generate_exception (DisasContext *ctx, int excp) generate_exception_err (ctx, excp, 0); } +static inline void check_cp1_enabled(DisasContext *ctx) +{ + if (!(ctx->hflags & MIPS_HFLAG_FPU)) + generate_exception_err(ctx, EXCP_CpU, 1); +} + +static inline void check_cp1_64bitmode(DisasContext *ctx) +{ + if (!(ctx->hflags & MIPS_HFLAG_F64)) + generate_exception(ctx, EXCP_RI); +} + +/* + * Verify if floating point register is valid; an operation is not defined + * if bit 0 of any register specification is set and the FR bit in the + * Status register equals zero, since the register numbers specify an + * even-odd pair of adjacent coprocessor general registers. When the FR bit + * in the Status register equals one, both even and odd register numbers + * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. + * + * Multiple 64 bit wide registers can be checked by calling + * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); + */ +void check_cp1_registers(DisasContext *ctx, int regs) +{ + if (!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)) + generate_exception(ctx, EXCP_RI); +} + #if defined(CONFIG_USER_ONLY) #define op_ldst(name) gen_op_##name##_raw() #define OP_LD_TABLE(width) @@ -4243,8 +4272,8 @@ GEN_MOVCF(s); GEN_MOVCF(ps); #undef GEN_MOVCF -static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, - int fs, int fd, int cc) +static void gen_farith (DisasContext *ctx, uint32_t op1, + int ft, int fs, int fd, int cc) { const char *opn = "farith"; const char *condnames[] = { @@ -4344,28 +4373,28 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "neg.s"; break; case FOP(8, 16): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_roundl_s(); GEN_STORE_FTN_FREG(fd, DT2); opn = "round.l.s"; break; case FOP(9, 16): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_truncl_s(); GEN_STORE_FTN_FREG(fd, DT2); opn = "trunc.l.s"; break; case FOP(10, 16): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_ceill_s(); GEN_STORE_FTN_FREG(fd, DT2); opn = "ceil.l.s"; break; case FOP(11, 16): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_floorl_s(); GEN_STORE_FTN_FREG(fd, DT2); @@ -4432,7 +4461,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "rsqrt.s"; break; case FOP(28, 16): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WT2, fd); gen_op_float_recip2_s(); @@ -4440,21 +4469,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "recip2.s"; break; case FOP(29, 16): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_recip1_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "recip1.s"; break; case FOP(30, 16): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_rsqrt1_s(); GEN_STORE_FTN_FREG(fd, WT2); opn = "rsqrt1.s"; break; case FOP(31, 16): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WT2, fd); gen_op_float_rsqrt2_s(); @@ -4462,7 +4491,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "rsqrt2.s"; break; case FOP(33, 16): - gen_op_cp1_registers(fd); + check_cp1_registers(ctx, fd); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_cvtd_s(); GEN_STORE_FTN_FREG(fd, DT2); @@ -4475,14 +4504,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "cvt.w.s"; break; case FOP(37, 16): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_cvtl_s(); GEN_STORE_FTN_FREG(fd, DT2); opn = "cvt.l.s"; break; case FOP(38, 16): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT1, fs); GEN_LOAD_FREG_FTN(WT0, ft); gen_op_float_cvtps_s(); @@ -4508,7 +4537,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WT1, ft); if (ctx->opcode & (1 << 6)) { - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); gen_cmpabs_s(func-48, cc); opn = condnames_abs[func-48]; } else { @@ -4517,7 +4546,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, } break; case FOP(0, 17): - gen_op_cp1_registers(fs | ft | fd); + check_cp1_registers(ctx, fs | ft | fd); GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT1, ft); gen_op_float_add_d(); @@ -4526,7 +4555,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, optype = BINOP; break; case FOP(1, 17): - gen_op_cp1_registers(fs | ft | fd); + check_cp1_registers(ctx, fs | ft | fd); GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT1, ft); gen_op_float_sub_d(); @@ -4535,7 +4564,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, optype = BINOP; break; case FOP(2, 17): - gen_op_cp1_registers(fs | ft | fd); + check_cp1_registers(ctx, fs | ft | fd); GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT1, ft); gen_op_float_mul_d(); @@ -4544,7 +4573,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, optype = BINOP; break; case FOP(3, 17): - gen_op_cp1_registers(fs | ft | fd); + check_cp1_registers(ctx, fs | ft | fd); GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT1, ft); gen_op_float_div_d(); @@ -4553,84 +4582,84 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, optype = BINOP; break; case FOP(4, 17): - gen_op_cp1_registers(fs | fd); + check_cp1_registers(ctx, fs | fd); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_sqrt_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "sqrt.d"; break; case FOP(5, 17): - gen_op_cp1_registers(fs | fd); + check_cp1_registers(ctx, fs | fd); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_abs_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "abs.d"; break; case FOP(6, 17): - gen_op_cp1_registers(fs | fd); + check_cp1_registers(ctx, fs | fd); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_mov_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "mov.d"; break; case FOP(7, 17): - gen_op_cp1_registers(fs | fd); + check_cp1_registers(ctx, fs | fd); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_chs_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "neg.d"; break; case FOP(8, 17): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_roundl_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "round.l.d"; break; case FOP(9, 17): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_truncl_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "trunc.l.d"; break; case FOP(10, 17): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_ceill_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "ceil.l.d"; break; case FOP(11, 17): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_floorl_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "floor.l.d"; break; case FOP(12, 17): - gen_op_cp1_registers(fs); + check_cp1_registers(ctx, fs); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_roundw_d(); GEN_STORE_FTN_FREG(fd, WT2); opn = "round.w.d"; break; case FOP(13, 17): - gen_op_cp1_registers(fs); + check_cp1_registers(ctx, fs); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_truncw_d(); GEN_STORE_FTN_FREG(fd, WT2); opn = "trunc.w.d"; break; case FOP(14, 17): - gen_op_cp1_registers(fs); + check_cp1_registers(ctx, fs); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_ceilw_d(); GEN_STORE_FTN_FREG(fd, WT2); opn = "ceil.w.d"; break; case FOP(15, 17): - gen_op_cp1_registers(fs); + check_cp1_registers(ctx, fs); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_floorw_d(); GEN_STORE_FTN_FREG(fd, WT2); @@ -4661,21 +4690,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "movn.d"; break; case FOP(21, 17): - gen_op_cp1_registers(fs | fd); + check_cp1_registers(ctx, fs | fd); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_recip_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "recip.d"; break; case FOP(22, 17): - gen_op_cp1_registers(fs | fd); + check_cp1_registers(ctx, fs | fd); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_rsqrt_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "rsqrt.d"; break; case FOP(28, 17): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT2, ft); gen_op_float_recip2_d(); @@ -4683,21 +4712,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "recip2.d"; break; case FOP(29, 17): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_recip1_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "recip1.d"; break; case FOP(30, 17): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_rsqrt1_d(); GEN_STORE_FTN_FREG(fd, DT2); opn = "rsqrt1.d"; break; case FOP(31, 17): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT2, ft); gen_op_float_rsqrt2_d(); @@ -4723,31 +4752,31 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, GEN_LOAD_FREG_FTN(DT0, fs); GEN_LOAD_FREG_FTN(DT1, ft); if (ctx->opcode & (1 << 6)) { - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); gen_cmpabs_d(func-48, cc); opn = condnames_abs[func-48]; } else { - gen_op_cp1_registers(fs | ft); + check_cp1_registers(ctx, fs | ft); gen_cmp_d(func-48, cc); opn = condnames[func-48]; } break; case FOP(32, 17): - gen_op_cp1_registers(fs); + check_cp1_registers(ctx, fs); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_cvts_d(); GEN_STORE_FTN_FREG(fd, WT2); opn = "cvt.s.d"; break; case FOP(36, 17): - gen_op_cp1_registers(fs); + check_cp1_registers(ctx, fs); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_cvtw_d(); GEN_STORE_FTN_FREG(fd, WT2); opn = "cvt.w.d"; break; case FOP(37, 17): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_cvtl_d(); GEN_STORE_FTN_FREG(fd, DT2); @@ -4760,21 +4789,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "cvt.s.w"; break; case FOP(33, 20): - gen_op_cp1_registers(fd); + check_cp1_registers(ctx, fd); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_cvtd_w(); GEN_STORE_FTN_FREG(fd, DT2); opn = "cvt.d.w"; break; case FOP(32, 21): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_cvts_l(); GEN_STORE_FTN_FREG(fd, WT2); opn = "cvt.s.l"; break; case FOP(33, 21): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(DT0, fs); gen_op_float_cvtd_l(); GEN_STORE_FTN_FREG(fd, DT2); @@ -4782,7 +4811,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, break; case FOP(38, 20): case FOP(38, 21): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_cvtps_pw(); @@ -4791,7 +4820,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "cvt.ps.pw"; break; case FOP(0, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT1, ft); @@ -4802,7 +4831,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "add.ps"; break; case FOP(1, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT1, ft); @@ -4813,7 +4842,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "sub.ps"; break; case FOP(2, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT1, ft); @@ -4824,7 +4853,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "mul.ps"; break; case FOP(5, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_abs_ps(); @@ -4833,7 +4862,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "abs.ps"; break; case FOP(6, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_mov_ps(); @@ -4842,7 +4871,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "mov.ps"; break; case FOP(7, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_chs_ps(); @@ -4851,7 +4880,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "neg.ps"; break; case FOP(17, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_REG_TN(T0, ft); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); @@ -4863,7 +4892,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "movcf.ps"; break; case FOP(18, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_REG_TN(T0, ft); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); @@ -4875,7 +4904,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "movz.ps"; break; case FOP(19, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_REG_TN(T0, ft); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); @@ -4887,7 +4916,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "movn.ps"; break; case FOP(24, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, ft); GEN_LOAD_FREG_FTN(WTH0, ft); GEN_LOAD_FREG_FTN(WT1, fs); @@ -4898,7 +4927,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "addr.ps"; break; case FOP(26, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, ft); GEN_LOAD_FREG_FTN(WTH0, ft); GEN_LOAD_FREG_FTN(WT1, fs); @@ -4909,7 +4938,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "mulr.ps"; break; case FOP(28, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT2, fd); @@ -4920,7 +4949,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "recip2.ps"; break; case FOP(29, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_recip1_ps(); @@ -4929,7 +4958,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "recip1.ps"; break; case FOP(30, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_rsqrt1_ps(); @@ -4938,7 +4967,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "rsqrt1.ps"; break; case FOP(31, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT2, fd); @@ -4949,14 +4978,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "rsqrt2.ps"; break; case FOP(32, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_cvts_pu(); GEN_STORE_FTN_FREG(fd, WT2); opn = "cvt.s.pu"; break; case FOP(36, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); gen_op_float_cvtpw_ps(); @@ -4965,14 +4994,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "cvt.pw.ps"; break; case FOP(40, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); gen_op_float_cvts_pl(); GEN_STORE_FTN_FREG(fd, WT2); opn = "cvt.s.pl"; break; case FOP(44, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WT1, ft); gen_op_float_pll_ps(); @@ -4980,7 +5009,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "pll.ps"; break; case FOP(45, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH1, ft); gen_op_float_plu_ps(); @@ -4988,7 +5017,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "plu.ps"; break; case FOP(46, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT1, ft); gen_op_float_pul_ps(); @@ -4996,7 +5025,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, opn = "pul.ps"; break; case FOP(47, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WTH1, ft); gen_op_float_puu_ps(); @@ -5019,7 +5048,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, case FOP(61, 22): case FOP(62, 22): case FOP(63, 22): - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); GEN_LOAD_FREG_FTN(WT0, fs); GEN_LOAD_FREG_FTN(WTH0, fs); GEN_LOAD_FREG_FTN(WT1, ft); @@ -5051,14 +5080,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, } /* Coprocessor 3 (FPU) */ -static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd, - int fs, int base, int index) +static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, + int fd, int fs, int base, int index) { const char *opn = "extended float load/store"; int store = 0; /* All of those work only on 64bit FPUs. */ - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); if (base == 0) { if (index == 0) gen_op_reset_T0(); @@ -5117,13 +5146,13 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd, regnames[index], regnames[base]); } -static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd, - int fr, int fs, int ft) +static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, + int fd, int fr, int fs, int ft) { const char *opn = "flt3_arith"; /* All of those work only on 64bit FPUs. */ - gen_op_cp1_64bitmode(); + check_cp1_64bitmode(ctx); switch (opc) { case OPC_ALNV_PS: GEN_LOAD_REG_TN(T0, fr); @@ -5363,7 +5392,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) case OPC_MOVCI: if (env->CP0_Config1 & (1 << CP0C1_FP)) { save_cpu_state(ctx, 1); - gen_op_cp1_enabled(); + check_cp1_enabled(ctx); gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, (ctx->opcode >> 16) & 1); } else { @@ -5634,7 +5663,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) case OPC_SDC1: if (env->CP0_Config1 & (1 << CP0C1_FP)) { save_cpu_state(ctx, 1); - gen_op_cp1_enabled(); + check_cp1_enabled(ctx); gen_flt_ldst(ctx, op, rt, rs, imm); } else { generate_exception_err(ctx, EXCP_CpU, 1); @@ -5644,7 +5673,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) case OPC_CP1: if (env->CP0_Config1 & (1 << CP0C1_FP)) { save_cpu_state(ctx, 1); - gen_op_cp1_enabled(); + check_cp1_enabled(ctx); op1 = MASK_CP1(ctx->opcode); switch (op1) { case OPC_MFC1: @@ -5696,7 +5725,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) case OPC_CP3: if (env->CP0_Config1 & (1 << CP0C1_FP)) { save_cpu_state(ctx, 1); - gen_op_cp1_enabled(); + check_cp1_enabled(ctx); op1 = MASK_CP3(ctx->opcode); switch (op1) { case OPC_LWXC1: @@ -5960,7 +5989,7 @@ void fpu_dump_state(CPUState *env, FILE *f, int flags) { int i; - int is_fpu64 = !!(env->CP0_Status & (1 << CP0St_FR)); + int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64); #define printfpr(fp) \ do { \ @@ -6038,7 +6067,6 @@ void cpu_dump_state (CPUState *env, FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...), int flags) { - uint32_t c0_status; int i; cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n", @@ -6051,13 +6079,11 @@ void cpu_dump_state (CPUState *env, FILE *f, cpu_fprintf(f, "\n"); } - c0_status = env->CP0_Status; - cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n", - c0_status, env->CP0_Cause, env->CP0_EPC); + env->CP0_Status, env->CP0_Cause, env->CP0_EPC); cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n", env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr); - if (c0_status & (1 << CP0St_CU1)) + if (env->hflags & MIPS_HFLAG_FPU) fpu_dump_state(env, f, cpu_fprintf, flags); #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS) cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);