Chromium Code Reviews| 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: | |
|
ivica.bogosavljevic
2017/01/23 13:22:38
Everything mentioned in simulator-mips.cc applies
Ilija.Pavlovic1
2017/01/27 09:10:12
Done.
| |
| 1670 break; | |
| 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_, |
| 1640 SNPrintF(trace_buf_, | 1689 "%016" PRIx64 " <-- [%016" PRIx64 " ] (%" PRId64 |
| 1641 "%016" PRIx64 " <-- [%016" PRIx64 " ] (%" PRId64 " )", value, | 1690 ") int32:%" PRId32 " uint32:%" PRIu32, |
| 1642 addr, icount_); | 1691 v.fmt_int64, addr, icount_, v.fmt_int32[0], v.fmt_int32[0]); |
| 1692 break; | |
| 1693 case DWORD: | |
| 1694 SNPrintF(trace_buf_, | |
| 1695 "%016" PRIx64 " <-- [%016" PRIx64 " ] (%" PRId64 | |
| 1696 ") int64:%" PRId64 " uint64:%" PRIu64, | |
| 1697 value, addr, icount_, value, value); | |
| 1698 break; | |
| 1699 case FLOAT: | |
| 1700 SNPrintF(trace_buf_, "%016" PRIx64 " <-- [%016" PRIx64 | |
| 1701 " ] (%" PRId64 ") flt:%e", | |
| 1702 v.fmt_int64, addr, icount_, v.fmt_float[0]); | |
| 1703 break; | |
| 1704 case DOUBLE: | |
| 1705 SNPrintF(trace_buf_, "%016" PRIx64 " <-- [%016" PRIx64 | |
| 1706 " ] (%" PRId64 ") dbl:%e", | |
| 1707 v.fmt_int64, addr, icount_, v.fmt_double); | |
| 1708 break; | |
| 1709 case FLOAT_DOUBLE: | |
| 1710 SNPrintF(trace_buf_, "%016" PRIx64 " <-- [%016" PRIx64 | |
| 1711 " ] (%" PRId64 ") flt:%e dbl:%e", | |
| 1712 v.fmt_int64, addr, icount_, v.fmt_float[0], v.fmt_double); | |
| 1713 break; | |
| 1714 default: | |
| 1715 break; | |
| 1716 } | |
| 1643 } | 1717 } |
| 1644 } | 1718 } |
| 1645 | 1719 |
| 1646 | 1720 |
| 1647 void Simulator::TraceMemWr(int64_t addr, int64_t value, TraceType t) { | 1721 void Simulator::TraceMemWr(int64_t addr, int64_t value, TraceType t) { |
| 1648 if (::v8::internal::FLAG_trace_sim) { | 1722 if (::v8::internal::FLAG_trace_sim) { |
| 1649 switch (t) { | 1723 switch (t) { |
| 1650 case BYTE: | 1724 case BYTE: |
| 1651 SNPrintF(trace_buf_, " %02x --> [%016" PRIx64 " ]", | 1725 SNPrintF(trace_buf_, " %02" PRIx8 " --> [%016" PRIx64 |
| 1652 static_cast<int8_t>(value), addr); | 1726 " ] (%" PRId64 ")", |
| 1727 static_cast<uint8_t>(value), addr, icount_); | |
| 1653 break; | 1728 break; |
| 1654 case HALF: | 1729 case HALF: |
| 1655 SNPrintF(trace_buf_, " %04x --> [%016" PRIx64 " ]", | 1730 SNPrintF(trace_buf_, " %04" PRIx16 " --> [%016" PRIx64 |
| 1656 static_cast<int16_t>(value), addr); | 1731 " ] (%" PRId64 ")", |
| 1732 static_cast<uint16_t>(value), addr, icount_); | |
| 1657 break; | 1733 break; |
| 1658 case WORD: | 1734 case WORD: |
| 1659 SNPrintF(trace_buf_, " %08x --> [%016" PRIx64 " ]", | 1735 SNPrintF(trace_buf_, |
| 1660 static_cast<int32_t>(value), addr); | 1736 " %08" PRIx32 " --> [%016" PRIx64 " ] (%" PRId64 ")", |
| 1737 static_cast<uint32_t>(value), addr, icount_); | |
| 1661 break; | 1738 break; |
| 1662 case DWORD: | 1739 case DWORD: |
| 1663 SNPrintF(trace_buf_, | 1740 SNPrintF(trace_buf_, |
| 1664 "%016" PRIx64 " --> [%016" PRIx64 " ] (%" PRId64 " )", | 1741 "%016" PRIx64 " --> [%016" PRIx64 " ] (%" PRId64 " )", |
| 1665 value, addr, icount_); | 1742 value, addr, icount_); |
| 1666 break; | 1743 break; |
| 1744 default: | |
| 1745 break; | |
| 1667 } | 1746 } |
| 1668 } | 1747 } |
| 1669 } | 1748 } |
| 1670 | 1749 |
| 1671 | 1750 |
| 1672 // TODO(plind): sign-extend and zero-extend not implmented properly | 1751 // 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. | 1752 // on all the ReadXX functions, I don't think re-interpret cast does it. |
| 1674 int32_t Simulator::ReadW(int64_t addr, Instruction* instr) { | 1753 int32_t Simulator::ReadW(int64_t addr, Instruction* instr, TraceType t) { |
| 1675 if (addr >=0 && addr < 0x400) { | 1754 if (addr >=0 && addr < 0x400) { |
| 1676 // This has to be a NULL-dereference, drop into debugger. | 1755 // This has to be a NULL-dereference, drop into debugger. |
| 1677 PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR | 1756 PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR |
| 1678 " \n", | 1757 " \n", |
| 1679 addr, reinterpret_cast<intptr_t>(instr)); | 1758 addr, reinterpret_cast<intptr_t>(instr)); |
| 1680 DieOrDebug(); | 1759 DieOrDebug(); |
| 1681 } | 1760 } |
| 1682 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { | 1761 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { |
| 1683 int32_t* ptr = reinterpret_cast<int32_t*>(addr); | 1762 int32_t* ptr = reinterpret_cast<int32_t*>(addr); |
| 1684 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1763 TraceMemRd(addr, static_cast<int64_t>(*ptr), t); |
| 1685 return *ptr; | 1764 return *ptr; |
| 1686 } | 1765 } |
| 1687 PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, | 1766 PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, |
| 1688 reinterpret_cast<intptr_t>(instr)); | 1767 reinterpret_cast<intptr_t>(instr)); |
| 1689 DieOrDebug(); | 1768 DieOrDebug(); |
| 1690 return 0; | 1769 return 0; |
| 1691 } | 1770 } |
| 1692 | 1771 |
| 1693 | 1772 |
| 1694 uint32_t Simulator::ReadWU(int64_t addr, Instruction* instr) { | 1773 uint32_t Simulator::ReadWU(int64_t addr, Instruction* instr) { |
| 1695 if (addr >=0 && addr < 0x400) { | 1774 if (addr >=0 && addr < 0x400) { |
| 1696 // This has to be a NULL-dereference, drop into debugger. | 1775 // This has to be a NULL-dereference, drop into debugger. |
| 1697 PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR | 1776 PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR |
| 1698 " \n", | 1777 " \n", |
| 1699 addr, reinterpret_cast<intptr_t>(instr)); | 1778 addr, reinterpret_cast<intptr_t>(instr)); |
| 1700 DieOrDebug(); | 1779 DieOrDebug(); |
| 1701 } | 1780 } |
| 1702 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { | 1781 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { |
| 1703 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); | 1782 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); |
| 1704 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1783 TraceMemRd(addr, static_cast<int64_t>(*ptr), WORD); |
| 1705 return *ptr; | 1784 return *ptr; |
| 1706 } | 1785 } |
| 1707 PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, | 1786 PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, |
| 1708 reinterpret_cast<intptr_t>(instr)); | 1787 reinterpret_cast<intptr_t>(instr)); |
| 1709 DieOrDebug(); | 1788 DieOrDebug(); |
| 1710 return 0; | 1789 return 0; |
| 1711 } | 1790 } |
| 1712 | 1791 |
| 1713 | 1792 |
| 1714 void Simulator::WriteW(int64_t addr, int32_t value, Instruction* instr) { | 1793 void Simulator::WriteW(int64_t addr, int32_t value, Instruction* instr) { |
| (...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2452 result = upper; | 2531 result = upper; |
| 2453 break; | 2532 break; |
| 2454 case kRoundToMinusInf: | 2533 case kRoundToMinusInf: |
| 2455 result = lower; | 2534 result = lower; |
| 2456 break; | 2535 break; |
| 2457 } | 2536 } |
| 2458 set_fpu_register_float(fd_reg(), result); | 2537 set_fpu_register_float(fd_reg(), result); |
| 2459 if (result != fs) { | 2538 if (result != fs) { |
| 2460 set_fcsr_bit(kFCSRInexactFlagBit, true); | 2539 set_fcsr_bit(kFCSRInexactFlagBit, true); |
| 2461 } | 2540 } |
| 2541 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2462 break; | 2542 break; |
| 2463 } | 2543 } |
| 2464 case ADD_S: | 2544 case ADD_S: |
| 2465 set_fpu_register_float( | 2545 set_fpu_register_float( |
| 2466 fd_reg(), | 2546 fd_reg(), |
| 2467 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs + rhs; }, | 2547 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs + rhs; }, |
| 2468 fs, ft)); | 2548 fs, ft)); |
| 2549 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2469 break; | 2550 break; |
| 2470 case SUB_S: | 2551 case SUB_S: |
| 2471 set_fpu_register_float( | 2552 set_fpu_register_float( |
| 2472 fd_reg(), | 2553 fd_reg(), |
| 2473 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs - rhs; }, | 2554 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs - rhs; }, |
| 2474 fs, ft)); | 2555 fs, ft)); |
| 2556 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2475 break; | 2557 break; |
| 2476 case MADDF_S: | 2558 case MADDF_S: |
| 2477 DCHECK(kArchVariant == kMips64r6); | 2559 DCHECK(kArchVariant == kMips64r6); |
| 2478 set_fpu_register_float(fd_reg(), std::fma(fs, ft, fd)); | 2560 set_fpu_register_float(fd_reg(), std::fma(fs, ft, fd)); |
| 2561 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2479 break; | 2562 break; |
| 2480 case MSUBF_S: | 2563 case MSUBF_S: |
| 2481 DCHECK(kArchVariant == kMips64r6); | 2564 DCHECK(kArchVariant == kMips64r6); |
| 2482 set_fpu_register_float(fd_reg(), std::fma(-fs, ft, fd)); | 2565 set_fpu_register_float(fd_reg(), std::fma(-fs, ft, fd)); |
| 2566 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2483 break; | 2567 break; |
| 2484 case MUL_S: | 2568 case MUL_S: |
| 2485 set_fpu_register_float( | 2569 set_fpu_register_float( |
| 2486 fd_reg(), | 2570 fd_reg(), |
| 2487 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs * rhs; }, | 2571 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs * rhs; }, |
| 2488 fs, ft)); | 2572 fs, ft)); |
| 2573 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2489 break; | 2574 break; |
| 2490 case DIV_S: | 2575 case DIV_S: |
| 2491 set_fpu_register_float( | 2576 set_fpu_register_float( |
| 2492 fd_reg(), | 2577 fd_reg(), |
| 2493 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs / rhs; }, | 2578 FPUCanonalizeOperation([](float lhs, float rhs) { return lhs / rhs; }, |
| 2494 fs, ft)); | 2579 fs, ft)); |
| 2580 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2495 break; | 2581 break; |
| 2496 case ABS_S: | 2582 case ABS_S: |
| 2497 set_fpu_register_float( | 2583 set_fpu_register_float( |
| 2498 fd_reg(), | 2584 fd_reg(), |
| 2499 FPUCanonalizeOperation([](float fs) { return FPAbs(fs); }, fs)); | 2585 FPUCanonalizeOperation([](float fs) { return FPAbs(fs); }, fs)); |
| 2586 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2500 break; | 2587 break; |
| 2501 case MOV_S: | 2588 case MOV_S: |
| 2502 set_fpu_register_float(fd_reg(), fs); | 2589 set_fpu_register_float(fd_reg(), fs); |
| 2590 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2503 break; | 2591 break; |
| 2504 case NEG_S: | 2592 case NEG_S: |
| 2505 set_fpu_register_float( | 2593 set_fpu_register_float( |
| 2506 fd_reg(), FPUCanonalizeOperation([](float src) { return -src; }, | 2594 fd_reg(), FPUCanonalizeOperation([](float src) { return -src; }, |
| 2507 KeepSign::yes, fs)); | 2595 KeepSign::yes, fs)); |
| 2596 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2508 break; | 2597 break; |
| 2509 case SQRT_S: | 2598 case SQRT_S: |
| 2510 set_fpu_register_float( | 2599 set_fpu_register_float( |
| 2511 fd_reg(), | 2600 fd_reg(), |
| 2512 FPUCanonalizeOperation([](float src) { return std::sqrt(src); }, fs)); | 2601 FPUCanonalizeOperation([](float src) { return std::sqrt(src); }, fs)); |
| 2602 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2513 break; | 2603 break; |
| 2514 case RSQRT_S: | 2604 case RSQRT_S: |
| 2515 set_fpu_register_float( | 2605 set_fpu_register_float( |
| 2516 fd_reg(), FPUCanonalizeOperation( | 2606 fd_reg(), FPUCanonalizeOperation( |
| 2517 [](float src) { return 1.0 / std::sqrt(src); }, fs)); | 2607 [](float src) { return 1.0 / std::sqrt(src); }, fs)); |
| 2608 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2518 break; | 2609 break; |
| 2519 case RECIP_S: | 2610 case RECIP_S: |
| 2520 set_fpu_register_float( | 2611 set_fpu_register_float( |
| 2521 fd_reg(), | 2612 fd_reg(), |
| 2522 FPUCanonalizeOperation([](float src) { return 1.0 / src; }, fs)); | 2613 FPUCanonalizeOperation([](float src) { return 1.0 / src; }, fs)); |
| 2614 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2523 break; | 2615 break; |
| 2524 case C_F_D: | 2616 case C_F_D: |
| 2525 set_fcsr_bit(fcsr_cc, false); | 2617 set_fcsr_bit(fcsr_cc, false); |
| 2618 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 2526 break; | 2619 break; |
| 2527 case C_UN_D: | 2620 case C_UN_D: |
| 2528 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); | 2621 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); |
| 2622 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 2529 break; | 2623 break; |
| 2530 case C_EQ_D: | 2624 case C_EQ_D: |
| 2531 set_fcsr_bit(fcsr_cc, (fs == ft)); | 2625 set_fcsr_bit(fcsr_cc, (fs == ft)); |
| 2626 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 2532 break; | 2627 break; |
| 2533 case C_UEQ_D: | 2628 case C_UEQ_D: |
| 2534 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); | 2629 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); |
| 2630 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 2535 break; | 2631 break; |
| 2536 case C_OLT_D: | 2632 case C_OLT_D: |
| 2537 set_fcsr_bit(fcsr_cc, (fs < ft)); | 2633 set_fcsr_bit(fcsr_cc, (fs < ft)); |
| 2634 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 2538 break; | 2635 break; |
| 2539 case C_ULT_D: | 2636 case C_ULT_D: |
| 2540 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); | 2637 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); |
| 2638 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 2541 break; | 2639 break; |
| 2542 case C_OLE_D: | 2640 case C_OLE_D: |
| 2543 set_fcsr_bit(fcsr_cc, (fs <= ft)); | 2641 set_fcsr_bit(fcsr_cc, (fs <= ft)); |
| 2642 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 2544 break; | 2643 break; |
| 2545 case C_ULE_D: | 2644 case C_ULE_D: |
| 2546 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); | 2645 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); |
| 2646 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 2547 break; | 2647 break; |
| 2548 case CVT_D_S: | 2648 case CVT_D_S: |
| 2549 set_fpu_register_double(fd_reg(), static_cast<double>(fs)); | 2649 set_fpu_register_double(fd_reg(), static_cast<double>(fs)); |
| 2650 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2550 break; | 2651 break; |
| 2551 case CLASS_S: { // Mips64r6 instruction | 2652 case CLASS_S: { // Mips64r6 instruction |
| 2552 // Convert float input to uint32_t for easier bit manipulation | 2653 // Convert float input to uint32_t for easier bit manipulation |
| 2553 uint32_t classed = bit_cast<uint32_t>(fs); | 2654 uint32_t classed = bit_cast<uint32_t>(fs); |
| 2554 | 2655 |
| 2555 // Extracting sign, exponent and mantissa from the input float | 2656 // Extracting sign, exponent and mantissa from the input float |
| 2556 uint32_t sign = (classed >> 31) & 1; | 2657 uint32_t sign = (classed >> 31) & 1; |
| 2557 uint32_t exponent = (classed >> 23) & 0x000000ff; | 2658 uint32_t exponent = (classed >> 23) & 0x000000ff; |
| 2558 uint32_t mantissa = classed & 0x007fffff; | 2659 uint32_t mantissa = classed & 0x007fffff; |
| 2559 uint32_t result; | 2660 uint32_t result; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2603 | 2704 |
| 2604 // Calculating result according to description of CLASS.S instruction | 2705 // Calculating result according to description of CLASS.S instruction |
| 2605 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | | 2706 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | |
| 2606 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | | 2707 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | |
| 2607 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; | 2708 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; |
| 2608 | 2709 |
| 2609 DCHECK(result != 0); | 2710 DCHECK(result != 0); |
| 2610 | 2711 |
| 2611 fResult = bit_cast<float>(result); | 2712 fResult = bit_cast<float>(result); |
| 2612 set_fpu_register_float(fd_reg(), fResult); | 2713 set_fpu_register_float(fd_reg(), fResult); |
| 2714 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2613 | 2715 |
| 2614 break; | 2716 break; |
| 2615 } | 2717 } |
| 2616 case CVT_L_S: { | 2718 case CVT_L_S: { |
| 2617 float rounded; | 2719 float rounded; |
| 2618 int64_t result; | 2720 int64_t result; |
| 2619 round64_according_to_fcsr(fs, rounded, result, fs); | 2721 round64_according_to_fcsr(fs, rounded, result, fs); |
| 2620 set_fpu_register(fd_reg(), result); | 2722 set_fpu_register(fd_reg(), result); |
| 2621 if (set_fcsr_round64_error(fs, rounded)) { | 2723 if (set_fcsr_round64_error(fs, rounded)) { |
| 2622 set_fpu_register_invalid_result64(fs, rounded); | 2724 set_fpu_register_invalid_result64(fs, rounded); |
| 2623 } | 2725 } |
| 2726 TraceRegWr(get_fpu_register(fd_reg())); | |
| 2624 break; | 2727 break; |
| 2625 } | 2728 } |
| 2626 case CVT_W_S: { | 2729 case CVT_W_S: { |
| 2627 float rounded; | 2730 float rounded; |
| 2628 int32_t result; | 2731 int32_t result; |
| 2629 round_according_to_fcsr(fs, rounded, result, fs); | 2732 round_according_to_fcsr(fs, rounded, result, fs); |
| 2630 set_fpu_register_word(fd_reg(), result); | 2733 set_fpu_register_word(fd_reg(), result); |
| 2631 if (set_fcsr_round_error(fs, rounded)) { | 2734 if (set_fcsr_round_error(fs, rounded)) { |
| 2632 set_fpu_register_word_invalid_result(fs, rounded); | 2735 set_fpu_register_word_invalid_result(fs, rounded); |
| 2633 } | 2736 } |
| 2737 TraceRegWr(get_fpu_register(fd_reg()), WORD); | |
| 2634 break; | 2738 break; |
| 2635 } | 2739 } |
| 2636 case TRUNC_W_S: { // Truncate single to word (round towards 0). | 2740 case TRUNC_W_S: { // Truncate single to word (round towards 0). |
| 2637 float rounded = trunc(fs); | 2741 float rounded = trunc(fs); |
| 2638 int32_t result = static_cast<int32_t>(rounded); | 2742 int32_t result = static_cast<int32_t>(rounded); |
| 2639 set_fpu_register_word(fd_reg(), result); | 2743 set_fpu_register_word(fd_reg(), result); |
| 2640 if (set_fcsr_round_error(fs, rounded)) { | 2744 if (set_fcsr_round_error(fs, rounded)) { |
| 2641 set_fpu_register_word_invalid_result(fs, rounded); | 2745 set_fpu_register_word_invalid_result(fs, rounded); |
| 2642 } | 2746 } |
| 2747 TraceRegWr(get_fpu_register(fd_reg()), WORD); | |
| 2643 } break; | 2748 } break; |
| 2644 case TRUNC_L_S: { // Mips64r2 instruction. | 2749 case TRUNC_L_S: { // Mips64r2 instruction. |
| 2645 float rounded = trunc(fs); | 2750 float rounded = trunc(fs); |
| 2646 int64_t result = static_cast<int64_t>(rounded); | 2751 int64_t result = static_cast<int64_t>(rounded); |
| 2647 set_fpu_register(fd_reg(), result); | 2752 set_fpu_register(fd_reg(), result); |
| 2648 if (set_fcsr_round64_error(fs, rounded)) { | 2753 if (set_fcsr_round64_error(fs, rounded)) { |
| 2649 set_fpu_register_invalid_result64(fs, rounded); | 2754 set_fpu_register_invalid_result64(fs, rounded); |
| 2650 } | 2755 } |
| 2756 TraceRegWr(get_fpu_register(fd_reg())); | |
| 2651 break; | 2757 break; |
| 2652 } | 2758 } |
| 2653 case ROUND_W_S: { | 2759 case ROUND_W_S: { |
| 2654 float rounded = std::floor(fs + 0.5); | 2760 float rounded = std::floor(fs + 0.5); |
| 2655 int32_t result = static_cast<int32_t>(rounded); | 2761 int32_t result = static_cast<int32_t>(rounded); |
| 2656 if ((result & 1) != 0 && result - fs == 0.5) { | 2762 if ((result & 1) != 0 && result - fs == 0.5) { |
| 2657 // If the number is halfway between two integers, | 2763 // If the number is halfway between two integers, |
| 2658 // round to the even one. | 2764 // round to the even one. |
| 2659 result--; | 2765 result--; |
| 2660 } | 2766 } |
| 2661 set_fpu_register_word(fd_reg(), result); | 2767 set_fpu_register_word(fd_reg(), result); |
| 2662 if (set_fcsr_round_error(fs, rounded)) { | 2768 if (set_fcsr_round_error(fs, rounded)) { |
| 2663 set_fpu_register_word_invalid_result(fs, rounded); | 2769 set_fpu_register_word_invalid_result(fs, rounded); |
| 2664 } | 2770 } |
| 2771 TraceRegWr(get_fpu_register(fd_reg()), WORD); | |
| 2665 break; | 2772 break; |
| 2666 } | 2773 } |
| 2667 case ROUND_L_S: { // Mips64r2 instruction. | 2774 case ROUND_L_S: { // Mips64r2 instruction. |
| 2668 float rounded = std::floor(fs + 0.5); | 2775 float rounded = std::floor(fs + 0.5); |
| 2669 int64_t result = static_cast<int64_t>(rounded); | 2776 int64_t result = static_cast<int64_t>(rounded); |
| 2670 if ((result & 1) != 0 && result - fs == 0.5) { | 2777 if ((result & 1) != 0 && result - fs == 0.5) { |
| 2671 // If the number is halfway between two integers, | 2778 // If the number is halfway between two integers, |
| 2672 // round to the even one. | 2779 // round to the even one. |
| 2673 result--; | 2780 result--; |
| 2674 } | 2781 } |
| 2675 int64_t i64 = static_cast<int64_t>(result); | 2782 int64_t i64 = static_cast<int64_t>(result); |
| 2676 set_fpu_register(fd_reg(), i64); | 2783 set_fpu_register(fd_reg(), i64); |
| 2677 if (set_fcsr_round64_error(fs, rounded)) { | 2784 if (set_fcsr_round64_error(fs, rounded)) { |
| 2678 set_fpu_register_invalid_result64(fs, rounded); | 2785 set_fpu_register_invalid_result64(fs, rounded); |
| 2679 } | 2786 } |
| 2787 TraceRegWr(get_fpu_register(fd_reg())); | |
| 2680 break; | 2788 break; |
| 2681 } | 2789 } |
| 2682 case FLOOR_L_S: { // Mips64r2 instruction. | 2790 case FLOOR_L_S: { // Mips64r2 instruction. |
| 2683 float rounded = floor(fs); | 2791 float rounded = floor(fs); |
| 2684 int64_t result = static_cast<int64_t>(rounded); | 2792 int64_t result = static_cast<int64_t>(rounded); |
| 2685 set_fpu_register(fd_reg(), result); | 2793 set_fpu_register(fd_reg(), result); |
| 2686 if (set_fcsr_round64_error(fs, rounded)) { | 2794 if (set_fcsr_round64_error(fs, rounded)) { |
| 2687 set_fpu_register_invalid_result64(fs, rounded); | 2795 set_fpu_register_invalid_result64(fs, rounded); |
| 2688 } | 2796 } |
| 2797 TraceRegWr(get_fpu_register(fd_reg())); | |
| 2689 break; | 2798 break; |
| 2690 } | 2799 } |
| 2691 case FLOOR_W_S: // Round double to word towards negative infinity. | 2800 case FLOOR_W_S: // Round double to word towards negative infinity. |
| 2692 { | 2801 { |
| 2693 float rounded = std::floor(fs); | 2802 float rounded = std::floor(fs); |
| 2694 int32_t result = static_cast<int32_t>(rounded); | 2803 int32_t result = static_cast<int32_t>(rounded); |
| 2695 set_fpu_register_word(fd_reg(), result); | 2804 set_fpu_register_word(fd_reg(), result); |
| 2696 if (set_fcsr_round_error(fs, rounded)) { | 2805 if (set_fcsr_round_error(fs, rounded)) { |
| 2697 set_fpu_register_word_invalid_result(fs, rounded); | 2806 set_fpu_register_word_invalid_result(fs, rounded); |
| 2698 } | 2807 } |
| 2808 TraceRegWr(get_fpu_register(fd_reg()), WORD); | |
| 2699 } break; | 2809 } break; |
| 2700 case CEIL_W_S: // Round double to word towards positive infinity. | 2810 case CEIL_W_S: // Round double to word towards positive infinity. |
| 2701 { | 2811 { |
| 2702 float rounded = std::ceil(fs); | 2812 float rounded = std::ceil(fs); |
| 2703 int32_t result = static_cast<int32_t>(rounded); | 2813 int32_t result = static_cast<int32_t>(rounded); |
| 2704 set_fpu_register_word(fd_reg(), result); | 2814 set_fpu_register_word(fd_reg(), result); |
| 2705 if (set_fcsr_round_error(fs, rounded)) { | 2815 if (set_fcsr_round_error(fs, rounded)) { |
| 2706 set_fpu_register_invalid_result(fs, rounded); | 2816 set_fpu_register_invalid_result(fs, rounded); |
| 2707 } | 2817 } |
| 2818 TraceRegWr(get_fpu_register(fd_reg()), WORD); | |
| 2708 } break; | 2819 } break; |
| 2709 case CEIL_L_S: { // Mips64r2 instruction. | 2820 case CEIL_L_S: { // Mips64r2 instruction. |
| 2710 float rounded = ceil(fs); | 2821 float rounded = ceil(fs); |
| 2711 int64_t result = static_cast<int64_t>(rounded); | 2822 int64_t result = static_cast<int64_t>(rounded); |
| 2712 set_fpu_register(fd_reg(), result); | 2823 set_fpu_register(fd_reg(), result); |
| 2713 if (set_fcsr_round64_error(fs, rounded)) { | 2824 if (set_fcsr_round64_error(fs, rounded)) { |
| 2714 set_fpu_register_invalid_result64(fs, rounded); | 2825 set_fpu_register_invalid_result64(fs, rounded); |
| 2715 } | 2826 } |
| 2827 TraceRegWr(get_fpu_register(fd_reg())); | |
| 2716 break; | 2828 break; |
| 2717 } | 2829 } |
| 2718 case MINA: | 2830 case MINA: |
| 2719 DCHECK(kArchVariant == kMips64r6); | 2831 DCHECK(kArchVariant == kMips64r6); |
| 2720 set_fpu_register_float(fd_reg(), FPUMinA(ft, fs)); | 2832 set_fpu_register_float(fd_reg(), FPUMinA(ft, fs)); |
| 2833 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2721 break; | 2834 break; |
| 2722 case MAXA: | 2835 case MAXA: |
| 2723 DCHECK(kArchVariant == kMips64r6); | 2836 DCHECK(kArchVariant == kMips64r6); |
| 2724 set_fpu_register_float(fd_reg(), FPUMaxA(ft, fs)); | 2837 set_fpu_register_float(fd_reg(), FPUMaxA(ft, fs)); |
| 2838 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2725 break; | 2839 break; |
| 2726 case MIN: | 2840 case MIN: |
| 2727 DCHECK(kArchVariant == kMips64r6); | 2841 DCHECK(kArchVariant == kMips64r6); |
| 2728 set_fpu_register_float(fd_reg(), FPUMin(ft, fs)); | 2842 set_fpu_register_float(fd_reg(), FPUMin(ft, fs)); |
| 2843 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2729 break; | 2844 break; |
| 2730 case MAX: | 2845 case MAX: |
| 2731 DCHECK(kArchVariant == kMips64r6); | 2846 DCHECK(kArchVariant == kMips64r6); |
| 2732 set_fpu_register_float(fd_reg(), FPUMax(ft, fs)); | 2847 set_fpu_register_float(fd_reg(), FPUMax(ft, fs)); |
| 2848 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2733 break; | 2849 break; |
| 2734 case SEL: | 2850 case SEL: |
| 2735 DCHECK(kArchVariant == kMips64r6); | 2851 DCHECK(kArchVariant == kMips64r6); |
| 2736 set_fpu_register_float(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); | 2852 set_fpu_register_float(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); |
| 2853 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2737 break; | 2854 break; |
| 2738 case SELEQZ_C: | 2855 case SELEQZ_C: |
| 2739 DCHECK(kArchVariant == kMips64r6); | 2856 DCHECK(kArchVariant == kMips64r6); |
| 2740 set_fpu_register_float(fd_reg(), (ft_int & 0x1) == 0 | 2857 set_fpu_register_float(fd_reg(), (ft_int & 0x1) == 0 |
| 2741 ? get_fpu_register_float(fs_reg()) | 2858 ? get_fpu_register_float(fs_reg()) |
| 2742 : 0.0); | 2859 : 0.0); |
| 2860 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2743 break; | 2861 break; |
| 2744 case SELNEZ_C: | 2862 case SELNEZ_C: |
| 2745 DCHECK(kArchVariant == kMips64r6); | 2863 DCHECK(kArchVariant == kMips64r6); |
| 2746 set_fpu_register_float(fd_reg(), (ft_int & 0x1) != 0 | 2864 set_fpu_register_float(fd_reg(), (ft_int & 0x1) != 0 |
| 2747 ? get_fpu_register_float(fs_reg()) | 2865 ? get_fpu_register_float(fs_reg()) |
| 2748 : 0.0); | 2866 : 0.0); |
| 2867 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2749 break; | 2868 break; |
| 2750 case MOVZ_C: { | 2869 case MOVZ_C: { |
| 2751 DCHECK(kArchVariant == kMips64r2); | 2870 DCHECK(kArchVariant == kMips64r2); |
| 2752 if (rt() == 0) { | 2871 if (rt() == 0) { |
| 2753 set_fpu_register_float(fd_reg(), fs); | 2872 set_fpu_register_float(fd_reg(), fs); |
| 2754 } | 2873 } |
| 2874 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2755 break; | 2875 break; |
| 2756 } | 2876 } |
| 2757 case MOVN_C: { | 2877 case MOVN_C: { |
| 2758 DCHECK(kArchVariant == kMips64r2); | 2878 DCHECK(kArchVariant == kMips64r2); |
| 2759 if (rt() != 0) { | 2879 if (rt() != 0) { |
| 2760 set_fpu_register_float(fd_reg(), fs); | 2880 set_fpu_register_float(fd_reg(), fs); |
| 2761 } | 2881 } |
| 2882 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2762 break; | 2883 break; |
| 2763 } | 2884 } |
| 2764 case MOVF: { | 2885 case MOVF: { |
| 2765 // Same function field for MOVT.D and MOVF.D | 2886 // Same function field for MOVT.D and MOVF.D |
| 2766 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; | 2887 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; |
| 2767 ft_cc = get_fcsr_condition_bit(ft_cc); | 2888 ft_cc = get_fcsr_condition_bit(ft_cc); |
| 2768 | 2889 |
| 2769 if (instr_.Bit(16)) { // Read Tf bit. | 2890 if (instr_.Bit(16)) { // Read Tf bit. |
| 2770 // MOVT.D | 2891 // MOVT.D |
| 2771 if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); | 2892 if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); |
| 2772 } else { | 2893 } else { |
| 2773 // MOVF.D | 2894 // MOVF.D |
| 2774 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); | 2895 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg(), fs); |
| 2775 } | 2896 } |
| 2897 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 2776 break; | 2898 break; |
| 2777 } | 2899 } |
| 2778 default: | 2900 default: |
| 2779 // TRUNC_W_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S | 2901 // 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. | 2902 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. |
| 2781 UNREACHABLE(); | 2903 UNREACHABLE(); |
| 2782 } | 2904 } |
| 2783 } | 2905 } |
| 2784 | 2906 |
| 2785 | 2907 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2823 result = upper; | 2945 result = upper; |
| 2824 break; | 2946 break; |
| 2825 case kRoundToMinusInf: | 2947 case kRoundToMinusInf: |
| 2826 result = lower; | 2948 result = lower; |
| 2827 break; | 2949 break; |
| 2828 } | 2950 } |
| 2829 set_fpu_register_double(fd_reg(), result); | 2951 set_fpu_register_double(fd_reg(), result); |
| 2830 if (result != fs) { | 2952 if (result != fs) { |
| 2831 set_fcsr_bit(kFCSRInexactFlagBit, true); | 2953 set_fcsr_bit(kFCSRInexactFlagBit, true); |
| 2832 } | 2954 } |
| 2955 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2833 break; | 2956 break; |
| 2834 } | 2957 } |
| 2835 case SEL: | 2958 case SEL: |
| 2836 DCHECK(kArchVariant == kMips64r6); | 2959 DCHECK(kArchVariant == kMips64r6); |
| 2837 set_fpu_register_double(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); | 2960 set_fpu_register_double(fd_reg(), (fd_int & 0x1) == 0 ? fs : ft); |
| 2961 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2838 break; | 2962 break; |
| 2839 case SELEQZ_C: | 2963 case SELEQZ_C: |
| 2840 DCHECK(kArchVariant == kMips64r6); | 2964 DCHECK(kArchVariant == kMips64r6); |
| 2841 set_fpu_register_double(fd_reg(), (ft_int & 0x1) == 0 ? fs : 0.0); | 2965 set_fpu_register_double(fd_reg(), (ft_int & 0x1) == 0 ? fs : 0.0); |
| 2966 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2842 break; | 2967 break; |
| 2843 case SELNEZ_C: | 2968 case SELNEZ_C: |
| 2844 DCHECK(kArchVariant == kMips64r6); | 2969 DCHECK(kArchVariant == kMips64r6); |
| 2845 set_fpu_register_double(fd_reg(), (ft_int & 0x1) != 0 ? fs : 0.0); | 2970 set_fpu_register_double(fd_reg(), (ft_int & 0x1) != 0 ? fs : 0.0); |
| 2971 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2846 break; | 2972 break; |
| 2847 case MOVZ_C: { | 2973 case MOVZ_C: { |
| 2848 DCHECK(kArchVariant == kMips64r2); | 2974 DCHECK(kArchVariant == kMips64r2); |
| 2849 if (rt() == 0) { | 2975 if (rt() == 0) { |
| 2850 set_fpu_register_double(fd_reg(), fs); | 2976 set_fpu_register_double(fd_reg(), fs); |
| 2851 } | 2977 } |
| 2978 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2852 break; | 2979 break; |
| 2853 } | 2980 } |
| 2854 case MOVN_C: { | 2981 case MOVN_C: { |
| 2855 DCHECK(kArchVariant == kMips64r2); | 2982 DCHECK(kArchVariant == kMips64r2); |
| 2856 if (rt() != 0) { | 2983 if (rt() != 0) { |
| 2857 set_fpu_register_double(fd_reg(), fs); | 2984 set_fpu_register_double(fd_reg(), fs); |
| 2858 } | 2985 } |
| 2986 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2859 break; | 2987 break; |
| 2860 } | 2988 } |
| 2861 case MOVF: { | 2989 case MOVF: { |
| 2862 // Same function field for MOVT.D and MOVF.D | 2990 // Same function field for MOVT.D and MOVF.D |
| 2863 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; | 2991 uint32_t ft_cc = (ft_reg() >> 2) & 0x7; |
| 2864 ft_cc = get_fcsr_condition_bit(ft_cc); | 2992 ft_cc = get_fcsr_condition_bit(ft_cc); |
| 2865 if (instr_.Bit(16)) { // Read Tf bit. | 2993 if (instr_.Bit(16)) { // Read Tf bit. |
| 2866 // MOVT.D | 2994 // MOVT.D |
| 2867 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); | 2995 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); |
| 2868 } else { | 2996 } else { |
| 2869 // MOVF.D | 2997 // MOVF.D |
| 2870 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); | 2998 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg(), fs); |
| 2871 } | 2999 } |
| 3000 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2872 break; | 3001 break; |
| 2873 } | 3002 } |
| 2874 case MINA: | 3003 case MINA: |
| 2875 DCHECK(kArchVariant == kMips64r6); | 3004 DCHECK(kArchVariant == kMips64r6); |
| 2876 set_fpu_register_double(fd_reg(), FPUMinA(ft, fs)); | 3005 set_fpu_register_double(fd_reg(), FPUMinA(ft, fs)); |
| 3006 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2877 break; | 3007 break; |
| 2878 case MAXA: | 3008 case MAXA: |
| 2879 DCHECK(kArchVariant == kMips64r6); | 3009 DCHECK(kArchVariant == kMips64r6); |
| 2880 set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs)); | 3010 set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs)); |
| 3011 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2881 break; | 3012 break; |
| 2882 case MIN: | 3013 case MIN: |
| 2883 DCHECK(kArchVariant == kMips64r6); | 3014 DCHECK(kArchVariant == kMips64r6); |
| 2884 set_fpu_register_double(fd_reg(), FPUMin(ft, fs)); | 3015 set_fpu_register_double(fd_reg(), FPUMin(ft, fs)); |
| 3016 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2885 break; | 3017 break; |
| 2886 case MAX: | 3018 case MAX: |
| 2887 DCHECK(kArchVariant == kMips64r6); | 3019 DCHECK(kArchVariant == kMips64r6); |
| 2888 set_fpu_register_double(fd_reg(), FPUMax(ft, fs)); | 3020 set_fpu_register_double(fd_reg(), FPUMax(ft, fs)); |
| 3021 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2889 break; | 3022 break; |
| 2890 case ADD_D: | 3023 case ADD_D: |
| 2891 set_fpu_register_double( | 3024 set_fpu_register_double( |
| 2892 fd_reg(), | 3025 fd_reg(), |
| 2893 FPUCanonalizeOperation( | 3026 FPUCanonalizeOperation( |
| 2894 [](double lhs, double rhs) { return lhs + rhs; }, fs, ft)); | 3027 [](double lhs, double rhs) { return lhs + rhs; }, fs, ft)); |
| 3028 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2895 break; | 3029 break; |
| 2896 case SUB_D: | 3030 case SUB_D: |
| 2897 set_fpu_register_double( | 3031 set_fpu_register_double( |
| 2898 fd_reg(), | 3032 fd_reg(), |
| 2899 FPUCanonalizeOperation( | 3033 FPUCanonalizeOperation( |
| 2900 [](double lhs, double rhs) { return lhs - rhs; }, fs, ft)); | 3034 [](double lhs, double rhs) { return lhs - rhs; }, fs, ft)); |
| 3035 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2901 break; | 3036 break; |
| 2902 case MADDF_D: | 3037 case MADDF_D: |
| 2903 DCHECK(kArchVariant == kMips64r6); | 3038 DCHECK(kArchVariant == kMips64r6); |
| 2904 set_fpu_register_double(fd_reg(), std::fma(fs, ft, fd)); | 3039 set_fpu_register_double(fd_reg(), std::fma(fs, ft, fd)); |
| 3040 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2905 break; | 3041 break; |
| 2906 case MSUBF_D: | 3042 case MSUBF_D: |
| 2907 DCHECK(kArchVariant == kMips64r6); | 3043 DCHECK(kArchVariant == kMips64r6); |
| 2908 set_fpu_register_double(fd_reg(), std::fma(-fs, ft, fd)); | 3044 set_fpu_register_double(fd_reg(), std::fma(-fs, ft, fd)); |
| 3045 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2909 break; | 3046 break; |
| 2910 case MUL_D: | 3047 case MUL_D: |
| 2911 set_fpu_register_double( | 3048 set_fpu_register_double( |
| 2912 fd_reg(), | 3049 fd_reg(), |
| 2913 FPUCanonalizeOperation( | 3050 FPUCanonalizeOperation( |
| 2914 [](double lhs, double rhs) { return lhs * rhs; }, fs, ft)); | 3051 [](double lhs, double rhs) { return lhs * rhs; }, fs, ft)); |
| 3052 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2915 break; | 3053 break; |
| 2916 case DIV_D: | 3054 case DIV_D: |
| 2917 set_fpu_register_double( | 3055 set_fpu_register_double( |
| 2918 fd_reg(), | 3056 fd_reg(), |
| 2919 FPUCanonalizeOperation( | 3057 FPUCanonalizeOperation( |
| 2920 [](double lhs, double rhs) { return lhs / rhs; }, fs, ft)); | 3058 [](double lhs, double rhs) { return lhs / rhs; }, fs, ft)); |
| 3059 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2921 break; | 3060 break; |
| 2922 case ABS_D: | 3061 case ABS_D: |
| 2923 set_fpu_register_double( | 3062 set_fpu_register_double( |
| 2924 fd_reg(), | 3063 fd_reg(), |
| 2925 FPUCanonalizeOperation([](double fs) { return FPAbs(fs); }, fs)); | 3064 FPUCanonalizeOperation([](double fs) { return FPAbs(fs); }, fs)); |
| 3065 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2926 break; | 3066 break; |
| 2927 case MOV_D: | 3067 case MOV_D: |
| 2928 set_fpu_register_double(fd_reg(), fs); | 3068 set_fpu_register_double(fd_reg(), fs); |
| 3069 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2929 break; | 3070 break; |
| 2930 case NEG_D: | 3071 case NEG_D: |
| 2931 set_fpu_register_double( | 3072 set_fpu_register_double( |
| 2932 fd_reg(), FPUCanonalizeOperation([](double src) { return -src; }, | 3073 fd_reg(), FPUCanonalizeOperation([](double src) { return -src; }, |
| 2933 KeepSign::yes, fs)); | 3074 KeepSign::yes, fs)); |
| 3075 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2934 break; | 3076 break; |
| 2935 case SQRT_D: | 3077 case SQRT_D: |
| 2936 set_fpu_register_double( | 3078 set_fpu_register_double( |
| 2937 fd_reg(), | 3079 fd_reg(), |
| 2938 FPUCanonalizeOperation([](double fs) { return std::sqrt(fs); }, fs)); | 3080 FPUCanonalizeOperation([](double fs) { return std::sqrt(fs); }, fs)); |
| 3081 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2939 break; | 3082 break; |
| 2940 case RSQRT_D: | 3083 case RSQRT_D: |
| 2941 set_fpu_register_double( | 3084 set_fpu_register_double( |
| 2942 fd_reg(), FPUCanonalizeOperation( | 3085 fd_reg(), FPUCanonalizeOperation( |
| 2943 [](double fs) { return 1.0 / std::sqrt(fs); }, fs)); | 3086 [](double fs) { return 1.0 / std::sqrt(fs); }, fs)); |
| 3087 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2944 break; | 3088 break; |
| 2945 case RECIP_D: | 3089 case RECIP_D: |
| 2946 set_fpu_register_double( | 3090 set_fpu_register_double( |
| 2947 fd_reg(), | 3091 fd_reg(), |
| 2948 FPUCanonalizeOperation([](double fs) { return 1.0 / fs; }, fs)); | 3092 FPUCanonalizeOperation([](double fs) { return 1.0 / fs; }, fs)); |
| 3093 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 2949 break; | 3094 break; |
| 2950 case C_UN_D: | 3095 case C_UN_D: |
| 2951 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); | 3096 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); |
| 3097 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 2952 break; | 3098 break; |
| 2953 case C_EQ_D: | 3099 case C_EQ_D: |
| 2954 set_fcsr_bit(fcsr_cc, (fs == ft)); | 3100 set_fcsr_bit(fcsr_cc, (fs == ft)); |
| 3101 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 2955 break; | 3102 break; |
| 2956 case C_UEQ_D: | 3103 case C_UEQ_D: |
| 2957 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); | 3104 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); |
| 3105 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 2958 break; | 3106 break; |
| 2959 case C_OLT_D: | 3107 case C_OLT_D: |
| 2960 set_fcsr_bit(fcsr_cc, (fs < ft)); | 3108 set_fcsr_bit(fcsr_cc, (fs < ft)); |
| 3109 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 2961 break; | 3110 break; |
| 2962 case C_ULT_D: | 3111 case C_ULT_D: |
| 2963 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); | 3112 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); |
| 3113 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 2964 break; | 3114 break; |
| 2965 case C_OLE_D: | 3115 case C_OLE_D: |
| 2966 set_fcsr_bit(fcsr_cc, (fs <= ft)); | 3116 set_fcsr_bit(fcsr_cc, (fs <= ft)); |
| 3117 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 2967 break; | 3118 break; |
| 2968 case C_ULE_D: | 3119 case C_ULE_D: |
| 2969 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); | 3120 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); |
| 3121 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 2970 break; | 3122 break; |
| 2971 case CVT_W_D: { // Convert double to word. | 3123 case CVT_W_D: { // Convert double to word. |
| 2972 double rounded; | 3124 double rounded; |
| 2973 int32_t result; | 3125 int32_t result; |
| 2974 round_according_to_fcsr(fs, rounded, result, fs); | 3126 round_according_to_fcsr(fs, rounded, result, fs); |
| 2975 set_fpu_register_word(fd_reg(), result); | 3127 set_fpu_register_word(fd_reg(), result); |
| 2976 if (set_fcsr_round_error(fs, rounded)) { | 3128 if (set_fcsr_round_error(fs, rounded)) { |
| 2977 set_fpu_register_word_invalid_result(fs, rounded); | 3129 set_fpu_register_word_invalid_result(fs, rounded); |
| 2978 } | 3130 } |
| 3131 TraceRegWr(get_fpu_register(fd_reg()), WORD); | |
| 2979 break; | 3132 break; |
| 2980 } | 3133 } |
| 2981 case ROUND_W_D: // Round double to word (round half to even). | 3134 case ROUND_W_D: // Round double to word (round half to even). |
| 2982 { | 3135 { |
| 2983 double rounded = std::floor(fs + 0.5); | 3136 double rounded = std::floor(fs + 0.5); |
| 2984 int32_t result = static_cast<int32_t>(rounded); | 3137 int32_t result = static_cast<int32_t>(rounded); |
| 2985 if ((result & 1) != 0 && result - fs == 0.5) { | 3138 if ((result & 1) != 0 && result - fs == 0.5) { |
| 2986 // If the number is halfway between two integers, | 3139 // If the number is halfway between two integers, |
| 2987 // round to the even one. | 3140 // round to the even one. |
| 2988 result--; | 3141 result--; |
| 2989 } | 3142 } |
| 2990 set_fpu_register_word(fd_reg(), result); | 3143 set_fpu_register_word(fd_reg(), result); |
| 2991 if (set_fcsr_round_error(fs, rounded)) { | 3144 if (set_fcsr_round_error(fs, rounded)) { |
| 2992 set_fpu_register_invalid_result(fs, rounded); | 3145 set_fpu_register_invalid_result(fs, rounded); |
| 2993 } | 3146 } |
| 3147 TraceRegWr(get_fpu_register(fd_reg()), WORD); | |
| 2994 } break; | 3148 } break; |
| 2995 case TRUNC_W_D: // Truncate double to word (round towards 0). | 3149 case TRUNC_W_D: // Truncate double to word (round towards 0). |
| 2996 { | 3150 { |
| 2997 double rounded = trunc(fs); | 3151 double rounded = trunc(fs); |
| 2998 int32_t result = static_cast<int32_t>(rounded); | 3152 int32_t result = static_cast<int32_t>(rounded); |
| 2999 set_fpu_register_word(fd_reg(), result); | 3153 set_fpu_register_word(fd_reg(), result); |
| 3000 if (set_fcsr_round_error(fs, rounded)) { | 3154 if (set_fcsr_round_error(fs, rounded)) { |
| 3001 set_fpu_register_invalid_result(fs, rounded); | 3155 set_fpu_register_invalid_result(fs, rounded); |
| 3002 } | 3156 } |
| 3157 TraceRegWr(get_fpu_register(fd_reg()), WORD); | |
| 3003 } break; | 3158 } break; |
| 3004 case FLOOR_W_D: // Round double to word towards negative infinity. | 3159 case FLOOR_W_D: // Round double to word towards negative infinity. |
| 3005 { | 3160 { |
| 3006 double rounded = std::floor(fs); | 3161 double rounded = std::floor(fs); |
| 3007 int32_t result = static_cast<int32_t>(rounded); | 3162 int32_t result = static_cast<int32_t>(rounded); |
| 3008 set_fpu_register_word(fd_reg(), result); | 3163 set_fpu_register_word(fd_reg(), result); |
| 3009 if (set_fcsr_round_error(fs, rounded)) { | 3164 if (set_fcsr_round_error(fs, rounded)) { |
| 3010 set_fpu_register_invalid_result(fs, rounded); | 3165 set_fpu_register_invalid_result(fs, rounded); |
| 3011 } | 3166 } |
| 3167 TraceRegWr(get_fpu_register(fd_reg()), WORD); | |
| 3012 } break; | 3168 } break; |
| 3013 case CEIL_W_D: // Round double to word towards positive infinity. | 3169 case CEIL_W_D: // Round double to word towards positive infinity. |
| 3014 { | 3170 { |
| 3015 double rounded = std::ceil(fs); | 3171 double rounded = std::ceil(fs); |
| 3016 int32_t result = static_cast<int32_t>(rounded); | 3172 int32_t result = static_cast<int32_t>(rounded); |
| 3017 set_fpu_register_word(fd_reg(), result); | 3173 set_fpu_register_word(fd_reg(), result); |
| 3018 if (set_fcsr_round_error(fs, rounded)) { | 3174 if (set_fcsr_round_error(fs, rounded)) { |
| 3019 set_fpu_register_invalid_result(fs, rounded); | 3175 set_fpu_register_invalid_result(fs, rounded); |
| 3020 } | 3176 } |
| 3177 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3021 } break; | 3178 } break; |
| 3022 case CVT_S_D: // Convert double to float (single). | 3179 case CVT_S_D: // Convert double to float (single). |
| 3023 set_fpu_register_float(fd_reg(), static_cast<float>(fs)); | 3180 set_fpu_register_float(fd_reg(), static_cast<float>(fs)); |
| 3181 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 3024 break; | 3182 break; |
| 3025 case CVT_L_D: { // Mips64r2: Truncate double to 64-bit long-word. | 3183 case CVT_L_D: { // Mips64r2: Truncate double to 64-bit long-word. |
| 3026 double rounded; | 3184 double rounded; |
| 3027 int64_t result; | 3185 int64_t result; |
| 3028 round64_according_to_fcsr(fs, rounded, result, fs); | 3186 round64_according_to_fcsr(fs, rounded, result, fs); |
| 3029 set_fpu_register(fd_reg(), result); | 3187 set_fpu_register(fd_reg(), result); |
| 3030 if (set_fcsr_round64_error(fs, rounded)) { | 3188 if (set_fcsr_round64_error(fs, rounded)) { |
| 3031 set_fpu_register_invalid_result64(fs, rounded); | 3189 set_fpu_register_invalid_result64(fs, rounded); |
| 3032 } | 3190 } |
| 3191 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3033 break; | 3192 break; |
| 3034 } | 3193 } |
| 3035 case ROUND_L_D: { // Mips64r2 instruction. | 3194 case ROUND_L_D: { // Mips64r2 instruction. |
| 3036 double rounded = std::floor(fs + 0.5); | 3195 double rounded = std::floor(fs + 0.5); |
| 3037 int64_t result = static_cast<int64_t>(rounded); | 3196 int64_t result = static_cast<int64_t>(rounded); |
| 3038 if ((result & 1) != 0 && result - fs == 0.5) { | 3197 if ((result & 1) != 0 && result - fs == 0.5) { |
| 3039 // If the number is halfway between two integers, | 3198 // If the number is halfway between two integers, |
| 3040 // round to the even one. | 3199 // round to the even one. |
| 3041 result--; | 3200 result--; |
| 3042 } | 3201 } |
| 3043 int64_t i64 = static_cast<int64_t>(result); | 3202 int64_t i64 = static_cast<int64_t>(result); |
| 3044 set_fpu_register(fd_reg(), i64); | 3203 set_fpu_register(fd_reg(), i64); |
| 3045 if (set_fcsr_round64_error(fs, rounded)) { | 3204 if (set_fcsr_round64_error(fs, rounded)) { |
| 3046 set_fpu_register_invalid_result64(fs, rounded); | 3205 set_fpu_register_invalid_result64(fs, rounded); |
| 3047 } | 3206 } |
| 3207 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3048 break; | 3208 break; |
| 3049 } | 3209 } |
| 3050 case TRUNC_L_D: { // Mips64r2 instruction. | 3210 case TRUNC_L_D: { // Mips64r2 instruction. |
| 3051 double rounded = trunc(fs); | 3211 double rounded = trunc(fs); |
| 3052 int64_t result = static_cast<int64_t>(rounded); | 3212 int64_t result = static_cast<int64_t>(rounded); |
| 3053 set_fpu_register(fd_reg(), result); | 3213 set_fpu_register(fd_reg(), result); |
| 3054 if (set_fcsr_round64_error(fs, rounded)) { | 3214 if (set_fcsr_round64_error(fs, rounded)) { |
| 3055 set_fpu_register_invalid_result64(fs, rounded); | 3215 set_fpu_register_invalid_result64(fs, rounded); |
| 3056 } | 3216 } |
| 3217 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3057 break; | 3218 break; |
| 3058 } | 3219 } |
| 3059 case FLOOR_L_D: { // Mips64r2 instruction. | 3220 case FLOOR_L_D: { // Mips64r2 instruction. |
| 3060 double rounded = floor(fs); | 3221 double rounded = floor(fs); |
| 3061 int64_t result = static_cast<int64_t>(rounded); | 3222 int64_t result = static_cast<int64_t>(rounded); |
| 3062 set_fpu_register(fd_reg(), result); | 3223 set_fpu_register(fd_reg(), result); |
| 3063 if (set_fcsr_round64_error(fs, rounded)) { | 3224 if (set_fcsr_round64_error(fs, rounded)) { |
| 3064 set_fpu_register_invalid_result64(fs, rounded); | 3225 set_fpu_register_invalid_result64(fs, rounded); |
| 3065 } | 3226 } |
| 3227 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3066 break; | 3228 break; |
| 3067 } | 3229 } |
| 3068 case CEIL_L_D: { // Mips64r2 instruction. | 3230 case CEIL_L_D: { // Mips64r2 instruction. |
| 3069 double rounded = ceil(fs); | 3231 double rounded = ceil(fs); |
| 3070 int64_t result = static_cast<int64_t>(rounded); | 3232 int64_t result = static_cast<int64_t>(rounded); |
| 3071 set_fpu_register(fd_reg(), result); | 3233 set_fpu_register(fd_reg(), result); |
| 3072 if (set_fcsr_round64_error(fs, rounded)) { | 3234 if (set_fcsr_round64_error(fs, rounded)) { |
| 3073 set_fpu_register_invalid_result64(fs, rounded); | 3235 set_fpu_register_invalid_result64(fs, rounded); |
| 3074 } | 3236 } |
| 3237 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3075 break; | 3238 break; |
| 3076 } | 3239 } |
| 3077 case CLASS_D: { // Mips64r6 instruction | 3240 case CLASS_D: { // Mips64r6 instruction |
| 3078 // Convert double input to uint64_t for easier bit manipulation | 3241 // Convert double input to uint64_t for easier bit manipulation |
| 3079 uint64_t classed = bit_cast<uint64_t>(fs); | 3242 uint64_t classed = bit_cast<uint64_t>(fs); |
| 3080 | 3243 |
| 3081 // Extracting sign, exponent and mantissa from the input double | 3244 // Extracting sign, exponent and mantissa from the input double |
| 3082 uint32_t sign = (classed >> 63) & 1; | 3245 uint32_t sign = (classed >> 63) & 1; |
| 3083 uint32_t exponent = (classed >> 52) & 0x00000000000007ff; | 3246 uint32_t exponent = (classed >> 52) & 0x00000000000007ff; |
| 3084 uint64_t mantissa = classed & 0x000fffffffffffff; | 3247 uint64_t mantissa = classed & 0x000fffffffffffff; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3129 | 3292 |
| 3130 // Calculating result according to description of CLASS.D instruction | 3293 // Calculating result according to description of CLASS.D instruction |
| 3131 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | | 3294 result = (posZero << 9) | (posSubnorm << 8) | (posNorm << 7) | |
| 3132 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | | 3295 (posInf << 6) | (negZero << 5) | (negSubnorm << 4) | |
| 3133 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; | 3296 (negNorm << 3) | (negInf << 2) | (quietNan << 1) | signalingNan; |
| 3134 | 3297 |
| 3135 DCHECK(result != 0); | 3298 DCHECK(result != 0); |
| 3136 | 3299 |
| 3137 dResult = bit_cast<double>(result); | 3300 dResult = bit_cast<double>(result); |
| 3138 set_fpu_register_double(fd_reg(), dResult); | 3301 set_fpu_register_double(fd_reg(), dResult); |
| 3302 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 3139 | 3303 |
| 3140 break; | 3304 break; |
| 3141 } | 3305 } |
| 3142 case C_F_D: { | 3306 case C_F_D: { |
| 3143 set_fcsr_bit(fcsr_cc, false); | 3307 set_fcsr_bit(fcsr_cc, false); |
| 3308 TraceRegWr(test_fcsr_bit(fcsr_cc)); | |
| 3144 break; | 3309 break; |
| 3145 } | 3310 } |
| 3146 default: | 3311 default: |
| 3147 UNREACHABLE(); | 3312 UNREACHABLE(); |
| 3148 } | 3313 } |
| 3149 } | 3314 } |
| 3150 | 3315 |
| 3151 | 3316 |
| 3152 void Simulator::DecodeTypeRegisterWRsType() { | 3317 void Simulator::DecodeTypeRegisterWRsType() { |
| 3153 float fs = get_fpu_register_float(fs_reg()); | 3318 float fs = get_fpu_register_float(fs_reg()); |
| 3154 float ft = get_fpu_register_float(ft_reg()); | 3319 float ft = get_fpu_register_float(ft_reg()); |
| 3155 int64_t alu_out = 0x12345678; | 3320 int64_t alu_out = 0x12345678; |
| 3156 switch (instr_.FunctionFieldRaw()) { | 3321 switch (instr_.FunctionFieldRaw()) { |
| 3157 case CVT_S_W: // Convert word to float (single). | 3322 case CVT_S_W: // Convert word to float (single). |
| 3158 alu_out = get_fpu_register_signed_word(fs_reg()); | 3323 alu_out = get_fpu_register_signed_word(fs_reg()); |
| 3159 set_fpu_register_float(fd_reg(), static_cast<float>(alu_out)); | 3324 set_fpu_register_float(fd_reg(), static_cast<float>(alu_out)); |
| 3325 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 3160 break; | 3326 break; |
| 3161 case CVT_D_W: // Convert word to double. | 3327 case CVT_D_W: // Convert word to double. |
| 3162 alu_out = get_fpu_register_signed_word(fs_reg()); | 3328 alu_out = get_fpu_register_signed_word(fs_reg()); |
| 3163 set_fpu_register_double(fd_reg(), static_cast<double>(alu_out)); | 3329 set_fpu_register_double(fd_reg(), static_cast<double>(alu_out)); |
| 3330 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 3164 break; | 3331 break; |
| 3165 case CMP_AF: | 3332 case CMP_AF: |
| 3166 set_fpu_register_word(fd_reg(), 0); | 3333 set_fpu_register_word(fd_reg(), 0); |
| 3334 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3167 break; | 3335 break; |
| 3168 case CMP_UN: | 3336 case CMP_UN: |
| 3169 if (std::isnan(fs) || std::isnan(ft)) { | 3337 if (std::isnan(fs) || std::isnan(ft)) { |
| 3170 set_fpu_register_word(fd_reg(), -1); | 3338 set_fpu_register_word(fd_reg(), -1); |
| 3171 } else { | 3339 } else { |
| 3172 set_fpu_register_word(fd_reg(), 0); | 3340 set_fpu_register_word(fd_reg(), 0); |
| 3173 } | 3341 } |
| 3342 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3174 break; | 3343 break; |
| 3175 case CMP_EQ: | 3344 case CMP_EQ: |
| 3176 if (fs == ft) { | 3345 if (fs == ft) { |
| 3177 set_fpu_register_word(fd_reg(), -1); | 3346 set_fpu_register_word(fd_reg(), -1); |
| 3178 } else { | 3347 } else { |
| 3179 set_fpu_register_word(fd_reg(), 0); | 3348 set_fpu_register_word(fd_reg(), 0); |
| 3180 } | 3349 } |
| 3350 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3181 break; | 3351 break; |
| 3182 case CMP_UEQ: | 3352 case CMP_UEQ: |
| 3183 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { | 3353 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 3184 set_fpu_register_word(fd_reg(), -1); | 3354 set_fpu_register_word(fd_reg(), -1); |
| 3185 } else { | 3355 } else { |
| 3186 set_fpu_register_word(fd_reg(), 0); | 3356 set_fpu_register_word(fd_reg(), 0); |
| 3187 } | 3357 } |
| 3358 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3188 break; | 3359 break; |
| 3189 case CMP_LT: | 3360 case CMP_LT: |
| 3190 if (fs < ft) { | 3361 if (fs < ft) { |
| 3191 set_fpu_register_word(fd_reg(), -1); | 3362 set_fpu_register_word(fd_reg(), -1); |
| 3192 } else { | 3363 } else { |
| 3193 set_fpu_register_word(fd_reg(), 0); | 3364 set_fpu_register_word(fd_reg(), 0); |
| 3194 } | 3365 } |
| 3366 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3195 break; | 3367 break; |
| 3196 case CMP_ULT: | 3368 case CMP_ULT: |
| 3197 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { | 3369 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 3198 set_fpu_register_word(fd_reg(), -1); | 3370 set_fpu_register_word(fd_reg(), -1); |
| 3199 } else { | 3371 } else { |
| 3200 set_fpu_register_word(fd_reg(), 0); | 3372 set_fpu_register_word(fd_reg(), 0); |
| 3201 } | 3373 } |
| 3374 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3202 break; | 3375 break; |
| 3203 case CMP_LE: | 3376 case CMP_LE: |
| 3204 if (fs <= ft) { | 3377 if (fs <= ft) { |
| 3205 set_fpu_register_word(fd_reg(), -1); | 3378 set_fpu_register_word(fd_reg(), -1); |
| 3206 } else { | 3379 } else { |
| 3207 set_fpu_register_word(fd_reg(), 0); | 3380 set_fpu_register_word(fd_reg(), 0); |
| 3208 } | 3381 } |
| 3382 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3209 break; | 3383 break; |
| 3210 case CMP_ULE: | 3384 case CMP_ULE: |
| 3211 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { | 3385 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 3212 set_fpu_register_word(fd_reg(), -1); | 3386 set_fpu_register_word(fd_reg(), -1); |
| 3213 } else { | 3387 } else { |
| 3214 set_fpu_register_word(fd_reg(), 0); | 3388 set_fpu_register_word(fd_reg(), 0); |
| 3215 } | 3389 } |
| 3390 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3216 break; | 3391 break; |
| 3217 case CMP_OR: | 3392 case CMP_OR: |
| 3218 if (!std::isnan(fs) && !std::isnan(ft)) { | 3393 if (!std::isnan(fs) && !std::isnan(ft)) { |
| 3219 set_fpu_register_word(fd_reg(), -1); | 3394 set_fpu_register_word(fd_reg(), -1); |
| 3220 } else { | 3395 } else { |
| 3221 set_fpu_register_word(fd_reg(), 0); | 3396 set_fpu_register_word(fd_reg(), 0); |
| 3222 } | 3397 } |
| 3398 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3223 break; | 3399 break; |
| 3224 case CMP_UNE: | 3400 case CMP_UNE: |
| 3225 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { | 3401 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 3226 set_fpu_register_word(fd_reg(), -1); | 3402 set_fpu_register_word(fd_reg(), -1); |
| 3227 } else { | 3403 } else { |
| 3228 set_fpu_register_word(fd_reg(), 0); | 3404 set_fpu_register_word(fd_reg(), 0); |
| 3229 } | 3405 } |
| 3406 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3230 break; | 3407 break; |
| 3231 case CMP_NE: | 3408 case CMP_NE: |
| 3232 if (fs != ft) { | 3409 if (fs != ft) { |
| 3233 set_fpu_register_word(fd_reg(), -1); | 3410 set_fpu_register_word(fd_reg(), -1); |
| 3234 } else { | 3411 } else { |
| 3235 set_fpu_register_word(fd_reg(), 0); | 3412 set_fpu_register_word(fd_reg(), 0); |
| 3236 } | 3413 } |
| 3414 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3237 break; | 3415 break; |
| 3238 default: | 3416 default: |
| 3239 UNREACHABLE(); | 3417 UNREACHABLE(); |
| 3240 } | 3418 } |
| 3241 } | 3419 } |
| 3242 | 3420 |
| 3243 | 3421 |
| 3244 void Simulator::DecodeTypeRegisterLRsType() { | 3422 void Simulator::DecodeTypeRegisterLRsType() { |
| 3245 double fs = get_fpu_register_double(fs_reg()); | 3423 double fs = get_fpu_register_double(fs_reg()); |
| 3246 double ft = get_fpu_register_double(ft_reg()); | 3424 double ft = get_fpu_register_double(ft_reg()); |
| 3247 int64_t i64; | 3425 int64_t i64; |
| 3248 switch (instr_.FunctionFieldRaw()) { | 3426 switch (instr_.FunctionFieldRaw()) { |
| 3249 case CVT_D_L: // Mips32r2 instruction. | 3427 case CVT_D_L: // Mips32r2 instruction. |
| 3250 i64 = get_fpu_register(fs_reg()); | 3428 i64 = get_fpu_register(fs_reg()); |
| 3251 set_fpu_register_double(fd_reg(), static_cast<double>(i64)); | 3429 set_fpu_register_double(fd_reg(), static_cast<double>(i64)); |
| 3430 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 3252 break; | 3431 break; |
| 3253 case CVT_S_L: | 3432 case CVT_S_L: |
| 3254 i64 = get_fpu_register(fs_reg()); | 3433 i64 = get_fpu_register(fs_reg()); |
| 3255 set_fpu_register_float(fd_reg(), static_cast<float>(i64)); | 3434 set_fpu_register_float(fd_reg(), static_cast<float>(i64)); |
| 3435 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 3256 break; | 3436 break; |
| 3257 case CMP_AF: | 3437 case CMP_AF: |
| 3258 set_fpu_register(fd_reg(), 0); | 3438 set_fpu_register(fd_reg(), 0); |
| 3439 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3259 break; | 3440 break; |
| 3260 case CMP_UN: | 3441 case CMP_UN: |
| 3261 if (std::isnan(fs) || std::isnan(ft)) { | 3442 if (std::isnan(fs) || std::isnan(ft)) { |
| 3262 set_fpu_register(fd_reg(), -1); | 3443 set_fpu_register(fd_reg(), -1); |
| 3263 } else { | 3444 } else { |
| 3264 set_fpu_register(fd_reg(), 0); | 3445 set_fpu_register(fd_reg(), 0); |
| 3265 } | 3446 } |
| 3447 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3266 break; | 3448 break; |
| 3267 case CMP_EQ: | 3449 case CMP_EQ: |
| 3268 if (fs == ft) { | 3450 if (fs == ft) { |
| 3269 set_fpu_register(fd_reg(), -1); | 3451 set_fpu_register(fd_reg(), -1); |
| 3270 } else { | 3452 } else { |
| 3271 set_fpu_register(fd_reg(), 0); | 3453 set_fpu_register(fd_reg(), 0); |
| 3272 } | 3454 } |
| 3455 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3273 break; | 3456 break; |
| 3274 case CMP_UEQ: | 3457 case CMP_UEQ: |
| 3275 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { | 3458 if ((fs == ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 3276 set_fpu_register(fd_reg(), -1); | 3459 set_fpu_register(fd_reg(), -1); |
| 3277 } else { | 3460 } else { |
| 3278 set_fpu_register(fd_reg(), 0); | 3461 set_fpu_register(fd_reg(), 0); |
| 3279 } | 3462 } |
| 3463 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3280 break; | 3464 break; |
| 3281 case CMP_LT: | 3465 case CMP_LT: |
| 3282 if (fs < ft) { | 3466 if (fs < ft) { |
| 3283 set_fpu_register(fd_reg(), -1); | 3467 set_fpu_register(fd_reg(), -1); |
| 3284 } else { | 3468 } else { |
| 3285 set_fpu_register(fd_reg(), 0); | 3469 set_fpu_register(fd_reg(), 0); |
| 3286 } | 3470 } |
| 3471 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3287 break; | 3472 break; |
| 3288 case CMP_ULT: | 3473 case CMP_ULT: |
| 3289 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { | 3474 if ((fs < ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 3290 set_fpu_register(fd_reg(), -1); | 3475 set_fpu_register(fd_reg(), -1); |
| 3291 } else { | 3476 } else { |
| 3292 set_fpu_register(fd_reg(), 0); | 3477 set_fpu_register(fd_reg(), 0); |
| 3293 } | 3478 } |
| 3479 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3294 break; | 3480 break; |
| 3295 case CMP_LE: | 3481 case CMP_LE: |
| 3296 if (fs <= ft) { | 3482 if (fs <= ft) { |
| 3297 set_fpu_register(fd_reg(), -1); | 3483 set_fpu_register(fd_reg(), -1); |
| 3298 } else { | 3484 } else { |
| 3299 set_fpu_register(fd_reg(), 0); | 3485 set_fpu_register(fd_reg(), 0); |
| 3300 } | 3486 } |
| 3487 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3301 break; | 3488 break; |
| 3302 case CMP_ULE: | 3489 case CMP_ULE: |
| 3303 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { | 3490 if ((fs <= ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 3304 set_fpu_register(fd_reg(), -1); | 3491 set_fpu_register(fd_reg(), -1); |
| 3305 } else { | 3492 } else { |
| 3306 set_fpu_register(fd_reg(), 0); | 3493 set_fpu_register(fd_reg(), 0); |
| 3307 } | 3494 } |
| 3495 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3308 break; | 3496 break; |
| 3309 case CMP_OR: | 3497 case CMP_OR: |
| 3310 if (!std::isnan(fs) && !std::isnan(ft)) { | 3498 if (!std::isnan(fs) && !std::isnan(ft)) { |
| 3311 set_fpu_register(fd_reg(), -1); | 3499 set_fpu_register(fd_reg(), -1); |
| 3312 } else { | 3500 } else { |
| 3313 set_fpu_register(fd_reg(), 0); | 3501 set_fpu_register(fd_reg(), 0); |
| 3314 } | 3502 } |
| 3503 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3315 break; | 3504 break; |
| 3316 case CMP_UNE: | 3505 case CMP_UNE: |
| 3317 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { | 3506 if ((fs != ft) || (std::isnan(fs) || std::isnan(ft))) { |
| 3318 set_fpu_register(fd_reg(), -1); | 3507 set_fpu_register(fd_reg(), -1); |
| 3319 } else { | 3508 } else { |
| 3320 set_fpu_register(fd_reg(), 0); | 3509 set_fpu_register(fd_reg(), 0); |
| 3321 } | 3510 } |
| 3511 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3322 break; | 3512 break; |
| 3323 case CMP_NE: | 3513 case CMP_NE: |
| 3324 if (fs != ft && (!std::isnan(fs) && !std::isnan(ft))) { | 3514 if (fs != ft && (!std::isnan(fs) && !std::isnan(ft))) { |
| 3325 set_fpu_register(fd_reg(), -1); | 3515 set_fpu_register(fd_reg(), -1); |
| 3326 } else { | 3516 } else { |
| 3327 set_fpu_register(fd_reg(), 0); | 3517 set_fpu_register(fd_reg(), 0); |
| 3328 } | 3518 } |
| 3519 TraceRegWr(get_fpu_register(fd_reg())); | |
| 3329 break; | 3520 break; |
| 3330 default: | 3521 default: |
| 3331 UNREACHABLE(); | 3522 UNREACHABLE(); |
| 3332 } | 3523 } |
| 3333 } | 3524 } |
| 3334 | 3525 |
| 3335 | 3526 |
| 3336 void Simulator::DecodeTypeRegisterCOP1() { | 3527 void Simulator::DecodeTypeRegisterCOP1() { |
| 3337 switch (instr_.RsFieldRaw()) { | 3528 switch (instr_.RsFieldRaw()) { |
| 3338 case BC1: // Branch on coprocessor condition. | 3529 case BC1: // Branch on coprocessor condition. |
| 3339 case BC1EQZ: | 3530 case BC1EQZ: |
| 3340 case BC1NEZ: | 3531 case BC1NEZ: |
| 3341 UNREACHABLE(); | 3532 UNREACHABLE(); |
| 3342 break; | 3533 break; |
| 3343 case CFC1: | 3534 case CFC1: |
| 3344 // At the moment only FCSR is supported. | 3535 // At the moment only FCSR is supported. |
| 3345 DCHECK(fs_reg() == kFCSRRegister); | 3536 DCHECK(fs_reg() == kFCSRRegister); |
| 3346 set_register(rt_reg(), FCSR_); | 3537 set_register(rt_reg(), FCSR_); |
| 3538 TraceRegWr(get_register(rt_reg())); | |
| 3347 break; | 3539 break; |
| 3348 case MFC1: | 3540 case MFC1: |
| 3349 set_register(rt_reg(), | 3541 set_register(rt_reg(), |
| 3350 static_cast<int64_t>(get_fpu_register_word(fs_reg()))); | 3542 static_cast<int64_t>(get_fpu_register_word(fs_reg()))); |
| 3543 TraceRegWr(get_register(rt_reg()), WORD_DWORD); | |
| 3351 break; | 3544 break; |
| 3352 case DMFC1: | 3545 case DMFC1: |
| 3353 set_register(rt_reg(), get_fpu_register(fs_reg())); | 3546 set_register(rt_reg(), get_fpu_register(fs_reg())); |
| 3547 TraceRegWr(get_register(rt_reg())); | |
| 3354 break; | 3548 break; |
| 3355 case MFHC1: | 3549 case MFHC1: |
| 3356 set_register(rt_reg(), get_fpu_register_hi_word(fs_reg())); | 3550 set_register(rt_reg(), get_fpu_register_hi_word(fs_reg())); |
| 3551 TraceRegWr(get_register(rt_reg())); | |
| 3357 break; | 3552 break; |
| 3358 case CTC1: { | 3553 case CTC1: { |
| 3359 // At the moment only FCSR is supported. | 3554 // At the moment only FCSR is supported. |
| 3360 DCHECK(fs_reg() == kFCSRRegister); | 3555 DCHECK(fs_reg() == kFCSRRegister); |
| 3361 uint32_t reg = static_cast<uint32_t>(rt()); | 3556 uint32_t reg = static_cast<uint32_t>(rt()); |
| 3362 if (kArchVariant == kMips64r6) { | 3557 if (kArchVariant == kMips64r6) { |
| 3363 FCSR_ = reg | kFCSRNaN2008FlagMask; | 3558 FCSR_ = reg | kFCSRNaN2008FlagMask; |
| 3364 } else { | 3559 } else { |
| 3365 DCHECK(kArchVariant == kMips64r2); | 3560 DCHECK(kArchVariant == kMips64r2); |
| 3366 FCSR_ = reg & ~kFCSRNaN2008FlagMask; | 3561 FCSR_ = reg & ~kFCSRNaN2008FlagMask; |
| 3367 } | 3562 } |
| 3563 TraceRegWr(FCSR_); | |
| 3368 break; | 3564 break; |
| 3369 } | 3565 } |
| 3370 case MTC1: | 3566 case MTC1: |
| 3371 // Hardware writes upper 32-bits to zero on mtc1. | 3567 // Hardware writes upper 32-bits to zero on mtc1. |
| 3372 set_fpu_register_hi_word(fs_reg(), 0); | 3568 set_fpu_register_hi_word(fs_reg(), 0); |
| 3373 set_fpu_register_word(fs_reg(), static_cast<int32_t>(rt())); | 3569 set_fpu_register_word(fs_reg(), static_cast<int32_t>(rt())); |
| 3570 TraceRegWr(get_fpu_register(fs_reg()), FLOAT_DOUBLE); | |
| 3374 break; | 3571 break; |
| 3375 case DMTC1: | 3572 case DMTC1: |
| 3376 set_fpu_register(fs_reg(), rt()); | 3573 set_fpu_register(fs_reg(), rt()); |
| 3574 TraceRegWr(get_fpu_register(fs_reg()), DOUBLE); | |
| 3377 break; | 3575 break; |
| 3378 case MTHC1: | 3576 case MTHC1: |
| 3379 set_fpu_register_hi_word(fs_reg(), static_cast<int32_t>(rt())); | 3577 set_fpu_register_hi_word(fs_reg(), static_cast<int32_t>(rt())); |
| 3578 TraceRegWr(get_fpu_register(fs_reg()), DOUBLE); | |
| 3380 break; | 3579 break; |
| 3381 case S: | 3580 case S: |
| 3382 DecodeTypeRegisterSRsType(); | 3581 DecodeTypeRegisterSRsType(); |
| 3383 break; | 3582 break; |
| 3384 case D: | 3583 case D: |
| 3385 DecodeTypeRegisterDRsType(); | 3584 DecodeTypeRegisterDRsType(); |
| 3386 break; | 3585 break; |
| 3387 case W: | 3586 case W: |
| 3388 DecodeTypeRegisterWRsType(); | 3587 DecodeTypeRegisterWRsType(); |
| 3389 break; | 3588 break; |
| 3390 case L: | 3589 case L: |
| 3391 DecodeTypeRegisterLRsType(); | 3590 DecodeTypeRegisterLRsType(); |
| 3392 break; | 3591 break; |
| 3393 default: | 3592 default: |
| 3394 UNREACHABLE(); | 3593 UNREACHABLE(); |
| 3395 } | 3594 } |
| 3396 } | 3595 } |
| 3397 | 3596 |
| 3398 | 3597 |
| 3399 void Simulator::DecodeTypeRegisterCOP1X() { | 3598 void Simulator::DecodeTypeRegisterCOP1X() { |
| 3400 switch (instr_.FunctionFieldRaw()) { | 3599 switch (instr_.FunctionFieldRaw()) { |
| 3401 case MADD_S: { | 3600 case MADD_S: { |
| 3402 DCHECK(kArchVariant == kMips64r2); | 3601 DCHECK(kArchVariant == kMips64r2); |
| 3403 float fr, ft, fs; | 3602 float fr, ft, fs; |
| 3404 fr = get_fpu_register_float(fr_reg()); | 3603 fr = get_fpu_register_float(fr_reg()); |
| 3405 fs = get_fpu_register_float(fs_reg()); | 3604 fs = get_fpu_register_float(fs_reg()); |
| 3406 ft = get_fpu_register_float(ft_reg()); | 3605 ft = get_fpu_register_float(ft_reg()); |
| 3407 set_fpu_register_float(fd_reg(), fs * ft + fr); | 3606 set_fpu_register_float(fd_reg(), fs * ft + fr); |
| 3607 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 3408 break; | 3608 break; |
| 3409 } | 3609 } |
| 3410 case MSUB_S: { | 3610 case MSUB_S: { |
| 3411 DCHECK(kArchVariant == kMips64r2); | 3611 DCHECK(kArchVariant == kMips64r2); |
| 3412 float fr, ft, fs; | 3612 float fr, ft, fs; |
| 3413 fr = get_fpu_register_float(fr_reg()); | 3613 fr = get_fpu_register_float(fr_reg()); |
| 3414 fs = get_fpu_register_float(fs_reg()); | 3614 fs = get_fpu_register_float(fs_reg()); |
| 3415 ft = get_fpu_register_float(ft_reg()); | 3615 ft = get_fpu_register_float(ft_reg()); |
| 3416 set_fpu_register_float(fd_reg(), fs * ft - fr); | 3616 set_fpu_register_float(fd_reg(), fs * ft - fr); |
| 3617 TraceRegWr(get_fpu_register(fd_reg()), FLOAT); | |
| 3417 break; | 3618 break; |
| 3418 } | 3619 } |
| 3419 case MADD_D: { | 3620 case MADD_D: { |
| 3420 DCHECK(kArchVariant == kMips64r2); | 3621 DCHECK(kArchVariant == kMips64r2); |
| 3421 double fr, ft, fs; | 3622 double fr, ft, fs; |
| 3422 fr = get_fpu_register_double(fr_reg()); | 3623 fr = get_fpu_register_double(fr_reg()); |
| 3423 fs = get_fpu_register_double(fs_reg()); | 3624 fs = get_fpu_register_double(fs_reg()); |
| 3424 ft = get_fpu_register_double(ft_reg()); | 3625 ft = get_fpu_register_double(ft_reg()); |
| 3425 set_fpu_register_double(fd_reg(), fs * ft + fr); | 3626 set_fpu_register_double(fd_reg(), fs * ft + fr); |
| 3627 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 3426 break; | 3628 break; |
| 3427 } | 3629 } |
| 3428 case MSUB_D: { | 3630 case MSUB_D: { |
| 3429 DCHECK(kArchVariant == kMips64r2); | 3631 DCHECK(kArchVariant == kMips64r2); |
| 3430 double fr, ft, fs; | 3632 double fr, ft, fs; |
| 3431 fr = get_fpu_register_double(fr_reg()); | 3633 fr = get_fpu_register_double(fr_reg()); |
| 3432 fs = get_fpu_register_double(fs_reg()); | 3634 fs = get_fpu_register_double(fs_reg()); |
| 3433 ft = get_fpu_register_double(ft_reg()); | 3635 ft = get_fpu_register_double(ft_reg()); |
| 3434 set_fpu_register_double(fd_reg(), fs * ft - fr); | 3636 set_fpu_register_double(fd_reg(), fs * ft - fr); |
| 3637 TraceRegWr(get_fpu_register(fd_reg()), DOUBLE); | |
| 3435 break; | 3638 break; |
| 3436 } | 3639 } |
| 3437 default: | 3640 default: |
| 3438 UNREACHABLE(); | 3641 UNREACHABLE(); |
| 3439 } | 3642 } |
| 3440 } | 3643 } |
| 3441 | 3644 |
| 3442 | 3645 |
| 3443 void Simulator::DecodeTypeRegisterSPECIAL() { | 3646 void Simulator::DecodeTypeRegisterSPECIAL() { |
| 3444 int64_t i64hilo; | 3647 int64_t i64hilo; |
| (...skipping 1237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4682 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; | 4885 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; |
| 4683 uint64_t mask = (1UL << al_offset * 8) - 1; | 4886 uint64_t mask = (1UL << al_offset * 8) - 1; |
| 4684 addr = rs + se_imm16 - al_offset; | 4887 addr = rs + se_imm16 - al_offset; |
| 4685 uint64_t mem_value = Read2W(addr, instr_.instr()); | 4888 uint64_t mem_value = Read2W(addr, instr_.instr()); |
| 4686 mem_value = (rt << al_offset * 8) | (mem_value & mask); | 4889 mem_value = (rt << al_offset * 8) | (mem_value & mask); |
| 4687 Write2W(addr, mem_value, instr_.instr()); | 4890 Write2W(addr, mem_value, instr_.instr()); |
| 4688 break; | 4891 break; |
| 4689 } | 4892 } |
| 4690 case LWC1: | 4893 case LWC1: |
| 4691 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits. | 4894 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits. |
| 4692 set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr_.instr())); | 4895 set_fpu_register_word(ft_reg, |
| 4896 ReadW(rs + se_imm16, instr_.instr(), FLOAT_DOUBLE)); | |
| 4693 break; | 4897 break; |
| 4694 case LDC1: | 4898 case LDC1: |
| 4695 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr_.instr())); | 4899 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr_.instr())); |
| 4900 TraceMemRd(addr, get_fpu_register(ft_reg), DOUBLE); | |
| 4696 break; | 4901 break; |
| 4697 case SWC1: { | 4902 case SWC1: { |
| 4698 int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg)); | 4903 int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg)); |
| 4699 WriteW(rs + se_imm16, alu_out_32, instr_.instr()); | 4904 WriteW(rs + se_imm16, alu_out_32, instr_.instr()); |
| 4700 break; | 4905 break; |
| 4701 } | 4906 } |
| 4702 case SDC1: | 4907 case SDC1: |
| 4703 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr_.instr()); | 4908 WriteD(rs + se_imm16, get_fpu_register_double(ft_reg), instr_.instr()); |
| 4909 TraceMemWr(rs + se_imm16, get_fpu_register(ft_reg), DWORD); | |
| 4704 break; | 4910 break; |
| 4705 // ------------- PC-Relative instructions. | 4911 // ------------- PC-Relative instructions. |
| 4706 case PCREL: { | 4912 case PCREL: { |
| 4707 // rt field: checking 5-bits. | 4913 // rt field: checking 5-bits. |
| 4708 int32_t imm21 = instr_.Imm21Value(); | 4914 int32_t imm21 = instr_.Imm21Value(); |
| 4709 int64_t current_pc = get_pc(); | 4915 int64_t current_pc = get_pc(); |
| 4710 uint8_t rt = (imm21 >> kImm16Bits); | 4916 uint8_t rt = (imm21 >> kImm16Bits); |
| 4711 switch (rt) { | 4917 switch (rt) { |
| 4712 case ALUIPC: | 4918 case ALUIPC: |
| 4713 addr = current_pc + (se_imm16 << 16); | 4919 addr = current_pc + (se_imm16 << 16); |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5052 } | 5258 } |
| 5053 | 5259 |
| 5054 | 5260 |
| 5055 #undef UNSUPPORTED | 5261 #undef UNSUPPORTED |
| 5056 } // namespace internal | 5262 } // namespace internal |
| 5057 } // namespace v8 | 5263 } // namespace v8 |
| 5058 | 5264 |
| 5059 #endif // USE_SIMULATOR | 5265 #endif // USE_SIMULATOR |
| 5060 | 5266 |
| 5061 #endif // V8_TARGET_ARCH_MIPS64 | 5267 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |