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

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

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

Powered by Google App Engine
This is Rietveld 408576698