Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(221)

Side by Side Diff: src/mips/simulator-mips.cc

Issue 2603083002: MIPS[64]: Add support for FPR content in simulator trace. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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, &registers_[reg], 2 * sizeof(registers_[0])); 1125 memcpy(buffer, &registers_[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 int64_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;
ivica.bogosavljevic 2017/01/23 13:22:38 According to strict C/C++, bitwise operation shoul
Ilija.Pavlovic1 2017/01/27 09:09:16 Done.
1140 return 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
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 default:
1716 break;
ivica.bogosavljevic 2017/01/23 13:22:38 this should be UNREACHABLE, right?
Ilija.Pavlovic1 2017/01/27 09:09:16 Yes, this should be UNREACHABLE(). Also, missing "
1717 }
1694 } 1718 }
1695 } 1719 }
1696 1720
1721 void Simulator::TraceRegWr(int64_t value, TraceType t) {
1722 if (::v8::internal::FLAG_trace_sim) {
1723 union {
1724 int64_t fmt_int64;
1725 double fmt_double;
1726 } v;
1727 v.fmt_int64 = value;
1697 1728
1698 // TODO(plind): consider making icount_ printing a flag option. 1729 switch (t) {
1699 void Simulator::TraceMemRd(int32_t addr, int32_t value) { 1730 case DWORD:
1700 if (::v8::internal::FLAG_trace_sim) { 1731 SNPrintF(trace_buf_, "%016" PRIx64 " (%" PRIu64 ") int64:%" PRId64
1701 SNPrintF(trace_buf_, "%08x <-- [%08x] (%" PRIu64 ")", value, addr, 1732 " uint64:%" PRIu64,
1702 icount_); 1733 value, icount_, value, value);
1734 break;
1735 case DOUBLE:
1736 SNPrintF(trace_buf_, "%016" PRIx64 " (%" PRIu64 ") dbl:%e",
1737 v.fmt_int64, icount_, v.fmt_double);
1738 default:
1739 break;
ivica.bogosavljevic 2017/01/23 13:22:38 UNREACHABLE!
Ilija.Pavlovic1 2017/01/27 09:09:16 Done.
1740 }
1703 } 1741 }
1704 } 1742 }
1705 1743
1744 // TODO(plind): consider making icount_ printing a flag option.
1745 void Simulator::TraceMemRd(int32_t addr, int32_t value, TraceType t) {
1746 if (::v8::internal::FLAG_trace_sim) {
1747 union {
1748 int32_t fmt_int32;
1749 float fmt_float;
1750 } v;
1751 v.fmt_int32 = value;
1752
1753 switch (t) {
1754 case WORD:
1755 SNPrintF(trace_buf_, "%08" PRIx32 " <-- [%08" PRIx32 "] (%" PRIu64
1756 ") int32:%" PRId32 " uint32:%" PRIu32,
1757 value, addr, icount_, value, value);
1758 break;
1759 case FLOAT:
1760 SNPrintF(trace_buf_,
1761 "%08" PRIx32 " <-- [%08" PRIx32 "] (%" PRIu64 ") flt:%e",
1762 v.fmt_int32, addr, icount_, v.fmt_float);
1763 break;
1764 default:
1765 break;
ivica.bogosavljevic 2017/01/23 13:22:38 ibid here and all places bellow!
Ilija.Pavlovic1 2017/01/27 09:09:16 Done.
1766 }
1767 }
1768 }
1769
1706 1770
1707 void Simulator::TraceMemWr(int32_t addr, int32_t value, TraceType t) { 1771 void Simulator::TraceMemWr(int32_t addr, int32_t value, TraceType t) {
1708 if (::v8::internal::FLAG_trace_sim) { 1772 if (::v8::internal::FLAG_trace_sim) {
1709 switch (t) { 1773 switch (t) {
1710 case BYTE: 1774 case BYTE:
1711 SNPrintF(trace_buf_, " %02x --> [%08x]", 1775 SNPrintF(trace_buf_,
1712 static_cast<int8_t>(value), addr); 1776 " %02" PRIx8 " --> [%08" PRIx32 "] (%" PRIu64 ")",
1777 static_cast<uint8_t>(value), addr, icount_);
1713 break; 1778 break;
1714 case HALF: 1779 case HALF:
1715 SNPrintF(trace_buf_, " %04x --> [%08x]", static_cast<int16_t>(value), 1780 SNPrintF(trace_buf_,
1716 addr); 1781 " %04" PRIx16 " --> [%08" PRIx32 "] (%" PRIu64 ")",
1782 static_cast<uint16_t>(value), addr, icount_);
1717 break; 1783 break;
1718 case WORD: 1784 case WORD:
1719 SNPrintF(trace_buf_, "%08x --> [%08x]", value, addr); 1785 SNPrintF(trace_buf_,
1786 "%08" PRIx32 " --> [%08" PRIx32 "] (%" PRIu64 ")", value,
1787 addr, icount_);
1788 break;
1789 default:
1720 break; 1790 break;
1721 } 1791 }
1722 } 1792 }
1723 } 1793 }
1724 1794
1795 void Simulator::TraceMemRd(int32_t addr, int64_t value, TraceType t) {
1796 if (::v8::internal::FLAG_trace_sim) {
1797 union {
1798 int64_t fmt_int64;
1799 int32_t fmt_int32[2];
1800 float fmt_float[2];
1801 double fmt_double;
1802 } v;
1803 v.fmt_int64 = value;
1725 1804
1726 int Simulator::ReadW(int32_t addr, Instruction* instr) { 1805 switch (t) {
1806 case DWORD:
1807 SNPrintF(trace_buf_, "%016" PRIx64 " <-- [%08" PRIx32 "] (%" PRIu64
1808 ") int64:%" PRId64 " uint64:%" PRIu64,
1809 v.fmt_int64, addr, icount_, v.fmt_int64, v.fmt_int64);
1810 break;
1811 case DOUBLE:
1812 SNPrintF(trace_buf_, "%016" PRIx64 " <-- [%08" PRIx32 "] (%" PRIu64
1813 ") dbl:%e",
1814 v.fmt_int64, addr, icount_, v.fmt_double);
1815 break;
1816 case FLOAT_DOUBLE:
1817 SNPrintF(trace_buf_, "%08" PRIx32 " <-- [%08" PRIx32 "] (%" PRIu64
1818 ") flt:%e dbl:%e",
1819 v.fmt_int32[1], addr, icount_, v.fmt_float[1], v.fmt_double);
1820 break;
1821 default:
1822 break;
1823 }
1824 }
1825 }
1826
1827 void Simulator::TraceMemWr(int32_t addr, int64_t value, TraceType t) {
1828 if (::v8::internal::FLAG_trace_sim) {
1829 switch (t) {
1830 case DWORD:
1831 SNPrintF(trace_buf_,
1832 "%016" PRIx64 " --> [%08" PRIx32 "] (%" PRIu64 ")", value,
1833 addr, icount_);
1834 break;
1835 default:
1836 break;
1837 }
1838 }
1839 }
1840
1841 int Simulator::ReadW(int32_t addr, Instruction* instr, TraceType t) {
1727 if (addr >=0 && addr < 0x400) { 1842 if (addr >=0 && addr < 0x400) {
1728 // This has to be a NULL-dereference, drop into debugger. 1843 // 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, 1844 PrintF("Memory read from bad address: 0x%08x, pc=0x%08" PRIxPTR "\n", addr,
1730 reinterpret_cast<intptr_t>(instr)); 1845 reinterpret_cast<intptr_t>(instr));
1731 MipsDebugger dbg(this); 1846 MipsDebugger dbg(this);
1732 dbg.Debug(); 1847 dbg.Debug();
1733 } 1848 }
1734 if ((addr & kPointerAlignmentMask) == 0 || IsMipsArchVariant(kMips32r6)) { 1849 if ((addr & kPointerAlignmentMask) == 0 || IsMipsArchVariant(kMips32r6)) {
1735 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); 1850 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1736 TraceMemRd(addr, static_cast<int32_t>(*ptr)); 1851 if (t == WORD) {
1852 TraceMemRd(addr, static_cast<int32_t>(*ptr), t);
ivica.bogosavljevic 2017/01/23 13:22:38 What happens if t != WORD? Should it be unreachabl
Ilija.Pavlovic1 2017/01/27 09:09:16 For WORD, the trace should be visible. For FLOAT,
1853 }
1737 return *ptr; 1854 return *ptr;
1738 } 1855 }
1739 PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n", 1856 PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1740 addr, 1857 addr,
1741 reinterpret_cast<intptr_t>(instr)); 1858 reinterpret_cast<intptr_t>(instr));
1742 MipsDebugger dbg(this); 1859 MipsDebugger dbg(this);
1743 dbg.Debug(); 1860 dbg.Debug();
1744 return 0; 1861 return 0;
1745 } 1862 }
1746 1863
1747
1748 void Simulator::WriteW(int32_t addr, int value, Instruction* instr) { 1864 void Simulator::WriteW(int32_t addr, int value, Instruction* instr) {
1749 if (addr >= 0 && addr < 0x400) { 1865 if (addr >= 0 && addr < 0x400) {
1750 // This has to be a NULL-dereference, drop into debugger. 1866 // 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, 1867 PrintF("Memory write to bad address: 0x%08x, pc=0x%08" PRIxPTR "\n", addr,
1752 reinterpret_cast<intptr_t>(instr)); 1868 reinterpret_cast<intptr_t>(instr));
1753 MipsDebugger dbg(this); 1869 MipsDebugger dbg(this);
1754 dbg.Debug(); 1870 dbg.Debug();
1755 } 1871 }
1756 if ((addr & kPointerAlignmentMask) == 0 || IsMipsArchVariant(kMips32r6)) { 1872 if ((addr & kPointerAlignmentMask) == 0 || IsMipsArchVariant(kMips32r6)) {
1757 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); 1873 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1758 TraceMemWr(addr, value, WORD); 1874 TraceMemWr(addr, value, WORD);
1759 *ptr = value; 1875 *ptr = value;
1760 return; 1876 return;
1761 } 1877 }
1762 PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n", 1878 PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1763 addr, 1879 addr,
1764 reinterpret_cast<intptr_t>(instr)); 1880 reinterpret_cast<intptr_t>(instr));
1765 MipsDebugger dbg(this); 1881 MipsDebugger dbg(this);
1766 dbg.Debug(); 1882 dbg.Debug();
1767 } 1883 }
1768 1884
1769
1770 double Simulator::ReadD(int32_t addr, Instruction* instr) { 1885 double Simulator::ReadD(int32_t addr, Instruction* instr) {
1771 if ((addr & kDoubleAlignmentMask) == 0 || IsMipsArchVariant(kMips32r6)) { 1886 if ((addr & kDoubleAlignmentMask) == 0 || IsMipsArchVariant(kMips32r6)) {
1772 double* ptr = reinterpret_cast<double*>(addr); 1887 double* ptr = reinterpret_cast<double*>(addr);
1773 return *ptr; 1888 return *ptr;
1774 } 1889 }
1775 PrintF("Unaligned (double) read at 0x%08x, pc=0x%08" V8PRIxPTR "\n", 1890 PrintF("Unaligned (double) read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
1776 addr, 1891 addr,
1777 reinterpret_cast<intptr_t>(instr)); 1892 reinterpret_cast<intptr_t>(instr));
1778 base::OS::Abort(); 1893 base::OS::Abort();
1779 return 0; 1894 return 0;
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after
2457 result = upper; 2572 result = upper;
2458 break; 2573 break;
2459 case kRoundToMinusInf: 2574 case kRoundToMinusInf:
2460 result = lower; 2575 result = lower;
2461 break; 2576 break;
2462 } 2577 }
2463 set_fpu_register_double(fd_reg(), result); 2578 set_fpu_register_double(fd_reg(), result);
2464 if (result != fs) { 2579 if (result != fs) {
2465 set_fcsr_bit(kFCSRInexactFlagBit, true); 2580 set_fcsr_bit(kFCSRInexactFlagBit, true);
2466 } 2581 }
2582 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2467 break; 2583 break;
2468 } 2584 }
2469 case SEL: 2585 case SEL:
2470 DCHECK(IsMipsArchVariant(kMips32r6)); 2586 DCHECK(IsMipsArchVariant(kMips32r6));
2471 set_fpu_register_double(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); 2587 set_fpu_register_double(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft);
2588 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2472 break; 2589 break;
2473 case SELEQZ_C: 2590 case SELEQZ_C:
2474 DCHECK(IsMipsArchVariant(kMips32r6)); 2591 DCHECK(IsMipsArchVariant(kMips32r6));
2475 set_fpu_register_double(fd_reg(), (ft_int & 0x1) == 0 ? fs : 0.0); 2592 set_fpu_register_double(fd_reg(), (ft_int & 0x1) == 0 ? fs : 0.0);
2593 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2476 break; 2594 break;
2477 case SELNEZ_C: 2595 case SELNEZ_C:
2478 DCHECK(IsMipsArchVariant(kMips32r6)); 2596 DCHECK(IsMipsArchVariant(kMips32r6));
2479 set_fpu_register_double(fd_reg(), (ft_int & 0x1) != 0 ? fs : 0.0); 2597 set_fpu_register_double(fd_reg(), (ft_int & 0x1) != 0 ? fs : 0.0);
2598 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2480 break; 2599 break;
2481 case MOVZ_C: { 2600 case MOVZ_C: {
2482 DCHECK(IsMipsArchVariant(kMips32r2)); 2601 DCHECK(IsMipsArchVariant(kMips32r2));
2483 if (rt() == 0) { 2602 if (rt() == 0) {
2484 set_fpu_register_double(fd_reg(), fs); 2603 set_fpu_register_double(fd_reg(), fs);
2485 } 2604 }
2605 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2486 break; 2606 break;
2487 } 2607 }
2488 case MOVN_C: { 2608 case MOVN_C: {
2489 DCHECK(IsMipsArchVariant(kMips32r2)); 2609 DCHECK(IsMipsArchVariant(kMips32r2));
2490 int32_t rt_reg = instr_.RtValue(); 2610 int32_t rt_reg = instr_.RtValue();
2491 int32_t rt = get_register(rt_reg); 2611 int32_t rt = get_register(rt_reg);
2492 if (rt != 0) { 2612 if (rt != 0) {
2493 set_fpu_register_double(fd_reg(), fs); 2613 set_fpu_register_double(fd_reg(), fs);
2494 } 2614 }
2615 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2495 break; 2616 break;
2496 } 2617 }
2497 case MOVF: { 2618 case MOVF: {
2498 // Same function field for MOVT.D and MOVF.D 2619 // Same function field for MOVT.D and MOVF.D
2499 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; 2620 uint32_t ft_cc = (ft_reg() >> 2) & 0x7;
2500 ft_cc = get_fcsr_condition_bit(ft_cc); 2621 ft_cc = get_fcsr_condition_bit(ft_cc);
2501 if (instr_.Bit(16)) { // Read Tf bit. 2622 if (instr_.Bit(16)) { // Read Tf bit.
2502 // MOVT.D 2623 // MOVT.D
2503 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); 2624 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs);
2504 } else { 2625 } else {
2505 // MOVF.D 2626 // MOVF.D
2506 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); 2627 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs);
2507 } 2628 }
2629 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2508 break; 2630 break;
2509 } 2631 }
2510 case MIN: 2632 case MIN:
2511 DCHECK(IsMipsArchVariant(kMips32r6)); 2633 DCHECK(IsMipsArchVariant(kMips32r6));
2512 set_fpu_register_double(fd_reg(), FPUMin(ft, fs)); 2634 set_fpu_register_double(fd_reg(), FPUMin(ft, fs));
2635 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2513 break; 2636 break;
2514 case MAX: 2637 case MAX:
2515 DCHECK(IsMipsArchVariant(kMips32r6)); 2638 DCHECK(IsMipsArchVariant(kMips32r6));
2516 set_fpu_register_double(fd_reg(), FPUMax(ft, fs)); 2639 set_fpu_register_double(fd_reg(), FPUMax(ft, fs));
2640 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2517 break; 2641 break;
2518 case MINA: 2642 case MINA:
2519 DCHECK(IsMipsArchVariant(kMips32r6)); 2643 DCHECK(IsMipsArchVariant(kMips32r6));
2520 set_fpu_register_double(fd_reg(), FPUMinA(ft, fs)); 2644 set_fpu_register_double(fd_reg(), FPUMinA(ft, fs));
2645 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2521 break; 2646 break;
2522 case MAXA: 2647 case MAXA:
2523 DCHECK(IsMipsArchVariant(kMips32r6)); 2648 DCHECK(IsMipsArchVariant(kMips32r6));
2524 set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs)); 2649 set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs));
2650 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2525 break; 2651 break;
2526 case ADD_D: 2652 case ADD_D:
2527 set_fpu_register_double( 2653 set_fpu_register_double(
2528 fd_reg(), 2654 fd_reg(),
2529 FPUCanonalizeOperation( 2655 FPUCanonalizeOperation(
2530 [](double lhs, double rhs) { return lhs + rhs; }, fs, ft)); 2656 [](double lhs, double rhs) { return lhs + rhs; }, fs, ft));
2657 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2531 break; 2658 break;
2532 case SUB_D: 2659 case SUB_D:
2533 set_fpu_register_double( 2660 set_fpu_register_double(
2534 fd_reg(), 2661 fd_reg(),
2535 FPUCanonalizeOperation( 2662 FPUCanonalizeOperation(
2536 [](double lhs, double rhs) { return lhs - rhs; }, fs, ft)); 2663 [](double lhs, double rhs) { return lhs - rhs; }, fs, ft));
2664 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2537 break; 2665 break;
2538 case MADDF_D: 2666 case MADDF_D:
2539 DCHECK(IsMipsArchVariant(kMips32r6)); 2667 DCHECK(IsMipsArchVariant(kMips32r6));
2540 set_fpu_register_double(fd_reg(), std::fma(fs, ft, fd)); 2668 set_fpu_register_double(fd_reg(), std::fma(fs, ft, fd));
2669 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2541 break; 2670 break;
2542 case MSUBF_D: 2671 case MSUBF_D:
2543 DCHECK(IsMipsArchVariant(kMips32r6)); 2672 DCHECK(IsMipsArchVariant(kMips32r6));
2544 set_fpu_register_double(fd_reg(), std::fma(-fs, ft, fd)); 2673 set_fpu_register_double(fd_reg(), std::fma(-fs, ft, fd));
2674 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2545 break; 2675 break;
2546 case MUL_D: 2676 case MUL_D:
2547 set_fpu_register_double( 2677 set_fpu_register_double(
2548 fd_reg(), 2678 fd_reg(),
2549 FPUCanonalizeOperation( 2679 FPUCanonalizeOperation(
2550 [](double lhs, double rhs) { return lhs * rhs; }, fs, ft)); 2680 [](double lhs, double rhs) { return lhs * rhs; }, fs, ft));
2681 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2551 break; 2682 break;
2552 case DIV_D: 2683 case DIV_D:
2553 set_fpu_register_double( 2684 set_fpu_register_double(
2554 fd_reg(), 2685 fd_reg(),
2555 FPUCanonalizeOperation( 2686 FPUCanonalizeOperation(
2556 [](double lhs, double rhs) { return lhs / rhs; }, fs, ft)); 2687 [](double lhs, double rhs) { return lhs / rhs; }, fs, ft));
2688 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2557 break; 2689 break;
2558 case ABS_D: 2690 case ABS_D:
2559 set_fpu_register_double( 2691 set_fpu_register_double(
2560 fd_reg(), 2692 fd_reg(),
2561 FPUCanonalizeOperation([](double fs) { return FPAbs(fs); }, fs)); 2693 FPUCanonalizeOperation([](double fs) { return FPAbs(fs); }, fs));
2694 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2562 break; 2695 break;
2563 case MOV_D: 2696 case MOV_D:
2564 set_fpu_register_double(fd_reg(), fs); 2697 set_fpu_register_double(fd_reg(), fs);
2698 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2565 break; 2699 break;
2566 case NEG_D: 2700 case NEG_D:
2567 set_fpu_register_double( 2701 set_fpu_register_double(
2568 fd_reg(), FPUCanonalizeOperation([](double src) { return -src; }, 2702 fd_reg(), FPUCanonalizeOperation([](double src) { return -src; },
2569 KeepSign::yes, fs)); 2703 KeepSign::yes, fs));
2704 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2570 break; 2705 break;
2571 case SQRT_D: 2706 case SQRT_D:
2572 set_fpu_register_double( 2707 set_fpu_register_double(
2573 fd_reg(), 2708 fd_reg(),
2574 FPUCanonalizeOperation([](double fs) { return std::sqrt(fs); }, fs)); 2709 FPUCanonalizeOperation([](double fs) { return std::sqrt(fs); }, fs));
2710 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2575 break; 2711 break;
2576 case RSQRT_D: 2712 case RSQRT_D:
2577 set_fpu_register_double( 2713 set_fpu_register_double(
2578 fd_reg(), FPUCanonalizeOperation( 2714 fd_reg(), FPUCanonalizeOperation(
2579 [](double fs) { return 1.0 / std::sqrt(fs); }, fs)); 2715 [](double fs) { return 1.0 / std::sqrt(fs); }, fs));
2716 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2580 break; 2717 break;
2581 case RECIP_D: 2718 case RECIP_D:
2582 set_fpu_register_double( 2719 set_fpu_register_double(
2583 fd_reg(), 2720 fd_reg(),
2584 FPUCanonalizeOperation([](double fs) { return 1.0 / fs; }, fs)); 2721 FPUCanonalizeOperation([](double fs) { return 1.0 / fs; }, fs));
2722 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2585 break; 2723 break;
2586 case C_UN_D: 2724 case C_UN_D:
2587 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); 2725 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
2726 TraceRegWr(test_fcsr_bit(fcsr_cc));
2588 break; 2727 break;
2589 case C_EQ_D: 2728 case C_EQ_D:
2590 set_fcsr_bit(fcsr_cc, (fs == ft)); 2729 set_fcsr_bit(fcsr_cc, (fs == ft));
2730 TraceRegWr(test_fcsr_bit(fcsr_cc));
2591 break; 2731 break;
2592 case C_UEQ_D: 2732 case C_UEQ_D:
2593 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); 2733 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft)));
2734 TraceRegWr(test_fcsr_bit(fcsr_cc));
2594 break; 2735 break;
2595 case C_OLT_D: 2736 case C_OLT_D:
2596 set_fcsr_bit(fcsr_cc, (fs < ft)); 2737 set_fcsr_bit(fcsr_cc, (fs < ft));
2738 TraceRegWr(test_fcsr_bit(fcsr_cc));
2597 break; 2739 break;
2598 case C_ULT_D: 2740 case C_ULT_D:
2599 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); 2741 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft)));
2742 TraceRegWr(test_fcsr_bit(fcsr_cc));
2600 break; 2743 break;
2601 case C_OLE_D: 2744 case C_OLE_D:
2602 set_fcsr_bit(fcsr_cc, (fs <= ft)); 2745 set_fcsr_bit(fcsr_cc, (fs <= ft));
2746 TraceRegWr(test_fcsr_bit(fcsr_cc));
2603 break; 2747 break;
2604 case C_ULE_D: 2748 case C_ULE_D:
2605 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); 2749 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft)));
2750 TraceRegWr(test_fcsr_bit(fcsr_cc));
2606 break; 2751 break;
2607 case CVT_W_D: { // Convert double to word. 2752 case CVT_W_D: { // Convert double to word.
2608 double rounded; 2753 double rounded;
2609 int32_t result; 2754 int32_t result;
2610 round_according_to_fcsr(fs, rounded, result, fs); 2755 round_according_to_fcsr(fs, rounded, result, fs);
2611 set_fpu_register_word(fd_reg(), result); 2756 set_fpu_register_word(fd_reg(), result);
2612 if (set_fcsr_round_error(fs, rounded)) { 2757 if (set_fcsr_round_error(fs, rounded)) {
2613 set_fpu_register_word_invalid_result(fs, rounded); 2758 set_fpu_register_word_invalid_result(fs, rounded);
2614 } 2759 }
2760 TraceRegWr(get_fpu_register_word(fd_reg()));
2615 } break; 2761 } break;
2616 case ROUND_W_D: // Round double to word (round half to even). 2762 case ROUND_W_D: // Round double to word (round half to even).
2617 { 2763 {
2618 double rounded = std::floor(fs + 0.5); 2764 double rounded = std::floor(fs + 0.5);
2619 int32_t result = static_cast<int32_t>(rounded); 2765 int32_t result = static_cast<int32_t>(rounded);
2620 if ((result & 1) != 0 && result - fs == 0.5) { 2766 if ((result & 1) != 0 && result - fs == 0.5) {
2621 // If the number is halfway between two integers, 2767 // If the number is halfway between two integers,
2622 // round to the even one. 2768 // round to the even one.
2623 result--; 2769 result--;
2624 } 2770 }
2625 set_fpu_register_word(fd_reg(), result); 2771 set_fpu_register_word(fd_reg(), result);
2626 if (set_fcsr_round_error(fs, rounded)) { 2772 if (set_fcsr_round_error(fs, rounded)) {
2627 set_fpu_register_word_invalid_result(fs, rounded); 2773 set_fpu_register_word_invalid_result(fs, rounded);
2628 } 2774 }
2775 TraceRegWr(get_fpu_register_word(fd_reg()));
2629 } break; 2776 } break;
2630 case TRUNC_W_D: // Truncate double to word (round towards 0). 2777 case TRUNC_W_D: // Truncate double to word (round towards 0).
2631 { 2778 {
2632 double rounded = trunc(fs); 2779 double rounded = trunc(fs);
2633 int32_t result = static_cast<int32_t>(rounded); 2780 int32_t result = static_cast<int32_t>(rounded);
2634 set_fpu_register_word(fd_reg(), result); 2781 set_fpu_register_word(fd_reg(), result);
2635 if (set_fcsr_round_error(fs, rounded)) { 2782 if (set_fcsr_round_error(fs, rounded)) {
2636 set_fpu_register_word_invalid_result(fs, rounded); 2783 set_fpu_register_word_invalid_result(fs, rounded);
2637 } 2784 }
2785 TraceRegWr(get_fpu_register_word(fd_reg()));
2638 } break; 2786 } break;
2639 case FLOOR_W_D: // Round double to word towards negative infinity. 2787 case FLOOR_W_D: // Round double to word towards negative infinity.
2640 { 2788 {
2641 double rounded = std::floor(fs); 2789 double rounded = std::floor(fs);
2642 int32_t result = static_cast<int32_t>(rounded); 2790 int32_t result = static_cast<int32_t>(rounded);
2643 set_fpu_register_word(fd_reg(), result); 2791 set_fpu_register_word(fd_reg(), result);
2644 if (set_fcsr_round_error(fs, rounded)) { 2792 if (set_fcsr_round_error(fs, rounded)) {
2645 set_fpu_register_word_invalid_result(fs, rounded); 2793 set_fpu_register_word_invalid_result(fs, rounded);
2646 } 2794 }
2795 TraceRegWr(get_fpu_register_word(fd_reg()));
2647 } break; 2796 } break;
2648 case CEIL_W_D: // Round double to word towards positive infinity. 2797 case CEIL_W_D: // Round double to word towards positive infinity.
2649 { 2798 {
2650 double rounded = std::ceil(fs); 2799 double rounded = std::ceil(fs);
2651 int32_t result = static_cast<int32_t>(rounded); 2800 int32_t result = static_cast<int32_t>(rounded);
2652 set_fpu_register_word(fd_reg(), result); 2801 set_fpu_register_word(fd_reg(), result);
2653 if (set_fcsr_round_error(fs, rounded)) { 2802 if (set_fcsr_round_error(fs, rounded)) {
2654 set_fpu_register_word_invalid_result(fs, rounded); 2803 set_fpu_register_word_invalid_result(fs, rounded);
2655 } 2804 }
2805 TraceRegWr(get_fpu_register_word(fd_reg()));
2656 } break; 2806 } break;
2657 case CVT_S_D: // Convert double to float (single). 2807 case CVT_S_D: // Convert double to float (single).
2658 set_fpu_register_float(fd_reg(), static_cast<float>(fs)); 2808 set_fpu_register_float(fd_reg(), static_cast<float>(fs));
2809 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
2659 break; 2810 break;
2660 case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word. 2811 case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word.
2661 if (IsFp64Mode()) { 2812 if (IsFp64Mode()) {
2662 int64_t result; 2813 int64_t result;
2663 double rounded; 2814 double rounded;
2664 round64_according_to_fcsr(fs, rounded, result, fs); 2815 round64_according_to_fcsr(fs, rounded, result, fs);
2665 set_fpu_register(fd_reg(), result); 2816 set_fpu_register(fd_reg(), result);
2666 if (set_fcsr_round64_error(fs, rounded)) { 2817 if (set_fcsr_round64_error(fs, rounded)) {
2667 set_fpu_register_invalid_result64(fs, rounded); 2818 set_fpu_register_invalid_result64(fs, rounded);
2668 } 2819 }
2820 TraceRegWr(get_fpu_register(fd_reg()));
2669 } else { 2821 } else {
2670 UNSUPPORTED(); 2822 UNSUPPORTED();
2671 } 2823 }
2672 break; 2824 break;
2673 break; 2825 break;
2674 } 2826 }
2675 case TRUNC_L_D: { // Mips32r2 instruction. 2827 case TRUNC_L_D: { // Mips32r2 instruction.
2676 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2828 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
2677 double rounded = trunc(fs); 2829 double rounded = trunc(fs);
2678 i64 = static_cast<int64_t>(rounded); 2830 i64 = static_cast<int64_t>(rounded);
2679 if (IsFp64Mode()) { 2831 if (IsFp64Mode()) {
2680 set_fpu_register(fd_reg(), i64); 2832 set_fpu_register(fd_reg(), i64);
2681 if (set_fcsr_round64_error(fs, rounded)) { 2833 if (set_fcsr_round64_error(fs, rounded)) {
2682 set_fpu_register_invalid_result64(fs, rounded); 2834 set_fpu_register_invalid_result64(fs, rounded);
2683 } 2835 }
2836 TraceRegWr(get_fpu_register(fd_reg()));
2684 } else { 2837 } else {
2685 UNSUPPORTED(); 2838 UNSUPPORTED();
2686 } 2839 }
2687 break; 2840 break;
2688 } 2841 }
2689 case ROUND_L_D: { // Mips32r2 instruction. 2842 case ROUND_L_D: { // Mips32r2 instruction.
2690 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2843 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
2691 double rounded = std::floor(fs + 0.5); 2844 double rounded = std::floor(fs + 0.5);
2692 int64_t result = static_cast<int64_t>(rounded); 2845 int64_t result = static_cast<int64_t>(rounded);
2693 if ((result & 1) != 0 && result - fs == 0.5) { 2846 if ((result & 1) != 0 && result - fs == 0.5) {
2694 // If the number is halfway between two integers, 2847 // If the number is halfway between two integers,
2695 // round to the even one. 2848 // round to the even one.
2696 result--; 2849 result--;
2697 } 2850 }
2698 int64_t i64 = static_cast<int64_t>(result); 2851 int64_t i64 = static_cast<int64_t>(result);
2699 if (IsFp64Mode()) { 2852 if (IsFp64Mode()) {
2700 set_fpu_register(fd_reg(), i64); 2853 set_fpu_register(fd_reg(), i64);
2701 if (set_fcsr_round64_error(fs, rounded)) { 2854 if (set_fcsr_round64_error(fs, rounded)) {
2702 set_fpu_register_invalid_result64(fs, rounded); 2855 set_fpu_register_invalid_result64(fs, rounded);
2703 } 2856 }
2857 TraceRegWr(get_fpu_register(fd_reg()));
2704 } else { 2858 } else {
2705 UNSUPPORTED(); 2859 UNSUPPORTED();
2706 } 2860 }
2707 break; 2861 break;
2708 } 2862 }
2709 case FLOOR_L_D: { // Mips32r2 instruction. 2863 case FLOOR_L_D: { // Mips32r2 instruction.
2710 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2864 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
2711 double rounded = std::floor(fs); 2865 double rounded = std::floor(fs);
2712 int64_t i64 = static_cast<int64_t>(rounded); 2866 int64_t i64 = static_cast<int64_t>(rounded);
2713 if (IsFp64Mode()) { 2867 if (IsFp64Mode()) {
2714 set_fpu_register(fd_reg(), i64); 2868 set_fpu_register(fd_reg(), i64);
2715 if (set_fcsr_round64_error(fs, rounded)) { 2869 if (set_fcsr_round64_error(fs, rounded)) {
2716 set_fpu_register_invalid_result64(fs, rounded); 2870 set_fpu_register_invalid_result64(fs, rounded);
2717 } 2871 }
2872 TraceRegWr(get_fpu_register(fd_reg()));
2718 } else { 2873 } else {
2719 UNSUPPORTED(); 2874 UNSUPPORTED();
2720 } 2875 }
2721 break; 2876 break;
2722 } 2877 }
2723 case CEIL_L_D: { // Mips32r2 instruction. 2878 case CEIL_L_D: { // Mips32r2 instruction.
2724 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2879 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
2725 double rounded = std::ceil(fs); 2880 double rounded = std::ceil(fs);
2726 int64_t i64 = static_cast<int64_t>(rounded); 2881 int64_t i64 = static_cast<int64_t>(rounded);
2727 if (IsFp64Mode()) { 2882 if (IsFp64Mode()) {
2728 set_fpu_register(fd_reg(), i64); 2883 set_fpu_register(fd_reg(), i64);
2729 if (set_fcsr_round64_error(fs, rounded)) { 2884 if (set_fcsr_round64_error(fs, rounded)) {
2730 set_fpu_register_invalid_result64(fs, rounded); 2885 set_fpu_register_invalid_result64(fs, rounded);
2731 } 2886 }
2887 TraceRegWr(get_fpu_register(fd_reg()));
2732 } else { 2888 } else {
2733 UNSUPPORTED(); 2889 UNSUPPORTED();
2734 } 2890 }
2735 break; 2891 break;
2736 } 2892 }
2737 case CLASS_D: { // Mips32r6 instruction 2893 case CLASS_D: { // Mips32r6 instruction
2738 // Convert double input to uint64_t for easier bit manipulation 2894 // Convert double input to uint64_t for easier bit manipulation
2739 uint64_t classed = bit_cast<uint64_t>(fs); 2895 uint64_t classed = bit_cast<uint64_t>(fs);
2740 2896
2741 // Extracting sign, exponent and mantissa from the input double 2897 // Extracting sign, exponent and mantissa from the input double
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2789 2945
2790 // Calculating result according to description of CLASS.D instruction 2946 // Calculating result according to description of CLASS.D instruction
2791 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | 2947 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) |
2792 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | 2948 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) |
2793 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; 2949 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan;
2794 2950
2795 DCHECK(result != 0); 2951 DCHECK(result != 0);
2796 2952
2797 dResult = bit_cast<double>(result); 2953 dResult = bit_cast<double>(result);
2798 set_fpu_register_double(fd_reg(), dResult); 2954 set_fpu_register_double(fd_reg(), dResult);
2955 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2799 2956
2800 break; 2957 break;
2801 } 2958 }
2802 case C_F_D: { 2959 case C_F_D: {
2803 set_fcsr_bit(fcsr_cc, false); 2960 set_fcsr_bit(fcsr_cc, false);
2961 TraceRegWr(test_fcsr_bit(fcsr_cc));
2804 break; 2962 break;
2805 } 2963 }
2806 default: 2964 default:
2807 UNREACHABLE(); 2965 UNREACHABLE();
2808 } 2966 }
2809 } 2967 }
2810 2968
2811 2969
2812 void Simulator::DecodeTypeRegisterWRsType() { 2970 void Simulator::DecodeTypeRegisterWRsType() {
2813 float fs = get_fpu_register_float(fs_reg()); 2971 float fs = get_fpu_register_float(fs_reg());
2814 float ft = get_fpu_register_float(ft_reg()); 2972 float ft = get_fpu_register_float(ft_reg());
2815 int32_t alu_out = 0x12345678; 2973 int32_t alu_out = 0x12345678;
2816 switch (instr_.FunctionFieldRaw()) { 2974 switch (instr_.FunctionFieldRaw()) {
2817 case CVT_S_W: // Convert word to float (single). 2975 case CVT_S_W: // Convert word to float (single).
2818 alu_out = get_fpu_register_signed_word(fs_reg()); 2976 alu_out = get_fpu_register_signed_word(fs_reg());
2819 set_fpu_register_float(fd_reg(), static_cast<float>(alu_out)); 2977 set_fpu_register_float(fd_reg(), static_cast<float>(alu_out));
2978 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
2820 break; 2979 break;
2821 case CVT_D_W: // Convert word to double. 2980 case CVT_D_W: // Convert word to double.
2822 alu_out = get_fpu_register_signed_word(fs_reg()); 2981 alu_out = get_fpu_register_signed_word(fs_reg());
2823 set_fpu_register_double(fd_reg(), static_cast<double>(alu_out)); 2982 set_fpu_register_double(fd_reg(), static_cast<double>(alu_out));
2983 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
2824 break; 2984 break;
2825 case CMP_AF: 2985 case CMP_AF:
2826 set_fpu_register_word(fd_reg(), 0); 2986 set_fpu_register_word(fd_reg(), 0);
2987 TraceRegWr(get_fpu_register_word(fd_reg()));
2827 break; 2988 break;
2828 case CMP_UN: 2989 case CMP_UN:
2829 if (std::isnan(fs) || std::isnan(ft)) { 2990 if (std::isnan(fs) || std::isnan(ft)) {
2830 set_fpu_register_word(fd_reg(), -1); 2991 set_fpu_register_word(fd_reg(), -1);
2831 } else { 2992 } else {
2832 set_fpu_register_word(fd_reg(), 0); 2993 set_fpu_register_word(fd_reg(), 0);
2833 } 2994 }
2995 TraceRegWr(get_fpu_register_word(fd_reg()));
2834 break; 2996 break;
2835 case CMP_EQ: 2997 case CMP_EQ:
2836 if (fs == ft) { 2998 if (fs == ft) {
2837 set_fpu_register_word(fd_reg(), -1); 2999 set_fpu_register_word(fd_reg(), -1);
2838 } else { 3000 } else {
2839 set_fpu_register_word(fd_reg(), 0); 3001 set_fpu_register_word(fd_reg(), 0);
2840 } 3002 }
3003 TraceRegWr(get_fpu_register_word(fd_reg()));
2841 break; 3004 break;
2842 case CMP_UEQ: 3005 case CMP_UEQ:
2843 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { 3006 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) {
2844 set_fpu_register_word(fd_reg(), -1); 3007 set_fpu_register_word(fd_reg(), -1);
2845 } else { 3008 } else {
2846 set_fpu_register_word(fd_reg(), 0); 3009 set_fpu_register_word(fd_reg(), 0);
2847 } 3010 }
3011 TraceRegWr(get_fpu_register_word(fd_reg()));
2848 break; 3012 break;
2849 case CMP_LT: 3013 case CMP_LT:
2850 if (fs < ft) { 3014 if (fs < ft) {
2851 set_fpu_register_word(fd_reg(), -1); 3015 set_fpu_register_word(fd_reg(), -1);
2852 } else { 3016 } else {
2853 set_fpu_register_word(fd_reg(), 0); 3017 set_fpu_register_word(fd_reg(), 0);
2854 } 3018 }
3019 TraceRegWr(get_fpu_register_word(fd_reg()));
2855 break; 3020 break;
2856 case CMP_ULT: 3021 case CMP_ULT:
2857 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { 3022 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) {
2858 set_fpu_register_word(fd_reg(), -1); 3023 set_fpu_register_word(fd_reg(), -1);
2859 } else { 3024 } else {
2860 set_fpu_register_word(fd_reg(), 0); 3025 set_fpu_register_word(fd_reg(), 0);
2861 } 3026 }
3027 TraceRegWr(get_fpu_register_word(fd_reg()));
2862 break; 3028 break;
2863 case CMP_LE: 3029 case CMP_LE:
2864 if (fs <= ft) { 3030 if (fs <= ft) {
2865 set_fpu_register_word(fd_reg(), -1); 3031 set_fpu_register_word(fd_reg(), -1);
2866 } else { 3032 } else {
2867 set_fpu_register_word(fd_reg(), 0); 3033 set_fpu_register_word(fd_reg(), 0);
2868 } 3034 }
3035 TraceRegWr(get_fpu_register_word(fd_reg()));
2869 break; 3036 break;
2870 case CMP_ULE: 3037 case CMP_ULE:
2871 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { 3038 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) {
2872 set_fpu_register_word(fd_reg(), -1); 3039 set_fpu_register_word(fd_reg(), -1);
2873 } else { 3040 } else {
2874 set_fpu_register_word(fd_reg(), 0); 3041 set_fpu_register_word(fd_reg(), 0);
2875 } 3042 }
3043 TraceRegWr(get_fpu_register_word(fd_reg()));
2876 break; 3044 break;
2877 case CMP_OR: 3045 case CMP_OR:
2878 if (!std::isnan(fs) && !std::isnan(ft)) { 3046 if (!std::isnan(fs) && !std::isnan(ft)) {
2879 set_fpu_register_word(fd_reg(), -1); 3047 set_fpu_register_word(fd_reg(), -1);
2880 } else { 3048 } else {
2881 set_fpu_register_word(fd_reg(), 0); 3049 set_fpu_register_word(fd_reg(), 0);
2882 } 3050 }
3051 TraceRegWr(get_fpu_register_word(fd_reg()));
2883 break; 3052 break;
2884 case CMP_UNE: 3053 case CMP_UNE:
2885 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { 3054 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) {
2886 set_fpu_register_word(fd_reg(), -1); 3055 set_fpu_register_word(fd_reg(), -1);
2887 } else { 3056 } else {
2888 set_fpu_register_word(fd_reg(), 0); 3057 set_fpu_register_word(fd_reg(), 0);
2889 } 3058 }
3059 TraceRegWr(get_fpu_register_word(fd_reg()));
2890 break; 3060 break;
2891 case CMP_NE: 3061 case CMP_NE:
2892 if (fs != ft) { 3062 if (fs != ft) {
2893 set_fpu_register_word(fd_reg(), -1); 3063 set_fpu_register_word(fd_reg(), -1);
2894 } else { 3064 } else {
2895 set_fpu_register_word(fd_reg(), 0); 3065 set_fpu_register_word(fd_reg(), 0);
2896 } 3066 }
3067 TraceRegWr(get_fpu_register_word(fd_reg()));
2897 break; 3068 break;
2898 default: 3069 default:
2899 UNREACHABLE(); 3070 UNREACHABLE();
2900 } 3071 }
2901 } 3072 }
2902 3073
2903 3074
2904 void Simulator::DecodeTypeRegisterSRsType() { 3075 void Simulator::DecodeTypeRegisterSRsType() {
2905 float fs, ft, fd; 3076 float fs, ft, fd;
2906 fs = get_fpu_register_float(fs_reg()); 3077 fs = get_fpu_register_float(fs_reg());
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2941 result = upper; 3112 result = upper;
2942 break; 3113 break;
2943 case kRoundToMinusInf: 3114 case kRoundToMinusInf:
2944 result = lower; 3115 result = lower;
2945 break; 3116 break;
2946 } 3117 }
2947 set_fpu_register_float(fd_reg(), result); 3118 set_fpu_register_float(fd_reg(), result);
2948 if (result != fs) { 3119 if (result != fs) {
2949 set_fcsr_bit(kFCSRInexactFlagBit, true); 3120 set_fcsr_bit(kFCSRInexactFlagBit, true);
2950 } 3121 }
3122 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
2951 break; 3123 break;
2952 } 3124 }
2953 case ADD_S: 3125 case ADD_S:
2954 set_fpu_register_float( 3126 set_fpu_register_float(
2955 fd_reg(), 3127 fd_reg(),
2956 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs + rhs; }, 3128 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs + rhs; },
2957 fs, ft)); 3129 fs, ft));
3130 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
2958 break; 3131 break;
2959 case SUB_S: 3132 case SUB_S:
2960 set_fpu_register_float( 3133 set_fpu_register_float(
2961 fd_reg(), 3134 fd_reg(),
2962 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs - rhs; }, 3135 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs - rhs; },
2963 fs, ft)); 3136 fs, ft));
3137 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
2964 break; 3138 break;
2965 case MADDF_S: 3139 case MADDF_S:
2966 DCHECK(IsMipsArchVariant(kMips32r6)); 3140 DCHECK(IsMipsArchVariant(kMips32r6));
2967 set_fpu_register_float(fd_reg(), std::fma(fs, ft, fd)); 3141 set_fpu_register_float(fd_reg(), std::fma(fs, ft, fd));
3142 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
2968 break; 3143 break;
2969 case MSUBF_S: 3144 case MSUBF_S:
2970 DCHECK(IsMipsArchVariant(kMips32r6)); 3145 DCHECK(IsMipsArchVariant(kMips32r6));
2971 set_fpu_register_float(fd_reg(), std::fma(-fs, ft, fd)); 3146 set_fpu_register_float(fd_reg(), std::fma(-fs, ft, fd));
3147 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
2972 break; 3148 break;
2973 case MUL_S: 3149 case MUL_S:
2974 set_fpu_register_float( 3150 set_fpu_register_float(
2975 fd_reg(), 3151 fd_reg(),
2976 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs * rhs; }, 3152 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs * rhs; },
2977 fs, ft)); 3153 fs, ft));
3154 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
2978 break; 3155 break;
2979 case DIV_S: 3156 case DIV_S:
2980 set_fpu_register_float( 3157 set_fpu_register_float(
2981 fd_reg(), 3158 fd_reg(),
2982 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs / rhs; }, 3159 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs / rhs; },
2983 fs, ft)); 3160 fs, ft));
3161 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
2984 break; 3162 break;
2985 case ABS_S: 3163 case ABS_S:
2986 set_fpu_register_float( 3164 set_fpu_register_float(
2987 fd_reg(), 3165 fd_reg(),
2988 FPUCanonalizeOperation([](float fs) { return FPAbs(fs); }, fs)); 3166 FPUCanonalizeOperation([](float fs) { return FPAbs(fs); }, fs));
3167 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
2989 break; 3168 break;
2990 case MOV_S: 3169 case MOV_S:
2991 set_fpu_register_float(fd_reg(), fs); 3170 set_fpu_register_float(fd_reg(), fs);
3171 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
2992 break; 3172 break;
2993 case NEG_S: 3173 case NEG_S:
2994 set_fpu_register_float( 3174 set_fpu_register_float(
2995 fd_reg(), FPUCanonalizeOperation([](float src) { return -src; }, 3175 fd_reg(), FPUCanonalizeOperation([](float src) { return -src; },
2996 KeepSign::yes, fs)); 3176 KeepSign::yes, fs));
3177 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
2997 break; 3178 break;
2998 case SQRT_S: 3179 case SQRT_S:
2999 set_fpu_register_float( 3180 set_fpu_register_float(
3000 fd_reg(), 3181 fd_reg(),
3001 FPUCanonalizeOperation([](float src) { return std::sqrt(src); }, fs)); 3182 FPUCanonalizeOperation([](float src) { return std::sqrt(src); }, fs));
3183 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3002 break; 3184 break;
3003 case RSQRT_S: 3185 case RSQRT_S:
3004 set_fpu_register_float( 3186 set_fpu_register_float(
3005 fd_reg(), FPUCanonalizeOperation( 3187 fd_reg(), FPUCanonalizeOperation(
3006 [](float src) { return 1.0 / std::sqrt(src); }, fs)); 3188 [](float src) { return 1.0 / std::sqrt(src); }, fs));
3189 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3007 break; 3190 break;
3008 case RECIP_S: 3191 case RECIP_S:
3009 set_fpu_register_float( 3192 set_fpu_register_float(
3010 fd_reg(), 3193 fd_reg(),
3011 FPUCanonalizeOperation([](float src) { return 1.0 / src; }, fs)); 3194 FPUCanonalizeOperation([](float src) { return 1.0 / src; }, fs));
3195 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3012 break; 3196 break;
3013 case C_F_D: 3197 case C_F_D:
3014 set_fcsr_bit(fcsr_cc, false); 3198 set_fcsr_bit(fcsr_cc, false);
3199 TraceRegWr(test_fcsr_bit(fcsr_cc));
3015 break; 3200 break;
3016 case C_UN_D: 3201 case C_UN_D:
3017 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); 3202 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
3203 TraceRegWr(test_fcsr_bit(fcsr_cc));
3018 break; 3204 break;
3019 case C_EQ_D: 3205 case C_EQ_D:
3020 set_fcsr_bit(fcsr_cc, (fs == ft)); 3206 set_fcsr_bit(fcsr_cc, (fs == ft));
3207 TraceRegWr(test_fcsr_bit(fcsr_cc));
3021 break; 3208 break;
3022 case C_UEQ_D: 3209 case C_UEQ_D:
3023 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); 3210 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft)));
3211 TraceRegWr(test_fcsr_bit(fcsr_cc));
3024 break; 3212 break;
3025 case C_OLT_D: 3213 case C_OLT_D:
3026 set_fcsr_bit(fcsr_cc, (fs < ft)); 3214 set_fcsr_bit(fcsr_cc, (fs < ft));
3215 TraceRegWr(test_fcsr_bit(fcsr_cc));
3027 break; 3216 break;
3028 case C_ULT_D: 3217 case C_ULT_D:
3029 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); 3218 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft)));
3219 TraceRegWr(test_fcsr_bit(fcsr_cc));
3030 break; 3220 break;
3031 case C_OLE_D: 3221 case C_OLE_D:
3032 set_fcsr_bit(fcsr_cc, (fs <= ft)); 3222 set_fcsr_bit(fcsr_cc, (fs <= ft));
3223 TraceRegWr(test_fcsr_bit(fcsr_cc));
3033 break; 3224 break;
3034 case C_ULE_D: 3225 case C_ULE_D:
3035 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); 3226 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft)));
3227 TraceRegWr(test_fcsr_bit(fcsr_cc));
3036 break; 3228 break;
3037 case CVT_D_S: 3229 case CVT_D_S:
3038 set_fpu_register_double(fd_reg(), static_cast<double>(fs)); 3230 set_fpu_register_double(fd_reg(), static_cast<double>(fs));
3231 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
3039 break; 3232 break;
3040 case SEL: 3233 case SEL:
3041 DCHECK(IsMipsArchVariant(kMips32r6)); 3234 DCHECK(IsMipsArchVariant(kMips32r6));
3042 set_fpu_register_float(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); 3235 set_fpu_register_float(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft);
3236 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3043 break; 3237 break;
3044 case CLASS_S: { // Mips32r6 instruction 3238 case CLASS_S: { // Mips32r6 instruction
3045 // Convert float input to uint32_t for easier bit manipulation 3239 // Convert float input to uint32_t for easier bit manipulation
3046 float fs = get_fpu_register_float(fs_reg()); 3240 float fs = get_fpu_register_float(fs_reg());
3047 uint32_t classed = bit_cast<uint32_t>(fs); 3241 uint32_t classed = bit_cast<uint32_t>(fs);
3048 3242
3049 // Extracting sign, exponent and mantissa from the input float 3243 // Extracting sign, exponent and mantissa from the input float
3050 uint32_t sign = (classed >> 31) & 1; 3244 uint32_t sign = (classed >> 31) & 1;
3051 uint32_t exponent = (classed >> 23) & 0x000000ff; 3245 uint32_t exponent = (classed >> 23) & 0x000000ff;
3052 uint32_t mantissa = classed & 0x007fffff; 3246 uint32_t mantissa = classed & 0x007fffff;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3097 3291
3098 // Calculating result according to description of CLASS.S instruction 3292 // Calculating result according to description of CLASS.S instruction
3099 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | 3293 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) |
3100 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | 3294 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) |
3101 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; 3295 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan;
3102 3296
3103 DCHECK(result != 0); 3297 DCHECK(result != 0);
3104 3298
3105 fResult = bit_cast<float>(result); 3299 fResult = bit_cast<float>(result);
3106 set_fpu_register_float(fd_reg(), fResult); 3300 set_fpu_register_float(fd_reg(), fResult);
3301 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3107 3302
3108 break; 3303 break;
3109 } 3304 }
3110 case SELEQZ_C: 3305 case SELEQZ_C:
3111 DCHECK(IsMipsArchVariant(kMips32r6)); 3306 DCHECK(IsMipsArchVariant(kMips32r6));
3112 set_fpu_register_float(fd_reg(), (ft_int & 0x1) == 0 3307 set_fpu_register_float(fd_reg(), (ft_int & 0x1) == 0
3113 ? get_fpu_register_float(fs_reg()) 3308 ? get_fpu_register_float(fs_reg())
3114 : 0.0); 3309 : 0.0);
3310 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3115 break; 3311 break;
3116 case SELNEZ_C: 3312 case SELNEZ_C:
3117 DCHECK(IsMipsArchVariant(kMips32r6)); 3313 DCHECK(IsMipsArchVariant(kMips32r6));
3118 set_fpu_register_float(fd_reg(), (ft_int & 0x1) != 0 3314 set_fpu_register_float(fd_reg(), (ft_int & 0x1) != 0
3119 ? get_fpu_register_float(fs_reg()) 3315 ? get_fpu_register_float(fs_reg())
3120 : 0.0); 3316 : 0.0);
3317 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3121 break; 3318 break;
3122 case MOVZ_C: { 3319 case MOVZ_C: {
3123 DCHECK(IsMipsArchVariant(kMips32r2)); 3320 DCHECK(IsMipsArchVariant(kMips32r2));
3124 if (rt() == 0) { 3321 if (rt() == 0) {
3125 set_fpu_register_float(fd_reg(), fs); 3322 set_fpu_register_float(fd_reg(), fs);
3126 } 3323 }
3324 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3127 break; 3325 break;
3128 } 3326 }
3129 case MOVN_C: { 3327 case MOVN_C: {
3130 DCHECK(IsMipsArchVariant(kMips32r2)); 3328 DCHECK(IsMipsArchVariant(kMips32r2));
3131 if (rt() != 0) { 3329 if (rt() != 0) {
3132 set_fpu_register_float(fd_reg(), fs); 3330 set_fpu_register_float(fd_reg(), fs);
3133 } 3331 }
3332 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3134 break; 3333 break;
3135 } 3334 }
3136 case MOVF: { 3335 case MOVF: {
3137 // Same function field for MOVT.D and MOVF.D 3336 // Same function field for MOVT.D and MOVF.D
3138 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; 3337 uint32_t ft_cc = (ft_reg() >> 2) & 0x7;
3139 ft_cc = get_fcsr_condition_bit(ft_cc); 3338 ft_cc = get_fcsr_condition_bit(ft_cc);
3140 3339
3141 if (instr_.Bit(16)) { // Read Tf bit. 3340 if (instr_.Bit(16)) { // Read Tf bit.
3142 // MOVT.D 3341 // MOVT.D
3143 if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); 3342 if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs);
3144 } else { 3343 } else {
3145 // MOVF.D 3344 // MOVF.D
3146 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); 3345 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs);
3147 } 3346 }
3347 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3148 break; 3348 break;
3149 } 3349 }
3150 case TRUNC_W_S: { // Truncate single to word (round towards 0). 3350 case TRUNC_W_S: { // Truncate single to word (round towards 0).
3151 float rounded = trunc(fs); 3351 float rounded = trunc(fs);
3152 int32_t result = static_cast<int32_t>(rounded); 3352 int32_t result = static_cast<int32_t>(rounded);
3153 set_fpu_register_word(fd_reg(), result); 3353 set_fpu_register_word(fd_reg(), result);
3154 if (set_fcsr_round_error(fs, rounded)) { 3354 if (set_fcsr_round_error(fs, rounded)) {
3155 set_fpu_register_word_invalid_result(fs, rounded); 3355 set_fpu_register_word_invalid_result(fs, rounded);
3156 } 3356 }
3357 TraceRegWr(get_fpu_register_word(fd_reg()));
3157 } break; 3358 } break;
3158 case TRUNC_L_S: { // Mips32r2 instruction. 3359 case TRUNC_L_S: { // Mips32r2 instruction.
3159 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 3360 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
3160 float rounded = trunc(fs); 3361 float rounded = trunc(fs);
3161 int64_t i64 = static_cast<int64_t>(rounded); 3362 int64_t i64 = static_cast<int64_t>(rounded);
3162 if (IsFp64Mode()) { 3363 if (IsFp64Mode()) {
3163 set_fpu_register(fd_reg(), i64); 3364 set_fpu_register(fd_reg(), i64);
3164 if (set_fcsr_round64_error(fs, rounded)) { 3365 if (set_fcsr_round64_error(fs, rounded)) {
3165 set_fpu_register_invalid_result64(fs, rounded); 3366 set_fpu_register_invalid_result64(fs, rounded);
3166 } 3367 }
3368 TraceRegWr(get_fpu_register(fd_reg()));
3167 } else { 3369 } else {
3168 UNSUPPORTED(); 3370 UNSUPPORTED();
3169 } 3371 }
3170 break; 3372 break;
3171 } 3373 }
3172 case FLOOR_W_S: // Round double to word towards negative infinity. 3374 case FLOOR_W_S: // Round double to word towards negative infinity.
3173 { 3375 {
3174 float rounded = std::floor(fs); 3376 float rounded = std::floor(fs);
3175 int32_t result = static_cast<int32_t>(rounded); 3377 int32_t result = static_cast<int32_t>(rounded);
3176 set_fpu_register_word(fd_reg(), result); 3378 set_fpu_register_word(fd_reg(), result);
3177 if (set_fcsr_round_error(fs, rounded)) { 3379 if (set_fcsr_round_error(fs, rounded)) {
3178 set_fpu_register_word_invalid_result(fs, rounded); 3380 set_fpu_register_word_invalid_result(fs, rounded);
3179 } 3381 }
3382 TraceRegWr(get_fpu_register_word(fd_reg()));
3180 } break; 3383 } break;
3181 case FLOOR_L_S: { // Mips32r2 instruction. 3384 case FLOOR_L_S: { // Mips32r2 instruction.
3182 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 3385 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
3183 float rounded = std::floor(fs); 3386 float rounded = std::floor(fs);
3184 int64_t i64 = static_cast<int64_t>(rounded); 3387 int64_t i64 = static_cast<int64_t>(rounded);
3185 if (IsFp64Mode()) { 3388 if (IsFp64Mode()) {
3186 set_fpu_register(fd_reg(), i64); 3389 set_fpu_register(fd_reg(), i64);
3187 if (set_fcsr_round64_error(fs, rounded)) { 3390 if (set_fcsr_round64_error(fs, rounded)) {
3188 set_fpu_register_invalid_result64(fs, rounded); 3391 set_fpu_register_invalid_result64(fs, rounded);
3189 } 3392 }
3393 TraceRegWr(get_fpu_register(fd_reg()));
3190 } else { 3394 } else {
3191 UNSUPPORTED(); 3395 UNSUPPORTED();
3192 } 3396 }
3193 break; 3397 break;
3194 } 3398 }
3195 case ROUND_W_S: { 3399 case ROUND_W_S: {
3196 float rounded = std::floor(fs + 0.5); 3400 float rounded = std::floor(fs + 0.5);
3197 int32_t result = static_cast<int32_t>(rounded); 3401 int32_t result = static_cast<int32_t>(rounded);
3198 if ((result & 1) != 0 && result - fs == 0.5) { 3402 if ((result & 1) != 0 && result - fs == 0.5) {
3199 // If the number is halfway between two integers, 3403 // If the number is halfway between two integers,
3200 // round to the even one. 3404 // round to the even one.
3201 result--; 3405 result--;
3202 } 3406 }
3203 set_fpu_register_word(fd_reg(), result); 3407 set_fpu_register_word(fd_reg(), result);
3204 if (set_fcsr_round_error(fs, rounded)) { 3408 if (set_fcsr_round_error(fs, rounded)) {
3205 set_fpu_register_word_invalid_result(fs, rounded); 3409 set_fpu_register_word_invalid_result(fs, rounded);
3206 } 3410 }
3411 TraceRegWr(get_fpu_register_word(fd_reg()));
3207 break; 3412 break;
3208 } 3413 }
3209 case ROUND_L_S: { // Mips32r2 instruction. 3414 case ROUND_L_S: { // Mips32r2 instruction.
3210 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 3415 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
3211 float rounded = std::floor(fs + 0.5); 3416 float rounded = std::floor(fs + 0.5);
3212 int64_t result = static_cast<int64_t>(rounded); 3417 int64_t result = static_cast<int64_t>(rounded);
3213 if ((result & 1) != 0 && result - fs == 0.5) { 3418 if ((result & 1) != 0 && result - fs == 0.5) {
3214 // If the number is halfway between two integers, 3419 // If the number is halfway between two integers,
3215 // round to the even one. 3420 // round to the even one.
3216 result--; 3421 result--;
3217 } 3422 }
3218 int64_t i64 = static_cast<int64_t>(result); 3423 int64_t i64 = static_cast<int64_t>(result);
3219 if (IsFp64Mode()) { 3424 if (IsFp64Mode()) {
3220 set_fpu_register(fd_reg(), i64); 3425 set_fpu_register(fd_reg(), i64);
3221 if (set_fcsr_round64_error(fs, rounded)) { 3426 if (set_fcsr_round64_error(fs, rounded)) {
3222 set_fpu_register_invalid_result64(fs, rounded); 3427 set_fpu_register_invalid_result64(fs, rounded);
3223 } 3428 }
3429 TraceRegWr(get_fpu_register(fd_reg()));
3224 } else { 3430 } else {
3225 UNSUPPORTED(); 3431 UNSUPPORTED();
3226 } 3432 }
3227 break; 3433 break;
3228 } 3434 }
3229 case CEIL_W_S: // Round double to word towards positive infinity. 3435 case CEIL_W_S: // Round double to word towards positive infinity.
3230 { 3436 {
3231 float rounded = std::ceil(fs); 3437 float rounded = std::ceil(fs);
3232 int32_t result = static_cast<int32_t>(rounded); 3438 int32_t result = static_cast<int32_t>(rounded);
3233 set_fpu_register_word(fd_reg(), result); 3439 set_fpu_register_word(fd_reg(), result);
3234 if (set_fcsr_round_error(fs, rounded)) { 3440 if (set_fcsr_round_error(fs, rounded)) {
3235 set_fpu_register_word_invalid_result(fs, rounded); 3441 set_fpu_register_word_invalid_result(fs, rounded);
3236 } 3442 }
3443 TraceRegWr(get_fpu_register_word(fd_reg()));
3237 } break; 3444 } break;
3238 case CEIL_L_S: { // Mips32r2 instruction. 3445 case CEIL_L_S: { // Mips32r2 instruction.
3239 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 3446 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
3240 float rounded = std::ceil(fs); 3447 float rounded = std::ceil(fs);
3241 int64_t i64 = static_cast<int64_t>(rounded); 3448 int64_t i64 = static_cast<int64_t>(rounded);
3242 if (IsFp64Mode()) { 3449 if (IsFp64Mode()) {
3243 set_fpu_register(fd_reg(), i64); 3450 set_fpu_register(fd_reg(), i64);
3244 if (set_fcsr_round64_error(fs, rounded)) { 3451 if (set_fcsr_round64_error(fs, rounded)) {
3245 set_fpu_register_invalid_result64(fs, rounded); 3452 set_fpu_register_invalid_result64(fs, rounded);
3246 } 3453 }
3454 TraceRegWr(get_fpu_register(fd_reg()));
3247 } else { 3455 } else {
3248 UNSUPPORTED(); 3456 UNSUPPORTED();
3249 } 3457 }
3250 break; 3458 break;
3251 } 3459 }
3252 case MIN: 3460 case MIN:
3253 DCHECK(IsMipsArchVariant(kMips32r6)); 3461 DCHECK(IsMipsArchVariant(kMips32r6));
3254 set_fpu_register_float(fd_reg(), FPUMin(ft, fs)); 3462 set_fpu_register_float(fd_reg(), FPUMin(ft, fs));
3463 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3255 break; 3464 break;
3256 case MAX: 3465 case MAX:
3257 DCHECK(IsMipsArchVariant(kMips32r6)); 3466 DCHECK(IsMipsArchVariant(kMips32r6));
3258 set_fpu_register_float(fd_reg(), FPUMax(ft, fs)); 3467 set_fpu_register_float(fd_reg(), FPUMax(ft, fs));
3468 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3259 break; 3469 break;
3260 case MINA: 3470 case MINA:
3261 DCHECK(IsMipsArchVariant(kMips32r6)); 3471 DCHECK(IsMipsArchVariant(kMips32r6));
3262 set_fpu_register_float(fd_reg(), FPUMinA(ft, fs)); 3472 set_fpu_register_float(fd_reg(), FPUMinA(ft, fs));
3473 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3263 break; 3474 break;
3264 case MAXA: 3475 case MAXA:
3265 DCHECK(IsMipsArchVariant(kMips32r6)); 3476 DCHECK(IsMipsArchVariant(kMips32r6));
3266 set_fpu_register_float(fd_reg(), FPUMaxA(ft, fs)); 3477 set_fpu_register_float(fd_reg(), FPUMaxA(ft, fs));
3478 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3267 break; 3479 break;
3268 case CVT_L_S: { 3480 case CVT_L_S: {
3269 if (IsFp64Mode()) { 3481 if (IsFp64Mode()) {
3270 int64_t result; 3482 int64_t result;
3271 float rounded; 3483 float rounded;
3272 round64_according_to_fcsr(fs, rounded, result, fs); 3484 round64_according_to_fcsr(fs, rounded, result, fs);
3273 set_fpu_register(fd_reg(), result); 3485 set_fpu_register(fd_reg(), result);
3274 if (set_fcsr_round64_error(fs, rounded)) { 3486 if (set_fcsr_round64_error(fs, rounded)) {
3275 set_fpu_register_invalid_result64(fs, rounded); 3487 set_fpu_register_invalid_result64(fs, rounded);
3276 } 3488 }
3489 TraceRegWr(get_fpu_register(fd_reg()));
3277 } else { 3490 } else {
3278 UNSUPPORTED(); 3491 UNSUPPORTED();
3279 } 3492 }
3280 break; 3493 break;
3281 } 3494 }
3282 case CVT_W_S: { 3495 case CVT_W_S: {
3283 float rounded; 3496 float rounded;
3284 int32_t result; 3497 int32_t result;
3285 round_according_to_fcsr(fs, rounded, result, fs); 3498 round_according_to_fcsr(fs, rounded, result, fs);
3286 set_fpu_register_word(fd_reg(), result); 3499 set_fpu_register_word(fd_reg(), result);
3287 if (set_fcsr_round_error(fs, rounded)) { 3500 if (set_fcsr_round_error(fs, rounded)) {
3288 set_fpu_register_word_invalid_result(fs, rounded); 3501 set_fpu_register_word_invalid_result(fs, rounded);
3289 } 3502 }
3503 TraceRegWr(get_fpu_register_word(fd_reg()));
3290 break; 3504 break;
3291 } 3505 }
3292 default: 3506 default:
3293 // CVT_W_S CVT_L_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S 3507 // 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. 3508 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented.
3295 UNREACHABLE(); 3509 UNREACHABLE();
3296 } 3510 }
3297 } 3511 }
3298 3512
3299 3513
3300 void Simulator::DecodeTypeRegisterLRsType() { 3514 void Simulator::DecodeTypeRegisterLRsType() {
3301 double fs = get_fpu_register_double(fs_reg()); 3515 double fs = get_fpu_register_double(fs_reg());
3302 double ft = get_fpu_register_double(ft_reg()); 3516 double ft = get_fpu_register_double(ft_reg());
3303 switch (instr_.FunctionFieldRaw()) { 3517 switch (instr_.FunctionFieldRaw()) {
3304 case CVT_D_L: // Mips32r2 instruction. 3518 case CVT_D_L: // Mips32r2 instruction.
3305 // Watch the signs here, we want 2 32-bit vals 3519 // Watch the signs here, we want 2 32-bit vals
3306 // to make a sign-64. 3520 // to make a sign-64.
3307 int64_t i64; 3521 int64_t i64;
3308 if (IsFp64Mode()) { 3522 if (IsFp64Mode()) {
3309 i64 = get_fpu_register(fs_reg()); 3523 i64 = get_fpu_register(fs_reg());
3310 } else { 3524 } else {
3311 i64 = static_cast<uint32_t>(get_fpu_register_word(fs_reg())); 3525 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; 3526 i64 |= static_cast<int64_t>(get_fpu_register_word(fs_reg() + 1)) << 32;
3313 } 3527 }
3314 set_fpu_register_double(fd_reg(), static_cast<double>(i64)); 3528 set_fpu_register_double(fd_reg(), static_cast<double>(i64));
3529 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
3315 break; 3530 break;
3316 case CVT_S_L: 3531 case CVT_S_L:
3317 if (IsFp64Mode()) { 3532 if (IsFp64Mode()) {
3318 i64 = get_fpu_register(fs_reg()); 3533 i64 = get_fpu_register(fs_reg());
3319 } else { 3534 } else {
3320 i64 = static_cast<uint32_t>(get_fpu_register_word(fs_reg())); 3535 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; 3536 i64 |= static_cast<int64_t>(get_fpu_register_word(fs_reg() + 1)) << 32;
3322 } 3537 }
3323 set_fpu_register_float(fd_reg(), static_cast<float>(i64)); 3538 set_fpu_register_float(fd_reg(), static_cast<float>(i64));
3539 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3324 break; 3540 break;
3325 case CMP_AF: // Mips64r6 CMP.D instructions. 3541 case CMP_AF: // Mips64r6 CMP.D instructions.
3326 set_fpu_register(fd_reg(), 0); 3542 set_fpu_register(fd_reg(), 0);
3543 TraceRegWr(get_fpu_register(fd_reg()));
3327 break; 3544 break;
3328 case CMP_UN: 3545 case CMP_UN:
3329 if (std::isnan(fs) || std::isnan(ft)) { 3546 if (std::isnan(fs) || std::isnan(ft)) {
3330 set_fpu_register(fd_reg(), -1); 3547 set_fpu_register(fd_reg(), -1);
3331 } else { 3548 } else {
3332 set_fpu_register(fd_reg(), 0); 3549 set_fpu_register(fd_reg(), 0);
3333 } 3550 }
3551 TraceRegWr(get_fpu_register(fd_reg()));
3334 break; 3552 break;
3335 case CMP_EQ: 3553 case CMP_EQ:
3336 if (fs == ft) { 3554 if (fs == ft) {
3337 set_fpu_register(fd_reg(), -1); 3555 set_fpu_register(fd_reg(), -1);
3338 } else { 3556 } else {
3339 set_fpu_register(fd_reg(), 0); 3557 set_fpu_register(fd_reg(), 0);
3340 } 3558 }
3559 TraceRegWr(get_fpu_register(fd_reg()));
3341 break; 3560 break;
3342 case CMP_UEQ: 3561 case CMP_UEQ:
3343 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { 3562 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) {
3344 set_fpu_register(fd_reg(), -1); 3563 set_fpu_register(fd_reg(), -1);
3345 } else { 3564 } else {
3346 set_fpu_register(fd_reg(), 0); 3565 set_fpu_register(fd_reg(), 0);
3347 } 3566 }
3567 TraceRegWr(get_fpu_register(fd_reg()));
3348 break; 3568 break;
3349 case CMP_LT: 3569 case CMP_LT:
3350 if (fs < ft) { 3570 if (fs < ft) {
3351 set_fpu_register(fd_reg(), -1); 3571 set_fpu_register(fd_reg(), -1);
3352 } else { 3572 } else {
3353 set_fpu_register(fd_reg(), 0); 3573 set_fpu_register(fd_reg(), 0);
3354 } 3574 }
3575 TraceRegWr(get_fpu_register(fd_reg()));
3355 break; 3576 break;
3356 case CMP_ULT: 3577 case CMP_ULT:
3357 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { 3578 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) {
3358 set_fpu_register(fd_reg(), -1); 3579 set_fpu_register(fd_reg(), -1);
3359 } else { 3580 } else {
3360 set_fpu_register(fd_reg(), 0); 3581 set_fpu_register(fd_reg(), 0);
3361 } 3582 }
3583 TraceRegWr(get_fpu_register(fd_reg()));
3362 break; 3584 break;
3363 case CMP_LE: 3585 case CMP_LE:
3364 if (fs <= ft) { 3586 if (fs <= ft) {
3365 set_fpu_register(fd_reg(), -1); 3587 set_fpu_register(fd_reg(), -1);
3366 } else { 3588 } else {
3367 set_fpu_register(fd_reg(), 0); 3589 set_fpu_register(fd_reg(), 0);
3368 } 3590 }
3591 TraceRegWr(get_fpu_register(fd_reg()));
3369 break; 3592 break;
3370 case CMP_ULE: 3593 case CMP_ULE:
3371 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { 3594 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) {
3372 set_fpu_register(fd_reg(), -1); 3595 set_fpu_register(fd_reg(), -1);
3373 } else { 3596 } else {
3374 set_fpu_register(fd_reg(), 0); 3597 set_fpu_register(fd_reg(), 0);
3375 } 3598 }
3599 TraceRegWr(get_fpu_register(fd_reg()));
3376 break; 3600 break;
3377 case CMP_OR: 3601 case CMP_OR:
3378 if (!std::isnan(fs) && !std::isnan(ft)) { 3602 if (!std::isnan(fs) && !std::isnan(ft)) {
3379 set_fpu_register(fd_reg(), -1); 3603 set_fpu_register(fd_reg(), -1);
3380 } else { 3604 } else {
3381 set_fpu_register(fd_reg(), 0); 3605 set_fpu_register(fd_reg(), 0);
3382 } 3606 }
3607 TraceRegWr(get_fpu_register(fd_reg()));
3383 break; 3608 break;
3384 case CMP_UNE: 3609 case CMP_UNE:
3385 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { 3610 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) {
3386 set_fpu_register(fd_reg(), -1); 3611 set_fpu_register(fd_reg(), -1);
3387 } else { 3612 } else {
3388 set_fpu_register(fd_reg(), 0); 3613 set_fpu_register(fd_reg(), 0);
3389 } 3614 }
3615 TraceRegWr(get_fpu_register(fd_reg()));
3390 break; 3616 break;
3391 case CMP_NE: 3617 case CMP_NE:
3392 if (fs != ft && (!std::isnan(fs) && !std::isnan(ft))) { 3618 if (fs != ft && (!std::isnan(fs) && !std::isnan(ft))) {
3393 set_fpu_register(fd_reg(), -1); 3619 set_fpu_register(fd_reg(), -1);
3394 } else { 3620 } else {
3395 set_fpu_register(fd_reg(), 0); 3621 set_fpu_register(fd_reg(), 0);
3396 } 3622 }
3623 TraceRegWr(get_fpu_register(fd_reg()));
3397 break; 3624 break;
3398 default: 3625 default:
3399 UNREACHABLE(); 3626 UNREACHABLE();
3400 } 3627 }
3401 } 3628 }
3402 3629
3403 3630
3404 void Simulator::DecodeTypeRegisterCOP1() { 3631 void Simulator::DecodeTypeRegisterCOP1() {
3405 switch (instr_.RsFieldRaw()) { 3632 switch (instr_.RsFieldRaw()) {
3406 case CFC1: 3633 case CFC1:
3407 // At the moment only FCSR is supported. 3634 // At the moment only FCSR is supported.
3408 DCHECK(fs_reg() == kFCSRRegister); 3635 DCHECK(fs_reg() == kFCSRRegister);
3409 set_register(rt_reg(), FCSR_); 3636 set_register(rt_reg(), FCSR_);
3637 TraceRegWr(get_register(rt_reg()));
3410 break; 3638 break;
3411 case MFC1: 3639 case MFC1:
3412 set_register(rt_reg(), get_fpu_register_word(fs_reg())); 3640 set_register(rt_reg(), get_fpu_register_word(fs_reg()));
3641 TraceRegWr(get_register(rt_reg()));
3413 break; 3642 break;
3414 case MFHC1: 3643 case MFHC1:
3415 if (IsFp64Mode()) { 3644 if (IsFp64Mode()) {
3416 set_register(rt_reg(), get_fpu_register_hi_word(fs_reg())); 3645 set_register(rt_reg(), get_fpu_register_hi_word(fs_reg()));
3417 } else { 3646 } else {
3418 set_register(rt_reg(), get_fpu_register_word(fs_reg() + 1)); 3647 set_register(rt_reg(), get_fpu_register_word(fs_reg() + 1));
3419 } 3648 }
3649 TraceRegWr(get_register(rt_reg()));
3420 break; 3650 break;
3421 case CTC1: { 3651 case CTC1: {
3422 // At the moment only FCSR is supported. 3652 // At the moment only FCSR is supported.
3423 DCHECK(fs_reg() == kFCSRRegister); 3653 DCHECK(fs_reg() == kFCSRRegister);
3424 int32_t reg = registers_[rt_reg()]; 3654 int32_t reg = registers_[rt_reg()];
3425 if (IsMipsArchVariant(kMips32r6)) { 3655 if (IsMipsArchVariant(kMips32r6)) {
3426 FCSR_ = reg | kFCSRNaN2008FlagMask; 3656 FCSR_ = reg | kFCSRNaN2008FlagMask;
3427 } else { 3657 } else {
3428 DCHECK(IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kMips32r2)); 3658 DCHECK(IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kMips32r2));
3429 FCSR_ = reg & ~kFCSRNaN2008FlagMask; 3659 FCSR_ = reg & ~kFCSRNaN2008FlagMask;
3430 } 3660 }
3661 TraceRegWr(static_cast<int32_t>(FCSR_), FLOAT);
3431 break; 3662 break;
3432 } 3663 }
3433 case MTC1: 3664 case MTC1:
3434 // Hardware writes upper 32-bits to zero on mtc1. 3665 // Hardware writes upper 32-bits to zero on mtc1.
3435 set_fpu_register_hi_word(fs_reg(), 0); 3666 set_fpu_register_hi_word(fs_reg(), 0);
3436 set_fpu_register_word(fs_reg(), registers_[rt_reg()]); 3667 set_fpu_register_word(fs_reg(), registers_[rt_reg()]);
3668 TraceRegWr(get_fpu_register_word(fs_reg()), FLOAT);
3437 break; 3669 break;
3438 case MTHC1: 3670 case MTHC1:
3439 if (IsFp64Mode()) { 3671 if (IsFp64Mode()) {
3440 set_fpu_register_hi_word(fs_reg(), registers_[rt_reg()]); 3672 set_fpu_register_hi_word(fs_reg(), registers_[rt_reg()]);
3673 TraceRegWr(get_fpu_register(fs_reg()), DOUBLE);
3441 } else { 3674 } else {
3442 set_fpu_register_word(fs_reg() + 1, registers_[rt_reg()]); 3675 set_fpu_register_word(fs_reg() + 1, registers_[rt_reg()]);
3676 if (fs_reg() % 2) {
3677 TraceRegWr(get_fpu_register_word(fs_reg() + 1), FLOAT);
3678 } else {
3679 TraceRegWr(get_fpu_register(fs_reg()), DOUBLE);
3680 }
3443 } 3681 }
3444 break; 3682 break;
3445 case S: { 3683 case S: {
3446 DecodeTypeRegisterSRsType(); 3684 DecodeTypeRegisterSRsType();
3447 break; 3685 break;
3448 } 3686 }
3449 case D: 3687 case D:
3450 DecodeTypeRegisterDRsType(); 3688 DecodeTypeRegisterDRsType();
3451 break; 3689 break;
3452 case W: 3690 case W:
(...skipping 13 matching lines...) Expand all
3466 3704
3467 void Simulator::DecodeTypeRegisterCOP1X() { 3705 void Simulator::DecodeTypeRegisterCOP1X() {
3468 switch (instr_.FunctionFieldRaw()) { 3706 switch (instr_.FunctionFieldRaw()) {
3469 case MADD_S: { 3707 case MADD_S: {
3470 DCHECK(IsMipsArchVariant(kMips32r2)); 3708 DCHECK(IsMipsArchVariant(kMips32r2));
3471 float fr, ft, fs; 3709 float fr, ft, fs;
3472 fr = get_fpu_register_float(fr_reg()); 3710 fr = get_fpu_register_float(fr_reg());
3473 fs = get_fpu_register_float(fs_reg()); 3711 fs = get_fpu_register_float(fs_reg());
3474 ft = get_fpu_register_float(ft_reg()); 3712 ft = get_fpu_register_float(ft_reg());
3475 set_fpu_register_float(fd_reg(), fs * ft + fr); 3713 set_fpu_register_float(fd_reg(), fs * ft + fr);
3714 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3476 break; 3715 break;
3477 } 3716 }
3478 case MSUB_S: { 3717 case MSUB_S: {
3479 DCHECK(IsMipsArchVariant(kMips32r2)); 3718 DCHECK(IsMipsArchVariant(kMips32r2));
3480 float fr, ft, fs; 3719 float fr, ft, fs;
3481 fr = get_fpu_register_float(fr_reg()); 3720 fr = get_fpu_register_float(fr_reg());
3482 fs = get_fpu_register_float(fs_reg()); 3721 fs = get_fpu_register_float(fs_reg());
3483 ft = get_fpu_register_float(ft_reg()); 3722 ft = get_fpu_register_float(ft_reg());
3484 set_fpu_register_float(fd_reg(), fs * ft - fr); 3723 set_fpu_register_float(fd_reg(), fs * ft - fr);
3724 TraceRegWr(get_fpu_register_word(fd_reg()), FLOAT);
3485 break; 3725 break;
3486 } 3726 }
3487 case MADD_D: { 3727 case MADD_D: {
3488 DCHECK(IsMipsArchVariant(kMips32r2)); 3728 DCHECK(IsMipsArchVariant(kMips32r2));
3489 double fr, ft, fs; 3729 double fr, ft, fs;
3490 fr = get_fpu_register_double(fr_reg()); 3730 fr = get_fpu_register_double(fr_reg());
3491 fs = get_fpu_register_double(fs_reg()); 3731 fs = get_fpu_register_double(fs_reg());
3492 ft = get_fpu_register_double(ft_reg()); 3732 ft = get_fpu_register_double(ft_reg());
3493 set_fpu_register_double(fd_reg(), fs * ft + fr); 3733 set_fpu_register_double(fd_reg(), fs * ft + fr);
3734 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
3494 break; 3735 break;
3495 } 3736 }
3496 case MSUB_D: { 3737 case MSUB_D: {
3497 DCHECK(IsMipsArchVariant(kMips32r2)); 3738 DCHECK(IsMipsArchVariant(kMips32r2));
3498 double fr, ft, fs; 3739 double fr, ft, fs;
3499 fr = get_fpu_register_double(fr_reg()); 3740 fr = get_fpu_register_double(fr_reg());
3500 fs = get_fpu_register_double(fs_reg()); 3741 fs = get_fpu_register_double(fs_reg());
3501 ft = get_fpu_register_double(ft_reg()); 3742 ft = get_fpu_register_double(ft_reg());
3502 set_fpu_register_double(fd_reg(), fs * ft - fr); 3743 set_fpu_register_double(fd_reg(), fs * ft - fr);
3744 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE);
3503 break; 3745 break;
3504 } 3746 }
3505 default: 3747 default:
3506 UNREACHABLE(); 3748 UNREACHABLE();
3507 } 3749 }
3508 } 3750 }
3509 3751
3510 3752
3511 void Simulator::DecodeTypeRegisterSPECIAL() { 3753 void Simulator::DecodeTypeRegisterSPECIAL() {
3512 int64_t alu_out = 0x12345678; 3754 int64_t alu_out = 0x12345678;
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after
4365 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask; 4607 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
4366 uint32_t mask = (1 << al_offset * 8) - 1; 4608 uint32_t mask = (1 << al_offset * 8) - 1;
4367 addr = rs + se_imm16 - al_offset; 4609 addr = rs + se_imm16 - al_offset;
4368 uint32_t mem_value = ReadW(addr, instr_.instr()); 4610 uint32_t mem_value = ReadW(addr, instr_.instr());
4369 mem_value = (rt << al_offset * 8) | (mem_value & mask); 4611 mem_value = (rt << al_offset * 8) | (mem_value & mask);
4370 WriteW(addr, mem_value, instr_.instr()); 4612 WriteW(addr, mem_value, instr_.instr());
4371 break; 4613 break;
4372 } 4614 }
4373 case LWC1: 4615 case LWC1:
4374 set_fpu_register_hi_word(ft_reg, 0); 4616 set_fpu_register_hi_word(ft_reg, 0);
4375 set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr_.instr())); 4617 set_fpu_register_word(ft_reg,
4618 ReadW(rs + se_imm16, instr_.instr(), FLOAT));
4619 if (ft_reg % 2) {
4620 TraceMemRd(rs + se_imm16, get_fpu_register(ft_reg - 1), FLOAT_DOUBLE);
4621 } else {
4622 TraceMemRd(rs + se_imm16, get_fpu_register_word(ft_reg), FLOAT);
4623 }
4376 break; 4624 break;
4377 case LDC1: 4625 case LDC1:
4378 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr_.instr())); 4626 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr_.instr()));
4627 TraceMemRd(rs + se_imm16, get_fpu_register(ft_reg), DOUBLE);
4379 break; 4628 break;
4380 case SWC1: 4629 case SWC1:
4381 WriteW(rs + se_imm16, get_fpu_register_word(ft_reg), instr_.instr()); 4630 WriteW(rs + se_imm16, get_fpu_register_word(ft_reg), instr_.instr());
4631 TraceMemWr(rs + se_imm16, get_fpu_register_word(ft_reg));
4382 break; 4632 break;
4383 case SDC1: 4633 case SDC1:
4384 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr_.instr()); 4634 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr_.instr());
4635 TraceMemWr(rs + se_imm16, get_fpu_register(ft_reg));
4385 break; 4636 break;
4386 // ------------- PC-Relative instructions. 4637 // ------------- PC-Relative instructions.
4387 case PCREL: { 4638 case PCREL: {
4388 // rt field: checking 5-bits. 4639 // rt field: checking 5-bits.
4389 int32_t imm21 = instr_.Imm21Value(); 4640 int32_t imm21 = instr_.Imm21Value();
4390 int32_t current_pc = get_pc(); 4641 int32_t current_pc = get_pc();
4391 uint8_t rt = (imm21 >> kImm16Bits); 4642 uint8_t rt = (imm21 >> kImm16Bits);
4392 switch (rt) { 4643 switch (rt) {
4393 case ALUIPC: 4644 case ALUIPC:
4394 addr = current_pc + (se_imm16 << 16); 4645 addr = current_pc + (se_imm16 << 16);
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
4694 4945
4695 4946
4696 #undef UNSUPPORTED 4947 #undef UNSUPPORTED
4697 4948
4698 } // namespace internal 4949 } // namespace internal
4699 } // namespace v8 4950 } // namespace v8
4700 4951
4701 #endif // USE_SIMULATOR 4952 #endif // USE_SIMULATOR
4702 4953
4703 #endif // V8_TARGET_ARCH_MIPS 4954 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698