| 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 1725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1736 // TODO(plind): sign-extend and zero-extend not implmented properly | 1736 // TODO(plind): sign-extend and zero-extend not implmented properly |
| 1737 // on all the ReadXX functions, I don't think re-interpret cast does it. | 1737 // on all the ReadXX functions, I don't think re-interpret cast does it. |
| 1738 int32_t Simulator::ReadW(int64_t addr, Instruction* instr) { | 1738 int32_t Simulator::ReadW(int64_t addr, Instruction* instr) { |
| 1739 if (addr >=0 && addr < 0x400) { | 1739 if (addr >=0 && addr < 0x400) { |
| 1740 // This has to be a NULL-dereference, drop into debugger. | 1740 // This has to be a NULL-dereference, drop into debugger. |
| 1741 PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR | 1741 PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR |
| 1742 " \n", | 1742 " \n", |
| 1743 addr, reinterpret_cast<intptr_t>(instr)); | 1743 addr, reinterpret_cast<intptr_t>(instr)); |
| 1744 DieOrDebug(); | 1744 DieOrDebug(); |
| 1745 } | 1745 } |
| 1746 if ((addr & 0x3) == 0) { | 1746 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { |
| 1747 int32_t* ptr = reinterpret_cast<int32_t*>(addr); | 1747 int32_t* ptr = reinterpret_cast<int32_t*>(addr); |
| 1748 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1748 TraceMemRd(addr, static_cast<int64_t>(*ptr)); |
| 1749 return *ptr; | 1749 return *ptr; |
| 1750 } | 1750 } |
| 1751 PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, | 1751 PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, |
| 1752 reinterpret_cast<intptr_t>(instr)); | 1752 reinterpret_cast<intptr_t>(instr)); |
| 1753 DieOrDebug(); | 1753 DieOrDebug(); |
| 1754 return 0; | 1754 return 0; |
| 1755 } | 1755 } |
| 1756 | 1756 |
| 1757 | 1757 |
| 1758 uint32_t Simulator::ReadWU(int64_t addr, Instruction* instr) { | 1758 uint32_t Simulator::ReadWU(int64_t addr, Instruction* instr) { |
| 1759 if (addr >=0 && addr < 0x400) { | 1759 if (addr >=0 && addr < 0x400) { |
| 1760 // This has to be a NULL-dereference, drop into debugger. | 1760 // This has to be a NULL-dereference, drop into debugger. |
| 1761 PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR | 1761 PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR |
| 1762 " \n", | 1762 " \n", |
| 1763 addr, reinterpret_cast<intptr_t>(instr)); | 1763 addr, reinterpret_cast<intptr_t>(instr)); |
| 1764 DieOrDebug(); | 1764 DieOrDebug(); |
| 1765 } | 1765 } |
| 1766 if ((addr & 0x3) == 0) { | 1766 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { |
| 1767 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); | 1767 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); |
| 1768 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1768 TraceMemRd(addr, static_cast<int64_t>(*ptr)); |
| 1769 return *ptr; | 1769 return *ptr; |
| 1770 } | 1770 } |
| 1771 PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, | 1771 PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, |
| 1772 reinterpret_cast<intptr_t>(instr)); | 1772 reinterpret_cast<intptr_t>(instr)); |
| 1773 DieOrDebug(); | 1773 DieOrDebug(); |
| 1774 return 0; | 1774 return 0; |
| 1775 } | 1775 } |
| 1776 | 1776 |
| 1777 | 1777 |
| 1778 void Simulator::WriteW(int64_t addr, int32_t value, Instruction* instr) { | 1778 void Simulator::WriteW(int64_t addr, int32_t value, Instruction* instr) { |
| 1779 if (addr >= 0 && addr < 0x400) { | 1779 if (addr >= 0 && addr < 0x400) { |
| 1780 // This has to be a NULL-dereference, drop into debugger. | 1780 // This has to be a NULL-dereference, drop into debugger. |
| 1781 PrintF("Memory write to bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR | 1781 PrintF("Memory write to bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR |
| 1782 " \n", | 1782 " \n", |
| 1783 addr, reinterpret_cast<intptr_t>(instr)); | 1783 addr, reinterpret_cast<intptr_t>(instr)); |
| 1784 DieOrDebug(); | 1784 DieOrDebug(); |
| 1785 } | 1785 } |
| 1786 if ((addr & 0x3) == 0) { | 1786 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { |
| 1787 TraceMemWr(addr, value, WORD); | 1787 TraceMemWr(addr, value, WORD); |
| 1788 int* ptr = reinterpret_cast<int*>(addr); | 1788 int* ptr = reinterpret_cast<int*>(addr); |
| 1789 *ptr = value; | 1789 *ptr = value; |
| 1790 return; | 1790 return; |
| 1791 } | 1791 } |
| 1792 PrintF("Unaligned write at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, | 1792 PrintF("Unaligned write at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, |
| 1793 reinterpret_cast<intptr_t>(instr)); | 1793 reinterpret_cast<intptr_t>(instr)); |
| 1794 DieOrDebug(); | 1794 DieOrDebug(); |
| 1795 } | 1795 } |
| 1796 | 1796 |
| 1797 | 1797 |
| 1798 int64_t Simulator::Read2W(int64_t addr, Instruction* instr) { | 1798 int64_t Simulator::Read2W(int64_t addr, Instruction* instr) { |
| 1799 if (addr >=0 && addr < 0x400) { | 1799 if (addr >=0 && addr < 0x400) { |
| 1800 // This has to be a NULL-dereference, drop into debugger. | 1800 // This has to be a NULL-dereference, drop into debugger. |
| 1801 PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR | 1801 PrintF("Memory read from bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR |
| 1802 " \n", | 1802 " \n", |
| 1803 addr, reinterpret_cast<intptr_t>(instr)); | 1803 addr, reinterpret_cast<intptr_t>(instr)); |
| 1804 DieOrDebug(); | 1804 DieOrDebug(); |
| 1805 } | 1805 } |
| 1806 if ((addr & kPointerAlignmentMask) == 0) { | 1806 if ((addr & kPointerAlignmentMask) == 0 || kArchVariant == kMips64r6) { |
| 1807 int64_t* ptr = reinterpret_cast<int64_t*>(addr); | 1807 int64_t* ptr = reinterpret_cast<int64_t*>(addr); |
| 1808 TraceMemRd(addr, *ptr); | 1808 TraceMemRd(addr, *ptr); |
| 1809 return *ptr; | 1809 return *ptr; |
| 1810 } | 1810 } |
| 1811 PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, | 1811 PrintF("Unaligned read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, |
| 1812 reinterpret_cast<intptr_t>(instr)); | 1812 reinterpret_cast<intptr_t>(instr)); |
| 1813 DieOrDebug(); | 1813 DieOrDebug(); |
| 1814 return 0; | 1814 return 0; |
| 1815 } | 1815 } |
| 1816 | 1816 |
| 1817 | 1817 |
| 1818 void Simulator::Write2W(int64_t addr, int64_t value, Instruction* instr) { | 1818 void Simulator::Write2W(int64_t addr, int64_t value, Instruction* instr) { |
| 1819 if (addr >= 0 && addr < 0x400) { | 1819 if (addr >= 0 && addr < 0x400) { |
| 1820 // This has to be a NULL-dereference, drop into debugger. | 1820 // This has to be a NULL-dereference, drop into debugger. |
| 1821 PrintF("Memory write to bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR | 1821 PrintF("Memory write to bad address: 0x%08" PRIx64 " , pc=0x%08" PRIxPTR |
| 1822 "\n", | 1822 "\n", |
| 1823 addr, reinterpret_cast<intptr_t>(instr)); | 1823 addr, reinterpret_cast<intptr_t>(instr)); |
| 1824 DieOrDebug(); | 1824 DieOrDebug(); |
| 1825 } | 1825 } |
| 1826 if ((addr & kPointerAlignmentMask) == 0) { | 1826 if ((addr & kPointerAlignmentMask) == 0 || kArchVariant == kMips64r6) { |
| 1827 TraceMemWr(addr, value, DWORD); | 1827 TraceMemWr(addr, value, DWORD); |
| 1828 int64_t* ptr = reinterpret_cast<int64_t*>(addr); | 1828 int64_t* ptr = reinterpret_cast<int64_t*>(addr); |
| 1829 *ptr = value; | 1829 *ptr = value; |
| 1830 return; | 1830 return; |
| 1831 } | 1831 } |
| 1832 PrintF("Unaligned write at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, | 1832 PrintF("Unaligned write at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", addr, |
| 1833 reinterpret_cast<intptr_t>(instr)); | 1833 reinterpret_cast<intptr_t>(instr)); |
| 1834 DieOrDebug(); | 1834 DieOrDebug(); |
| 1835 } | 1835 } |
| 1836 | 1836 |
| 1837 | 1837 |
| 1838 double Simulator::ReadD(int64_t addr, Instruction* instr) { | 1838 double Simulator::ReadD(int64_t addr, Instruction* instr) { |
| 1839 if ((addr & kDoubleAlignmentMask) == 0) { | 1839 if ((addr & kDoubleAlignmentMask) == 0 || kArchVariant == kMips64r6) { |
| 1840 double* ptr = reinterpret_cast<double*>(addr); | 1840 double* ptr = reinterpret_cast<double*>(addr); |
| 1841 return *ptr; | 1841 return *ptr; |
| 1842 } | 1842 } |
| 1843 PrintF("Unaligned (double) read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", | 1843 PrintF("Unaligned (double) read at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR "\n", |
| 1844 addr, reinterpret_cast<intptr_t>(instr)); | 1844 addr, reinterpret_cast<intptr_t>(instr)); |
| 1845 base::OS::Abort(); | 1845 base::OS::Abort(); |
| 1846 return 0; | 1846 return 0; |
| 1847 } | 1847 } |
| 1848 | 1848 |
| 1849 | 1849 |
| 1850 void Simulator::WriteD(int64_t addr, double value, Instruction* instr) { | 1850 void Simulator::WriteD(int64_t addr, double value, Instruction* instr) { |
| 1851 if ((addr & kDoubleAlignmentMask) == 0) { | 1851 if ((addr & kDoubleAlignmentMask) == 0 || kArchVariant == kMips64r6) { |
| 1852 double* ptr = reinterpret_cast<double*>(addr); | 1852 double* ptr = reinterpret_cast<double*>(addr); |
| 1853 *ptr = value; | 1853 *ptr = value; |
| 1854 return; | 1854 return; |
| 1855 } | 1855 } |
| 1856 PrintF("Unaligned (double) write at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR | 1856 PrintF("Unaligned (double) write at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR |
| 1857 "\n", | 1857 "\n", |
| 1858 addr, reinterpret_cast<intptr_t>(instr)); | 1858 addr, reinterpret_cast<intptr_t>(instr)); |
| 1859 DieOrDebug(); | 1859 DieOrDebug(); |
| 1860 } | 1860 } |
| 1861 | 1861 |
| 1862 | 1862 |
| 1863 uint16_t Simulator::ReadHU(int64_t addr, Instruction* instr) { | 1863 uint16_t Simulator::ReadHU(int64_t addr, Instruction* instr) { |
| 1864 if ((addr & 1) == 0) { | 1864 if ((addr & 1) == 0 || kArchVariant == kMips64r6) { |
| 1865 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); | 1865 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); |
| 1866 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1866 TraceMemRd(addr, static_cast<int64_t>(*ptr)); |
| 1867 return *ptr; | 1867 return *ptr; |
| 1868 } | 1868 } |
| 1869 PrintF("Unaligned unsigned halfword read at 0x%08" PRIx64 | 1869 PrintF("Unaligned unsigned halfword read at 0x%08" PRIx64 |
| 1870 " , pc=0x%08" V8PRIxPTR "\n", | 1870 " , pc=0x%08" V8PRIxPTR "\n", |
| 1871 addr, reinterpret_cast<intptr_t>(instr)); | 1871 addr, reinterpret_cast<intptr_t>(instr)); |
| 1872 DieOrDebug(); | 1872 DieOrDebug(); |
| 1873 return 0; | 1873 return 0; |
| 1874 } | 1874 } |
| 1875 | 1875 |
| 1876 | 1876 |
| 1877 int16_t Simulator::ReadH(int64_t addr, Instruction* instr) { | 1877 int16_t Simulator::ReadH(int64_t addr, Instruction* instr) { |
| 1878 if ((addr & 1) == 0) { | 1878 if ((addr & 1) == 0 || kArchVariant == kMips64r6) { |
| 1879 int16_t* ptr = reinterpret_cast<int16_t*>(addr); | 1879 int16_t* ptr = reinterpret_cast<int16_t*>(addr); |
| 1880 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1880 TraceMemRd(addr, static_cast<int64_t>(*ptr)); |
| 1881 return *ptr; | 1881 return *ptr; |
| 1882 } | 1882 } |
| 1883 PrintF("Unaligned signed halfword read at 0x%08" PRIx64 | 1883 PrintF("Unaligned signed halfword read at 0x%08" PRIx64 |
| 1884 " , pc=0x%08" V8PRIxPTR "\n", | 1884 " , pc=0x%08" V8PRIxPTR "\n", |
| 1885 addr, reinterpret_cast<intptr_t>(instr)); | 1885 addr, reinterpret_cast<intptr_t>(instr)); |
| 1886 DieOrDebug(); | 1886 DieOrDebug(); |
| 1887 return 0; | 1887 return 0; |
| 1888 } | 1888 } |
| 1889 | 1889 |
| 1890 | 1890 |
| 1891 void Simulator::WriteH(int64_t addr, uint16_t value, Instruction* instr) { | 1891 void Simulator::WriteH(int64_t addr, uint16_t value, Instruction* instr) { |
| 1892 if ((addr & 1) == 0) { | 1892 if ((addr & 1) == 0 || kArchVariant == kMips64r6) { |
| 1893 TraceMemWr(addr, value, HALF); | 1893 TraceMemWr(addr, value, HALF); |
| 1894 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); | 1894 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); |
| 1895 *ptr = value; | 1895 *ptr = value; |
| 1896 return; | 1896 return; |
| 1897 } | 1897 } |
| 1898 PrintF("Unaligned unsigned halfword write at 0x%08" PRIx64 | 1898 PrintF("Unaligned unsigned halfword write at 0x%08" PRIx64 |
| 1899 " , pc=0x%08" V8PRIxPTR "\n", | 1899 " , pc=0x%08" V8PRIxPTR "\n", |
| 1900 addr, reinterpret_cast<intptr_t>(instr)); | 1900 addr, reinterpret_cast<intptr_t>(instr)); |
| 1901 DieOrDebug(); | 1901 DieOrDebug(); |
| 1902 } | 1902 } |
| 1903 | 1903 |
| 1904 | 1904 |
| 1905 void Simulator::WriteH(int64_t addr, int16_t value, Instruction* instr) { | 1905 void Simulator::WriteH(int64_t addr, int16_t value, Instruction* instr) { |
| 1906 if ((addr & 1) == 0) { | 1906 if ((addr & 1) == 0 || kArchVariant == kMips64r6) { |
| 1907 TraceMemWr(addr, value, HALF); | 1907 TraceMemWr(addr, value, HALF); |
| 1908 int16_t* ptr = reinterpret_cast<int16_t*>(addr); | 1908 int16_t* ptr = reinterpret_cast<int16_t*>(addr); |
| 1909 *ptr = value; | 1909 *ptr = value; |
| 1910 return; | 1910 return; |
| 1911 } | 1911 } |
| 1912 PrintF("Unaligned halfword write at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR | 1912 PrintF("Unaligned halfword write at 0x%08" PRIx64 " , pc=0x%08" V8PRIxPTR |
| 1913 "\n", | 1913 "\n", |
| 1914 addr, reinterpret_cast<intptr_t>(instr)); | 1914 addr, reinterpret_cast<intptr_t>(instr)); |
| 1915 DieOrDebug(); | 1915 DieOrDebug(); |
| 1916 } | 1916 } |
| (...skipping 2240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4157 // Used for conditional branch instructions. | 4157 // Used for conditional branch instructions. |
| 4158 bool execute_branch_delay_instruction = false; | 4158 bool execute_branch_delay_instruction = false; |
| 4159 | 4159 |
| 4160 // Used for arithmetic instructions. | 4160 // Used for arithmetic instructions. |
| 4161 int64_t alu_out = 0; | 4161 int64_t alu_out = 0; |
| 4162 | 4162 |
| 4163 // Used for memory instructions. | 4163 // Used for memory instructions. |
| 4164 int64_t addr = 0x0; | 4164 int64_t addr = 0x0; |
| 4165 // Alignment for 32-bit integers used in LWL, LWR, etc. | 4165 // Alignment for 32-bit integers used in LWL, LWR, etc. |
| 4166 const int kInt32AlignmentMask = sizeof(uint32_t) - 1; | 4166 const int kInt32AlignmentMask = sizeof(uint32_t) - 1; |
| 4167 // Alignment for 64-bit integers used in LDL, LDR, etc. |
| 4168 const int kInt64AlignmentMask = sizeof(uint64_t) - 1; |
| 4167 | 4169 |
| 4168 // Branch instructions common part. | 4170 // Branch instructions common part. |
| 4169 auto BranchAndLinkHelper = [this, instr, &next_pc, | 4171 auto BranchAndLinkHelper = [this, instr, &next_pc, |
| 4170 &execute_branch_delay_instruction]( | 4172 &execute_branch_delay_instruction]( |
| 4171 bool do_branch) { | 4173 bool do_branch) { |
| 4172 execute_branch_delay_instruction = true; | 4174 execute_branch_delay_instruction = true; |
| 4173 int64_t current_pc = get_pc(); | 4175 int64_t current_pc = get_pc(); |
| 4174 if (do_branch) { | 4176 if (do_branch) { |
| 4175 int16_t imm16 = instr->Imm16Value(); | 4177 int16_t imm16 = instr->Imm16Value(); |
| 4176 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; | 4178 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4458 break; | 4460 break; |
| 4459 case LH: | 4461 case LH: |
| 4460 set_register(rt_reg, ReadH(rs + se_imm16, instr)); | 4462 set_register(rt_reg, ReadH(rs + se_imm16, instr)); |
| 4461 break; | 4463 break; |
| 4462 case LWL: { | 4464 case LWL: { |
| 4463 // al_offset is offset of the effective address within an aligned word. | 4465 // al_offset is offset of the effective address within an aligned word. |
| 4464 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; | 4466 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; |
| 4465 uint8_t byte_shift = kInt32AlignmentMask - al_offset; | 4467 uint8_t byte_shift = kInt32AlignmentMask - al_offset; |
| 4466 uint32_t mask = (1 << byte_shift * 8) - 1; | 4468 uint32_t mask = (1 << byte_shift * 8) - 1; |
| 4467 addr = rs + se_imm16 - al_offset; | 4469 addr = rs + se_imm16 - al_offset; |
| 4468 alu_out = ReadW(addr, instr); | 4470 int32_t val = ReadW(addr, instr); |
| 4469 alu_out <<= byte_shift * 8; | 4471 val <<= byte_shift * 8; |
| 4470 alu_out |= rt & mask; | 4472 val |= rt & mask; |
| 4471 set_register(rt_reg, alu_out); | 4473 set_register(rt_reg, static_cast<int64_t>(val)); |
| 4472 break; | 4474 break; |
| 4473 } | 4475 } |
| 4474 case LW: | 4476 case LW: |
| 4475 set_register(rt_reg, ReadW(rs + se_imm16, instr)); | 4477 set_register(rt_reg, ReadW(rs + se_imm16, instr)); |
| 4476 break; | 4478 break; |
| 4477 case LWU: | 4479 case LWU: |
| 4478 set_register(rt_reg, ReadWU(rs + se_imm16, instr)); | 4480 set_register(rt_reg, ReadWU(rs + se_imm16, instr)); |
| 4479 break; | 4481 break; |
| 4480 case LD: | 4482 case LD: |
| 4481 set_register(rt_reg, Read2W(rs + se_imm16, instr)); | 4483 set_register(rt_reg, Read2W(rs + se_imm16, instr)); |
| 4482 break; | 4484 break; |
| 4483 case LBU: | 4485 case LBU: |
| 4484 set_register(rt_reg, ReadBU(rs + se_imm16)); | 4486 set_register(rt_reg, ReadBU(rs + se_imm16)); |
| 4485 break; | 4487 break; |
| 4486 case LHU: | 4488 case LHU: |
| 4487 set_register(rt_reg, ReadHU(rs + se_imm16, instr)); | 4489 set_register(rt_reg, ReadHU(rs + se_imm16, instr)); |
| 4488 break; | 4490 break; |
| 4489 case LWR: { | 4491 case LWR: { |
| 4490 // al_offset is offset of the effective address within an aligned word. | 4492 // al_offset is offset of the effective address within an aligned word. |
| 4491 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; | 4493 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; |
| 4492 uint8_t byte_shift = kInt32AlignmentMask - al_offset; | 4494 uint8_t byte_shift = kInt32AlignmentMask - al_offset; |
| 4493 uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0; | 4495 uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0; |
| 4494 addr = rs + se_imm16 - al_offset; | 4496 addr = rs + se_imm16 - al_offset; |
| 4495 alu_out = ReadW(addr, instr); | 4497 alu_out = ReadW(addr, instr); |
| 4496 alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8; | 4498 alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8; |
| 4497 alu_out |= rt & mask; | 4499 alu_out |= rt & mask; |
| 4498 set_register(rt_reg, alu_out); | 4500 set_register(rt_reg, alu_out); |
| 4499 break; | 4501 break; |
| 4500 } | 4502 } |
| 4503 case LDL: { |
| 4504 // al_offset is offset of the effective address within an aligned word. |
| 4505 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; |
| 4506 uint8_t byte_shift = kInt64AlignmentMask - al_offset; |
| 4507 uint64_t mask = (1UL << byte_shift * 8) - 1; |
| 4508 addr = rs + se_imm16 - al_offset; |
| 4509 alu_out = Read2W(addr, instr); |
| 4510 alu_out <<= byte_shift * 8; |
| 4511 alu_out |= rt & mask; |
| 4512 set_register(rt_reg, alu_out); |
| 4513 break; |
| 4514 } |
| 4515 case LDR: { |
| 4516 // al_offset is offset of the effective address within an aligned word. |
| 4517 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; |
| 4518 uint8_t byte_shift = kInt64AlignmentMask - al_offset; |
| 4519 uint64_t mask = al_offset ? (~0UL << (byte_shift + 1) * 8) : 0UL; |
| 4520 addr = rs + se_imm16 - al_offset; |
| 4521 alu_out = Read2W(addr, instr); |
| 4522 alu_out = alu_out >> al_offset * 8; |
| 4523 alu_out |= rt & mask; |
| 4524 set_register(rt_reg, alu_out); |
| 4525 break; |
| 4526 } |
| 4501 case SB: | 4527 case SB: |
| 4502 WriteB(rs + se_imm16, static_cast<int8_t>(rt)); | 4528 WriteB(rs + se_imm16, static_cast<int8_t>(rt)); |
| 4503 break; | 4529 break; |
| 4504 case SH: | 4530 case SH: |
| 4505 WriteH(rs + se_imm16, static_cast<uint16_t>(rt), instr); | 4531 WriteH(rs + se_imm16, static_cast<uint16_t>(rt), instr); |
| 4506 break; | 4532 break; |
| 4507 case SWL: { | 4533 case SWL: { |
| 4508 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; | 4534 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; |
| 4509 uint8_t byte_shift = kInt32AlignmentMask - al_offset; | 4535 uint8_t byte_shift = kInt32AlignmentMask - al_offset; |
| 4510 uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0; | 4536 uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4522 break; | 4548 break; |
| 4523 case SWR: { | 4549 case SWR: { |
| 4524 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; | 4550 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; |
| 4525 uint32_t mask = (1 << al_offset * 8) - 1; | 4551 uint32_t mask = (1 << al_offset * 8) - 1; |
| 4526 addr = rs + se_imm16 - al_offset; | 4552 addr = rs + se_imm16 - al_offset; |
| 4527 uint64_t mem_value = ReadW(addr, instr); | 4553 uint64_t mem_value = ReadW(addr, instr); |
| 4528 mem_value = (rt << al_offset * 8) | (mem_value & mask); | 4554 mem_value = (rt << al_offset * 8) | (mem_value & mask); |
| 4529 WriteW(addr, static_cast<int32_t>(mem_value), instr); | 4555 WriteW(addr, static_cast<int32_t>(mem_value), instr); |
| 4530 break; | 4556 break; |
| 4531 } | 4557 } |
| 4558 case SDL: { |
| 4559 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; |
| 4560 uint8_t byte_shift = kInt64AlignmentMask - al_offset; |
| 4561 uint64_t mask = byte_shift ? (~0UL << (al_offset + 1) * 8) : 0; |
| 4562 addr = rs + se_imm16 - al_offset; |
| 4563 uint64_t mem_value = Read2W(addr, instr) & mask; |
| 4564 mem_value |= rt >> byte_shift * 8; |
| 4565 Write2W(addr, mem_value, instr); |
| 4566 break; |
| 4567 } |
| 4568 case SDR: { |
| 4569 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; |
| 4570 uint64_t mask = (1UL << al_offset * 8) - 1; |
| 4571 addr = rs + se_imm16 - al_offset; |
| 4572 uint64_t mem_value = Read2W(addr, instr); |
| 4573 mem_value = (rt << al_offset * 8) | (mem_value & mask); |
| 4574 Write2W(addr, mem_value, instr); |
| 4575 break; |
| 4576 } |
| 4532 case LWC1: | 4577 case LWC1: |
| 4533 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits. | 4578 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits. |
| 4534 set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr)); | 4579 set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr)); |
| 4535 break; | 4580 break; |
| 4536 case LDC1: | 4581 case LDC1: |
| 4537 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr)); | 4582 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr)); |
| 4538 break; | 4583 break; |
| 4539 case SWC1: { | 4584 case SWC1: { |
| 4540 int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg)); | 4585 int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg)); |
| 4541 WriteW(rs + se_imm16, alu_out_32, instr); | 4586 WriteW(rs + se_imm16, alu_out_32, instr); |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4892 } | 4937 } |
| 4893 | 4938 |
| 4894 | 4939 |
| 4895 #undef UNSUPPORTED | 4940 #undef UNSUPPORTED |
| 4896 } // namespace internal | 4941 } // namespace internal |
| 4897 } // namespace v8 | 4942 } // namespace v8 |
| 4898 | 4943 |
| 4899 #endif // USE_SIMULATOR | 4944 #endif // USE_SIMULATOR |
| 4900 | 4945 |
| 4901 #endif // V8_TARGET_ARCH_MIPS64 | 4946 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |