Commit 5e755519ac9d867f7da13f58a9d0c262db82e14c

Authored by ths
1 parent acf930aa

Don't check the FPU state for each FPU instruction, use hflags to

handle this per-tb.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2896 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/cpu.h
... ... @@ -258,9 +258,11 @@ struct CPUMIPSState {
258 258 #define MIPS_HFLAG_TMASK 0x007F
259 259 #define MIPS_HFLAG_MODE 0x001F /* execution modes */
260 260 #define MIPS_HFLAG_UM 0x0001 /* user mode */
261   -#define MIPS_HFLAG_DM 0x0008 /* Debug mode */
262   -#define MIPS_HFLAG_SM 0x0010 /* Supervisor mode */
263   -#define MIPS_HFLAG_64 0x0020 /* 64-bit instructions enabled */
  261 +#define MIPS_HFLAG_DM 0x0002 /* Debug mode */
  262 +#define MIPS_HFLAG_SM 0x0004 /* Supervisor mode */
  263 +#define MIPS_HFLAG_64 0x0008 /* 64-bit instructions enabled */
  264 +#define MIPS_HFLAG_FPU 0x0010 /* FPU enabled */
  265 +#define MIPS_HFLAG_F64 0x0020 /* 64-bit FPU enabled */
264 266 #define MIPS_HFLAG_RE 0x0040 /* Reversed endianness */
265 267 /* If translation is interrupted between the branch instruction and
266 268 * the delay slot, record what type of branch it is so that we can
... ...
target-mips/fop_template.c
... ... @@ -49,7 +49,7 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG)
49 49 #define OP_DLOAD_FREG(treg, tregname, FREG) \
50 50 void glue(glue(op_load_fpr_,tregname), FREG) (void) \
51 51 { \
52   - if (env->CP0_Status & (1 << CP0St_FR)) \
  52 + if (env->hflags & MIPS_HFLAG_F64) \
53 53 treg = env->fpr[FREG].fd; \
54 54 else \
55 55 treg = (uint64_t)(env->fpr[FREG | 1].fs[FP_ENDIAN_IDX]) << 32 | \
... ... @@ -60,7 +60,7 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG)
60 60 #define OP_DSTORE_FREG(treg, tregname, FREG) \
61 61 void glue(glue(op_store_fpr_,tregname), FREG) (void) \
62 62 { \
63   - if (env->CP0_Status & (1 << CP0St_FR)) \
  63 + if (env->hflags & MIPS_HFLAG_F64) \
64 64 env->fpr[FREG].fd = treg; \
65 65 else { \
66 66 env->fpr[FREG | 1].fs[FP_ENDIAN_IDX] = treg >> 32; \
... ...
target-mips/op.c
... ... @@ -1349,8 +1349,7 @@ void op_mtc0_status (void)
1349 1349 uint32_t val, old;
1350 1350 uint32_t mask = env->Status_rw_bitmask;
1351 1351  
1352   - /* No reverse endianness, no MDMX/DSP, no 64bit ops
1353   - implemented. */
  1352 + /* No reverse endianness, no MDMX/DSP implemented. */
1354 1353 val = T0 & mask;
1355 1354 old = env->CP0_Status;
1356 1355 if (!(val & (1 << CP0St_EXL)) &&
... ... @@ -1364,6 +1363,14 @@ void op_mtc0_status (void)
1364 1363 !(val & (1 << CP0St_UX)))
1365 1364 env->hflags &= ~MIPS_HFLAG_64;
1366 1365 #endif
  1366 + if (val & (1 << CP0St_CU1))
  1367 + env->hflags |= MIPS_HFLAG_FPU;
  1368 + else
  1369 + env->hflags &= ~MIPS_HFLAG_FPU;
  1370 + if (val & (1 << CP0St_FR))
  1371 + env->hflags |= MIPS_HFLAG_F64;
  1372 + else
  1373 + env->hflags &= ~MIPS_HFLAG_F64;
1367 1374 env->CP0_Status = (env->CP0_Status & ~mask) | val;
1368 1375 if (loglevel & CPU_LOG_EXEC)
1369 1376 CALL_FROM_TB2(do_mtc0_status_debug, old, val);
... ... @@ -1606,41 +1613,6 @@ void op_cp0_enabled(void)
1606 1613 RETURN();
1607 1614 }
1608 1615  
1609   -void op_cp1_enabled(void)
1610   -{
1611   - if (!(env->CP0_Status & (1 << CP0St_CU1))) {
1612   - CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1);
1613   - }
1614   - RETURN();
1615   -}
1616   -
1617   -void op_cp1_64bitmode(void)
1618   -{
1619   - if (!(env->CP0_Status & (1 << CP0St_FR))) {
1620   - CALL_FROM_TB1(do_raise_exception, EXCP_RI);
1621   - }
1622   - RETURN();
1623   -}
1624   -
1625   -/*
1626   - * Verify if floating point register is valid; an operation is not defined
1627   - * if bit 0 of any register specification is set and the FR bit in the
1628   - * Status register equals zero, since the register numbers specify an
1629   - * even-odd pair of adjacent coprocessor general registers. When the FR bit
1630   - * in the Status register equals one, both even and odd register numbers
1631   - * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1632   - *
1633   - * Multiple 64 bit wide registers can be checked by calling
1634   - * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1635   - */
1636   -void op_cp1_registers(void)
1637   -{
1638   - if (!(env->CP0_Status & (1 << CP0St_FR)) && (PARAM1 & 1)) {
1639   - CALL_FROM_TB1(do_raise_exception, EXCP_RI);
1640   - }
1641   - RETURN();
1642   -}
1643   -
1644 1616 void op_cfc1 (void)
1645 1617 {
1646 1618 switch (T1) {
... ...
target-mips/translate.c
... ... @@ -703,6 +703,35 @@ static inline void generate_exception (DisasContext *ctx, int excp)
703 703 generate_exception_err (ctx, excp, 0);
704 704 }
705 705  
  706 +static inline void check_cp1_enabled(DisasContext *ctx)
  707 +{
  708 + if (!(ctx->hflags & MIPS_HFLAG_FPU))
  709 + generate_exception_err(ctx, EXCP_CpU, 1);
  710 +}
  711 +
  712 +static inline void check_cp1_64bitmode(DisasContext *ctx)
  713 +{
  714 + if (!(ctx->hflags & MIPS_HFLAG_F64))
  715 + generate_exception(ctx, EXCP_RI);
  716 +}
  717 +
  718 +/*
  719 + * Verify if floating point register is valid; an operation is not defined
  720 + * if bit 0 of any register specification is set and the FR bit in the
  721 + * Status register equals zero, since the register numbers specify an
  722 + * even-odd pair of adjacent coprocessor general registers. When the FR bit
  723 + * in the Status register equals one, both even and odd register numbers
  724 + * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
  725 + *
  726 + * Multiple 64 bit wide registers can be checked by calling
  727 + * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
  728 + */
  729 +void check_cp1_registers(DisasContext *ctx, int regs)
  730 +{
  731 + if (!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))
  732 + generate_exception(ctx, EXCP_RI);
  733 +}
  734 +
706 735 #if defined(CONFIG_USER_ONLY)
707 736 #define op_ldst(name) gen_op_##name##_raw()
708 737 #define OP_LD_TABLE(width)
... ... @@ -4243,8 +4272,8 @@ GEN_MOVCF(s);
4243 4272 GEN_MOVCF(ps);
4244 4273 #undef GEN_MOVCF
4245 4274  
4246   -static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4247   - int fs, int fd, int cc)
  4275 +static void gen_farith (DisasContext *ctx, uint32_t op1,
  4276 + int ft, int fs, int fd, int cc)
4248 4277 {
4249 4278 const char *opn = "farith";
4250 4279 const char *condnames[] = {
... ... @@ -4344,28 +4373,28 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4344 4373 opn = "neg.s";
4345 4374 break;
4346 4375 case FOP(8, 16):
4347   - gen_op_cp1_64bitmode();
  4376 + check_cp1_64bitmode(ctx);
4348 4377 GEN_LOAD_FREG_FTN(WT0, fs);
4349 4378 gen_op_float_roundl_s();
4350 4379 GEN_STORE_FTN_FREG(fd, DT2);
4351 4380 opn = "round.l.s";
4352 4381 break;
4353 4382 case FOP(9, 16):
4354   - gen_op_cp1_64bitmode();
  4383 + check_cp1_64bitmode(ctx);
4355 4384 GEN_LOAD_FREG_FTN(WT0, fs);
4356 4385 gen_op_float_truncl_s();
4357 4386 GEN_STORE_FTN_FREG(fd, DT2);
4358 4387 opn = "trunc.l.s";
4359 4388 break;
4360 4389 case FOP(10, 16):
4361   - gen_op_cp1_64bitmode();
  4390 + check_cp1_64bitmode(ctx);
4362 4391 GEN_LOAD_FREG_FTN(WT0, fs);
4363 4392 gen_op_float_ceill_s();
4364 4393 GEN_STORE_FTN_FREG(fd, DT2);
4365 4394 opn = "ceil.l.s";
4366 4395 break;
4367 4396 case FOP(11, 16):
4368   - gen_op_cp1_64bitmode();
  4397 + check_cp1_64bitmode(ctx);
4369 4398 GEN_LOAD_FREG_FTN(WT0, fs);
4370 4399 gen_op_float_floorl_s();
4371 4400 GEN_STORE_FTN_FREG(fd, DT2);
... ... @@ -4432,7 +4461,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4432 4461 opn = "rsqrt.s";
4433 4462 break;
4434 4463 case FOP(28, 16):
4435   - gen_op_cp1_64bitmode();
  4464 + check_cp1_64bitmode(ctx);
4436 4465 GEN_LOAD_FREG_FTN(WT0, fs);
4437 4466 GEN_LOAD_FREG_FTN(WT2, fd);
4438 4467 gen_op_float_recip2_s();
... ... @@ -4440,21 +4469,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4440 4469 opn = "recip2.s";
4441 4470 break;
4442 4471 case FOP(29, 16):
4443   - gen_op_cp1_64bitmode();
  4472 + check_cp1_64bitmode(ctx);
4444 4473 GEN_LOAD_FREG_FTN(WT0, fs);
4445 4474 gen_op_float_recip1_s();
4446 4475 GEN_STORE_FTN_FREG(fd, WT2);
4447 4476 opn = "recip1.s";
4448 4477 break;
4449 4478 case FOP(30, 16):
4450   - gen_op_cp1_64bitmode();
  4479 + check_cp1_64bitmode(ctx);
4451 4480 GEN_LOAD_FREG_FTN(WT0, fs);
4452 4481 gen_op_float_rsqrt1_s();
4453 4482 GEN_STORE_FTN_FREG(fd, WT2);
4454 4483 opn = "rsqrt1.s";
4455 4484 break;
4456 4485 case FOP(31, 16):
4457   - gen_op_cp1_64bitmode();
  4486 + check_cp1_64bitmode(ctx);
4458 4487 GEN_LOAD_FREG_FTN(WT0, fs);
4459 4488 GEN_LOAD_FREG_FTN(WT2, fd);
4460 4489 gen_op_float_rsqrt2_s();
... ... @@ -4462,7 +4491,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4462 4491 opn = "rsqrt2.s";
4463 4492 break;
4464 4493 case FOP(33, 16):
4465   - gen_op_cp1_registers(fd);
  4494 + check_cp1_registers(ctx, fd);
4466 4495 GEN_LOAD_FREG_FTN(WT0, fs);
4467 4496 gen_op_float_cvtd_s();
4468 4497 GEN_STORE_FTN_FREG(fd, DT2);
... ... @@ -4475,14 +4504,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4475 4504 opn = "cvt.w.s";
4476 4505 break;
4477 4506 case FOP(37, 16):
4478   - gen_op_cp1_64bitmode();
  4507 + check_cp1_64bitmode(ctx);
4479 4508 GEN_LOAD_FREG_FTN(WT0, fs);
4480 4509 gen_op_float_cvtl_s();
4481 4510 GEN_STORE_FTN_FREG(fd, DT2);
4482 4511 opn = "cvt.l.s";
4483 4512 break;
4484 4513 case FOP(38, 16):
4485   - gen_op_cp1_64bitmode();
  4514 + check_cp1_64bitmode(ctx);
4486 4515 GEN_LOAD_FREG_FTN(WT1, fs);
4487 4516 GEN_LOAD_FREG_FTN(WT0, ft);
4488 4517 gen_op_float_cvtps_s();
... ... @@ -4508,7 +4537,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4508 4537 GEN_LOAD_FREG_FTN(WT0, fs);
4509 4538 GEN_LOAD_FREG_FTN(WT1, ft);
4510 4539 if (ctx->opcode & (1 << 6)) {
4511   - gen_op_cp1_64bitmode();
  4540 + check_cp1_64bitmode(ctx);
4512 4541 gen_cmpabs_s(func-48, cc);
4513 4542 opn = condnames_abs[func-48];
4514 4543 } else {
... ... @@ -4517,7 +4546,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4517 4546 }
4518 4547 break;
4519 4548 case FOP(0, 17):
4520   - gen_op_cp1_registers(fs | ft | fd);
  4549 + check_cp1_registers(ctx, fs | ft | fd);
4521 4550 GEN_LOAD_FREG_FTN(DT0, fs);
4522 4551 GEN_LOAD_FREG_FTN(DT1, ft);
4523 4552 gen_op_float_add_d();
... ... @@ -4526,7 +4555,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4526 4555 optype = BINOP;
4527 4556 break;
4528 4557 case FOP(1, 17):
4529   - gen_op_cp1_registers(fs | ft | fd);
  4558 + check_cp1_registers(ctx, fs | ft | fd);
4530 4559 GEN_LOAD_FREG_FTN(DT0, fs);
4531 4560 GEN_LOAD_FREG_FTN(DT1, ft);
4532 4561 gen_op_float_sub_d();
... ... @@ -4535,7 +4564,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4535 4564 optype = BINOP;
4536 4565 break;
4537 4566 case FOP(2, 17):
4538   - gen_op_cp1_registers(fs | ft | fd);
  4567 + check_cp1_registers(ctx, fs | ft | fd);
4539 4568 GEN_LOAD_FREG_FTN(DT0, fs);
4540 4569 GEN_LOAD_FREG_FTN(DT1, ft);
4541 4570 gen_op_float_mul_d();
... ... @@ -4544,7 +4573,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4544 4573 optype = BINOP;
4545 4574 break;
4546 4575 case FOP(3, 17):
4547   - gen_op_cp1_registers(fs | ft | fd);
  4576 + check_cp1_registers(ctx, fs | ft | fd);
4548 4577 GEN_LOAD_FREG_FTN(DT0, fs);
4549 4578 GEN_LOAD_FREG_FTN(DT1, ft);
4550 4579 gen_op_float_div_d();
... ... @@ -4553,84 +4582,84 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4553 4582 optype = BINOP;
4554 4583 break;
4555 4584 case FOP(4, 17):
4556   - gen_op_cp1_registers(fs | fd);
  4585 + check_cp1_registers(ctx, fs | fd);
4557 4586 GEN_LOAD_FREG_FTN(DT0, fs);
4558 4587 gen_op_float_sqrt_d();
4559 4588 GEN_STORE_FTN_FREG(fd, DT2);
4560 4589 opn = "sqrt.d";
4561 4590 break;
4562 4591 case FOP(5, 17):
4563   - gen_op_cp1_registers(fs | fd);
  4592 + check_cp1_registers(ctx, fs | fd);
4564 4593 GEN_LOAD_FREG_FTN(DT0, fs);
4565 4594 gen_op_float_abs_d();
4566 4595 GEN_STORE_FTN_FREG(fd, DT2);
4567 4596 opn = "abs.d";
4568 4597 break;
4569 4598 case FOP(6, 17):
4570   - gen_op_cp1_registers(fs | fd);
  4599 + check_cp1_registers(ctx, fs | fd);
4571 4600 GEN_LOAD_FREG_FTN(DT0, fs);
4572 4601 gen_op_float_mov_d();
4573 4602 GEN_STORE_FTN_FREG(fd, DT2);
4574 4603 opn = "mov.d";
4575 4604 break;
4576 4605 case FOP(7, 17):
4577   - gen_op_cp1_registers(fs | fd);
  4606 + check_cp1_registers(ctx, fs | fd);
4578 4607 GEN_LOAD_FREG_FTN(DT0, fs);
4579 4608 gen_op_float_chs_d();
4580 4609 GEN_STORE_FTN_FREG(fd, DT2);
4581 4610 opn = "neg.d";
4582 4611 break;
4583 4612 case FOP(8, 17):
4584   - gen_op_cp1_64bitmode();
  4613 + check_cp1_64bitmode(ctx);
4585 4614 GEN_LOAD_FREG_FTN(DT0, fs);
4586 4615 gen_op_float_roundl_d();
4587 4616 GEN_STORE_FTN_FREG(fd, DT2);
4588 4617 opn = "round.l.d";
4589 4618 break;
4590 4619 case FOP(9, 17):
4591   - gen_op_cp1_64bitmode();
  4620 + check_cp1_64bitmode(ctx);
4592 4621 GEN_LOAD_FREG_FTN(DT0, fs);
4593 4622 gen_op_float_truncl_d();
4594 4623 GEN_STORE_FTN_FREG(fd, DT2);
4595 4624 opn = "trunc.l.d";
4596 4625 break;
4597 4626 case FOP(10, 17):
4598   - gen_op_cp1_64bitmode();
  4627 + check_cp1_64bitmode(ctx);
4599 4628 GEN_LOAD_FREG_FTN(DT0, fs);
4600 4629 gen_op_float_ceill_d();
4601 4630 GEN_STORE_FTN_FREG(fd, DT2);
4602 4631 opn = "ceil.l.d";
4603 4632 break;
4604 4633 case FOP(11, 17):
4605   - gen_op_cp1_64bitmode();
  4634 + check_cp1_64bitmode(ctx);
4606 4635 GEN_LOAD_FREG_FTN(DT0, fs);
4607 4636 gen_op_float_floorl_d();
4608 4637 GEN_STORE_FTN_FREG(fd, DT2);
4609 4638 opn = "floor.l.d";
4610 4639 break;
4611 4640 case FOP(12, 17):
4612   - gen_op_cp1_registers(fs);
  4641 + check_cp1_registers(ctx, fs);
4613 4642 GEN_LOAD_FREG_FTN(DT0, fs);
4614 4643 gen_op_float_roundw_d();
4615 4644 GEN_STORE_FTN_FREG(fd, WT2);
4616 4645 opn = "round.w.d";
4617 4646 break;
4618 4647 case FOP(13, 17):
4619   - gen_op_cp1_registers(fs);
  4648 + check_cp1_registers(ctx, fs);
4620 4649 GEN_LOAD_FREG_FTN(DT0, fs);
4621 4650 gen_op_float_truncw_d();
4622 4651 GEN_STORE_FTN_FREG(fd, WT2);
4623 4652 opn = "trunc.w.d";
4624 4653 break;
4625 4654 case FOP(14, 17):
4626   - gen_op_cp1_registers(fs);
  4655 + check_cp1_registers(ctx, fs);
4627 4656 GEN_LOAD_FREG_FTN(DT0, fs);
4628 4657 gen_op_float_ceilw_d();
4629 4658 GEN_STORE_FTN_FREG(fd, WT2);
4630 4659 opn = "ceil.w.d";
4631 4660 break;
4632 4661 case FOP(15, 17):
4633   - gen_op_cp1_registers(fs);
  4662 + check_cp1_registers(ctx, fs);
4634 4663 GEN_LOAD_FREG_FTN(DT0, fs);
4635 4664 gen_op_float_floorw_d();
4636 4665 GEN_STORE_FTN_FREG(fd, WT2);
... ... @@ -4661,21 +4690,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4661 4690 opn = "movn.d";
4662 4691 break;
4663 4692 case FOP(21, 17):
4664   - gen_op_cp1_registers(fs | fd);
  4693 + check_cp1_registers(ctx, fs | fd);
4665 4694 GEN_LOAD_FREG_FTN(DT0, fs);
4666 4695 gen_op_float_recip_d();
4667 4696 GEN_STORE_FTN_FREG(fd, DT2);
4668 4697 opn = "recip.d";
4669 4698 break;
4670 4699 case FOP(22, 17):
4671   - gen_op_cp1_registers(fs | fd);
  4700 + check_cp1_registers(ctx, fs | fd);
4672 4701 GEN_LOAD_FREG_FTN(DT0, fs);
4673 4702 gen_op_float_rsqrt_d();
4674 4703 GEN_STORE_FTN_FREG(fd, DT2);
4675 4704 opn = "rsqrt.d";
4676 4705 break;
4677 4706 case FOP(28, 17):
4678   - gen_op_cp1_64bitmode();
  4707 + check_cp1_64bitmode(ctx);
4679 4708 GEN_LOAD_FREG_FTN(DT0, fs);
4680 4709 GEN_LOAD_FREG_FTN(DT2, ft);
4681 4710 gen_op_float_recip2_d();
... ... @@ -4683,21 +4712,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4683 4712 opn = "recip2.d";
4684 4713 break;
4685 4714 case FOP(29, 17):
4686   - gen_op_cp1_64bitmode();
  4715 + check_cp1_64bitmode(ctx);
4687 4716 GEN_LOAD_FREG_FTN(DT0, fs);
4688 4717 gen_op_float_recip1_d();
4689 4718 GEN_STORE_FTN_FREG(fd, DT2);
4690 4719 opn = "recip1.d";
4691 4720 break;
4692 4721 case FOP(30, 17):
4693   - gen_op_cp1_64bitmode();
  4722 + check_cp1_64bitmode(ctx);
4694 4723 GEN_LOAD_FREG_FTN(DT0, fs);
4695 4724 gen_op_float_rsqrt1_d();
4696 4725 GEN_STORE_FTN_FREG(fd, DT2);
4697 4726 opn = "rsqrt1.d";
4698 4727 break;
4699 4728 case FOP(31, 17):
4700   - gen_op_cp1_64bitmode();
  4729 + check_cp1_64bitmode(ctx);
4701 4730 GEN_LOAD_FREG_FTN(DT0, fs);
4702 4731 GEN_LOAD_FREG_FTN(DT2, ft);
4703 4732 gen_op_float_rsqrt2_d();
... ... @@ -4723,31 +4752,31 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4723 4752 GEN_LOAD_FREG_FTN(DT0, fs);
4724 4753 GEN_LOAD_FREG_FTN(DT1, ft);
4725 4754 if (ctx->opcode & (1 << 6)) {
4726   - gen_op_cp1_64bitmode();
  4755 + check_cp1_64bitmode(ctx);
4727 4756 gen_cmpabs_d(func-48, cc);
4728 4757 opn = condnames_abs[func-48];
4729 4758 } else {
4730   - gen_op_cp1_registers(fs | ft);
  4759 + check_cp1_registers(ctx, fs | ft);
4731 4760 gen_cmp_d(func-48, cc);
4732 4761 opn = condnames[func-48];
4733 4762 }
4734 4763 break;
4735 4764 case FOP(32, 17):
4736   - gen_op_cp1_registers(fs);
  4765 + check_cp1_registers(ctx, fs);
4737 4766 GEN_LOAD_FREG_FTN(DT0, fs);
4738 4767 gen_op_float_cvts_d();
4739 4768 GEN_STORE_FTN_FREG(fd, WT2);
4740 4769 opn = "cvt.s.d";
4741 4770 break;
4742 4771 case FOP(36, 17):
4743   - gen_op_cp1_registers(fs);
  4772 + check_cp1_registers(ctx, fs);
4744 4773 GEN_LOAD_FREG_FTN(DT0, fs);
4745 4774 gen_op_float_cvtw_d();
4746 4775 GEN_STORE_FTN_FREG(fd, WT2);
4747 4776 opn = "cvt.w.d";
4748 4777 break;
4749 4778 case FOP(37, 17):
4750   - gen_op_cp1_64bitmode();
  4779 + check_cp1_64bitmode(ctx);
4751 4780 GEN_LOAD_FREG_FTN(DT0, fs);
4752 4781 gen_op_float_cvtl_d();
4753 4782 GEN_STORE_FTN_FREG(fd, DT2);
... ... @@ -4760,21 +4789,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4760 4789 opn = "cvt.s.w";
4761 4790 break;
4762 4791 case FOP(33, 20):
4763   - gen_op_cp1_registers(fd);
  4792 + check_cp1_registers(ctx, fd);
4764 4793 GEN_LOAD_FREG_FTN(WT0, fs);
4765 4794 gen_op_float_cvtd_w();
4766 4795 GEN_STORE_FTN_FREG(fd, DT2);
4767 4796 opn = "cvt.d.w";
4768 4797 break;
4769 4798 case FOP(32, 21):
4770   - gen_op_cp1_64bitmode();
  4799 + check_cp1_64bitmode(ctx);
4771 4800 GEN_LOAD_FREG_FTN(DT0, fs);
4772 4801 gen_op_float_cvts_l();
4773 4802 GEN_STORE_FTN_FREG(fd, WT2);
4774 4803 opn = "cvt.s.l";
4775 4804 break;
4776 4805 case FOP(33, 21):
4777   - gen_op_cp1_64bitmode();
  4806 + check_cp1_64bitmode(ctx);
4778 4807 GEN_LOAD_FREG_FTN(DT0, fs);
4779 4808 gen_op_float_cvtd_l();
4780 4809 GEN_STORE_FTN_FREG(fd, DT2);
... ... @@ -4782,7 +4811,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4782 4811 break;
4783 4812 case FOP(38, 20):
4784 4813 case FOP(38, 21):
4785   - gen_op_cp1_64bitmode();
  4814 + check_cp1_64bitmode(ctx);
4786 4815 GEN_LOAD_FREG_FTN(WT0, fs);
4787 4816 GEN_LOAD_FREG_FTN(WTH0, fs);
4788 4817 gen_op_float_cvtps_pw();
... ... @@ -4791,7 +4820,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4791 4820 opn = "cvt.ps.pw";
4792 4821 break;
4793 4822 case FOP(0, 22):
4794   - gen_op_cp1_64bitmode();
  4823 + check_cp1_64bitmode(ctx);
4795 4824 GEN_LOAD_FREG_FTN(WT0, fs);
4796 4825 GEN_LOAD_FREG_FTN(WTH0, fs);
4797 4826 GEN_LOAD_FREG_FTN(WT1, ft);
... ... @@ -4802,7 +4831,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4802 4831 opn = "add.ps";
4803 4832 break;
4804 4833 case FOP(1, 22):
4805   - gen_op_cp1_64bitmode();
  4834 + check_cp1_64bitmode(ctx);
4806 4835 GEN_LOAD_FREG_FTN(WT0, fs);
4807 4836 GEN_LOAD_FREG_FTN(WTH0, fs);
4808 4837 GEN_LOAD_FREG_FTN(WT1, ft);
... ... @@ -4813,7 +4842,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4813 4842 opn = "sub.ps";
4814 4843 break;
4815 4844 case FOP(2, 22):
4816   - gen_op_cp1_64bitmode();
  4845 + check_cp1_64bitmode(ctx);
4817 4846 GEN_LOAD_FREG_FTN(WT0, fs);
4818 4847 GEN_LOAD_FREG_FTN(WTH0, fs);
4819 4848 GEN_LOAD_FREG_FTN(WT1, ft);
... ... @@ -4824,7 +4853,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4824 4853 opn = "mul.ps";
4825 4854 break;
4826 4855 case FOP(5, 22):
4827   - gen_op_cp1_64bitmode();
  4856 + check_cp1_64bitmode(ctx);
4828 4857 GEN_LOAD_FREG_FTN(WT0, fs);
4829 4858 GEN_LOAD_FREG_FTN(WTH0, fs);
4830 4859 gen_op_float_abs_ps();
... ... @@ -4833,7 +4862,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4833 4862 opn = "abs.ps";
4834 4863 break;
4835 4864 case FOP(6, 22):
4836   - gen_op_cp1_64bitmode();
  4865 + check_cp1_64bitmode(ctx);
4837 4866 GEN_LOAD_FREG_FTN(WT0, fs);
4838 4867 GEN_LOAD_FREG_FTN(WTH0, fs);
4839 4868 gen_op_float_mov_ps();
... ... @@ -4842,7 +4871,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4842 4871 opn = "mov.ps";
4843 4872 break;
4844 4873 case FOP(7, 22):
4845   - gen_op_cp1_64bitmode();
  4874 + check_cp1_64bitmode(ctx);
4846 4875 GEN_LOAD_FREG_FTN(WT0, fs);
4847 4876 GEN_LOAD_FREG_FTN(WTH0, fs);
4848 4877 gen_op_float_chs_ps();
... ... @@ -4851,7 +4880,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4851 4880 opn = "neg.ps";
4852 4881 break;
4853 4882 case FOP(17, 22):
4854   - gen_op_cp1_64bitmode();
  4883 + check_cp1_64bitmode(ctx);
4855 4884 GEN_LOAD_REG_TN(T0, ft);
4856 4885 GEN_LOAD_FREG_FTN(WT0, fs);
4857 4886 GEN_LOAD_FREG_FTN(WTH0, fs);
... ... @@ -4863,7 +4892,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4863 4892 opn = "movcf.ps";
4864 4893 break;
4865 4894 case FOP(18, 22):
4866   - gen_op_cp1_64bitmode();
  4895 + check_cp1_64bitmode(ctx);
4867 4896 GEN_LOAD_REG_TN(T0, ft);
4868 4897 GEN_LOAD_FREG_FTN(WT0, fs);
4869 4898 GEN_LOAD_FREG_FTN(WTH0, fs);
... ... @@ -4875,7 +4904,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4875 4904 opn = "movz.ps";
4876 4905 break;
4877 4906 case FOP(19, 22):
4878   - gen_op_cp1_64bitmode();
  4907 + check_cp1_64bitmode(ctx);
4879 4908 GEN_LOAD_REG_TN(T0, ft);
4880 4909 GEN_LOAD_FREG_FTN(WT0, fs);
4881 4910 GEN_LOAD_FREG_FTN(WTH0, fs);
... ... @@ -4887,7 +4916,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4887 4916 opn = "movn.ps";
4888 4917 break;
4889 4918 case FOP(24, 22):
4890   - gen_op_cp1_64bitmode();
  4919 + check_cp1_64bitmode(ctx);
4891 4920 GEN_LOAD_FREG_FTN(WT0, ft);
4892 4921 GEN_LOAD_FREG_FTN(WTH0, ft);
4893 4922 GEN_LOAD_FREG_FTN(WT1, fs);
... ... @@ -4898,7 +4927,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4898 4927 opn = "addr.ps";
4899 4928 break;
4900 4929 case FOP(26, 22):
4901   - gen_op_cp1_64bitmode();
  4930 + check_cp1_64bitmode(ctx);
4902 4931 GEN_LOAD_FREG_FTN(WT0, ft);
4903 4932 GEN_LOAD_FREG_FTN(WTH0, ft);
4904 4933 GEN_LOAD_FREG_FTN(WT1, fs);
... ... @@ -4909,7 +4938,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4909 4938 opn = "mulr.ps";
4910 4939 break;
4911 4940 case FOP(28, 22):
4912   - gen_op_cp1_64bitmode();
  4941 + check_cp1_64bitmode(ctx);
4913 4942 GEN_LOAD_FREG_FTN(WT0, fs);
4914 4943 GEN_LOAD_FREG_FTN(WTH0, fs);
4915 4944 GEN_LOAD_FREG_FTN(WT2, fd);
... ... @@ -4920,7 +4949,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4920 4949 opn = "recip2.ps";
4921 4950 break;
4922 4951 case FOP(29, 22):
4923   - gen_op_cp1_64bitmode();
  4952 + check_cp1_64bitmode(ctx);
4924 4953 GEN_LOAD_FREG_FTN(WT0, fs);
4925 4954 GEN_LOAD_FREG_FTN(WTH0, fs);
4926 4955 gen_op_float_recip1_ps();
... ... @@ -4929,7 +4958,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4929 4958 opn = "recip1.ps";
4930 4959 break;
4931 4960 case FOP(30, 22):
4932   - gen_op_cp1_64bitmode();
  4961 + check_cp1_64bitmode(ctx);
4933 4962 GEN_LOAD_FREG_FTN(WT0, fs);
4934 4963 GEN_LOAD_FREG_FTN(WTH0, fs);
4935 4964 gen_op_float_rsqrt1_ps();
... ... @@ -4938,7 +4967,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4938 4967 opn = "rsqrt1.ps";
4939 4968 break;
4940 4969 case FOP(31, 22):
4941   - gen_op_cp1_64bitmode();
  4970 + check_cp1_64bitmode(ctx);
4942 4971 GEN_LOAD_FREG_FTN(WT0, fs);
4943 4972 GEN_LOAD_FREG_FTN(WTH0, fs);
4944 4973 GEN_LOAD_FREG_FTN(WT2, fd);
... ... @@ -4949,14 +4978,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4949 4978 opn = "rsqrt2.ps";
4950 4979 break;
4951 4980 case FOP(32, 22):
4952   - gen_op_cp1_64bitmode();
  4981 + check_cp1_64bitmode(ctx);
4953 4982 GEN_LOAD_FREG_FTN(WTH0, fs);
4954 4983 gen_op_float_cvts_pu();
4955 4984 GEN_STORE_FTN_FREG(fd, WT2);
4956 4985 opn = "cvt.s.pu";
4957 4986 break;
4958 4987 case FOP(36, 22):
4959   - gen_op_cp1_64bitmode();
  4988 + check_cp1_64bitmode(ctx);
4960 4989 GEN_LOAD_FREG_FTN(WT0, fs);
4961 4990 GEN_LOAD_FREG_FTN(WTH0, fs);
4962 4991 gen_op_float_cvtpw_ps();
... ... @@ -4965,14 +4994,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4965 4994 opn = "cvt.pw.ps";
4966 4995 break;
4967 4996 case FOP(40, 22):
4968   - gen_op_cp1_64bitmode();
  4997 + check_cp1_64bitmode(ctx);
4969 4998 GEN_LOAD_FREG_FTN(WT0, fs);
4970 4999 gen_op_float_cvts_pl();
4971 5000 GEN_STORE_FTN_FREG(fd, WT2);
4972 5001 opn = "cvt.s.pl";
4973 5002 break;
4974 5003 case FOP(44, 22):
4975   - gen_op_cp1_64bitmode();
  5004 + check_cp1_64bitmode(ctx);
4976 5005 GEN_LOAD_FREG_FTN(WT0, fs);
4977 5006 GEN_LOAD_FREG_FTN(WT1, ft);
4978 5007 gen_op_float_pll_ps();
... ... @@ -4980,7 +5009,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4980 5009 opn = "pll.ps";
4981 5010 break;
4982 5011 case FOP(45, 22):
4983   - gen_op_cp1_64bitmode();
  5012 + check_cp1_64bitmode(ctx);
4984 5013 GEN_LOAD_FREG_FTN(WT0, fs);
4985 5014 GEN_LOAD_FREG_FTN(WTH1, ft);
4986 5015 gen_op_float_plu_ps();
... ... @@ -4988,7 +5017,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4988 5017 opn = "plu.ps";
4989 5018 break;
4990 5019 case FOP(46, 22):
4991   - gen_op_cp1_64bitmode();
  5020 + check_cp1_64bitmode(ctx);
4992 5021 GEN_LOAD_FREG_FTN(WTH0, fs);
4993 5022 GEN_LOAD_FREG_FTN(WT1, ft);
4994 5023 gen_op_float_pul_ps();
... ... @@ -4996,7 +5025,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4996 5025 opn = "pul.ps";
4997 5026 break;
4998 5027 case FOP(47, 22):
4999   - gen_op_cp1_64bitmode();
  5028 + check_cp1_64bitmode(ctx);
5000 5029 GEN_LOAD_FREG_FTN(WTH0, fs);
5001 5030 GEN_LOAD_FREG_FTN(WTH1, ft);
5002 5031 gen_op_float_puu_ps();
... ... @@ -5019,7 +5048,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
5019 5048 case FOP(61, 22):
5020 5049 case FOP(62, 22):
5021 5050 case FOP(63, 22):
5022   - gen_op_cp1_64bitmode();
  5051 + check_cp1_64bitmode(ctx);
5023 5052 GEN_LOAD_FREG_FTN(WT0, fs);
5024 5053 GEN_LOAD_FREG_FTN(WTH0, fs);
5025 5054 GEN_LOAD_FREG_FTN(WT1, ft);
... ... @@ -5051,14 +5080,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
5051 5080 }
5052 5081  
5053 5082 /* Coprocessor 3 (FPU) */
5054   -static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
5055   - int fs, int base, int index)
  5083 +static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
  5084 + int fd, int fs, int base, int index)
5056 5085 {
5057 5086 const char *opn = "extended float load/store";
5058 5087 int store = 0;
5059 5088  
5060 5089 /* All of those work only on 64bit FPUs. */
5061   - gen_op_cp1_64bitmode();
  5090 + check_cp1_64bitmode(ctx);
5062 5091 if (base == 0) {
5063 5092 if (index == 0)
5064 5093 gen_op_reset_T0();
... ... @@ -5117,13 +5146,13 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
5117 5146 regnames[index], regnames[base]);
5118 5147 }
5119 5148  
5120   -static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
5121   - int fr, int fs, int ft)
  5149 +static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
  5150 + int fd, int fr, int fs, int ft)
5122 5151 {
5123 5152 const char *opn = "flt3_arith";
5124 5153  
5125 5154 /* All of those work only on 64bit FPUs. */
5126   - gen_op_cp1_64bitmode();
  5155 + check_cp1_64bitmode(ctx);
5127 5156 switch (opc) {
5128 5157 case OPC_ALNV_PS:
5129 5158 GEN_LOAD_REG_TN(T0, fr);
... ... @@ -5363,7 +5392,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5363 5392 case OPC_MOVCI:
5364 5393 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5365 5394 save_cpu_state(ctx, 1);
5366   - gen_op_cp1_enabled();
  5395 + check_cp1_enabled(ctx);
5367 5396 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
5368 5397 (ctx->opcode >> 16) & 1);
5369 5398 } else {
... ... @@ -5634,7 +5663,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5634 5663 case OPC_SDC1:
5635 5664 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5636 5665 save_cpu_state(ctx, 1);
5637   - gen_op_cp1_enabled();
  5666 + check_cp1_enabled(ctx);
5638 5667 gen_flt_ldst(ctx, op, rt, rs, imm);
5639 5668 } else {
5640 5669 generate_exception_err(ctx, EXCP_CpU, 1);
... ... @@ -5644,7 +5673,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5644 5673 case OPC_CP1:
5645 5674 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5646 5675 save_cpu_state(ctx, 1);
5647   - gen_op_cp1_enabled();
  5676 + check_cp1_enabled(ctx);
5648 5677 op1 = MASK_CP1(ctx->opcode);
5649 5678 switch (op1) {
5650 5679 case OPC_MFC1:
... ... @@ -5696,7 +5725,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5696 5725 case OPC_CP3:
5697 5726 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5698 5727 save_cpu_state(ctx, 1);
5699   - gen_op_cp1_enabled();
  5728 + check_cp1_enabled(ctx);
5700 5729 op1 = MASK_CP3(ctx->opcode);
5701 5730 switch (op1) {
5702 5731 case OPC_LWXC1:
... ... @@ -5960,7 +5989,7 @@ void fpu_dump_state(CPUState *env, FILE *f,
5960 5989 int flags)
5961 5990 {
5962 5991 int i;
5963   - int is_fpu64 = !!(env->CP0_Status & (1 << CP0St_FR));
  5992 + int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5964 5993  
5965 5994 #define printfpr(fp) \
5966 5995 do { \
... ... @@ -6038,7 +6067,6 @@ void cpu_dump_state (CPUState *env, FILE *f,
6038 6067 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6039 6068 int flags)
6040 6069 {
6041   - uint32_t c0_status;
6042 6070 int i;
6043 6071  
6044 6072 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,
6051 6079 cpu_fprintf(f, "\n");
6052 6080 }
6053 6081  
6054   - c0_status = env->CP0_Status;
6055   -
6056 6082 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
6057   - c0_status, env->CP0_Cause, env->CP0_EPC);
  6083 + env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
6058 6084 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6059 6085 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6060   - if (c0_status & (1 << CP0St_CU1))
  6086 + if (env->hflags & MIPS_HFLAG_FPU)
6061 6087 fpu_dump_state(env, f, cpu_fprintf, flags);
6062 6088 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6063 6089 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
... ...