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

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

Issue 2603083002: MIPS[64]: Add support for FPR content in simulator trace. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/mips/simulator-mips.cc ('K') | « src/mips64/simulator-mips64.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <limits.h> 5 #include <limits.h>
6 #include <stdarg.h> 6 #include <stdarg.h>
7 #include <stdlib.h> 7 #include <stdlib.h>
8 #include <cmath> 8 #include <cmath>
9 9
10 #if V8_TARGET_ARCH_MIPS64 10 #if V8_TARGET_ARCH_MIPS64
(...skipping 1608 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
OLDNEW
« src/mips/simulator-mips.cc ('K') | « src/mips64/simulator-mips64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698