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

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

Issue 2603083002: MIPS[64]: Add support for FPR content in simulator trace. (Closed)
Patch Set: Using Set*Result functions. Created 3 years, 10 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
« no previous file with comments | « src/mips/simulator-mips.h ('k') | src/mips64/simulator-mips64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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
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 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
2453 case kRoundToZero: 2577 case kRoundToZero:
2454 result = (fs > 0 ? lower : upper); 2578 result = (fs > 0 ? lower : upper);
2455 break; 2579 break;
2456 case kRoundToPlusInf: 2580 case kRoundToPlusInf:
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 SetFPUDoubleResult(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 }
2467 break; 2591 break;
2468 } 2592 }
2469 case SEL: 2593 case SEL:
2470 DCHECK(IsMipsArchVariant(kMips32r6)); 2594 DCHECK(IsMipsArchVariant(kMips32r6));
2471 set_fpu_register_double(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); 2595 SetFPUDoubleResult(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft);
2472 break; 2596 break;
2473 case SELEQZ_C: 2597 case SELEQZ_C:
2474 DCHECK(IsMipsArchVariant(kMips32r6)); 2598 DCHECK(IsMipsArchVariant(kMips32r6));
2475 set_fpu_register_double(fd_reg(), (ft_int & 0x1) == 0 ? fs : 0.0); 2599 SetFPUDoubleResult(fd_reg(), (ft_int & 0x1) == 0 ? fs : 0.0);
2476 break; 2600 break;
2477 case SELNEZ_C: 2601 case SELNEZ_C:
2478 DCHECK(IsMipsArchVariant(kMips32r6)); 2602 DCHECK(IsMipsArchVariant(kMips32r6));
2479 set_fpu_register_double(fd_reg(), (ft_int & 0x1) != 0 ? fs : 0.0); 2603 SetFPUDoubleResult(fd_reg(), (ft_int & 0x1) != 0 ? fs : 0.0);
2480 break; 2604 break;
2481 case MOVZ_C: { 2605 case MOVZ_C: {
2482 DCHECK(IsMipsArchVariant(kMips32r2)); 2606 DCHECK(IsMipsArchVariant(kMips32r2));
2483 if (rt() == 0) { 2607 if (rt() == 0) {
2484 set_fpu_register_double(fd_reg(), fs); 2608 SetFPUDoubleResult(fd_reg(), fs);
2485 } 2609 }
2486 break; 2610 break;
2487 } 2611 }
2488 case MOVN_C: { 2612 case MOVN_C: {
2489 DCHECK(IsMipsArchVariant(kMips32r2)); 2613 DCHECK(IsMipsArchVariant(kMips32r2));
2490 int32_t rt_reg = instr_.RtValue(); 2614 int32_t rt_reg = instr_.RtValue();
2491 int32_t rt = get_register(rt_reg); 2615 int32_t rt = get_register(rt_reg);
2492 if (rt != 0) { 2616 if (rt != 0) {
2493 set_fpu_register_double(fd_reg(), fs); 2617 SetFPUDoubleResult(fd_reg(), fs);
2494 } 2618 }
2495 break; 2619 break;
2496 } 2620 }
2497 case MOVF: { 2621 case MOVF: {
2498 // Same function field for MOVT.D and MOVF.D 2622 // Same function field for MOVT.D and MOVF.D
2499 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; 2623 uint32_t ft_cc = (ft_reg() >> 2) & 0x7;
2500 ft_cc = get_fcsr_condition_bit(ft_cc); 2624 ft_cc = get_fcsr_condition_bit(ft_cc);
2501 if (instr_.Bit(16)) { // Read Tf bit. 2625 if (instr_.Bit(16)) { // Read Tf bit.
2502 // MOVT.D 2626 // MOVT.D
2503 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); 2627 if (test_fcsr_bit(ft_cc)) SetFPUDoubleResult(fd_reg(), fs);
2504 } else { 2628 } else {
2505 // MOVF.D 2629 // MOVF.D
2506 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); 2630 if (!test_fcsr_bit(ft_cc)) SetFPUDoubleResult(fd_reg(), fs);
2507 } 2631 }
2508 break; 2632 break;
2509 } 2633 }
2510 case MIN: 2634 case MIN:
2511 DCHECK(IsMipsArchVariant(kMips32r6)); 2635 DCHECK(IsMipsArchVariant(kMips32r6));
2512 set_fpu_register_double(fd_reg(), FPUMin(ft, fs)); 2636 SetFPUDoubleResult(fd_reg(), FPUMin(ft, fs));
2513 break; 2637 break;
2514 case MAX: 2638 case MAX:
2515 DCHECK(IsMipsArchVariant(kMips32r6)); 2639 DCHECK(IsMipsArchVariant(kMips32r6));
2516 set_fpu_register_double(fd_reg(), FPUMax(ft, fs)); 2640 SetFPUDoubleResult(fd_reg(), FPUMax(ft, fs));
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 SetFPUDoubleResult(fd_reg(), FPUMinA(ft, fs));
2521 break; 2645 break;
2522 case MAXA: 2646 case MAXA:
2523 DCHECK(IsMipsArchVariant(kMips32r6)); 2647 DCHECK(IsMipsArchVariant(kMips32r6));
2524 set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs)); 2648 SetFPUDoubleResult(fd_reg(), FPUMaxA(ft, fs));
2525 break; 2649 break;
2526 case ADD_D: 2650 case ADD_D:
2527 set_fpu_register_double( 2651 SetFPUDoubleResult(
2528 fd_reg(), 2652 fd_reg(),
2529 FPUCanonalizeOperation( 2653 FPUCanonalizeOperation(
2530 [](double lhs, double rhs) { return lhs + rhs; }, fs, ft)); 2654 [](double lhs, double rhs) { return lhs + rhs; }, fs, ft));
2531 break; 2655 break;
2532 case SUB_D: 2656 case SUB_D:
2533 set_fpu_register_double( 2657 SetFPUDoubleResult(
2534 fd_reg(), 2658 fd_reg(),
2535 FPUCanonalizeOperation( 2659 FPUCanonalizeOperation(
2536 [](double lhs, double rhs) { return lhs - rhs; }, fs, ft)); 2660 [](double lhs, double rhs) { return lhs - rhs; }, fs, ft));
2537 break; 2661 break;
2538 case MADDF_D: 2662 case MADDF_D:
2539 DCHECK(IsMipsArchVariant(kMips32r6)); 2663 DCHECK(IsMipsArchVariant(kMips32r6));
2540 set_fpu_register_double(fd_reg(), std::fma(fs, ft, fd)); 2664 SetFPUDoubleResult(fd_reg(), std::fma(fs, ft, fd));
2541 break; 2665 break;
2542 case MSUBF_D: 2666 case MSUBF_D:
2543 DCHECK(IsMipsArchVariant(kMips32r6)); 2667 DCHECK(IsMipsArchVariant(kMips32r6));
2544 set_fpu_register_double(fd_reg(), std::fma(-fs, ft, fd)); 2668 SetFPUDoubleResult(fd_reg(), std::fma(-fs, ft, fd));
2545 break; 2669 break;
2546 case MUL_D: 2670 case MUL_D:
2547 set_fpu_register_double( 2671 SetFPUDoubleResult(
2548 fd_reg(), 2672 fd_reg(),
2549 FPUCanonalizeOperation( 2673 FPUCanonalizeOperation(
2550 [](double lhs, double rhs) { return lhs * rhs; }, fs, ft)); 2674 [](double lhs, double rhs) { return lhs * rhs; }, fs, ft));
2551 break; 2675 break;
2552 case DIV_D: 2676 case DIV_D:
2553 set_fpu_register_double( 2677 SetFPUDoubleResult(
2554 fd_reg(), 2678 fd_reg(),
2555 FPUCanonalizeOperation( 2679 FPUCanonalizeOperation(
2556 [](double lhs, double rhs) { return lhs / rhs; }, fs, ft)); 2680 [](double lhs, double rhs) { return lhs / rhs; }, fs, ft));
2557 break; 2681 break;
2558 case ABS_D: 2682 case ABS_D:
2559 set_fpu_register_double( 2683 SetFPUDoubleResult(
2560 fd_reg(), 2684 fd_reg(),
2561 FPUCanonalizeOperation([](double fs) { return FPAbs(fs); }, fs)); 2685 FPUCanonalizeOperation([](double fs) { return FPAbs(fs); }, fs));
2562 break; 2686 break;
2563 case MOV_D: 2687 case MOV_D:
2564 set_fpu_register_double(fd_reg(), fs); 2688 SetFPUDoubleResult(fd_reg(), fs);
2565 break; 2689 break;
2566 case NEG_D: 2690 case NEG_D:
2567 set_fpu_register_double( 2691 SetFPUDoubleResult(fd_reg(),
2568 fd_reg(), FPUCanonalizeOperation([](double src) { return -src; }, 2692 FPUCanonalizeOperation([](double src) { return -src; },
2569 KeepSign::yes, fs)); 2693 KeepSign::yes, fs));
2570 break; 2694 break;
2571 case SQRT_D: 2695 case SQRT_D:
2572 set_fpu_register_double( 2696 SetFPUDoubleResult(
2573 fd_reg(), 2697 fd_reg(),
2574 FPUCanonalizeOperation([](double fs) { return std::sqrt(fs); }, fs)); 2698 FPUCanonalizeOperation([](double fs) { return std::sqrt(fs); }, fs));
2575 break; 2699 break;
2576 case RSQRT_D: 2700 case RSQRT_D:
2577 set_fpu_register_double( 2701 SetFPUDoubleResult(
2578 fd_reg(), FPUCanonalizeOperation( 2702 fd_reg(), FPUCanonalizeOperation(
2579 [](double fs) { return 1.0 / std::sqrt(fs); }, fs)); 2703 [](double fs) { return 1.0 / std::sqrt(fs); }, fs));
2580 break; 2704 break;
2581 case RECIP_D: 2705 case RECIP_D:
2582 set_fpu_register_double( 2706 SetFPUDoubleResult(fd_reg(), FPUCanonalizeOperation(
2583 fd_reg(), 2707 [](double fs) { return 1.0 / fs; }, fs));
2584 FPUCanonalizeOperation([](double fs) { return 1.0 / fs; }, fs));
2585 break; 2708 break;
2586 case C_UN_D: 2709 case C_UN_D:
2587 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); 2710 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
2711 TraceRegWr(test_fcsr_bit(fcsr_cc));
2588 break; 2712 break;
2589 case C_EQ_D: 2713 case C_EQ_D:
2590 set_fcsr_bit(fcsr_cc, (fs == ft)); 2714 set_fcsr_bit(fcsr_cc, (fs == ft));
2715 TraceRegWr(test_fcsr_bit(fcsr_cc));
2591 break; 2716 break;
2592 case C_UEQ_D: 2717 case C_UEQ_D:
2593 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); 2718 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft)));
2719 TraceRegWr(test_fcsr_bit(fcsr_cc));
2594 break; 2720 break;
2595 case C_OLT_D: 2721 case C_OLT_D:
2596 set_fcsr_bit(fcsr_cc, (fs < ft)); 2722 set_fcsr_bit(fcsr_cc, (fs < ft));
2723 TraceRegWr(test_fcsr_bit(fcsr_cc));
2597 break; 2724 break;
2598 case C_ULT_D: 2725 case C_ULT_D:
2599 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); 2726 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft)));
2727 TraceRegWr(test_fcsr_bit(fcsr_cc));
2600 break; 2728 break;
2601 case C_OLE_D: 2729 case C_OLE_D:
2602 set_fcsr_bit(fcsr_cc, (fs <= ft)); 2730 set_fcsr_bit(fcsr_cc, (fs <= ft));
2731 TraceRegWr(test_fcsr_bit(fcsr_cc));
2603 break; 2732 break;
2604 case C_ULE_D: 2733 case C_ULE_D:
2605 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); 2734 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft)));
2735 TraceRegWr(test_fcsr_bit(fcsr_cc));
2606 break; 2736 break;
2607 case CVT_W_D: { // Convert double to word. 2737 case CVT_W_D: { // Convert double to word.
2608 double rounded; 2738 double rounded;
2609 int32_t result; 2739 int32_t result;
2610 round_according_to_fcsr(fs, rounded, result, fs); 2740 round_according_to_fcsr(fs, rounded, result, fs);
2611 set_fpu_register_word(fd_reg(), result); 2741 SetFPUWordResult(fd_reg(), result);
2612 if (set_fcsr_round_error(fs, rounded)) { 2742 if (set_fcsr_round_error(fs, rounded)) {
2613 set_fpu_register_word_invalid_result(fs, rounded); 2743 set_fpu_register_word_invalid_result(fs, rounded);
2614 } 2744 }
2615 } break; 2745 } break;
2616 case ROUND_W_D: // Round double to word (round half to even). 2746 case ROUND_W_D: // Round double to word (round half to even).
2617 { 2747 {
2618 double rounded = std::floor(fs + 0.5); 2748 double rounded = std::floor(fs + 0.5);
2619 int32_t result = static_cast<int32_t>(rounded); 2749 int32_t result = static_cast<int32_t>(rounded);
2620 if ((result & 1) != 0 && result - fs == 0.5) { 2750 if ((result & 1) != 0 && result - fs == 0.5) {
2621 // If the number is halfway between two integers, 2751 // If the number is halfway between two integers,
2622 // round to the even one. 2752 // round to the even one.
2623 result--; 2753 result--;
2624 } 2754 }
2625 set_fpu_register_word(fd_reg(), result); 2755 SetFPUWordResult(fd_reg(), result);
2626 if (set_fcsr_round_error(fs, rounded)) { 2756 if (set_fcsr_round_error(fs, rounded)) {
2627 set_fpu_register_word_invalid_result(fs, rounded); 2757 set_fpu_register_word_invalid_result(fs, rounded);
2628 } 2758 }
2629 } break; 2759 } break;
2630 case TRUNC_W_D: // Truncate double to word (round towards 0). 2760 case TRUNC_W_D: // Truncate double to word (round towards 0).
2631 { 2761 {
2632 double rounded = trunc(fs); 2762 double rounded = trunc(fs);
2633 int32_t result = static_cast<int32_t>(rounded); 2763 int32_t result = static_cast<int32_t>(rounded);
2634 set_fpu_register_word(fd_reg(), result); 2764 SetFPUWordResult(fd_reg(), result);
2635 if (set_fcsr_round_error(fs, rounded)) { 2765 if (set_fcsr_round_error(fs, rounded)) {
2636 set_fpu_register_word_invalid_result(fs, rounded); 2766 set_fpu_register_word_invalid_result(fs, rounded);
2637 } 2767 }
2638 } break; 2768 } break;
2639 case FLOOR_W_D: // Round double to word towards negative infinity. 2769 case FLOOR_W_D: // Round double to word towards negative infinity.
2640 { 2770 {
2641 double rounded = std::floor(fs); 2771 double rounded = std::floor(fs);
2642 int32_t result = static_cast<int32_t>(rounded); 2772 int32_t result = static_cast<int32_t>(rounded);
2643 set_fpu_register_word(fd_reg(), result); 2773 SetFPUWordResult(fd_reg(), result);
2644 if (set_fcsr_round_error(fs, rounded)) { 2774 if (set_fcsr_round_error(fs, rounded)) {
2645 set_fpu_register_word_invalid_result(fs, rounded); 2775 set_fpu_register_word_invalid_result(fs, rounded);
2646 } 2776 }
2647 } break; 2777 } break;
2648 case CEIL_W_D: // Round double to word towards positive infinity. 2778 case CEIL_W_D: // Round double to word towards positive infinity.
2649 { 2779 {
2650 double rounded = std::ceil(fs); 2780 double rounded = std::ceil(fs);
2651 int32_t result = static_cast<int32_t>(rounded); 2781 int32_t result = static_cast<int32_t>(rounded);
2652 set_fpu_register_word(fd_reg(), result); 2782 SetFPUWordResult(fd_reg(), result);
2653 if (set_fcsr_round_error(fs, rounded)) { 2783 if (set_fcsr_round_error(fs, rounded)) {
2654 set_fpu_register_word_invalid_result(fs, rounded); 2784 set_fpu_register_word_invalid_result(fs, rounded);
2655 } 2785 }
2656 } break; 2786 } break;
2657 case CVT_S_D: // Convert double to float (single). 2787 case CVT_S_D: // Convert double to float (single).
2658 set_fpu_register_float(fd_reg(), static_cast<float>(fs)); 2788 SetFPUFloatResult(fd_reg(), static_cast<float>(fs));
2659 break; 2789 break;
2660 case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word. 2790 case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word.
2661 if (IsFp64Mode()) { 2791 if (IsFp64Mode()) {
2662 int64_t result; 2792 int64_t result;
2663 double rounded; 2793 double rounded;
2664 round64_according_to_fcsr(fs, rounded, result, fs); 2794 round64_according_to_fcsr(fs, rounded, result, fs);
2665 set_fpu_register(fd_reg(), result); 2795 SetFPUResult(fd_reg(), result);
2666 if (set_fcsr_round64_error(fs, rounded)) { 2796 if (set_fcsr_round64_error(fs, rounded)) {
2667 set_fpu_register_invalid_result64(fs, rounded); 2797 set_fpu_register_invalid_result64(fs, rounded);
2668 } 2798 }
2669 } else { 2799 } else {
2670 UNSUPPORTED(); 2800 UNSUPPORTED();
2671 } 2801 }
2672 break; 2802 break;
2673 break; 2803 break;
2674 } 2804 }
2675 case TRUNC_L_D: { // Mips32r2 instruction. 2805 case TRUNC_L_D: { // Mips32r2 instruction.
2676 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2806 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
2677 double rounded = trunc(fs); 2807 double rounded = trunc(fs);
2678 i64 = static_cast<int64_t>(rounded); 2808 i64 = static_cast<int64_t>(rounded);
2679 if (IsFp64Mode()) { 2809 if (IsFp64Mode()) {
2680 set_fpu_register(fd_reg(), i64); 2810 SetFPUResult(fd_reg(), i64);
2681 if (set_fcsr_round64_error(fs, rounded)) { 2811 if (set_fcsr_round64_error(fs, rounded)) {
2682 set_fpu_register_invalid_result64(fs, rounded); 2812 set_fpu_register_invalid_result64(fs, rounded);
2683 } 2813 }
2684 } else { 2814 } else {
2685 UNSUPPORTED(); 2815 UNSUPPORTED();
2686 } 2816 }
2687 break; 2817 break;
2688 } 2818 }
2689 case ROUND_L_D: { // Mips32r2 instruction. 2819 case ROUND_L_D: { // Mips32r2 instruction.
2690 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2820 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
2691 double rounded = std::floor(fs + 0.5); 2821 double rounded = std::floor(fs + 0.5);
2692 int64_t result = static_cast<int64_t>(rounded); 2822 int64_t result = static_cast<int64_t>(rounded);
2693 if ((result & 1) != 0 && result - fs == 0.5) { 2823 if ((result & 1) != 0 && result - fs == 0.5) {
2694 // If the number is halfway between two integers, 2824 // If the number is halfway between two integers,
2695 // round to the even one. 2825 // round to the even one.
2696 result--; 2826 result--;
2697 } 2827 }
2698 int64_t i64 = static_cast<int64_t>(result); 2828 int64_t i64 = static_cast<int64_t>(result);
2699 if (IsFp64Mode()) { 2829 if (IsFp64Mode()) {
2700 set_fpu_register(fd_reg(), i64); 2830 SetFPUResult(fd_reg(), i64);
2701 if (set_fcsr_round64_error(fs, rounded)) { 2831 if (set_fcsr_round64_error(fs, rounded)) {
2702 set_fpu_register_invalid_result64(fs, rounded); 2832 set_fpu_register_invalid_result64(fs, rounded);
2703 } 2833 }
2704 } else { 2834 } else {
2705 UNSUPPORTED(); 2835 UNSUPPORTED();
2706 } 2836 }
2707 break; 2837 break;
2708 } 2838 }
2709 case FLOOR_L_D: { // Mips32r2 instruction. 2839 case FLOOR_L_D: { // Mips32r2 instruction.
2710 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2840 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
2711 double rounded = std::floor(fs); 2841 double rounded = std::floor(fs);
2712 int64_t i64 = static_cast<int64_t>(rounded); 2842 int64_t i64 = static_cast<int64_t>(rounded);
2713 if (IsFp64Mode()) { 2843 if (IsFp64Mode()) {
2714 set_fpu_register(fd_reg(), i64); 2844 SetFPUResult(fd_reg(), i64);
2715 if (set_fcsr_round64_error(fs, rounded)) { 2845 if (set_fcsr_round64_error(fs, rounded)) {
2716 set_fpu_register_invalid_result64(fs, rounded); 2846 set_fpu_register_invalid_result64(fs, rounded);
2717 } 2847 }
2718 } else { 2848 } else {
2719 UNSUPPORTED(); 2849 UNSUPPORTED();
2720 } 2850 }
2721 break; 2851 break;
2722 } 2852 }
2723 case CEIL_L_D: { // Mips32r2 instruction. 2853 case CEIL_L_D: { // Mips32r2 instruction.
2724 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 2854 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
2725 double rounded = std::ceil(fs); 2855 double rounded = std::ceil(fs);
2726 int64_t i64 = static_cast<int64_t>(rounded); 2856 int64_t i64 = static_cast<int64_t>(rounded);
2727 if (IsFp64Mode()) { 2857 if (IsFp64Mode()) {
2728 set_fpu_register(fd_reg(), i64); 2858 SetFPUResult(fd_reg(), i64);
2729 if (set_fcsr_round64_error(fs, rounded)) { 2859 if (set_fcsr_round64_error(fs, rounded)) {
2730 set_fpu_register_invalid_result64(fs, rounded); 2860 set_fpu_register_invalid_result64(fs, rounded);
2731 } 2861 }
2732 } else { 2862 } else {
2733 UNSUPPORTED(); 2863 UNSUPPORTED();
2734 } 2864 }
2735 break; 2865 break;
2736 } 2866 }
2737 case CLASS_D: { // Mips32r6 instruction 2867 case CLASS_D: { // Mips32r6 instruction
2738 // Convert double input to uint64_t for easier bit manipulation 2868 // Convert double input to uint64_t for easier bit manipulation
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2788 } 2918 }
2789 2919
2790 // Calculating result according to description of CLASS.D instruction 2920 // Calculating result according to description of CLASS.D instruction
2791 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | 2921 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) |
2792 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | 2922 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) |
2793 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; 2923 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan;
2794 2924
2795 DCHECK(result != 0); 2925 DCHECK(result != 0);
2796 2926
2797 dResult = bit_cast<double>(result); 2927 dResult = bit_cast<double>(result);
2798 set_fpu_register_double(fd_reg(), dResult); 2928 SetFPUDoubleResult(fd_reg(), dResult);
2799 2929
2800 break; 2930 break;
2801 } 2931 }
2802 case C_F_D: { 2932 case C_F_D: {
2803 set_fcsr_bit(fcsr_cc, false); 2933 set_fcsr_bit(fcsr_cc, false);
2934 TraceRegWr(test_fcsr_bit(fcsr_cc));
2804 break; 2935 break;
2805 } 2936 }
2806 default: 2937 default:
2807 UNREACHABLE(); 2938 UNREACHABLE();
2808 } 2939 }
2809 } 2940 }
2810 2941
2811 2942
2812 void Simulator::DecodeTypeRegisterWRsType() { 2943 void Simulator::DecodeTypeRegisterWRsType() {
2813 float fs = get_fpu_register_float(fs_reg()); 2944 float fs = get_fpu_register_float(fs_reg());
2814 float ft = get_fpu_register_float(ft_reg()); 2945 float ft = get_fpu_register_float(ft_reg());
2815 int32_t alu_out = 0x12345678; 2946 int32_t alu_out = 0x12345678;
2816 switch (instr_.FunctionFieldRaw()) { 2947 switch (instr_.FunctionFieldRaw()) {
2817 case CVT_S_W: // Convert word to float (single). 2948 case CVT_S_W: // Convert word to float (single).
2818 alu_out = get_fpu_register_signed_word(fs_reg()); 2949 alu_out = get_fpu_register_signed_word(fs_reg());
2819 set_fpu_register_float(fd_reg(), static_cast<float>(alu_out)); 2950 SetFPUFloatResult(fd_reg(), static_cast<float>(alu_out));
2820 break; 2951 break;
2821 case CVT_D_W: // Convert word to double. 2952 case CVT_D_W: // Convert word to double.
2822 alu_out = get_fpu_register_signed_word(fs_reg()); 2953 alu_out = get_fpu_register_signed_word(fs_reg());
2823 set_fpu_register_double(fd_reg(), static_cast<double>(alu_out)); 2954 SetFPUDoubleResult(fd_reg(), static_cast<double>(alu_out));
2824 break; 2955 break;
2825 case CMP_AF: 2956 case CMP_AF:
2826 set_fpu_register_word(fd_reg(), 0); 2957 SetFPUWordResult(fd_reg(), 0);
2827 break; 2958 break;
2828 case CMP_UN: 2959 case CMP_UN:
2829 if (std::isnan(fs) || std::isnan(ft)) { 2960 if (std::isnan(fs) || std::isnan(ft)) {
2830 set_fpu_register_word(fd_reg(), -1); 2961 SetFPUWordResult(fd_reg(), -1);
2831 } else { 2962 } else {
2832 set_fpu_register_word(fd_reg(), 0); 2963 SetFPUWordResult(fd_reg(), 0);
2833 } 2964 }
2834 break; 2965 break;
2835 case CMP_EQ: 2966 case CMP_EQ:
2836 if (fs == ft) { 2967 if (fs == ft) {
2837 set_fpu_register_word(fd_reg(), -1); 2968 SetFPUWordResult(fd_reg(), -1);
2838 } else { 2969 } else {
2839 set_fpu_register_word(fd_reg(), 0); 2970 SetFPUWordResult(fd_reg(), 0);
2840 } 2971 }
2841 break; 2972 break;
2842 case CMP_UEQ: 2973 case CMP_UEQ:
2843 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { 2974 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) {
2844 set_fpu_register_word(fd_reg(), -1); 2975 SetFPUWordResult(fd_reg(), -1);
2845 } else { 2976 } else {
2846 set_fpu_register_word(fd_reg(), 0); 2977 SetFPUWordResult(fd_reg(), 0);
2847 } 2978 }
2848 break; 2979 break;
2849 case CMP_LT: 2980 case CMP_LT:
2850 if (fs < ft) { 2981 if (fs < ft) {
2851 set_fpu_register_word(fd_reg(), -1); 2982 SetFPUWordResult(fd_reg(), -1);
2852 } else { 2983 } else {
2853 set_fpu_register_word(fd_reg(), 0); 2984 SetFPUWordResult(fd_reg(), 0);
2854 } 2985 }
2855 break; 2986 break;
2856 case CMP_ULT: 2987 case CMP_ULT:
2857 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { 2988 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) {
2858 set_fpu_register_word(fd_reg(), -1); 2989 SetFPUWordResult(fd_reg(), -1);
2859 } else { 2990 } else {
2860 set_fpu_register_word(fd_reg(), 0); 2991 SetFPUWordResult(fd_reg(), 0);
2861 } 2992 }
2862 break; 2993 break;
2863 case CMP_LE: 2994 case CMP_LE:
2864 if (fs <= ft) { 2995 if (fs <= ft) {
2865 set_fpu_register_word(fd_reg(), -1); 2996 SetFPUWordResult(fd_reg(), -1);
2866 } else { 2997 } else {
2867 set_fpu_register_word(fd_reg(), 0); 2998 SetFPUWordResult(fd_reg(), 0);
2868 } 2999 }
2869 break; 3000 break;
2870 case CMP_ULE: 3001 case CMP_ULE:
2871 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { 3002 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) {
2872 set_fpu_register_word(fd_reg(), -1); 3003 SetFPUWordResult(fd_reg(), -1);
2873 } else { 3004 } else {
2874 set_fpu_register_word(fd_reg(), 0); 3005 SetFPUWordResult(fd_reg(), 0);
2875 } 3006 }
2876 break; 3007 break;
2877 case CMP_OR: 3008 case CMP_OR:
2878 if (!std::isnan(fs) && !std::isnan(ft)) { 3009 if (!std::isnan(fs) && !std::isnan(ft)) {
2879 set_fpu_register_word(fd_reg(), -1); 3010 SetFPUWordResult(fd_reg(), -1);
2880 } else { 3011 } else {
2881 set_fpu_register_word(fd_reg(), 0); 3012 SetFPUWordResult(fd_reg(), 0);
2882 } 3013 }
2883 break; 3014 break;
2884 case CMP_UNE: 3015 case CMP_UNE:
2885 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { 3016 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) {
2886 set_fpu_register_word(fd_reg(), -1); 3017 SetFPUWordResult(fd_reg(), -1);
2887 } else { 3018 } else {
2888 set_fpu_register_word(fd_reg(), 0); 3019 SetFPUWordResult(fd_reg(), 0);
2889 } 3020 }
2890 break; 3021 break;
2891 case CMP_NE: 3022 case CMP_NE:
2892 if (fs != ft) { 3023 if (fs != ft) {
2893 set_fpu_register_word(fd_reg(), -1); 3024 SetFPUWordResult(fd_reg(), -1);
2894 } else { 3025 } else {
2895 set_fpu_register_word(fd_reg(), 0); 3026 SetFPUWordResult(fd_reg(), 0);
2896 } 3027 }
2897 break; 3028 break;
2898 default: 3029 default:
2899 UNREACHABLE(); 3030 UNREACHABLE();
2900 } 3031 }
2901 } 3032 }
2902 3033
2903 3034
2904 void Simulator::DecodeTypeRegisterSRsType() { 3035 void Simulator::DecodeTypeRegisterSRsType() {
2905 float fs, ft, fd; 3036 float fs, ft, fd;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2937 case kRoundToZero: 3068 case kRoundToZero:
2938 result = (fs > 0 ? lower : upper); 3069 result = (fs > 0 ? lower : upper);
2939 break; 3070 break;
2940 case kRoundToPlusInf: 3071 case kRoundToPlusInf:
2941 result = upper; 3072 result = upper;
2942 break; 3073 break;
2943 case kRoundToMinusInf: 3074 case kRoundToMinusInf:
2944 result = lower; 3075 result = lower;
2945 break; 3076 break;
2946 } 3077 }
2947 set_fpu_register_float(fd_reg(), result); 3078 SetFPUFloatResult(fd_reg(), result);
2948 if (result != fs) { 3079 if (result != fs) {
2949 set_fcsr_bit(kFCSRInexactFlagBit, true); 3080 set_fcsr_bit(kFCSRInexactFlagBit, true);
2950 } 3081 }
2951 break; 3082 break;
2952 } 3083 }
2953 case ADD_S: 3084 case ADD_S:
2954 set_fpu_register_float( 3085 SetFPUFloatResult(
2955 fd_reg(), 3086 fd_reg(),
2956 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs + rhs; }, 3087 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs + rhs; },
2957 fs, ft)); 3088 fs, ft));
2958 break; 3089 break;
2959 case SUB_S: 3090 case SUB_S:
2960 set_fpu_register_float( 3091 SetFPUFloatResult(
2961 fd_reg(), 3092 fd_reg(),
2962 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs - rhs; }, 3093 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs - rhs; },
2963 fs, ft)); 3094 fs, ft));
2964 break; 3095 break;
2965 case MADDF_S: 3096 case MADDF_S:
2966 DCHECK(IsMipsArchVariant(kMips32r6)); 3097 DCHECK(IsMipsArchVariant(kMips32r6));
2967 set_fpu_register_float(fd_reg(), std::fma(fs, ft, fd)); 3098 SetFPUFloatResult(fd_reg(), std::fma(fs, ft, fd));
2968 break; 3099 break;
2969 case MSUBF_S: 3100 case MSUBF_S:
2970 DCHECK(IsMipsArchVariant(kMips32r6)); 3101 DCHECK(IsMipsArchVariant(kMips32r6));
2971 set_fpu_register_float(fd_reg(), std::fma(-fs, ft, fd)); 3102 SetFPUFloatResult(fd_reg(), std::fma(-fs, ft, fd));
2972 break; 3103 break;
2973 case MUL_S: 3104 case MUL_S:
2974 set_fpu_register_float( 3105 SetFPUFloatResult(
2975 fd_reg(), 3106 fd_reg(),
2976 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs * rhs; }, 3107 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs * rhs; },
2977 fs, ft)); 3108 fs, ft));
2978 break; 3109 break;
2979 case DIV_S: 3110 case DIV_S:
2980 set_fpu_register_float( 3111 SetFPUFloatResult(
2981 fd_reg(), 3112 fd_reg(),
2982 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs / rhs; }, 3113 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs / rhs; },
2983 fs, ft)); 3114 fs, ft));
2984 break; 3115 break;
2985 case ABS_S: 3116 case ABS_S:
2986 set_fpu_register_float( 3117 SetFPUFloatResult(fd_reg(), FPUCanonalizeOperation(
2987 fd_reg(), 3118 [](float fs) { return FPAbs(fs); }, fs));
2988 FPUCanonalizeOperation([](float fs) { return FPAbs(fs); }, fs));
2989 break; 3119 break;
2990 case MOV_S: 3120 case MOV_S:
2991 set_fpu_register_float(fd_reg(), fs); 3121 SetFPUFloatResult(fd_reg(), fs);
2992 break; 3122 break;
2993 case NEG_S: 3123 case NEG_S:
2994 set_fpu_register_float( 3124 SetFPUFloatResult(fd_reg(),
2995 fd_reg(), FPUCanonalizeOperation([](float src) { return -src; }, 3125 FPUCanonalizeOperation([](float src) { return -src; },
2996 KeepSign::yes, fs)); 3126 KeepSign::yes, fs));
2997 break; 3127 break;
2998 case SQRT_S: 3128 case SQRT_S:
2999 set_fpu_register_float( 3129 SetFPUFloatResult(
3000 fd_reg(), 3130 fd_reg(),
3001 FPUCanonalizeOperation([](float src) { return std::sqrt(src); }, fs)); 3131 FPUCanonalizeOperation([](float src) { return std::sqrt(src); }, fs));
3002 break; 3132 break;
3003 case RSQRT_S: 3133 case RSQRT_S:
3004 set_fpu_register_float( 3134 SetFPUFloatResult(
3005 fd_reg(), FPUCanonalizeOperation( 3135 fd_reg(), FPUCanonalizeOperation(
3006 [](float src) { return 1.0 / std::sqrt(src); }, fs)); 3136 [](float src) { return 1.0 / std::sqrt(src); }, fs));
3007 break; 3137 break;
3008 case RECIP_S: 3138 case RECIP_S:
3009 set_fpu_register_float( 3139 SetFPUFloatResult(fd_reg(), FPUCanonalizeOperation(
3010 fd_reg(), 3140 [](float src) { return 1.0 / src; }, fs));
3011 FPUCanonalizeOperation([](float src) { return 1.0 / src; }, fs));
3012 break; 3141 break;
3013 case C_F_D: 3142 case C_F_D:
3014 set_fcsr_bit(fcsr_cc, false); 3143 set_fcsr_bit(fcsr_cc, false);
3144 TraceRegWr(test_fcsr_bit(fcsr_cc));
3015 break; 3145 break;
3016 case C_UN_D: 3146 case C_UN_D:
3017 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); 3147 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
3148 TraceRegWr(test_fcsr_bit(fcsr_cc));
3018 break; 3149 break;
3019 case C_EQ_D: 3150 case C_EQ_D:
3020 set_fcsr_bit(fcsr_cc, (fs == ft)); 3151 set_fcsr_bit(fcsr_cc, (fs == ft));
3152 TraceRegWr(test_fcsr_bit(fcsr_cc));
3021 break; 3153 break;
3022 case C_UEQ_D: 3154 case C_UEQ_D:
3023 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); 3155 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft)));
3156 TraceRegWr(test_fcsr_bit(fcsr_cc));
3024 break; 3157 break;
3025 case C_OLT_D: 3158 case C_OLT_D:
3026 set_fcsr_bit(fcsr_cc, (fs < ft)); 3159 set_fcsr_bit(fcsr_cc, (fs < ft));
3160 TraceRegWr(test_fcsr_bit(fcsr_cc));
3027 break; 3161 break;
3028 case C_ULT_D: 3162 case C_ULT_D:
3029 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); 3163 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft)));
3164 TraceRegWr(test_fcsr_bit(fcsr_cc));
3030 break; 3165 break;
3031 case C_OLE_D: 3166 case C_OLE_D:
3032 set_fcsr_bit(fcsr_cc, (fs <= ft)); 3167 set_fcsr_bit(fcsr_cc, (fs <= ft));
3168 TraceRegWr(test_fcsr_bit(fcsr_cc));
3033 break; 3169 break;
3034 case C_ULE_D: 3170 case C_ULE_D:
3035 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); 3171 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft)));
3172 TraceRegWr(test_fcsr_bit(fcsr_cc));
3036 break; 3173 break;
3037 case CVT_D_S: 3174 case CVT_D_S:
3038 set_fpu_register_double(fd_reg(), static_cast<double>(fs)); 3175 SetFPUDoubleResult(fd_reg(), static_cast<double>(fs));
3039 break; 3176 break;
3040 case SEL: 3177 case SEL:
3041 DCHECK(IsMipsArchVariant(kMips32r6)); 3178 DCHECK(IsMipsArchVariant(kMips32r6));
3042 set_fpu_register_float(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); 3179 SetFPUFloatResult(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft);
3043 break; 3180 break;
3044 case CLASS_S: { // Mips32r6 instruction 3181 case CLASS_S: { // Mips32r6 instruction
3045 // Convert float input to uint32_t for easier bit manipulation 3182 // Convert float input to uint32_t for easier bit manipulation
3046 float fs = get_fpu_register_float(fs_reg()); 3183 float fs = get_fpu_register_float(fs_reg());
3047 uint32_t classed = bit_cast<uint32_t>(fs); 3184 uint32_t classed = bit_cast<uint32_t>(fs);
3048 3185
3049 // Extracting sign, exponent and mantissa from the input float 3186 // Extracting sign, exponent and mantissa from the input float
3050 uint32_t sign = (classed >> 31) & 1; 3187 uint32_t sign = (classed >> 31) & 1;
3051 uint32_t exponent = (classed >> 23) & 0x000000ff; 3188 uint32_t exponent = (classed >> 23) & 0x000000ff;
3052 uint32_t mantissa = classed & 0x007fffff; 3189 uint32_t mantissa = classed & 0x007fffff;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
3096 } 3233 }
3097 3234
3098 // Calculating result according to description of CLASS.S instruction 3235 // Calculating result according to description of CLASS.S instruction
3099 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | 3236 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) |
3100 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | 3237 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) |
3101 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; 3238 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan;
3102 3239
3103 DCHECK(result != 0); 3240 DCHECK(result != 0);
3104 3241
3105 fResult = bit_cast<float>(result); 3242 fResult = bit_cast<float>(result);
3106 set_fpu_register_float(fd_reg(), fResult); 3243 SetFPUFloatResult(fd_reg(), fResult);
3107 3244
3108 break; 3245 break;
3109 } 3246 }
3110 case SELEQZ_C: 3247 case SELEQZ_C:
3111 DCHECK(IsMipsArchVariant(kMips32r6)); 3248 DCHECK(IsMipsArchVariant(kMips32r6));
3112 set_fpu_register_float(fd_reg(), (ft_int & 0x1) == 0 3249 SetFPUFloatResult(
3113 ? get_fpu_register_float(fs_reg()) 3250 fd_reg(),
3114 : 0.0); 3251 (ft_int & 0x1) == 0 ? get_fpu_register_float(fs_reg()) : 0.0);
3115 break; 3252 break;
3116 case SELNEZ_C: 3253 case SELNEZ_C:
3117 DCHECK(IsMipsArchVariant(kMips32r6)); 3254 DCHECK(IsMipsArchVariant(kMips32r6));
3118 set_fpu_register_float(fd_reg(), (ft_int & 0x1) != 0 3255 SetFPUFloatResult(
3119 ? get_fpu_register_float(fs_reg()) 3256 fd_reg(),
3120 : 0.0); 3257 (ft_int & 0x1) != 0 ? get_fpu_register_float(fs_reg()) : 0.0);
3121 break; 3258 break;
3122 case MOVZ_C: { 3259 case MOVZ_C: {
3123 DCHECK(IsMipsArchVariant(kMips32r2)); 3260 DCHECK(IsMipsArchVariant(kMips32r2));
3124 if (rt() == 0) { 3261 if (rt() == 0) {
3125 set_fpu_register_float(fd_reg(), fs); 3262 SetFPUFloatResult(fd_reg(), fs);
3126 } 3263 }
3127 break; 3264 break;
3128 } 3265 }
3129 case MOVN_C: { 3266 case MOVN_C: {
3130 DCHECK(IsMipsArchVariant(kMips32r2)); 3267 DCHECK(IsMipsArchVariant(kMips32r2));
3131 if (rt() != 0) { 3268 if (rt() != 0) {
3132 set_fpu_register_float(fd_reg(), fs); 3269 SetFPUFloatResult(fd_reg(), fs);
3133 } 3270 }
3134 break; 3271 break;
3135 } 3272 }
3136 case MOVF: { 3273 case MOVF: {
3137 // Same function field for MOVT.D and MOVF.D 3274 // Same function field for MOVT.D and MOVF.D
3138 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; 3275 uint32_t ft_cc = (ft_reg() >> 2) & 0x7;
3139 ft_cc = get_fcsr_condition_bit(ft_cc); 3276 ft_cc = get_fcsr_condition_bit(ft_cc);
3140 3277
3141 if (instr_.Bit(16)) { // Read Tf bit. 3278 if (instr_.Bit(16)) { // Read Tf bit.
3142 // MOVT.D 3279 // MOVT.D
3143 if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); 3280 if (test_fcsr_bit(ft_cc)) SetFPUFloatResult(fd_reg(), fs);
3144 } else { 3281 } else {
3145 // MOVF.D 3282 // MOVF.D
3146 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); 3283 if (!test_fcsr_bit(ft_cc)) SetFPUFloatResult(fd_reg(), fs);
3147 } 3284 }
3148 break; 3285 break;
3149 } 3286 }
3150 case TRUNC_W_S: { // Truncate single to word (round towards 0). 3287 case TRUNC_W_S: { // Truncate single to word (round towards 0).
3151 float rounded = trunc(fs); 3288 float rounded = trunc(fs);
3152 int32_t result = static_cast<int32_t>(rounded); 3289 int32_t result = static_cast<int32_t>(rounded);
3153 set_fpu_register_word(fd_reg(), result); 3290 SetFPUWordResult(fd_reg(), result);
3154 if (set_fcsr_round_error(fs, rounded)) { 3291 if (set_fcsr_round_error(fs, rounded)) {
3155 set_fpu_register_word_invalid_result(fs, rounded); 3292 set_fpu_register_word_invalid_result(fs, rounded);
3156 } 3293 }
3157 } break; 3294 } break;
3158 case TRUNC_L_S: { // Mips32r2 instruction. 3295 case TRUNC_L_S: { // Mips32r2 instruction.
3159 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 3296 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
3160 float rounded = trunc(fs); 3297 float rounded = trunc(fs);
3161 int64_t i64 = static_cast<int64_t>(rounded); 3298 int64_t i64 = static_cast<int64_t>(rounded);
3162 if (IsFp64Mode()) { 3299 if (IsFp64Mode()) {
3163 set_fpu_register(fd_reg(), i64); 3300 SetFPUResult(fd_reg(), i64);
3164 if (set_fcsr_round64_error(fs, rounded)) { 3301 if (set_fcsr_round64_error(fs, rounded)) {
3165 set_fpu_register_invalid_result64(fs, rounded); 3302 set_fpu_register_invalid_result64(fs, rounded);
3166 } 3303 }
3167 } else { 3304 } else {
3168 UNSUPPORTED(); 3305 UNSUPPORTED();
3169 } 3306 }
3170 break; 3307 break;
3171 } 3308 }
3172 case FLOOR_W_S: // Round double to word towards negative infinity. 3309 case FLOOR_W_S: // Round double to word towards negative infinity.
3173 { 3310 {
3174 float rounded = std::floor(fs); 3311 float rounded = std::floor(fs);
3175 int32_t result = static_cast<int32_t>(rounded); 3312 int32_t result = static_cast<int32_t>(rounded);
3176 set_fpu_register_word(fd_reg(), result); 3313 SetFPUWordResult(fd_reg(), result);
3177 if (set_fcsr_round_error(fs, rounded)) { 3314 if (set_fcsr_round_error(fs, rounded)) {
3178 set_fpu_register_word_invalid_result(fs, rounded); 3315 set_fpu_register_word_invalid_result(fs, rounded);
3179 } 3316 }
3180 } break; 3317 } break;
3181 case FLOOR_L_S: { // Mips32r2 instruction. 3318 case FLOOR_L_S: { // Mips32r2 instruction.
3182 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 3319 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
3183 float rounded = std::floor(fs); 3320 float rounded = std::floor(fs);
3184 int64_t i64 = static_cast<int64_t>(rounded); 3321 int64_t i64 = static_cast<int64_t>(rounded);
3185 if (IsFp64Mode()) { 3322 if (IsFp64Mode()) {
3186 set_fpu_register(fd_reg(), i64); 3323 SetFPUResult(fd_reg(), i64);
3187 if (set_fcsr_round64_error(fs, rounded)) { 3324 if (set_fcsr_round64_error(fs, rounded)) {
3188 set_fpu_register_invalid_result64(fs, rounded); 3325 set_fpu_register_invalid_result64(fs, rounded);
3189 } 3326 }
3190 } else { 3327 } else {
3191 UNSUPPORTED(); 3328 UNSUPPORTED();
3192 } 3329 }
3193 break; 3330 break;
3194 } 3331 }
3195 case ROUND_W_S: { 3332 case ROUND_W_S: {
3196 float rounded = std::floor(fs + 0.5); 3333 float rounded = std::floor(fs + 0.5);
3197 int32_t result = static_cast<int32_t>(rounded); 3334 int32_t result = static_cast<int32_t>(rounded);
3198 if ((result & 1) != 0 && result - fs == 0.5) { 3335 if ((result & 1) != 0 && result - fs == 0.5) {
3199 // If the number is halfway between two integers, 3336 // If the number is halfway between two integers,
3200 // round to the even one. 3337 // round to the even one.
3201 result--; 3338 result--;
3202 } 3339 }
3203 set_fpu_register_word(fd_reg(), result); 3340 SetFPUWordResult(fd_reg(), result);
3204 if (set_fcsr_round_error(fs, rounded)) { 3341 if (set_fcsr_round_error(fs, rounded)) {
3205 set_fpu_register_word_invalid_result(fs, rounded); 3342 set_fpu_register_word_invalid_result(fs, rounded);
3206 } 3343 }
3207 break; 3344 break;
3208 } 3345 }
3209 case ROUND_L_S: { // Mips32r2 instruction. 3346 case ROUND_L_S: { // Mips32r2 instruction.
3210 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 3347 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
3211 float rounded = std::floor(fs + 0.5); 3348 float rounded = std::floor(fs + 0.5);
3212 int64_t result = static_cast<int64_t>(rounded); 3349 int64_t result = static_cast<int64_t>(rounded);
3213 if ((result & 1) != 0 && result - fs == 0.5) { 3350 if ((result & 1) != 0 && result - fs == 0.5) {
3214 // If the number is halfway between two integers, 3351 // If the number is halfway between two integers,
3215 // round to the even one. 3352 // round to the even one.
3216 result--; 3353 result--;
3217 } 3354 }
3218 int64_t i64 = static_cast<int64_t>(result); 3355 int64_t i64 = static_cast<int64_t>(result);
3219 if (IsFp64Mode()) { 3356 if (IsFp64Mode()) {
3220 set_fpu_register(fd_reg(), i64); 3357 SetFPUResult(fd_reg(), i64);
3221 if (set_fcsr_round64_error(fs, rounded)) { 3358 if (set_fcsr_round64_error(fs, rounded)) {
3222 set_fpu_register_invalid_result64(fs, rounded); 3359 set_fpu_register_invalid_result64(fs, rounded);
3223 } 3360 }
3224 } else { 3361 } else {
3225 UNSUPPORTED(); 3362 UNSUPPORTED();
3226 } 3363 }
3227 break; 3364 break;
3228 } 3365 }
3229 case CEIL_W_S: // Round double to word towards positive infinity. 3366 case CEIL_W_S: // Round double to word towards positive infinity.
3230 { 3367 {
3231 float rounded = std::ceil(fs); 3368 float rounded = std::ceil(fs);
3232 int32_t result = static_cast<int32_t>(rounded); 3369 int32_t result = static_cast<int32_t>(rounded);
3233 set_fpu_register_word(fd_reg(), result); 3370 SetFPUWordResult(fd_reg(), result);
3234 if (set_fcsr_round_error(fs, rounded)) { 3371 if (set_fcsr_round_error(fs, rounded)) {
3235 set_fpu_register_word_invalid_result(fs, rounded); 3372 set_fpu_register_word_invalid_result(fs, rounded);
3236 } 3373 }
3237 } break; 3374 } break;
3238 case CEIL_L_S: { // Mips32r2 instruction. 3375 case CEIL_L_S: { // Mips32r2 instruction.
3239 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)); 3376 DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
3240 float rounded = std::ceil(fs); 3377 float rounded = std::ceil(fs);
3241 int64_t i64 = static_cast<int64_t>(rounded); 3378 int64_t i64 = static_cast<int64_t>(rounded);
3242 if (IsFp64Mode()) { 3379 if (IsFp64Mode()) {
3243 set_fpu_register(fd_reg(), i64); 3380 SetFPUResult(fd_reg(), i64);
3244 if (set_fcsr_round64_error(fs, rounded)) { 3381 if (set_fcsr_round64_error(fs, rounded)) {
3245 set_fpu_register_invalid_result64(fs, rounded); 3382 set_fpu_register_invalid_result64(fs, rounded);
3246 } 3383 }
3247 } else { 3384 } else {
3248 UNSUPPORTED(); 3385 UNSUPPORTED();
3249 } 3386 }
3250 break; 3387 break;
3251 } 3388 }
3252 case MIN: 3389 case MIN:
3253 DCHECK(IsMipsArchVariant(kMips32r6)); 3390 DCHECK(IsMipsArchVariant(kMips32r6));
3254 set_fpu_register_float(fd_reg(), FPUMin(ft, fs)); 3391 SetFPUFloatResult(fd_reg(), FPUMin(ft, fs));
3255 break; 3392 break;
3256 case MAX: 3393 case MAX:
3257 DCHECK(IsMipsArchVariant(kMips32r6)); 3394 DCHECK(IsMipsArchVariant(kMips32r6));
3258 set_fpu_register_float(fd_reg(), FPUMax(ft, fs)); 3395 SetFPUFloatResult(fd_reg(), FPUMax(ft, fs));
3259 break; 3396 break;
3260 case MINA: 3397 case MINA:
3261 DCHECK(IsMipsArchVariant(kMips32r6)); 3398 DCHECK(IsMipsArchVariant(kMips32r6));
3262 set_fpu_register_float(fd_reg(), FPUMinA(ft, fs)); 3399 SetFPUFloatResult(fd_reg(), FPUMinA(ft, fs));
3263 break; 3400 break;
3264 case MAXA: 3401 case MAXA:
3265 DCHECK(IsMipsArchVariant(kMips32r6)); 3402 DCHECK(IsMipsArchVariant(kMips32r6));
3266 set_fpu_register_float(fd_reg(), FPUMaxA(ft, fs)); 3403 SetFPUFloatResult(fd_reg(), FPUMaxA(ft, fs));
3267 break; 3404 break;
3268 case CVT_L_S: { 3405 case CVT_L_S: {
3269 if (IsFp64Mode()) { 3406 if (IsFp64Mode()) {
3270 int64_t result; 3407 int64_t result;
3271 float rounded; 3408 float rounded;
3272 round64_according_to_fcsr(fs, rounded, result, fs); 3409 round64_according_to_fcsr(fs, rounded, result, fs);
3273 set_fpu_register(fd_reg(), result); 3410 SetFPUResult(fd_reg(), result);
3274 if (set_fcsr_round64_error(fs, rounded)) { 3411 if (set_fcsr_round64_error(fs, rounded)) {
3275 set_fpu_register_invalid_result64(fs, rounded); 3412 set_fpu_register_invalid_result64(fs, rounded);
3276 } 3413 }
3277 } else { 3414 } else {
3278 UNSUPPORTED(); 3415 UNSUPPORTED();
3279 } 3416 }
3280 break; 3417 break;
3281 } 3418 }
3282 case CVT_W_S: { 3419 case CVT_W_S: {
3283 float rounded; 3420 float rounded;
3284 int32_t result; 3421 int32_t result;
3285 round_according_to_fcsr(fs, rounded, result, fs); 3422 round_according_to_fcsr(fs, rounded, result, fs);
3286 set_fpu_register_word(fd_reg(), result); 3423 SetFPUWordResult(fd_reg(), result);
3287 if (set_fcsr_round_error(fs, rounded)) { 3424 if (set_fcsr_round_error(fs, rounded)) {
3288 set_fpu_register_word_invalid_result(fs, rounded); 3425 set_fpu_register_word_invalid_result(fs, rounded);
3289 } 3426 }
3290 break; 3427 break;
3291 } 3428 }
3292 default: 3429 default:
3293 // CVT_W_S CVT_L_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S 3430 // 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. 3431 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented.
3295 UNREACHABLE(); 3432 UNREACHABLE();
3296 } 3433 }
3297 } 3434 }
3298 3435
3299 3436
3300 void Simulator::DecodeTypeRegisterLRsType() { 3437 void Simulator::DecodeTypeRegisterLRsType() {
3301 double fs = get_fpu_register_double(fs_reg()); 3438 double fs = get_fpu_register_double(fs_reg());
3302 double ft = get_fpu_register_double(ft_reg()); 3439 double ft = get_fpu_register_double(ft_reg());
3303 switch (instr_.FunctionFieldRaw()) { 3440 switch (instr_.FunctionFieldRaw()) {
3304 case CVT_D_L: // Mips32r2 instruction. 3441 case CVT_D_L: // Mips32r2 instruction.
3305 // Watch the signs here, we want 2 32-bit vals 3442 // Watch the signs here, we want 2 32-bit vals
3306 // to make a sign-64. 3443 // to make a sign-64.
3307 int64_t i64; 3444 int64_t i64;
3308 if (IsFp64Mode()) { 3445 if (IsFp64Mode()) {
3309 i64 = get_fpu_register(fs_reg()); 3446 i64 = get_fpu_register(fs_reg());
3310 } else { 3447 } else {
3311 i64 = static_cast<uint32_t>(get_fpu_register_word(fs_reg())); 3448 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; 3449 i64 |= static_cast<int64_t>(get_fpu_register_word(fs_reg() + 1)) << 32;
3313 } 3450 }
3314 set_fpu_register_double(fd_reg(), static_cast<double>(i64)); 3451 SetFPUDoubleResult(fd_reg(), static_cast<double>(i64));
3315 break; 3452 break;
3316 case CVT_S_L: 3453 case CVT_S_L:
3317 if (IsFp64Mode()) { 3454 if (IsFp64Mode()) {
3318 i64 = get_fpu_register(fs_reg()); 3455 i64 = get_fpu_register(fs_reg());
3319 } else { 3456 } else {
3320 i64 = static_cast<uint32_t>(get_fpu_register_word(fs_reg())); 3457 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; 3458 i64 |= static_cast<int64_t>(get_fpu_register_word(fs_reg() + 1)) << 32;
3322 } 3459 }
3323 set_fpu_register_float(fd_reg(), static_cast<float>(i64)); 3460 SetFPUFloatResult(fd_reg(), static_cast<float>(i64));
3324 break; 3461 break;
3325 case CMP_AF: // Mips64r6 CMP.D instructions. 3462 case CMP_AF: // Mips64r6 CMP.D instructions.
3326 set_fpu_register(fd_reg(), 0); 3463 SetFPUResult(fd_reg(), 0);
3327 break; 3464 break;
3328 case CMP_UN: 3465 case CMP_UN:
3329 if (std::isnan(fs) || std::isnan(ft)) { 3466 if (std::isnan(fs) || std::isnan(ft)) {
3330 set_fpu_register(fd_reg(), -1); 3467 SetFPUResult(fd_reg(), -1);
3331 } else { 3468 } else {
3332 set_fpu_register(fd_reg(), 0); 3469 SetFPUResult(fd_reg(), 0);
3333 } 3470 }
3334 break; 3471 break;
3335 case CMP_EQ: 3472 case CMP_EQ:
3336 if (fs == ft) { 3473 if (fs == ft) {
3337 set_fpu_register(fd_reg(), -1); 3474 SetFPUResult(fd_reg(), -1);
3338 } else { 3475 } else {
3339 set_fpu_register(fd_reg(), 0); 3476 SetFPUResult(fd_reg(), 0);
3340 } 3477 }
3341 break; 3478 break;
3342 case CMP_UEQ: 3479 case CMP_UEQ:
3343 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { 3480 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) {
3344 set_fpu_register(fd_reg(), -1); 3481 SetFPUResult(fd_reg(), -1);
3345 } else { 3482 } else {
3346 set_fpu_register(fd_reg(), 0); 3483 SetFPUResult(fd_reg(), 0);
3347 } 3484 }
3348 break; 3485 break;
3349 case CMP_LT: 3486 case CMP_LT:
3350 if (fs < ft) { 3487 if (fs < ft) {
3351 set_fpu_register(fd_reg(), -1); 3488 SetFPUResult(fd_reg(), -1);
3352 } else { 3489 } else {
3353 set_fpu_register(fd_reg(), 0); 3490 SetFPUResult(fd_reg(), 0);
3354 } 3491 }
3355 break; 3492 break;
3356 case CMP_ULT: 3493 case CMP_ULT:
3357 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { 3494 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) {
3358 set_fpu_register(fd_reg(), -1); 3495 SetFPUResult(fd_reg(), -1);
3359 } else { 3496 } else {
3360 set_fpu_register(fd_reg(), 0); 3497 SetFPUResult(fd_reg(), 0);
3361 } 3498 }
3362 break; 3499 break;
3363 case CMP_LE: 3500 case CMP_LE:
3364 if (fs <= ft) { 3501 if (fs <= ft) {
3365 set_fpu_register(fd_reg(), -1); 3502 SetFPUResult(fd_reg(), -1);
3366 } else { 3503 } else {
3367 set_fpu_register(fd_reg(), 0); 3504 SetFPUResult(fd_reg(), 0);
3368 } 3505 }
3369 break; 3506 break;
3370 case CMP_ULE: 3507 case CMP_ULE:
3371 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { 3508 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) {
3372 set_fpu_register(fd_reg(), -1); 3509 SetFPUResult(fd_reg(), -1);
3373 } else { 3510 } else {
3374 set_fpu_register(fd_reg(), 0); 3511 SetFPUResult(fd_reg(), 0);
3375 } 3512 }
3376 break; 3513 break;
3377 case CMP_OR: 3514 case CMP_OR:
3378 if (!std::isnan(fs) && !std::isnan(ft)) { 3515 if (!std::isnan(fs) && !std::isnan(ft)) {
3379 set_fpu_register(fd_reg(), -1); 3516 SetFPUResult(fd_reg(), -1);
3380 } else { 3517 } else {
3381 set_fpu_register(fd_reg(), 0); 3518 SetFPUResult(fd_reg(), 0);
3382 } 3519 }
3383 break; 3520 break;
3384 case CMP_UNE: 3521 case CMP_UNE:
3385 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { 3522 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) {
3386 set_fpu_register(fd_reg(), -1); 3523 SetFPUResult(fd_reg(), -1);
3387 } else { 3524 } else {
3388 set_fpu_register(fd_reg(), 0); 3525 SetFPUResult(fd_reg(), 0);
3389 } 3526 }
3390 break; 3527 break;
3391 case CMP_NE: 3528 case CMP_NE:
3392 if (fs != ft && (!std::isnan(fs) && !std::isnan(ft))) { 3529 if (fs != ft && (!std::isnan(fs) && !std::isnan(ft))) {
3393 set_fpu_register(fd_reg(), -1); 3530 SetFPUResult(fd_reg(), -1);
3394 } else { 3531 } else {
3395 set_fpu_register(fd_reg(), 0); 3532 SetFPUResult(fd_reg(), 0);
3396 } 3533 }
3397 break; 3534 break;
3398 default: 3535 default:
3399 UNREACHABLE(); 3536 UNREACHABLE();
3400 } 3537 }
3401 } 3538 }
3402 3539
3403 3540
3404 void Simulator::DecodeTypeRegisterCOP1() { 3541 void Simulator::DecodeTypeRegisterCOP1() {
3405 switch (instr_.RsFieldRaw()) { 3542 switch (instr_.RsFieldRaw()) {
3406 case CFC1: 3543 case CFC1:
3407 // At the moment only FCSR is supported. 3544 // At the moment only FCSR is supported.
3408 DCHECK(fs_reg() == kFCSRRegister); 3545 DCHECK(fs_reg() == kFCSRRegister);
3409 set_register(rt_reg(), FCSR_); 3546 SetResult(rt_reg(), FCSR_);
3410 break; 3547 break;
3411 case MFC1: 3548 case MFC1:
3412 set_register(rt_reg(), get_fpu_register_word(fs_reg())); 3549 SetResult(rt_reg(), get_fpu_register_word(fs_reg()));
3413 break; 3550 break;
3414 case MFHC1: 3551 case MFHC1:
3415 if (IsFp64Mode()) { 3552 if (IsFp64Mode()) {
3416 set_register(rt_reg(), get_fpu_register_hi_word(fs_reg())); 3553 SetResult(rt_reg(), get_fpu_register_hi_word(fs_reg()));
3417 } else { 3554 } else {
3418 set_register(rt_reg(), get_fpu_register_word(fs_reg() + 1)); 3555 SetResult(rt_reg(), get_fpu_register_word(fs_reg() + 1));
3419 } 3556 }
3420 break; 3557 break;
3421 case CTC1: { 3558 case CTC1: {
3422 // At the moment only FCSR is supported. 3559 // At the moment only FCSR is supported.
3423 DCHECK(fs_reg() == kFCSRRegister); 3560 DCHECK(fs_reg() == kFCSRRegister);
3424 int32_t reg = registers_[rt_reg()]; 3561 int32_t reg = registers_[rt_reg()];
3425 if (IsMipsArchVariant(kMips32r6)) { 3562 if (IsMipsArchVariant(kMips32r6)) {
3426 FCSR_ = reg | kFCSRNaN2008FlagMask; 3563 FCSR_ = reg | kFCSRNaN2008FlagMask;
3427 } else { 3564 } else {
3428 DCHECK(IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kMips32r2)); 3565 DCHECK(IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kMips32r2));
3429 FCSR_ = reg & ~kFCSRNaN2008FlagMask; 3566 FCSR_ = reg & ~kFCSRNaN2008FlagMask;
3430 } 3567 }
3568 TraceRegWr(static_cast<int32_t>(FCSR_));
3431 break; 3569 break;
3432 } 3570 }
3433 case MTC1: 3571 case MTC1:
3434 // Hardware writes upper 32-bits to zero on mtc1. 3572 // Hardware writes upper 32-bits to zero on mtc1.
3435 set_fpu_register_hi_word(fs_reg(), 0); 3573 set_fpu_register_hi_word(fs_reg(), 0);
3436 set_fpu_register_word(fs_reg(), registers_[rt_reg()]); 3574 set_fpu_register_word(fs_reg(), registers_[rt_reg()]);
3575 TraceRegWr(get_fpu_register_word(fs_reg()), FLOAT);
3437 break; 3576 break;
3438 case MTHC1: 3577 case MTHC1:
3439 if (IsFp64Mode()) { 3578 if (IsFp64Mode()) {
3440 set_fpu_register_hi_word(fs_reg(), registers_[rt_reg()]); 3579 set_fpu_register_hi_word(fs_reg(), registers_[rt_reg()]);
3580 TraceRegWr(get_fpu_register(fs_reg()), DOUBLE);
3441 } else { 3581 } else {
3442 set_fpu_register_word(fs_reg() + 1, registers_[rt_reg()]); 3582 set_fpu_register_word(fs_reg() + 1, registers_[rt_reg()]);
3583 if (fs_reg() % 2) {
3584 TraceRegWr(get_fpu_register_word(fs_reg() + 1), FLOAT);
3585 } else {
3586 TraceRegWr(get_fpu_register(fs_reg()), DOUBLE);
3587 }
3443 } 3588 }
3444 break; 3589 break;
3445 case S: { 3590 case S: {
3446 DecodeTypeRegisterSRsType(); 3591 DecodeTypeRegisterSRsType();
3447 break; 3592 break;
3448 } 3593 }
3449 case D: 3594 case D:
3450 DecodeTypeRegisterDRsType(); 3595 DecodeTypeRegisterDRsType();
3451 break; 3596 break;
3452 case W: 3597 case W:
(...skipping 12 matching lines...) Expand all
3465 3610
3466 3611
3467 void Simulator::DecodeTypeRegisterCOP1X() { 3612 void Simulator::DecodeTypeRegisterCOP1X() {
3468 switch (instr_.FunctionFieldRaw()) { 3613 switch (instr_.FunctionFieldRaw()) {
3469 case MADD_S: { 3614 case MADD_S: {
3470 DCHECK(IsMipsArchVariant(kMips32r2)); 3615 DCHECK(IsMipsArchVariant(kMips32r2));
3471 float fr, ft, fs; 3616 float fr, ft, fs;
3472 fr = get_fpu_register_float(fr_reg()); 3617 fr = get_fpu_register_float(fr_reg());
3473 fs = get_fpu_register_float(fs_reg()); 3618 fs = get_fpu_register_float(fs_reg());
3474 ft = get_fpu_register_float(ft_reg()); 3619 ft = get_fpu_register_float(ft_reg());
3475 set_fpu_register_float(fd_reg(), fs * ft + fr); 3620 SetFPUFloatResult(fd_reg(), fs * ft + fr);
3476 break; 3621 break;
3477 } 3622 }
3478 case MSUB_S: { 3623 case MSUB_S: {
3479 DCHECK(IsMipsArchVariant(kMips32r2)); 3624 DCHECK(IsMipsArchVariant(kMips32r2));
3480 float fr, ft, fs; 3625 float fr, ft, fs;
3481 fr = get_fpu_register_float(fr_reg()); 3626 fr = get_fpu_register_float(fr_reg());
3482 fs = get_fpu_register_float(fs_reg()); 3627 fs = get_fpu_register_float(fs_reg());
3483 ft = get_fpu_register_float(ft_reg()); 3628 ft = get_fpu_register_float(ft_reg());
3484 set_fpu_register_float(fd_reg(), fs * ft - fr); 3629 SetFPUFloatResult(fd_reg(), fs * ft - fr);
3485 break; 3630 break;
3486 } 3631 }
3487 case MADD_D: { 3632 case MADD_D: {
3488 DCHECK(IsMipsArchVariant(kMips32r2)); 3633 DCHECK(IsMipsArchVariant(kMips32r2));
3489 double fr, ft, fs; 3634 double fr, ft, fs;
3490 fr = get_fpu_register_double(fr_reg()); 3635 fr = get_fpu_register_double(fr_reg());
3491 fs = get_fpu_register_double(fs_reg()); 3636 fs = get_fpu_register_double(fs_reg());
3492 ft = get_fpu_register_double(ft_reg()); 3637 ft = get_fpu_register_double(ft_reg());
3493 set_fpu_register_double(fd_reg(), fs * ft + fr); 3638 SetFPUDoubleResult(fd_reg(), fs * ft + fr);
3494 break; 3639 break;
3495 } 3640 }
3496 case MSUB_D: { 3641 case MSUB_D: {
3497 DCHECK(IsMipsArchVariant(kMips32r2)); 3642 DCHECK(IsMipsArchVariant(kMips32r2));
3498 double fr, ft, fs; 3643 double fr, ft, fs;
3499 fr = get_fpu_register_double(fr_reg()); 3644 fr = get_fpu_register_double(fr_reg());
3500 fs = get_fpu_register_double(fs_reg()); 3645 fs = get_fpu_register_double(fs_reg());
3501 ft = get_fpu_register_double(ft_reg()); 3646 ft = get_fpu_register_double(ft_reg());
3502 set_fpu_register_double(fd_reg(), fs * ft - fr); 3647 SetFPUDoubleResult(fd_reg(), fs * ft - fr);
3503 break; 3648 break;
3504 } 3649 }
3505 default: 3650 default:
3506 UNREACHABLE(); 3651 UNREACHABLE();
3507 } 3652 }
3508 } 3653 }
3509 3654
3510 3655
3511 void Simulator::DecodeTypeRegisterSPECIAL() { 3656 void Simulator::DecodeTypeRegisterSPECIAL() {
3512 int64_t alu_out = 0x12345678; 3657 int64_t alu_out = 0x12345678;
3513 int64_t i64hilo = 0; 3658 int64_t i64hilo = 0;
3514 uint64_t u64hilo = 0; 3659 uint64_t u64hilo = 0;
3515 bool do_interrupt = false; 3660 bool do_interrupt = false;
3516 3661
3517 switch (instr_.FunctionFieldRaw()) { 3662 switch (instr_.FunctionFieldRaw()) {
3518 case SELEQZ_S: 3663 case SELEQZ_S:
3519 DCHECK(IsMipsArchVariant(kMips32r6)); 3664 DCHECK(IsMipsArchVariant(kMips32r6));
3520 set_register(rd_reg(), rt() == 0 ? rs() : 0); 3665 SetResult(rd_reg(), rt() == 0 ? rs() : 0);
3521 break; 3666 break;
3522 case SELNEZ_S: 3667 case SELNEZ_S:
3523 DCHECK(IsMipsArchVariant(kMips32r6)); 3668 DCHECK(IsMipsArchVariant(kMips32r6));
3524 set_register(rd_reg(), rt() != 0 ? rs() : 0); 3669 SetResult(rd_reg(), rt() != 0 ? rs() : 0);
3525 break; 3670 break;
3526 case JR: { 3671 case JR: {
3527 int32_t next_pc = rs(); 3672 int32_t next_pc = rs();
3528 int32_t current_pc = get_pc(); 3673 int32_t current_pc = get_pc();
3529 Instruction* branch_delay_instr = 3674 Instruction* branch_delay_instr =
3530 reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize); 3675 reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize);
3531 BranchDelayInstructionDecode(branch_delay_instr); 3676 BranchDelayInstructionDecode(branch_delay_instr);
3532 set_pc(next_pc); 3677 set_pc(next_pc);
3533 pc_modified_ = true; 3678 pc_modified_ = true;
3534 break; 3679 break;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
3615 break; 3760 break;
3616 // Instructions using HI and LO registers. 3761 // Instructions using HI and LO registers.
3617 case MULT: 3762 case MULT:
3618 i64hilo = static_cast<int64_t>(rs()) * static_cast<int64_t>(rt()); 3763 i64hilo = static_cast<int64_t>(rs()) * static_cast<int64_t>(rt());
3619 if (!IsMipsArchVariant(kMips32r6)) { 3764 if (!IsMipsArchVariant(kMips32r6)) {
3620 set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff)); 3765 set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff));
3621 set_register(HI, static_cast<int32_t>(i64hilo >> 32)); 3766 set_register(HI, static_cast<int32_t>(i64hilo >> 32));
3622 } else { 3767 } else {
3623 switch (sa()) { 3768 switch (sa()) {
3624 case MUL_OP: 3769 case MUL_OP:
3625 set_register(rd_reg(), static_cast<int32_t>(i64hilo & 0xffffffff)); 3770 SetResult(rd_reg(), static_cast<int32_t>(i64hilo & 0xffffffff));
3626 break; 3771 break;
3627 case MUH_OP: 3772 case MUH_OP:
3628 set_register(rd_reg(), static_cast<int32_t>(i64hilo >> 32)); 3773 SetResult(rd_reg(), static_cast<int32_t>(i64hilo >> 32));
3629 break; 3774 break;
3630 default: 3775 default:
3631 UNIMPLEMENTED_MIPS(); 3776 UNIMPLEMENTED_MIPS();
3632 break; 3777 break;
3633 } 3778 }
3634 } 3779 }
3635 break; 3780 break;
3636 case MULTU: 3781 case MULTU:
3637 u64hilo = static_cast<uint64_t>(rs_u()) * static_cast<uint64_t>(rt_u()); 3782 u64hilo = static_cast<uint64_t>(rs_u()) * static_cast<uint64_t>(rt_u());
3638 if (!IsMipsArchVariant(kMips32r6)) { 3783 if (!IsMipsArchVariant(kMips32r6)) {
3639 set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff)); 3784 set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff));
3640 set_register(HI, static_cast<int32_t>(u64hilo >> 32)); 3785 set_register(HI, static_cast<int32_t>(u64hilo >> 32));
3641 } else { 3786 } else {
3642 switch (sa()) { 3787 switch (sa()) {
3643 case MUL_OP: 3788 case MUL_OP:
3644 set_register(rd_reg(), static_cast<int32_t>(u64hilo & 0xffffffff)); 3789 SetResult(rd_reg(), static_cast<int32_t>(u64hilo & 0xffffffff));
3645 break; 3790 break;
3646 case MUH_OP: 3791 case MUH_OP:
3647 set_register(rd_reg(), static_cast<int32_t>(u64hilo >> 32)); 3792 SetResult(rd_reg(), static_cast<int32_t>(u64hilo >> 32));
3648 break; 3793 break;
3649 default: 3794 default:
3650 UNIMPLEMENTED_MIPS(); 3795 UNIMPLEMENTED_MIPS();
3651 break; 3796 break;
3652 } 3797 }
3653 } 3798 }
3654 break; 3799 break;
3655 case DIV: 3800 case DIV:
3656 if (IsMipsArchVariant(kMips32r6)) { 3801 if (IsMipsArchVariant(kMips32r6)) {
3657 switch (sa()) { 3802 switch (sa()) {
3658 case DIV_OP: 3803 case DIV_OP:
3659 if (rs() == INT_MIN && rt() == -1) { 3804 if (rs() == INT_MIN && rt() == -1) {
3660 set_register(rd_reg(), INT_MIN); 3805 SetResult(rd_reg(), INT_MIN);
3661 } else if (rt() != 0) { 3806 } else if (rt() != 0) {
3662 set_register(rd_reg(), rs() / rt()); 3807 SetResult(rd_reg(), rs() / rt());
3663 } 3808 }
3664 break; 3809 break;
3665 case MOD_OP: 3810 case MOD_OP:
3666 if (rs() == INT_MIN && rt() == -1) { 3811 if (rs() == INT_MIN && rt() == -1) {
3667 set_register(rd_reg(), 0); 3812 SetResult(rd_reg(), 0);
3668 } else if (rt() != 0) { 3813 } else if (rt() != 0) {
3669 set_register(rd_reg(), rs() % rt()); 3814 SetResult(rd_reg(), rs() % rt());
3670 } 3815 }
3671 break; 3816 break;
3672 default: 3817 default:
3673 UNIMPLEMENTED_MIPS(); 3818 UNIMPLEMENTED_MIPS();
3674 break; 3819 break;
3675 } 3820 }
3676 } else { 3821 } else {
3677 // Divide by zero and overflow was not checked in the 3822 // Divide by zero and overflow was not checked in the
3678 // configuration step - div and divu do not raise exceptions. On 3823 // configuration step - div and divu do not raise exceptions. On
3679 // division by 0 the result will be UNPREDICTABLE. On overflow 3824 // division by 0 the result will be UNPREDICTABLE. On overflow
3680 // (INT_MIN/-1), return INT_MIN which is what the hardware does. 3825 // (INT_MIN/-1), return INT_MIN which is what the hardware does.
3681 if (rs() == INT_MIN && rt() == -1) { 3826 if (rs() == INT_MIN && rt() == -1) {
3682 set_register(LO, INT_MIN); 3827 set_register(LO, INT_MIN);
3683 set_register(HI, 0); 3828 set_register(HI, 0);
3684 } else if (rt() != 0) { 3829 } else if (rt() != 0) {
3685 set_register(LO, rs() / rt()); 3830 set_register(LO, rs() / rt());
3686 set_register(HI, rs() % rt()); 3831 set_register(HI, rs() % rt());
3687 } 3832 }
3688 } 3833 }
3689 break; 3834 break;
3690 case DIVU: 3835 case DIVU:
3691 if (IsMipsArchVariant(kMips32r6)) { 3836 if (IsMipsArchVariant(kMips32r6)) {
3692 switch (sa()) { 3837 switch (sa()) {
3693 case DIV_OP: 3838 case DIV_OP:
3694 if (rt_u() != 0) { 3839 if (rt_u() != 0) {
3695 set_register(rd_reg(), rs_u() / rt_u()); 3840 SetResult(rd_reg(), rs_u() / rt_u());
3696 } 3841 }
3697 break; 3842 break;
3698 case MOD_OP: 3843 case MOD_OP:
3699 if (rt_u() != 0) { 3844 if (rt_u() != 0) {
3700 set_register(rd_reg(), rs_u() % rt_u()); 3845 SetResult(rd_reg(), rs_u() % rt_u());
3701 } 3846 }
3702 break; 3847 break;
3703 default: 3848 default:
3704 UNIMPLEMENTED_MIPS(); 3849 UNIMPLEMENTED_MIPS();
3705 break; 3850 break;
3706 } 3851 }
3707 } else { 3852 } else {
3708 if (rt_u() != 0) { 3853 if (rt_u() != 0) {
3709 set_register(LO, rs_u() / rt_u()); 3854 set_register(LO, rs_u() / rt_u());
3710 set_register(HI, rs_u() % rt_u()); 3855 set_register(HI, rs_u() % rt_u());
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
3784 break; 3929 break;
3785 case TNE: 3930 case TNE:
3786 do_interrupt = rs() != rt(); 3931 do_interrupt = rs() != rt();
3787 break; 3932 break;
3788 case SYNC: 3933 case SYNC:
3789 // TODO(palfia): Ignore sync instruction for now. 3934 // TODO(palfia): Ignore sync instruction for now.
3790 break; 3935 break;
3791 // Conditional moves. 3936 // Conditional moves.
3792 case MOVN: 3937 case MOVN:
3793 if (rt()) { 3938 if (rt()) {
3794 set_register(rd_reg(), rs()); 3939 SetResult(rd_reg(), rs());
3795 TraceRegWr(rs());
3796 } 3940 }
3797 break; 3941 break;
3798 case MOVCI: { 3942 case MOVCI: {
3799 uint32_t cc = instr_.FBccValue(); 3943 uint32_t cc = instr_.FBccValue();
3800 uint32_t fcsr_cc = get_fcsr_condition_bit(cc); 3944 uint32_t fcsr_cc = get_fcsr_condition_bit(cc);
3801 if (instr_.Bit(16)) { // Read Tf bit. 3945 if (instr_.Bit(16)) { // Read Tf bit.
3802 if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs()); 3946 if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs());
3803 } else { 3947 } else {
3804 if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs()); 3948 if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs());
3805 } 3949 }
3806 break; 3950 break;
3807 } 3951 }
3808 case MOVZ: 3952 case MOVZ:
3809 if (!rt()) { 3953 if (!rt()) {
3810 set_register(rd_reg(), rs()); 3954 SetResult(rd_reg(), rs());
3811 TraceRegWr(rs());
3812 } 3955 }
3813 break; 3956 break;
3814 default: 3957 default:
3815 UNREACHABLE(); 3958 UNREACHABLE();
3816 } 3959 }
3817 if (do_interrupt) { 3960 if (do_interrupt) {
3818 SoftwareInterrupt(); 3961 SoftwareInterrupt();
3819 } 3962 }
3820 } 3963 }
3821 3964
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
4365 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask; 4508 uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
4366 uint32_t mask = (1 << al_offset * 8) - 1; 4509 uint32_t mask = (1 << al_offset * 8) - 1;
4367 addr = rs + se_imm16 - al_offset; 4510 addr = rs + se_imm16 - al_offset;
4368 uint32_t mem_value = ReadW(addr, instr_.instr()); 4511 uint32_t mem_value = ReadW(addr, instr_.instr());
4369 mem_value = (rt << al_offset * 8) | (mem_value & mask); 4512 mem_value = (rt << al_offset * 8) | (mem_value & mask);
4370 WriteW(addr, mem_value, instr_.instr()); 4513 WriteW(addr, mem_value, instr_.instr());
4371 break; 4514 break;
4372 } 4515 }
4373 case LWC1: 4516 case LWC1:
4374 set_fpu_register_hi_word(ft_reg, 0); 4517 set_fpu_register_hi_word(ft_reg, 0);
4375 set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr_.instr())); 4518 set_fpu_register_word(ft_reg,
4519 ReadW(rs + se_imm16, instr_.instr(), FLOAT));
4520 if (ft_reg % 2) {
4521 TraceMemRd(rs + se_imm16, get_fpu_register(ft_reg - 1), FLOAT_DOUBLE);
4522 } else {
4523 TraceMemRd(rs + se_imm16, get_fpu_register_word(ft_reg), FLOAT);
4524 }
4376 break; 4525 break;
4377 case LDC1: 4526 case LDC1:
4378 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr_.instr())); 4527 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr_.instr()));
4528 TraceMemRd(rs + se_imm16, get_fpu_register(ft_reg), DOUBLE);
4379 break; 4529 break;
4380 case SWC1: 4530 case SWC1:
4381 WriteW(rs + se_imm16, get_fpu_register_word(ft_reg), instr_.instr()); 4531 WriteW(rs + se_imm16, get_fpu_register_word(ft_reg), instr_.instr());
4532 TraceMemWr(rs + se_imm16, get_fpu_register_word(ft_reg));
4382 break; 4533 break;
4383 case SDC1: 4534 case SDC1:
4384 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr_.instr()); 4535 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr_.instr());
4536 TraceMemWr(rs + se_imm16, get_fpu_register(ft_reg));
4385 break; 4537 break;
4386 // ------------- PC-Relative instructions. 4538 // ------------- PC-Relative instructions.
4387 case PCREL: { 4539 case PCREL: {
4388 // rt field: checking 5-bits. 4540 // rt field: checking 5-bits.
4389 int32_t imm21 = instr_.Imm21Value(); 4541 int32_t imm21 = instr_.Imm21Value();
4390 int32_t current_pc = get_pc(); 4542 int32_t current_pc = get_pc();
4391 uint8_t rt = (imm21 >> kImm16Bits); 4543 uint8_t rt = (imm21 >> kImm16Bits);
4392 switch (rt) { 4544 switch (rt) {
4393 case ALUIPC: 4545 case ALUIPC:
4394 addr = current_pc + (se_imm16 << 16); 4546 addr = current_pc + (se_imm16 << 16);
(...skipping 20 matching lines...) Expand all
4415 int32_t se_imm19 = imm19 | ((imm19 & 0x40000) ? 0xfff80000 : 0); 4567 int32_t se_imm19 = imm19 | ((imm19 & 0x40000) ? 0xfff80000 : 0);
4416 alu_out = current_pc + (se_imm19 << 2); 4568 alu_out = current_pc + (se_imm19 << 2);
4417 break; 4569 break;
4418 } 4570 }
4419 default: 4571 default:
4420 UNREACHABLE(); 4572 UNREACHABLE();
4421 break; 4573 break;
4422 } 4574 }
4423 } 4575 }
4424 } 4576 }
4425 set_register(rs_reg, alu_out); 4577 SetResult(rs_reg, alu_out);
4426 break; 4578 break;
4427 } 4579 }
4428 default: 4580 default:
4429 UNREACHABLE(); 4581 UNREACHABLE();
4430 } 4582 }
4431 4583
4432 if (execute_branch_delay_instruction) { 4584 if (execute_branch_delay_instruction) {
4433 // Execute branch delay slot 4585 // Execute branch delay slot
4434 // We don't check for end_sim_pc. First it should not be met as the current 4586 // 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. 4587 // 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
4694 4846
4695 4847
4696 #undef UNSUPPORTED 4848 #undef UNSUPPORTED
4697 4849
4698 } // namespace internal 4850 } // namespace internal
4699 } // namespace v8 4851 } // namespace v8
4700 4852
4701 #endif // USE_SIMULATOR 4853 #endif // USE_SIMULATOR
4702 4854
4703 #endif // V8_TARGET_ARCH_MIPS 4855 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/simulator-mips.h ('k') | src/mips64/simulator-mips64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698