OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <limits.h> | 5 #include <limits.h> |
6 #include <stdarg.h> | 6 #include <stdarg.h> |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #if V8_TARGET_ARCH_MIPS64 | 10 #if V8_TARGET_ARCH_MIPS64 |
(...skipping 1719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1730 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 | 1730 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 |
1731 ") dbl[0..1]:%e %e", | 1731 ") dbl[0..1]:%e %e", |
1732 v.d[0], v.d[1], icount_, v.df[0], v.df[1]); | 1732 v.d[0], v.d[1], icount_, v.df[0], v.df[1]); |
1733 break; | 1733 break; |
1734 default: | 1734 default: |
1735 UNREACHABLE(); | 1735 UNREACHABLE(); |
1736 } | 1736 } |
1737 } | 1737 } |
1738 } | 1738 } |
1739 | 1739 |
| 1740 template <typename T> |
| 1741 void Simulator::TraceMSARegWr(T* value) { |
| 1742 if (::v8::internal::FLAG_trace_sim) { |
| 1743 union { |
| 1744 uint8_t b[kMSALanesByte]; |
| 1745 uint16_t h[kMSALanesHalf]; |
| 1746 uint32_t w[kMSALanesWord]; |
| 1747 uint64_t d[kMSALanesDword]; |
| 1748 float f[kMSALanesWord]; |
| 1749 double df[kMSALanesDword]; |
| 1750 } v; |
| 1751 memcpy(v.b, value, kMSALanesByte); |
| 1752 |
| 1753 if (std::is_same<T, int32_t>::value) { |
| 1754 SNPrintF(trace_buf_, |
| 1755 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 |
| 1756 ") int32[0..3]:%" PRId32 " %" PRId32 " %" PRId32 |
| 1757 " %" PRId32, |
| 1758 v.d[0], v.d[1], icount_, v.w[0], v.w[1], v.w[2], v.w[3]); |
| 1759 } else if (std::is_same<T, float>::value) { |
| 1760 SNPrintF(trace_buf_, |
| 1761 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 |
| 1762 ") flt[0..3]:%e %e %e %e", |
| 1763 v.d[0], v.d[1], icount_, v.f[0], v.f[1], v.f[2], v.f[3]); |
| 1764 } else if (std::is_same<T, double>::value) { |
| 1765 SNPrintF(trace_buf_, |
| 1766 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 |
| 1767 ") dbl[0..1]:%e %e", |
| 1768 v.d[0], v.d[1], icount_, v.df[0], v.df[1]); |
| 1769 } else { |
| 1770 SNPrintF(trace_buf_, |
| 1771 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 ")", |
| 1772 v.d[0], v.d[1], icount_); |
| 1773 } |
| 1774 } |
| 1775 } |
| 1776 |
1740 // TODO(plind): consider making icount_ printing a flag option. | 1777 // TODO(plind): consider making icount_ printing a flag option. |
1741 void Simulator::TraceMemRd(int64_t addr, int64_t value, TraceType t) { | 1778 void Simulator::TraceMemRd(int64_t addr, int64_t value, TraceType t) { |
1742 if (::v8::internal::FLAG_trace_sim) { | 1779 if (::v8::internal::FLAG_trace_sim) { |
1743 union { | 1780 union { |
1744 int64_t fmt_int64; | 1781 int64_t fmt_int64; |
1745 int32_t fmt_int32[2]; | 1782 int32_t fmt_int32[2]; |
1746 float fmt_float[2]; | 1783 float fmt_float[2]; |
1747 double fmt_double; | 1784 double fmt_double; |
1748 } v; | 1785 } v; |
1749 v.fmt_int64 = value; | 1786 v.fmt_int64 = value; |
(...skipping 2728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4478 break; | 4515 break; |
4479 } | 4516 } |
4480 } | 4517 } |
4481 return df; | 4518 return df; |
4482 } | 4519 } |
4483 | 4520 |
4484 void Simulator::DecodeTypeMsaI8() { | 4521 void Simulator::DecodeTypeMsaI8() { |
4485 DCHECK(kArchVariant == kMips64r6); | 4522 DCHECK(kArchVariant == kMips64r6); |
4486 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); | 4523 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
4487 uint32_t opcode = instr_.InstructionBits() & kMsaI8Mask; | 4524 uint32_t opcode = instr_.InstructionBits() & kMsaI8Mask; |
| 4525 int8_t i8 = instr_.MsaImm8Value(); |
| 4526 msa_reg_t ws, wd; |
4488 | 4527 |
4489 switch (opcode) { | 4528 switch (opcode) { |
4490 case ANDI_B: | 4529 case ANDI_B: |
| 4530 get_msa_register(instr_.WsValue(), ws.b); |
| 4531 for (int i = 0; i < kMSALanesByte; i++) { |
| 4532 wd.b[i] = ws.b[i] & i8; |
| 4533 } |
| 4534 set_msa_register(instr_.WdValue(), wd.b); |
| 4535 TraceMSARegWr(wd.b); |
| 4536 break; |
4491 case ORI_B: | 4537 case ORI_B: |
| 4538 get_msa_register(instr_.WsValue(), ws.b); |
| 4539 for (int i = 0; i < kMSALanesByte; i++) { |
| 4540 wd.b[i] = ws.b[i] | i8; |
| 4541 } |
| 4542 set_msa_register(instr_.WdValue(), wd.b); |
| 4543 TraceMSARegWr(wd.b); |
| 4544 break; |
4492 case NORI_B: | 4545 case NORI_B: |
| 4546 get_msa_register(instr_.WsValue(), ws.b); |
| 4547 for (int i = 0; i < kMSALanesByte; i++) { |
| 4548 wd.b[i] = ~(ws.b[i] | i8); |
| 4549 } |
| 4550 set_msa_register(instr_.WdValue(), wd.b); |
| 4551 TraceMSARegWr(wd.b); |
| 4552 break; |
4493 case XORI_B: | 4553 case XORI_B: |
| 4554 get_msa_register(instr_.WsValue(), ws.b); |
| 4555 for (int i = 0; i < kMSALanesByte; i++) { |
| 4556 wd.b[i] = ws.b[i] ^ i8; |
| 4557 } |
| 4558 set_msa_register(instr_.WdValue(), wd.b); |
| 4559 TraceMSARegWr(wd.b); |
| 4560 break; |
4494 case BMNZI_B: | 4561 case BMNZI_B: |
| 4562 get_msa_register(instr_.WsValue(), ws.b); |
| 4563 get_msa_register(instr_.WdValue(), wd.b); |
| 4564 for (int i = 0; i < kMSALanesByte; i++) { |
| 4565 wd.b[i] = (ws.b[i] & i8) | (wd.b[i] & ~i8); |
| 4566 } |
| 4567 set_msa_register(instr_.WdValue(), wd.b); |
| 4568 TraceMSARegWr(wd.b); |
| 4569 break; |
4495 case BMZI_B: | 4570 case BMZI_B: |
| 4571 get_msa_register(instr_.WsValue(), ws.b); |
| 4572 get_msa_register(instr_.WdValue(), wd.b); |
| 4573 for (int i = 0; i < kMSALanesByte; i++) { |
| 4574 wd.b[i] = (ws.b[i] & ~i8) | (wd.b[i] & i8); |
| 4575 } |
| 4576 set_msa_register(instr_.WdValue(), wd.b); |
| 4577 TraceMSARegWr(wd.b); |
| 4578 break; |
4496 case BSELI_B: | 4579 case BSELI_B: |
| 4580 get_msa_register(instr_.WsValue(), ws.b); |
| 4581 get_msa_register(instr_.WdValue(), wd.b); |
| 4582 for (int i = 0; i < kMSALanesByte; i++) { |
| 4583 wd.b[i] = (ws.b[i] & ~wd.b[i]) | (wd.b[i] & i8); |
| 4584 } |
| 4585 set_msa_register(instr_.WdValue(), wd.b); |
| 4586 TraceMSARegWr(wd.b); |
| 4587 break; |
4497 case SHF_B: | 4588 case SHF_B: |
| 4589 get_msa_register(instr_.WsValue(), ws.b); |
| 4590 for (int i = 0; i < kMSALanesByte; i++) { |
| 4591 int j = i % 4; |
| 4592 int k = (i8 >> (2 * j)) & 0x3; |
| 4593 wd.b[i] = ws.b[i - j + k]; |
| 4594 } |
| 4595 set_msa_register(instr_.WdValue(), wd.b); |
| 4596 TraceMSARegWr(wd.b); |
| 4597 break; |
4498 case SHF_H: | 4598 case SHF_H: |
| 4599 get_msa_register(instr_.WsValue(), ws.h); |
| 4600 for (int i = 0; i < kMSALanesHalf; i++) { |
| 4601 int j = i % 4; |
| 4602 int k = (i8 >> (2 * j)) & 0x3; |
| 4603 wd.h[i] = ws.h[i - j + k]; |
| 4604 } |
| 4605 set_msa_register(instr_.WdValue(), wd.h); |
| 4606 TraceMSARegWr(wd.h); |
| 4607 break; |
4499 case SHF_W: | 4608 case SHF_W: |
4500 UNIMPLEMENTED(); | 4609 get_msa_register(instr_.WsValue(), ws.w); |
| 4610 for (int i = 0; i < kMSALanesWord; i++) { |
| 4611 int j = (i8 >> (2 * i)) & 0x3; |
| 4612 wd.w[i] = ws.w[j]; |
| 4613 } |
| 4614 set_msa_register(instr_.WdValue(), wd.w); |
| 4615 TraceMSARegWr(wd.w); |
4501 break; | 4616 break; |
4502 default: | 4617 default: |
4503 UNREACHABLE(); | 4618 UNREACHABLE(); |
4504 } | 4619 } |
4505 } | 4620 } |
4506 | 4621 |
4507 void Simulator::DecodeTypeMsaI5() { | 4622 void Simulator::DecodeTypeMsaI5() { |
4508 DCHECK(kArchVariant == kMips64r6); | 4623 DCHECK(kArchVariant == kMips64r6); |
4509 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); | 4624 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
4510 uint32_t opcode = instr_.InstructionBits() & kMsaI5Mask; | 4625 uint32_t opcode = instr_.InstructionBits() & kMsaI5Mask; |
(...skipping 29 matching lines...) Expand all Loading... |
4540 } | 4655 } |
4541 | 4656 |
4542 void Simulator::DecodeTypeMsaELM() { | 4657 void Simulator::DecodeTypeMsaELM() { |
4543 DCHECK(kArchVariant == kMips64r6); | 4658 DCHECK(kArchVariant == kMips64r6); |
4544 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); | 4659 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
4545 uint32_t opcode = instr_.InstructionBits() & kMsaELMMask; | 4660 uint32_t opcode = instr_.InstructionBits() & kMsaELMMask; |
4546 int32_t n = instr_.MsaElmNValue(); | 4661 int32_t n = instr_.MsaElmNValue(); |
4547 int64_t alu_out; | 4662 int64_t alu_out; |
4548 switch (opcode) { | 4663 switch (opcode) { |
4549 case COPY_S: | 4664 case COPY_S: |
4550 case COPY_U: | 4665 case COPY_U: { |
| 4666 msa_reg_t ws; |
| 4667 switch (DecodeMsaDataFormat()) { |
| 4668 case MSA_BYTE: |
| 4669 DCHECK(n < kMSALanesByte); |
| 4670 get_msa_register(instr_.WsValue(), ws.b); |
| 4671 alu_out = static_cast<int32_t>(ws.b[n]); |
| 4672 SetResult(wd_reg(), (opcode == COPY_U) ? alu_out & 0xFFu : alu_out); |
| 4673 break; |
| 4674 case MSA_HALF: |
| 4675 DCHECK(n < kMSALanesHalf); |
| 4676 get_msa_register(instr_.WsValue(), ws.h); |
| 4677 alu_out = static_cast<int32_t>(ws.h[n]); |
| 4678 SetResult(wd_reg(), (opcode == COPY_U) ? alu_out & 0xFFFFu : alu_out); |
| 4679 break; |
| 4680 case MSA_WORD: |
| 4681 DCHECK(n < kMSALanesWord); |
| 4682 get_msa_register(instr_.WsValue(), ws.w); |
| 4683 alu_out = static_cast<int32_t>(ws.w[n]); |
| 4684 SetResult(wd_reg(), |
| 4685 (opcode == COPY_U) ? alu_out & 0xFFFFFFFFu : alu_out); |
| 4686 break; |
| 4687 case MSA_DWORD: |
| 4688 DCHECK(n < kMSALanesDword); |
| 4689 get_msa_register(instr_.WsValue(), ws.d); |
| 4690 alu_out = static_cast<int64_t>(ws.d[n]); |
| 4691 SetResult(wd_reg(), alu_out); |
| 4692 break; |
| 4693 default: |
| 4694 UNREACHABLE(); |
| 4695 } |
| 4696 } break; |
| 4697 case INSERT: { |
| 4698 msa_reg_t wd; |
4551 switch (DecodeMsaDataFormat()) { | 4699 switch (DecodeMsaDataFormat()) { |
4552 case MSA_BYTE: { | 4700 case MSA_BYTE: { |
4553 DCHECK(n < 16); | 4701 DCHECK(n < kMSALanesByte); |
4554 int8_t ws[16]; | 4702 int64_t rs = get_register(instr_.WsValue()); |
4555 get_msa_register(instr_.WsValue(), ws); | 4703 get_msa_register(instr_.WdValue(), wd.b); |
4556 alu_out = static_cast<int32_t>(ws[n]); | 4704 wd.b[n] = rs & 0xFFu; |
4557 SetResult(wd_reg(), (opcode == COPY_U) ? alu_out & 0xFFu : alu_out); | 4705 set_msa_register(instr_.WdValue(), wd.b); |
| 4706 TraceMSARegWr(wd.b); |
4558 break; | 4707 break; |
4559 } | 4708 } |
4560 case MSA_HALF: { | 4709 case MSA_HALF: { |
4561 DCHECK(n < 8); | 4710 DCHECK(n < kMSALanesHalf); |
4562 int16_t ws[8]; | 4711 int64_t rs = get_register(instr_.WsValue()); |
4563 get_msa_register(instr_.WsValue(), ws); | 4712 get_msa_register(instr_.WdValue(), wd.h); |
4564 alu_out = static_cast<int32_t>(ws[n]); | 4713 wd.h[n] = rs & 0xFFFFu; |
4565 SetResult(wd_reg(), (opcode == COPY_U) ? alu_out & 0xFFFFu : alu_out); | 4714 set_msa_register(instr_.WdValue(), wd.h); |
| 4715 TraceMSARegWr(wd.h); |
4566 break; | 4716 break; |
4567 } | 4717 } |
4568 case MSA_WORD: { | 4718 case MSA_WORD: { |
4569 DCHECK(n < 4); | 4719 DCHECK(n < kMSALanesWord); |
4570 int32_t ws[4]; | 4720 int64_t rs = get_register(instr_.WsValue()); |
4571 get_msa_register(instr_.WsValue(), ws); | 4721 get_msa_register(instr_.WdValue(), wd.w); |
4572 alu_out = static_cast<int32_t>(ws[n]); | 4722 wd.w[n] = rs & 0xFFFFFFFFu; |
4573 SetResult(wd_reg(), | 4723 set_msa_register(instr_.WdValue(), wd.w); |
4574 (opcode == COPY_U) ? alu_out & 0xFFFFFFFFu : alu_out); | 4724 TraceMSARegWr(wd.w); |
4575 break; | 4725 break; |
4576 } | 4726 } |
4577 case MSA_DWORD: { | 4727 case MSA_DWORD: { |
4578 DCHECK(n < 2); | 4728 DCHECK(n < kMSALanesDword); |
4579 int64_t ws[2]; | 4729 int64_t rs = get_register(instr_.WsValue()); |
4580 get_msa_register(instr_.WsValue(), ws); | 4730 get_msa_register(instr_.WdValue(), wd.d); |
4581 alu_out = static_cast<int64_t>(ws[n]); | 4731 wd.d[n] = rs; |
4582 SetResult(wd_reg(), alu_out); | 4732 set_msa_register(instr_.WdValue(), wd.d); |
| 4733 TraceMSARegWr(wd.d); |
4583 break; | 4734 break; |
4584 } | 4735 } |
4585 default: | 4736 default: |
4586 UNREACHABLE(); | 4737 UNREACHABLE(); |
4587 } | 4738 } |
4588 break; | 4739 } break; |
4589 case SLDI: | 4740 case SLDI: |
4590 case SPLATI: | 4741 case SPLATI: |
4591 case INSERT: | |
4592 case INSVE: | 4742 case INSVE: |
4593 UNIMPLEMENTED(); | 4743 UNIMPLEMENTED(); |
4594 break; | 4744 break; |
4595 default: | 4745 default: |
4596 UNREACHABLE(); | 4746 UNREACHABLE(); |
4597 } | 4747 } |
4598 } | 4748 } |
4599 | 4749 |
4600 void Simulator::DecodeTypeMsaBIT() { | 4750 void Simulator::DecodeTypeMsaBIT() { |
4601 DCHECK(kArchVariant == kMips64r6); | 4751 DCHECK(kArchVariant == kMips64r6); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4779 break; | 4929 break; |
4780 default: | 4930 default: |
4781 UNREACHABLE(); | 4931 UNREACHABLE(); |
4782 } | 4932 } |
4783 } | 4933 } |
4784 | 4934 |
4785 void Simulator::DecodeTypeMsa2R() { | 4935 void Simulator::DecodeTypeMsa2R() { |
4786 DCHECK(kArchVariant == kMips64r6); | 4936 DCHECK(kArchVariant == kMips64r6); |
4787 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); | 4937 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
4788 uint32_t opcode = instr_.InstructionBits() & kMsa2RMask; | 4938 uint32_t opcode = instr_.InstructionBits() & kMsa2RMask; |
| 4939 msa_reg_t wd; |
4789 switch (opcode) { | 4940 switch (opcode) { |
4790 case FILL: | 4941 case FILL: |
4791 switch (DecodeMsaDataFormat()) { | 4942 switch (DecodeMsaDataFormat()) { |
4792 case MSA_BYTE: { | 4943 case MSA_BYTE: { |
4793 int8_t wd[16]; | |
4794 int64_t rs = get_register(instr_.WsValue()); | 4944 int64_t rs = get_register(instr_.WsValue()); |
4795 for (int i = 0; i < 16; i++) { | 4945 for (int i = 0; i < kMSALanesByte; i++) { |
4796 wd[i] = rs & 0xFFu; | 4946 wd.b[i] = rs & 0xFFu; |
4797 } | 4947 } |
4798 set_msa_register(instr_.WdValue(), wd); | 4948 set_msa_register(instr_.WdValue(), wd.b); |
4799 TraceMSARegWr(wd, BYTE); | 4949 TraceMSARegWr(wd.b); |
4800 break; | 4950 break; |
4801 } | 4951 } |
4802 case MSA_HALF: { | 4952 case MSA_HALF: { |
4803 int16_t wd[8]; | |
4804 int64_t rs = get_register(instr_.WsValue()); | 4953 int64_t rs = get_register(instr_.WsValue()); |
4805 for (int i = 0; i < 8; i++) { | 4954 for (int i = 0; i < kMSALanesHalf; i++) { |
4806 wd[i] = rs & 0xFFFFu; | 4955 wd.h[i] = rs & 0xFFFFu; |
4807 } | 4956 } |
4808 set_msa_register(instr_.WdValue(), wd); | 4957 set_msa_register(instr_.WdValue(), wd.h); |
4809 TraceMSARegWr(wd, HALF); | 4958 TraceMSARegWr(wd.h); |
4810 break; | 4959 break; |
4811 } | 4960 } |
4812 case MSA_WORD: { | 4961 case MSA_WORD: { |
4813 int32_t wd[4]; | |
4814 int64_t rs = get_register(instr_.WsValue()); | 4962 int64_t rs = get_register(instr_.WsValue()); |
4815 for (int i = 0; i < 4; i++) { | 4963 for (int i = 0; i < kMSALanesWord; i++) { |
4816 wd[i] = rs & 0xFFFFFFFFu; | 4964 wd.w[i] = rs & 0xFFFFFFFFu; |
4817 } | 4965 } |
4818 set_msa_register(instr_.WdValue(), wd); | 4966 set_msa_register(instr_.WdValue(), wd.w); |
4819 TraceMSARegWr(wd, WORD); | 4967 TraceMSARegWr(wd.w); |
4820 break; | 4968 break; |
4821 } | 4969 } |
4822 case MSA_DWORD: { | 4970 case MSA_DWORD: { |
4823 int64_t wd[2]; | |
4824 int64_t rs = get_register(instr_.WsValue()); | 4971 int64_t rs = get_register(instr_.WsValue()); |
4825 wd[0] = wd[1] = rs; | 4972 wd.d[0] = wd.d[1] = rs; |
4826 set_msa_register(instr_.WdValue(), wd); | 4973 set_msa_register(instr_.WdValue(), wd.d); |
4827 TraceMSARegWr(wd, DWORD); | 4974 TraceMSARegWr(wd.d); |
4828 break; | 4975 break; |
4829 } | 4976 } |
4830 default: | 4977 default: |
4831 UNREACHABLE(); | 4978 UNREACHABLE(); |
4832 } | 4979 } |
4833 break; | 4980 break; |
4834 case PCNT: | 4981 case PCNT: |
4835 case NLOC: | 4982 case NLOC: |
4836 case NLZC: | 4983 case NLZC: |
4837 UNIMPLEMENTED(); | 4984 UNIMPLEMENTED(); |
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5764 } | 5911 } |
5765 | 5912 |
5766 | 5913 |
5767 #undef UNSUPPORTED | 5914 #undef UNSUPPORTED |
5768 } // namespace internal | 5915 } // namespace internal |
5769 } // namespace v8 | 5916 } // namespace v8 |
5770 | 5917 |
5771 #endif // USE_SIMULATOR | 5918 #endif // USE_SIMULATOR |
5772 | 5919 |
5773 #endif // V8_TARGET_ARCH_MIPS64 | 5920 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |