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