| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <limits.h> | 5 #include <limits.h> |
| 6 #include <stdarg.h> | 6 #include <stdarg.h> |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 #if V8_TARGET_ARCH_MIPS64 | 10 #if V8_TARGET_ARCH_MIPS64 |
| (...skipping 1715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1726 | 1726 |
| 1727 // TODO(plind): sign-extend and zero-extend not implmented properly | 1727 // TODO(plind): sign-extend and zero-extend not implmented properly |
| 1728 // on all the ReadXX functions, I don't think re-interpret cast does it. | 1728 // on all the ReadXX functions, I don't think re-interpret cast does it. |
| 1729 int32_t Simulator::ReadW(int64_t addr, Instruction* instr) { | 1729 int32_t Simulator::ReadW(int64_t addr, Instruction* instr) { |
| 1730 if (addr >=0 && addr < 0x400) { | 1730 if (addr >=0 && addr < 0x400) { |
| 1731 // This has to be a NULL-dereference, drop into debugger. | 1731 // This has to be a NULL-dereference, drop into debugger. |
| 1732 PrintF("Memory read from bad address: 0x%08lx, pc=0x%08lx\n", | 1732 PrintF("Memory read from bad address: 0x%08lx, pc=0x%08lx\n", |
| 1733 addr, reinterpret_cast<intptr_t>(instr)); | 1733 addr, reinterpret_cast<intptr_t>(instr)); |
| 1734 DieOrDebug(); | 1734 DieOrDebug(); |
| 1735 } | 1735 } |
| 1736 if ((addr & 0x3) == 0) { | 1736 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { |
| 1737 int32_t* ptr = reinterpret_cast<int32_t*>(addr); | 1737 int32_t* ptr = reinterpret_cast<int32_t*>(addr); |
| 1738 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1738 TraceMemRd(addr, static_cast<int64_t>(*ptr)); |
| 1739 return *ptr; | 1739 return *ptr; |
| 1740 } | 1740 } |
| 1741 PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1741 PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
| 1742 addr, | 1742 addr, |
| 1743 reinterpret_cast<intptr_t>(instr)); | 1743 reinterpret_cast<intptr_t>(instr)); |
| 1744 DieOrDebug(); | 1744 DieOrDebug(); |
| 1745 return 0; | 1745 return 0; |
| 1746 } | 1746 } |
| 1747 | 1747 |
| 1748 | 1748 |
| 1749 uint32_t Simulator::ReadWU(int64_t addr, Instruction* instr) { | 1749 uint32_t Simulator::ReadWU(int64_t addr, Instruction* instr) { |
| 1750 if (addr >=0 && addr < 0x400) { | 1750 if (addr >=0 && addr < 0x400) { |
| 1751 // This has to be a NULL-dereference, drop into debugger. | 1751 // This has to be a NULL-dereference, drop into debugger. |
| 1752 PrintF("Memory read from bad address: 0x%08lx, pc=0x%08lx\n", | 1752 PrintF("Memory read from bad address: 0x%08lx, pc=0x%08lx\n", |
| 1753 addr, reinterpret_cast<intptr_t>(instr)); | 1753 addr, reinterpret_cast<intptr_t>(instr)); |
| 1754 DieOrDebug(); | 1754 DieOrDebug(); |
| 1755 } | 1755 } |
| 1756 if ((addr & 0x3) == 0) { | 1756 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { |
| 1757 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); | 1757 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); |
| 1758 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1758 TraceMemRd(addr, static_cast<int64_t>(*ptr)); |
| 1759 return *ptr; | 1759 return *ptr; |
| 1760 } | 1760 } |
| 1761 PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1761 PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
| 1762 addr, | 1762 addr, |
| 1763 reinterpret_cast<intptr_t>(instr)); | 1763 reinterpret_cast<intptr_t>(instr)); |
| 1764 DieOrDebug(); | 1764 DieOrDebug(); |
| 1765 return 0; | 1765 return 0; |
| 1766 } | 1766 } |
| 1767 | 1767 |
| 1768 | 1768 |
| 1769 void Simulator::WriteW(int64_t addr, int32_t value, Instruction* instr) { | 1769 void Simulator::WriteW(int64_t addr, int32_t value, Instruction* instr) { |
| 1770 if (addr >= 0 && addr < 0x400) { | 1770 if (addr >= 0 && addr < 0x400) { |
| 1771 // This has to be a NULL-dereference, drop into debugger. | 1771 // This has to be a NULL-dereference, drop into debugger. |
| 1772 PrintF("Memory write to bad address: 0x%08lx, pc=0x%08lx\n", | 1772 PrintF("Memory write to bad address: 0x%08lx, pc=0x%08lx\n", |
| 1773 addr, reinterpret_cast<intptr_t>(instr)); | 1773 addr, reinterpret_cast<intptr_t>(instr)); |
| 1774 DieOrDebug(); | 1774 DieOrDebug(); |
| 1775 } | 1775 } |
| 1776 if ((addr & 0x3) == 0) { | 1776 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { |
| 1777 TraceMemWr(addr, value, WORD); | 1777 TraceMemWr(addr, value, WORD); |
| 1778 int* ptr = reinterpret_cast<int*>(addr); | 1778 int* ptr = reinterpret_cast<int*>(addr); |
| 1779 *ptr = value; | 1779 *ptr = value; |
| 1780 return; | 1780 return; |
| 1781 } | 1781 } |
| 1782 PrintF("Unaligned write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1782 PrintF("Unaligned write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
| 1783 addr, | 1783 addr, |
| 1784 reinterpret_cast<intptr_t>(instr)); | 1784 reinterpret_cast<intptr_t>(instr)); |
| 1785 DieOrDebug(); | 1785 DieOrDebug(); |
| 1786 } | 1786 } |
| 1787 | 1787 |
| 1788 | 1788 |
| 1789 int64_t Simulator::Read2W(int64_t addr, Instruction* instr) { | 1789 int64_t Simulator::Read2W(int64_t addr, Instruction* instr) { |
| 1790 if (addr >=0 && addr < 0x400) { | 1790 if (addr >=0 && addr < 0x400) { |
| 1791 // This has to be a NULL-dereference, drop into debugger. | 1791 // This has to be a NULL-dereference, drop into debugger. |
| 1792 PrintF("Memory read from bad address: 0x%08lx, pc=0x%08lx\n", | 1792 PrintF("Memory read from bad address: 0x%08lx, pc=0x%08lx\n", |
| 1793 addr, reinterpret_cast<intptr_t>(instr)); | 1793 addr, reinterpret_cast<intptr_t>(instr)); |
| 1794 DieOrDebug(); | 1794 DieOrDebug(); |
| 1795 } | 1795 } |
| 1796 if ((addr & kPointerAlignmentMask) == 0) { | 1796 if ((addr & kPointerAlignmentMask) == 0 || kArchVariant == kMips64r6) { |
| 1797 int64_t* ptr = reinterpret_cast<int64_t*>(addr); | 1797 int64_t* ptr = reinterpret_cast<int64_t*>(addr); |
| 1798 TraceMemRd(addr, *ptr); | 1798 TraceMemRd(addr, *ptr); |
| 1799 return *ptr; | 1799 return *ptr; |
| 1800 } | 1800 } |
| 1801 PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1801 PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
| 1802 addr, | 1802 addr, |
| 1803 reinterpret_cast<intptr_t>(instr)); | 1803 reinterpret_cast<intptr_t>(instr)); |
| 1804 DieOrDebug(); | 1804 DieOrDebug(); |
| 1805 return 0; | 1805 return 0; |
| 1806 } | 1806 } |
| 1807 | 1807 |
| 1808 | 1808 |
| 1809 void Simulator::Write2W(int64_t addr, int64_t value, Instruction* instr) { | 1809 void Simulator::Write2W(int64_t addr, int64_t value, Instruction* instr) { |
| 1810 if (addr >= 0 && addr < 0x400) { | 1810 if (addr >= 0 && addr < 0x400) { |
| 1811 // This has to be a NULL-dereference, drop into debugger. | 1811 // This has to be a NULL-dereference, drop into debugger. |
| 1812 PrintF("Memory write to bad address: 0x%08lx, pc=0x%08lx\n", | 1812 PrintF("Memory write to bad address: 0x%08lx, pc=0x%08lx\n", |
| 1813 addr, reinterpret_cast<intptr_t>(instr)); | 1813 addr, reinterpret_cast<intptr_t>(instr)); |
| 1814 DieOrDebug(); | 1814 DieOrDebug(); |
| 1815 } | 1815 } |
| 1816 if ((addr & kPointerAlignmentMask) == 0) { | 1816 if ((addr & kPointerAlignmentMask) == 0 || kArchVariant == kMips64r6) { |
| 1817 TraceMemWr(addr, value, DWORD); | 1817 TraceMemWr(addr, value, DWORD); |
| 1818 int64_t* ptr = reinterpret_cast<int64_t*>(addr); | 1818 int64_t* ptr = reinterpret_cast<int64_t*>(addr); |
| 1819 *ptr = value; | 1819 *ptr = value; |
| 1820 return; | 1820 return; |
| 1821 } | 1821 } |
| 1822 PrintF("Unaligned write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1822 PrintF("Unaligned write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
| 1823 addr, | 1823 addr, |
| 1824 reinterpret_cast<intptr_t>(instr)); | 1824 reinterpret_cast<intptr_t>(instr)); |
| 1825 DieOrDebug(); | 1825 DieOrDebug(); |
| 1826 } | 1826 } |
| 1827 | 1827 |
| 1828 | 1828 |
| 1829 double Simulator::ReadD(int64_t addr, Instruction* instr) { | 1829 double Simulator::ReadD(int64_t addr, Instruction* instr) { |
| 1830 if ((addr & kDoubleAlignmentMask) == 0) { | 1830 if ((addr & kDoubleAlignmentMask) == 0 || kArchVariant == kMips64r6) { |
| 1831 double* ptr = reinterpret_cast<double*>(addr); | 1831 double* ptr = reinterpret_cast<double*>(addr); |
| 1832 return *ptr; | 1832 return *ptr; |
| 1833 } | 1833 } |
| 1834 PrintF("Unaligned (double) read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1834 PrintF("Unaligned (double) read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
| 1835 addr, | 1835 addr, |
| 1836 reinterpret_cast<intptr_t>(instr)); | 1836 reinterpret_cast<intptr_t>(instr)); |
| 1837 base::OS::Abort(); | 1837 base::OS::Abort(); |
| 1838 return 0; | 1838 return 0; |
| 1839 } | 1839 } |
| 1840 | 1840 |
| 1841 | 1841 |
| 1842 void Simulator::WriteD(int64_t addr, double value, Instruction* instr) { | 1842 void Simulator::WriteD(int64_t addr, double value, Instruction* instr) { |
| 1843 if ((addr & kDoubleAlignmentMask) == 0) { | 1843 if ((addr & kDoubleAlignmentMask) == 0 || kArchVariant == kMips64r6) { |
| 1844 double* ptr = reinterpret_cast<double*>(addr); | 1844 double* ptr = reinterpret_cast<double*>(addr); |
| 1845 *ptr = value; | 1845 *ptr = value; |
| 1846 return; | 1846 return; |
| 1847 } | 1847 } |
| 1848 PrintF("Unaligned (double) write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1848 PrintF("Unaligned (double) write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
| 1849 addr, | 1849 addr, |
| 1850 reinterpret_cast<intptr_t>(instr)); | 1850 reinterpret_cast<intptr_t>(instr)); |
| 1851 DieOrDebug(); | 1851 DieOrDebug(); |
| 1852 } | 1852 } |
| 1853 | 1853 |
| 1854 | 1854 |
| 1855 uint16_t Simulator::ReadHU(int64_t addr, Instruction* instr) { | 1855 uint16_t Simulator::ReadHU(int64_t addr, Instruction* instr) { |
| 1856 if ((addr & 1) == 0) { | 1856 if ((addr & 1) == 0 || kArchVariant == kMips64r6) { |
| 1857 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); | 1857 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); |
| 1858 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1858 TraceMemRd(addr, static_cast<int64_t>(*ptr)); |
| 1859 return *ptr; | 1859 return *ptr; |
| 1860 } | 1860 } |
| 1861 PrintF("Unaligned unsigned halfword read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1861 PrintF("Unaligned unsigned halfword read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
| 1862 addr, | 1862 addr, |
| 1863 reinterpret_cast<intptr_t>(instr)); | 1863 reinterpret_cast<intptr_t>(instr)); |
| 1864 DieOrDebug(); | 1864 DieOrDebug(); |
| 1865 return 0; | 1865 return 0; |
| 1866 } | 1866 } |
| 1867 | 1867 |
| 1868 | 1868 |
| 1869 int16_t Simulator::ReadH(int64_t addr, Instruction* instr) { | 1869 int16_t Simulator::ReadH(int64_t addr, Instruction* instr) { |
| 1870 if ((addr & 1) == 0) { | 1870 if ((addr & 1) == 0 || kArchVariant == kMips64r6) { |
| 1871 int16_t* ptr = reinterpret_cast<int16_t*>(addr); | 1871 int16_t* ptr = reinterpret_cast<int16_t*>(addr); |
| 1872 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1872 TraceMemRd(addr, static_cast<int64_t>(*ptr)); |
| 1873 return *ptr; | 1873 return *ptr; |
| 1874 } | 1874 } |
| 1875 PrintF("Unaligned signed halfword read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1875 PrintF("Unaligned signed halfword read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
| 1876 addr, | 1876 addr, |
| 1877 reinterpret_cast<intptr_t>(instr)); | 1877 reinterpret_cast<intptr_t>(instr)); |
| 1878 DieOrDebug(); | 1878 DieOrDebug(); |
| 1879 return 0; | 1879 return 0; |
| 1880 } | 1880 } |
| 1881 | 1881 |
| 1882 | 1882 |
| 1883 void Simulator::WriteH(int64_t addr, uint16_t value, Instruction* instr) { | 1883 void Simulator::WriteH(int64_t addr, uint16_t value, Instruction* instr) { |
| 1884 if ((addr & 1) == 0) { | 1884 if ((addr & 1) == 0 || kArchVariant == kMips64r6) { |
| 1885 TraceMemWr(addr, value, HALF); | 1885 TraceMemWr(addr, value, HALF); |
| 1886 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); | 1886 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); |
| 1887 *ptr = value; | 1887 *ptr = value; |
| 1888 return; | 1888 return; |
| 1889 } | 1889 } |
| 1890 PrintF( | 1890 PrintF( |
| 1891 "Unaligned unsigned halfword write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1891 "Unaligned unsigned halfword write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
| 1892 addr, | 1892 addr, |
| 1893 reinterpret_cast<intptr_t>(instr)); | 1893 reinterpret_cast<intptr_t>(instr)); |
| 1894 DieOrDebug(); | 1894 DieOrDebug(); |
| 1895 } | 1895 } |
| 1896 | 1896 |
| 1897 | 1897 |
| 1898 void Simulator::WriteH(int64_t addr, int16_t value, Instruction* instr) { | 1898 void Simulator::WriteH(int64_t addr, int16_t value, Instruction* instr) { |
| 1899 if ((addr & 1) == 0) { | 1899 if ((addr & 1) == 0 || kArchVariant == kMips64r6) { |
| 1900 TraceMemWr(addr, value, HALF); | 1900 TraceMemWr(addr, value, HALF); |
| 1901 int16_t* ptr = reinterpret_cast<int16_t*>(addr); | 1901 int16_t* ptr = reinterpret_cast<int16_t*>(addr); |
| 1902 *ptr = value; | 1902 *ptr = value; |
| 1903 return; | 1903 return; |
| 1904 } | 1904 } |
| 1905 PrintF("Unaligned halfword write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1905 PrintF("Unaligned halfword write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
| 1906 addr, | 1906 addr, |
| 1907 reinterpret_cast<intptr_t>(instr)); | 1907 reinterpret_cast<intptr_t>(instr)); |
| 1908 DieOrDebug(); | 1908 DieOrDebug(); |
| 1909 } | 1909 } |
| (...skipping 2205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4115 // Used for conditional branch instructions. | 4115 // Used for conditional branch instructions. |
| 4116 bool execute_branch_delay_instruction = false; | 4116 bool execute_branch_delay_instruction = false; |
| 4117 | 4117 |
| 4118 // Used for arithmetic instructions. | 4118 // Used for arithmetic instructions. |
| 4119 int64_t alu_out = 0; | 4119 int64_t alu_out = 0; |
| 4120 | 4120 |
| 4121 // Used for memory instructions. | 4121 // Used for memory instructions. |
| 4122 int64_t addr = 0x0; | 4122 int64_t addr = 0x0; |
| 4123 // Alignment for 32-bit integers used in LWL, LWR, etc. | 4123 // Alignment for 32-bit integers used in LWL, LWR, etc. |
| 4124 const int kInt32AlignmentMask = sizeof(uint32_t) - 1; | 4124 const int kInt32AlignmentMask = sizeof(uint32_t) - 1; |
| 4125 // Alignment for 64-bit integers used in LDL, LDR, etc. |
| 4126 const int kInt64AlignmentMask = sizeof(uint64_t) - 1; |
| 4125 | 4127 |
| 4126 // Branch instructions common part. | 4128 // Branch instructions common part. |
| 4127 auto BranchAndLinkHelper = [this, instr, &next_pc, | 4129 auto BranchAndLinkHelper = [this, instr, &next_pc, |
| 4128 &execute_branch_delay_instruction]( | 4130 &execute_branch_delay_instruction]( |
| 4129 bool do_branch) { | 4131 bool do_branch) { |
| 4130 execute_branch_delay_instruction = true; | 4132 execute_branch_delay_instruction = true; |
| 4131 int64_t current_pc = get_pc(); | 4133 int64_t current_pc = get_pc(); |
| 4132 if (do_branch) { | 4134 if (do_branch) { |
| 4133 int16_t imm16 = instr->Imm16Value(); | 4135 int16_t imm16 = instr->Imm16Value(); |
| 4134 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; | 4136 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4422 break; | 4424 break; |
| 4423 case LH: | 4425 case LH: |
| 4424 set_register(rt_reg, ReadH(rs + se_imm16, instr)); | 4426 set_register(rt_reg, ReadH(rs + se_imm16, instr)); |
| 4425 break; | 4427 break; |
| 4426 case LWL: { | 4428 case LWL: { |
| 4427 // al_offset is offset of the effective address within an aligned word. | 4429 // al_offset is offset of the effective address within an aligned word. |
| 4428 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; | 4430 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; |
| 4429 uint8_t byte_shift = kInt32AlignmentMask - al_offset; | 4431 uint8_t byte_shift = kInt32AlignmentMask - al_offset; |
| 4430 uint32_t mask = (1 << byte_shift * 8) - 1; | 4432 uint32_t mask = (1 << byte_shift * 8) - 1; |
| 4431 addr = rs + se_imm16 - al_offset; | 4433 addr = rs + se_imm16 - al_offset; |
| 4432 alu_out = ReadW(addr, instr); | 4434 int32_t val = ReadW(addr, instr); |
| 4433 alu_out <<= byte_shift * 8; | 4435 val <<= byte_shift * 8; |
| 4434 alu_out |= rt & mask; | 4436 val |= rt & mask; |
| 4435 set_register(rt_reg, alu_out); | 4437 set_register(rt_reg, static_cast<int64_t>(val)); |
| 4436 break; | 4438 break; |
| 4437 } | 4439 } |
| 4438 case LW: | 4440 case LW: |
| 4439 set_register(rt_reg, ReadW(rs + se_imm16, instr)); | 4441 set_register(rt_reg, ReadW(rs + se_imm16, instr)); |
| 4440 break; | 4442 break; |
| 4441 case LWU: | 4443 case LWU: |
| 4442 set_register(rt_reg, ReadWU(rs + se_imm16, instr)); | 4444 set_register(rt_reg, ReadWU(rs + se_imm16, instr)); |
| 4443 break; | 4445 break; |
| 4444 case LD: | 4446 case LD: |
| 4445 set_register(rt_reg, Read2W(rs + se_imm16, instr)); | 4447 set_register(rt_reg, Read2W(rs + se_imm16, instr)); |
| 4446 break; | 4448 break; |
| 4447 case LBU: | 4449 case LBU: |
| 4448 set_register(rt_reg, ReadBU(rs + se_imm16)); | 4450 set_register(rt_reg, ReadBU(rs + se_imm16)); |
| 4449 break; | 4451 break; |
| 4450 case LHU: | 4452 case LHU: |
| 4451 set_register(rt_reg, ReadHU(rs + se_imm16, instr)); | 4453 set_register(rt_reg, ReadHU(rs + se_imm16, instr)); |
| 4452 break; | 4454 break; |
| 4453 case LWR: { | 4455 case LWR: { |
| 4454 // al_offset is offset of the effective address within an aligned word. | 4456 // al_offset is offset of the effective address within an aligned word. |
| 4455 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; | 4457 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; |
| 4456 uint8_t byte_shift = kInt32AlignmentMask - al_offset; | 4458 uint8_t byte_shift = kInt32AlignmentMask - al_offset; |
| 4457 uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0; | 4459 uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0; |
| 4458 addr = rs + se_imm16 - al_offset; | 4460 addr = rs + se_imm16 - al_offset; |
| 4459 alu_out = ReadW(addr, instr); | 4461 alu_out = ReadW(addr, instr); |
| 4460 alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8; | 4462 alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8; |
| 4461 alu_out |= rt & mask; | 4463 alu_out |= rt & mask; |
| 4462 set_register(rt_reg, alu_out); | 4464 set_register(rt_reg, alu_out); |
| 4463 break; | 4465 break; |
| 4464 } | 4466 } |
| 4467 case LDL: { |
| 4468 // al_offset is offset of the effective address within an aligned word. |
| 4469 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; |
| 4470 uint8_t byte_shift = kInt64AlignmentMask - al_offset; |
| 4471 uint64_t mask = (1UL << byte_shift * 8) - 1; |
| 4472 addr = rs + se_imm16 - al_offset; |
| 4473 alu_out = Read2W(addr, instr); |
| 4474 alu_out <<= byte_shift * 8; |
| 4475 alu_out |= rt & mask; |
| 4476 set_register(rt_reg, alu_out); |
| 4477 break; |
| 4478 } |
| 4479 case LDR: { |
| 4480 // al_offset is offset of the effective address within an aligned word. |
| 4481 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; |
| 4482 uint8_t byte_shift = kInt64AlignmentMask - al_offset; |
| 4483 uint64_t mask = al_offset ? (~0UL << (byte_shift + 1) * 8) : 0UL; |
| 4484 addr = rs + se_imm16 - al_offset; |
| 4485 alu_out = Read2W(addr, instr); |
| 4486 alu_out = alu_out >> al_offset * 8; |
| 4487 alu_out |= rt & mask; |
| 4488 set_register(rt_reg, alu_out); |
| 4489 break; |
| 4490 } |
| 4465 case SB: | 4491 case SB: |
| 4466 WriteB(rs + se_imm16, static_cast<int8_t>(rt)); | 4492 WriteB(rs + se_imm16, static_cast<int8_t>(rt)); |
| 4467 break; | 4493 break; |
| 4468 case SH: | 4494 case SH: |
| 4469 WriteH(rs + se_imm16, static_cast<uint16_t>(rt), instr); | 4495 WriteH(rs + se_imm16, static_cast<uint16_t>(rt), instr); |
| 4470 break; | 4496 break; |
| 4471 case SWL: { | 4497 case SWL: { |
| 4472 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; | 4498 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; |
| 4473 uint8_t byte_shift = kInt32AlignmentMask - al_offset; | 4499 uint8_t byte_shift = kInt32AlignmentMask - al_offset; |
| 4474 uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0; | 4500 uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4486 break; | 4512 break; |
| 4487 case SWR: { | 4513 case SWR: { |
| 4488 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; | 4514 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; |
| 4489 uint32_t mask = (1 << al_offset * 8) - 1; | 4515 uint32_t mask = (1 << al_offset * 8) - 1; |
| 4490 addr = rs + se_imm16 - al_offset; | 4516 addr = rs + se_imm16 - al_offset; |
| 4491 uint64_t mem_value = ReadW(addr, instr); | 4517 uint64_t mem_value = ReadW(addr, instr); |
| 4492 mem_value = (rt << al_offset * 8) | (mem_value & mask); | 4518 mem_value = (rt << al_offset * 8) | (mem_value & mask); |
| 4493 WriteW(addr, static_cast<int32_t>(mem_value), instr); | 4519 WriteW(addr, static_cast<int32_t>(mem_value), instr); |
| 4494 break; | 4520 break; |
| 4495 } | 4521 } |
| 4522 case SDL: { |
| 4523 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; |
| 4524 uint8_t byte_shift = kInt64AlignmentMask - al_offset; |
| 4525 uint64_t mask = byte_shift ? (~0UL << (al_offset + 1) * 8) : 0; |
| 4526 addr = rs + se_imm16 - al_offset; |
| 4527 uint64_t mem_value = Read2W(addr, instr) & mask; |
| 4528 mem_value |= rt >> byte_shift * 8; |
| 4529 Write2W(addr, mem_value, instr); |
| 4530 break; |
| 4531 } |
| 4532 case SDR: { |
| 4533 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; |
| 4534 uint64_t mask = (1UL << al_offset * 8) - 1; |
| 4535 addr = rs + se_imm16 - al_offset; |
| 4536 uint64_t mem_value = Read2W(addr, instr); |
| 4537 mem_value = (rt << al_offset * 8) | (mem_value & mask); |
| 4538 Write2W(addr, mem_value, instr); |
| 4539 break; |
| 4540 } |
| 4496 case LWC1: | 4541 case LWC1: |
| 4497 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits. | 4542 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits. |
| 4498 set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr)); | 4543 set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr)); |
| 4499 break; | 4544 break; |
| 4500 case LDC1: | 4545 case LDC1: |
| 4501 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr)); | 4546 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr)); |
| 4502 break; | 4547 break; |
| 4503 case SWC1: { | 4548 case SWC1: { |
| 4504 int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg)); | 4549 int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg)); |
| 4505 WriteW(rs + se_imm16, alu_out_32, instr); | 4550 WriteW(rs + se_imm16, alu_out_32, instr); |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4855 } | 4900 } |
| 4856 | 4901 |
| 4857 | 4902 |
| 4858 #undef UNSUPPORTED | 4903 #undef UNSUPPORTED |
| 4859 } // namespace internal | 4904 } // namespace internal |
| 4860 } // namespace v8 | 4905 } // namespace v8 |
| 4861 | 4906 |
| 4862 #endif // USE_SIMULATOR | 4907 #endif // USE_SIMULATOR |
| 4863 | 4908 |
| 4864 #endif // V8_TARGET_ARCH_MIPS64 | 4909 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |