Revision 5e755519

b/target-mips/cpu.h
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
b/target-mips/fop_template.c
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 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; \
b/target-mips/op.c
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 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 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) {
b/target-mips/translate.c
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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);

Also available in: Unified diff