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_MIPS | 10 #if V8_TARGET_ARCH_MIPS |
(...skipping 1111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1122 // Read the bits from the unsigned integer register_[] array | 1122 // Read the bits from the unsigned integer register_[] array |
1123 // into the double precision floating point value and return it. | 1123 // into the double precision floating point value and return it. |
1124 char buffer[2 * sizeof(registers_[0])]; | 1124 char buffer[2 * sizeof(registers_[0])]; |
1125 memcpy(buffer, ®isters_[reg], 2 * sizeof(registers_[0])); | 1125 memcpy(buffer, ®isters_[reg], 2 * sizeof(registers_[0])); |
1126 memcpy(&dm_val, buffer, 2 * sizeof(registers_[0])); | 1126 memcpy(&dm_val, buffer, 2 * sizeof(registers_[0])); |
1127 return(dm_val); | 1127 return(dm_val); |
1128 } | 1128 } |
1129 | 1129 |
1130 | 1130 |
1131 int64_t Simulator::get_fpu_register(int fpureg) const { | 1131 int64_t Simulator::get_fpu_register(int fpureg) const { |
1132 DCHECK(IsFp64Mode()); | 1132 if (IsFp64Mode()) { |
1133 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1133 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1134 return FPUregisters_[fpureg]; | 1134 return FPUregisters_[fpureg]; |
1135 } else { | |
1136 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); | |
1137 uint64_t i64; | |
1138 i64 = static_cast<uint32_t>(get_fpu_register_word(fpureg)); | |
1139 i64 |= static_cast<uint64_t>(get_fpu_register_word(fpureg + 1)) << 32; | |
1140 return static_cast<int64_t>(i64); | |
1141 } | |
1135 } | 1142 } |
1136 | 1143 |
1137 | 1144 |
1138 int32_t Simulator::get_fpu_register_word(int fpureg) const { | 1145 int32_t Simulator::get_fpu_register_word(int fpureg) const { |
1139 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1146 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1140 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff); | 1147 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff); |
1141 } | 1148 } |
1142 | 1149 |
1143 | 1150 |
1144 int32_t Simulator::get_fpu_register_signed_word(int fpureg) const { | 1151 int32_t Simulator::get_fpu_register_signed_word(int fpureg) const { |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1681 | 1688 |
1682 | 1689 |
1683 // The MIPS cannot do unaligned reads and writes. On some MIPS platforms an | 1690 // The MIPS cannot do unaligned reads and writes. On some MIPS platforms an |
1684 // interrupt is caused. On others it does a funky rotation thing. For now we | 1691 // interrupt is caused. On others it does a funky rotation thing. For now we |
1685 // simply disallow unaligned reads, but at some point we may want to move to | 1692 // simply disallow unaligned reads, but at some point we may want to move to |
1686 // emulating the rotate behaviour. Note that simulator runs have the runtime | 1693 // emulating the rotate behaviour. Note that simulator runs have the runtime |
1687 // system running directly on the host system and only generated code is | 1694 // system running directly on the host system and only generated code is |
1688 // executed in the simulator. Since the host is typically IA32 we will not | 1695 // executed in the simulator. Since the host is typically IA32 we will not |
1689 // get the correct MIPS-like behaviour on unaligned accesses. | 1696 // get the correct MIPS-like behaviour on unaligned accesses. |
1690 | 1697 |
1691 void Simulator::TraceRegWr(int32_t value) { | 1698 void Simulator::TraceRegWr(int32_t value, TraceType t) { |
1692 if (::v8::internal::FLAG_trace_sim) { | 1699 if (::v8::internal::FLAG_trace_sim) { |
1693 SNPrintF(trace_buf_, "%08x", value); | 1700 union { |
1701 int32_t fmt_int32; | |
1702 float fmt_float; | |
1703 } v; | |
1704 v.fmt_int32 = value; | |
1705 | |
1706 switch (t) { | |
1707 case WORD: | |
1708 SNPrintF(trace_buf_, "%08" PRIx32 " (%" PRIu64 ") int32:%" PRId32 | |
1709 " uint32:%" PRIu32, | |
1710 value, icount_, value, value); | |
1711 break; | |
1712 case FLOAT: | |
1713 SNPrintF(trace_buf_, "%08" PRIx32 " (%" PRIu64 ") flt:%e", | |
1714 v.fmt_int32, icount_, v.fmt_float); | |
1715 break; | |
1716 default: | |
1717 UNREACHABLE(); | |
1718 } | |
1694 } | 1719 } |
1695 } | 1720 } |
1696 | 1721 |
1722 void Simulator::TraceRegWr(int64_t value, TraceType t) { | |
1723 if (::v8::internal::FLAG_trace_sim) { | |
1724 union { | |
1725 int64_t fmt_int64; | |
1726 double fmt_double; | |
1727 } v; | |
1728 v.fmt_int64 = value; | |
1697 | 1729 |
1698 // TODO(plind): consider making icount_ printing a flag option. | 1730 switch (t) { |
1699 void Simulator::TraceMemRd(int32_t addr, int32_t value) { | 1731 case DWORD: |
1700 if (::v8::internal::FLAG_trace_sim) { | 1732 SNPrintF(trace_buf_, "%016" PRIx64 " (%" PRIu64 ") int64:%" PRId64 |
1701 SNPrintF(trace_buf_, "%08x <-- [%08x] (%" PRIu64 ")", value, addr, | 1733 " uint64:%" PRIu64, |
1702 icount_); | 1734 value, icount_, value, value); |
1735 break; | |
1736 case DOUBLE: | |
1737 SNPrintF(trace_buf_, "%016" PRIx64 " (%" PRIu64 ") dbl:%e", | |
1738 v.fmt_int64, icount_, v.fmt_double); | |
1739 break; | |
1740 default: | |
1741 UNREACHABLE(); | |
1742 } | |
1703 } | 1743 } |
1704 } | 1744 } |
1705 | 1745 |
1746 // TODO(plind): consider making icount_ printing a flag option. | |
1747 void Simulator::TraceMemRd(int32_t addr, int32_t value, TraceType t) { | |
1748 if (::v8::internal::FLAG_trace_sim) { | |
1749 union { | |
1750 int32_t fmt_int32; | |
1751 float fmt_float; | |
1752 } v; | |
1753 v.fmt_int32 = value; | |
1754 | |
1755 switch (t) { | |
1756 case WORD: | |
1757 SNPrintF(trace_buf_, "%08" PRIx32 " <-- [%08" PRIx32 "] (%" PRIu64 | |
1758 ") int32:%" PRId32 " uint32:%" PRIu32, | |
1759 value, addr, icount_, value, value); | |
1760 break; | |
1761 case FLOAT: | |
1762 SNPrintF(trace_buf_, | |
1763 "%08" PRIx32 " <-- [%08" PRIx32 "] (%" PRIu64 ") flt:%e", | |
1764 v.fmt_int32, addr, icount_, v.fmt_float); | |
1765 break; | |
1766 default: | |
1767 UNREACHABLE(); | |
1768 } | |
1769 } | |
1770 } | |
1771 | |
1706 | 1772 |
1707 void Simulator::TraceMemWr(int32_t addr, int32_t value, TraceType t) { | 1773 void Simulator::TraceMemWr(int32_t addr, int32_t value, TraceType t) { |
1708 if (::v8::internal::FLAG_trace_sim) { | 1774 if (::v8::internal::FLAG_trace_sim) { |
1709 switch (t) { | 1775 switch (t) { |
1710 case BYTE: | 1776 case BYTE: |
1711 SNPrintF(trace_buf_, " %02x --> [%08x]", | 1777 SNPrintF(trace_buf_, |
1712 static_cast<int8_t>(value), addr); | 1778 " %02" PRIx8 " --> [%08" PRIx32 "] (%" PRIu64 ")", |
1779 static_cast<uint8_t>(value), addr, icount_); | |
1713 break; | 1780 break; |
1714 case HALF: | 1781 case HALF: |
1715 SNPrintF(trace_buf_, " %04x --> [%08x]", static_cast<int16_t>(value), | 1782 SNPrintF(trace_buf_, |
1716 addr); | 1783 " %04" PRIx16 " --> [%08" PRIx32 "] (%" PRIu64 ")", |
1784 static_cast<uint16_t>(value), addr, icount_); | |
1717 break; | 1785 break; |
1718 case WORD: | 1786 case WORD: |
1719 SNPrintF(trace_buf_, "%08x --> [%08x]", value, addr); | 1787 SNPrintF(trace_buf_, |
1788 "%08" PRIx32 " --> [%08" PRIx32 "] (%" PRIu64 ")", value, | |
1789 addr, icount_); | |
1720 break; | 1790 break; |
1791 default: | |
1792 UNREACHABLE(); | |
1721 } | 1793 } |
1722 } | 1794 } |
1723 } | 1795 } |
1724 | 1796 |
1797 void Simulator::TraceMemRd(int32_t addr, int64_t value, TraceType t) { | |
1798 if (::v8::internal::FLAG_trace_sim) { | |
1799 union { | |
1800 int64_t fmt_int64; | |
1801 int32_t fmt_int32[2]; | |
1802 float fmt_float[2]; | |
1803 double fmt_double; | |
1804 } v; | |
1805 v.fmt_int64 = value; | |
1725 | 1806 |
1726 int Simulator::ReadW(int32_t addr, Instruction* instr) { | 1807 switch (t) { |
1808 case DWORD: | |
1809 SNPrintF(trace_buf_, "%016" PRIx64 " <-- [%08" PRIx32 "] (%" PRIu64 | |
1810 ") int64:%" PRId64 " uint64:%" PRIu64, | |
1811 v.fmt_int64, addr, icount_, v.fmt_int64, v.fmt_int64); | |
1812 break; | |
1813 case DOUBLE: | |
1814 SNPrintF(trace_buf_, "%016" PRIx64 " <-- [%08" PRIx32 "] (%" PRIu64 | |
1815 ") dbl:%e", | |
1816 v.fmt_int64, addr, icount_, v.fmt_double); | |
1817 break; | |
1818 case FLOAT_DOUBLE: | |
1819 SNPrintF(trace_buf_, "%08" PRIx32 " <-- [%08" PRIx32 "] (%" PRIu64 | |
1820 ") flt:%e dbl:%e", | |
1821 v.fmt_int32[1], addr, icount_, v.fmt_float[1], v.fmt_double); | |
1822 break; | |
1823 default: | |
1824 UNREACHABLE(); | |
1825 } | |
1826 } | |
1827 } | |
1828 | |
1829 void Simulator::TraceMemWr(int32_t addr, int64_t value, TraceType t) { | |
1830 if (::v8::internal::FLAG_trace_sim) { | |
1831 switch (t) { | |
1832 case DWORD: | |
1833 SNPrintF(trace_buf_, | |
1834 "%016" PRIx64 " --> [%08" PRIx32 "] (%" PRIu64 ")", value, | |
1835 addr, icount_); | |
1836 break; | |
1837 default: | |
1838 UNREACHABLE(); | |
1839 } | |
1840 } | |
1841 } | |
1842 | |
1843 int Simulator::ReadW(int32_t addr, Instruction* instr, TraceType t) { | |
1727 if (addr >=0 && addr < 0x400) { | 1844 if (addr >=0 && addr < 0x400) { |
1728 // This has to be a NULL-dereference, drop into debugger. | 1845 // This has to be a NULL-dereference, drop into debugger. |
1729 PrintF("Memory read from bad address: 0x%08x, pc=0x%08" PRIxPTR "\n", addr, | 1846 PrintF("Memory read from bad address: 0x%08x, pc=0x%08" PRIxPTR "\n", addr, |
1730 reinterpret_cast<intptr_t>(instr)); | 1847 reinterpret_cast<intptr_t>(instr)); |
1731 MipsDebugger dbg(this); | 1848 MipsDebugger dbg(this); |
1732 dbg.Debug(); | 1849 dbg.Debug(); |
1733 } | 1850 } |
1734 if ((addr & kPointerAlignmentMask) == 0 || IsMipsArchVariant(kMips32r6)) { | 1851 if ((addr & kPointerAlignmentMask) == 0 || IsMipsArchVariant(kMips32r6)) { |
1735 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); | 1852 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); |
1736 TraceMemRd(addr, static_cast<int32_t>(*ptr)); | 1853 switch (t) { |
1854 case WORD: | |
1855 TraceMemRd(addr, static_cast<int32_t>(*ptr), t); | |
1856 break; | |
1857 case FLOAT: | |
1858 // This TraceType is allowed but tracing for this value will be omitted. | |
1859 break; | |
1860 default: | |
1861 UNREACHABLE(); | |
1862 } | |
1737 return *ptr; | 1863 return *ptr; |
1738 } | 1864 } |
1739 PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n", | 1865 PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n", |
1740 addr, | 1866 addr, |
1741 reinterpret_cast<intptr_t>(instr)); | 1867 reinterpret_cast<intptr_t>(instr)); |
1742 MipsDebugger dbg(this); | 1868 MipsDebugger dbg(this); |
1743 dbg.Debug(); | 1869 dbg.Debug(); |
1744 return 0; | 1870 return 0; |
1745 } | 1871 } |
1746 | 1872 |
1747 | |
1748 void Simulator::WriteW(int32_t addr, int value, Instruction* instr) { | 1873 void Simulator::WriteW(int32_t addr, int value, Instruction* instr) { |
1749 if (addr >= 0 && addr < 0x400) { | 1874 if (addr >= 0 && addr < 0x400) { |
1750 // This has to be a NULL-dereference, drop into debugger. | 1875 // This has to be a NULL-dereference, drop into debugger. |
1751 PrintF("Memory write to bad address: 0x%08x, pc=0x%08" PRIxPTR "\n", addr, | 1876 PrintF("Memory write to bad address: 0x%08x, pc=0x%08" PRIxPTR "\n", addr, |
1752 reinterpret_cast<intptr_t>(instr)); | 1877 reinterpret_cast<intptr_t>(instr)); |
1753 MipsDebugger dbg(this); | 1878 MipsDebugger dbg(this); |
1754 dbg.Debug(); | 1879 dbg.Debug(); |
1755 } | 1880 } |
1756 if ((addr & kPointerAlignmentMask) == 0 || IsMipsArchVariant(kMips32r6)) { | 1881 if ((addr & kPointerAlignmentMask) == 0 || IsMipsArchVariant(kMips32r6)) { |
1757 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); | 1882 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); |
1758 TraceMemWr(addr, value, WORD); | 1883 TraceMemWr(addr, value, WORD); |
1759 *ptr = value; | 1884 *ptr = value; |
1760 return; | 1885 return; |
1761 } | 1886 } |
1762 PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n", | 1887 PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n", |
1763 addr, | 1888 addr, |
1764 reinterpret_cast<intptr_t>(instr)); | 1889 reinterpret_cast<intptr_t>(instr)); |
1765 MipsDebugger dbg(this); | 1890 MipsDebugger dbg(this); |
1766 dbg.Debug(); | 1891 dbg.Debug(); |
1767 } | 1892 } |
1768 | 1893 |
1769 | |
1770 double Simulator::ReadD(int32_t addr, Instruction* instr) { | 1894 double Simulator::ReadD(int32_t addr, Instruction* instr) { |
1771 if ((addr & kDoubleAlignmentMask) == 0 || IsMipsArchVariant(kMips32r6)) { | 1895 if ((addr & kDoubleAlignmentMask) == 0 || IsMipsArchVariant(kMips32r6)) { |
1772 double* ptr = reinterpret_cast<double*>(addr); | 1896 double* ptr = reinterpret_cast<double*>(addr); |
1773 return *ptr; | 1897 return *ptr; |
1774 } | 1898 } |
1775 PrintF("Unaligned (double) read at 0x%08x, pc=0x%08" V8PRIxPTR "\n", | 1899 PrintF("Unaligned (double) read at 0x%08x, pc=0x%08" V8PRIxPTR "\n", |
1776 addr, | 1900 addr, |
1777 reinterpret_cast<intptr_t>(instr)); | 1901 reinterpret_cast<intptr_t>(instr)); |
1778 base::OS::Abort(); | 1902 base::OS::Abort(); |
1779 return 0; | 1903 return 0; |
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2457 result = upper; | 2581 result = upper; |
2458 break; | 2582 break; |
2459 case kRoundToMinusInf: | 2583 case kRoundToMinusInf: |
2460 result = lower; | 2584 result = lower; |
2461 break; | 2585 break; |
2462 } | 2586 } |
2463 set_fpu_register_double(fd_reg(), result); | 2587 set_fpu_register_double(fd_reg(), result); |
2464 if (result != fs) { | 2588 if (result != fs) { |
2465 set_fcsr_bit(kFCSRInexactFlagBit, true); | 2589 set_fcsr_bit(kFCSRInexactFlagBit, true); |
2466 } | 2590 } |
2591 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2467 break; | 2592 break; |
2468 } | 2593 } |
2469 case SEL: | 2594 case SEL: |
2470 DCHECK(IsMipsArchVariant(kMips32r6)); | 2595 DCHECK(IsMipsArchVariant(kMips32r6)); |
2471 set_fpu_register_double(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); | 2596 set_fpu_register_double(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); |
2597 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2472 break; | 2598 break; |
2473 case SELEQZ_C: | 2599 case SELEQZ_C: |
2474 DCHECK(IsMipsArchVariant(kMips32r6)); | 2600 DCHECK(IsMipsArchVariant(kMips32r6)); |
2475 set_fpu_register_double(fd_reg(), (ft_int & 0x1) == 0 ? fs : 0.0); | 2601 set_fpu_register_double(fd_reg(), (ft_int & 0x1) == 0 ? fs : 0.0); |
2602 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2476 break; | 2603 break; |
2477 case SELNEZ_C: | 2604 case SELNEZ_C: |
2478 DCHECK(IsMipsArchVariant(kMips32r6)); | 2605 DCHECK(IsMipsArchVariant(kMips32r6)); |
2479 set_fpu_register_double(fd_reg(), (ft_int & 0x1) != 0 ? fs : 0.0); | 2606 set_fpu_register_double(fd_reg(), (ft_int & 0x1) != 0 ? fs : 0.0); |
2607 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2480 break; | 2608 break; |
2481 case MOVZ_C: { | 2609 case MOVZ_C: { |
2482 DCHECK(IsMipsArchVariant(kMips32r2)); | 2610 DCHECK(IsMipsArchVariant(kMips32r2)); |
2483 if (rt() == 0) { | 2611 if (rt() == 0) { |
2484 set_fpu_register_double(fd_reg(), fs); | 2612 set_fpu_register_double(fd_reg(), fs); |
2485 } | 2613 } |
2614 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
ivica.bogosavljevic
2017/01/27 09:55:11
If rt() != 0, the trace will point that the value
Ilija.Pavlovic1
2017/01/31 08:59:35
Done.
| |
2486 break; | 2615 break; |
2487 } | 2616 } |
2488 case MOVN_C: { | 2617 case MOVN_C: { |
2489 DCHECK(IsMipsArchVariant(kMips32r2)); | 2618 DCHECK(IsMipsArchVariant(kMips32r2)); |
2490 int32_t rt_reg = instr_.RtValue(); | 2619 int32_t rt_reg = instr_.RtValue(); |
2491 int32_t rt = get_register(rt_reg); | 2620 int32_t rt = get_register(rt_reg); |
2492 if (rt != 0) { | 2621 if (rt != 0) { |
2493 set_fpu_register_double(fd_reg(), fs); | 2622 set_fpu_register_double(fd_reg(), fs); |
2494 } | 2623 } |
2624 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2495 break; | 2625 break; |
2496 } | 2626 } |
2497 case MOVF: { | 2627 case MOVF: { |
2498 // Same function field for MOVT.D and MOVF.D | 2628 // Same function field for MOVT.D and MOVF.D |
2499 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; | 2629 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; |
2500 ft_cc = get_fcsr_condition_bit(ft_cc); | 2630 ft_cc = get_fcsr_condition_bit(ft_cc); |
2501 if (instr_.Bit(16)) { // Read Tf bit. | 2631 if (instr_.Bit(16)) { // Read Tf bit. |
2502 // MOVT.D | 2632 // MOVT.D |
2503 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); | 2633 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); |
2504 } else { | 2634 } else { |
2505 // MOVF.D | 2635 // MOVF.D |
2506 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); | 2636 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); |
2507 } | 2637 } |
2638 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2508 break; | 2639 break; |
2509 } | 2640 } |
2510 case MIN: | 2641 case MIN: |
2511 DCHECK(IsMipsArchVariant(kMips32r6)); | 2642 DCHECK(IsMipsArchVariant(kMips32r6)); |
2512 set_fpu_register_double(fd_reg(), FPUMin(ft, fs)); | 2643 set_fpu_register_double(fd_reg(), FPUMin(ft, fs)); |
2644 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
ivica.bogosavljevic
2017/01/27 09:55:11
I think it would be a very good idea to implement
Ilija.Pavlovic1
2017/01/31 08:59:35
Done.
| |
2513 break; | 2645 break; |
2514 case MAX: | 2646 case MAX: |
2515 DCHECK(IsMipsArchVariant(kMips32r6)); | 2647 DCHECK(IsMipsArchVariant(kMips32r6)); |
2516 set_fpu_register_double(fd_reg(), FPUMax(ft, fs)); | 2648 set_fpu_register_double(fd_reg(), FPUMax(ft, fs)); |
2649 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2517 break; | 2650 break; |
2518 case MINA: | 2651 case MINA: |
2519 DCHECK(IsMipsArchVariant(kMips32r6)); | 2652 DCHECK(IsMipsArchVariant(kMips32r6)); |
2520 set_fpu_register_double(fd_reg(), FPUMinA(ft, fs)); | 2653 set_fpu_register_double(fd_reg(), FPUMinA(ft, fs)); |
2654 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2521 break; | 2655 break; |
2522 case MAXA: | 2656 case MAXA: |
2523 DCHECK(IsMipsArchVariant(kMips32r6)); | 2657 DCHECK(IsMipsArchVariant(kMips32r6)); |
2524 set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs)); | 2658 set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs)); |
2659 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2525 break; | 2660 break; |
2526 case ADD_D: | 2661 case ADD_D: |
2527 set_fpu_register_double( | 2662 set_fpu_register_double( |
2528 fd_reg(), | 2663 fd_reg(), |
2529 FPUCanonalizeOperation( | 2664 FPUCanonalizeOperation( |
2530 [](double lhs, double rhs) { return lhs + rhs; }, fs, ft)); | 2665 [](double lhs, double rhs) { return lhs + rhs; }, fs, ft)); |
2666 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2531 break; | 2667 break; |
2532 case SUB_D: | 2668 case SUB_D: |
2533 set_fpu_register_double( | 2669 set_fpu_register_double( |
2534 fd_reg(), | 2670 fd_reg(), |
2535 FPUCanonalizeOperation( | 2671 FPUCanonalizeOperation( |
2536 [](double lhs, double rhs) { return lhs - rhs; }, fs, ft)); | 2672 [](double lhs, double rhs) { return lhs - rhs; }, fs, ft)); |
2673 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2537 break; | 2674 break; |
2538 case MADDF_D: | 2675 case MADDF_D: |
2539 DCHECK(IsMipsArchVariant(kMips32r6)); | 2676 DCHECK(IsMipsArchVariant(kMips32r6)); |
2540 set_fpu_register_double(fd_reg(), std::fma(fs, ft, fd)); | 2677 set_fpu_register_double(fd_reg(), std::fma(fs, ft, fd)); |
2678 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2541 break; | 2679 break; |
2542 case MSUBF_D: | 2680 case MSUBF_D: |
2543 DCHECK(IsMipsArchVariant(kMips32r6)); | 2681 DCHECK(IsMipsArchVariant(kMips32r6)); |
2544 set_fpu_register_double(fd_reg(), std::fma(-fs, ft, fd)); | 2682 set_fpu_register_double(fd_reg(), std::fma(-fs, ft, fd)); |
2683 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2545 break; | 2684 break; |
2546 case MUL_D: | 2685 case MUL_D: |
2547 set_fpu_register_double( | 2686 set_fpu_register_double( |
2548 fd_reg(), | 2687 fd_reg(), |
2549 FPUCanonalizeOperation( | 2688 FPUCanonalizeOperation( |
2550 [](double lhs, double rhs) { return lhs * rhs; }, fs, ft)); | 2689 [](double lhs, double rhs) { return lhs * rhs; }, fs, ft)); |
2690 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2551 break; | 2691 break; |
2552 case DIV_D: | 2692 case DIV_D: |
2553 set_fpu_register_double( | 2693 set_fpu_register_double( |
2554 fd_reg(), | 2694 fd_reg(), |
2555 FPUCanonalizeOperation( | 2695 FPUCanonalizeOperation( |
2556 [](double lhs, double rhs) { return lhs / rhs; }, fs, ft)); | 2696 [](double lhs, double rhs) { return lhs / rhs; }, fs, ft)); |
2697 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2557 break; | 2698 break; |
2558 case ABS_D: | 2699 case ABS_D: |
2559 set_fpu_register_double( | 2700 set_fpu_register_double( |
2560 fd_reg(), | 2701 fd_reg(), |
2561 FPUCanonalizeOperation([](double fs) { return FPAbs(fs); }, fs)); | 2702 FPUCanonalizeOperation([](double fs) { return FPAbs(fs); }, fs)); |
2703 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2562 break; | 2704 break; |
2563 case MOV_D: | 2705 case MOV_D: |
2564 set_fpu_register_double(fd_reg(), fs); | 2706 set_fpu_register_double(fd_reg(), fs); |
2707 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2565 break; | 2708 break; |
2566 case NEG_D: | 2709 case NEG_D: |
2567 set_fpu_register_double( | 2710 set_fpu_register_double( |
2568 fd_reg(), FPUCanonalizeOperation([](double src) { return -src; }, | 2711 fd_reg(), FPUCanonalizeOperation([](double src) { return -src; }, |
2569 KeepSign::yes, fs)); | 2712 KeepSign::yes, fs)); |
2713 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2570 break; | 2714 break; |
2571 case SQRT_D: | 2715 case SQRT_D: |
2572 set_fpu_register_double( | 2716 set_fpu_register_double( |
2573 fd_reg(), | 2717 fd_reg(), |
2574 FPUCanonalizeOperation([](double fs) { return std::sqrt(fs); }, fs)); | 2718 FPUCanonalizeOperation([](double fs) { return std::sqrt(fs); }, fs)); |
2719 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2575 break; | 2720 break; |
2576 case RSQRT_D: | 2721 case RSQRT_D: |
2577 set_fpu_register_double( | 2722 set_fpu_register_double( |
2578 fd_reg(), FPUCanonalizeOperation( | 2723 fd_reg(), FPUCanonalizeOperation( |
2579 [](double fs) { return 1.0 / std::sqrt(fs); }, fs)); | 2724 [](double fs) { return 1.0 / std::sqrt(fs); }, fs)); |
2725 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2580 break; | 2726 break; |
2581 case RECIP_D: | 2727 case RECIP_D: |
2582 set_fpu_register_double( | 2728 set_fpu_register_double( |
2583 fd_reg(), | 2729 fd_reg(), |
2584 FPUCanonalizeOperation([](double fs) { return 1.0 / fs; }, fs)); | 2730 FPUCanonalizeOperation([](double fs) { return 1.0 / fs; }, fs)); |
2731 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2585 break; | 2732 break; |
2586 case C_UN_D: | 2733 case C_UN_D: |
2587 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); | 2734 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); |
2735 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
2588 break; | 2736 break; |
2589 case C_EQ_D: | 2737 case C_EQ_D: |
2590 set_fcsr_bit(fcsr_cc, (fs == ft)); | 2738 set_fcsr_bit(fcsr_cc, (fs == ft)); |
2739 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
2591 break; | 2740 break; |
2592 case C_UEQ_D: | 2741 case C_UEQ_D: |
2593 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); | 2742 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); |
2743 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
2594 break; | 2744 break; |
2595 case C_OLT_D: | 2745 case C_OLT_D: |
2596 set_fcsr_bit(fcsr_cc, (fs < ft)); | 2746 set_fcsr_bit(fcsr_cc, (fs < ft)); |
2747 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
2597 break; | 2748 break; |
2598 case C_ULT_D: | 2749 case C_ULT_D: |
2599 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); | 2750 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); |
2751 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
2600 break; | 2752 break; |
2601 case C_OLE_D: | 2753 case C_OLE_D: |
2602 set_fcsr_bit(fcsr_cc, (fs <= ft)); | 2754 set_fcsr_bit(fcsr_cc, (fs <= ft)); |
2755 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
2603 break; | 2756 break; |
2604 case C_ULE_D: | 2757 case C_ULE_D: |
2605 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); | 2758 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); |
2759 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
2606 break; | 2760 break; |
2607 case CVT_W_D: { // Convert double to word. | 2761 case CVT_W_D: { // Convert double to word. |
2608 double rounded; | 2762 double rounded; |
2609 int32_t result; | 2763 int32_t result; |
2610 round_according_to_fcsr(fs, rounded, result, fs); | 2764 round_according_to_fcsr(fs, rounded, result, fs); |
2611 set_fpu_register_word(fd_reg(), result); | 2765 set_fpu_register_word(fd_reg(), result); |
2612 if (set_fcsr_round_error(fs, rounded)) { | 2766 if (set_fcsr_round_error(fs, rounded)) { |
2613 set_fpu_register_word_invalid_result(fs, rounded); | 2767 set_fpu_register_word_invalid_result(fs, rounded); |
2614 } | 2768 } |
2769 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2615 } break; | 2770 } break; |
2616 case ROUND_W_D: // Round double to word (round half to even). | 2771 case ROUND_W_D: // Round double to word (round half to even). |
2617 { | 2772 { |
2618 double rounded = std::floor(fs + 0.5); | 2773 double rounded = std::floor(fs + 0.5); |
2619 int32_t result = static_cast<int32_t>(rounded); | 2774 int32_t result = static_cast<int32_t>(rounded); |
2620 if ((result & 1) != 0 && result - fs == 0.5) { | 2775 if ((result & 1) != 0 && result - fs == 0.5) { |
2621 // If the number is halfway between two integers, | 2776 // If the number is halfway between two integers, |
2622 // round to the even one. | 2777 // round to the even one. |
2623 result--; | 2778 result--; |
2624 } | 2779 } |
2625 set_fpu_register_word(fd_reg(), result); | 2780 set_fpu_register_word(fd_reg(), result); |
2626 if (set_fcsr_round_error(fs, rounded)) { | 2781 if (set_fcsr_round_error(fs, rounded)) { |
2627 set_fpu_register_word_invalid_result(fs, rounded); | 2782 set_fpu_register_word_invalid_result(fs, rounded); |
2628 } | 2783 } |
2784 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2629 } break; | 2785 } break; |
2630 case TRUNC_W_D: // Truncate double to word (round towards 0). | 2786 case TRUNC_W_D: // Truncate double to word (round towards 0). |
2631 { | 2787 { |
2632 double rounded = trunc(fs); | 2788 double rounded = trunc(fs); |
2633 int32_t result = static_cast<int32_t>(rounded); | 2789 int32_t result = static_cast<int32_t>(rounded); |
2634 set_fpu_register_word(fd_reg(), result); | 2790 set_fpu_register_word(fd_reg(), result); |
2635 if (set_fcsr_round_error(fs, rounded)) { | 2791 if (set_fcsr_round_error(fs, rounded)) { |
2636 set_fpu_register_word_invalid_result(fs, rounded); | 2792 set_fpu_register_word_invalid_result(fs, rounded); |
2637 } | 2793 } |
2794 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2638 } break; | 2795 } break; |
2639 case FLOOR_W_D: // Round double to word towards negative infinity. | 2796 case FLOOR_W_D: // Round double to word towards negative infinity. |
2640 { | 2797 { |
2641 double rounded = std::floor(fs); | 2798 double rounded = std::floor(fs); |
2642 int32_t result = static_cast<int32_t>(rounded); | 2799 int32_t result = static_cast<int32_t>(rounded); |
2643 set_fpu_register_word(fd_reg(), result); | 2800 set_fpu_register_word(fd_reg(), result); |
2644 if (set_fcsr_round_error(fs, rounded)) { | 2801 if (set_fcsr_round_error(fs, rounded)) { |
2645 set_fpu_register_word_invalid_result(fs, rounded); | 2802 set_fpu_register_word_invalid_result(fs, rounded); |
2646 } | 2803 } |
2804 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2647 } break; | 2805 } break; |
2648 case CEIL_W_D: // Round double to word towards positive infinity. | 2806 case CEIL_W_D: // Round double to word towards positive infinity. |
2649 { | 2807 { |
2650 double rounded = std::ceil(fs); | 2808 double rounded = std::ceil(fs); |
2651 int32_t result = static_cast<int32_t>(rounded); | 2809 int32_t result = static_cast<int32_t>(rounded); |
2652 set_fpu_register_word(fd_reg(), result); | 2810 set_fpu_register_word(fd_reg(), result); |
2653 if (set_fcsr_round_error(fs, rounded)) { | 2811 if (set_fcsr_round_error(fs, rounded)) { |
2654 set_fpu_register_word_invalid_result(fs, rounded); | 2812 set_fpu_register_word_invalid_result(fs, rounded); |
2655 } | 2813 } |
2814 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2656 } break; | 2815 } break; |
2657 case CVT_S_D: // Convert double to float (single). | 2816 case CVT_S_D: // Convert double to float (single). |
2658 set_fpu_register_float(fd_reg(), static_cast<float>(fs)); | 2817 set_fpu_register_float(fd_reg(), static_cast<float>(fs)); |
2818 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
2659 break; | 2819 break; |
2660 case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word. | 2820 case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word. |
2661 if (IsFp64Mode()) { | 2821 if (IsFp64Mode()) { |
2662 int64_t result; | 2822 int64_t result; |
2663 double rounded; | 2823 double rounded; |
2664 round64_according_to_fcsr(fs, rounded, result, fs); | 2824 round64_according_to_fcsr(fs, rounded, result, fs); |
2665 set_fpu_register(fd_reg(), result); | 2825 set_fpu_register(fd_reg(), result); |
2666 if (set_fcsr_round64_error(fs, rounded)) { | 2826 if (set_fcsr_round64_error(fs, rounded)) { |
2667 set_fpu_register_invalid_result64(fs, rounded); | 2827 set_fpu_register_invalid_result64(fs, rounded); |
2668 } | 2828 } |
2829 TraceRegWr(get_fpu_register(fd_reg())); | |
2669 } else { | 2830 } else { |
2670 UNSUPPORTED(); | 2831 UNSUPPORTED(); |
2671 } | 2832 } |
2672 break; | 2833 break; |
2673 break; | 2834 break; |
2674 } | 2835 } |
2675 case TRUNC_L_D: { // Mips32r2 instruction. | 2836 case TRUNC_L_D: { // Mips32r2 instruction. |
2676 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); | 2837 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); |
2677 double rounded = trunc(fs); | 2838 double rounded = trunc(fs); |
2678 i64 = static_cast<int64_t>(rounded); | 2839 i64 = static_cast<int64_t>(rounded); |
2679 if (IsFp64Mode()) { | 2840 if (IsFp64Mode()) { |
2680 set_fpu_register(fd_reg(), i64); | 2841 set_fpu_register(fd_reg(), i64); |
2681 if (set_fcsr_round64_error(fs, rounded)) { | 2842 if (set_fcsr_round64_error(fs, rounded)) { |
2682 set_fpu_register_invalid_result64(fs, rounded); | 2843 set_fpu_register_invalid_result64(fs, rounded); |
2683 } | 2844 } |
2845 TraceRegWr(get_fpu_register(fd_reg())); | |
2684 } else { | 2846 } else { |
2685 UNSUPPORTED(); | 2847 UNSUPPORTED(); |
2686 } | 2848 } |
2687 break; | 2849 break; |
2688 } | 2850 } |
2689 case ROUND_L_D: { // Mips32r2 instruction. | 2851 case ROUND_L_D: { // Mips32r2 instruction. |
2690 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); | 2852 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); |
2691 double rounded = std::floor(fs + 0.5); | 2853 double rounded = std::floor(fs + 0.5); |
2692 int64_t result = static_cast<int64_t>(rounded); | 2854 int64_t result = static_cast<int64_t>(rounded); |
2693 if ((result & 1) != 0 && result - fs == 0.5) { | 2855 if ((result & 1) != 0 && result - fs == 0.5) { |
2694 // If the number is halfway between two integers, | 2856 // If the number is halfway between two integers, |
2695 // round to the even one. | 2857 // round to the even one. |
2696 result--; | 2858 result--; |
2697 } | 2859 } |
2698 int64_t i64 = static_cast<int64_t>(result); | 2860 int64_t i64 = static_cast<int64_t>(result); |
2699 if (IsFp64Mode()) { | 2861 if (IsFp64Mode()) { |
2700 set_fpu_register(fd_reg(), i64); | 2862 set_fpu_register(fd_reg(), i64); |
2701 if (set_fcsr_round64_error(fs, rounded)) { | 2863 if (set_fcsr_round64_error(fs, rounded)) { |
2702 set_fpu_register_invalid_result64(fs, rounded); | 2864 set_fpu_register_invalid_result64(fs, rounded); |
2703 } | 2865 } |
2866 TraceRegWr(get_fpu_register(fd_reg())); | |
2704 } else { | 2867 } else { |
2705 UNSUPPORTED(); | 2868 UNSUPPORTED(); |
2706 } | 2869 } |
2707 break; | 2870 break; |
2708 } | 2871 } |
2709 case FLOOR_L_D: { // Mips32r2 instruction. | 2872 case FLOOR_L_D: { // Mips32r2 instruction. |
2710 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); | 2873 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); |
2711 double rounded = std::floor(fs); | 2874 double rounded = std::floor(fs); |
2712 int64_t i64 = static_cast<int64_t>(rounded); | 2875 int64_t i64 = static_cast<int64_t>(rounded); |
2713 if (IsFp64Mode()) { | 2876 if (IsFp64Mode()) { |
2714 set_fpu_register(fd_reg(), i64); | 2877 set_fpu_register(fd_reg(), i64); |
2715 if (set_fcsr_round64_error(fs, rounded)) { | 2878 if (set_fcsr_round64_error(fs, rounded)) { |
2716 set_fpu_register_invalid_result64(fs, rounded); | 2879 set_fpu_register_invalid_result64(fs, rounded); |
2717 } | 2880 } |
2881 TraceRegWr(get_fpu_register(fd_reg())); | |
2718 } else { | 2882 } else { |
2719 UNSUPPORTED(); | 2883 UNSUPPORTED(); |
2720 } | 2884 } |
2721 break; | 2885 break; |
2722 } | 2886 } |
2723 case CEIL_L_D: { // Mips32r2 instruction. | 2887 case CEIL_L_D: { // Mips32r2 instruction. |
2724 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); | 2888 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); |
2725 double rounded = std::ceil(fs); | 2889 double rounded = std::ceil(fs); |
2726 int64_t i64 = static_cast<int64_t>(rounded); | 2890 int64_t i64 = static_cast<int64_t>(rounded); |
2727 if (IsFp64Mode()) { | 2891 if (IsFp64Mode()) { |
2728 set_fpu_register(fd_reg(), i64); | 2892 set_fpu_register(fd_reg(), i64); |
2729 if (set_fcsr_round64_error(fs, rounded)) { | 2893 if (set_fcsr_round64_error(fs, rounded)) { |
2730 set_fpu_register_invalid_result64(fs, rounded); | 2894 set_fpu_register_invalid_result64(fs, rounded); |
2731 } | 2895 } |
2896 TraceRegWr(get_fpu_register(fd_reg())); | |
2732 } else { | 2897 } else { |
2733 UNSUPPORTED(); | 2898 UNSUPPORTED(); |
2734 } | 2899 } |
2735 break; | 2900 break; |
2736 } | 2901 } |
2737 case CLASS_D: { // Mips32r6 instruction | 2902 case CLASS_D: { // Mips32r6 instruction |
2738 // Convert double input to uint64_t for easier bit manipulation | 2903 // Convert double input to uint64_t for easier bit manipulation |
2739 uint64_t classed = bit_cast<uint64_t>(fs); | 2904 uint64_t classed = bit_cast<uint64_t>(fs); |
2740 | 2905 |
2741 // Extracting sign, exponent and mantissa from the input double | 2906 // Extracting sign, exponent and mantissa from the input double |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2789 | 2954 |
2790 // Calculating result according to description of CLASS.D instruction | 2955 // Calculating result according to description of CLASS.D instruction |
2791 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | | 2956 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | |
2792 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | | 2957 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | |
2793 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; | 2958 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; |
2794 | 2959 |
2795 DCHECK(result != 0); | 2960 DCHECK(result != 0); |
2796 | 2961 |
2797 dResult = bit_cast<double>(result); | 2962 dResult = bit_cast<double>(result); |
2798 set_fpu_register_double(fd_reg(), dResult); | 2963 set_fpu_register_double(fd_reg(), dResult); |
2964 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2799 | 2965 |
2800 break; | 2966 break; |
2801 } | 2967 } |
2802 case C_F_D: { | 2968 case C_F_D: { |
2803 set_fcsr_bit(fcsr_cc, false); | 2969 set_fcsr_bit(fcsr_cc, false); |
2970 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
2804 break; | 2971 break; |
2805 } | 2972 } |
2806 default: | 2973 default: |
2807 UNREACHABLE(); | 2974 UNREACHABLE(); |
2808 } | 2975 } |
2809 } | 2976 } |
2810 | 2977 |
2811 | 2978 |
2812 void Simulator::DecodeTypeRegisterWRsType() { | 2979 void Simulator::DecodeTypeRegisterWRsType() { |
2813 float fs = get_fpu_register_float(fs_reg()); | 2980 float fs = get_fpu_register_float(fs_reg()); |
2814 float ft = get_fpu_register_float(ft_reg()); | 2981 float ft = get_fpu_register_float(ft_reg()); |
2815 int32_t alu_out = 0x12345678; | 2982 int32_t alu_out = 0x12345678; |
2816 switch (instr_.FunctionFieldRaw()) { | 2983 switch (instr_.FunctionFieldRaw()) { |
2817 case CVT_S_W: // Convert word to float (single). | 2984 case CVT_S_W: // Convert word to float (single). |
2818 alu_out = get_fpu_register_signed_word(fs_reg()); | 2985 alu_out = get_fpu_register_signed_word(fs_reg()); |
2819 set_fpu_register_float(fd_reg(), static_cast<float>(alu_out)); | 2986 set_fpu_register_float(fd_reg(), static_cast<float>(alu_out)); |
2987 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
2820 break; | 2988 break; |
2821 case CVT_D_W: // Convert word to double. | 2989 case CVT_D_W: // Convert word to double. |
2822 alu_out = get_fpu_register_signed_word(fs_reg()); | 2990 alu_out = get_fpu_register_signed_word(fs_reg()); |
2823 set_fpu_register_double(fd_reg(), static_cast<double>(alu_out)); | 2991 set_fpu_register_double(fd_reg(), static_cast<double>(alu_out)); |
2992 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
2824 break; | 2993 break; |
2825 case CMP_AF: | 2994 case CMP_AF: |
2826 set_fpu_register_word(fd_reg(), 0); | 2995 set_fpu_register_word(fd_reg(), 0); |
2996 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2827 break; | 2997 break; |
2828 case CMP_UN: | 2998 case CMP_UN: |
2829 if (std::isnan(fs) || std::isnan(ft)) { | 2999 if (std::isnan(fs) || std::isnan(ft)) { |
2830 set_fpu_register_word(fd_reg(), -1); | 3000 set_fpu_register_word(fd_reg(), -1); |
2831 } else { | 3001 } else { |
2832 set_fpu_register_word(fd_reg(), 0); | 3002 set_fpu_register_word(fd_reg(), 0); |
2833 } | 3003 } |
3004 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2834 break; | 3005 break; |
2835 case CMP_EQ: | 3006 case CMP_EQ: |
2836 if (fs == ft) { | 3007 if (fs == ft) { |
2837 set_fpu_register_word(fd_reg(), -1); | 3008 set_fpu_register_word(fd_reg(), -1); |
2838 } else { | 3009 } else { |
2839 set_fpu_register_word(fd_reg(), 0); | 3010 set_fpu_register_word(fd_reg(), 0); |
2840 } | 3011 } |
3012 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2841 break; | 3013 break; |
2842 case CMP_UEQ: | 3014 case CMP_UEQ: |
2843 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { | 3015 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { |
2844 set_fpu_register_word(fd_reg(), -1); | 3016 set_fpu_register_word(fd_reg(), -1); |
2845 } else { | 3017 } else { |
2846 set_fpu_register_word(fd_reg(), 0); | 3018 set_fpu_register_word(fd_reg(), 0); |
2847 } | 3019 } |
3020 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2848 break; | 3021 break; |
2849 case CMP_LT: | 3022 case CMP_LT: |
2850 if (fs < ft) { | 3023 if (fs < ft) { |
2851 set_fpu_register_word(fd_reg(), -1); | 3024 set_fpu_register_word(fd_reg(), -1); |
2852 } else { | 3025 } else { |
2853 set_fpu_register_word(fd_reg(), 0); | 3026 set_fpu_register_word(fd_reg(), 0); |
2854 } | 3027 } |
3028 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2855 break; | 3029 break; |
2856 case CMP_ULT: | 3030 case CMP_ULT: |
2857 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { | 3031 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { |
2858 set_fpu_register_word(fd_reg(), -1); | 3032 set_fpu_register_word(fd_reg(), -1); |
2859 } else { | 3033 } else { |
2860 set_fpu_register_word(fd_reg(), 0); | 3034 set_fpu_register_word(fd_reg(), 0); |
2861 } | 3035 } |
3036 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2862 break; | 3037 break; |
2863 case CMP_LE: | 3038 case CMP_LE: |
2864 if (fs <= ft) { | 3039 if (fs <= ft) { |
2865 set_fpu_register_word(fd_reg(), -1); | 3040 set_fpu_register_word(fd_reg(), -1); |
2866 } else { | 3041 } else { |
2867 set_fpu_register_word(fd_reg(), 0); | 3042 set_fpu_register_word(fd_reg(), 0); |
2868 } | 3043 } |
3044 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2869 break; | 3045 break; |
2870 case CMP_ULE: | 3046 case CMP_ULE: |
2871 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { | 3047 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { |
2872 set_fpu_register_word(fd_reg(), -1); | 3048 set_fpu_register_word(fd_reg(), -1); |
2873 } else { | 3049 } else { |
2874 set_fpu_register_word(fd_reg(), 0); | 3050 set_fpu_register_word(fd_reg(), 0); |
2875 } | 3051 } |
3052 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2876 break; | 3053 break; |
2877 case CMP_OR: | 3054 case CMP_OR: |
2878 if (!std::isnan(fs) && !std::isnan(ft)) { | 3055 if (!std::isnan(fs) && !std::isnan(ft)) { |
2879 set_fpu_register_word(fd_reg(), -1); | 3056 set_fpu_register_word(fd_reg(), -1); |
2880 } else { | 3057 } else { |
2881 set_fpu_register_word(fd_reg(), 0); | 3058 set_fpu_register_word(fd_reg(), 0); |
2882 } | 3059 } |
3060 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2883 break; | 3061 break; |
2884 case CMP_UNE: | 3062 case CMP_UNE: |
2885 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { | 3063 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { |
2886 set_fpu_register_word(fd_reg(), -1); | 3064 set_fpu_register_word(fd_reg(), -1); |
2887 } else { | 3065 } else { |
2888 set_fpu_register_word(fd_reg(), 0); | 3066 set_fpu_register_word(fd_reg(), 0); |
2889 } | 3067 } |
3068 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2890 break; | 3069 break; |
2891 case CMP_NE: | 3070 case CMP_NE: |
2892 if (fs != ft) { | 3071 if (fs != ft) { |
2893 set_fpu_register_word(fd_reg(), -1); | 3072 set_fpu_register_word(fd_reg(), -1); |
2894 } else { | 3073 } else { |
2895 set_fpu_register_word(fd_reg(), 0); | 3074 set_fpu_register_word(fd_reg(), 0); |
2896 } | 3075 } |
3076 TraceRegWr(get_fpu_register_word(fd_reg())); | |
2897 break; | 3077 break; |
2898 default: | 3078 default: |
2899 UNREACHABLE(); | 3079 UNREACHABLE(); |
2900 } | 3080 } |
2901 } | 3081 } |
2902 | 3082 |
2903 | 3083 |
2904 void Simulator::DecodeTypeRegisterSRsType() { | 3084 void Simulator::DecodeTypeRegisterSRsType() { |
2905 float fs, ft, fd; | 3085 float fs, ft, fd; |
2906 fs = get_fpu_register_float(fs_reg()); | 3086 fs = get_fpu_register_float(fs_reg()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2941 result = upper; | 3121 result = upper; |
2942 break; | 3122 break; |
2943 case kRoundToMinusInf: | 3123 case kRoundToMinusInf: |
2944 result = lower; | 3124 result = lower; |
2945 break; | 3125 break; |
2946 } | 3126 } |
2947 set_fpu_register_float(fd_reg(), result); | 3127 set_fpu_register_float(fd_reg(), result); |
2948 if (result != fs) { | 3128 if (result != fs) { |
2949 set_fcsr_bit(kFCSRInexactFlagBit, true); | 3129 set_fcsr_bit(kFCSRInexactFlagBit, true); |
2950 } | 3130 } |
3131 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
2951 break; | 3132 break; |
2952 } | 3133 } |
2953 case ADD_S: | 3134 case ADD_S: |
2954 set_fpu_register_float( | 3135 set_fpu_register_float( |
2955 fd_reg(), | 3136 fd_reg(), |
2956 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs + rhs; }, | 3137 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs + rhs; }, |
2957 fs, ft)); | 3138 fs, ft)); |
3139 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
2958 break; | 3140 break; |
2959 case SUB_S: | 3141 case SUB_S: |
2960 set_fpu_register_float( | 3142 set_fpu_register_float( |
2961 fd_reg(), | 3143 fd_reg(), |
2962 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs - rhs; }, | 3144 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs - rhs; }, |
2963 fs, ft)); | 3145 fs, ft)); |
3146 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
2964 break; | 3147 break; |
2965 case MADDF_S: | 3148 case MADDF_S: |
2966 DCHECK(IsMipsArchVariant(kMips32r6)); | 3149 DCHECK(IsMipsArchVariant(kMips32r6)); |
2967 set_fpu_register_float(fd_reg(), std::fma(fs, ft, fd)); | 3150 set_fpu_register_float(fd_reg(), std::fma(fs, ft, fd)); |
3151 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
2968 break; | 3152 break; |
2969 case MSUBF_S: | 3153 case MSUBF_S: |
2970 DCHECK(IsMipsArchVariant(kMips32r6)); | 3154 DCHECK(IsMipsArchVariant(kMips32r6)); |
2971 set_fpu_register_float(fd_reg(), std::fma(-fs, ft, fd)); | 3155 set_fpu_register_float(fd_reg(), std::fma(-fs, ft, fd)); |
3156 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
2972 break; | 3157 break; |
2973 case MUL_S: | 3158 case MUL_S: |
2974 set_fpu_register_float( | 3159 set_fpu_register_float( |
2975 fd_reg(), | 3160 fd_reg(), |
2976 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs * rhs; }, | 3161 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs * rhs; }, |
2977 fs, ft)); | 3162 fs, ft)); |
3163 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
2978 break; | 3164 break; |
2979 case DIV_S: | 3165 case DIV_S: |
2980 set_fpu_register_float( | 3166 set_fpu_register_float( |
2981 fd_reg(), | 3167 fd_reg(), |
2982 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs / rhs; }, | 3168 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs / rhs; }, |
2983 fs, ft)); | 3169 fs, ft)); |
3170 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
2984 break; | 3171 break; |
2985 case ABS_S: | 3172 case ABS_S: |
2986 set_fpu_register_float( | 3173 set_fpu_register_float( |
2987 fd_reg(), | 3174 fd_reg(), |
2988 FPUCanonalizeOperation([](float fs) { return FPAbs(fs); }, fs)); | 3175 FPUCanonalizeOperation([](float fs) { return FPAbs(fs); }, fs)); |
3176 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
2989 break; | 3177 break; |
2990 case MOV_S: | 3178 case MOV_S: |
2991 set_fpu_register_float(fd_reg(), fs); | 3179 set_fpu_register_float(fd_reg(), fs); |
3180 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
2992 break; | 3181 break; |
2993 case NEG_S: | 3182 case NEG_S: |
2994 set_fpu_register_float( | 3183 set_fpu_register_float( |
2995 fd_reg(), FPUCanonalizeOperation([](float src) { return -src; }, | 3184 fd_reg(), FPUCanonalizeOperation([](float src) { return -src; }, |
2996 KeepSign::yes, fs)); | 3185 KeepSign::yes, fs)); |
3186 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
2997 break; | 3187 break; |
2998 case SQRT_S: | 3188 case SQRT_S: |
2999 set_fpu_register_float( | 3189 set_fpu_register_float( |
3000 fd_reg(), | 3190 fd_reg(), |
3001 FPUCanonalizeOperation([](float src) { return std::sqrt(src); }, fs)); | 3191 FPUCanonalizeOperation([](float src) { return std::sqrt(src); }, fs)); |
3192 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3002 break; | 3193 break; |
3003 case RSQRT_S: | 3194 case RSQRT_S: |
3004 set_fpu_register_float( | 3195 set_fpu_register_float( |
3005 fd_reg(), FPUCanonalizeOperation( | 3196 fd_reg(), FPUCanonalizeOperation( |
3006 [](float src) { return 1.0 / std::sqrt(src); }, fs)); | 3197 [](float src) { return 1.0 / std::sqrt(src); }, fs)); |
3198 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3007 break; | 3199 break; |
3008 case RECIP_S: | 3200 case RECIP_S: |
3009 set_fpu_register_float( | 3201 set_fpu_register_float( |
3010 fd_reg(), | 3202 fd_reg(), |
3011 FPUCanonalizeOperation([](float src) { return 1.0 / src; }, fs)); | 3203 FPUCanonalizeOperation([](float src) { return 1.0 / src; }, fs)); |
3204 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3012 break; | 3205 break; |
3013 case C_F_D: | 3206 case C_F_D: |
3014 set_fcsr_bit(fcsr_cc, false); | 3207 set_fcsr_bit(fcsr_cc, false); |
3208 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
3015 break; | 3209 break; |
3016 case C_UN_D: | 3210 case C_UN_D: |
3017 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); | 3211 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); |
3212 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
3018 break; | 3213 break; |
3019 case C_EQ_D: | 3214 case C_EQ_D: |
3020 set_fcsr_bit(fcsr_cc, (fs == ft)); | 3215 set_fcsr_bit(fcsr_cc, (fs == ft)); |
3216 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
3021 break; | 3217 break; |
3022 case C_UEQ_D: | 3218 case C_UEQ_D: |
3023 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); | 3219 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); |
3220 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
3024 break; | 3221 break; |
3025 case C_OLT_D: | 3222 case C_OLT_D: |
3026 set_fcsr_bit(fcsr_cc, (fs < ft)); | 3223 set_fcsr_bit(fcsr_cc, (fs < ft)); |
3224 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
3027 break; | 3225 break; |
3028 case C_ULT_D: | 3226 case C_ULT_D: |
3029 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); | 3227 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); |
3228 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
3030 break; | 3229 break; |
3031 case C_OLE_D: | 3230 case C_OLE_D: |
3032 set_fcsr_bit(fcsr_cc, (fs <= ft)); | 3231 set_fcsr_bit(fcsr_cc, (fs <= ft)); |
3232 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
3033 break; | 3233 break; |
3034 case C_ULE_D: | 3234 case C_ULE_D: |
3035 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); | 3235 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); |
3236 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
3036 break; | 3237 break; |
3037 case CVT_D_S: | 3238 case CVT_D_S: |
3038 set_fpu_register_double(fd_reg(), static_cast<double>(fs)); | 3239 set_fpu_register_double(fd_reg(), static_cast<double>(fs)); |
3240 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
3039 break; | 3241 break; |
3040 case SEL: | 3242 case SEL: |
3041 DCHECK(IsMipsArchVariant(kMips32r6)); | 3243 DCHECK(IsMipsArchVariant(kMips32r6)); |
3042 set_fpu_register_float(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); | 3244 set_fpu_register_float(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); |
3245 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3043 break; | 3246 break; |
3044 case CLASS_S: { // Mips32r6 instruction | 3247 case CLASS_S: { // Mips32r6 instruction |
3045 // Convert float input to uint32_t for easier bit manipulation | 3248 // Convert float input to uint32_t for easier bit manipulation |
3046 float fs = get_fpu_register_float(fs_reg()); | 3249 float fs = get_fpu_register_float(fs_reg()); |
3047 uint32_t classed = bit_cast<uint32_t>(fs); | 3250 uint32_t classed = bit_cast<uint32_t>(fs); |
3048 | 3251 |
3049 // Extracting sign, exponent and mantissa from the input float | 3252 // Extracting sign, exponent and mantissa from the input float |
3050 uint32_t sign = (classed >> 31) & 1; | 3253 uint32_t sign = (classed >> 31) & 1; |
3051 uint32_t exponent = (classed >> 23) & 0x000000ff; | 3254 uint32_t exponent = (classed >> 23) & 0x000000ff; |
3052 uint32_t mantissa = classed & 0x007fffff; | 3255 uint32_t mantissa = classed & 0x007fffff; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3097 | 3300 |
3098 // Calculating result according to description of CLASS.S instruction | 3301 // Calculating result according to description of CLASS.S instruction |
3099 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | | 3302 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | |
3100 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | | 3303 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | |
3101 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; | 3304 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; |
3102 | 3305 |
3103 DCHECK(result != 0); | 3306 DCHECK(result != 0); |
3104 | 3307 |
3105 fResult = bit_cast<float>(result); | 3308 fResult = bit_cast<float>(result); |
3106 set_fpu_register_float(fd_reg(), fResult); | 3309 set_fpu_register_float(fd_reg(), fResult); |
3310 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3107 | 3311 |
3108 break; | 3312 break; |
3109 } | 3313 } |
3110 case SELEQZ_C: | 3314 case SELEQZ_C: |
3111 DCHECK(IsMipsArchVariant(kMips32r6)); | 3315 DCHECK(IsMipsArchVariant(kMips32r6)); |
3112 set_fpu_register_float(fd_reg(), (ft_int & 0x1) == 0 | 3316 set_fpu_register_float(fd_reg(), (ft_int & 0x1) == 0 |
3113 ? get_fpu_register_float(fs_reg()) | 3317 ? get_fpu_register_float(fs_reg()) |
3114 : 0.0); | 3318 : 0.0); |
3319 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3115 break; | 3320 break; |
3116 case SELNEZ_C: | 3321 case SELNEZ_C: |
3117 DCHECK(IsMipsArchVariant(kMips32r6)); | 3322 DCHECK(IsMipsArchVariant(kMips32r6)); |
3118 set_fpu_register_float(fd_reg(), (ft_int & 0x1) != 0 | 3323 set_fpu_register_float(fd_reg(), (ft_int & 0x1) != 0 |
3119 ? get_fpu_register_float(fs_reg()) | 3324 ? get_fpu_register_float(fs_reg()) |
3120 : 0.0); | 3325 : 0.0); |
3326 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3121 break; | 3327 break; |
3122 case MOVZ_C: { | 3328 case MOVZ_C: { |
3123 DCHECK(IsMipsArchVariant(kMips32r2)); | 3329 DCHECK(IsMipsArchVariant(kMips32r2)); |
3124 if (rt() == 0) { | 3330 if (rt() == 0) { |
3125 set_fpu_register_float(fd_reg(), fs); | 3331 set_fpu_register_float(fd_reg(), fs); |
3126 } | 3332 } |
3333 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3127 break; | 3334 break; |
3128 } | 3335 } |
3129 case MOVN_C: { | 3336 case MOVN_C: { |
3130 DCHECK(IsMipsArchVariant(kMips32r2)); | 3337 DCHECK(IsMipsArchVariant(kMips32r2)); |
3131 if (rt() != 0) { | 3338 if (rt() != 0) { |
3132 set_fpu_register_float(fd_reg(), fs); | 3339 set_fpu_register_float(fd_reg(), fs); |
3133 } | 3340 } |
3341 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3134 break; | 3342 break; |
3135 } | 3343 } |
3136 case MOVF: { | 3344 case MOVF: { |
3137 // Same function field for MOVT.D and MOVF.D | 3345 // Same function field for MOVT.D and MOVF.D |
3138 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; | 3346 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; |
3139 ft_cc = get_fcsr_condition_bit(ft_cc); | 3347 ft_cc = get_fcsr_condition_bit(ft_cc); |
3140 | 3348 |
3141 if (instr_.Bit(16)) { // Read Tf bit. | 3349 if (instr_.Bit(16)) { // Read Tf bit. |
3142 // MOVT.D | 3350 // MOVT.D |
3143 if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); | 3351 if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); |
3144 } else { | 3352 } else { |
3145 // MOVF.D | 3353 // MOVF.D |
3146 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); | 3354 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); |
3147 } | 3355 } |
3356 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3148 break; | 3357 break; |
3149 } | 3358 } |
3150 case TRUNC_W_S: { // Truncate single to word (round towards 0). | 3359 case TRUNC_W_S: { // Truncate single to word (round towards 0). |
3151 float rounded = trunc(fs); | 3360 float rounded = trunc(fs); |
3152 int32_t result = static_cast<int32_t>(rounded); | 3361 int32_t result = static_cast<int32_t>(rounded); |
3153 set_fpu_register_word(fd_reg(), result); | 3362 set_fpu_register_word(fd_reg(), result); |
3154 if (set_fcsr_round_error(fs, rounded)) { | 3363 if (set_fcsr_round_error(fs, rounded)) { |
3155 set_fpu_register_word_invalid_result(fs, rounded); | 3364 set_fpu_register_word_invalid_result(fs, rounded); |
3156 } | 3365 } |
3366 TraceRegWr(get_fpu_register_word(fd_reg())); | |
3157 } break; | 3367 } break; |
3158 case TRUNC_L_S: { // Mips32r2 instruction. | 3368 case TRUNC_L_S: { // Mips32r2 instruction. |
3159 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); | 3369 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); |
3160 float rounded = trunc(fs); | 3370 float rounded = trunc(fs); |
3161 int64_t i64 = static_cast<int64_t>(rounded); | 3371 int64_t i64 = static_cast<int64_t>(rounded); |
3162 if (IsFp64Mode()) { | 3372 if (IsFp64Mode()) { |
3163 set_fpu_register(fd_reg(), i64); | 3373 set_fpu_register(fd_reg(), i64); |
3164 if (set_fcsr_round64_error(fs, rounded)) { | 3374 if (set_fcsr_round64_error(fs, rounded)) { |
3165 set_fpu_register_invalid_result64(fs, rounded); | 3375 set_fpu_register_invalid_result64(fs, rounded); |
3166 } | 3376 } |
3377 TraceRegWr(get_fpu_register(fd_reg())); | |
3167 } else { | 3378 } else { |
3168 UNSUPPORTED(); | 3379 UNSUPPORTED(); |
3169 } | 3380 } |
3170 break; | 3381 break; |
3171 } | 3382 } |
3172 case FLOOR_W_S: // Round double to word towards negative infinity. | 3383 case FLOOR_W_S: // Round double to word towards negative infinity. |
3173 { | 3384 { |
3174 float rounded = std::floor(fs); | 3385 float rounded = std::floor(fs); |
3175 int32_t result = static_cast<int32_t>(rounded); | 3386 int32_t result = static_cast<int32_t>(rounded); |
3176 set_fpu_register_word(fd_reg(), result); | 3387 set_fpu_register_word(fd_reg(), result); |
3177 if (set_fcsr_round_error(fs, rounded)) { | 3388 if (set_fcsr_round_error(fs, rounded)) { |
3178 set_fpu_register_word_invalid_result(fs, rounded); | 3389 set_fpu_register_word_invalid_result(fs, rounded); |
3179 } | 3390 } |
3391 TraceRegWr(get_fpu_register_word(fd_reg())); | |
3180 } break; | 3392 } break; |
3181 case FLOOR_L_S: { // Mips32r2 instruction. | 3393 case FLOOR_L_S: { // Mips32r2 instruction. |
3182 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); | 3394 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); |
3183 float rounded = std::floor(fs); | 3395 float rounded = std::floor(fs); |
3184 int64_t i64 = static_cast<int64_t>(rounded); | 3396 int64_t i64 = static_cast<int64_t>(rounded); |
3185 if (IsFp64Mode()) { | 3397 if (IsFp64Mode()) { |
3186 set_fpu_register(fd_reg(), i64); | 3398 set_fpu_register(fd_reg(), i64); |
3187 if (set_fcsr_round64_error(fs, rounded)) { | 3399 if (set_fcsr_round64_error(fs, rounded)) { |
3188 set_fpu_register_invalid_result64(fs, rounded); | 3400 set_fpu_register_invalid_result64(fs, rounded); |
3189 } | 3401 } |
3402 TraceRegWr(get_fpu_register(fd_reg())); | |
3190 } else { | 3403 } else { |
3191 UNSUPPORTED(); | 3404 UNSUPPORTED(); |
3192 } | 3405 } |
3193 break; | 3406 break; |
3194 } | 3407 } |
3195 case ROUND_W_S: { | 3408 case ROUND_W_S: { |
3196 float rounded = std::floor(fs + 0.5); | 3409 float rounded = std::floor(fs + 0.5); |
3197 int32_t result = static_cast<int32_t>(rounded); | 3410 int32_t result = static_cast<int32_t>(rounded); |
3198 if ((result & 1) != 0 && result - fs == 0.5) { | 3411 if ((result & 1) != 0 && result - fs == 0.5) { |
3199 // If the number is halfway between two integers, | 3412 // If the number is halfway between two integers, |
3200 // round to the even one. | 3413 // round to the even one. |
3201 result--; | 3414 result--; |
3202 } | 3415 } |
3203 set_fpu_register_word(fd_reg(), result); | 3416 set_fpu_register_word(fd_reg(), result); |
3204 if (set_fcsr_round_error(fs, rounded)) { | 3417 if (set_fcsr_round_error(fs, rounded)) { |
3205 set_fpu_register_word_invalid_result(fs, rounded); | 3418 set_fpu_register_word_invalid_result(fs, rounded); |
3206 } | 3419 } |
3420 TraceRegWr(get_fpu_register_word(fd_reg())); | |
3207 break; | 3421 break; |
3208 } | 3422 } |
3209 case ROUND_L_S: { // Mips32r2 instruction. | 3423 case ROUND_L_S: { // Mips32r2 instruction. |
3210 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); | 3424 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); |
3211 float rounded = std::floor(fs + 0.5); | 3425 float rounded = std::floor(fs + 0.5); |
3212 int64_t result = static_cast<int64_t>(rounded); | 3426 int64_t result = static_cast<int64_t>(rounded); |
3213 if ((result & 1) != 0 && result - fs == 0.5) { | 3427 if ((result & 1) != 0 && result - fs == 0.5) { |
3214 // If the number is halfway between two integers, | 3428 // If the number is halfway between two integers, |
3215 // round to the even one. | 3429 // round to the even one. |
3216 result--; | 3430 result--; |
3217 } | 3431 } |
3218 int64_t i64 = static_cast<int64_t>(result); | 3432 int64_t i64 = static_cast<int64_t>(result); |
3219 if (IsFp64Mode()) { | 3433 if (IsFp64Mode()) { |
3220 set_fpu_register(fd_reg(), i64); | 3434 set_fpu_register(fd_reg(), i64); |
3221 if (set_fcsr_round64_error(fs, rounded)) { | 3435 if (set_fcsr_round64_error(fs, rounded)) { |
3222 set_fpu_register_invalid_result64(fs, rounded); | 3436 set_fpu_register_invalid_result64(fs, rounded); |
3223 } | 3437 } |
3438 TraceRegWr(get_fpu_register(fd_reg())); | |
3224 } else { | 3439 } else { |
3225 UNSUPPORTED(); | 3440 UNSUPPORTED(); |
3226 } | 3441 } |
3227 break; | 3442 break; |
3228 } | 3443 } |
3229 case CEIL_W_S: // Round double to word towards positive infinity. | 3444 case CEIL_W_S: // Round double to word towards positive infinity. |
3230 { | 3445 { |
3231 float rounded = std::ceil(fs); | 3446 float rounded = std::ceil(fs); |
3232 int32_t result = static_cast<int32_t>(rounded); | 3447 int32_t result = static_cast<int32_t>(rounded); |
3233 set_fpu_register_word(fd_reg(), result); | 3448 set_fpu_register_word(fd_reg(), result); |
3234 if (set_fcsr_round_error(fs, rounded)) { | 3449 if (set_fcsr_round_error(fs, rounded)) { |
3235 set_fpu_register_word_invalid_result(fs, rounded); | 3450 set_fpu_register_word_invalid_result(fs, rounded); |
3236 } | 3451 } |
3452 TraceRegWr(get_fpu_register_word(fd_reg())); | |
3237 } break; | 3453 } break; |
3238 case CEIL_L_S: { // Mips32r2 instruction. | 3454 case CEIL_L_S: { // Mips32r2 instruction. |
3239 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); | 3455 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); |
3240 float rounded = std::ceil(fs); | 3456 float rounded = std::ceil(fs); |
3241 int64_t i64 = static_cast<int64_t>(rounded); | 3457 int64_t i64 = static_cast<int64_t>(rounded); |
3242 if (IsFp64Mode()) { | 3458 if (IsFp64Mode()) { |
3243 set_fpu_register(fd_reg(), i64); | 3459 set_fpu_register(fd_reg(), i64); |
3244 if (set_fcsr_round64_error(fs, rounded)) { | 3460 if (set_fcsr_round64_error(fs, rounded)) { |
3245 set_fpu_register_invalid_result64(fs, rounded); | 3461 set_fpu_register_invalid_result64(fs, rounded); |
3246 } | 3462 } |
3463 TraceRegWr(get_fpu_register(fd_reg())); | |
3247 } else { | 3464 } else { |
3248 UNSUPPORTED(); | 3465 UNSUPPORTED(); |
3249 } | 3466 } |
3250 break; | 3467 break; |
3251 } | 3468 } |
3252 case MIN: | 3469 case MIN: |
3253 DCHECK(IsMipsArchVariant(kMips32r6)); | 3470 DCHECK(IsMipsArchVariant(kMips32r6)); |
3254 set_fpu_register_float(fd_reg(), FPUMin(ft, fs)); | 3471 set_fpu_register_float(fd_reg(), FPUMin(ft, fs)); |
3472 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3255 break; | 3473 break; |
3256 case MAX: | 3474 case MAX: |
3257 DCHECK(IsMipsArchVariant(kMips32r6)); | 3475 DCHECK(IsMipsArchVariant(kMips32r6)); |
3258 set_fpu_register_float(fd_reg(), FPUMax(ft, fs)); | 3476 set_fpu_register_float(fd_reg(), FPUMax(ft, fs)); |
3477 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3259 break; | 3478 break; |
3260 case MINA: | 3479 case MINA: |
3261 DCHECK(IsMipsArchVariant(kMips32r6)); | 3480 DCHECK(IsMipsArchVariant(kMips32r6)); |
3262 set_fpu_register_float(fd_reg(), FPUMinA(ft, fs)); | 3481 set_fpu_register_float(fd_reg(), FPUMinA(ft, fs)); |
3482 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3263 break; | 3483 break; |
3264 case MAXA: | 3484 case MAXA: |
3265 DCHECK(IsMipsArchVariant(kMips32r6)); | 3485 DCHECK(IsMipsArchVariant(kMips32r6)); |
3266 set_fpu_register_float(fd_reg(), FPUMaxA(ft, fs)); | 3486 set_fpu_register_float(fd_reg(), FPUMaxA(ft, fs)); |
3487 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3267 break; | 3488 break; |
3268 case CVT_L_S: { | 3489 case CVT_L_S: { |
3269 if (IsFp64Mode()) { | 3490 if (IsFp64Mode()) { |
3270 int64_t result; | 3491 int64_t result; |
3271 float rounded; | 3492 float rounded; |
3272 round64_according_to_fcsr(fs, rounded, result, fs); | 3493 round64_according_to_fcsr(fs, rounded, result, fs); |
3273 set_fpu_register(fd_reg(), result); | 3494 set_fpu_register(fd_reg(), result); |
3274 if (set_fcsr_round64_error(fs, rounded)) { | 3495 if (set_fcsr_round64_error(fs, rounded)) { |
3275 set_fpu_register_invalid_result64(fs, rounded); | 3496 set_fpu_register_invalid_result64(fs, rounded); |
3276 } | 3497 } |
3498 TraceRegWr(get_fpu_register(fd_reg())); | |
3277 } else { | 3499 } else { |
3278 UNSUPPORTED(); | 3500 UNSUPPORTED(); |
3279 } | 3501 } |
3280 break; | 3502 break; |
3281 } | 3503 } |
3282 case CVT_W_S: { | 3504 case CVT_W_S: { |
3283 float rounded; | 3505 float rounded; |
3284 int32_t result; | 3506 int32_t result; |
3285 round_according_to_fcsr(fs, rounded, result, fs); | 3507 round_according_to_fcsr(fs, rounded, result, fs); |
3286 set_fpu_register_word(fd_reg(), result); | 3508 set_fpu_register_word(fd_reg(), result); |
3287 if (set_fcsr_round_error(fs, rounded)) { | 3509 if (set_fcsr_round_error(fs, rounded)) { |
3288 set_fpu_register_word_invalid_result(fs, rounded); | 3510 set_fpu_register_word_invalid_result(fs, rounded); |
3289 } | 3511 } |
3512 TraceRegWr(get_fpu_register_word(fd_reg())); | |
3290 break; | 3513 break; |
3291 } | 3514 } |
3292 default: | 3515 default: |
3293 // CVT_W_S CVT_L_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S | 3516 // CVT_W_S CVT_L_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S |
3294 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. | 3517 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. |
3295 UNREACHABLE(); | 3518 UNREACHABLE(); |
3296 } | 3519 } |
3297 } | 3520 } |
3298 | 3521 |
3299 | 3522 |
3300 void Simulator::DecodeTypeRegisterLRsType() { | 3523 void Simulator::DecodeTypeRegisterLRsType() { |
3301 double fs = get_fpu_register_double(fs_reg()); | 3524 double fs = get_fpu_register_double(fs_reg()); |
3302 double ft = get_fpu_register_double(ft_reg()); | 3525 double ft = get_fpu_register_double(ft_reg()); |
3303 switch (instr_.FunctionFieldRaw()) { | 3526 switch (instr_.FunctionFieldRaw()) { |
3304 case CVT_D_L: // Mips32r2 instruction. | 3527 case CVT_D_L: // Mips32r2 instruction. |
3305 // Watch the signs here, we want 2 32-bit vals | 3528 // Watch the signs here, we want 2 32-bit vals |
3306 // to make a sign-64. | 3529 // to make a sign-64. |
3307 int64_t i64; | 3530 int64_t i64; |
3308 if (IsFp64Mode()) { | 3531 if (IsFp64Mode()) { |
3309 i64 = get_fpu_register(fs_reg()); | 3532 i64 = get_fpu_register(fs_reg()); |
3310 } else { | 3533 } else { |
3311 i64 = static_cast<uint32_t>(get_fpu_register_word(fs_reg())); | 3534 i64 = static_cast<uint32_t>(get_fpu_register_word(fs_reg())); |
3312 i64 |= static_cast<int64_t>(get_fpu_register_word(fs_reg() + 1)) << 32; | 3535 i64 |= static_cast<int64_t>(get_fpu_register_word(fs_reg() + 1)) << 32; |
3313 } | 3536 } |
3314 set_fpu_register_double(fd_reg(), static_cast<double>(i64)); | 3537 set_fpu_register_double(fd_reg(), static_cast<double>(i64)); |
3538 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
3315 break; | 3539 break; |
3316 case CVT_S_L: | 3540 case CVT_S_L: |
3317 if (IsFp64Mode()) { | 3541 if (IsFp64Mode()) { |
3318 i64 = get_fpu_register(fs_reg()); | 3542 i64 = get_fpu_register(fs_reg()); |
3319 } else { | 3543 } else { |
3320 i64 = static_cast<uint32_t>(get_fpu_register_word(fs_reg())); | 3544 i64 = static_cast<uint32_t>(get_fpu_register_word(fs_reg())); |
3321 i64 |= static_cast<int64_t>(get_fpu_register_word(fs_reg() + 1)) << 32; | 3545 i64 |= static_cast<int64_t>(get_fpu_register_word(fs_reg() + 1)) << 32; |
3322 } | 3546 } |
3323 set_fpu_register_float(fd_reg(), static_cast<float>(i64)); | 3547 set_fpu_register_float(fd_reg(), static_cast<float>(i64)); |
3548 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3324 break; | 3549 break; |
3325 case CMP_AF: // Mips64r6 CMP.D instructions. | 3550 case CMP_AF: // Mips64r6 CMP.D instructions. |
3326 set_fpu_register(fd_reg(), 0); | 3551 set_fpu_register(fd_reg(), 0); |
3552 TraceRegWr(get_fpu_register(fd_reg())); | |
3327 break; | 3553 break; |
3328 case CMP_UN: | 3554 case CMP_UN: |
3329 if (std::isnan(fs) || std::isnan(ft)) { | 3555 if (std::isnan(fs) || std::isnan(ft)) { |
3330 set_fpu_register(fd_reg(), -1); | 3556 set_fpu_register(fd_reg(), -1); |
3331 } else { | 3557 } else { |
3332 set_fpu_register(fd_reg(), 0); | 3558 set_fpu_register(fd_reg(), 0); |
3333 } | 3559 } |
3560 TraceRegWr(get_fpu_register(fd_reg())); | |
3334 break; | 3561 break; |
3335 case CMP_EQ: | 3562 case CMP_EQ: |
3336 if (fs == ft) { | 3563 if (fs == ft) { |
3337 set_fpu_register(fd_reg(), -1); | 3564 set_fpu_register(fd_reg(), -1); |
3338 } else { | 3565 } else { |
3339 set_fpu_register(fd_reg(), 0); | 3566 set_fpu_register(fd_reg(), 0); |
3340 } | 3567 } |
3568 TraceRegWr(get_fpu_register(fd_reg())); | |
3341 break; | 3569 break; |
3342 case CMP_UEQ: | 3570 case CMP_UEQ: |
3343 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { | 3571 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { |
3344 set_fpu_register(fd_reg(), -1); | 3572 set_fpu_register(fd_reg(), -1); |
3345 } else { | 3573 } else { |
3346 set_fpu_register(fd_reg(), 0); | 3574 set_fpu_register(fd_reg(), 0); |
3347 } | 3575 } |
3576 TraceRegWr(get_fpu_register(fd_reg())); | |
3348 break; | 3577 break; |
3349 case CMP_LT: | 3578 case CMP_LT: |
3350 if (fs < ft) { | 3579 if (fs < ft) { |
3351 set_fpu_register(fd_reg(), -1); | 3580 set_fpu_register(fd_reg(), -1); |
3352 } else { | 3581 } else { |
3353 set_fpu_register(fd_reg(), 0); | 3582 set_fpu_register(fd_reg(), 0); |
3354 } | 3583 } |
3584 TraceRegWr(get_fpu_register(fd_reg())); | |
3355 break; | 3585 break; |
3356 case CMP_ULT: | 3586 case CMP_ULT: |
3357 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { | 3587 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { |
3358 set_fpu_register(fd_reg(), -1); | 3588 set_fpu_register(fd_reg(), -1); |
3359 } else { | 3589 } else { |
3360 set_fpu_register(fd_reg(), 0); | 3590 set_fpu_register(fd_reg(), 0); |
3361 } | 3591 } |
3592 TraceRegWr(get_fpu_register(fd_reg())); | |
3362 break; | 3593 break; |
3363 case CMP_LE: | 3594 case CMP_LE: |
3364 if (fs <= ft) { | 3595 if (fs <= ft) { |
3365 set_fpu_register(fd_reg(), -1); | 3596 set_fpu_register(fd_reg(), -1); |
3366 } else { | 3597 } else { |
3367 set_fpu_register(fd_reg(), 0); | 3598 set_fpu_register(fd_reg(), 0); |
3368 } | 3599 } |
3600 TraceRegWr(get_fpu_register(fd_reg())); | |
3369 break; | 3601 break; |
3370 case CMP_ULE: | 3602 case CMP_ULE: |
3371 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { | 3603 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { |
3372 set_fpu_register(fd_reg(), -1); | 3604 set_fpu_register(fd_reg(), -1); |
3373 } else { | 3605 } else { |
3374 set_fpu_register(fd_reg(), 0); | 3606 set_fpu_register(fd_reg(), 0); |
3375 } | 3607 } |
3608 TraceRegWr(get_fpu_register(fd_reg())); | |
3376 break; | 3609 break; |
3377 case CMP_OR: | 3610 case CMP_OR: |
3378 if (!std::isnan(fs) && !std::isnan(ft)) { | 3611 if (!std::isnan(fs) && !std::isnan(ft)) { |
3379 set_fpu_register(fd_reg(), -1); | 3612 set_fpu_register(fd_reg(), -1); |
3380 } else { | 3613 } else { |
3381 set_fpu_register(fd_reg(), 0); | 3614 set_fpu_register(fd_reg(), 0); |
3382 } | 3615 } |
3616 TraceRegWr(get_fpu_register(fd_reg())); | |
3383 break; | 3617 break; |
3384 case CMP_UNE: | 3618 case CMP_UNE: |
3385 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { | 3619 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { |
3386 set_fpu_register(fd_reg(), -1); | 3620 set_fpu_register(fd_reg(), -1); |
3387 } else { | 3621 } else { |
3388 set_fpu_register(fd_reg(), 0); | 3622 set_fpu_register(fd_reg(), 0); |
3389 } | 3623 } |
3624 TraceRegWr(get_fpu_register(fd_reg())); | |
3390 break; | 3625 break; |
3391 case CMP_NE: | 3626 case CMP_NE: |
3392 if (fs != ft && (!std::isnan(fs) && !std::isnan(ft))) { | 3627 if (fs != ft && (!std::isnan(fs) && !std::isnan(ft))) { |
3393 set_fpu_register(fd_reg(), -1); | 3628 set_fpu_register(fd_reg(), -1); |
3394 } else { | 3629 } else { |
3395 set_fpu_register(fd_reg(), 0); | 3630 set_fpu_register(fd_reg(), 0); |
3396 } | 3631 } |
3632 TraceRegWr(get_fpu_register(fd_reg())); | |
3397 break; | 3633 break; |
3398 default: | 3634 default: |
3399 UNREACHABLE(); | 3635 UNREACHABLE(); |
3400 } | 3636 } |
3401 } | 3637 } |
3402 | 3638 |
3403 | 3639 |
3404 void Simulator::DecodeTypeRegisterCOP1() { | 3640 void Simulator::DecodeTypeRegisterCOP1() { |
3405 switch (instr_.RsFieldRaw()) { | 3641 switch (instr_.RsFieldRaw()) { |
3406 case CFC1: | 3642 case CFC1: |
3407 // At the moment only FCSR is supported. | 3643 // At the moment only FCSR is supported. |
3408 DCHECK(fs_reg() == kFCSRRegister); | 3644 DCHECK(fs_reg() == kFCSRRegister); |
3409 set_register(rt_reg(), FCSR_); | 3645 set_register(rt_reg(), FCSR_); |
3646 TraceRegWr(get_register(rt_reg())); | |
3410 break; | 3647 break; |
3411 case MFC1: | 3648 case MFC1: |
3412 set_register(rt_reg(), get_fpu_register_word(fs_reg())); | 3649 set_register(rt_reg(), get_fpu_register_word(fs_reg())); |
3650 TraceRegWr(get_register(rt_reg())); | |
3413 break; | 3651 break; |
3414 case MFHC1: | 3652 case MFHC1: |
3415 if (IsFp64Mode()) { | 3653 if (IsFp64Mode()) { |
3416 set_register(rt_reg(), get_fpu_register_hi_word(fs_reg())); | 3654 set_register(rt_reg(), get_fpu_register_hi_word(fs_reg())); |
3417 } else { | 3655 } else { |
3418 set_register(rt_reg(), get_fpu_register_word(fs_reg() + 1)); | 3656 set_register(rt_reg(), get_fpu_register_word(fs_reg() + 1)); |
3419 } | 3657 } |
3658 TraceRegWr(get_register(rt_reg())); | |
3420 break; | 3659 break; |
3421 case CTC1: { | 3660 case CTC1: { |
3422 // At the moment only FCSR is supported. | 3661 // At the moment only FCSR is supported. |
3423 DCHECK(fs_reg() == kFCSRRegister); | 3662 DCHECK(fs_reg() == kFCSRRegister); |
3424 int32_t reg = registers_[rt_reg()]; | 3663 int32_t reg = registers_[rt_reg()]; |
3425 if (IsMipsArchVariant(kMips32r6)) { | 3664 if (IsMipsArchVariant(kMips32r6)) { |
3426 FCSR_ = reg | kFCSRNaN2008FlagMask; | 3665 FCSR_ = reg | kFCSRNaN2008FlagMask; |
3427 } else { | 3666 } else { |
3428 DCHECK(IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kMips32r2)); | 3667 DCHECK(IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kMips32r2)); |
3429 FCSR_ = reg & ~kFCSRNaN2008FlagMask; | 3668 FCSR_ = reg & ~kFCSRNaN2008FlagMask; |
3430 } | 3669 } |
3670 TraceRegWr(static_cast<int32_t>(FCSR_), FLOAT); | |
3431 break; | 3671 break; |
3432 } | 3672 } |
3433 case MTC1: | 3673 case MTC1: |
3434 // Hardware writes upper 32-bits to zero on mtc1. | 3674 // Hardware writes upper 32-bits to zero on mtc1. |
3435 set_fpu_register_hi_word(fs_reg(), 0); | 3675 set_fpu_register_hi_word(fs_reg(), 0); |
3436 set_fpu_register_word(fs_reg(), registers_[rt_reg()]); | 3676 set_fpu_register_word(fs_reg(), registers_[rt_reg()]); |
3677 TraceRegWr(get_fpu_register_word(fs_reg()), FLOAT); | |
3437 break; | 3678 break; |
3438 case MTHC1: | 3679 case MTHC1: |
3439 if (IsFp64Mode()) { | 3680 if (IsFp64Mode()) { |
3440 set_fpu_register_hi_word(fs_reg(), registers_[rt_reg()]); | 3681 set_fpu_register_hi_word(fs_reg(), registers_[rt_reg()]); |
3682 TraceRegWr(get_fpu_register(fs_reg()), DOUBLE); | |
3441 } else { | 3683 } else { |
3442 set_fpu_register_word(fs_reg() + 1, registers_[rt_reg()]); | 3684 set_fpu_register_word(fs_reg() + 1, registers_[rt_reg()]); |
3685 if (fs_reg() % 2) { | |
3686 TraceRegWr(get_fpu_register_word(fs_reg() + 1), FLOAT); | |
3687 } else { | |
3688 TraceRegWr(get_fpu_register(fs_reg()), DOUBLE); | |
3689 } | |
3443 } | 3690 } |
3444 break; | 3691 break; |
3445 case S: { | 3692 case S: { |
3446 DecodeTypeRegisterSRsType(); | 3693 DecodeTypeRegisterSRsType(); |
3447 break; | 3694 break; |
3448 } | 3695 } |
3449 case D: | 3696 case D: |
3450 DecodeTypeRegisterDRsType(); | 3697 DecodeTypeRegisterDRsType(); |
3451 break; | 3698 break; |
3452 case W: | 3699 case W: |
(...skipping 13 matching lines...) Expand all Loading... | |
3466 | 3713 |
3467 void Simulator::DecodeTypeRegisterCOP1X() { | 3714 void Simulator::DecodeTypeRegisterCOP1X() { |
3468 switch (instr_.FunctionFieldRaw()) { | 3715 switch (instr_.FunctionFieldRaw()) { |
3469 case MADD_S: { | 3716 case MADD_S: { |
3470 DCHECK(IsMipsArchVariant(kMips32r2)); | 3717 DCHECK(IsMipsArchVariant(kMips32r2)); |
3471 float fr, ft, fs; | 3718 float fr, ft, fs; |
3472 fr = get_fpu_register_float(fr_reg()); | 3719 fr = get_fpu_register_float(fr_reg()); |
3473 fs = get_fpu_register_float(fs_reg()); | 3720 fs = get_fpu_register_float(fs_reg()); |
3474 ft = get_fpu_register_float(ft_reg()); | 3721 ft = get_fpu_register_float(ft_reg()); |
3475 set_fpu_register_float(fd_reg(), fs * ft + fr); | 3722 set_fpu_register_float(fd_reg(), fs * ft + fr); |
3723 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3476 break; | 3724 break; |
3477 } | 3725 } |
3478 case MSUB_S: { | 3726 case MSUB_S: { |
3479 DCHECK(IsMipsArchVariant(kMips32r2)); | 3727 DCHECK(IsMipsArchVariant(kMips32r2)); |
3480 float fr, ft, fs; | 3728 float fr, ft, fs; |
3481 fr = get_fpu_register_float(fr_reg()); | 3729 fr = get_fpu_register_float(fr_reg()); |
3482 fs = get_fpu_register_float(fs_reg()); | 3730 fs = get_fpu_register_float(fs_reg()); |
3483 ft = get_fpu_register_float(ft_reg()); | 3731 ft = get_fpu_register_float(ft_reg()); |
3484 set_fpu_register_float(fd_reg(), fs * ft - fr); | 3732 set_fpu_register_float(fd_reg(), fs * ft - fr); |
3733 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT); | |
3485 break; | 3734 break; |
3486 } | 3735 } |
3487 case MADD_D: { | 3736 case MADD_D: { |
3488 DCHECK(IsMipsArchVariant(kMips32r2)); | 3737 DCHECK(IsMipsArchVariant(kMips32r2)); |
3489 double fr, ft, fs; | 3738 double fr, ft, fs; |
3490 fr = get_fpu_register_double(fr_reg()); | 3739 fr = get_fpu_register_double(fr_reg()); |
3491 fs = get_fpu_register_double(fs_reg()); | 3740 fs = get_fpu_register_double(fs_reg()); |
3492 ft = get_fpu_register_double(ft_reg()); | 3741 ft = get_fpu_register_double(ft_reg()); |
3493 set_fpu_register_double(fd_reg(), fs * ft + fr); | 3742 set_fpu_register_double(fd_reg(), fs * ft + fr); |
3743 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
3494 break; | 3744 break; |
3495 } | 3745 } |
3496 case MSUB_D: { | 3746 case MSUB_D: { |
3497 DCHECK(IsMipsArchVariant(kMips32r2)); | 3747 DCHECK(IsMipsArchVariant(kMips32r2)); |
3498 double fr, ft, fs; | 3748 double fr, ft, fs; |
3499 fr = get_fpu_register_double(fr_reg()); | 3749 fr = get_fpu_register_double(fr_reg()); |
3500 fs = get_fpu_register_double(fs_reg()); | 3750 fs = get_fpu_register_double(fs_reg()); |
3501 ft = get_fpu_register_double(ft_reg()); | 3751 ft = get_fpu_register_double(ft_reg()); |
3502 set_fpu_register_double(fd_reg(), fs * ft - fr); | 3752 set_fpu_register_double(fd_reg(), fs * ft - fr); |
3753 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
3503 break; | 3754 break; |
3504 } | 3755 } |
3505 default: | 3756 default: |
3506 UNREACHABLE(); | 3757 UNREACHABLE(); |
3507 } | 3758 } |
3508 } | 3759 } |
3509 | 3760 |
3510 | 3761 |
3511 void Simulator::DecodeTypeRegisterSPECIAL() { | 3762 void Simulator::DecodeTypeRegisterSPECIAL() { |
3512 int64_t alu_out = 0x12345678; | 3763 int64_t alu_out = 0x12345678; |
3513 int64_t i64hilo = 0; | 3764 int64_t i64hilo = 0; |
3514 uint64_t u64hilo = 0; | 3765 uint64_t u64hilo = 0; |
3515 bool do_interrupt = false; | 3766 bool do_interrupt = false; |
3516 | 3767 |
3517 switch (instr_.FunctionFieldRaw()) { | 3768 switch (instr_.FunctionFieldRaw()) { |
3518 case SELEQZ_S: | 3769 case SELEQZ_S: |
3519 DCHECK(IsMipsArchVariant(kMips32r6)); | 3770 DCHECK(IsMipsArchVariant(kMips32r6)); |
3520 set_register(rd_reg(), rt() == 0 ? rs() : 0); | 3771 SetResult(rd_reg(), rt() == 0 ? rs() : 0); |
3521 break; | 3772 break; |
3522 case SELNEZ_S: | 3773 case SELNEZ_S: |
3523 DCHECK(IsMipsArchVariant(kMips32r6)); | 3774 DCHECK(IsMipsArchVariant(kMips32r6)); |
3524 set_register(rd_reg(), rt() != 0 ? rs() : 0); | 3775 SetResult(rd_reg(), rt() != 0 ? rs() : 0); |
3525 break; | 3776 break; |
3526 case JR: { | 3777 case JR: { |
3527 int32_t next_pc = rs(); | 3778 int32_t next_pc = rs(); |
3528 int32_t current_pc = get_pc(); | 3779 int32_t current_pc = get_pc(); |
3529 Instruction* branch_delay_instr = | 3780 Instruction* branch_delay_instr = |
3530 reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize); | 3781 reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize); |
3531 BranchDelayInstructionDecode(branch_delay_instr); | 3782 BranchDelayInstructionDecode(branch_delay_instr); |
3532 set_pc(next_pc); | 3783 set_pc(next_pc); |
3533 pc_modified_ = true; | 3784 pc_modified_ = true; |
3534 break; | 3785 break; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3615 break; | 3866 break; |
3616 // Instructions using HI and LO registers. | 3867 // Instructions using HI and LO registers. |
3617 case MULT: | 3868 case MULT: |
3618 i64hilo = static_cast<int64_t>(rs()) * static_cast<int64_t>(rt()); | 3869 i64hilo = static_cast<int64_t>(rs()) * static_cast<int64_t>(rt()); |
3619 if (!IsMipsArchVariant(kMips32r6)) { | 3870 if (!IsMipsArchVariant(kMips32r6)) { |
3620 set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff)); | 3871 set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff)); |
3621 set_register(HI, static_cast<int32_t>(i64hilo >> 32)); | 3872 set_register(HI, static_cast<int32_t>(i64hilo >> 32)); |
3622 } else { | 3873 } else { |
3623 switch (sa()) { | 3874 switch (sa()) { |
3624 case MUL_OP: | 3875 case MUL_OP: |
3625 set_register(rd_reg(), static_cast<int32_t>(i64hilo & 0xffffffff)); | 3876 SetResult(rd_reg(), static_cast<int32_t>(i64hilo & 0xffffffff)); |
3626 break; | 3877 break; |
3627 case MUH_OP: | 3878 case MUH_OP: |
3628 set_register(rd_reg(), static_cast<int32_t>(i64hilo >> 32)); | 3879 SetResult(rd_reg(), static_cast<int32_t>(i64hilo >> 32)); |
3629 break; | 3880 break; |
3630 default: | 3881 default: |
3631 UNIMPLEMENTED_MIPS(); | 3882 UNIMPLEMENTED_MIPS(); |
3632 break; | 3883 break; |
3633 } | 3884 } |
3634 } | 3885 } |
3635 break; | 3886 break; |
3636 case MULTU: | 3887 case MULTU: |
3637 u64hilo = static_cast<uint64_t>(rs_u()) * static_cast<uint64_t>(rt_u()); | 3888 u64hilo = static_cast<uint64_t>(rs_u()) * static_cast<uint64_t>(rt_u()); |
3638 if (!IsMipsArchVariant(kMips32r6)) { | 3889 if (!IsMipsArchVariant(kMips32r6)) { |
3639 set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff)); | 3890 set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff)); |
3640 set_register(HI, static_cast<int32_t>(u64hilo >> 32)); | 3891 set_register(HI, static_cast<int32_t>(u64hilo >> 32)); |
3641 } else { | 3892 } else { |
3642 switch (sa()) { | 3893 switch (sa()) { |
3643 case MUL_OP: | 3894 case MUL_OP: |
3644 set_register(rd_reg(), static_cast<int32_t>(u64hilo & 0xffffffff)); | 3895 SetResult(rd_reg(), static_cast<int32_t>(u64hilo & 0xffffffff)); |
3645 break; | 3896 break; |
3646 case MUH_OP: | 3897 case MUH_OP: |
3647 set_register(rd_reg(), static_cast<int32_t>(u64hilo >> 32)); | 3898 SetResult(rd_reg(), static_cast<int32_t>(u64hilo >> 32)); |
3648 break; | 3899 break; |
3649 default: | 3900 default: |
3650 UNIMPLEMENTED_MIPS(); | 3901 UNIMPLEMENTED_MIPS(); |
3651 break; | 3902 break; |
3652 } | 3903 } |
3653 } | 3904 } |
3654 break; | 3905 break; |
3655 case DIV: | 3906 case DIV: |
3656 if (IsMipsArchVariant(kMips32r6)) { | 3907 if (IsMipsArchVariant(kMips32r6)) { |
3657 switch (sa()) { | 3908 switch (sa()) { |
3658 case DIV_OP: | 3909 case DIV_OP: |
3659 if (rs() == INT_MIN && rt() == -1) { | 3910 if (rs() == INT_MIN && rt() == -1) { |
3660 set_register(rd_reg(), INT_MIN); | 3911 SetResult(rd_reg(), INT_MIN); |
3661 } else if (rt() != 0) { | 3912 } else if (rt() != 0) { |
3662 set_register(rd_reg(), rs() / rt()); | 3913 SetResult(rd_reg(), rs() / rt()); |
3663 } | 3914 } |
3664 break; | 3915 break; |
3665 case MOD_OP: | 3916 case MOD_OP: |
3666 if (rs() == INT_MIN && rt() == -1) { | 3917 if (rs() == INT_MIN && rt() == -1) { |
3667 set_register(rd_reg(), 0); | 3918 SetResult(rd_reg(), 0); |
3668 } else if (rt() != 0) { | 3919 } else if (rt() != 0) { |
3669 set_register(rd_reg(), rs() % rt()); | 3920 SetResult(rd_reg(), rs() % rt()); |
3670 } | 3921 } |
3671 break; | 3922 break; |
3672 default: | 3923 default: |
3673 UNIMPLEMENTED_MIPS(); | 3924 UNIMPLEMENTED_MIPS(); |
3674 break; | 3925 break; |
3675 } | 3926 } |
3676 } else { | 3927 } else { |
3677 // Divide by zero and overflow was not checked in the | 3928 // Divide by zero and overflow was not checked in the |
3678 // configuration step - div and divu do not raise exceptions. On | 3929 // configuration step - div and divu do not raise exceptions. On |
3679 // division by 0 the result will be UNPREDICTABLE. On overflow | 3930 // division by 0 the result will be UNPREDICTABLE. On overflow |
3680 // (INT_MIN/-1), return INT_MIN which is what the hardware does. | 3931 // (INT_MIN/-1), return INT_MIN which is what the hardware does. |
3681 if (rs() == INT_MIN && rt() == -1) { | 3932 if (rs() == INT_MIN && rt() == -1) { |
3682 set_register(LO, INT_MIN); | 3933 set_register(LO, INT_MIN); |
3683 set_register(HI, 0); | 3934 set_register(HI, 0); |
3684 } else if (rt() != 0) { | 3935 } else if (rt() != 0) { |
3685 set_register(LO, rs() / rt()); | 3936 set_register(LO, rs() / rt()); |
3686 set_register(HI, rs() % rt()); | 3937 set_register(HI, rs() % rt()); |
3687 } | 3938 } |
3688 } | 3939 } |
3689 break; | 3940 break; |
3690 case DIVU: | 3941 case DIVU: |
3691 if (IsMipsArchVariant(kMips32r6)) { | 3942 if (IsMipsArchVariant(kMips32r6)) { |
3692 switch (sa()) { | 3943 switch (sa()) { |
3693 case DIV_OP: | 3944 case DIV_OP: |
3694 if (rt_u() != 0) { | 3945 if (rt_u() != 0) { |
3695 set_register(rd_reg(), rs_u() / rt_u()); | 3946 SetResult(rd_reg(), rs_u() / rt_u()); |
3696 } | 3947 } |
3697 break; | 3948 break; |
3698 case MOD_OP: | 3949 case MOD_OP: |
3699 if (rt_u() != 0) { | 3950 if (rt_u() != 0) { |
3700 set_register(rd_reg(), rs_u() % rt_u()); | 3951 SetResult(rd_reg(), rs_u() % rt_u()); |
3701 } | 3952 } |
3702 break; | 3953 break; |
3703 default: | 3954 default: |
3704 UNIMPLEMENTED_MIPS(); | 3955 UNIMPLEMENTED_MIPS(); |
3705 break; | 3956 break; |
3706 } | 3957 } |
3707 } else { | 3958 } else { |
3708 if (rt_u() != 0) { | 3959 if (rt_u() != 0) { |
3709 set_register(LO, rs_u() / rt_u()); | 3960 set_register(LO, rs_u() / rt_u()); |
3710 set_register(HI, rs_u() % rt_u()); | 3961 set_register(HI, rs_u() % rt_u()); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3784 break; | 4035 break; |
3785 case TNE: | 4036 case TNE: |
3786 do_interrupt = rs() != rt(); | 4037 do_interrupt = rs() != rt(); |
3787 break; | 4038 break; |
3788 case SYNC: | 4039 case SYNC: |
3789 // TODO(palfia): Ignore sync instruction for now. | 4040 // TODO(palfia): Ignore sync instruction for now. |
3790 break; | 4041 break; |
3791 // Conditional moves. | 4042 // Conditional moves. |
3792 case MOVN: | 4043 case MOVN: |
3793 if (rt()) { | 4044 if (rt()) { |
3794 set_register(rd_reg(), rs()); | 4045 SetResult(rd_reg(), rs()); |
3795 TraceRegWr(rs()); | |
3796 } | 4046 } |
3797 break; | 4047 break; |
3798 case MOVCI: { | 4048 case MOVCI: { |
3799 uint32_t cc = instr_.FBccValue(); | 4049 uint32_t cc = instr_.FBccValue(); |
3800 uint32_t fcsr_cc = get_fcsr_condition_bit(cc); | 4050 uint32_t fcsr_cc = get_fcsr_condition_bit(cc); |
3801 if (instr_.Bit(16)) { // Read Tf bit. | 4051 if (instr_.Bit(16)) { // Read Tf bit. |
3802 if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs()); | 4052 if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs()); |
3803 } else { | 4053 } else { |
3804 if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs()); | 4054 if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs()); |
3805 } | 4055 } |
3806 break; | 4056 break; |
3807 } | 4057 } |
3808 case MOVZ: | 4058 case MOVZ: |
3809 if (!rt()) { | 4059 if (!rt()) { |
3810 set_register(rd_reg(), rs()); | 4060 SetResult(rd_reg(), rs()); |
3811 TraceRegWr(rs()); | |
3812 } | 4061 } |
3813 break; | 4062 break; |
3814 default: | 4063 default: |
3815 UNREACHABLE(); | 4064 UNREACHABLE(); |
3816 } | 4065 } |
3817 if (do_interrupt) { | 4066 if (do_interrupt) { |
3818 SoftwareInterrupt(); | 4067 SoftwareInterrupt(); |
3819 } | 4068 } |
3820 } | 4069 } |
3821 | 4070 |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4365 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask; | 4614 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask; |
4366 uint32_t mask = (1 << al_offset * 8) - 1; | 4615 uint32_t mask = (1 << al_offset * 8) - 1; |
4367 addr = rs + se_imm16 - al_offset; | 4616 addr = rs + se_imm16 - al_offset; |
4368 uint32_t mem_value = ReadW(addr, instr_.instr()); | 4617 uint32_t mem_value = ReadW(addr, instr_.instr()); |
4369 mem_value = (rt << al_offset * 8) | (mem_value & mask); | 4618 mem_value = (rt << al_offset * 8) | (mem_value & mask); |
4370 WriteW(addr, mem_value, instr_.instr()); | 4619 WriteW(addr, mem_value, instr_.instr()); |
4371 break; | 4620 break; |
4372 } | 4621 } |
4373 case LWC1: | 4622 case LWC1: |
4374 set_fpu_register_hi_word(ft_reg, 0); | 4623 set_fpu_register_hi_word(ft_reg, 0); |
4375 set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr_.instr())); | 4624 set_fpu_register_word(ft_reg, |
4625 ReadW(rs + se_imm16, instr_.instr(), FLOAT)); | |
4626 if (ft_reg % 2) { | |
4627 TraceMemRd(rs + se_imm16, get_fpu_register(ft_reg - 1), FLOAT_DOUBLE); | |
4628 } else { | |
4629 TraceMemRd(rs + se_imm16, get_fpu_register_word(ft_reg), FLOAT); | |
4630 } | |
4376 break; | 4631 break; |
4377 case LDC1: | 4632 case LDC1: |
4378 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr_.instr())); | 4633 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr_.instr())); |
4634 TraceMemRd(rs + se_imm16, get_fpu_register(ft_reg), DOUBLE); | |
4379 break; | 4635 break; |
4380 case SWC1: | 4636 case SWC1: |
4381 WriteW(rs + se_imm16, get_fpu_register_word(ft_reg), instr_.instr()); | 4637 WriteW(rs + se_imm16, get_fpu_register_word(ft_reg), instr_.instr()); |
4638 TraceMemWr(rs + se_imm16, get_fpu_register_word(ft_reg)); | |
4382 break; | 4639 break; |
4383 case SDC1: | 4640 case SDC1: |
4384 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr_.instr()); | 4641 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr_.instr()); |
4642 TraceMemWr(rs + se_imm16, get_fpu_register(ft_reg)); | |
4385 break; | 4643 break; |
4386 // ------------- PC-Relative instructions. | 4644 // ------------- PC-Relative instructions. |
4387 case PCREL: { | 4645 case PCREL: { |
4388 // rt field: checking 5-bits. | 4646 // rt field: checking 5-bits. |
4389 int32_t imm21 = instr_.Imm21Value(); | 4647 int32_t imm21 = instr_.Imm21Value(); |
4390 int32_t current_pc = get_pc(); | 4648 int32_t current_pc = get_pc(); |
4391 uint8_t rt = (imm21 >> kImm16Bits); | 4649 uint8_t rt = (imm21 >> kImm16Bits); |
4392 switch (rt) { | 4650 switch (rt) { |
4393 case ALUIPC: | 4651 case ALUIPC: |
4394 addr = current_pc + (se_imm16 << 16); | 4652 addr = current_pc + (se_imm16 << 16); |
(...skipping 20 matching lines...) Expand all Loading... | |
4415 int32_t se_imm19 = imm19 | ((imm19 & 0x40000) ? 0xfff80000 : 0); | 4673 int32_t se_imm19 = imm19 | ((imm19 & 0x40000) ? 0xfff80000 : 0); |
4416 alu_out = current_pc + (se_imm19 << 2); | 4674 alu_out = current_pc + (se_imm19 << 2); |
4417 break; | 4675 break; |
4418 } | 4676 } |
4419 default: | 4677 default: |
4420 UNREACHABLE(); | 4678 UNREACHABLE(); |
4421 break; | 4679 break; |
4422 } | 4680 } |
4423 } | 4681 } |
4424 } | 4682 } |
4425 set_register(rs_reg, alu_out); | 4683 SetResult(rs_reg, alu_out); |
4426 break; | 4684 break; |
4427 } | 4685 } |
4428 default: | 4686 default: |
4429 UNREACHABLE(); | 4687 UNREACHABLE(); |
4430 } | 4688 } |
4431 | 4689 |
4432 if (execute_branch_delay_instruction) { | 4690 if (execute_branch_delay_instruction) { |
4433 // Execute branch delay slot | 4691 // Execute branch delay slot |
4434 // We don't check for end_sim_pc. First it should not be met as the current | 4692 // We don't check for end_sim_pc. First it should not be met as the current |
4435 // pc is valid. Secondly a jump should always execute its branch delay slot. | 4693 // pc is valid. Secondly a jump should always execute its branch delay slot. |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4694 | 4952 |
4695 | 4953 |
4696 #undef UNSUPPORTED | 4954 #undef UNSUPPORTED |
4697 | 4955 |
4698 } // namespace internal | 4956 } // namespace internal |
4699 } // namespace v8 | 4957 } // namespace v8 |
4700 | 4958 |
4701 #endif // USE_SIMULATOR | 4959 #endif // USE_SIMULATOR |
4702 | 4960 |
4703 #endif // V8_TARGET_ARCH_MIPS | 4961 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |