OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <limits.h> | 5 #include <limits.h> |
6 #include <stdarg.h> | 6 #include <stdarg.h> |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #if V8_TARGET_ARCH_MIPS64 | 10 #if V8_TARGET_ARCH_MIPS64 |
(...skipping 1608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1619 // TODO(plind): refactor this messy debug code when we do unaligned access. | 1619 // TODO(plind): refactor this messy debug code when we do unaligned access. |
1620 void Simulator::DieOrDebug() { | 1620 void Simulator::DieOrDebug() { |
1621 if (1) { // Flag for this was removed. | 1621 if (1) { // Flag for this was removed. |
1622 MipsDebugger dbg(this); | 1622 MipsDebugger dbg(this); |
1623 dbg.Debug(); | 1623 dbg.Debug(); |
1624 } else { | 1624 } else { |
1625 base::OS::Abort(); | 1625 base::OS::Abort(); |
1626 } | 1626 } |
1627 } | 1627 } |
1628 | 1628 |
| 1629 void Simulator::TraceRegWr(int64_t value, TraceType t) { |
| 1630 if (::v8::internal::FLAG_trace_sim) { |
| 1631 union { |
| 1632 int64_t fmt_int64; |
| 1633 int32_t fmt_int32[2]; |
| 1634 float fmt_float[2]; |
| 1635 double fmt_double; |
| 1636 } v; |
| 1637 v.fmt_int64 = value; |
1629 | 1638 |
1630 void Simulator::TraceRegWr(int64_t value) { | 1639 switch (t) { |
1631 if (::v8::internal::FLAG_trace_sim) { | 1640 case WORD: |
1632 SNPrintF(trace_buf_, "%016" PRIx64 " ", value); | 1641 SNPrintF(trace_buf_, "%016" PRIx64 " (%" PRId64 ") int32:%" PRId32 |
| 1642 " uint32:%" PRIu32, |
| 1643 v.fmt_int64, icount_, v.fmt_int32[0], v.fmt_int32[0]); |
| 1644 break; |
| 1645 case DWORD: |
| 1646 SNPrintF(trace_buf_, "%016" PRIx64 " (%" PRId64 ") int64:%" PRId64 |
| 1647 " uint64:%" PRIu64, |
| 1648 value, icount_, value, value); |
| 1649 break; |
| 1650 case FLOAT: |
| 1651 SNPrintF(trace_buf_, "%016" PRIx64 " (%" PRId64 ") flt:%e", |
| 1652 v.fmt_int64, icount_, v.fmt_float[0]); |
| 1653 break; |
| 1654 case DOUBLE: |
| 1655 SNPrintF(trace_buf_, "%016" PRIx64 " (%" PRId64 ") dbl:%e", |
| 1656 v.fmt_int64, icount_, v.fmt_double); |
| 1657 break; |
| 1658 case FLOAT_DOUBLE: |
| 1659 SNPrintF(trace_buf_, "%016" PRIx64 " (%" PRId64 ") flt:%e dbl:%e", |
| 1660 v.fmt_int64, icount_, v.fmt_float[0], v.fmt_double); |
| 1661 break; |
| 1662 case WORD_DWORD: |
| 1663 SNPrintF(trace_buf_, |
| 1664 "%016" PRIx64 " (%" PRId64 ") int32:%" PRId32 |
| 1665 " uint32:%" PRIu32 " int64:%" PRId64 " uint64:%" PRIu64, |
| 1666 v.fmt_int64, icount_, v.fmt_int32[0], v.fmt_int32[0], |
| 1667 v.fmt_int64, v.fmt_int64); |
| 1668 break; |
| 1669 default: |
| 1670 UNREACHABLE(); |
| 1671 } |
1633 } | 1672 } |
1634 } | 1673 } |
1635 | 1674 |
| 1675 // TODO(plind): consider making icount_ printing a flag option. |
| 1676 void Simulator::TraceMemRd(int64_t addr, int64_t value, TraceType t) { |
| 1677 if (::v8::internal::FLAG_trace_sim) { |
| 1678 union { |
| 1679 int64_t fmt_int64; |
| 1680 int32_t fmt_int32[2]; |
| 1681 float fmt_float[2]; |
| 1682 double fmt_double; |
| 1683 } v; |
| 1684 v.fmt_int64 = value; |
1636 | 1685 |
1637 // TODO(plind): consider making icount_ printing a flag option. | 1686 switch (t) { |
1638 void Simulator::TraceMemRd(int64_t addr, int64_t value) { | 1687 case WORD: |
1639 if (::v8::internal::FLAG_trace_sim) { | 1688 SNPrintF(trace_buf_, "%016" PRIx64 " <-- [%016" PRIx64 "] (%" PRId64 |
1640 SNPrintF(trace_buf_, | 1689 ") int32:%" PRId32 " uint32:%" PRIu32, |
1641 "%016" PRIx64 " <-- [%016" PRIx64 " ] (%" PRId64 " )", value, | 1690 v.fmt_int64, addr, icount_, v.fmt_int32[0], v.fmt_int32[0]); |
1642 addr, icount_); | 1691 break; |
| 1692 case DWORD: |
| 1693 SNPrintF(trace_buf_, "%016" PRIx64 " <-- [%016" PRIx64 "] (%" PRId64 |
| 1694 ") int64:%" PRId64 " uint64:%" PRIu64, |
| 1695 value, addr, icount_, value, value); |
| 1696 break; |
| 1697 case FLOAT: |
| 1698 SNPrintF(trace_buf_, "%016" PRIx64 " <-- [%016" PRIx64 "] (%" PRId64 |
| 1699 ") flt:%e", |
| 1700 v.fmt_int64, addr, icount_, v.fmt_float[0]); |
| 1701 break; |
| 1702 case DOUBLE: |
| 1703 SNPrintF(trace_buf_, "%016" PRIx64 " <-- [%016" PRIx64 "] (%" PRId64 |
| 1704 ") dbl:%e", |
| 1705 v.fmt_int64, addr, icount_, v.fmt_double); |
| 1706 break; |
| 1707 case FLOAT_DOUBLE: |
| 1708 SNPrintF(trace_buf_, "%016" PRIx64 " <-- [%016" PRIx64 "] (%" PRId64 |
| 1709 ") flt:%e dbl:%e", |
| 1710 v.fmt_int64, addr, icount_, v.fmt_float[0], v.fmt_double); |
| 1711 break; |
| 1712 default: |
| 1713 UNREACHABLE(); |
| 1714 } |
1643 } | 1715 } |
1644 } | 1716 } |
1645 | 1717 |
1646 | 1718 |
1647 void Simulator::TraceMemWr(int64_t addr, int64_t value, TraceType t) { | 1719 void Simulator::TraceMemWr(int64_t addr, int64_t value, TraceType t) { |
1648 if (::v8::internal::FLAG_trace_sim) { | 1720 if (::v8::internal::FLAG_trace_sim) { |
1649 switch (t) { | 1721 switch (t) { |
1650 case BYTE: | 1722 case BYTE: |
1651 SNPrintF(trace_buf_, " %02x --> [%016" PRIx64 " ]", | 1723 SNPrintF(trace_buf_, " %02" PRIx8 " --> [%016" PRIx64 |
1652 static_cast<int8_t>(value), addr); | 1724 "] (%" PRId64 ")", |
| 1725 static_cast<uint8_t>(value), addr, icount_); |
1653 break; | 1726 break; |
1654 case HALF: | 1727 case HALF: |
1655 SNPrintF(trace_buf_, " %04x --> [%016" PRIx64 " ]", | 1728 SNPrintF(trace_buf_, " %04" PRIx16 " --> [%016" PRIx64 |
1656 static_cast<int16_t>(value), addr); | 1729 "] (%" PRId64 ")", |
| 1730 static_cast<uint16_t>(value), addr, icount_); |
1657 break; | 1731 break; |
1658 case WORD: | 1732 case WORD: |
1659 SNPrintF(trace_buf_, " %08x --> [%016" PRIx64 " ]", | 1733 SNPrintF(trace_buf_, |
1660 static_cast<int32_t>(value), addr); | 1734 " %08" PRIx32 " --> [%016" PRIx64 "] (%" PRId64 ")", |
| 1735 static_cast<uint32_t>(value), addr, icount_); |
1661 break; | 1736 break; |
1662 case DWORD: | 1737 case DWORD: |
1663 SNPrintF(trace_buf_, | 1738 SNPrintF(trace_buf_, |
1664 "%016" PRIx64 " --> [%016" PRIx64 " ] (%" PRId64 " )", | 1739 "%016" PRIx64 " --> [%016" PRIx64 "] (%" PRId64 " )", |
1665 value, addr, icount_); | 1740 value, addr, icount_); |
1666 break; | 1741 break; |
| 1742 default: |
| 1743 UNREACHABLE(); |
1667 } | 1744 } |
1668 } | 1745 } |
1669 } | 1746 } |
1670 | 1747 |
1671 | 1748 |
1672 // TODO(plind): sign-extend and zero-extend not implmented properly | 1749 // TODO(plind): sign-extend and zero-extend not implmented properly |
1673 // on all the ReadXX functions, I don't think re-interpret cast does it. | 1750 // on all the ReadXX functions, I don't think re-interpret cast does it. |
1674 int32_t Simulator::ReadW(int64_t addr, Instruction* instr) { | 1751 int32_t Simulator::ReadW(int64_t addr, Instruction* instr, TraceType t) { |
1675 if (addr >=0 && addr < 0x400) { | 1752 if (addr >=0 && addr < 0x400) { |
1676 // This has to be a NULL-dereference, drop into debugger. | 1753 // This has to be a NULL-dereference, drop into debugger. |
1677 PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR | 1754 PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR |
1678 " \n", | 1755 " \n", |
1679 addr, reinterpret_cast<intptr_t>(instr)); | 1756 addr, reinterpret_cast<intptr_t>(instr)); |
1680 DieOrDebug(); | 1757 DieOrDebug(); |
1681 } | 1758 } |
1682 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { | 1759 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { |
1683 int32_t* ptr = reinterpret_cast<int32_t*>(addr); | 1760 int32_t* ptr = reinterpret_cast<int32_t*>(addr); |
1684 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1761 TraceMemRd(addr, static_cast<int64_t>(*ptr), t); |
1685 return *ptr; | 1762 return *ptr; |
1686 } | 1763 } |
1687 PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, | 1764 PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, |
1688 reinterpret_cast<intptr_t>(instr)); | 1765 reinterpret_cast<intptr_t>(instr)); |
1689 DieOrDebug(); | 1766 DieOrDebug(); |
1690 return 0; | 1767 return 0; |
1691 } | 1768 } |
1692 | 1769 |
1693 | 1770 |
1694 uint32_t Simulator::ReadWU(int64_t addr, Instruction* instr) { | 1771 uint32_t Simulator::ReadWU(int64_t addr, Instruction* instr) { |
1695 if (addr >=0 && addr < 0x400) { | 1772 if (addr >=0 && addr < 0x400) { |
1696 // This has to be a NULL-dereference, drop into debugger. | 1773 // This has to be a NULL-dereference, drop into debugger. |
1697 PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR | 1774 PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR |
1698 " \n", | 1775 " \n", |
1699 addr, reinterpret_cast<intptr_t>(instr)); | 1776 addr, reinterpret_cast<intptr_t>(instr)); |
1700 DieOrDebug(); | 1777 DieOrDebug(); |
1701 } | 1778 } |
1702 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { | 1779 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { |
1703 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); | 1780 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); |
1704 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1781 TraceMemRd(addr, static_cast<int64_t>(*ptr), WORD); |
1705 return *ptr; | 1782 return *ptr; |
1706 } | 1783 } |
1707 PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, | 1784 PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, |
1708 reinterpret_cast<intptr_t>(instr)); | 1785 reinterpret_cast<intptr_t>(instr)); |
1709 DieOrDebug(); | 1786 DieOrDebug(); |
1710 return 0; | 1787 return 0; |
1711 } | 1788 } |
1712 | 1789 |
1713 | 1790 |
1714 void Simulator::WriteW(int64_t addr, int32_t value, Instruction* instr) { | 1791 void Simulator::WriteW(int64_t addr, int32_t value, Instruction* instr) { |
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2448 case kRoundToZero: | 2525 case kRoundToZero: |
2449 result = (fs > 0 ? lower : upper); | 2526 result = (fs > 0 ? lower : upper); |
2450 break; | 2527 break; |
2451 case kRoundToPlusInf: | 2528 case kRoundToPlusInf: |
2452 result = upper; | 2529 result = upper; |
2453 break; | 2530 break; |
2454 case kRoundToMinusInf: | 2531 case kRoundToMinusInf: |
2455 result = lower; | 2532 result = lower; |
2456 break; | 2533 break; |
2457 } | 2534 } |
2458 set_fpu_register_float(fd_reg(), result); | 2535 SetFPUFloatResult(fd_reg(), result); |
2459 if (result != fs) { | 2536 if (result != fs) { |
2460 set_fcsr_bit(kFCSRInexactFlagBit, true); | 2537 set_fcsr_bit(kFCSRInexactFlagBit, true); |
2461 } | 2538 } |
2462 break; | 2539 break; |
2463 } | 2540 } |
2464 case ADD_S: | 2541 case ADD_S: |
2465 set_fpu_register_float( | 2542 SetFPUFloatResult( |
2466 fd_reg(), | 2543 fd_reg(), |
2467 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs + rhs; }, | 2544 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs + rhs; }, |
2468 fs, ft)); | 2545 fs, ft)); |
2469 break; | 2546 break; |
2470 case SUB_S: | 2547 case SUB_S: |
2471 set_fpu_register_float( | 2548 SetFPUFloatResult( |
2472 fd_reg(), | 2549 fd_reg(), |
2473 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs - rhs; }, | 2550 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs - rhs; }, |
2474 fs, ft)); | 2551 fs, ft)); |
2475 break; | 2552 break; |
2476 case MADDF_S: | 2553 case MADDF_S: |
2477 DCHECK(kArchVariant == kMips64r6); | 2554 DCHECK(kArchVariant == kMips64r6); |
2478 set_fpu_register_float(fd_reg(), std::fma(fs, ft, fd)); | 2555 SetFPUFloatResult(fd_reg(), std::fma(fs, ft, fd)); |
2479 break; | 2556 break; |
2480 case MSUBF_S: | 2557 case MSUBF_S: |
2481 DCHECK(kArchVariant == kMips64r6); | 2558 DCHECK(kArchVariant == kMips64r6); |
2482 set_fpu_register_float(fd_reg(), std::fma(-fs, ft, fd)); | 2559 SetFPUFloatResult(fd_reg(), std::fma(-fs, ft, fd)); |
2483 break; | 2560 break; |
2484 case MUL_S: | 2561 case MUL_S: |
2485 set_fpu_register_float( | 2562 SetFPUFloatResult( |
2486 fd_reg(), | 2563 fd_reg(), |
2487 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs * rhs; }, | 2564 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs * rhs; }, |
2488 fs, ft)); | 2565 fs, ft)); |
2489 break; | 2566 break; |
2490 case DIV_S: | 2567 case DIV_S: |
2491 set_fpu_register_float( | 2568 SetFPUFloatResult( |
2492 fd_reg(), | 2569 fd_reg(), |
2493 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs / rhs; }, | 2570 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs / rhs; }, |
2494 fs, ft)); | 2571 fs, ft)); |
2495 break; | 2572 break; |
2496 case ABS_S: | 2573 case ABS_S: |
2497 set_fpu_register_float( | 2574 SetFPUFloatResult(fd_reg(), FPUCanonalizeOperation( |
2498 fd_reg(), | 2575 [](float fs) { return FPAbs(fs); }, fs)); |
2499 FPUCanonalizeOperation([](float fs) { return FPAbs(fs); }, fs)); | |
2500 break; | 2576 break; |
2501 case MOV_S: | 2577 case MOV_S: |
2502 set_fpu_register_float(fd_reg(), fs); | 2578 SetFPUFloatResult(fd_reg(), fs); |
2503 break; | 2579 break; |
2504 case NEG_S: | 2580 case NEG_S: |
2505 set_fpu_register_float( | 2581 SetFPUFloatResult(fd_reg(), |
2506 fd_reg(), FPUCanonalizeOperation([](float src) { return -src; }, | 2582 FPUCanonalizeOperation([](float src) { return -src; }, |
2507 KeepSign::yes, fs)); | 2583 KeepSign::yes, fs)); |
2508 break; | 2584 break; |
2509 case SQRT_S: | 2585 case SQRT_S: |
2510 set_fpu_register_float( | 2586 SetFPUFloatResult( |
2511 fd_reg(), | 2587 fd_reg(), |
2512 FPUCanonalizeOperation([](float src) { return std::sqrt(src); }, fs)); | 2588 FPUCanonalizeOperation([](float src) { return std::sqrt(src); }, fs)); |
2513 break; | 2589 break; |
2514 case RSQRT_S: | 2590 case RSQRT_S: |
2515 set_fpu_register_float( | 2591 SetFPUFloatResult( |
2516 fd_reg(), FPUCanonalizeOperation( | 2592 fd_reg(), FPUCanonalizeOperation( |
2517 [](float src) { return 1.0 / std::sqrt(src); }, fs)); | 2593 [](float src) { return 1.0 / std::sqrt(src); }, fs)); |
2518 break; | 2594 break; |
2519 case RECIP_S: | 2595 case RECIP_S: |
2520 set_fpu_register_float( | 2596 SetFPUFloatResult(fd_reg(), FPUCanonalizeOperation( |
2521 fd_reg(), | 2597 [](float src) { return 1.0 / src; }, fs)); |
2522 FPUCanonalizeOperation([](float src) { return 1.0 / src; }, fs)); | |
2523 break; | 2598 break; |
2524 case C_F_D: | 2599 case C_F_D: |
2525 set_fcsr_bit(fcsr_cc, false); | 2600 set_fcsr_bit(fcsr_cc, false); |
| 2601 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
2526 break; | 2602 break; |
2527 case C_UN_D: | 2603 case C_UN_D: |
2528 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); | 2604 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); |
| 2605 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
2529 break; | 2606 break; |
2530 case C_EQ_D: | 2607 case C_EQ_D: |
2531 set_fcsr_bit(fcsr_cc, (fs == ft)); | 2608 set_fcsr_bit(fcsr_cc, (fs == ft)); |
| 2609 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
2532 break; | 2610 break; |
2533 case C_UEQ_D: | 2611 case C_UEQ_D: |
2534 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); | 2612 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); |
| 2613 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
2535 break; | 2614 break; |
2536 case C_OLT_D: | 2615 case C_OLT_D: |
2537 set_fcsr_bit(fcsr_cc, (fs < ft)); | 2616 set_fcsr_bit(fcsr_cc, (fs < ft)); |
| 2617 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
2538 break; | 2618 break; |
2539 case C_ULT_D: | 2619 case C_ULT_D: |
2540 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); | 2620 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); |
| 2621 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
2541 break; | 2622 break; |
2542 case C_OLE_D: | 2623 case C_OLE_D: |
2543 set_fcsr_bit(fcsr_cc, (fs <= ft)); | 2624 set_fcsr_bit(fcsr_cc, (fs <= ft)); |
| 2625 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
2544 break; | 2626 break; |
2545 case C_ULE_D: | 2627 case C_ULE_D: |
2546 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); | 2628 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); |
| 2629 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
2547 break; | 2630 break; |
2548 case CVT_D_S: | 2631 case CVT_D_S: |
2549 set_fpu_register_double(fd_reg(), static_cast<double>(fs)); | 2632 SetFPUDoubleResult(fd_reg(), static_cast<double>(fs)); |
2550 break; | 2633 break; |
2551 case CLASS_S: { // Mips64r6 instruction | 2634 case CLASS_S: { // Mips64r6 instruction |
2552 // Convert float input to uint32_t for easier bit manipulation | 2635 // Convert float input to uint32_t for easier bit manipulation |
2553 uint32_t classed = bit_cast<uint32_t>(fs); | 2636 uint32_t classed = bit_cast<uint32_t>(fs); |
2554 | 2637 |
2555 // Extracting sign, exponent and mantissa from the input float | 2638 // Extracting sign, exponent and mantissa from the input float |
2556 uint32_t sign = (classed >> 31) & 1; | 2639 uint32_t sign = (classed >> 31) & 1; |
2557 uint32_t exponent = (classed >> 23) & 0x000000ff; | 2640 uint32_t exponent = (classed >> 23) & 0x000000ff; |
2558 uint32_t mantissa = classed & 0x007fffff; | 2641 uint32_t mantissa = classed & 0x007fffff; |
2559 uint32_t result; | 2642 uint32_t result; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2602 } | 2685 } |
2603 | 2686 |
2604 // Calculating result according to description of CLASS.S instruction | 2687 // Calculating result according to description of CLASS.S instruction |
2605 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | | 2688 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | |
2606 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | | 2689 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | |
2607 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; | 2690 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; |
2608 | 2691 |
2609 DCHECK(result != 0); | 2692 DCHECK(result != 0); |
2610 | 2693 |
2611 fResult = bit_cast<float>(result); | 2694 fResult = bit_cast<float>(result); |
2612 set_fpu_register_float(fd_reg(), fResult); | 2695 SetFPUFloatResult(fd_reg(), fResult); |
2613 | |
2614 break; | 2696 break; |
2615 } | 2697 } |
2616 case CVT_L_S: { | 2698 case CVT_L_S: { |
2617 float rounded; | 2699 float rounded; |
2618 int64_t result; | 2700 int64_t result; |
2619 round64_according_to_fcsr(fs, rounded, result, fs); | 2701 round64_according_to_fcsr(fs, rounded, result, fs); |
2620 set_fpu_register(fd_reg(), result); | 2702 SetFPUResult(fd_reg(), result); |
2621 if (set_fcsr_round64_error(fs, rounded)) { | 2703 if (set_fcsr_round64_error(fs, rounded)) { |
2622 set_fpu_register_invalid_result64(fs, rounded); | 2704 set_fpu_register_invalid_result64(fs, rounded); |
2623 } | 2705 } |
2624 break; | 2706 break; |
2625 } | 2707 } |
2626 case CVT_W_S: { | 2708 case CVT_W_S: { |
2627 float rounded; | 2709 float rounded; |
2628 int32_t result; | 2710 int32_t result; |
2629 round_according_to_fcsr(fs, rounded, result, fs); | 2711 round_according_to_fcsr(fs, rounded, result, fs); |
2630 set_fpu_register_word(fd_reg(), result); | 2712 SetFPUWordResult(fd_reg(), result); |
2631 if (set_fcsr_round_error(fs, rounded)) { | 2713 if (set_fcsr_round_error(fs, rounded)) { |
2632 set_fpu_register_word_invalid_result(fs, rounded); | 2714 set_fpu_register_word_invalid_result(fs, rounded); |
2633 } | 2715 } |
2634 break; | 2716 break; |
2635 } | 2717 } |
2636 case TRUNC_W_S: { // Truncate single to word (round towards 0). | 2718 case TRUNC_W_S: { // Truncate single to word (round towards 0). |
2637 float rounded = trunc(fs); | 2719 float rounded = trunc(fs); |
2638 int32_t result = static_cast<int32_t>(rounded); | 2720 int32_t result = static_cast<int32_t>(rounded); |
2639 set_fpu_register_word(fd_reg(), result); | 2721 SetFPUWordResult(fd_reg(), result); |
2640 if (set_fcsr_round_error(fs, rounded)) { | 2722 if (set_fcsr_round_error(fs, rounded)) { |
2641 set_fpu_register_word_invalid_result(fs, rounded); | 2723 set_fpu_register_word_invalid_result(fs, rounded); |
2642 } | 2724 } |
2643 } break; | 2725 } break; |
2644 case TRUNC_L_S: { // Mips64r2 instruction. | 2726 case TRUNC_L_S: { // Mips64r2 instruction. |
2645 float rounded = trunc(fs); | 2727 float rounded = trunc(fs); |
2646 int64_t result = static_cast<int64_t>(rounded); | 2728 int64_t result = static_cast<int64_t>(rounded); |
2647 set_fpu_register(fd_reg(), result); | 2729 SetFPUResult(fd_reg(), result); |
2648 if (set_fcsr_round64_error(fs, rounded)) { | 2730 if (set_fcsr_round64_error(fs, rounded)) { |
2649 set_fpu_register_invalid_result64(fs, rounded); | 2731 set_fpu_register_invalid_result64(fs, rounded); |
2650 } | 2732 } |
2651 break; | 2733 break; |
2652 } | 2734 } |
2653 case ROUND_W_S: { | 2735 case ROUND_W_S: { |
2654 float rounded = std::floor(fs + 0.5); | 2736 float rounded = std::floor(fs + 0.5); |
2655 int32_t result = static_cast<int32_t>(rounded); | 2737 int32_t result = static_cast<int32_t>(rounded); |
2656 if ((result & 1) != 0 && result - fs == 0.5) { | 2738 if ((result & 1) != 0 && result - fs == 0.5) { |
2657 // If the number is halfway between two integers, | 2739 // If the number is halfway between two integers, |
2658 // round to the even one. | 2740 // round to the even one. |
2659 result--; | 2741 result--; |
2660 } | 2742 } |
2661 set_fpu_register_word(fd_reg(), result); | 2743 SetFPUWordResult(fd_reg(), result); |
2662 if (set_fcsr_round_error(fs, rounded)) { | 2744 if (set_fcsr_round_error(fs, rounded)) { |
2663 set_fpu_register_word_invalid_result(fs, rounded); | 2745 set_fpu_register_word_invalid_result(fs, rounded); |
2664 } | 2746 } |
2665 break; | 2747 break; |
2666 } | 2748 } |
2667 case ROUND_L_S: { // Mips64r2 instruction. | 2749 case ROUND_L_S: { // Mips64r2 instruction. |
2668 float rounded = std::floor(fs + 0.5); | 2750 float rounded = std::floor(fs + 0.5); |
2669 int64_t result = static_cast<int64_t>(rounded); | 2751 int64_t result = static_cast<int64_t>(rounded); |
2670 if ((result & 1) != 0 && result - fs == 0.5) { | 2752 if ((result & 1) != 0 && result - fs == 0.5) { |
2671 // If the number is halfway between two integers, | 2753 // If the number is halfway between two integers, |
2672 // round to the even one. | 2754 // round to the even one. |
2673 result--; | 2755 result--; |
2674 } | 2756 } |
2675 int64_t i64 = static_cast<int64_t>(result); | 2757 int64_t i64 = static_cast<int64_t>(result); |
2676 set_fpu_register(fd_reg(), i64); | 2758 SetFPUResult(fd_reg(), i64); |
2677 if (set_fcsr_round64_error(fs, rounded)) { | 2759 if (set_fcsr_round64_error(fs, rounded)) { |
2678 set_fpu_register_invalid_result64(fs, rounded); | 2760 set_fpu_register_invalid_result64(fs, rounded); |
2679 } | 2761 } |
2680 break; | 2762 break; |
2681 } | 2763 } |
2682 case FLOOR_L_S: { // Mips64r2 instruction. | 2764 case FLOOR_L_S: { // Mips64r2 instruction. |
2683 float rounded = floor(fs); | 2765 float rounded = floor(fs); |
2684 int64_t result = static_cast<int64_t>(rounded); | 2766 int64_t result = static_cast<int64_t>(rounded); |
2685 set_fpu_register(fd_reg(), result); | 2767 SetFPUResult(fd_reg(), result); |
2686 if (set_fcsr_round64_error(fs, rounded)) { | 2768 if (set_fcsr_round64_error(fs, rounded)) { |
2687 set_fpu_register_invalid_result64(fs, rounded); | 2769 set_fpu_register_invalid_result64(fs, rounded); |
2688 } | 2770 } |
2689 break; | 2771 break; |
2690 } | 2772 } |
2691 case FLOOR_W_S: // Round double to word towards negative infinity. | 2773 case FLOOR_W_S: // Round double to word towards negative infinity. |
2692 { | 2774 { |
2693 float rounded = std::floor(fs); | 2775 float rounded = std::floor(fs); |
2694 int32_t result = static_cast<int32_t>(rounded); | 2776 int32_t result = static_cast<int32_t>(rounded); |
2695 set_fpu_register_word(fd_reg(), result); | 2777 SetFPUWordResult(fd_reg(), result); |
2696 if (set_fcsr_round_error(fs, rounded)) { | 2778 if (set_fcsr_round_error(fs, rounded)) { |
2697 set_fpu_register_word_invalid_result(fs, rounded); | 2779 set_fpu_register_word_invalid_result(fs, rounded); |
2698 } | 2780 } |
2699 } break; | 2781 } break; |
2700 case CEIL_W_S: // Round double to word towards positive infinity. | 2782 case CEIL_W_S: // Round double to word towards positive infinity. |
2701 { | 2783 { |
2702 float rounded = std::ceil(fs); | 2784 float rounded = std::ceil(fs); |
2703 int32_t result = static_cast<int32_t>(rounded); | 2785 int32_t result = static_cast<int32_t>(rounded); |
2704 set_fpu_register_word(fd_reg(), result); | 2786 SetFPUWordResult(fd_reg(), result); |
2705 if (set_fcsr_round_error(fs, rounded)) { | 2787 if (set_fcsr_round_error(fs, rounded)) { |
2706 set_fpu_register_invalid_result(fs, rounded); | 2788 set_fpu_register_invalid_result(fs, rounded); |
2707 } | 2789 } |
2708 } break; | 2790 } break; |
2709 case CEIL_L_S: { // Mips64r2 instruction. | 2791 case CEIL_L_S: { // Mips64r2 instruction. |
2710 float rounded = ceil(fs); | 2792 float rounded = ceil(fs); |
2711 int64_t result = static_cast<int64_t>(rounded); | 2793 int64_t result = static_cast<int64_t>(rounded); |
2712 set_fpu_register(fd_reg(), result); | 2794 SetFPUResult(fd_reg(), result); |
2713 if (set_fcsr_round64_error(fs, rounded)) { | 2795 if (set_fcsr_round64_error(fs, rounded)) { |
2714 set_fpu_register_invalid_result64(fs, rounded); | 2796 set_fpu_register_invalid_result64(fs, rounded); |
2715 } | 2797 } |
2716 break; | 2798 break; |
2717 } | 2799 } |
2718 case MINA: | 2800 case MINA: |
2719 DCHECK(kArchVariant == kMips64r6); | 2801 DCHECK(kArchVariant == kMips64r6); |
2720 set_fpu_register_float(fd_reg(), FPUMinA(ft, fs)); | 2802 SetFPUFloatResult(fd_reg(), FPUMinA(ft, fs)); |
2721 break; | 2803 break; |
2722 case MAXA: | 2804 case MAXA: |
2723 DCHECK(kArchVariant == kMips64r6); | 2805 DCHECK(kArchVariant == kMips64r6); |
2724 set_fpu_register_float(fd_reg(), FPUMaxA(ft, fs)); | 2806 SetFPUFloatResult(fd_reg(), FPUMaxA(ft, fs)); |
2725 break; | 2807 break; |
2726 case MIN: | 2808 case MIN: |
2727 DCHECK(kArchVariant == kMips64r6); | 2809 DCHECK(kArchVariant == kMips64r6); |
2728 set_fpu_register_float(fd_reg(), FPUMin(ft, fs)); | 2810 SetFPUFloatResult(fd_reg(), FPUMin(ft, fs)); |
2729 break; | 2811 break; |
2730 case MAX: | 2812 case MAX: |
2731 DCHECK(kArchVariant == kMips64r6); | 2813 DCHECK(kArchVariant == kMips64r6); |
2732 set_fpu_register_float(fd_reg(), FPUMax(ft, fs)); | 2814 SetFPUFloatResult(fd_reg(), FPUMax(ft, fs)); |
2733 break; | 2815 break; |
2734 case SEL: | 2816 case SEL: |
2735 DCHECK(kArchVariant == kMips64r6); | 2817 DCHECK(kArchVariant == kMips64r6); |
2736 set_fpu_register_float(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); | 2818 SetFPUFloatResult(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); |
2737 break; | 2819 break; |
2738 case SELEQZ_C: | 2820 case SELEQZ_C: |
2739 DCHECK(kArchVariant == kMips64r6); | 2821 DCHECK(kArchVariant == kMips64r6); |
2740 set_fpu_register_float(fd_reg(), (ft_int & 0x1) == 0 | 2822 SetFPUFloatResult( |
2741 ? get_fpu_register_float(fs_reg()) | 2823 fd_reg(), |
2742 : 0.0); | 2824 (ft_int & 0x1) == 0 ? get_fpu_register_float(fs_reg()) : 0.0); |
2743 break; | 2825 break; |
2744 case SELNEZ_C: | 2826 case SELNEZ_C: |
2745 DCHECK(kArchVariant == kMips64r6); | 2827 DCHECK(kArchVariant == kMips64r6); |
2746 set_fpu_register_float(fd_reg(), (ft_int & 0x1) != 0 | 2828 SetFPUFloatResult( |
2747 ? get_fpu_register_float(fs_reg()) | 2829 fd_reg(), |
2748 : 0.0); | 2830 (ft_int & 0x1) != 0 ? get_fpu_register_float(fs_reg()) : 0.0); |
2749 break; | 2831 break; |
2750 case MOVZ_C: { | 2832 case MOVZ_C: { |
2751 DCHECK(kArchVariant == kMips64r2); | 2833 DCHECK(kArchVariant == kMips64r2); |
2752 if (rt() == 0) { | 2834 if (rt() == 0) { |
2753 set_fpu_register_float(fd_reg(), fs); | 2835 SetFPUFloatResult(fd_reg(), fs); |
2754 } | 2836 } |
2755 break; | 2837 break; |
2756 } | 2838 } |
2757 case MOVN_C: { | 2839 case MOVN_C: { |
2758 DCHECK(kArchVariant == kMips64r2); | 2840 DCHECK(kArchVariant == kMips64r2); |
2759 if (rt() != 0) { | 2841 if (rt() != 0) { |
2760 set_fpu_register_float(fd_reg(), fs); | 2842 SetFPUFloatResult(fd_reg(), fs); |
2761 } | 2843 } |
2762 break; | 2844 break; |
2763 } | 2845 } |
2764 case MOVF: { | 2846 case MOVF: { |
2765 // Same function field for MOVT.D and MOVF.D | 2847 // Same function field for MOVT.D and MOVF.D |
2766 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; | 2848 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; |
2767 ft_cc = get_fcsr_condition_bit(ft_cc); | 2849 ft_cc = get_fcsr_condition_bit(ft_cc); |
2768 | 2850 |
2769 if (instr_.Bit(16)) { // Read Tf bit. | 2851 if (instr_.Bit(16)) { // Read Tf bit. |
2770 // MOVT.D | 2852 // MOVT.D |
2771 if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); | 2853 if (test_fcsr_bit(ft_cc)) SetFPUFloatResult(fd_reg(), fs); |
2772 } else { | 2854 } else { |
2773 // MOVF.D | 2855 // MOVF.D |
2774 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); | 2856 if (!test_fcsr_bit(ft_cc)) SetFPUFloatResult(fd_reg(), fs); |
2775 } | 2857 } |
2776 break; | 2858 break; |
2777 } | 2859 } |
2778 default: | 2860 default: |
2779 // TRUNC_W_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S | 2861 // TRUNC_W_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S |
2780 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. | 2862 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. |
2781 UNREACHABLE(); | 2863 UNREACHABLE(); |
2782 } | 2864 } |
2783 } | 2865 } |
2784 | 2866 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2819 case kRoundToZero: | 2901 case kRoundToZero: |
2820 result = (fs > 0 ? lower : upper); | 2902 result = (fs > 0 ? lower : upper); |
2821 break; | 2903 break; |
2822 case kRoundToPlusInf: | 2904 case kRoundToPlusInf: |
2823 result = upper; | 2905 result = upper; |
2824 break; | 2906 break; |
2825 case kRoundToMinusInf: | 2907 case kRoundToMinusInf: |
2826 result = lower; | 2908 result = lower; |
2827 break; | 2909 break; |
2828 } | 2910 } |
2829 set_fpu_register_double(fd_reg(), result); | 2911 SetFPUDoubleResult(fd_reg(), result); |
2830 if (result != fs) { | 2912 if (result != fs) { |
2831 set_fcsr_bit(kFCSRInexactFlagBit, true); | 2913 set_fcsr_bit(kFCSRInexactFlagBit, true); |
2832 } | 2914 } |
2833 break; | 2915 break; |
2834 } | 2916 } |
2835 case SEL: | 2917 case SEL: |
2836 DCHECK(kArchVariant == kMips64r6); | 2918 DCHECK(kArchVariant == kMips64r6); |
2837 set_fpu_register_double(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); | 2919 SetFPUDoubleResult(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); |
2838 break; | 2920 break; |
2839 case SELEQZ_C: | 2921 case SELEQZ_C: |
2840 DCHECK(kArchVariant == kMips64r6); | 2922 DCHECK(kArchVariant == kMips64r6); |
2841 set_fpu_register_double(fd_reg(), (ft_int & 0x1) == 0 ? fs : 0.0); | 2923 SetFPUDoubleResult(fd_reg(), (ft_int & 0x1) == 0 ? fs : 0.0); |
2842 break; | 2924 break; |
2843 case SELNEZ_C: | 2925 case SELNEZ_C: |
2844 DCHECK(kArchVariant == kMips64r6); | 2926 DCHECK(kArchVariant == kMips64r6); |
2845 set_fpu_register_double(fd_reg(), (ft_int & 0x1) != 0 ? fs : 0.0); | 2927 SetFPUDoubleResult(fd_reg(), (ft_int & 0x1) != 0 ? fs : 0.0); |
2846 break; | 2928 break; |
2847 case MOVZ_C: { | 2929 case MOVZ_C: { |
2848 DCHECK(kArchVariant == kMips64r2); | 2930 DCHECK(kArchVariant == kMips64r2); |
2849 if (rt() == 0) { | 2931 if (rt() == 0) { |
2850 set_fpu_register_double(fd_reg(), fs); | 2932 SetFPUDoubleResult(fd_reg(), fs); |
2851 } | 2933 } |
2852 break; | 2934 break; |
2853 } | 2935 } |
2854 case MOVN_C: { | 2936 case MOVN_C: { |
2855 DCHECK(kArchVariant == kMips64r2); | 2937 DCHECK(kArchVariant == kMips64r2); |
2856 if (rt() != 0) { | 2938 if (rt() != 0) { |
2857 set_fpu_register_double(fd_reg(), fs); | 2939 SetFPUDoubleResult(fd_reg(), fs); |
2858 } | 2940 } |
2859 break; | 2941 break; |
2860 } | 2942 } |
2861 case MOVF: { | 2943 case MOVF: { |
2862 // Same function field for MOVT.D and MOVF.D | 2944 // Same function field for MOVT.D and MOVF.D |
2863 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; | 2945 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; |
2864 ft_cc = get_fcsr_condition_bit(ft_cc); | 2946 ft_cc = get_fcsr_condition_bit(ft_cc); |
2865 if (instr_.Bit(16)) { // Read Tf bit. | 2947 if (instr_.Bit(16)) { // Read Tf bit. |
2866 // MOVT.D | 2948 // MOVT.D |
2867 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); | 2949 if (test_fcsr_bit(ft_cc)) SetFPUDoubleResult(fd_reg(), fs); |
2868 } else { | 2950 } else { |
2869 // MOVF.D | 2951 // MOVF.D |
2870 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); | 2952 if (!test_fcsr_bit(ft_cc)) SetFPUDoubleResult(fd_reg(), fs); |
2871 } | 2953 } |
2872 break; | 2954 break; |
2873 } | 2955 } |
2874 case MINA: | 2956 case MINA: |
2875 DCHECK(kArchVariant == kMips64r6); | 2957 DCHECK(kArchVariant == kMips64r6); |
2876 set_fpu_register_double(fd_reg(), FPUMinA(ft, fs)); | 2958 SetFPUDoubleResult(fd_reg(), FPUMinA(ft, fs)); |
2877 break; | 2959 break; |
2878 case MAXA: | 2960 case MAXA: |
2879 DCHECK(kArchVariant == kMips64r6); | 2961 DCHECK(kArchVariant == kMips64r6); |
2880 set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs)); | 2962 SetFPUDoubleResult(fd_reg(), FPUMaxA(ft, fs)); |
2881 break; | 2963 break; |
2882 case MIN: | 2964 case MIN: |
2883 DCHECK(kArchVariant == kMips64r6); | 2965 DCHECK(kArchVariant == kMips64r6); |
2884 set_fpu_register_double(fd_reg(), FPUMin(ft, fs)); | 2966 SetFPUDoubleResult(fd_reg(), FPUMin(ft, fs)); |
2885 break; | 2967 break; |
2886 case MAX: | 2968 case MAX: |
2887 DCHECK(kArchVariant == kMips64r6); | 2969 DCHECK(kArchVariant == kMips64r6); |
2888 set_fpu_register_double(fd_reg(), FPUMax(ft, fs)); | 2970 SetFPUDoubleResult(fd_reg(), FPUMax(ft, fs)); |
2889 break; | 2971 break; |
2890 case ADD_D: | 2972 case ADD_D: |
2891 set_fpu_register_double( | 2973 SetFPUDoubleResult( |
2892 fd_reg(), | 2974 fd_reg(), |
2893 FPUCanonalizeOperation( | 2975 FPUCanonalizeOperation( |
2894 [](double lhs, double rhs) { return lhs + rhs; }, fs, ft)); | 2976 [](double lhs, double rhs) { return lhs + rhs; }, fs, ft)); |
2895 break; | 2977 break; |
2896 case SUB_D: | 2978 case SUB_D: |
2897 set_fpu_register_double( | 2979 SetFPUDoubleResult( |
2898 fd_reg(), | 2980 fd_reg(), |
2899 FPUCanonalizeOperation( | 2981 FPUCanonalizeOperation( |
2900 [](double lhs, double rhs) { return lhs - rhs; }, fs, ft)); | 2982 [](double lhs, double rhs) { return lhs - rhs; }, fs, ft)); |
2901 break; | 2983 break; |
2902 case MADDF_D: | 2984 case MADDF_D: |
2903 DCHECK(kArchVariant == kMips64r6); | 2985 DCHECK(kArchVariant == kMips64r6); |
2904 set_fpu_register_double(fd_reg(), std::fma(fs, ft, fd)); | 2986 SetFPUDoubleResult(fd_reg(), std::fma(fs, ft, fd)); |
2905 break; | 2987 break; |
2906 case MSUBF_D: | 2988 case MSUBF_D: |
2907 DCHECK(kArchVariant == kMips64r6); | 2989 DCHECK(kArchVariant == kMips64r6); |
2908 set_fpu_register_double(fd_reg(), std::fma(-fs, ft, fd)); | 2990 SetFPUDoubleResult(fd_reg(), std::fma(-fs, ft, fd)); |
2909 break; | 2991 break; |
2910 case MUL_D: | 2992 case MUL_D: |
2911 set_fpu_register_double( | 2993 SetFPUDoubleResult( |
2912 fd_reg(), | 2994 fd_reg(), |
2913 FPUCanonalizeOperation( | 2995 FPUCanonalizeOperation( |
2914 [](double lhs, double rhs) { return lhs * rhs; }, fs, ft)); | 2996 [](double lhs, double rhs) { return lhs * rhs; }, fs, ft)); |
2915 break; | 2997 break; |
2916 case DIV_D: | 2998 case DIV_D: |
2917 set_fpu_register_double( | 2999 SetFPUDoubleResult( |
2918 fd_reg(), | 3000 fd_reg(), |
2919 FPUCanonalizeOperation( | 3001 FPUCanonalizeOperation( |
2920 [](double lhs, double rhs) { return lhs / rhs; }, fs, ft)); | 3002 [](double lhs, double rhs) { return lhs / rhs; }, fs, ft)); |
2921 break; | 3003 break; |
2922 case ABS_D: | 3004 case ABS_D: |
2923 set_fpu_register_double( | 3005 SetFPUDoubleResult( |
2924 fd_reg(), | 3006 fd_reg(), |
2925 FPUCanonalizeOperation([](double fs) { return FPAbs(fs); }, fs)); | 3007 FPUCanonalizeOperation([](double fs) { return FPAbs(fs); }, fs)); |
2926 break; | 3008 break; |
2927 case MOV_D: | 3009 case MOV_D: |
2928 set_fpu_register_double(fd_reg(), fs); | 3010 SetFPUDoubleResult(fd_reg(), fs); |
2929 break; | 3011 break; |
2930 case NEG_D: | 3012 case NEG_D: |
2931 set_fpu_register_double( | 3013 SetFPUDoubleResult(fd_reg(), |
2932 fd_reg(), FPUCanonalizeOperation([](double src) { return -src; }, | 3014 FPUCanonalizeOperation([](double src) { return -src; }, |
2933 KeepSign::yes, fs)); | 3015 KeepSign::yes, fs)); |
2934 break; | 3016 break; |
2935 case SQRT_D: | 3017 case SQRT_D: |
2936 set_fpu_register_double( | 3018 SetFPUDoubleResult( |
2937 fd_reg(), | 3019 fd_reg(), |
2938 FPUCanonalizeOperation([](double fs) { return std::sqrt(fs); }, fs)); | 3020 FPUCanonalizeOperation([](double fs) { return std::sqrt(fs); }, fs)); |
2939 break; | 3021 break; |
2940 case RSQRT_D: | 3022 case RSQRT_D: |
2941 set_fpu_register_double( | 3023 SetFPUDoubleResult( |
2942 fd_reg(), FPUCanonalizeOperation( | 3024 fd_reg(), FPUCanonalizeOperation( |
2943 [](double fs) { return 1.0 / std::sqrt(fs); }, fs)); | 3025 [](double fs) { return 1.0 / std::sqrt(fs); }, fs)); |
2944 break; | 3026 break; |
2945 case RECIP_D: | 3027 case RECIP_D: |
2946 set_fpu_register_double( | 3028 SetFPUDoubleResult(fd_reg(), FPUCanonalizeOperation( |
2947 fd_reg(), | 3029 [](double fs) { return 1.0 / fs; }, fs)); |
2948 FPUCanonalizeOperation([](double fs) { return 1.0 / fs; }, fs)); | |
2949 break; | 3030 break; |
2950 case C_UN_D: | 3031 case C_UN_D: |
2951 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); | 3032 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); |
| 3033 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
2952 break; | 3034 break; |
2953 case C_EQ_D: | 3035 case C_EQ_D: |
2954 set_fcsr_bit(fcsr_cc, (fs == ft)); | 3036 set_fcsr_bit(fcsr_cc, (fs == ft)); |
| 3037 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
2955 break; | 3038 break; |
2956 case C_UEQ_D: | 3039 case C_UEQ_D: |
2957 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); | 3040 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); |
| 3041 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
2958 break; | 3042 break; |
2959 case C_OLT_D: | 3043 case C_OLT_D: |
2960 set_fcsr_bit(fcsr_cc, (fs < ft)); | 3044 set_fcsr_bit(fcsr_cc, (fs < ft)); |
| 3045 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
2961 break; | 3046 break; |
2962 case C_ULT_D: | 3047 case C_ULT_D: |
2963 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); | 3048 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); |
| 3049 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
2964 break; | 3050 break; |
2965 case C_OLE_D: | 3051 case C_OLE_D: |
2966 set_fcsr_bit(fcsr_cc, (fs <= ft)); | 3052 set_fcsr_bit(fcsr_cc, (fs <= ft)); |
| 3053 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
2967 break; | 3054 break; |
2968 case C_ULE_D: | 3055 case C_ULE_D: |
2969 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); | 3056 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); |
| 3057 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
2970 break; | 3058 break; |
2971 case CVT_W_D: { // Convert double to word. | 3059 case CVT_W_D: { // Convert double to word. |
2972 double rounded; | 3060 double rounded; |
2973 int32_t result; | 3061 int32_t result; |
2974 round_according_to_fcsr(fs, rounded, result, fs); | 3062 round_according_to_fcsr(fs, rounded, result, fs); |
2975 set_fpu_register_word(fd_reg(), result); | 3063 SetFPUWordResult(fd_reg(), result); |
2976 if (set_fcsr_round_error(fs, rounded)) { | 3064 if (set_fcsr_round_error(fs, rounded)) { |
2977 set_fpu_register_word_invalid_result(fs, rounded); | 3065 set_fpu_register_word_invalid_result(fs, rounded); |
2978 } | 3066 } |
2979 break; | 3067 break; |
2980 } | 3068 } |
2981 case ROUND_W_D: // Round double to word (round half to even). | 3069 case ROUND_W_D: // Round double to word (round half to even). |
2982 { | 3070 { |
2983 double rounded = std::floor(fs + 0.5); | 3071 double rounded = std::floor(fs + 0.5); |
2984 int32_t result = static_cast<int32_t>(rounded); | 3072 int32_t result = static_cast<int32_t>(rounded); |
2985 if ((result & 1) != 0 && result - fs == 0.5) { | 3073 if ((result & 1) != 0 && result - fs == 0.5) { |
2986 // If the number is halfway between two integers, | 3074 // If the number is halfway between two integers, |
2987 // round to the even one. | 3075 // round to the even one. |
2988 result--; | 3076 result--; |
2989 } | 3077 } |
2990 set_fpu_register_word(fd_reg(), result); | 3078 SetFPUWordResult(fd_reg(), result); |
2991 if (set_fcsr_round_error(fs, rounded)) { | 3079 if (set_fcsr_round_error(fs, rounded)) { |
2992 set_fpu_register_invalid_result(fs, rounded); | 3080 set_fpu_register_invalid_result(fs, rounded); |
2993 } | 3081 } |
2994 } break; | 3082 } break; |
2995 case TRUNC_W_D: // Truncate double to word (round towards 0). | 3083 case TRUNC_W_D: // Truncate double to word (round towards 0). |
2996 { | 3084 { |
2997 double rounded = trunc(fs); | 3085 double rounded = trunc(fs); |
2998 int32_t result = static_cast<int32_t>(rounded); | 3086 int32_t result = static_cast<int32_t>(rounded); |
2999 set_fpu_register_word(fd_reg(), result); | 3087 SetFPUWordResult(fd_reg(), result); |
3000 if (set_fcsr_round_error(fs, rounded)) { | 3088 if (set_fcsr_round_error(fs, rounded)) { |
3001 set_fpu_register_invalid_result(fs, rounded); | 3089 set_fpu_register_invalid_result(fs, rounded); |
3002 } | 3090 } |
3003 } break; | 3091 } break; |
3004 case FLOOR_W_D: // Round double to word towards negative infinity. | 3092 case FLOOR_W_D: // Round double to word towards negative infinity. |
3005 { | 3093 { |
3006 double rounded = std::floor(fs); | 3094 double rounded = std::floor(fs); |
3007 int32_t result = static_cast<int32_t>(rounded); | 3095 int32_t result = static_cast<int32_t>(rounded); |
3008 set_fpu_register_word(fd_reg(), result); | 3096 SetFPUWordResult(fd_reg(), result); |
3009 if (set_fcsr_round_error(fs, rounded)) { | 3097 if (set_fcsr_round_error(fs, rounded)) { |
3010 set_fpu_register_invalid_result(fs, rounded); | 3098 set_fpu_register_invalid_result(fs, rounded); |
3011 } | 3099 } |
3012 } break; | 3100 } break; |
3013 case CEIL_W_D: // Round double to word towards positive infinity. | 3101 case CEIL_W_D: // Round double to word towards positive infinity. |
3014 { | 3102 { |
3015 double rounded = std::ceil(fs); | 3103 double rounded = std::ceil(fs); |
3016 int32_t result = static_cast<int32_t>(rounded); | 3104 int32_t result = static_cast<int32_t>(rounded); |
3017 set_fpu_register_word(fd_reg(), result); | 3105 SetFPUWordResult2(fd_reg(), result); |
3018 if (set_fcsr_round_error(fs, rounded)) { | 3106 if (set_fcsr_round_error(fs, rounded)) { |
3019 set_fpu_register_invalid_result(fs, rounded); | 3107 set_fpu_register_invalid_result(fs, rounded); |
3020 } | 3108 } |
3021 } break; | 3109 } break; |
3022 case CVT_S_D: // Convert double to float (single). | 3110 case CVT_S_D: // Convert double to float (single). |
3023 set_fpu_register_float(fd_reg(), static_cast<float>(fs)); | 3111 SetFPUFloatResult(fd_reg(), static_cast<float>(fs)); |
3024 break; | 3112 break; |
3025 case CVT_L_D: { // Mips64r2: Truncate double to 64-bit long-word. | 3113 case CVT_L_D: { // Mips64r2: Truncate double to 64-bit long-word. |
3026 double rounded; | 3114 double rounded; |
3027 int64_t result; | 3115 int64_t result; |
3028 round64_according_to_fcsr(fs, rounded, result, fs); | 3116 round64_according_to_fcsr(fs, rounded, result, fs); |
3029 set_fpu_register(fd_reg(), result); | 3117 SetFPUResult(fd_reg(), result); |
3030 if (set_fcsr_round64_error(fs, rounded)) { | 3118 if (set_fcsr_round64_error(fs, rounded)) { |
3031 set_fpu_register_invalid_result64(fs, rounded); | 3119 set_fpu_register_invalid_result64(fs, rounded); |
3032 } | 3120 } |
3033 break; | 3121 break; |
3034 } | 3122 } |
3035 case ROUND_L_D: { // Mips64r2 instruction. | 3123 case ROUND_L_D: { // Mips64r2 instruction. |
3036 double rounded = std::floor(fs + 0.5); | 3124 double rounded = std::floor(fs + 0.5); |
3037 int64_t result = static_cast<int64_t>(rounded); | 3125 int64_t result = static_cast<int64_t>(rounded); |
3038 if ((result & 1) != 0 && result - fs == 0.5) { | 3126 if ((result & 1) != 0 && result - fs == 0.5) { |
3039 // If the number is halfway between two integers, | 3127 // If the number is halfway between two integers, |
3040 // round to the even one. | 3128 // round to the even one. |
3041 result--; | 3129 result--; |
3042 } | 3130 } |
3043 int64_t i64 = static_cast<int64_t>(result); | 3131 int64_t i64 = static_cast<int64_t>(result); |
3044 set_fpu_register(fd_reg(), i64); | 3132 SetFPUResult(fd_reg(), i64); |
3045 if (set_fcsr_round64_error(fs, rounded)) { | 3133 if (set_fcsr_round64_error(fs, rounded)) { |
3046 set_fpu_register_invalid_result64(fs, rounded); | 3134 set_fpu_register_invalid_result64(fs, rounded); |
3047 } | 3135 } |
3048 break; | 3136 break; |
3049 } | 3137 } |
3050 case TRUNC_L_D: { // Mips64r2 instruction. | 3138 case TRUNC_L_D: { // Mips64r2 instruction. |
3051 double rounded = trunc(fs); | 3139 double rounded = trunc(fs); |
3052 int64_t result = static_cast<int64_t>(rounded); | 3140 int64_t result = static_cast<int64_t>(rounded); |
3053 set_fpu_register(fd_reg(), result); | 3141 SetFPUResult(fd_reg(), result); |
3054 if (set_fcsr_round64_error(fs, rounded)) { | 3142 if (set_fcsr_round64_error(fs, rounded)) { |
3055 set_fpu_register_invalid_result64(fs, rounded); | 3143 set_fpu_register_invalid_result64(fs, rounded); |
3056 } | 3144 } |
3057 break; | 3145 break; |
3058 } | 3146 } |
3059 case FLOOR_L_D: { // Mips64r2 instruction. | 3147 case FLOOR_L_D: { // Mips64r2 instruction. |
3060 double rounded = floor(fs); | 3148 double rounded = floor(fs); |
3061 int64_t result = static_cast<int64_t>(rounded); | 3149 int64_t result = static_cast<int64_t>(rounded); |
3062 set_fpu_register(fd_reg(), result); | 3150 SetFPUResult(fd_reg(), result); |
3063 if (set_fcsr_round64_error(fs, rounded)) { | 3151 if (set_fcsr_round64_error(fs, rounded)) { |
3064 set_fpu_register_invalid_result64(fs, rounded); | 3152 set_fpu_register_invalid_result64(fs, rounded); |
3065 } | 3153 } |
3066 break; | 3154 break; |
3067 } | 3155 } |
3068 case CEIL_L_D: { // Mips64r2 instruction. | 3156 case CEIL_L_D: { // Mips64r2 instruction. |
3069 double rounded = ceil(fs); | 3157 double rounded = ceil(fs); |
3070 int64_t result = static_cast<int64_t>(rounded); | 3158 int64_t result = static_cast<int64_t>(rounded); |
3071 set_fpu_register(fd_reg(), result); | 3159 SetFPUResult(fd_reg(), result); |
3072 if (set_fcsr_round64_error(fs, rounded)) { | 3160 if (set_fcsr_round64_error(fs, rounded)) { |
3073 set_fpu_register_invalid_result64(fs, rounded); | 3161 set_fpu_register_invalid_result64(fs, rounded); |
3074 } | 3162 } |
3075 break; | 3163 break; |
3076 } | 3164 } |
3077 case CLASS_D: { // Mips64r6 instruction | 3165 case CLASS_D: { // Mips64r6 instruction |
3078 // Convert double input to uint64_t for easier bit manipulation | 3166 // Convert double input to uint64_t for easier bit manipulation |
3079 uint64_t classed = bit_cast<uint64_t>(fs); | 3167 uint64_t classed = bit_cast<uint64_t>(fs); |
3080 | 3168 |
3081 // Extracting sign, exponent and mantissa from the input double | 3169 // Extracting sign, exponent and mantissa from the input double |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3128 } | 3216 } |
3129 | 3217 |
3130 // Calculating result according to description of CLASS.D instruction | 3218 // Calculating result according to description of CLASS.D instruction |
3131 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | | 3219 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | |
3132 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | | 3220 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | |
3133 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; | 3221 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; |
3134 | 3222 |
3135 DCHECK(result != 0); | 3223 DCHECK(result != 0); |
3136 | 3224 |
3137 dResult = bit_cast<double>(result); | 3225 dResult = bit_cast<double>(result); |
3138 set_fpu_register_double(fd_reg(), dResult); | 3226 SetFPUDoubleResult(fd_reg(), dResult); |
3139 | |
3140 break; | 3227 break; |
3141 } | 3228 } |
3142 case C_F_D: { | 3229 case C_F_D: { |
3143 set_fcsr_bit(fcsr_cc, false); | 3230 set_fcsr_bit(fcsr_cc, false); |
| 3231 TraceRegWr(test_fcsr_bit(fcsr_cc)); |
3144 break; | 3232 break; |
3145 } | 3233 } |
3146 default: | 3234 default: |
3147 UNREACHABLE(); | 3235 UNREACHABLE(); |
3148 } | 3236 } |
3149 } | 3237 } |
3150 | 3238 |
3151 | 3239 |
3152 void Simulator::DecodeTypeRegisterWRsType() { | 3240 void Simulator::DecodeTypeRegisterWRsType() { |
3153 float fs = get_fpu_register_float(fs_reg()); | 3241 float fs = get_fpu_register_float(fs_reg()); |
3154 float ft = get_fpu_register_float(ft_reg()); | 3242 float ft = get_fpu_register_float(ft_reg()); |
3155 int64_t alu_out = 0x12345678; | 3243 int64_t alu_out = 0x12345678; |
3156 switch (instr_.FunctionFieldRaw()) { | 3244 switch (instr_.FunctionFieldRaw()) { |
3157 case CVT_S_W: // Convert word to float (single). | 3245 case CVT_S_W: // Convert word to float (single). |
3158 alu_out = get_fpu_register_signed_word(fs_reg()); | 3246 alu_out = get_fpu_register_signed_word(fs_reg()); |
3159 set_fpu_register_float(fd_reg(), static_cast<float>(alu_out)); | 3247 SetFPUFloatResult(fd_reg(), static_cast<float>(alu_out)); |
3160 break; | 3248 break; |
3161 case CVT_D_W: // Convert word to double. | 3249 case CVT_D_W: // Convert word to double. |
3162 alu_out = get_fpu_register_signed_word(fs_reg()); | 3250 alu_out = get_fpu_register_signed_word(fs_reg()); |
3163 set_fpu_register_double(fd_reg(), static_cast<double>(alu_out)); | 3251 SetFPUDoubleResult(fd_reg(), static_cast<double>(alu_out)); |
3164 break; | 3252 break; |
3165 case CMP_AF: | 3253 case CMP_AF: |
3166 set_fpu_register_word(fd_reg(), 0); | 3254 SetFPUWordResult2(fd_reg(), 0); |
3167 break; | 3255 break; |
3168 case CMP_UN: | 3256 case CMP_UN: |
3169 if (std::isnan(fs) || std::isnan(ft)) { | 3257 if (std::isnan(fs) || std::isnan(ft)) { |
3170 set_fpu_register_word(fd_reg(), -1); | 3258 SetFPUWordResult2(fd_reg(), -1); |
3171 } else { | 3259 } else { |
3172 set_fpu_register_word(fd_reg(), 0); | 3260 SetFPUWordResult2(fd_reg(), 0); |
3173 } | 3261 } |
3174 break; | 3262 break; |
3175 case CMP_EQ: | 3263 case CMP_EQ: |
3176 if (fs == ft) { | 3264 if (fs == ft) { |
3177 set_fpu_register_word(fd_reg(), -1); | 3265 SetFPUWordResult2(fd_reg(), -1); |
3178 } else { | 3266 } else { |
3179 set_fpu_register_word(fd_reg(), 0); | 3267 SetFPUWordResult2(fd_reg(), 0); |
3180 } | 3268 } |
3181 break; | 3269 break; |
3182 case CMP_UEQ: | 3270 case CMP_UEQ: |
3183 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { | 3271 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { |
3184 set_fpu_register_word(fd_reg(), -1); | 3272 SetFPUWordResult2(fd_reg(), -1); |
3185 } else { | 3273 } else { |
3186 set_fpu_register_word(fd_reg(), 0); | 3274 SetFPUWordResult2(fd_reg(), 0); |
3187 } | 3275 } |
3188 break; | 3276 break; |
3189 case CMP_LT: | 3277 case CMP_LT: |
3190 if (fs < ft) { | 3278 if (fs < ft) { |
3191 set_fpu_register_word(fd_reg(), -1); | 3279 SetFPUWordResult2(fd_reg(), -1); |
3192 } else { | 3280 } else { |
3193 set_fpu_register_word(fd_reg(), 0); | 3281 SetFPUWordResult2(fd_reg(), 0); |
3194 } | 3282 } |
3195 break; | 3283 break; |
3196 case CMP_ULT: | 3284 case CMP_ULT: |
3197 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { | 3285 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { |
3198 set_fpu_register_word(fd_reg(), -1); | 3286 SetFPUWordResult2(fd_reg(), -1); |
3199 } else { | 3287 } else { |
3200 set_fpu_register_word(fd_reg(), 0); | 3288 SetFPUWordResult2(fd_reg(), 0); |
3201 } | 3289 } |
3202 break; | 3290 break; |
3203 case CMP_LE: | 3291 case CMP_LE: |
3204 if (fs <= ft) { | 3292 if (fs <= ft) { |
3205 set_fpu_register_word(fd_reg(), -1); | 3293 SetFPUWordResult2(fd_reg(), -1); |
3206 } else { | 3294 } else { |
3207 set_fpu_register_word(fd_reg(), 0); | 3295 SetFPUWordResult2(fd_reg(), 0); |
3208 } | 3296 } |
3209 break; | 3297 break; |
3210 case CMP_ULE: | 3298 case CMP_ULE: |
3211 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { | 3299 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { |
3212 set_fpu_register_word(fd_reg(), -1); | 3300 SetFPUWordResult2(fd_reg(), -1); |
3213 } else { | 3301 } else { |
3214 set_fpu_register_word(fd_reg(), 0); | 3302 SetFPUWordResult2(fd_reg(), 0); |
3215 } | 3303 } |
3216 break; | 3304 break; |
3217 case CMP_OR: | 3305 case CMP_OR: |
3218 if (!std::isnan(fs) && !std::isnan(ft)) { | 3306 if (!std::isnan(fs) && !std::isnan(ft)) { |
3219 set_fpu_register_word(fd_reg(), -1); | 3307 SetFPUWordResult2(fd_reg(), -1); |
3220 } else { | 3308 } else { |
3221 set_fpu_register_word(fd_reg(), 0); | 3309 SetFPUWordResult2(fd_reg(), 0); |
3222 } | 3310 } |
3223 break; | 3311 break; |
3224 case CMP_UNE: | 3312 case CMP_UNE: |
3225 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { | 3313 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { |
3226 set_fpu_register_word(fd_reg(), -1); | 3314 SetFPUWordResult2(fd_reg(), -1); |
3227 } else { | 3315 } else { |
3228 set_fpu_register_word(fd_reg(), 0); | 3316 SetFPUWordResult2(fd_reg(), 0); |
3229 } | 3317 } |
3230 break; | 3318 break; |
3231 case CMP_NE: | 3319 case CMP_NE: |
3232 if (fs != ft) { | 3320 if (fs != ft) { |
3233 set_fpu_register_word(fd_reg(), -1); | 3321 SetFPUWordResult2(fd_reg(), -1); |
3234 } else { | 3322 } else { |
3235 set_fpu_register_word(fd_reg(), 0); | 3323 SetFPUWordResult2(fd_reg(), 0); |
3236 } | 3324 } |
3237 break; | 3325 break; |
3238 default: | 3326 default: |
3239 UNREACHABLE(); | 3327 UNREACHABLE(); |
3240 } | 3328 } |
3241 } | 3329 } |
3242 | 3330 |
3243 | 3331 |
3244 void Simulator::DecodeTypeRegisterLRsType() { | 3332 void Simulator::DecodeTypeRegisterLRsType() { |
3245 double fs = get_fpu_register_double(fs_reg()); | 3333 double fs = get_fpu_register_double(fs_reg()); |
3246 double ft = get_fpu_register_double(ft_reg()); | 3334 double ft = get_fpu_register_double(ft_reg()); |
3247 int64_t i64; | 3335 int64_t i64; |
3248 switch (instr_.FunctionFieldRaw()) { | 3336 switch (instr_.FunctionFieldRaw()) { |
3249 case CVT_D_L: // Mips32r2 instruction. | 3337 case CVT_D_L: // Mips32r2 instruction. |
3250 i64 = get_fpu_register(fs_reg()); | 3338 i64 = get_fpu_register(fs_reg()); |
3251 set_fpu_register_double(fd_reg(), static_cast<double>(i64)); | 3339 SetFPUDoubleResult(fd_reg(), static_cast<double>(i64)); |
3252 break; | 3340 break; |
3253 case CVT_S_L: | 3341 case CVT_S_L: |
3254 i64 = get_fpu_register(fs_reg()); | 3342 i64 = get_fpu_register(fs_reg()); |
3255 set_fpu_register_float(fd_reg(), static_cast<float>(i64)); | 3343 SetFPUFloatResult(fd_reg(), static_cast<float>(i64)); |
3256 break; | 3344 break; |
3257 case CMP_AF: | 3345 case CMP_AF: |
3258 set_fpu_register(fd_reg(), 0); | 3346 SetFPUResult(fd_reg(), 0); |
3259 break; | 3347 break; |
3260 case CMP_UN: | 3348 case CMP_UN: |
3261 if (std::isnan(fs) || std::isnan(ft)) { | 3349 if (std::isnan(fs) || std::isnan(ft)) { |
3262 set_fpu_register(fd_reg(), -1); | 3350 SetFPUResult(fd_reg(), -1); |
3263 } else { | 3351 } else { |
3264 set_fpu_register(fd_reg(), 0); | 3352 SetFPUResult(fd_reg(), 0); |
3265 } | 3353 } |
3266 break; | 3354 break; |
3267 case CMP_EQ: | 3355 case CMP_EQ: |
3268 if (fs == ft) { | 3356 if (fs == ft) { |
3269 set_fpu_register(fd_reg(), -1); | 3357 SetFPUResult(fd_reg(), -1); |
3270 } else { | 3358 } else { |
3271 set_fpu_register(fd_reg(), 0); | 3359 SetFPUResult(fd_reg(), 0); |
3272 } | 3360 } |
3273 break; | 3361 break; |
3274 case CMP_UEQ: | 3362 case CMP_UEQ: |
3275 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { | 3363 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { |
3276 set_fpu_register(fd_reg(), -1); | 3364 SetFPUResult(fd_reg(), -1); |
3277 } else { | 3365 } else { |
3278 set_fpu_register(fd_reg(), 0); | 3366 SetFPUResult(fd_reg(), 0); |
3279 } | 3367 } |
3280 break; | 3368 break; |
3281 case CMP_LT: | 3369 case CMP_LT: |
3282 if (fs < ft) { | 3370 if (fs < ft) { |
3283 set_fpu_register(fd_reg(), -1); | 3371 SetFPUResult(fd_reg(), -1); |
3284 } else { | 3372 } else { |
3285 set_fpu_register(fd_reg(), 0); | 3373 SetFPUResult(fd_reg(), 0); |
3286 } | 3374 } |
3287 break; | 3375 break; |
3288 case CMP_ULT: | 3376 case CMP_ULT: |
3289 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { | 3377 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { |
3290 set_fpu_register(fd_reg(), -1); | 3378 SetFPUResult(fd_reg(), -1); |
3291 } else { | 3379 } else { |
3292 set_fpu_register(fd_reg(), 0); | 3380 SetFPUResult(fd_reg(), 0); |
3293 } | 3381 } |
3294 break; | 3382 break; |
3295 case CMP_LE: | 3383 case CMP_LE: |
3296 if (fs <= ft) { | 3384 if (fs <= ft) { |
3297 set_fpu_register(fd_reg(), -1); | 3385 SetFPUResult(fd_reg(), -1); |
3298 } else { | 3386 } else { |
3299 set_fpu_register(fd_reg(), 0); | 3387 SetFPUResult(fd_reg(), 0); |
3300 } | 3388 } |
3301 break; | 3389 break; |
3302 case CMP_ULE: | 3390 case CMP_ULE: |
3303 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { | 3391 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { |
3304 set_fpu_register(fd_reg(), -1); | 3392 SetFPUResult(fd_reg(), -1); |
3305 } else { | 3393 } else { |
3306 set_fpu_register(fd_reg(), 0); | 3394 SetFPUResult(fd_reg(), 0); |
3307 } | 3395 } |
3308 break; | 3396 break; |
3309 case CMP_OR: | 3397 case CMP_OR: |
3310 if (!std::isnan(fs) && !std::isnan(ft)) { | 3398 if (!std::isnan(fs) && !std::isnan(ft)) { |
3311 set_fpu_register(fd_reg(), -1); | 3399 SetFPUResult(fd_reg(), -1); |
3312 } else { | 3400 } else { |
3313 set_fpu_register(fd_reg(), 0); | 3401 SetFPUResult(fd_reg(), 0); |
3314 } | 3402 } |
3315 break; | 3403 break; |
3316 case CMP_UNE: | 3404 case CMP_UNE: |
3317 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { | 3405 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { |
3318 set_fpu_register(fd_reg(), -1); | 3406 SetFPUResult(fd_reg(), -1); |
3319 } else { | 3407 } else { |
3320 set_fpu_register(fd_reg(), 0); | 3408 SetFPUResult(fd_reg(), 0); |
3321 } | 3409 } |
3322 break; | 3410 break; |
3323 case CMP_NE: | 3411 case CMP_NE: |
3324 if (fs != ft && (!std::isnan(fs) && !std::isnan(ft))) { | 3412 if (fs != ft && (!std::isnan(fs) && !std::isnan(ft))) { |
3325 set_fpu_register(fd_reg(), -1); | 3413 SetFPUResult(fd_reg(), -1); |
3326 } else { | 3414 } else { |
3327 set_fpu_register(fd_reg(), 0); | 3415 SetFPUResult(fd_reg(), 0); |
3328 } | 3416 } |
3329 break; | 3417 break; |
3330 default: | 3418 default: |
3331 UNREACHABLE(); | 3419 UNREACHABLE(); |
3332 } | 3420 } |
3333 } | 3421 } |
3334 | 3422 |
3335 | 3423 |
3336 void Simulator::DecodeTypeRegisterCOP1() { | 3424 void Simulator::DecodeTypeRegisterCOP1() { |
3337 switch (instr_.RsFieldRaw()) { | 3425 switch (instr_.RsFieldRaw()) { |
3338 case BC1: // Branch on coprocessor condition. | 3426 case BC1: // Branch on coprocessor condition. |
3339 case BC1EQZ: | 3427 case BC1EQZ: |
3340 case BC1NEZ: | 3428 case BC1NEZ: |
3341 UNREACHABLE(); | 3429 UNREACHABLE(); |
3342 break; | 3430 break; |
3343 case CFC1: | 3431 case CFC1: |
3344 // At the moment only FCSR is supported. | 3432 // At the moment only FCSR is supported. |
3345 DCHECK(fs_reg() == kFCSRRegister); | 3433 DCHECK(fs_reg() == kFCSRRegister); |
3346 set_register(rt_reg(), FCSR_); | 3434 SetResult(rt_reg(), FCSR_); |
3347 break; | 3435 break; |
3348 case MFC1: | 3436 case MFC1: |
3349 set_register(rt_reg(), | 3437 set_register(rt_reg(), |
3350 static_cast<int64_t>(get_fpu_register_word(fs_reg()))); | 3438 static_cast<int64_t>(get_fpu_register_word(fs_reg()))); |
| 3439 TraceRegWr(get_register(rt_reg()), WORD_DWORD); |
3351 break; | 3440 break; |
3352 case DMFC1: | 3441 case DMFC1: |
3353 set_register(rt_reg(), get_fpu_register(fs_reg())); | 3442 SetResult(rt_reg(), get_fpu_register(fs_reg())); |
3354 break; | 3443 break; |
3355 case MFHC1: | 3444 case MFHC1: |
3356 set_register(rt_reg(), get_fpu_register_hi_word(fs_reg())); | 3445 SetResult(rt_reg(), get_fpu_register_hi_word(fs_reg())); |
3357 break; | 3446 break; |
3358 case CTC1: { | 3447 case CTC1: { |
3359 // At the moment only FCSR is supported. | 3448 // At the moment only FCSR is supported. |
3360 DCHECK(fs_reg() == kFCSRRegister); | 3449 DCHECK(fs_reg() == kFCSRRegister); |
3361 uint32_t reg = static_cast<uint32_t>(rt()); | 3450 uint32_t reg = static_cast<uint32_t>(rt()); |
3362 if (kArchVariant == kMips64r6) { | 3451 if (kArchVariant == kMips64r6) { |
3363 FCSR_ = reg | kFCSRNaN2008FlagMask; | 3452 FCSR_ = reg | kFCSRNaN2008FlagMask; |
3364 } else { | 3453 } else { |
3365 DCHECK(kArchVariant == kMips64r2); | 3454 DCHECK(kArchVariant == kMips64r2); |
3366 FCSR_ = reg & ~kFCSRNaN2008FlagMask; | 3455 FCSR_ = reg & ~kFCSRNaN2008FlagMask; |
3367 } | 3456 } |
| 3457 TraceRegWr(FCSR_); |
3368 break; | 3458 break; |
3369 } | 3459 } |
3370 case MTC1: | 3460 case MTC1: |
3371 // Hardware writes upper 32-bits to zero on mtc1. | 3461 // Hardware writes upper 32-bits to zero on mtc1. |
3372 set_fpu_register_hi_word(fs_reg(), 0); | 3462 set_fpu_register_hi_word(fs_reg(), 0); |
3373 set_fpu_register_word(fs_reg(), static_cast<int32_t>(rt())); | 3463 set_fpu_register_word(fs_reg(), static_cast<int32_t>(rt())); |
| 3464 TraceRegWr(get_fpu_register(fs_reg()), FLOAT_DOUBLE); |
3374 break; | 3465 break; |
3375 case DMTC1: | 3466 case DMTC1: |
3376 set_fpu_register(fs_reg(), rt()); | 3467 SetFPUResult2(fs_reg(), rt()); |
3377 break; | 3468 break; |
3378 case MTHC1: | 3469 case MTHC1: |
3379 set_fpu_register_hi_word(fs_reg(), static_cast<int32_t>(rt())); | 3470 set_fpu_register_hi_word(fs_reg(), static_cast<int32_t>(rt())); |
| 3471 TraceRegWr(get_fpu_register(fs_reg()), DOUBLE); |
3380 break; | 3472 break; |
3381 case S: | 3473 case S: |
3382 DecodeTypeRegisterSRsType(); | 3474 DecodeTypeRegisterSRsType(); |
3383 break; | 3475 break; |
3384 case D: | 3476 case D: |
3385 DecodeTypeRegisterDRsType(); | 3477 DecodeTypeRegisterDRsType(); |
3386 break; | 3478 break; |
3387 case W: | 3479 case W: |
3388 DecodeTypeRegisterWRsType(); | 3480 DecodeTypeRegisterWRsType(); |
3389 break; | 3481 break; |
3390 case L: | 3482 case L: |
3391 DecodeTypeRegisterLRsType(); | 3483 DecodeTypeRegisterLRsType(); |
3392 break; | 3484 break; |
3393 default: | 3485 default: |
3394 UNREACHABLE(); | 3486 UNREACHABLE(); |
3395 } | 3487 } |
3396 } | 3488 } |
3397 | 3489 |
3398 | 3490 |
3399 void Simulator::DecodeTypeRegisterCOP1X() { | 3491 void Simulator::DecodeTypeRegisterCOP1X() { |
3400 switch (instr_.FunctionFieldRaw()) { | 3492 switch (instr_.FunctionFieldRaw()) { |
3401 case MADD_S: { | 3493 case MADD_S: { |
3402 DCHECK(kArchVariant == kMips64r2); | 3494 DCHECK(kArchVariant == kMips64r2); |
3403 float fr, ft, fs; | 3495 float fr, ft, fs; |
3404 fr = get_fpu_register_float(fr_reg()); | 3496 fr = get_fpu_register_float(fr_reg()); |
3405 fs = get_fpu_register_float(fs_reg()); | 3497 fs = get_fpu_register_float(fs_reg()); |
3406 ft = get_fpu_register_float(ft_reg()); | 3498 ft = get_fpu_register_float(ft_reg()); |
3407 set_fpu_register_float(fd_reg(), fs * ft + fr); | 3499 SetFPUFloatResult(fd_reg(), fs * ft + fr); |
3408 break; | 3500 break; |
3409 } | 3501 } |
3410 case MSUB_S: { | 3502 case MSUB_S: { |
3411 DCHECK(kArchVariant == kMips64r2); | 3503 DCHECK(kArchVariant == kMips64r2); |
3412 float fr, ft, fs; | 3504 float fr, ft, fs; |
3413 fr = get_fpu_register_float(fr_reg()); | 3505 fr = get_fpu_register_float(fr_reg()); |
3414 fs = get_fpu_register_float(fs_reg()); | 3506 fs = get_fpu_register_float(fs_reg()); |
3415 ft = get_fpu_register_float(ft_reg()); | 3507 ft = get_fpu_register_float(ft_reg()); |
3416 set_fpu_register_float(fd_reg(), fs * ft - fr); | 3508 SetFPUFloatResult(fd_reg(), fs * ft - fr); |
3417 break; | 3509 break; |
3418 } | 3510 } |
3419 case MADD_D: { | 3511 case MADD_D: { |
3420 DCHECK(kArchVariant == kMips64r2); | 3512 DCHECK(kArchVariant == kMips64r2); |
3421 double fr, ft, fs; | 3513 double fr, ft, fs; |
3422 fr = get_fpu_register_double(fr_reg()); | 3514 fr = get_fpu_register_double(fr_reg()); |
3423 fs = get_fpu_register_double(fs_reg()); | 3515 fs = get_fpu_register_double(fs_reg()); |
3424 ft = get_fpu_register_double(ft_reg()); | 3516 ft = get_fpu_register_double(ft_reg()); |
3425 set_fpu_register_double(fd_reg(), fs * ft + fr); | 3517 SetFPUDoubleResult(fd_reg(), fs * ft + fr); |
3426 break; | 3518 break; |
3427 } | 3519 } |
3428 case MSUB_D: { | 3520 case MSUB_D: { |
3429 DCHECK(kArchVariant == kMips64r2); | 3521 DCHECK(kArchVariant == kMips64r2); |
3430 double fr, ft, fs; | 3522 double fr, ft, fs; |
3431 fr = get_fpu_register_double(fr_reg()); | 3523 fr = get_fpu_register_double(fr_reg()); |
3432 fs = get_fpu_register_double(fs_reg()); | 3524 fs = get_fpu_register_double(fs_reg()); |
3433 ft = get_fpu_register_double(ft_reg()); | 3525 ft = get_fpu_register_double(ft_reg()); |
3434 set_fpu_register_double(fd_reg(), fs * ft - fr); | 3526 SetFPUDoubleResult(fd_reg(), fs * ft - fr); |
3435 break; | 3527 break; |
3436 } | 3528 } |
3437 default: | 3529 default: |
3438 UNREACHABLE(); | 3530 UNREACHABLE(); |
3439 } | 3531 } |
3440 } | 3532 } |
3441 | 3533 |
3442 | 3534 |
3443 void Simulator::DecodeTypeRegisterSPECIAL() { | 3535 void Simulator::DecodeTypeRegisterSPECIAL() { |
3444 int64_t i64hilo; | 3536 int64_t i64hilo; |
3445 uint64_t u64hilo; | 3537 uint64_t u64hilo; |
3446 int64_t alu_out; | 3538 int64_t alu_out; |
3447 bool do_interrupt = false; | 3539 bool do_interrupt = false; |
3448 | 3540 |
3449 switch (instr_.FunctionFieldRaw()) { | 3541 switch (instr_.FunctionFieldRaw()) { |
3450 case SELEQZ_S: | 3542 case SELEQZ_S: |
3451 DCHECK(kArchVariant == kMips64r6); | 3543 DCHECK(kArchVariant == kMips64r6); |
3452 set_register(rd_reg(), rt() == 0 ? rs() : 0); | 3544 SetResult(rd_reg(), rt() == 0 ? rs() : 0); |
3453 break; | 3545 break; |
3454 case SELNEZ_S: | 3546 case SELNEZ_S: |
3455 DCHECK(kArchVariant == kMips64r6); | 3547 DCHECK(kArchVariant == kMips64r6); |
3456 set_register(rd_reg(), rt() != 0 ? rs() : 0); | 3548 SetResult(rd_reg(), rt() != 0 ? rs() : 0); |
3457 break; | 3549 break; |
3458 case JR: { | 3550 case JR: { |
3459 int64_t next_pc = rs(); | 3551 int64_t next_pc = rs(); |
3460 int64_t current_pc = get_pc(); | 3552 int64_t current_pc = get_pc(); |
3461 Instruction* branch_delay_instr = | 3553 Instruction* branch_delay_instr = |
3462 reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize); | 3554 reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize); |
3463 BranchDelayInstructionDecode(branch_delay_instr); | 3555 BranchDelayInstructionDecode(branch_delay_instr); |
3464 set_pc(next_pc); | 3556 set_pc(next_pc); |
3465 pc_modified_ = true; | 3557 pc_modified_ = true; |
3466 break; | 3558 break; |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3629 case MULT: { // MULT == D_MUL_MUH. | 3721 case MULT: { // MULT == D_MUL_MUH. |
3630 int32_t rs_lo = static_cast<int32_t>(rs()); | 3722 int32_t rs_lo = static_cast<int32_t>(rs()); |
3631 int32_t rt_lo = static_cast<int32_t>(rt()); | 3723 int32_t rt_lo = static_cast<int32_t>(rt()); |
3632 i64hilo = static_cast<int64_t>(rs_lo) * static_cast<int64_t>(rt_lo); | 3724 i64hilo = static_cast<int64_t>(rs_lo) * static_cast<int64_t>(rt_lo); |
3633 if (kArchVariant != kMips64r6) { | 3725 if (kArchVariant != kMips64r6) { |
3634 set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff)); | 3726 set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff)); |
3635 set_register(HI, static_cast<int32_t>(i64hilo >> 32)); | 3727 set_register(HI, static_cast<int32_t>(i64hilo >> 32)); |
3636 } else { | 3728 } else { |
3637 switch (sa()) { | 3729 switch (sa()) { |
3638 case MUL_OP: | 3730 case MUL_OP: |
3639 set_register(rd_reg(), static_cast<int32_t>(i64hilo & 0xffffffff)); | 3731 SetResult(rd_reg(), static_cast<int32_t>(i64hilo & 0xffffffff)); |
3640 break; | 3732 break; |
3641 case MUH_OP: | 3733 case MUH_OP: |
3642 set_register(rd_reg(), static_cast<int32_t>(i64hilo >> 32)); | 3734 SetResult(rd_reg(), static_cast<int32_t>(i64hilo >> 32)); |
3643 break; | 3735 break; |
3644 default: | 3736 default: |
3645 UNIMPLEMENTED_MIPS(); | 3737 UNIMPLEMENTED_MIPS(); |
3646 break; | 3738 break; |
3647 } | 3739 } |
3648 } | 3740 } |
3649 break; | 3741 break; |
3650 } | 3742 } |
3651 case MULTU: | 3743 case MULTU: |
3652 u64hilo = static_cast<uint64_t>(rs_u() & 0xffffffff) * | 3744 u64hilo = static_cast<uint64_t>(rs_u() & 0xffffffff) * |
3653 static_cast<uint64_t>(rt_u() & 0xffffffff); | 3745 static_cast<uint64_t>(rt_u() & 0xffffffff); |
3654 if (kArchVariant != kMips64r6) { | 3746 if (kArchVariant != kMips64r6) { |
3655 set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff)); | 3747 set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff)); |
3656 set_register(HI, static_cast<int32_t>(u64hilo >> 32)); | 3748 set_register(HI, static_cast<int32_t>(u64hilo >> 32)); |
3657 } else { | 3749 } else { |
3658 switch (sa()) { | 3750 switch (sa()) { |
3659 case MUL_OP: | 3751 case MUL_OP: |
3660 set_register(rd_reg(), static_cast<int32_t>(u64hilo & 0xffffffff)); | 3752 SetResult(rd_reg(), static_cast<int32_t>(u64hilo & 0xffffffff)); |
3661 break; | 3753 break; |
3662 case MUH_OP: | 3754 case MUH_OP: |
3663 set_register(rd_reg(), static_cast<int32_t>(u64hilo >> 32)); | 3755 SetResult(rd_reg(), static_cast<int32_t>(u64hilo >> 32)); |
3664 break; | 3756 break; |
3665 default: | 3757 default: |
3666 UNIMPLEMENTED_MIPS(); | 3758 UNIMPLEMENTED_MIPS(); |
3667 break; | 3759 break; |
3668 } | 3760 } |
3669 } | 3761 } |
3670 break; | 3762 break; |
3671 case DMULT: // DMULT == D_MUL_MUH. | 3763 case DMULT: // DMULT == D_MUL_MUH. |
3672 if (kArchVariant != kMips64r6) { | 3764 if (kArchVariant != kMips64r6) { |
3673 set_register(LO, rs() * rt()); | 3765 set_register(LO, rs() * rt()); |
3674 set_register(HI, MultiplyHighSigned(rs(), rt())); | 3766 set_register(HI, MultiplyHighSigned(rs(), rt())); |
3675 } else { | 3767 } else { |
3676 switch (sa()) { | 3768 switch (sa()) { |
3677 case MUL_OP: | 3769 case MUL_OP: |
3678 set_register(rd_reg(), rs() * rt()); | 3770 SetResult(rd_reg(), rs() * rt()); |
3679 break; | 3771 break; |
3680 case MUH_OP: | 3772 case MUH_OP: |
3681 set_register(rd_reg(), MultiplyHighSigned(rs(), rt())); | 3773 SetResult(rd_reg(), MultiplyHighSigned(rs(), rt())); |
3682 break; | 3774 break; |
3683 default: | 3775 default: |
3684 UNIMPLEMENTED_MIPS(); | 3776 UNIMPLEMENTED_MIPS(); |
3685 break; | 3777 break; |
3686 } | 3778 } |
3687 } | 3779 } |
3688 break; | 3780 break; |
3689 case DMULTU: | 3781 case DMULTU: |
3690 UNIMPLEMENTED_MIPS(); | 3782 UNIMPLEMENTED_MIPS(); |
3691 break; | 3783 break; |
(...skipping 12 matching lines...) Expand all Loading... |
3704 set_register(HI, 0); | 3796 set_register(HI, 0); |
3705 } else if (rt() != 0) { | 3797 } else if (rt() != 0) { |
3706 set_register(LO, rs() / rt()); | 3798 set_register(LO, rs() / rt()); |
3707 set_register(HI, rs() % rt()); | 3799 set_register(HI, rs() % rt()); |
3708 } | 3800 } |
3709 break; | 3801 break; |
3710 case kMips64r6: | 3802 case kMips64r6: |
3711 switch (sa()) { | 3803 switch (sa()) { |
3712 case DIV_OP: | 3804 case DIV_OP: |
3713 if (rs() == int_min_value && rt() == -1) { | 3805 if (rs() == int_min_value && rt() == -1) { |
3714 set_register(rd_reg(), int_min_value); | 3806 SetResult(rd_reg(), int_min_value); |
3715 } else if (rt() != 0) { | 3807 } else if (rt() != 0) { |
3716 set_register(rd_reg(), rs() / rt()); | 3808 SetResult(rd_reg(), rs() / rt()); |
3717 } | 3809 } |
3718 break; | 3810 break; |
3719 case MOD_OP: | 3811 case MOD_OP: |
3720 if (rs() == int_min_value && rt() == -1) { | 3812 if (rs() == int_min_value && rt() == -1) { |
3721 set_register(rd_reg(), 0); | 3813 SetResult(rd_reg(), 0); |
3722 } else if (rt() != 0) { | 3814 } else if (rt() != 0) { |
3723 set_register(rd_reg(), rs() % rt()); | 3815 SetResult(rd_reg(), rs() % rt()); |
3724 } | 3816 } |
3725 break; | 3817 break; |
3726 default: | 3818 default: |
3727 UNIMPLEMENTED_MIPS(); | 3819 UNIMPLEMENTED_MIPS(); |
3728 break; | 3820 break; |
3729 } | 3821 } |
3730 break; | 3822 break; |
3731 default: | 3823 default: |
3732 break; | 3824 break; |
3733 } | 3825 } |
3734 break; | 3826 break; |
3735 } | 3827 } |
3736 case DIVU: | 3828 case DIVU: |
3737 switch (kArchVariant) { | 3829 switch (kArchVariant) { |
3738 case kMips64r6: { | 3830 case kMips64r6: { |
3739 uint32_t rt_u_32 = static_cast<uint32_t>(rt_u()); | 3831 uint32_t rt_u_32 = static_cast<uint32_t>(rt_u()); |
3740 uint32_t rs_u_32 = static_cast<uint32_t>(rs_u()); | 3832 uint32_t rs_u_32 = static_cast<uint32_t>(rs_u()); |
3741 switch (sa()) { | 3833 switch (sa()) { |
3742 case DIV_OP: | 3834 case DIV_OP: |
3743 if (rt_u_32 != 0) { | 3835 if (rt_u_32 != 0) { |
3744 set_register(rd_reg(), rs_u_32 / rt_u_32); | 3836 SetResult(rd_reg(), rs_u_32 / rt_u_32); |
3745 } | 3837 } |
3746 break; | 3838 break; |
3747 case MOD_OP: | 3839 case MOD_OP: |
3748 if (rt_u() != 0) { | 3840 if (rt_u() != 0) { |
3749 set_register(rd_reg(), rs_u_32 % rt_u_32); | 3841 SetResult(rd_reg(), rs_u_32 % rt_u_32); |
3750 } | 3842 } |
3751 break; | 3843 break; |
3752 default: | 3844 default: |
3753 UNIMPLEMENTED_MIPS(); | 3845 UNIMPLEMENTED_MIPS(); |
3754 break; | 3846 break; |
3755 } | 3847 } |
3756 } break; | 3848 } break; |
3757 default: { | 3849 default: { |
3758 if (rt_u() != 0) { | 3850 if (rt_u() != 0) { |
3759 uint32_t rt_u_32 = static_cast<uint32_t>(rt_u()); | 3851 uint32_t rt_u_32 = static_cast<uint32_t>(rt_u()); |
3760 uint32_t rs_u_32 = static_cast<uint32_t>(rs_u()); | 3852 uint32_t rs_u_32 = static_cast<uint32_t>(rs_u()); |
3761 set_register(LO, rs_u_32 / rt_u_32); | 3853 set_register(LO, rs_u_32 / rt_u_32); |
3762 set_register(HI, rs_u_32 % rt_u_32); | 3854 set_register(HI, rs_u_32 % rt_u_32); |
3763 } | 3855 } |
3764 } | 3856 } |
3765 } | 3857 } |
3766 break; | 3858 break; |
3767 case DDIVU: | 3859 case DDIVU: |
3768 switch (kArchVariant) { | 3860 switch (kArchVariant) { |
3769 case kMips64r6: { | 3861 case kMips64r6: { |
3770 switch (instr_.SaValue()) { | 3862 switch (instr_.SaValue()) { |
3771 case DIV_OP: | 3863 case DIV_OP: |
3772 if (rt_u() != 0) { | 3864 if (rt_u() != 0) { |
3773 set_register(rd_reg(), rs_u() / rt_u()); | 3865 SetResult(rd_reg(), rs_u() / rt_u()); |
3774 } | 3866 } |
3775 break; | 3867 break; |
3776 case MOD_OP: | 3868 case MOD_OP: |
3777 if (rt_u() != 0) { | 3869 if (rt_u() != 0) { |
3778 set_register(rd_reg(), rs_u() % rt_u()); | 3870 SetResult(rd_reg(), rs_u() % rt_u()); |
3779 } | 3871 } |
3780 break; | 3872 break; |
3781 default: | 3873 default: |
3782 UNIMPLEMENTED_MIPS(); | 3874 UNIMPLEMENTED_MIPS(); |
3783 break; | 3875 break; |
3784 } | 3876 } |
3785 } break; | 3877 } break; |
3786 default: { | 3878 default: { |
3787 if (rt_u() != 0) { | 3879 if (rt_u() != 0) { |
3788 set_register(LO, rs_u() / rt_u()); | 3880 set_register(LO, rs_u() / rt_u()); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3885 // Conditional moves. | 3977 // Conditional moves. |
3886 case MOVN: | 3978 case MOVN: |
3887 if (rt()) { | 3979 if (rt()) { |
3888 SetResult(rd_reg(), rs()); | 3980 SetResult(rd_reg(), rs()); |
3889 } | 3981 } |
3890 break; | 3982 break; |
3891 case MOVCI: { | 3983 case MOVCI: { |
3892 uint32_t cc = instr_.FBccValue(); | 3984 uint32_t cc = instr_.FBccValue(); |
3893 uint32_t fcsr_cc = get_fcsr_condition_bit(cc); | 3985 uint32_t fcsr_cc = get_fcsr_condition_bit(cc); |
3894 if (instr_.Bit(16)) { // Read Tf bit. | 3986 if (instr_.Bit(16)) { // Read Tf bit. |
3895 if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs()); | 3987 if (test_fcsr_bit(fcsr_cc)) SetResult(rd_reg(), rs()); |
3896 } else { | 3988 } else { |
3897 if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg(), rs()); | 3989 if (!test_fcsr_bit(fcsr_cc)) SetResult(rd_reg(), rs()); |
3898 } | 3990 } |
3899 break; | 3991 break; |
3900 } | 3992 } |
3901 case MOVZ: | 3993 case MOVZ: |
3902 if (!rt()) { | 3994 if (!rt()) { |
3903 SetResult(rd_reg(), rs()); | 3995 SetResult(rd_reg(), rs()); |
3904 } | 3996 } |
3905 break; | 3997 break; |
3906 default: | 3998 default: |
3907 UNREACHABLE(); | 3999 UNREACHABLE(); |
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4682 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; | 4774 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; |
4683 uint64_t mask = (1UL << al_offset * 8) - 1; | 4775 uint64_t mask = (1UL << al_offset * 8) - 1; |
4684 addr = rs + se_imm16 - al_offset; | 4776 addr = rs + se_imm16 - al_offset; |
4685 uint64_t mem_value = Read2W(addr, instr_.instr()); | 4777 uint64_t mem_value = Read2W(addr, instr_.instr()); |
4686 mem_value = (rt << al_offset * 8) | (mem_value & mask); | 4778 mem_value = (rt << al_offset * 8) | (mem_value & mask); |
4687 Write2W(addr, mem_value, instr_.instr()); | 4779 Write2W(addr, mem_value, instr_.instr()); |
4688 break; | 4780 break; |
4689 } | 4781 } |
4690 case LWC1: | 4782 case LWC1: |
4691 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits. | 4783 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits. |
4692 set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr_.instr())); | 4784 set_fpu_register_word(ft_reg, |
| 4785 ReadW(rs + se_imm16, instr_.instr(), FLOAT_DOUBLE)); |
4693 break; | 4786 break; |
4694 case LDC1: | 4787 case LDC1: |
4695 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr_.instr())); | 4788 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr_.instr())); |
| 4789 TraceMemRd(addr, get_fpu_register(ft_reg), DOUBLE); |
4696 break; | 4790 break; |
4697 case SWC1: { | 4791 case SWC1: { |
4698 int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg)); | 4792 int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg)); |
4699 WriteW(rs + se_imm16, alu_out_32, instr_.instr()); | 4793 WriteW(rs + se_imm16, alu_out_32, instr_.instr()); |
4700 break; | 4794 break; |
4701 } | 4795 } |
4702 case SDC1: | 4796 case SDC1: |
4703 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr_.instr()); | 4797 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr_.instr()); |
| 4798 TraceMemWr(rs + se_imm16, get_fpu_register(ft_reg), DWORD); |
4704 break; | 4799 break; |
4705 // ------------- PC-Relative instructions. | 4800 // ------------- PC-Relative instructions. |
4706 case PCREL: { | 4801 case PCREL: { |
4707 // rt field: checking 5-bits. | 4802 // rt field: checking 5-bits. |
4708 int32_t imm21 = instr_.Imm21Value(); | 4803 int32_t imm21 = instr_.Imm21Value(); |
4709 int64_t current_pc = get_pc(); | 4804 int64_t current_pc = get_pc(); |
4710 uint8_t rt = (imm21 >> kImm16Bits); | 4805 uint8_t rt = (imm21 >> kImm16Bits); |
4711 switch (rt) { | 4806 switch (rt) { |
4712 case ALUIPC: | 4807 case ALUIPC: |
4713 addr = current_pc + (se_imm16 << 16); | 4808 addr = current_pc + (se_imm16 << 16); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4757 default: | 4852 default: |
4758 UNREACHABLE(); | 4853 UNREACHABLE(); |
4759 break; | 4854 break; |
4760 } | 4855 } |
4761 break; | 4856 break; |
4762 } | 4857 } |
4763 } | 4858 } |
4764 break; | 4859 break; |
4765 } | 4860 } |
4766 } | 4861 } |
4767 set_register(rs_reg, alu_out); | 4862 SetResult(rs_reg, alu_out); |
4768 break; | 4863 break; |
4769 } | 4864 } |
4770 default: | 4865 default: |
4771 UNREACHABLE(); | 4866 UNREACHABLE(); |
4772 } | 4867 } |
4773 | 4868 |
4774 if (execute_branch_delay_instruction) { | 4869 if (execute_branch_delay_instruction) { |
4775 // Execute branch delay slot | 4870 // Execute branch delay slot |
4776 // We don't check for end_sim_pc. First it should not be met as the current | 4871 // We don't check for end_sim_pc. First it should not be met as the current |
4777 // pc is valid. Secondly a jump should always execute its branch delay slot. | 4872 // pc is valid. Secondly a jump should always execute its branch delay slot. |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5052 } | 5147 } |
5053 | 5148 |
5054 | 5149 |
5055 #undef UNSUPPORTED | 5150 #undef UNSUPPORTED |
5056 } // namespace internal | 5151 } // namespace internal |
5057 } // namespace v8 | 5152 } // namespace v8 |
5058 | 5153 |
5059 #endif // USE_SIMULATOR | 5154 #endif // USE_SIMULATOR |
5060 | 5155 |
5061 #endif // V8_TARGET_ARCH_MIPS64 | 5156 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |