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 1712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1723 | 1723 |
1724 // TODO(plind): sign-extend and zero-extend not implmented properly | 1724 // TODO(plind): sign-extend and zero-extend not implmented properly |
1725 // on all the ReadXX functions, I don't think re-interpret cast does it. | 1725 // on all the ReadXX functions, I don't think re-interpret cast does it. |
1726 int32_t Simulator::ReadW(int64_t addr, Instruction* instr) { | 1726 int32_t Simulator::ReadW(int64_t addr, Instruction* instr) { |
1727 if (addr >=0 && addr < 0x400) { | 1727 if (addr >=0 && addr < 0x400) { |
1728 // This has to be a NULL-dereference, drop into debugger. | 1728 // This has to be a NULL-dereference, drop into debugger. |
1729 PrintF("Memory read from bad address: 0x%08lx, pc=0x%08lx\n", | 1729 PrintF("Memory read from bad address: 0x%08lx, pc=0x%08lx\n", |
1730 addr, reinterpret_cast<intptr_t>(instr)); | 1730 addr, reinterpret_cast<intptr_t>(instr)); |
1731 DieOrDebug(); | 1731 DieOrDebug(); |
1732 } | 1732 } |
1733 if ((addr & 0x3) == 0) { | 1733 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { |
1734 int32_t* ptr = reinterpret_cast<int32_t*>(addr); | 1734 int32_t* ptr = reinterpret_cast<int32_t*>(addr); |
1735 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1735 TraceMemRd(addr, static_cast<int64_t>(*ptr)); |
1736 return *ptr; | 1736 return *ptr; |
1737 } | 1737 } |
1738 PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1738 PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
1739 addr, | 1739 addr, |
1740 reinterpret_cast<intptr_t>(instr)); | 1740 reinterpret_cast<intptr_t>(instr)); |
1741 DieOrDebug(); | 1741 DieOrDebug(); |
1742 return 0; | 1742 return 0; |
1743 } | 1743 } |
1744 | 1744 |
1745 | 1745 |
1746 uint32_t Simulator::ReadWU(int64_t addr, Instruction* instr) { | 1746 uint32_t Simulator::ReadWU(int64_t addr, Instruction* instr) { |
1747 if (addr >=0 && addr < 0x400) { | 1747 if (addr >=0 && addr < 0x400) { |
1748 // This has to be a NULL-dereference, drop into debugger. | 1748 // This has to be a NULL-dereference, drop into debugger. |
1749 PrintF("Memory read from bad address: 0x%08lx, pc=0x%08lx\n", | 1749 PrintF("Memory read from bad address: 0x%08lx, pc=0x%08lx\n", |
1750 addr, reinterpret_cast<intptr_t>(instr)); | 1750 addr, reinterpret_cast<intptr_t>(instr)); |
1751 DieOrDebug(); | 1751 DieOrDebug(); |
1752 } | 1752 } |
1753 if ((addr & 0x3) == 0) { | 1753 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { |
1754 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); | 1754 uint32_t* ptr = reinterpret_cast<uint32_t*>(addr); |
1755 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1755 TraceMemRd(addr, static_cast<int64_t>(*ptr)); |
1756 return *ptr; | 1756 return *ptr; |
1757 } | 1757 } |
1758 PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1758 PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
1759 addr, | 1759 addr, |
1760 reinterpret_cast<intptr_t>(instr)); | 1760 reinterpret_cast<intptr_t>(instr)); |
1761 DieOrDebug(); | 1761 DieOrDebug(); |
1762 return 0; | 1762 return 0; |
1763 } | 1763 } |
1764 | 1764 |
1765 | 1765 |
1766 void Simulator::WriteW(int64_t addr, int32_t value, Instruction* instr) { | 1766 void Simulator::WriteW(int64_t addr, int32_t value, Instruction* instr) { |
1767 if (addr >= 0 && addr < 0x400) { | 1767 if (addr >= 0 && addr < 0x400) { |
1768 // This has to be a NULL-dereference, drop into debugger. | 1768 // This has to be a NULL-dereference, drop into debugger. |
1769 PrintF("Memory write to bad address: 0x%08lx, pc=0x%08lx\n", | 1769 PrintF("Memory write to bad address: 0x%08lx, pc=0x%08lx\n", |
1770 addr, reinterpret_cast<intptr_t>(instr)); | 1770 addr, reinterpret_cast<intptr_t>(instr)); |
1771 DieOrDebug(); | 1771 DieOrDebug(); |
1772 } | 1772 } |
1773 if ((addr & 0x3) == 0) { | 1773 if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) { |
1774 TraceMemWr(addr, value, WORD); | 1774 TraceMemWr(addr, value, WORD); |
1775 int* ptr = reinterpret_cast<int*>(addr); | 1775 int* ptr = reinterpret_cast<int*>(addr); |
1776 *ptr = value; | 1776 *ptr = value; |
1777 return; | 1777 return; |
1778 } | 1778 } |
1779 PrintF("Unaligned write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1779 PrintF("Unaligned write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
1780 addr, | 1780 addr, |
1781 reinterpret_cast<intptr_t>(instr)); | 1781 reinterpret_cast<intptr_t>(instr)); |
1782 DieOrDebug(); | 1782 DieOrDebug(); |
1783 } | 1783 } |
1784 | 1784 |
1785 | 1785 |
1786 int64_t Simulator::Read2W(int64_t addr, Instruction* instr) { | 1786 int64_t Simulator::Read2W(int64_t addr, Instruction* instr) { |
1787 if (addr >=0 && addr < 0x400) { | 1787 if (addr >=0 && addr < 0x400) { |
1788 // This has to be a NULL-dereference, drop into debugger. | 1788 // This has to be a NULL-dereference, drop into debugger. |
1789 PrintF("Memory read from bad address: 0x%08lx, pc=0x%08lx\n", | 1789 PrintF("Memory read from bad address: 0x%08lx, pc=0x%08lx\n", |
1790 addr, reinterpret_cast<intptr_t>(instr)); | 1790 addr, reinterpret_cast<intptr_t>(instr)); |
1791 DieOrDebug(); | 1791 DieOrDebug(); |
1792 } | 1792 } |
1793 if ((addr & kPointerAlignmentMask) == 0) { | 1793 if ((addr & kPointerAlignmentMask) == 0 || kArchVariant == kMips64r6) { |
1794 int64_t* ptr = reinterpret_cast<int64_t*>(addr); | 1794 int64_t* ptr = reinterpret_cast<int64_t*>(addr); |
1795 TraceMemRd(addr, *ptr); | 1795 TraceMemRd(addr, *ptr); |
1796 return *ptr; | 1796 return *ptr; |
1797 } | 1797 } |
1798 PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1798 PrintF("Unaligned read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
1799 addr, | 1799 addr, |
1800 reinterpret_cast<intptr_t>(instr)); | 1800 reinterpret_cast<intptr_t>(instr)); |
1801 DieOrDebug(); | 1801 DieOrDebug(); |
1802 return 0; | 1802 return 0; |
1803 } | 1803 } |
1804 | 1804 |
1805 | 1805 |
1806 void Simulator::Write2W(int64_t addr, int64_t value, Instruction* instr) { | 1806 void Simulator::Write2W(int64_t addr, int64_t value, Instruction* instr) { |
1807 if (addr >= 0 && addr < 0x400) { | 1807 if (addr >= 0 && addr < 0x400) { |
1808 // This has to be a NULL-dereference, drop into debugger. | 1808 // This has to be a NULL-dereference, drop into debugger. |
1809 PrintF("Memory write to bad address: 0x%08lx, pc=0x%08lx\n", | 1809 PrintF("Memory write to bad address: 0x%08lx, pc=0x%08lx\n", |
1810 addr, reinterpret_cast<intptr_t>(instr)); | 1810 addr, reinterpret_cast<intptr_t>(instr)); |
1811 DieOrDebug(); | 1811 DieOrDebug(); |
1812 } | 1812 } |
1813 if ((addr & kPointerAlignmentMask) == 0) { | 1813 if ((addr & kPointerAlignmentMask) == 0 || kArchVariant == kMips64r6) { |
1814 TraceMemWr(addr, value, DWORD); | 1814 TraceMemWr(addr, value, DWORD); |
1815 int64_t* ptr = reinterpret_cast<int64_t*>(addr); | 1815 int64_t* ptr = reinterpret_cast<int64_t*>(addr); |
1816 *ptr = value; | 1816 *ptr = value; |
1817 return; | 1817 return; |
1818 } | 1818 } |
1819 PrintF("Unaligned write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1819 PrintF("Unaligned write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
1820 addr, | 1820 addr, |
1821 reinterpret_cast<intptr_t>(instr)); | 1821 reinterpret_cast<intptr_t>(instr)); |
1822 DieOrDebug(); | 1822 DieOrDebug(); |
1823 } | 1823 } |
1824 | 1824 |
1825 | 1825 |
1826 double Simulator::ReadD(int64_t addr, Instruction* instr) { | 1826 double Simulator::ReadD(int64_t addr, Instruction* instr) { |
1827 if ((addr & kDoubleAlignmentMask) == 0) { | 1827 if ((addr & kDoubleAlignmentMask) == 0 || kArchVariant == kMips64r6) { |
1828 double* ptr = reinterpret_cast<double*>(addr); | 1828 double* ptr = reinterpret_cast<double*>(addr); |
1829 return *ptr; | 1829 return *ptr; |
1830 } | 1830 } |
1831 PrintF("Unaligned (double) read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1831 PrintF("Unaligned (double) read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
1832 addr, | 1832 addr, |
1833 reinterpret_cast<intptr_t>(instr)); | 1833 reinterpret_cast<intptr_t>(instr)); |
1834 base::OS::Abort(); | 1834 base::OS::Abort(); |
1835 return 0; | 1835 return 0; |
1836 } | 1836 } |
1837 | 1837 |
1838 | 1838 |
1839 void Simulator::WriteD(int64_t addr, double value, Instruction* instr) { | 1839 void Simulator::WriteD(int64_t addr, double value, Instruction* instr) { |
1840 if ((addr & kDoubleAlignmentMask) == 0) { | 1840 if ((addr & kDoubleAlignmentMask) == 0 || kArchVariant == kMips64r6) { |
1841 double* ptr = reinterpret_cast<double*>(addr); | 1841 double* ptr = reinterpret_cast<double*>(addr); |
1842 *ptr = value; | 1842 *ptr = value; |
1843 return; | 1843 return; |
1844 } | 1844 } |
1845 PrintF("Unaligned (double) write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1845 PrintF("Unaligned (double) write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
1846 addr, | 1846 addr, |
1847 reinterpret_cast<intptr_t>(instr)); | 1847 reinterpret_cast<intptr_t>(instr)); |
1848 DieOrDebug(); | 1848 DieOrDebug(); |
1849 } | 1849 } |
1850 | 1850 |
1851 | 1851 |
1852 uint16_t Simulator::ReadHU(int64_t addr, Instruction* instr) { | 1852 uint16_t Simulator::ReadHU(int64_t addr, Instruction* instr) { |
1853 if ((addr & 1) == 0) { | 1853 if ((addr & 1) == 0 || kArchVariant == kMips64r6) { |
1854 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); | 1854 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); |
1855 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1855 TraceMemRd(addr, static_cast<int64_t>(*ptr)); |
1856 return *ptr; | 1856 return *ptr; |
1857 } | 1857 } |
1858 PrintF("Unaligned unsigned halfword read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1858 PrintF("Unaligned unsigned halfword read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
1859 addr, | 1859 addr, |
1860 reinterpret_cast<intptr_t>(instr)); | 1860 reinterpret_cast<intptr_t>(instr)); |
1861 DieOrDebug(); | 1861 DieOrDebug(); |
1862 return 0; | 1862 return 0; |
1863 } | 1863 } |
1864 | 1864 |
1865 | 1865 |
1866 int16_t Simulator::ReadH(int64_t addr, Instruction* instr) { | 1866 int16_t Simulator::ReadH(int64_t addr, Instruction* instr) { |
1867 if ((addr & 1) == 0) { | 1867 if ((addr & 1) == 0 || kArchVariant == kMips64r6) { |
1868 int16_t* ptr = reinterpret_cast<int16_t*>(addr); | 1868 int16_t* ptr = reinterpret_cast<int16_t*>(addr); |
1869 TraceMemRd(addr, static_cast<int64_t>(*ptr)); | 1869 TraceMemRd(addr, static_cast<int64_t>(*ptr)); |
1870 return *ptr; | 1870 return *ptr; |
1871 } | 1871 } |
1872 PrintF("Unaligned signed halfword read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1872 PrintF("Unaligned signed halfword read at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
1873 addr, | 1873 addr, |
1874 reinterpret_cast<intptr_t>(instr)); | 1874 reinterpret_cast<intptr_t>(instr)); |
1875 DieOrDebug(); | 1875 DieOrDebug(); |
1876 return 0; | 1876 return 0; |
1877 } | 1877 } |
1878 | 1878 |
1879 | 1879 |
1880 void Simulator::WriteH(int64_t addr, uint16_t value, Instruction* instr) { | 1880 void Simulator::WriteH(int64_t addr, uint16_t value, Instruction* instr) { |
1881 if ((addr & 1) == 0) { | 1881 if ((addr & 1) == 0 || kArchVariant == kMips64r6) { |
1882 TraceMemWr(addr, value, HALF); | 1882 TraceMemWr(addr, value, HALF); |
1883 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); | 1883 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); |
1884 *ptr = value; | 1884 *ptr = value; |
1885 return; | 1885 return; |
1886 } | 1886 } |
1887 PrintF( | 1887 PrintF( |
1888 "Unaligned unsigned halfword write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1888 "Unaligned unsigned halfword write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
1889 addr, | 1889 addr, |
1890 reinterpret_cast<intptr_t>(instr)); | 1890 reinterpret_cast<intptr_t>(instr)); |
1891 DieOrDebug(); | 1891 DieOrDebug(); |
1892 } | 1892 } |
1893 | 1893 |
1894 | 1894 |
1895 void Simulator::WriteH(int64_t addr, int16_t value, Instruction* instr) { | 1895 void Simulator::WriteH(int64_t addr, int16_t value, Instruction* instr) { |
1896 if ((addr & 1) == 0) { | 1896 if ((addr & 1) == 0 || kArchVariant == kMips64r6) { |
1897 TraceMemWr(addr, value, HALF); | 1897 TraceMemWr(addr, value, HALF); |
1898 int16_t* ptr = reinterpret_cast<int16_t*>(addr); | 1898 int16_t* ptr = reinterpret_cast<int16_t*>(addr); |
1899 *ptr = value; | 1899 *ptr = value; |
1900 return; | 1900 return; |
1901 } | 1901 } |
1902 PrintF("Unaligned halfword write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", | 1902 PrintF("Unaligned halfword write at 0x%08lx, pc=0x%08" V8PRIxPTR "\n", |
1903 addr, | 1903 addr, |
1904 reinterpret_cast<intptr_t>(instr)); | 1904 reinterpret_cast<intptr_t>(instr)); |
1905 DieOrDebug(); | 1905 DieOrDebug(); |
1906 } | 1906 } |
(...skipping 2235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4142 // Used for conditional branch instructions. | 4142 // Used for conditional branch instructions. |
4143 bool execute_branch_delay_instruction = false; | 4143 bool execute_branch_delay_instruction = false; |
4144 | 4144 |
4145 // Used for arithmetic instructions. | 4145 // Used for arithmetic instructions. |
4146 int64_t alu_out = 0; | 4146 int64_t alu_out = 0; |
4147 | 4147 |
4148 // Used for memory instructions. | 4148 // Used for memory instructions. |
4149 int64_t addr = 0x0; | 4149 int64_t addr = 0x0; |
4150 // Alignment for 32-bit integers used in LWL, LWR, etc. | 4150 // Alignment for 32-bit integers used in LWL, LWR, etc. |
4151 const int kInt32AlignmentMask = sizeof(uint32_t) - 1; | 4151 const int kInt32AlignmentMask = sizeof(uint32_t) - 1; |
| 4152 // Alignment for 64-bit integers used in LDL, LDR, etc. |
| 4153 const int kInt64AlignmentMask = sizeof(uint64_t) - 1; |
4152 | 4154 |
4153 // Branch instructions common part. | 4155 // Branch instructions common part. |
4154 auto BranchAndLinkHelper = [this, instr, &next_pc, | 4156 auto BranchAndLinkHelper = [this, instr, &next_pc, |
4155 &execute_branch_delay_instruction]( | 4157 &execute_branch_delay_instruction]( |
4156 bool do_branch) { | 4158 bool do_branch) { |
4157 execute_branch_delay_instruction = true; | 4159 execute_branch_delay_instruction = true; |
4158 int64_t current_pc = get_pc(); | 4160 int64_t current_pc = get_pc(); |
4159 if (do_branch) { | 4161 if (do_branch) { |
4160 int16_t imm16 = instr->Imm16Value(); | 4162 int16_t imm16 = instr->Imm16Value(); |
4161 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; | 4163 next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize; |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4443 break; | 4445 break; |
4444 case LH: | 4446 case LH: |
4445 set_register(rt_reg, ReadH(rs + se_imm16, instr)); | 4447 set_register(rt_reg, ReadH(rs + se_imm16, instr)); |
4446 break; | 4448 break; |
4447 case LWL: { | 4449 case LWL: { |
4448 // al_offset is offset of the effective address within an aligned word. | 4450 // al_offset is offset of the effective address within an aligned word. |
4449 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; | 4451 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; |
4450 uint8_t byte_shift = kInt32AlignmentMask - al_offset; | 4452 uint8_t byte_shift = kInt32AlignmentMask - al_offset; |
4451 uint32_t mask = (1 << byte_shift * 8) - 1; | 4453 uint32_t mask = (1 << byte_shift * 8) - 1; |
4452 addr = rs + se_imm16 - al_offset; | 4454 addr = rs + se_imm16 - al_offset; |
4453 alu_out = ReadW(addr, instr); | 4455 int32_t val = ReadW(addr, instr); |
4454 alu_out <<= byte_shift * 8; | 4456 val <<= byte_shift * 8; |
4455 alu_out |= rt & mask; | 4457 val |= rt & mask; |
4456 set_register(rt_reg, alu_out); | 4458 set_register(rt_reg, static_cast<int64_t>(val)); |
4457 break; | 4459 break; |
4458 } | 4460 } |
4459 case LW: | 4461 case LW: |
4460 set_register(rt_reg, ReadW(rs + se_imm16, instr)); | 4462 set_register(rt_reg, ReadW(rs + se_imm16, instr)); |
4461 break; | 4463 break; |
4462 case LWU: | 4464 case LWU: |
4463 set_register(rt_reg, ReadWU(rs + se_imm16, instr)); | 4465 set_register(rt_reg, ReadWU(rs + se_imm16, instr)); |
4464 break; | 4466 break; |
4465 case LD: | 4467 case LD: |
4466 set_register(rt_reg, Read2W(rs + se_imm16, instr)); | 4468 set_register(rt_reg, Read2W(rs + se_imm16, instr)); |
4467 break; | 4469 break; |
4468 case LBU: | 4470 case LBU: |
4469 set_register(rt_reg, ReadBU(rs + se_imm16)); | 4471 set_register(rt_reg, ReadBU(rs + se_imm16)); |
4470 break; | 4472 break; |
4471 case LHU: | 4473 case LHU: |
4472 set_register(rt_reg, ReadHU(rs + se_imm16, instr)); | 4474 set_register(rt_reg, ReadHU(rs + se_imm16, instr)); |
4473 break; | 4475 break; |
4474 case LWR: { | 4476 case LWR: { |
4475 // al_offset is offset of the effective address within an aligned word. | 4477 // al_offset is offset of the effective address within an aligned word. |
4476 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; | 4478 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; |
4477 uint8_t byte_shift = kInt32AlignmentMask - al_offset; | 4479 uint8_t byte_shift = kInt32AlignmentMask - al_offset; |
4478 uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0; | 4480 uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0; |
4479 addr = rs + se_imm16 - al_offset; | 4481 addr = rs + se_imm16 - al_offset; |
4480 alu_out = ReadW(addr, instr); | 4482 alu_out = ReadW(addr, instr); |
4481 alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8; | 4483 alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8; |
4482 alu_out |= rt & mask; | 4484 alu_out |= rt & mask; |
4483 set_register(rt_reg, alu_out); | 4485 set_register(rt_reg, alu_out); |
4484 break; | 4486 break; |
4485 } | 4487 } |
| 4488 case LDL: { |
| 4489 // al_offset is offset of the effective address within an aligned word. |
| 4490 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; |
| 4491 uint8_t byte_shift = kInt64AlignmentMask - al_offset; |
| 4492 uint64_t mask = (1UL << byte_shift * 8) - 1; |
| 4493 addr = rs + se_imm16 - al_offset; |
| 4494 alu_out = Read2W(addr, instr); |
| 4495 alu_out <<= byte_shift * 8; |
| 4496 alu_out |= rt & mask; |
| 4497 set_register(rt_reg, alu_out); |
| 4498 break; |
| 4499 } |
| 4500 case LDR: { |
| 4501 // al_offset is offset of the effective address within an aligned word. |
| 4502 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; |
| 4503 uint8_t byte_shift = kInt64AlignmentMask - al_offset; |
| 4504 uint64_t mask = al_offset ? (~0UL << (byte_shift + 1) * 8) : 0UL; |
| 4505 addr = rs + se_imm16 - al_offset; |
| 4506 alu_out = Read2W(addr, instr); |
| 4507 alu_out = alu_out >> al_offset * 8; |
| 4508 alu_out |= rt & mask; |
| 4509 set_register(rt_reg, alu_out); |
| 4510 break; |
| 4511 } |
4486 case SB: | 4512 case SB: |
4487 WriteB(rs + se_imm16, static_cast<int8_t>(rt)); | 4513 WriteB(rs + se_imm16, static_cast<int8_t>(rt)); |
4488 break; | 4514 break; |
4489 case SH: | 4515 case SH: |
4490 WriteH(rs + se_imm16, static_cast<uint16_t>(rt), instr); | 4516 WriteH(rs + se_imm16, static_cast<uint16_t>(rt), instr); |
4491 break; | 4517 break; |
4492 case SWL: { | 4518 case SWL: { |
4493 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; | 4519 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; |
4494 uint8_t byte_shift = kInt32AlignmentMask - al_offset; | 4520 uint8_t byte_shift = kInt32AlignmentMask - al_offset; |
4495 uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0; | 4521 uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0; |
(...skipping 11 matching lines...) Expand all Loading... |
4507 break; | 4533 break; |
4508 case SWR: { | 4534 case SWR: { |
4509 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; | 4535 uint8_t al_offset = (rs + se_imm16) & kInt32AlignmentMask; |
4510 uint32_t mask = (1 << al_offset * 8) - 1; | 4536 uint32_t mask = (1 << al_offset * 8) - 1; |
4511 addr = rs + se_imm16 - al_offset; | 4537 addr = rs + se_imm16 - al_offset; |
4512 uint64_t mem_value = ReadW(addr, instr); | 4538 uint64_t mem_value = ReadW(addr, instr); |
4513 mem_value = (rt << al_offset * 8) | (mem_value & mask); | 4539 mem_value = (rt << al_offset * 8) | (mem_value & mask); |
4514 WriteW(addr, static_cast<int32_t>(mem_value), instr); | 4540 WriteW(addr, static_cast<int32_t>(mem_value), instr); |
4515 break; | 4541 break; |
4516 } | 4542 } |
| 4543 case SDL: { |
| 4544 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; |
| 4545 uint8_t byte_shift = kInt64AlignmentMask - al_offset; |
| 4546 uint64_t mask = byte_shift ? (~0UL << (al_offset + 1) * 8) : 0; |
| 4547 addr = rs + se_imm16 - al_offset; |
| 4548 uint64_t mem_value = Read2W(addr, instr) & mask; |
| 4549 mem_value |= rt >> byte_shift * 8; |
| 4550 Write2W(addr, mem_value, instr); |
| 4551 break; |
| 4552 } |
| 4553 case SDR: { |
| 4554 uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask; |
| 4555 uint64_t mask = (1UL << al_offset * 8) - 1; |
| 4556 addr = rs + se_imm16 - al_offset; |
| 4557 uint64_t mem_value = Read2W(addr, instr); |
| 4558 mem_value = (rt << al_offset * 8) | (mem_value & mask); |
| 4559 Write2W(addr, mem_value, instr); |
| 4560 break; |
| 4561 } |
4517 case LWC1: | 4562 case LWC1: |
4518 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits. | 4563 set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits. |
4519 set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr)); | 4564 set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr)); |
4520 break; | 4565 break; |
4521 case LDC1: | 4566 case LDC1: |
4522 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr)); | 4567 set_fpu_register_double(ft_reg, ReadD(rs + se_imm16, instr)); |
4523 break; | 4568 break; |
4524 case SWC1: { | 4569 case SWC1: { |
4525 int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg)); | 4570 int32_t alu_out_32 = static_cast<int32_t>(get_fpu_register(ft_reg)); |
4526 WriteW(rs + se_imm16, alu_out_32, instr); | 4571 WriteW(rs + se_imm16, alu_out_32, instr); |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4876 } | 4921 } |
4877 | 4922 |
4878 | 4923 |
4879 #undef UNSUPPORTED | 4924 #undef UNSUPPORTED |
4880 } // namespace internal | 4925 } // namespace internal |
4881 } // namespace v8 | 4926 } // namespace v8 |
4882 | 4927 |
4883 #endif // USE_SIMULATOR | 4928 #endif // USE_SIMULATOR |
4884 | 4929 |
4885 #endif // V8_TARGET_ARCH_MIPS64 | 4930 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |