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 <math.h> // for isnan. | 5 #include <math.h> // for isnan. |
6 #include <setjmp.h> | 6 #include <setjmp.h> |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 | 8 |
9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
10 #if defined(TARGET_ARCH_ARM64) | 10 #if defined(TARGET_ARCH_ARM64) |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 "r28", "r29", "r30", | 124 "r28", "r29", "r30", |
125 | 125 |
126 "ip0", "ip1", "pp", "ctx", "fp", "lr", "sp", "zr", | 126 "ip0", "ip1", "pp", "ctx", "fp", "lr", "sp", "zr", |
127 }; | 127 }; |
128 static const Register kRegisters[] = { | 128 static const Register kRegisters[] = { |
129 R0, R1, R2, R3, R4, R5, R6, R7, | 129 R0, R1, R2, R3, R4, R5, R6, R7, |
130 R8, R9, R10, R11, R12, R13, R14, R15, | 130 R8, R9, R10, R11, R12, R13, R14, R15, |
131 R16, R17, R18, R19, R20, R21, R22, R23, | 131 R16, R17, R18, R19, R20, R21, R22, R23, |
132 R24, R25, R26, R27, R28, R29, R30, | 132 R24, R25, R26, R27, R28, R29, R30, |
133 | 133 |
134 IP0, IP1, PP, CTX, FP, LR, SP, ZR, | 134 IP0, IP1, PP, CTX, FP, LR, R31, ZR, |
135 }; | 135 }; |
136 ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters)); | 136 ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters)); |
137 for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) { | 137 for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) { |
138 if (strcmp(kNames[i], name) == 0) { | 138 if (strcmp(kNames[i], name) == 0) { |
139 return kRegisters[i]; | 139 return kRegisters[i]; |
140 } | 140 } |
141 } | 141 } |
142 return kNoRegister; | 142 return kNoRegister; |
143 } | 143 } |
144 | 144 |
145 | 145 |
146 bool SimulatorDebugger::GetValue(char* desc, int64_t* value) { | 146 bool SimulatorDebugger::GetValue(char* desc, int64_t* value) { |
147 Register reg = LookupCpuRegisterByName(desc); | 147 Register reg = LookupCpuRegisterByName(desc); |
148 if (reg != kNoRegister) { | 148 if (reg != kNoRegister) { |
| 149 if (reg == ZR) { |
| 150 *value = 0; |
| 151 return true; |
| 152 } |
149 *value = sim_->get_register(reg); | 153 *value = sim_->get_register(reg); |
150 return true; | 154 return true; |
151 } | 155 } |
152 if (desc[0] == '*') { | 156 if (desc[0] == '*') { |
153 int64_t addr; | 157 int64_t addr; |
154 if (GetValue(desc + 1, &addr)) { | 158 if (GetValue(desc + 1, &addr)) { |
155 if (Simulator::IsIllegalAddress(addr)) { | 159 if (Simulator::IsIllegalAddress(addr)) { |
156 return false; | 160 return false; |
157 } | 161 } |
158 *value = *(reinterpret_cast<int64_t*>(addr)); | 162 *value = *(reinterpret_cast<int64_t*>(addr)); |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 dbg.Stop(instr, buffer); | 589 dbg.Stop(instr, buffer); |
586 // The debugger will return control in non-interactive mode. | 590 // The debugger will return control in non-interactive mode. |
587 FATAL("Cannot continue execution after illegal memory access."); | 591 FATAL("Cannot continue execution after illegal memory access."); |
588 } | 592 } |
589 | 593 |
590 | 594 |
591 // The ARMv8 manual advises that an unaligned access may generate a fault, | 595 // The ARMv8 manual advises that an unaligned access may generate a fault, |
592 // and if not, will likely take a number of additional cycles to execute, | 596 // and if not, will likely take a number of additional cycles to execute, |
593 // so let's just not generate any. | 597 // so let's just not generate any. |
594 void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) { | 598 void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) { |
595 char buffer[64]; | 599 char buffer[128]; |
596 snprintf(buffer, sizeof(buffer), | 600 snprintf(buffer, sizeof(buffer), |
597 "unaligned %s at 0x%" Px ", pc=%p\n", msg, addr, instr); | 601 "unaligned %s at 0x%" Px ", pc=%p\n", msg, addr, instr); |
598 SimulatorDebugger dbg(this); | 602 SimulatorDebugger dbg(this); |
599 dbg.Stop(instr, buffer); | 603 dbg.Stop(instr, buffer); |
600 // The debugger will not be able to single step past this instruction, but | 604 // The debugger will not be able to single step past this instruction, but |
601 // it will be possible to disassemble the code and inspect registers. | 605 // it will be possible to disassemble the code and inspect registers. |
602 FATAL("Cannot continue execution after unaligned access."); | 606 FATAL("Cannot continue execution after unaligned access."); |
603 } | 607 } |
604 | 608 |
605 | 609 |
606 void Simulator::UnimplementedInstruction(Instr* instr) { | 610 void Simulator::UnimplementedInstruction(Instr* instr) { |
607 char buffer[64]; | 611 char buffer[128]; |
608 snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr); | 612 snprintf(buffer, sizeof(buffer), |
| 613 "Unimplemented instruction: at %p, last_pc=0x%"Px"\n", |
| 614 instr, get_last_pc()); |
609 SimulatorDebugger dbg(this); | 615 SimulatorDebugger dbg(this); |
610 dbg.Stop(instr, buffer); | 616 dbg.Stop(instr, buffer); |
611 FATAL("Cannot continue execution after unimplemented instruction."); | 617 FATAL("Cannot continue execution after unimplemented instruction."); |
612 } | 618 } |
613 | 619 |
614 | 620 |
615 // Returns the top of the stack area to enable checking for stack pointer | 621 // Returns the top of the stack area to enable checking for stack pointer |
616 // validity. | 622 // validity. |
617 uword Simulator::StackTop() const { | 623 uword Simulator::StackTop() const { |
618 // To be safe in potential stack underflows we leave some buffer above and | 624 // To be safe in potential stack underflows we leave some buffer above and |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1003 } else { | 1009 } else { |
1004 // Format(instr, "cbnz'sf 'rt, 'dest19"); | 1010 // Format(instr, "cbnz'sf 'rt, 'dest19"); |
1005 if (rt_val != 0) { | 1011 if (rt_val != 0) { |
1006 set_pc(dest); | 1012 set_pc(dest); |
1007 } | 1013 } |
1008 } | 1014 } |
1009 } | 1015 } |
1010 | 1016 |
1011 | 1017 |
1012 bool Simulator::ConditionallyExecute(Instr* instr) { | 1018 bool Simulator::ConditionallyExecute(Instr* instr) { |
1013 switch (instr->ConditionField()) { | 1019 Condition cond; |
| 1020 if (instr->IsConditionalSelectOp()) { |
| 1021 cond = instr->SelectConditionField(); |
| 1022 } else { |
| 1023 cond = instr->ConditionField(); |
| 1024 } |
| 1025 switch (cond) { |
1014 case EQ: return z_flag_; | 1026 case EQ: return z_flag_; |
1015 case NE: return !z_flag_; | 1027 case NE: return !z_flag_; |
1016 case CS: return c_flag_; | 1028 case CS: return c_flag_; |
1017 case CC: return !c_flag_; | 1029 case CC: return !c_flag_; |
1018 case MI: return n_flag_; | 1030 case MI: return n_flag_; |
1019 case PL: return !n_flag_; | 1031 case PL: return !n_flag_; |
1020 case VS: return v_flag_; | 1032 case VS: return v_flag_; |
1021 case VC: return !v_flag_; | 1033 case VC: return !v_flag_; |
1022 case HI: return c_flag_ && !z_flag_; | 1034 case HI: return c_flag_ && !z_flag_; |
1023 case LS: return !c_flag_ || z_flag_; | 1035 case LS: return !c_flag_ || z_flag_; |
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1811 const int32_t ra_val = get_wregister(ra, R31IsZR); | 1823 const int32_t ra_val = get_wregister(ra, R31IsZR); |
1812 const int32_t alu_out = ra_val + (rn_val * rm_val); | 1824 const int32_t alu_out = ra_val + (rn_val * rm_val); |
1813 set_wregister(rd, alu_out, R31IsZR); | 1825 set_wregister(rd, alu_out, R31IsZR); |
1814 } | 1826 } |
1815 } else { | 1827 } else { |
1816 UnimplementedInstruction(instr); | 1828 UnimplementedInstruction(instr); |
1817 } | 1829 } |
1818 } | 1830 } |
1819 | 1831 |
1820 | 1832 |
| 1833 void Simulator::DecodeConditionalSelect(Instr* instr) { |
| 1834 if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 0)) { |
| 1835 // Format(instr, "mov'sf'cond 'rd, 'rn, 'rm"); |
| 1836 const Register rd = instr->RdField(); |
| 1837 const Register rn = instr->RnField(); |
| 1838 const Register rm = instr->RmField(); |
| 1839 if (instr->SFField() == 1) { |
| 1840 int64_t res = 0; |
| 1841 if (ConditionallyExecute(instr)) { |
| 1842 res = get_register(rn, instr->RnMode()); |
| 1843 } else { |
| 1844 res = get_register(rm, R31IsZR); |
| 1845 } |
| 1846 set_register(rd, res, instr->RdMode()); |
| 1847 } else { |
| 1848 int32_t res = 0; |
| 1849 if (ConditionallyExecute(instr)) { |
| 1850 res = get_wregister(rn, instr->RnMode()); |
| 1851 } else { |
| 1852 res = get_wregister(rm, R31IsZR); |
| 1853 } |
| 1854 set_wregister(rd, res, instr->RdMode()); |
| 1855 } |
| 1856 |
| 1857 } else { |
| 1858 UnimplementedInstruction(instr); |
| 1859 } |
| 1860 } |
| 1861 |
| 1862 |
1821 void Simulator::DecodeDPRegister(Instr* instr) { | 1863 void Simulator::DecodeDPRegister(Instr* instr) { |
1822 if (instr->IsAddSubShiftExtOp()) { | 1864 if (instr->IsAddSubShiftExtOp()) { |
1823 DecodeAddSubShiftExt(instr); | 1865 DecodeAddSubShiftExt(instr); |
1824 } else if (instr->IsLogicalShiftOp()) { | 1866 } else if (instr->IsLogicalShiftOp()) { |
1825 DecodeLogicalShift(instr); | 1867 DecodeLogicalShift(instr); |
1826 } else if (instr->IsMiscDP2SourceOp()) { | 1868 } else if (instr->IsMiscDP2SourceOp()) { |
1827 DecodeMiscDP2Source(instr); | 1869 DecodeMiscDP2Source(instr); |
1828 } else if (instr->IsMiscDP3SourceOp()) { | 1870 } else if (instr->IsMiscDP3SourceOp()) { |
1829 DecodeMiscDP3Source(instr); | 1871 DecodeMiscDP3Source(instr); |
| 1872 } else if (instr->IsConditionalSelectOp()) { |
| 1873 DecodeConditionalSelect(instr); |
1830 } else { | 1874 } else { |
1831 UnimplementedInstruction(instr); | 1875 UnimplementedInstruction(instr); |
1832 } | 1876 } |
1833 } | 1877 } |
1834 | 1878 |
1835 | 1879 |
1836 void Simulator::DecodeDPSimd1(Instr* instr) { | 1880 void Simulator::DecodeDPSimd1(Instr* instr) { |
1837 UnimplementedInstruction(instr); | 1881 UnimplementedInstruction(instr); |
1838 } | 1882 } |
1839 | 1883 |
(...skipping 15 matching lines...) Expand all Loading... |
1855 if (instr->IsDPImmediateOp()) { | 1899 if (instr->IsDPImmediateOp()) { |
1856 DecodeDPImmediate(instr); | 1900 DecodeDPImmediate(instr); |
1857 } else if (instr->IsCompareBranchOp()) { | 1901 } else if (instr->IsCompareBranchOp()) { |
1858 DecodeCompareBranch(instr); | 1902 DecodeCompareBranch(instr); |
1859 } else if (instr->IsLoadStoreOp()) { | 1903 } else if (instr->IsLoadStoreOp()) { |
1860 DecodeLoadStore(instr); | 1904 DecodeLoadStore(instr); |
1861 } else if (instr->IsDPRegisterOp()) { | 1905 } else if (instr->IsDPRegisterOp()) { |
1862 DecodeDPRegister(instr); | 1906 DecodeDPRegister(instr); |
1863 } else if (instr->IsDPSimd1Op()) { | 1907 } else if (instr->IsDPSimd1Op()) { |
1864 DecodeDPSimd1(instr); | 1908 DecodeDPSimd1(instr); |
| 1909 } else if (instr->IsDPSimd2Op()) { |
| 1910 DecodeDPSimd2(instr); |
1865 } else { | 1911 } else { |
1866 ASSERT(instr->IsDPSimd2Op()); | 1912 UnimplementedInstruction(instr); |
1867 DecodeDPSimd2(instr); | |
1868 } | 1913 } |
1869 | 1914 |
1870 if (!pc_modified_) { | 1915 if (!pc_modified_) { |
1871 set_pc(reinterpret_cast<int64_t>(instr) + Instr::kInstrSize); | 1916 set_pc(reinterpret_cast<int64_t>(instr) + Instr::kInstrSize); |
1872 } | 1917 } |
1873 } | 1918 } |
1874 | 1919 |
1875 | 1920 |
1876 void Simulator::Execute() { | 1921 void Simulator::Execute() { |
1877 // Get the PC to simulate. Cannot use the accessor here as we need the | 1922 // Get the PC to simulate. Cannot use the accessor here as we need the |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2002 int64_t return_value; | 2047 int64_t return_value; |
2003 return_value = get_register(R0); | 2048 return_value = get_register(R0); |
2004 return return_value; | 2049 return return_value; |
2005 } | 2050 } |
2006 | 2051 |
2007 } // namespace dart | 2052 } // namespace dart |
2008 | 2053 |
2009 #endif // !defined(HOST_ARCH_ARM64) | 2054 #endif // !defined(HOST_ARCH_ARM64) |
2010 | 2055 |
2011 #endif // defined TARGET_ARCH_ARM64 | 2056 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |