Revision 5e755519 target-mips/translate.c
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