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 |