| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include <setjmp.h> | 5 #include <setjmp.h> |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 | 7 |
| 8 #include "vm/globals.h" | 8 #include "vm/globals.h" |
| 9 #if defined(TARGET_ARCH_ARM64) | 9 #if defined(TARGET_ARCH_ARM64) |
| 10 | 10 |
| (...skipping 1706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1717 } | 1717 } |
| 1718 } | 1718 } |
| 1719 | 1719 |
| 1720 // Do writeback. | 1720 // Do writeback. |
| 1721 if (wb) { | 1721 if (wb) { |
| 1722 set_register(instr, rn, wb_address, R31IsSP); | 1722 set_register(instr, rn, wb_address, R31IsSP); |
| 1723 } | 1723 } |
| 1724 } | 1724 } |
| 1725 | 1725 |
| 1726 | 1726 |
| 1727 void Simulator::DecodeLoadStoreRegPair(Instr* instr) { |
| 1728 const int32_t opc = instr->Bits(23, 3); |
| 1729 const Register rn = instr->RnField(); |
| 1730 const Register rt = instr->RtField(); |
| 1731 const Register rt2 = instr->Rt2Field(); |
| 1732 const int64_t rn_val = get_register(rn, R31IsSP); |
| 1733 const intptr_t shift = 2 + instr->SFField(); |
| 1734 const intptr_t size = 1 << shift; |
| 1735 const int32_t offset = (instr->SImm7Field() << shift); |
| 1736 uword address = 0; |
| 1737 uword wb_address = 0; |
| 1738 bool wb = false; |
| 1739 |
| 1740 if ((instr->Bits(30, 2) == 3) || (instr->Bit(26) != 0)) { |
| 1741 UnimplementedInstruction(instr); |
| 1742 return; |
| 1743 } |
| 1744 |
| 1745 // Calculate address. |
| 1746 switch (opc) { |
| 1747 case 1: |
| 1748 address = rn_val; |
| 1749 wb_address = rn_val + offset; |
| 1750 wb = true; |
| 1751 break; |
| 1752 case 2: |
| 1753 address = rn_val + offset; |
| 1754 break; |
| 1755 case 3: |
| 1756 address = rn_val + offset; |
| 1757 wb_address = address; |
| 1758 wb = true; |
| 1759 break; |
| 1760 default: |
| 1761 UnimplementedInstruction(instr); |
| 1762 return; |
| 1763 } |
| 1764 |
| 1765 // Check the address. |
| 1766 if (IsIllegalAddress(address)) { |
| 1767 HandleIllegalAccess(address, instr); |
| 1768 return; |
| 1769 } |
| 1770 |
| 1771 // Do access. |
| 1772 if (instr->Bit(22)) { |
| 1773 // Format(instr, "ldp'sf 'rt, 'ra, 'memop"); |
| 1774 const bool signd = instr->Bit(30) == 1; |
| 1775 int64_t val1 = 0; // Sign extend into an int64_t. |
| 1776 int64_t val2 = 0; |
| 1777 if (instr->Bit(31) == 1) { |
| 1778 // 64-bit read. |
| 1779 val1 = ReadX(address, instr); |
| 1780 val2 = ReadX(address + size, instr); |
| 1781 } else { |
| 1782 if (signd) { |
| 1783 val1 = static_cast<int64_t>(ReadW(address, instr)); |
| 1784 val2 = static_cast<int64_t>(ReadW(address + size, instr)); |
| 1785 } else { |
| 1786 val1 = static_cast<int64_t>(ReadWU(address, instr)); |
| 1787 val2 = static_cast<int64_t>(ReadWU(address + size, instr)); |
| 1788 } |
| 1789 } |
| 1790 |
| 1791 // Write to register. |
| 1792 if (instr->Bit(31) == 1) { |
| 1793 set_register(instr, rt, val1, R31IsZR); |
| 1794 set_register(instr, rt2, val2, R31IsZR); |
| 1795 } else { |
| 1796 set_wregister(rt, static_cast<int32_t>(val1), R31IsZR); |
| 1797 set_wregister(rt2, static_cast<int32_t>(val2), R31IsZR); |
| 1798 } |
| 1799 } else { |
| 1800 // Format(instr, "stp'sf 'rt, 'ra, 'memop"); |
| 1801 if (instr->Bit(31) == 1) { |
| 1802 const int64_t val1 = get_register(rt, R31IsZR); |
| 1803 const int64_t val2 = get_register(rt2, R31IsZR); |
| 1804 WriteX(address, val1, instr); |
| 1805 WriteX(address + size, val2, instr); |
| 1806 } else { |
| 1807 const int32_t val1 = get_wregister(rt, R31IsZR); |
| 1808 const int32_t val2 = get_wregister(rt2, R31IsZR); |
| 1809 WriteW(address, val1, instr); |
| 1810 WriteW(address + size, val2, instr); |
| 1811 } |
| 1812 } |
| 1813 |
| 1814 // Do writeback. |
| 1815 if (wb) { |
| 1816 set_register(instr, rn, wb_address, R31IsSP); |
| 1817 } |
| 1818 } |
| 1819 |
| 1820 |
| 1727 void Simulator::DecodeLoadRegLiteral(Instr* instr) { | 1821 void Simulator::DecodeLoadRegLiteral(Instr* instr) { |
| 1728 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || | 1822 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || |
| 1729 (instr->Bits(24, 3) != 0)) { | 1823 (instr->Bits(24, 3) != 0)) { |
| 1730 UnimplementedInstruction(instr); | 1824 UnimplementedInstruction(instr); |
| 1731 } | 1825 } |
| 1732 | 1826 |
| 1733 const Register rt = instr->RtField(); | 1827 const Register rt = instr->RtField(); |
| 1734 const int64_t off = instr->SImm19Field() << 2; | 1828 const int64_t off = instr->SImm19Field() << 2; |
| 1735 const int64_t pc = reinterpret_cast<int64_t>(instr); | 1829 const int64_t pc = reinterpret_cast<int64_t>(instr); |
| 1736 const int64_t address = pc + off; | 1830 const int64_t address = pc + off; |
| 1737 const int64_t val = ReadX(address, instr); | 1831 const int64_t val = ReadX(address, instr); |
| 1738 if (instr->Bit(30)) { | 1832 if (instr->Bit(30)) { |
| 1739 // Format(instr, "ldrx 'rt, 'pcldr"); | 1833 // Format(instr, "ldrx 'rt, 'pcldr"); |
| 1740 set_register(instr, rt, val, R31IsZR); | 1834 set_register(instr, rt, val, R31IsZR); |
| 1741 } else { | 1835 } else { |
| 1742 // Format(instr, "ldrw 'rt, 'pcldr"); | 1836 // Format(instr, "ldrw 'rt, 'pcldr"); |
| 1743 set_wregister(rt, static_cast<int32_t>(val), R31IsZR); | 1837 set_wregister(rt, static_cast<int32_t>(val), R31IsZR); |
| 1744 } | 1838 } |
| 1745 } | 1839 } |
| 1746 | 1840 |
| 1747 | 1841 |
| 1748 void Simulator::DecodeLoadStore(Instr* instr) { | 1842 void Simulator::DecodeLoadStore(Instr* instr) { |
| 1749 if (instr->IsLoadStoreRegOp()) { | 1843 if (instr->IsLoadStoreRegOp()) { |
| 1750 DecodeLoadStoreReg(instr); | 1844 DecodeLoadStoreReg(instr); |
| 1845 } else if (instr->IsLoadStoreRegPairOp()) { |
| 1846 DecodeLoadStoreRegPair(instr); |
| 1751 } else if (instr->IsLoadRegLiteralOp()) { | 1847 } else if (instr->IsLoadRegLiteralOp()) { |
| 1752 DecodeLoadRegLiteral(instr); | 1848 DecodeLoadRegLiteral(instr); |
| 1753 } else { | 1849 } else { |
| 1754 UnimplementedInstruction(instr); | 1850 UnimplementedInstruction(instr); |
| 1755 } | 1851 } |
| 1756 } | 1852 } |
| 1757 | 1853 |
| 1758 | 1854 |
| 1759 int64_t Simulator::ShiftOperand(uint8_t reg_size, | 1855 int64_t Simulator::ShiftOperand(uint8_t reg_size, |
| 1760 int64_t value, | 1856 int64_t value, |
| (...skipping 1296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3057 set_register(NULL, kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); | 3153 set_register(NULL, kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); |
| 3058 set_register(NULL, kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); | 3154 set_register(NULL, kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); |
| 3059 buf->Longjmp(); | 3155 buf->Longjmp(); |
| 3060 } | 3156 } |
| 3061 | 3157 |
| 3062 } // namespace dart | 3158 } // namespace dart |
| 3063 | 3159 |
| 3064 #endif // !defined(HOST_ARCH_ARM64) | 3160 #endif // !defined(HOST_ARCH_ARM64) |
| 3065 | 3161 |
| 3066 #endif // defined TARGET_ARCH_ARM64 | 3162 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |