OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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> // NOLINT | 5 #include <setjmp.h> // NOLINT |
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_ARM) | 9 #if defined(TARGET_ARCH_ARM) |
10 | 10 |
11 // Only build the simulator if not compiling for real ARM hardware. | 11 // Only build the simulator if not compiling for real ARM hardware. |
12 #if defined(USING_SIMULATOR) | 12 #if defined(USING_SIMULATOR) |
13 | 13 |
14 #include "vm/simulator.h" | 14 #include "vm/simulator.h" |
15 | 15 |
16 #include "vm/assembler.h" | 16 #include "vm/assembler.h" |
17 #include "vm/constants_arm.h" | 17 #include "vm/constants_arm.h" |
18 #include "vm/cpu.h" | 18 #include "vm/cpu.h" |
19 #include "vm/disassembler.h" | 19 #include "vm/disassembler.h" |
20 #include "vm/lockers.h" | 20 #include "vm/lockers.h" |
21 #include "vm/native_arguments.h" | 21 #include "vm/native_arguments.h" |
| 22 #include "vm/os_thread.h" |
22 #include "vm/stack_frame.h" | 23 #include "vm/stack_frame.h" |
23 #include "vm/os_thread.h" | |
24 | 24 |
25 namespace dart { | 25 namespace dart { |
26 | 26 |
27 DEFINE_FLAG(uint64_t, | 27 DEFINE_FLAG(uint64_t, |
28 trace_sim_after, | 28 trace_sim_after, |
29 ULLONG_MAX, | 29 ULLONG_MAX, |
30 "Trace simulator execution after instruction count reached."); | 30 "Trace simulator execution after instruction count reached."); |
31 DEFINE_FLAG(uint64_t, | 31 DEFINE_FLAG(uint64_t, |
32 stop_sim_at, | 32 stop_sim_at, |
33 ULLONG_MAX, | 33 ULLONG_MAX, |
34 "Instruction address or instruction count to stop simulator at."); | 34 "Instruction address or instruction count to stop simulator at."); |
35 | 35 |
36 | |
37 // This macro provides a platform independent use of sscanf. The reason for | 36 // This macro provides a platform independent use of sscanf. The reason for |
38 // SScanF not being implemented in a platform independent way through | 37 // SScanF not being implemented in a platform independent way through |
39 // OS in the same way as SNPrint is that the Windows C Run-Time | 38 // OS in the same way as SNPrint is that the Windows C Run-Time |
40 // Library does not provide vsscanf. | 39 // Library does not provide vsscanf. |
41 #define SScanF sscanf // NOLINT | 40 #define SScanF sscanf // NOLINT |
42 | 41 |
43 | |
44 // SimulatorSetjmpBuffer are linked together, and the last created one | 42 // SimulatorSetjmpBuffer are linked together, and the last created one |
45 // is referenced by the Simulator. When an exception is thrown, the exception | 43 // is referenced by the Simulator. When an exception is thrown, the exception |
46 // runtime looks at where to jump and finds the corresponding | 44 // runtime looks at where to jump and finds the corresponding |
47 // SimulatorSetjmpBuffer based on the stack pointer of the exception handler. | 45 // SimulatorSetjmpBuffer based on the stack pointer of the exception handler. |
48 // The runtime then does a Longjmp on that buffer to return to the simulator. | 46 // The runtime then does a Longjmp on that buffer to return to the simulator. |
49 class SimulatorSetjmpBuffer { | 47 class SimulatorSetjmpBuffer { |
50 public: | 48 public: |
51 void Longjmp() { | 49 void Longjmp() { |
52 // "This" is now the last setjmp buffer. | 50 // "This" is now the last setjmp buffer. |
53 simulator_->set_last_setjmp_buffer(this); | 51 simulator_->set_last_setjmp_buffer(this); |
(...skipping 18 matching lines...) Expand all Loading... |
72 | 70 |
73 private: | 71 private: |
74 uword sp_; | 72 uword sp_; |
75 Simulator* simulator_; | 73 Simulator* simulator_; |
76 SimulatorSetjmpBuffer* link_; | 74 SimulatorSetjmpBuffer* link_; |
77 jmp_buf buffer_; | 75 jmp_buf buffer_; |
78 | 76 |
79 friend class Simulator; | 77 friend class Simulator; |
80 }; | 78 }; |
81 | 79 |
82 | |
83 // The SimulatorDebugger class is used by the simulator while debugging | 80 // The SimulatorDebugger class is used by the simulator while debugging |
84 // simulated ARM code. | 81 // simulated ARM code. |
85 class SimulatorDebugger { | 82 class SimulatorDebugger { |
86 public: | 83 public: |
87 explicit SimulatorDebugger(Simulator* sim); | 84 explicit SimulatorDebugger(Simulator* sim); |
88 ~SimulatorDebugger(); | 85 ~SimulatorDebugger(); |
89 | 86 |
90 void Stop(Instr* instr, const char* message); | 87 void Stop(Instr* instr, const char* message); |
91 void Debug(); | 88 void Debug(); |
92 char* ReadLine(const char* prompt); | 89 char* ReadLine(const char* prompt); |
(...skipping 19 matching lines...) Expand all Loading... |
112 // Set or delete a breakpoint. Returns true if successful. | 109 // Set or delete a breakpoint. Returns true if successful. |
113 bool SetBreakpoint(Instr* breakpc); | 110 bool SetBreakpoint(Instr* breakpc); |
114 bool DeleteBreakpoint(Instr* breakpc); | 111 bool DeleteBreakpoint(Instr* breakpc); |
115 | 112 |
116 // Undo and redo all breakpoints. This is needed to bracket disassembly and | 113 // Undo and redo all breakpoints. This is needed to bracket disassembly and |
117 // execution to skip past breakpoints when run from the debugger. | 114 // execution to skip past breakpoints when run from the debugger. |
118 void UndoBreakpoints(); | 115 void UndoBreakpoints(); |
119 void RedoBreakpoints(); | 116 void RedoBreakpoints(); |
120 }; | 117 }; |
121 | 118 |
122 | |
123 SimulatorDebugger::SimulatorDebugger(Simulator* sim) { | 119 SimulatorDebugger::SimulatorDebugger(Simulator* sim) { |
124 sim_ = sim; | 120 sim_ = sim; |
125 } | 121 } |
126 | 122 |
127 | |
128 SimulatorDebugger::~SimulatorDebugger() {} | 123 SimulatorDebugger::~SimulatorDebugger() {} |
129 | 124 |
130 | |
131 void SimulatorDebugger::Stop(Instr* instr, const char* message) { | 125 void SimulatorDebugger::Stop(Instr* instr, const char* message) { |
132 OS::Print("Simulator hit %s\n", message); | 126 OS::Print("Simulator hit %s\n", message); |
133 Debug(); | 127 Debug(); |
134 } | 128 } |
135 | 129 |
136 | |
137 static Register LookupCpuRegisterByName(const char* name) { | 130 static Register LookupCpuRegisterByName(const char* name) { |
138 static const char* kNames[] = {"r0", "r1", "r2", "r3", "r4", "r5", | 131 static const char* kNames[] = {"r0", "r1", "r2", "r3", "r4", "r5", |
139 "r6", "r7", "r8", "r9", "r10", "r11", | 132 "r6", "r7", "r8", "r9", "r10", "r11", |
140 "r12", "r13", "r14", "r15", "pc", "lr", | 133 "r12", "r13", "r14", "r15", "pc", "lr", |
141 "sp", "ip", "fp", "pp", "ctx"}; | 134 "sp", "ip", "fp", "pp", "ctx"}; |
142 static const Register kRegisters[] = {R0, R1, R2, R3, R4, R5, R6, R7, | 135 static const Register kRegisters[] = {R0, R1, R2, R3, R4, R5, R6, R7, |
143 R8, R9, R10, R11, R12, R13, R14, R15, | 136 R8, R9, R10, R11, R12, R13, R14, R15, |
144 PC, LR, SP, IP, FP, PP, CTX}; | 137 PC, LR, SP, IP, FP, PP, CTX}; |
145 ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters)); | 138 ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters)); |
146 for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) { | 139 for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) { |
147 if (strcmp(kNames[i], name) == 0) { | 140 if (strcmp(kNames[i], name) == 0) { |
148 return kRegisters[i]; | 141 return kRegisters[i]; |
149 } | 142 } |
150 } | 143 } |
151 return kNoRegister; | 144 return kNoRegister; |
152 } | 145 } |
153 | 146 |
154 | |
155 static SRegister LookupSRegisterByName(const char* name) { | 147 static SRegister LookupSRegisterByName(const char* name) { |
156 int reg_nr = -1; | 148 int reg_nr = -1; |
157 bool ok = SScanF(name, "s%d", ®_nr); | 149 bool ok = SScanF(name, "s%d", ®_nr); |
158 if (ok && (0 <= reg_nr) && (reg_nr < kNumberOfSRegisters)) { | 150 if (ok && (0 <= reg_nr) && (reg_nr < kNumberOfSRegisters)) { |
159 return static_cast<SRegister>(reg_nr); | 151 return static_cast<SRegister>(reg_nr); |
160 } | 152 } |
161 return kNoSRegister; | 153 return kNoSRegister; |
162 } | 154 } |
163 | 155 |
164 | |
165 static DRegister LookupDRegisterByName(const char* name) { | 156 static DRegister LookupDRegisterByName(const char* name) { |
166 int reg_nr = -1; | 157 int reg_nr = -1; |
167 bool ok = SScanF(name, "d%d", ®_nr); | 158 bool ok = SScanF(name, "d%d", ®_nr); |
168 if (ok && (0 <= reg_nr) && (reg_nr < kNumberOfDRegisters)) { | 159 if (ok && (0 <= reg_nr) && (reg_nr < kNumberOfDRegisters)) { |
169 return static_cast<DRegister>(reg_nr); | 160 return static_cast<DRegister>(reg_nr); |
170 } | 161 } |
171 return kNoDRegister; | 162 return kNoDRegister; |
172 } | 163 } |
173 | 164 |
174 | |
175 bool SimulatorDebugger::GetValue(char* desc, uint32_t* value) { | 165 bool SimulatorDebugger::GetValue(char* desc, uint32_t* value) { |
176 Register reg = LookupCpuRegisterByName(desc); | 166 Register reg = LookupCpuRegisterByName(desc); |
177 if (reg != kNoRegister) { | 167 if (reg != kNoRegister) { |
178 if (reg == PC) { | 168 if (reg == PC) { |
179 *value = sim_->get_pc(); | 169 *value = sim_->get_pc(); |
180 } else { | 170 } else { |
181 *value = sim_->get_register(reg); | 171 *value = sim_->get_register(reg); |
182 } | 172 } |
183 return true; | 173 return true; |
184 } | 174 } |
185 if (desc[0] == '*') { | 175 if (desc[0] == '*') { |
186 uint32_t addr; | 176 uint32_t addr; |
187 if (GetValue(desc + 1, &addr)) { | 177 if (GetValue(desc + 1, &addr)) { |
188 if (Simulator::IsIllegalAddress(addr)) { | 178 if (Simulator::IsIllegalAddress(addr)) { |
189 return false; | 179 return false; |
190 } | 180 } |
191 *value = *(reinterpret_cast<uint32_t*>(addr)); | 181 *value = *(reinterpret_cast<uint32_t*>(addr)); |
192 return true; | 182 return true; |
193 } | 183 } |
194 } | 184 } |
195 bool retval = SScanF(desc, "0x%x", value) == 1; | 185 bool retval = SScanF(desc, "0x%x", value) == 1; |
196 if (!retval) { | 186 if (!retval) { |
197 retval = SScanF(desc, "%x", value) == 1; | 187 retval = SScanF(desc, "%x", value) == 1; |
198 } | 188 } |
199 return retval; | 189 return retval; |
200 } | 190 } |
201 | 191 |
202 | |
203 bool SimulatorDebugger::GetFValue(char* desc, float* value) { | 192 bool SimulatorDebugger::GetFValue(char* desc, float* value) { |
204 SRegister sreg = LookupSRegisterByName(desc); | 193 SRegister sreg = LookupSRegisterByName(desc); |
205 if (sreg != kNoSRegister) { | 194 if (sreg != kNoSRegister) { |
206 *value = sim_->get_sregister(sreg); | 195 *value = sim_->get_sregister(sreg); |
207 return true; | 196 return true; |
208 } | 197 } |
209 if (desc[0] == '*') { | 198 if (desc[0] == '*') { |
210 uint32_t addr; | 199 uint32_t addr; |
211 if (GetValue(desc + 1, &addr)) { | 200 if (GetValue(desc + 1, &addr)) { |
212 if (Simulator::IsIllegalAddress(addr)) { | 201 if (Simulator::IsIllegalAddress(addr)) { |
213 return false; | 202 return false; |
214 } | 203 } |
215 *value = *(reinterpret_cast<float*>(addr)); | 204 *value = *(reinterpret_cast<float*>(addr)); |
216 return true; | 205 return true; |
217 } | 206 } |
218 } | 207 } |
219 return false; | 208 return false; |
220 } | 209 } |
221 | 210 |
222 | |
223 bool SimulatorDebugger::GetDValue(char* desc, double* value) { | 211 bool SimulatorDebugger::GetDValue(char* desc, double* value) { |
224 DRegister dreg = LookupDRegisterByName(desc); | 212 DRegister dreg = LookupDRegisterByName(desc); |
225 if (dreg != kNoDRegister) { | 213 if (dreg != kNoDRegister) { |
226 *value = sim_->get_dregister(dreg); | 214 *value = sim_->get_dregister(dreg); |
227 return true; | 215 return true; |
228 } | 216 } |
229 if (desc[0] == '*') { | 217 if (desc[0] == '*') { |
230 uint32_t addr; | 218 uint32_t addr; |
231 if (GetValue(desc + 1, &addr)) { | 219 if (GetValue(desc + 1, &addr)) { |
232 if (Simulator::IsIllegalAddress(addr)) { | 220 if (Simulator::IsIllegalAddress(addr)) { |
233 return false; | 221 return false; |
234 } | 222 } |
235 *value = *(reinterpret_cast<double*>(addr)); | 223 *value = *(reinterpret_cast<double*>(addr)); |
236 return true; | 224 return true; |
237 } | 225 } |
238 } | 226 } |
239 return false; | 227 return false; |
240 } | 228 } |
241 | 229 |
242 | |
243 TokenPosition SimulatorDebugger::GetApproximateTokenIndex(const Code& code, | 230 TokenPosition SimulatorDebugger::GetApproximateTokenIndex(const Code& code, |
244 uword pc) { | 231 uword pc) { |
245 TokenPosition token_pos = TokenPosition::kNoSource; | 232 TokenPosition token_pos = TokenPosition::kNoSource; |
246 uword pc_offset = pc - code.PayloadStart(); | 233 uword pc_offset = pc - code.PayloadStart(); |
247 const PcDescriptors& descriptors = | 234 const PcDescriptors& descriptors = |
248 PcDescriptors::Handle(code.pc_descriptors()); | 235 PcDescriptors::Handle(code.pc_descriptors()); |
249 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); | 236 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); |
250 while (iter.MoveNext()) { | 237 while (iter.MoveNext()) { |
251 if (iter.PcOffset() == pc_offset) { | 238 if (iter.PcOffset() == pc_offset) { |
252 return iter.TokenPos(); | 239 return iter.TokenPos(); |
253 } else if (!token_pos.IsReal() && (iter.PcOffset() > pc_offset)) { | 240 } else if (!token_pos.IsReal() && (iter.PcOffset() > pc_offset)) { |
254 token_pos = iter.TokenPos(); | 241 token_pos = iter.TokenPos(); |
255 } | 242 } |
256 } | 243 } |
257 return token_pos; | 244 return token_pos; |
258 } | 245 } |
259 | 246 |
260 | |
261 void SimulatorDebugger::PrintDartFrame(uword pc, | 247 void SimulatorDebugger::PrintDartFrame(uword pc, |
262 uword fp, | 248 uword fp, |
263 uword sp, | 249 uword sp, |
264 const Function& function, | 250 const Function& function, |
265 TokenPosition token_pos, | 251 TokenPosition token_pos, |
266 bool is_optimized, | 252 bool is_optimized, |
267 bool is_inlined) { | 253 bool is_inlined) { |
268 const Script& script = Script::Handle(function.script()); | 254 const Script& script = Script::Handle(function.script()); |
269 const String& func_name = String::Handle(function.QualifiedScrubbedName()); | 255 const String& func_name = String::Handle(function.QualifiedScrubbedName()); |
270 const String& url = String::Handle(script.url()); | 256 const String& url = String::Handle(script.url()); |
271 intptr_t line = -1; | 257 intptr_t line = -1; |
272 intptr_t column = -1; | 258 intptr_t column = -1; |
273 if (token_pos.IsReal()) { | 259 if (token_pos.IsReal()) { |
274 script.GetTokenLocation(token_pos, &line, &column); | 260 script.GetTokenLocation(token_pos, &line, &column); |
275 } | 261 } |
276 OS::Print( | 262 OS::Print( |
277 "pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd ":%" Pd ")\n", pc, | 263 "pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd ":%" Pd ")\n", pc, |
278 fp, sp, is_optimized ? (is_inlined ? "inlined " : "optimized ") : "", | 264 fp, sp, is_optimized ? (is_inlined ? "inlined " : "optimized ") : "", |
279 func_name.ToCString(), url.ToCString(), line, column); | 265 func_name.ToCString(), url.ToCString(), line, column); |
280 } | 266 } |
281 | 267 |
282 | |
283 void SimulatorDebugger::PrintBacktrace() { | 268 void SimulatorDebugger::PrintBacktrace() { |
284 StackFrameIterator frames( | 269 StackFrameIterator frames( |
285 sim_->get_register(FP), sim_->get_register(SP), sim_->get_pc(), | 270 sim_->get_register(FP), sim_->get_register(SP), sim_->get_pc(), |
286 StackFrameIterator::kDontValidateFrames, Thread::Current(), | 271 StackFrameIterator::kDontValidateFrames, Thread::Current(), |
287 StackFrameIterator::kNoCrossThreadIteration); | 272 StackFrameIterator::kNoCrossThreadIteration); |
288 StackFrame* frame = frames.NextFrame(); | 273 StackFrame* frame = frames.NextFrame(); |
289 ASSERT(frame != NULL); | 274 ASSERT(frame != NULL); |
290 Function& function = Function::Handle(); | 275 Function& function = Function::Handle(); |
291 Function& inlined_function = Function::Handle(); | 276 Function& inlined_function = Function::Handle(); |
292 Code& code = Code::Handle(); | 277 Code& code = Code::Handle(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 frame->IsEntryFrame() | 309 frame->IsEntryFrame() |
325 ? "entry" | 310 ? "entry" |
326 : frame->IsExitFrame() | 311 : frame->IsExitFrame() |
327 ? "exit" | 312 ? "exit" |
328 : frame->IsStubFrame() ? "stub" : "invalid"); | 313 : frame->IsStubFrame() ? "stub" : "invalid"); |
329 } | 314 } |
330 frame = frames.NextFrame(); | 315 frame = frames.NextFrame(); |
331 } | 316 } |
332 } | 317 } |
333 | 318 |
334 | |
335 bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) { | 319 bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) { |
336 // Check if a breakpoint can be set. If not return without any side-effects. | 320 // Check if a breakpoint can be set. If not return without any side-effects. |
337 if (sim_->break_pc_ != NULL) { | 321 if (sim_->break_pc_ != NULL) { |
338 return false; | 322 return false; |
339 } | 323 } |
340 | 324 |
341 // Set the breakpoint. | 325 // Set the breakpoint. |
342 sim_->break_pc_ = breakpc; | 326 sim_->break_pc_ = breakpc; |
343 sim_->break_instr_ = breakpc->InstructionBits(); | 327 sim_->break_instr_ = breakpc->InstructionBits(); |
344 // Not setting the breakpoint instruction in the code itself. It will be set | 328 // Not setting the breakpoint instruction in the code itself. It will be set |
345 // when the debugger shell continues. | 329 // when the debugger shell continues. |
346 return true; | 330 return true; |
347 } | 331 } |
348 | 332 |
349 | |
350 bool SimulatorDebugger::DeleteBreakpoint(Instr* breakpc) { | 333 bool SimulatorDebugger::DeleteBreakpoint(Instr* breakpc) { |
351 if (sim_->break_pc_ != NULL) { | 334 if (sim_->break_pc_ != NULL) { |
352 sim_->break_pc_->SetInstructionBits(sim_->break_instr_); | 335 sim_->break_pc_->SetInstructionBits(sim_->break_instr_); |
353 } | 336 } |
354 | 337 |
355 sim_->break_pc_ = NULL; | 338 sim_->break_pc_ = NULL; |
356 sim_->break_instr_ = 0; | 339 sim_->break_instr_ = 0; |
357 return true; | 340 return true; |
358 } | 341 } |
359 | 342 |
360 | |
361 void SimulatorDebugger::UndoBreakpoints() { | 343 void SimulatorDebugger::UndoBreakpoints() { |
362 if (sim_->break_pc_ != NULL) { | 344 if (sim_->break_pc_ != NULL) { |
363 sim_->break_pc_->SetInstructionBits(sim_->break_instr_); | 345 sim_->break_pc_->SetInstructionBits(sim_->break_instr_); |
364 } | 346 } |
365 } | 347 } |
366 | 348 |
367 | |
368 void SimulatorDebugger::RedoBreakpoints() { | 349 void SimulatorDebugger::RedoBreakpoints() { |
369 if (sim_->break_pc_ != NULL) { | 350 if (sim_->break_pc_ != NULL) { |
370 sim_->break_pc_->SetInstructionBits(Instr::kSimulatorBreakpointInstruction); | 351 sim_->break_pc_->SetInstructionBits(Instr::kSimulatorBreakpointInstruction); |
371 } | 352 } |
372 } | 353 } |
373 | 354 |
374 | |
375 void SimulatorDebugger::Debug() { | 355 void SimulatorDebugger::Debug() { |
376 intptr_t last_pc = -1; | 356 intptr_t last_pc = -1; |
377 bool done = false; | 357 bool done = false; |
378 | 358 |
379 #define COMMAND_SIZE 63 | 359 #define COMMAND_SIZE 63 |
380 #define ARG_SIZE 255 | 360 #define ARG_SIZE 255 |
381 | 361 |
382 #define STR(a) #a | 362 #define STR(a) #a |
383 #define XSTR(a) STR(a) | 363 #define XSTR(a) STR(a) |
384 | 364 |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 // shell when hit. | 594 // shell when hit. |
615 RedoBreakpoints(); | 595 RedoBreakpoints(); |
616 | 596 |
617 #undef COMMAND_SIZE | 597 #undef COMMAND_SIZE |
618 #undef ARG_SIZE | 598 #undef ARG_SIZE |
619 | 599 |
620 #undef STR | 600 #undef STR |
621 #undef XSTR | 601 #undef XSTR |
622 } | 602 } |
623 | 603 |
624 | |
625 char* SimulatorDebugger::ReadLine(const char* prompt) { | 604 char* SimulatorDebugger::ReadLine(const char* prompt) { |
626 char* result = NULL; | 605 char* result = NULL; |
627 char line_buf[256]; | 606 char line_buf[256]; |
628 intptr_t offset = 0; | 607 intptr_t offset = 0; |
629 bool keep_going = true; | 608 bool keep_going = true; |
630 OS::Print("%s", prompt); | 609 OS::Print("%s", prompt); |
631 while (keep_going) { | 610 while (keep_going) { |
632 if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) { | 611 if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) { |
633 // fgets got an error. Just give up. | 612 // fgets got an error. Just give up. |
634 if (result != NULL) { | 613 if (result != NULL) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 } | 652 } |
674 // Copy the newly read line into the result. | 653 // Copy the newly read line into the result. |
675 memmove(result + offset, line_buf, len); | 654 memmove(result + offset, line_buf, len); |
676 offset += len; | 655 offset += len; |
677 } | 656 } |
678 ASSERT(result != NULL); | 657 ASSERT(result != NULL); |
679 result[offset] = '\0'; | 658 result[offset] = '\0'; |
680 return result; | 659 return result; |
681 } | 660 } |
682 | 661 |
683 | |
684 // Synchronization primitives support. | 662 // Synchronization primitives support. |
685 Mutex* Simulator::exclusive_access_lock_ = NULL; | 663 Mutex* Simulator::exclusive_access_lock_ = NULL; |
686 Simulator::AddressTag Simulator::exclusive_access_state_[kNumAddressTags] = { | 664 Simulator::AddressTag Simulator::exclusive_access_state_[kNumAddressTags] = { |
687 {NULL, 0}}; | 665 {NULL, 0}}; |
688 int Simulator::next_address_tag_ = 0; | 666 int Simulator::next_address_tag_ = 0; |
689 | 667 |
690 | |
691 void Simulator::InitOnce() { | 668 void Simulator::InitOnce() { |
692 // Setup exclusive access state lock. | 669 // Setup exclusive access state lock. |
693 exclusive_access_lock_ = new Mutex(); | 670 exclusive_access_lock_ = new Mutex(); |
694 } | 671 } |
695 | 672 |
696 | |
697 Simulator::Simulator() { | 673 Simulator::Simulator() { |
698 // Setup simulator support first. Some of this information is needed to | 674 // Setup simulator support first. Some of this information is needed to |
699 // setup the architecture state. | 675 // setup the architecture state. |
700 // We allocate the stack here, the size is computed as the sum of | 676 // We allocate the stack here, the size is computed as the sum of |
701 // the size specified by the user and the buffer space needed for | 677 // the size specified by the user and the buffer space needed for |
702 // handling stack overflow exceptions. To be safe in potential | 678 // handling stack overflow exceptions. To be safe in potential |
703 // stack underflows we also add some underflow buffer space. | 679 // stack underflows we also add some underflow buffer space. |
704 stack_ = | 680 stack_ = |
705 new char[(OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer + | 681 new char[(OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer + |
706 kSimulatorStackUnderflowSize)]; | 682 kSimulatorStackUnderflowSize)]; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 ASSERT(2 * kNumberOfDRegisters >= kNumberOfSRegisters); | 714 ASSERT(2 * kNumberOfDRegisters >= kNumberOfSRegisters); |
739 for (int i = 0; i < kNumberOfSRegisters; i++) { | 715 for (int i = 0; i < kNumberOfSRegisters; i++) { |
740 ASSERT(sregisters_[i] == 0.0); | 716 ASSERT(sregisters_[i] == 0.0); |
741 } | 717 } |
742 fp_n_flag_ = false; | 718 fp_n_flag_ = false; |
743 fp_z_flag_ = false; | 719 fp_z_flag_ = false; |
744 fp_c_flag_ = false; | 720 fp_c_flag_ = false; |
745 fp_v_flag_ = false; | 721 fp_v_flag_ = false; |
746 } | 722 } |
747 | 723 |
748 | |
749 Simulator::~Simulator() { | 724 Simulator::~Simulator() { |
750 delete[] stack_; | 725 delete[] stack_; |
751 Isolate* isolate = Isolate::Current(); | 726 Isolate* isolate = Isolate::Current(); |
752 if (isolate != NULL) { | 727 if (isolate != NULL) { |
753 isolate->set_simulator(NULL); | 728 isolate->set_simulator(NULL); |
754 } | 729 } |
755 } | 730 } |
756 | 731 |
757 | |
758 // When the generated code calls an external reference we need to catch that in | 732 // When the generated code calls an external reference we need to catch that in |
759 // the simulator. The external reference will be a function compiled for the | 733 // the simulator. The external reference will be a function compiled for the |
760 // host architecture. We need to call that function instead of trying to | 734 // host architecture. We need to call that function instead of trying to |
761 // execute it with the simulator. We do that by redirecting the external | 735 // execute it with the simulator. We do that by redirecting the external |
762 // reference to a svc (supervisor call) instruction that is handled by | 736 // reference to a svc (supervisor call) instruction that is handled by |
763 // the simulator. We write the original destination of the jump just at a known | 737 // the simulator. We write the original destination of the jump just at a known |
764 // offset from the svc instruction so the simulator knows what to call. | 738 // offset from the svc instruction so the simulator knows what to call. |
765 class Redirection { | 739 class Redirection { |
766 public: | 740 public: |
767 uword address_of_svc_instruction() { | 741 uword address_of_svc_instruction() { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 } | 796 } |
823 | 797 |
824 uword external_function_; | 798 uword external_function_; |
825 Simulator::CallKind call_kind_; | 799 Simulator::CallKind call_kind_; |
826 int argument_count_; | 800 int argument_count_; |
827 uint32_t svc_instruction_; | 801 uint32_t svc_instruction_; |
828 Redirection* next_; | 802 Redirection* next_; |
829 static Redirection* list_; | 803 static Redirection* list_; |
830 }; | 804 }; |
831 | 805 |
832 | |
833 Redirection* Redirection::list_ = NULL; | 806 Redirection* Redirection::list_ = NULL; |
834 | 807 |
835 | |
836 uword Simulator::RedirectExternalReference(uword function, | 808 uword Simulator::RedirectExternalReference(uword function, |
837 CallKind call_kind, | 809 CallKind call_kind, |
838 int argument_count) { | 810 int argument_count) { |
839 Redirection* redirection = | 811 Redirection* redirection = |
840 Redirection::Get(function, call_kind, argument_count); | 812 Redirection::Get(function, call_kind, argument_count); |
841 return redirection->address_of_svc_instruction(); | 813 return redirection->address_of_svc_instruction(); |
842 } | 814 } |
843 | 815 |
844 | |
845 uword Simulator::FunctionForRedirect(uword redirect) { | 816 uword Simulator::FunctionForRedirect(uword redirect) { |
846 return Redirection::FunctionForRedirect(redirect); | 817 return Redirection::FunctionForRedirect(redirect); |
847 } | 818 } |
848 | 819 |
849 | |
850 // Get the active Simulator for the current isolate. | 820 // Get the active Simulator for the current isolate. |
851 Simulator* Simulator::Current() { | 821 Simulator* Simulator::Current() { |
852 Simulator* simulator = Isolate::Current()->simulator(); | 822 Simulator* simulator = Isolate::Current()->simulator(); |
853 if (simulator == NULL) { | 823 if (simulator == NULL) { |
854 simulator = new Simulator(); | 824 simulator = new Simulator(); |
855 Isolate::Current()->set_simulator(simulator); | 825 Isolate::Current()->set_simulator(simulator); |
856 } | 826 } |
857 return simulator; | 827 return simulator; |
858 } | 828 } |
859 | 829 |
860 | |
861 // Sets the register in the architecture state. It will also deal with updating | 830 // Sets the register in the architecture state. It will also deal with updating |
862 // Simulator internal state for special registers such as PC. | 831 // Simulator internal state for special registers such as PC. |
863 void Simulator::set_register(Register reg, int32_t value) { | 832 void Simulator::set_register(Register reg, int32_t value) { |
864 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); | 833 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); |
865 if (reg == PC) { | 834 if (reg == PC) { |
866 pc_modified_ = true; | 835 pc_modified_ = true; |
867 } | 836 } |
868 registers_[reg] = value; | 837 registers_[reg] = value; |
869 } | 838 } |
870 | 839 |
871 | |
872 // Get the register from the architecture state. This function does handle | 840 // Get the register from the architecture state. This function does handle |
873 // the special case of accessing the PC register. | 841 // the special case of accessing the PC register. |
874 int32_t Simulator::get_register(Register reg) const { | 842 int32_t Simulator::get_register(Register reg) const { |
875 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); | 843 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); |
876 return registers_[reg] + ((reg == PC) ? Instr::kPCReadOffset : 0); | 844 return registers_[reg] + ((reg == PC) ? Instr::kPCReadOffset : 0); |
877 } | 845 } |
878 | 846 |
879 | |
880 // Raw access to the PC register. | 847 // Raw access to the PC register. |
881 void Simulator::set_pc(int32_t value) { | 848 void Simulator::set_pc(int32_t value) { |
882 pc_modified_ = true; | 849 pc_modified_ = true; |
883 registers_[PC] = value; | 850 registers_[PC] = value; |
884 } | 851 } |
885 | 852 |
886 | |
887 // Raw access to the PC register without the special adjustment when reading. | 853 // Raw access to the PC register without the special adjustment when reading. |
888 int32_t Simulator::get_pc() const { | 854 int32_t Simulator::get_pc() const { |
889 return registers_[PC]; | 855 return registers_[PC]; |
890 } | 856 } |
891 | 857 |
892 | |
893 // Accessors for VFP register state. | 858 // Accessors for VFP register state. |
894 void Simulator::set_sregister(SRegister reg, float value) { | 859 void Simulator::set_sregister(SRegister reg, float value) { |
895 ASSERT(TargetCPUFeatures::vfp_supported()); | 860 ASSERT(TargetCPUFeatures::vfp_supported()); |
896 ASSERT((reg >= 0) && (reg < kNumberOfSRegisters)); | 861 ASSERT((reg >= 0) && (reg < kNumberOfSRegisters)); |
897 sregisters_[reg] = bit_cast<int32_t, float>(value); | 862 sregisters_[reg] = bit_cast<int32_t, float>(value); |
898 } | 863 } |
899 | 864 |
900 | |
901 float Simulator::get_sregister(SRegister reg) const { | 865 float Simulator::get_sregister(SRegister reg) const { |
902 ASSERT(TargetCPUFeatures::vfp_supported()); | 866 ASSERT(TargetCPUFeatures::vfp_supported()); |
903 ASSERT((reg >= 0) && (reg < kNumberOfSRegisters)); | 867 ASSERT((reg >= 0) && (reg < kNumberOfSRegisters)); |
904 return bit_cast<float, int32_t>(sregisters_[reg]); | 868 return bit_cast<float, int32_t>(sregisters_[reg]); |
905 } | 869 } |
906 | 870 |
907 | |
908 void Simulator::set_dregister(DRegister reg, double value) { | 871 void Simulator::set_dregister(DRegister reg, double value) { |
909 ASSERT(TargetCPUFeatures::vfp_supported()); | 872 ASSERT(TargetCPUFeatures::vfp_supported()); |
910 ASSERT((reg >= 0) && (reg < kNumberOfDRegisters)); | 873 ASSERT((reg >= 0) && (reg < kNumberOfDRegisters)); |
911 dregisters_[reg] = bit_cast<int64_t, double>(value); | 874 dregisters_[reg] = bit_cast<int64_t, double>(value); |
912 } | 875 } |
913 | 876 |
914 | |
915 double Simulator::get_dregister(DRegister reg) const { | 877 double Simulator::get_dregister(DRegister reg) const { |
916 ASSERT(TargetCPUFeatures::vfp_supported()); | 878 ASSERT(TargetCPUFeatures::vfp_supported()); |
917 ASSERT((reg >= 0) && (reg < kNumberOfDRegisters)); | 879 ASSERT((reg >= 0) && (reg < kNumberOfDRegisters)); |
918 return bit_cast<double, int64_t>(dregisters_[reg]); | 880 return bit_cast<double, int64_t>(dregisters_[reg]); |
919 } | 881 } |
920 | 882 |
921 | |
922 void Simulator::set_qregister(QRegister reg, const simd_value_t& value) { | 883 void Simulator::set_qregister(QRegister reg, const simd_value_t& value) { |
923 ASSERT(TargetCPUFeatures::neon_supported()); | 884 ASSERT(TargetCPUFeatures::neon_supported()); |
924 ASSERT((reg >= 0) && (reg < kNumberOfQRegisters)); | 885 ASSERT((reg >= 0) && (reg < kNumberOfQRegisters)); |
925 qregisters_[reg].data_[0] = value.data_[0]; | 886 qregisters_[reg].data_[0] = value.data_[0]; |
926 qregisters_[reg].data_[1] = value.data_[1]; | 887 qregisters_[reg].data_[1] = value.data_[1]; |
927 qregisters_[reg].data_[2] = value.data_[2]; | 888 qregisters_[reg].data_[2] = value.data_[2]; |
928 qregisters_[reg].data_[3] = value.data_[3]; | 889 qregisters_[reg].data_[3] = value.data_[3]; |
929 } | 890 } |
930 | 891 |
931 | |
932 void Simulator::get_qregister(QRegister reg, simd_value_t* value) const { | 892 void Simulator::get_qregister(QRegister reg, simd_value_t* value) const { |
933 ASSERT(TargetCPUFeatures::neon_supported()); | 893 ASSERT(TargetCPUFeatures::neon_supported()); |
934 // TODO(zra): Replace this test with an assert after we support | 894 // TODO(zra): Replace this test with an assert after we support |
935 // 16 Q registers. | 895 // 16 Q registers. |
936 if ((reg >= 0) && (reg < kNumberOfQRegisters)) { | 896 if ((reg >= 0) && (reg < kNumberOfQRegisters)) { |
937 *value = qregisters_[reg]; | 897 *value = qregisters_[reg]; |
938 } | 898 } |
939 } | 899 } |
940 | 900 |
941 | |
942 void Simulator::set_sregister_bits(SRegister reg, int32_t value) { | 901 void Simulator::set_sregister_bits(SRegister reg, int32_t value) { |
943 ASSERT(TargetCPUFeatures::vfp_supported()); | 902 ASSERT(TargetCPUFeatures::vfp_supported()); |
944 ASSERT((reg >= 0) && (reg < kNumberOfSRegisters)); | 903 ASSERT((reg >= 0) && (reg < kNumberOfSRegisters)); |
945 sregisters_[reg] = value; | 904 sregisters_[reg] = value; |
946 } | 905 } |
947 | 906 |
948 | |
949 int32_t Simulator::get_sregister_bits(SRegister reg) const { | 907 int32_t Simulator::get_sregister_bits(SRegister reg) const { |
950 ASSERT(TargetCPUFeatures::vfp_supported()); | 908 ASSERT(TargetCPUFeatures::vfp_supported()); |
951 ASSERT((reg >= 0) && (reg < kNumberOfSRegisters)); | 909 ASSERT((reg >= 0) && (reg < kNumberOfSRegisters)); |
952 return sregisters_[reg]; | 910 return sregisters_[reg]; |
953 } | 911 } |
954 | 912 |
955 | |
956 void Simulator::set_dregister_bits(DRegister reg, int64_t value) { | 913 void Simulator::set_dregister_bits(DRegister reg, int64_t value) { |
957 ASSERT(TargetCPUFeatures::vfp_supported()); | 914 ASSERT(TargetCPUFeatures::vfp_supported()); |
958 ASSERT((reg >= 0) && (reg < kNumberOfDRegisters)); | 915 ASSERT((reg >= 0) && (reg < kNumberOfDRegisters)); |
959 dregisters_[reg] = value; | 916 dregisters_[reg] = value; |
960 } | 917 } |
961 | 918 |
962 | |
963 int64_t Simulator::get_dregister_bits(DRegister reg) const { | 919 int64_t Simulator::get_dregister_bits(DRegister reg) const { |
964 ASSERT(TargetCPUFeatures::vfp_supported()); | 920 ASSERT(TargetCPUFeatures::vfp_supported()); |
965 ASSERT((reg >= 0) && (reg < kNumberOfDRegisters)); | 921 ASSERT((reg >= 0) && (reg < kNumberOfDRegisters)); |
966 return dregisters_[reg]; | 922 return dregisters_[reg]; |
967 } | 923 } |
968 | 924 |
969 | |
970 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) { | 925 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) { |
971 uword fault_pc = get_pc(); | 926 uword fault_pc = get_pc(); |
972 // The debugger will not be able to single step past this instruction, but | 927 // The debugger will not be able to single step past this instruction, but |
973 // it will be possible to disassemble the code and inspect registers. | 928 // it will be possible to disassemble the code and inspect registers. |
974 char buffer[128]; | 929 char buffer[128]; |
975 snprintf(buffer, sizeof(buffer), | 930 snprintf(buffer, sizeof(buffer), |
976 "illegal memory access at 0x%" Px ", pc=0x%" Px "\n", addr, | 931 "illegal memory access at 0x%" Px ", pc=0x%" Px "\n", addr, |
977 fault_pc); | 932 fault_pc); |
978 SimulatorDebugger dbg(this); | 933 SimulatorDebugger dbg(this); |
979 dbg.Stop(instr, buffer); | 934 dbg.Stop(instr, buffer); |
980 // The debugger will return control in non-interactive mode. | 935 // The debugger will return control in non-interactive mode. |
981 FATAL("Cannot continue execution after illegal memory access."); | 936 FATAL("Cannot continue execution after illegal memory access."); |
982 } | 937 } |
983 | 938 |
984 | |
985 // Processor versions prior to ARMv7 could not do unaligned reads and writes. | 939 // Processor versions prior to ARMv7 could not do unaligned reads and writes. |
986 // On some ARM platforms an interrupt is caused. On others it does a funky | 940 // On some ARM platforms an interrupt is caused. On others it does a funky |
987 // rotation thing. However, from version v7, unaligned access is supported. | 941 // rotation thing. However, from version v7, unaligned access is supported. |
988 // Note that simulator runs have the runtime system running directly on the host | 942 // Note that simulator runs have the runtime system running directly on the host |
989 // system and only generated code is executed in the simulator. Since the host | 943 // system and only generated code is executed in the simulator. Since the host |
990 // is typically IA32 we will get the correct ARMv7-like behaviour on unaligned | 944 // is typically IA32 we will get the correct ARMv7-like behaviour on unaligned |
991 // accesses, but we should actually not generate code accessing unaligned data, | 945 // accesses, but we should actually not generate code accessing unaligned data, |
992 // so we still want to know and abort if we encounter such code. | 946 // so we still want to know and abort if we encounter such code. |
993 void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) { | 947 void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) { |
994 // The debugger will not be able to single step past this instruction, but | 948 // The debugger will not be able to single step past this instruction, but |
995 // it will be possible to disassemble the code and inspect registers. | 949 // it will be possible to disassemble the code and inspect registers. |
996 char buffer[64]; | 950 char buffer[64]; |
997 snprintf(buffer, sizeof(buffer), "unaligned %s at 0x%" Px ", pc=%p\n", msg, | 951 snprintf(buffer, sizeof(buffer), "unaligned %s at 0x%" Px ", pc=%p\n", msg, |
998 addr, instr); | 952 addr, instr); |
999 SimulatorDebugger dbg(this); | 953 SimulatorDebugger dbg(this); |
1000 dbg.Stop(instr, buffer); | 954 dbg.Stop(instr, buffer); |
1001 // The debugger will return control in non-interactive mode. | 955 // The debugger will return control in non-interactive mode. |
1002 FATAL("Cannot continue execution after unaligned access."); | 956 FATAL("Cannot continue execution after unaligned access."); |
1003 } | 957 } |
1004 | 958 |
1005 | |
1006 void Simulator::UnimplementedInstruction(Instr* instr) { | 959 void Simulator::UnimplementedInstruction(Instr* instr) { |
1007 char buffer[64]; | 960 char buffer[64]; |
1008 snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr); | 961 snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr); |
1009 SimulatorDebugger dbg(this); | 962 SimulatorDebugger dbg(this); |
1010 dbg.Stop(instr, buffer); | 963 dbg.Stop(instr, buffer); |
1011 FATAL("Cannot continue execution after unimplemented instruction."); | 964 FATAL("Cannot continue execution after unimplemented instruction."); |
1012 } | 965 } |
1013 | 966 |
1014 | |
1015 intptr_t Simulator::ReadW(uword addr, Instr* instr) { | 967 intptr_t Simulator::ReadW(uword addr, Instr* instr) { |
1016 if ((addr & 3) == 0) { | 968 if ((addr & 3) == 0) { |
1017 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); | 969 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); |
1018 return *ptr; | 970 return *ptr; |
1019 } | 971 } |
1020 UnalignedAccess("read", addr, instr); | 972 UnalignedAccess("read", addr, instr); |
1021 return 0; | 973 return 0; |
1022 } | 974 } |
1023 | 975 |
1024 | |
1025 void Simulator::WriteW(uword addr, intptr_t value, Instr* instr) { | 976 void Simulator::WriteW(uword addr, intptr_t value, Instr* instr) { |
1026 if ((addr & 3) == 0) { | 977 if ((addr & 3) == 0) { |
1027 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); | 978 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); |
1028 *ptr = value; | 979 *ptr = value; |
1029 return; | 980 return; |
1030 } | 981 } |
1031 UnalignedAccess("write", addr, instr); | 982 UnalignedAccess("write", addr, instr); |
1032 } | 983 } |
1033 | 984 |
1034 | |
1035 uint16_t Simulator::ReadHU(uword addr, Instr* instr) { | 985 uint16_t Simulator::ReadHU(uword addr, Instr* instr) { |
1036 if ((addr & 1) == 0) { | 986 if ((addr & 1) == 0) { |
1037 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); | 987 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); |
1038 return *ptr; | 988 return *ptr; |
1039 } | 989 } |
1040 UnalignedAccess("unsigned halfword read", addr, instr); | 990 UnalignedAccess("unsigned halfword read", addr, instr); |
1041 return 0; | 991 return 0; |
1042 } | 992 } |
1043 | 993 |
1044 | |
1045 int16_t Simulator::ReadH(uword addr, Instr* instr) { | 994 int16_t Simulator::ReadH(uword addr, Instr* instr) { |
1046 if ((addr & 1) == 0) { | 995 if ((addr & 1) == 0) { |
1047 int16_t* ptr = reinterpret_cast<int16_t*>(addr); | 996 int16_t* ptr = reinterpret_cast<int16_t*>(addr); |
1048 return *ptr; | 997 return *ptr; |
1049 } | 998 } |
1050 UnalignedAccess("signed halfword read", addr, instr); | 999 UnalignedAccess("signed halfword read", addr, instr); |
1051 return 0; | 1000 return 0; |
1052 } | 1001 } |
1053 | 1002 |
1054 | |
1055 void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) { | 1003 void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) { |
1056 if ((addr & 1) == 0) { | 1004 if ((addr & 1) == 0) { |
1057 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); | 1005 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); |
1058 *ptr = value; | 1006 *ptr = value; |
1059 return; | 1007 return; |
1060 } | 1008 } |
1061 UnalignedAccess("halfword write", addr, instr); | 1009 UnalignedAccess("halfword write", addr, instr); |
1062 } | 1010 } |
1063 | 1011 |
1064 | |
1065 uint8_t Simulator::ReadBU(uword addr) { | 1012 uint8_t Simulator::ReadBU(uword addr) { |
1066 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); | 1013 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); |
1067 return *ptr; | 1014 return *ptr; |
1068 } | 1015 } |
1069 | 1016 |
1070 | |
1071 int8_t Simulator::ReadB(uword addr) { | 1017 int8_t Simulator::ReadB(uword addr) { |
1072 int8_t* ptr = reinterpret_cast<int8_t*>(addr); | 1018 int8_t* ptr = reinterpret_cast<int8_t*>(addr); |
1073 return *ptr; | 1019 return *ptr; |
1074 } | 1020 } |
1075 | 1021 |
1076 | |
1077 void Simulator::WriteB(uword addr, uint8_t value) { | 1022 void Simulator::WriteB(uword addr, uint8_t value) { |
1078 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); | 1023 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); |
1079 *ptr = value; | 1024 *ptr = value; |
1080 } | 1025 } |
1081 | 1026 |
1082 | |
1083 // Synchronization primitives support. | 1027 // Synchronization primitives support. |
1084 void Simulator::SetExclusiveAccess(uword addr) { | 1028 void Simulator::SetExclusiveAccess(uword addr) { |
1085 Thread* thread = Thread::Current(); | 1029 Thread* thread = Thread::Current(); |
1086 ASSERT(thread != NULL); | 1030 ASSERT(thread != NULL); |
1087 DEBUG_ASSERT(exclusive_access_lock_->IsOwnedByCurrentThread()); | 1031 DEBUG_ASSERT(exclusive_access_lock_->IsOwnedByCurrentThread()); |
1088 int i = 0; | 1032 int i = 0; |
1089 // Find an entry for this thread in the exclusive access state. | 1033 // Find an entry for this thread in the exclusive access state. |
1090 while ((i < kNumAddressTags) && | 1034 while ((i < kNumAddressTags) && |
1091 (exclusive_access_state_[i].thread != thread)) { | 1035 (exclusive_access_state_[i].thread != thread)) { |
1092 i++; | 1036 i++; |
1093 } | 1037 } |
1094 // Round-robin replacement of previously used entries. | 1038 // Round-robin replacement of previously used entries. |
1095 if (i == kNumAddressTags) { | 1039 if (i == kNumAddressTags) { |
1096 i = next_address_tag_; | 1040 i = next_address_tag_; |
1097 if (++next_address_tag_ == kNumAddressTags) { | 1041 if (++next_address_tag_ == kNumAddressTags) { |
1098 next_address_tag_ = 0; | 1042 next_address_tag_ = 0; |
1099 } | 1043 } |
1100 exclusive_access_state_[i].thread = thread; | 1044 exclusive_access_state_[i].thread = thread; |
1101 } | 1045 } |
1102 // Remember the address being reserved. | 1046 // Remember the address being reserved. |
1103 exclusive_access_state_[i].addr = addr; | 1047 exclusive_access_state_[i].addr = addr; |
1104 } | 1048 } |
1105 | 1049 |
1106 | |
1107 bool Simulator::HasExclusiveAccessAndOpen(uword addr) { | 1050 bool Simulator::HasExclusiveAccessAndOpen(uword addr) { |
1108 Thread* thread = Thread::Current(); | 1051 Thread* thread = Thread::Current(); |
1109 ASSERT(thread != NULL); | 1052 ASSERT(thread != NULL); |
1110 ASSERT(addr != 0); | 1053 ASSERT(addr != 0); |
1111 DEBUG_ASSERT(exclusive_access_lock_->IsOwnedByCurrentThread()); | 1054 DEBUG_ASSERT(exclusive_access_lock_->IsOwnedByCurrentThread()); |
1112 bool result = false; | 1055 bool result = false; |
1113 for (int i = 0; i < kNumAddressTags; i++) { | 1056 for (int i = 0; i < kNumAddressTags; i++) { |
1114 if (exclusive_access_state_[i].thread == thread) { | 1057 if (exclusive_access_state_[i].thread == thread) { |
1115 // Check whether the current thread's address reservation matches. | 1058 // Check whether the current thread's address reservation matches. |
1116 if (exclusive_access_state_[i].addr == addr) { | 1059 if (exclusive_access_state_[i].addr == addr) { |
1117 result = true; | 1060 result = true; |
1118 } | 1061 } |
1119 exclusive_access_state_[i].addr = 0; | 1062 exclusive_access_state_[i].addr = 0; |
1120 } else if (exclusive_access_state_[i].addr == addr) { | 1063 } else if (exclusive_access_state_[i].addr == addr) { |
1121 // Other threads with matching address lose their reservations. | 1064 // Other threads with matching address lose their reservations. |
1122 exclusive_access_state_[i].addr = 0; | 1065 exclusive_access_state_[i].addr = 0; |
1123 } | 1066 } |
1124 } | 1067 } |
1125 return result; | 1068 return result; |
1126 } | 1069 } |
1127 | 1070 |
1128 | |
1129 void Simulator::ClearExclusive() { | 1071 void Simulator::ClearExclusive() { |
1130 MutexLocker ml(exclusive_access_lock_); | 1072 MutexLocker ml(exclusive_access_lock_); |
1131 // Remove the reservation for this thread. | 1073 // Remove the reservation for this thread. |
1132 SetExclusiveAccess(0); | 1074 SetExclusiveAccess(0); |
1133 } | 1075 } |
1134 | 1076 |
1135 | |
1136 intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) { | 1077 intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) { |
1137 MutexLocker ml(exclusive_access_lock_); | 1078 MutexLocker ml(exclusive_access_lock_); |
1138 SetExclusiveAccess(addr); | 1079 SetExclusiveAccess(addr); |
1139 return ReadW(addr, instr); | 1080 return ReadW(addr, instr); |
1140 } | 1081 } |
1141 | 1082 |
1142 | |
1143 intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) { | 1083 intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) { |
1144 MutexLocker ml(exclusive_access_lock_); | 1084 MutexLocker ml(exclusive_access_lock_); |
1145 bool write_allowed = HasExclusiveAccessAndOpen(addr); | 1085 bool write_allowed = HasExclusiveAccessAndOpen(addr); |
1146 if (write_allowed) { | 1086 if (write_allowed) { |
1147 WriteW(addr, value, instr); | 1087 WriteW(addr, value, instr); |
1148 return 0; // Success. | 1088 return 0; // Success. |
1149 } | 1089 } |
1150 return 1; // Failure. | 1090 return 1; // Failure. |
1151 } | 1091 } |
1152 | 1092 |
1153 | |
1154 uword Simulator::CompareExchange(uword* address, | 1093 uword Simulator::CompareExchange(uword* address, |
1155 uword compare_value, | 1094 uword compare_value, |
1156 uword new_value) { | 1095 uword new_value) { |
1157 MutexLocker ml(exclusive_access_lock_); | 1096 MutexLocker ml(exclusive_access_lock_); |
1158 // We do not get a reservation as it would be guaranteed to be found when | 1097 // We do not get a reservation as it would be guaranteed to be found when |
1159 // writing below. No other thread is able to make a reservation while we | 1098 // writing below. No other thread is able to make a reservation while we |
1160 // hold the lock. | 1099 // hold the lock. |
1161 uword value = *address; | 1100 uword value = *address; |
1162 if (value == compare_value) { | 1101 if (value == compare_value) { |
1163 *address = new_value; | 1102 *address = new_value; |
1164 // Same effect on exclusive access state as a successful STREX. | 1103 // Same effect on exclusive access state as a successful STREX. |
1165 HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address)); | 1104 HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address)); |
1166 } else { | 1105 } else { |
1167 // Same effect on exclusive access state as an LDREX. | 1106 // Same effect on exclusive access state as an LDREX. |
1168 SetExclusiveAccess(reinterpret_cast<uword>(address)); | 1107 SetExclusiveAccess(reinterpret_cast<uword>(address)); |
1169 } | 1108 } |
1170 return value; | 1109 return value; |
1171 } | 1110 } |
1172 | 1111 |
1173 | |
1174 uint32_t Simulator::CompareExchangeUint32(uint32_t* address, | 1112 uint32_t Simulator::CompareExchangeUint32(uint32_t* address, |
1175 uint32_t compare_value, | 1113 uint32_t compare_value, |
1176 uint32_t new_value) { | 1114 uint32_t new_value) { |
1177 COMPILE_ASSERT(sizeof(uword) == sizeof(uint32_t)); | 1115 COMPILE_ASSERT(sizeof(uword) == sizeof(uint32_t)); |
1178 return CompareExchange(reinterpret_cast<uword*>(address), | 1116 return CompareExchange(reinterpret_cast<uword*>(address), |
1179 static_cast<uword>(compare_value), | 1117 static_cast<uword>(compare_value), |
1180 static_cast<uword>(new_value)); | 1118 static_cast<uword>(new_value)); |
1181 } | 1119 } |
1182 | 1120 |
1183 | |
1184 // Returns the top of the stack area to enable checking for stack pointer | 1121 // Returns the top of the stack area to enable checking for stack pointer |
1185 // validity. | 1122 // validity. |
1186 uword Simulator::StackTop() const { | 1123 uword Simulator::StackTop() const { |
1187 // To be safe in potential stack underflows we leave some buffer above and | 1124 // To be safe in potential stack underflows we leave some buffer above and |
1188 // set the stack top. | 1125 // set the stack top. |
1189 return StackBase() + | 1126 return StackBase() + |
1190 (OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer); | 1127 (OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer); |
1191 } | 1128 } |
1192 | 1129 |
1193 | |
1194 bool Simulator::IsTracingExecution() const { | 1130 bool Simulator::IsTracingExecution() const { |
1195 return icount_ > FLAG_trace_sim_after; | 1131 return icount_ > FLAG_trace_sim_after; |
1196 } | 1132 } |
1197 | 1133 |
1198 | |
1199 // Unsupported instructions use Format to print an error and stop execution. | 1134 // Unsupported instructions use Format to print an error and stop execution. |
1200 void Simulator::Format(Instr* instr, const char* format) { | 1135 void Simulator::Format(Instr* instr, const char* format) { |
1201 OS::Print("Simulator found unsupported instruction:\n 0x%p: %s\n", instr, | 1136 OS::Print("Simulator found unsupported instruction:\n 0x%p: %s\n", instr, |
1202 format); | 1137 format); |
1203 UNIMPLEMENTED(); | 1138 UNIMPLEMENTED(); |
1204 } | 1139 } |
1205 | 1140 |
1206 | |
1207 // Checks if the current instruction should be executed based on its | 1141 // Checks if the current instruction should be executed based on its |
1208 // condition bits. | 1142 // condition bits. |
1209 bool Simulator::ConditionallyExecute(Instr* instr) { | 1143 bool Simulator::ConditionallyExecute(Instr* instr) { |
1210 switch (instr->ConditionField()) { | 1144 switch (instr->ConditionField()) { |
1211 case EQ: | 1145 case EQ: |
1212 return z_flag_; | 1146 return z_flag_; |
1213 case NE: | 1147 case NE: |
1214 return !z_flag_; | 1148 return !z_flag_; |
1215 case CS: | 1149 case CS: |
1216 return c_flag_; | 1150 return c_flag_; |
(...skipping 20 matching lines...) Expand all Loading... |
1237 case LE: | 1171 case LE: |
1238 return z_flag_ || (n_flag_ != v_flag_); | 1172 return z_flag_ || (n_flag_ != v_flag_); |
1239 case AL: | 1173 case AL: |
1240 return true; | 1174 return true; |
1241 default: | 1175 default: |
1242 UNREACHABLE(); | 1176 UNREACHABLE(); |
1243 } | 1177 } |
1244 return false; | 1178 return false; |
1245 } | 1179 } |
1246 | 1180 |
1247 | |
1248 // Calculate and set the Negative and Zero flags. | 1181 // Calculate and set the Negative and Zero flags. |
1249 void Simulator::SetNZFlags(int32_t val) { | 1182 void Simulator::SetNZFlags(int32_t val) { |
1250 n_flag_ = (val < 0); | 1183 n_flag_ = (val < 0); |
1251 z_flag_ = (val == 0); | 1184 z_flag_ = (val == 0); |
1252 } | 1185 } |
1253 | 1186 |
1254 | |
1255 // Set the Carry flag. | 1187 // Set the Carry flag. |
1256 void Simulator::SetCFlag(bool val) { | 1188 void Simulator::SetCFlag(bool val) { |
1257 c_flag_ = val; | 1189 c_flag_ = val; |
1258 } | 1190 } |
1259 | 1191 |
1260 | |
1261 // Set the oVerflow flag. | 1192 // Set the oVerflow flag. |
1262 void Simulator::SetVFlag(bool val) { | 1193 void Simulator::SetVFlag(bool val) { |
1263 v_flag_ = val; | 1194 v_flag_ = val; |
1264 } | 1195 } |
1265 | 1196 |
1266 | |
1267 // Calculate C flag value for additions (and subtractions with adjusted args). | 1197 // Calculate C flag value for additions (and subtractions with adjusted args). |
1268 bool Simulator::CarryFrom(int32_t left, int32_t right, int32_t carry) { | 1198 bool Simulator::CarryFrom(int32_t left, int32_t right, int32_t carry) { |
1269 uint64_t uleft = static_cast<uint32_t>(left); | 1199 uint64_t uleft = static_cast<uint32_t>(left); |
1270 uint64_t uright = static_cast<uint32_t>(right); | 1200 uint64_t uright = static_cast<uint32_t>(right); |
1271 uint64_t ucarry = static_cast<uint32_t>(carry); | 1201 uint64_t ucarry = static_cast<uint32_t>(carry); |
1272 return ((uleft + uright + ucarry) >> 32) != 0; | 1202 return ((uleft + uright + ucarry) >> 32) != 0; |
1273 } | 1203 } |
1274 | 1204 |
1275 | |
1276 // Calculate V flag value for additions (and subtractions with adjusted args). | 1205 // Calculate V flag value for additions (and subtractions with adjusted args). |
1277 bool Simulator::OverflowFrom(int32_t left, int32_t right, int32_t carry) { | 1206 bool Simulator::OverflowFrom(int32_t left, int32_t right, int32_t carry) { |
1278 int64_t result = static_cast<int64_t>(left) + right + carry; | 1207 int64_t result = static_cast<int64_t>(left) + right + carry; |
1279 return (result >> 31) != (result >> 32); | 1208 return (result >> 31) != (result >> 32); |
1280 } | 1209 } |
1281 | 1210 |
1282 | |
1283 // Addressing Mode 1 - Data-processing operands: | 1211 // Addressing Mode 1 - Data-processing operands: |
1284 // Get the value based on the shifter_operand with register. | 1212 // Get the value based on the shifter_operand with register. |
1285 int32_t Simulator::GetShiftRm(Instr* instr, bool* carry_out) { | 1213 int32_t Simulator::GetShiftRm(Instr* instr, bool* carry_out) { |
1286 Shift shift = instr->ShiftField(); | 1214 Shift shift = instr->ShiftField(); |
1287 int shift_amount = instr->ShiftAmountField(); | 1215 int shift_amount = instr->ShiftAmountField(); |
1288 int32_t result = get_register(instr->RmField()); | 1216 int32_t result = get_register(instr->RmField()); |
1289 if (instr->Bit(4) == 0) { | 1217 if (instr->Bit(4) == 0) { |
1290 // by immediate | 1218 // by immediate |
1291 if ((shift == ROR) && (shift_amount == 0)) { | 1219 if ((shift == ROR) && (shift_amount == 0)) { |
1292 UnimplementedInstruction(instr); | 1220 UnimplementedInstruction(instr); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1415 | 1343 |
1416 default: { | 1344 default: { |
1417 UNREACHABLE(); | 1345 UNREACHABLE(); |
1418 break; | 1346 break; |
1419 } | 1347 } |
1420 } | 1348 } |
1421 } | 1349 } |
1422 return result; | 1350 return result; |
1423 } | 1351 } |
1424 | 1352 |
1425 | |
1426 // Addressing Mode 1 - Data-processing operands: | 1353 // Addressing Mode 1 - Data-processing operands: |
1427 // Get the value based on the shifter_operand with immediate. | 1354 // Get the value based on the shifter_operand with immediate. |
1428 int32_t Simulator::GetImm(Instr* instr, bool* carry_out) { | 1355 int32_t Simulator::GetImm(Instr* instr, bool* carry_out) { |
1429 int rotate = instr->RotateField() * 2; | 1356 int rotate = instr->RotateField() * 2; |
1430 int immed8 = instr->Immed8Field(); | 1357 int immed8 = instr->Immed8Field(); |
1431 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate)); | 1358 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate)); |
1432 *carry_out = (rotate == 0) ? c_flag_ : (imm < 0); | 1359 *carry_out = (rotate == 0) ? c_flag_ : (imm < 0); |
1433 return imm; | 1360 return imm; |
1434 } | 1361 } |
1435 | 1362 |
1436 | |
1437 static int count_bits(int bit_vector) { | 1363 static int count_bits(int bit_vector) { |
1438 int count = 0; | 1364 int count = 0; |
1439 while (bit_vector != 0) { | 1365 while (bit_vector != 0) { |
1440 if ((bit_vector & 1) != 0) { | 1366 if ((bit_vector & 1) != 0) { |
1441 count++; | 1367 count++; |
1442 } | 1368 } |
1443 bit_vector >>= 1; | 1369 bit_vector >>= 1; |
1444 } | 1370 } |
1445 return count; | 1371 return count; |
1446 } | 1372 } |
1447 | 1373 |
1448 | |
1449 // Addressing Mode 4 - Load and Store Multiple | 1374 // Addressing Mode 4 - Load and Store Multiple |
1450 void Simulator::HandleRList(Instr* instr, bool load) { | 1375 void Simulator::HandleRList(Instr* instr, bool load) { |
1451 Register rn = instr->RnField(); | 1376 Register rn = instr->RnField(); |
1452 int32_t rn_val = get_register(rn); | 1377 int32_t rn_val = get_register(rn); |
1453 int rlist = instr->RlistField(); | 1378 int rlist = instr->RlistField(); |
1454 int num_regs = count_bits(rlist); | 1379 int num_regs = count_bits(rlist); |
1455 | 1380 |
1456 uword address = 0; | 1381 uword address = 0; |
1457 uword end_address = 0; | 1382 uword end_address = 0; |
1458 switch (instr->PUField()) { | 1383 switch (instr->PUField()) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1505 } | 1430 } |
1506 address += 4; | 1431 address += 4; |
1507 } | 1432 } |
1508 reg++; | 1433 reg++; |
1509 rlist >>= 1; | 1434 rlist >>= 1; |
1510 } | 1435 } |
1511 ASSERT(end_address == address); | 1436 ASSERT(end_address == address); |
1512 } | 1437 } |
1513 } | 1438 } |
1514 | 1439 |
1515 | |
1516 // Calls into the Dart runtime are based on this interface. | 1440 // Calls into the Dart runtime are based on this interface. |
1517 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments); | 1441 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments); |
1518 | 1442 |
1519 // Calls to leaf Dart runtime functions are based on this interface. | 1443 // Calls to leaf Dart runtime functions are based on this interface. |
1520 typedef int32_t (*SimulatorLeafRuntimeCall)(int32_t r0, | 1444 typedef int32_t (*SimulatorLeafRuntimeCall)(int32_t r0, |
1521 int32_t r1, | 1445 int32_t r1, |
1522 int32_t r2, | 1446 int32_t r2, |
1523 int32_t r3); | 1447 int32_t r3); |
1524 | 1448 |
1525 // Calls to leaf float Dart runtime functions are based on this interface. | 1449 // Calls to leaf float Dart runtime functions are based on this interface. |
1526 typedef double (*SimulatorLeafFloatRuntimeCall)(double d0, double d1); | 1450 typedef double (*SimulatorLeafFloatRuntimeCall)(double d0, double d1); |
1527 | 1451 |
1528 // Calls to native Dart functions are based on this interface. | 1452 // Calls to native Dart functions are based on this interface. |
1529 typedef void (*SimulatorBootstrapNativeCall)(NativeArguments* arguments); | 1453 typedef void (*SimulatorBootstrapNativeCall)(NativeArguments* arguments); |
1530 typedef void (*SimulatorNativeCall)(NativeArguments* arguments, uword target); | 1454 typedef void (*SimulatorNativeCall)(NativeArguments* arguments, uword target); |
1531 | 1455 |
1532 | |
1533 void Simulator::SupervisorCall(Instr* instr) { | 1456 void Simulator::SupervisorCall(Instr* instr) { |
1534 int svc = instr->SvcField(); | 1457 int svc = instr->SvcField(); |
1535 switch (svc) { | 1458 switch (svc) { |
1536 case Instr::kSimulatorRedirectCode: { | 1459 case Instr::kSimulatorRedirectCode: { |
1537 SimulatorSetjmpBuffer buffer(this); | 1460 SimulatorSetjmpBuffer buffer(this); |
1538 | 1461 |
1539 if (!setjmp(buffer.buffer_)) { | 1462 if (!setjmp(buffer.buffer_)) { |
1540 int32_t saved_lr = get_register(LR); | 1463 int32_t saved_lr = get_register(LR); |
1541 Redirection* redirection = Redirection::FromSvcInstruction(instr); | 1464 Redirection* redirection = Redirection::FromSvcInstruction(instr); |
1542 uword external = redirection->external_function(); | 1465 uword external = redirection->external_function(); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1660 dbg.Stop(instr, "breakpoint"); | 1583 dbg.Stop(instr, "breakpoint"); |
1661 break; | 1584 break; |
1662 } | 1585 } |
1663 default: { | 1586 default: { |
1664 UNREACHABLE(); | 1587 UNREACHABLE(); |
1665 break; | 1588 break; |
1666 } | 1589 } |
1667 } | 1590 } |
1668 } | 1591 } |
1669 | 1592 |
1670 | |
1671 // Handle execution based on instruction types. | 1593 // Handle execution based on instruction types. |
1672 | 1594 |
1673 // Instruction types 0 and 1 are both rolled into one function because they | 1595 // Instruction types 0 and 1 are both rolled into one function because they |
1674 // only differ in the handling of the shifter_operand. | 1596 // only differ in the handling of the shifter_operand. |
1675 void Simulator::DecodeType01(Instr* instr) { | 1597 void Simulator::DecodeType01(Instr* instr) { |
1676 if (!instr->IsDataProcessing()) { | 1598 if (!instr->IsDataProcessing()) { |
1677 // miscellaneous, multiply, sync primitives, extra loads and stores. | 1599 // miscellaneous, multiply, sync primitives, extra loads and stores. |
1678 if (instr->IsMiscellaneous()) { | 1600 if (instr->IsMiscellaneous()) { |
1679 switch (instr->Bits(4, 3)) { | 1601 switch (instr->Bits(4, 3)) { |
1680 case 1: { | 1602 case 1: { |
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2285 } | 2207 } |
2286 | 2208 |
2287 default: { | 2209 default: { |
2288 UNREACHABLE(); | 2210 UNREACHABLE(); |
2289 break; | 2211 break; |
2290 } | 2212 } |
2291 } | 2213 } |
2292 } | 2214 } |
2293 } | 2215 } |
2294 | 2216 |
2295 | |
2296 void Simulator::DecodeType2(Instr* instr) { | 2217 void Simulator::DecodeType2(Instr* instr) { |
2297 Register rd = instr->RdField(); | 2218 Register rd = instr->RdField(); |
2298 Register rn = instr->RnField(); | 2219 Register rn = instr->RnField(); |
2299 int32_t rn_val = get_register(rn); | 2220 int32_t rn_val = get_register(rn); |
2300 int32_t im_val = instr->Offset12Field(); | 2221 int32_t im_val = instr->Offset12Field(); |
2301 uword addr = 0; | 2222 uword addr = 0; |
2302 bool write_back = false; | 2223 bool write_back = false; |
2303 switch (instr->PUField()) { | 2224 switch (instr->PUField()) { |
2304 case 0: { | 2225 case 0: { |
2305 // Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12"); | 2226 // Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12"); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2354 } else { | 2275 } else { |
2355 if (instr->HasL()) { | 2276 if (instr->HasL()) { |
2356 set_register(rd, ReadW(addr, instr)); | 2277 set_register(rd, ReadW(addr, instr)); |
2357 } else { | 2278 } else { |
2358 WriteW(addr, get_register(rd), instr); | 2279 WriteW(addr, get_register(rd), instr); |
2359 } | 2280 } |
2360 } | 2281 } |
2361 } | 2282 } |
2362 } | 2283 } |
2363 | 2284 |
2364 | |
2365 void Simulator::DoDivision(Instr* instr) { | 2285 void Simulator::DoDivision(Instr* instr) { |
2366 const Register rd = instr->DivRdField(); | 2286 const Register rd = instr->DivRdField(); |
2367 const Register rn = instr->DivRnField(); | 2287 const Register rn = instr->DivRnField(); |
2368 const Register rm = instr->DivRmField(); | 2288 const Register rm = instr->DivRmField(); |
2369 | 2289 |
2370 if (!TargetCPUFeatures::integer_division_supported()) { | 2290 if (!TargetCPUFeatures::integer_division_supported()) { |
2371 UnimplementedInstruction(instr); | 2291 UnimplementedInstruction(instr); |
2372 return; | 2292 return; |
2373 } | 2293 } |
2374 | 2294 |
(...skipping 18 matching lines...) Expand all Loading... |
2393 if ((rn_val == static_cast<int32_t>(0x80000000)) && | 2313 if ((rn_val == static_cast<int32_t>(0x80000000)) && |
2394 (rm_val == static_cast<int32_t>(0xffffffff))) { | 2314 (rm_val == static_cast<int32_t>(0xffffffff))) { |
2395 result = 0x80000000; | 2315 result = 0x80000000; |
2396 } else { | 2316 } else { |
2397 result = rn_val / rm_val; | 2317 result = rn_val / rm_val; |
2398 } | 2318 } |
2399 set_register(rd, result); | 2319 set_register(rd, result); |
2400 } | 2320 } |
2401 } | 2321 } |
2402 | 2322 |
2403 | |
2404 void Simulator::DecodeType3(Instr* instr) { | 2323 void Simulator::DecodeType3(Instr* instr) { |
2405 if (instr->IsDivision()) { | 2324 if (instr->IsDivision()) { |
2406 DoDivision(instr); | 2325 DoDivision(instr); |
2407 return; | 2326 return; |
2408 } | 2327 } |
2409 Register rd = instr->RdField(); | 2328 Register rd = instr->RdField(); |
2410 Register rn = instr->RnField(); | 2329 Register rn = instr->RnField(); |
2411 int32_t rn_val = get_register(rn); | 2330 int32_t rn_val = get_register(rn); |
2412 bool shifter_carry_out = 0; | 2331 bool shifter_carry_out = 0; |
2413 int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out); | 2332 int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2467 } else { | 2386 } else { |
2468 if (instr->HasL()) { | 2387 if (instr->HasL()) { |
2469 set_register(rd, ReadW(addr, instr)); | 2388 set_register(rd, ReadW(addr, instr)); |
2470 } else { | 2389 } else { |
2471 WriteW(addr, get_register(rd), instr); | 2390 WriteW(addr, get_register(rd), instr); |
2472 } | 2391 } |
2473 } | 2392 } |
2474 } | 2393 } |
2475 } | 2394 } |
2476 | 2395 |
2477 | |
2478 void Simulator::DecodeType4(Instr* instr) { | 2396 void Simulator::DecodeType4(Instr* instr) { |
2479 ASSERT(instr->Bit(22) == 0); // only allowed to be set in privileged mode | 2397 ASSERT(instr->Bit(22) == 0); // only allowed to be set in privileged mode |
2480 if (instr->HasL()) { | 2398 if (instr->HasL()) { |
2481 // Format(instr, "ldm'cond'pu 'rn'w, 'rlist"); | 2399 // Format(instr, "ldm'cond'pu 'rn'w, 'rlist"); |
2482 HandleRList(instr, true); | 2400 HandleRList(instr, true); |
2483 } else { | 2401 } else { |
2484 // Format(instr, "stm'cond'pu 'rn'w, 'rlist"); | 2402 // Format(instr, "stm'cond'pu 'rn'w, 'rlist"); |
2485 HandleRList(instr, false); | 2403 HandleRList(instr, false); |
2486 } | 2404 } |
2487 } | 2405 } |
2488 | 2406 |
2489 | |
2490 void Simulator::DecodeType5(Instr* instr) { | 2407 void Simulator::DecodeType5(Instr* instr) { |
2491 // Format(instr, "b'l'cond 'target"); | 2408 // Format(instr, "b'l'cond 'target"); |
2492 int off = (instr->SImmed24Field() << 2) + 8; | 2409 int off = (instr->SImmed24Field() << 2) + 8; |
2493 intptr_t pc = get_pc(); | 2410 intptr_t pc = get_pc(); |
2494 if (instr->HasLink()) { | 2411 if (instr->HasLink()) { |
2495 set_register(LR, pc + Instr::kInstrSize); | 2412 set_register(LR, pc + Instr::kInstrSize); |
2496 } | 2413 } |
2497 set_pc(pc + off); | 2414 set_pc(pc + off); |
2498 } | 2415 } |
2499 | 2416 |
2500 | |
2501 void Simulator::DecodeType6(Instr* instr) { | 2417 void Simulator::DecodeType6(Instr* instr) { |
2502 if (instr->IsVFPDoubleTransfer()) { | 2418 if (instr->IsVFPDoubleTransfer()) { |
2503 Register rd = instr->RdField(); | 2419 Register rd = instr->RdField(); |
2504 Register rn = instr->RnField(); | 2420 Register rn = instr->RnField(); |
2505 if (instr->Bit(8) == 0) { | 2421 if (instr->Bit(8) == 0) { |
2506 SRegister sm = instr->SmField(); | 2422 SRegister sm = instr->SmField(); |
2507 SRegister sm1 = static_cast<SRegister>(sm + 1); | 2423 SRegister sm1 = static_cast<SRegister>(sm + 1); |
2508 ASSERT(sm1 < kNumberOfSRegisters); | 2424 ASSERT(sm1 < kNumberOfSRegisters); |
2509 if (instr->Bit(20) == 1) { | 2425 if (instr->Bit(20) == 1) { |
2510 // Format(instr, "vmovrrs'cond 'rd, 'rn, {'sm', 'sm1}"); | 2426 // Format(instr, "vmovrrs'cond 'rd, 'rn, {'sm', 'sm1}"); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2622 } else { | 2538 } else { |
2623 UnimplementedInstruction(instr); | 2539 UnimplementedInstruction(instr); |
2624 } | 2540 } |
2625 } | 2541 } |
2626 } | 2542 } |
2627 } else { | 2543 } else { |
2628 UnimplementedInstruction(instr); | 2544 UnimplementedInstruction(instr); |
2629 } | 2545 } |
2630 } | 2546 } |
2631 | 2547 |
2632 | |
2633 void Simulator::DecodeType7(Instr* instr) { | 2548 void Simulator::DecodeType7(Instr* instr) { |
2634 if (instr->Bit(24) == 1) { | 2549 if (instr->Bit(24) == 1) { |
2635 // Format(instr, "svc #'svc"); | 2550 // Format(instr, "svc #'svc"); |
2636 SupervisorCall(instr); | 2551 SupervisorCall(instr); |
2637 } else if (instr->IsVFPDataProcessingOrSingleTransfer()) { | 2552 } else if (instr->IsVFPDataProcessingOrSingleTransfer()) { |
2638 if (instr->Bit(4) == 0) { | 2553 if (instr->Bit(4) == 0) { |
2639 // VFP Data Processing | 2554 // VFP Data Processing |
2640 SRegister sd; | 2555 SRegister sd; |
2641 SRegister sn; | 2556 SRegister sn; |
2642 SRegister sm; | 2557 SRegister sm; |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3018 } | 2933 } |
3019 } else { | 2934 } else { |
3020 UnimplementedInstruction(instr); | 2935 UnimplementedInstruction(instr); |
3021 } | 2936 } |
3022 } | 2937 } |
3023 } else { | 2938 } else { |
3024 UnimplementedInstruction(instr); | 2939 UnimplementedInstruction(instr); |
3025 } | 2940 } |
3026 } | 2941 } |
3027 | 2942 |
3028 | |
3029 static float arm_reciprocal_sqrt_estimate(float a) { | 2943 static float arm_reciprocal_sqrt_estimate(float a) { |
3030 // From the ARM Architecture Reference Manual A2-87. | 2944 // From the ARM Architecture Reference Manual A2-87. |
3031 if (isinf(a) || (fabs(a) >= exp2f(126))) | 2945 if (isinf(a) || (fabs(a) >= exp2f(126))) |
3032 return 0.0; | 2946 return 0.0; |
3033 else if (a == 0.0) | 2947 else if (a == 0.0) |
3034 return kPosInfinity; | 2948 return kPosInfinity; |
3035 else if (isnan(a)) | 2949 else if (isnan(a)) |
3036 return a; | 2950 return a; |
3037 | 2951 |
3038 uint32_t a_bits = bit_cast<uint32_t, float>(a); | 2952 uint32_t a_bits = bit_cast<uint32_t, float>(a); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3073 double estimate = static_cast<double>(s) / 256.0; | 2987 double estimate = static_cast<double>(s) / 256.0; |
3074 ASSERT((estimate >= 1.0) && (estimate <= (511.0 / 256.0))); | 2988 ASSERT((estimate >= 1.0) && (estimate <= (511.0 / 256.0))); |
3075 | 2989 |
3076 // result = 0 : result_exp<7:0> : estimate<51:29> | 2990 // result = 0 : result_exp<7:0> : estimate<51:29> |
3077 int32_t result_bits = | 2991 int32_t result_bits = |
3078 ((result_exp & 0xff) << 23) | | 2992 ((result_exp & 0xff) << 23) | |
3079 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); | 2993 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); |
3080 return bit_cast<float, int32_t>(result_bits); | 2994 return bit_cast<float, int32_t>(result_bits); |
3081 } | 2995 } |
3082 | 2996 |
3083 | |
3084 static float arm_recip_estimate(float a) { | 2997 static float arm_recip_estimate(float a) { |
3085 // From the ARM Architecture Reference Manual A2-85. | 2998 // From the ARM Architecture Reference Manual A2-85. |
3086 if (isinf(a) || (fabs(a) >= exp2f(126))) | 2999 if (isinf(a) || (fabs(a) >= exp2f(126))) |
3087 return 0.0; | 3000 return 0.0; |
3088 else if (a == 0.0) | 3001 else if (a == 0.0) |
3089 return kPosInfinity; | 3002 return kPosInfinity; |
3090 else if (isnan(a)) | 3003 else if (isnan(a)) |
3091 return a; | 3004 return a; |
3092 | 3005 |
3093 uint32_t a_bits = bit_cast<uint32_t, float>(a); | 3006 uint32_t a_bits = bit_cast<uint32_t, float>(a); |
(...skipping 16 matching lines...) Expand all Loading... |
3110 double estimate = static_cast<double>(s) / 256.0; | 3023 double estimate = static_cast<double>(s) / 256.0; |
3111 ASSERT((estimate >= 1.0) && (estimate <= (511.0 / 256.0))); | 3024 ASSERT((estimate >= 1.0) && (estimate <= (511.0 / 256.0))); |
3112 | 3025 |
3113 // result = sign : result_exp<7:0> : estimate<51:29> | 3026 // result = sign : result_exp<7:0> : estimate<51:29> |
3114 int32_t result_bits = | 3027 int32_t result_bits = |
3115 (a_bits & 0x80000000) | ((result_exp & 0xff) << 23) | | 3028 (a_bits & 0x80000000) | ((result_exp & 0xff) << 23) | |
3116 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); | 3029 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); |
3117 return bit_cast<float, int32_t>(result_bits); | 3030 return bit_cast<float, int32_t>(result_bits); |
3118 } | 3031 } |
3119 | 3032 |
3120 | |
3121 static void simd_value_swap(simd_value_t* s1, | 3033 static void simd_value_swap(simd_value_t* s1, |
3122 int i1, | 3034 int i1, |
3123 simd_value_t* s2, | 3035 simd_value_t* s2, |
3124 int i2) { | 3036 int i2) { |
3125 uint32_t tmp; | 3037 uint32_t tmp; |
3126 tmp = s1->data_[i1].u; | 3038 tmp = s1->data_[i1].u; |
3127 s1->data_[i1].u = s2->data_[i2].u; | 3039 s1->data_[i1].u = s2->data_[i2].u; |
3128 s2->data_[i2].u = tmp; | 3040 s2->data_[i2].u = tmp; |
3129 } | 3041 } |
3130 | 3042 |
3131 | |
3132 void Simulator::DecodeSIMDDataProcessing(Instr* instr) { | 3043 void Simulator::DecodeSIMDDataProcessing(Instr* instr) { |
3133 ASSERT(instr->ConditionField() == kSpecialCondition); | 3044 ASSERT(instr->ConditionField() == kSpecialCondition); |
3134 | 3045 |
3135 if (instr->Bit(6) == 1) { | 3046 if (instr->Bit(6) == 1) { |
3136 // Q = 1, Using 128-bit Q registers. | 3047 // Q = 1, Using 128-bit Q registers. |
3137 const QRegister qd = instr->QdField(); | 3048 const QRegister qd = instr->QdField(); |
3138 const QRegister qn = instr->QnField(); | 3049 const QRegister qn = instr->QnField(); |
3139 const QRegister qm = instr->QmField(); | 3050 const QRegister qm = instr->QmField(); |
3140 simd_value_t s8d; | 3051 simd_value_t s8d; |
3141 simd_value_t s8n; | 3052 simd_value_t s8n; |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3613 } | 3524 } |
3614 } | 3525 } |
3615 | 3526 |
3616 set_dregister_bits(dd, result); | 3527 set_dregister_bits(dd, result); |
3617 } else { | 3528 } else { |
3618 UnimplementedInstruction(instr); | 3529 UnimplementedInstruction(instr); |
3619 } | 3530 } |
3620 } | 3531 } |
3621 } | 3532 } |
3622 | 3533 |
3623 | |
3624 // Executes the current instruction. | 3534 // Executes the current instruction. |
3625 void Simulator::InstructionDecode(Instr* instr) { | 3535 void Simulator::InstructionDecode(Instr* instr) { |
3626 pc_modified_ = false; | 3536 pc_modified_ = false; |
3627 if (IsTracingExecution()) { | 3537 if (IsTracingExecution()) { |
3628 THR_Print("%" Pu64 " ", icount_); | 3538 THR_Print("%" Pu64 " ", icount_); |
3629 const uword start = reinterpret_cast<uword>(instr); | 3539 const uword start = reinterpret_cast<uword>(instr); |
3630 const uword end = start + Instr::kInstrSize; | 3540 const uword end = start + Instr::kInstrSize; |
3631 if (FLAG_support_disassembler) { | 3541 if (FLAG_support_disassembler) { |
3632 Disassembler::Disassemble(start, end); | 3542 Disassembler::Disassemble(start, end); |
3633 } else { | 3543 } else { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3681 UNREACHABLE(); | 3591 UNREACHABLE(); |
3682 break; | 3592 break; |
3683 } | 3593 } |
3684 } | 3594 } |
3685 } | 3595 } |
3686 if (!pc_modified_) { | 3596 if (!pc_modified_) { |
3687 set_register(PC, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize); | 3597 set_register(PC, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize); |
3688 } | 3598 } |
3689 } | 3599 } |
3690 | 3600 |
3691 | |
3692 void Simulator::Execute() { | 3601 void Simulator::Execute() { |
3693 // Get the PC to simulate. Cannot use the accessor here as we need the | 3602 // Get the PC to simulate. Cannot use the accessor here as we need the |
3694 // raw PC value and not the one used as input to arithmetic instructions. | 3603 // raw PC value and not the one used as input to arithmetic instructions. |
3695 uword program_counter = get_pc(); | 3604 uword program_counter = get_pc(); |
3696 | 3605 |
3697 if (FLAG_stop_sim_at == ULLONG_MAX) { | 3606 if (FLAG_stop_sim_at == ULLONG_MAX) { |
3698 // Fast version of the dispatch loop without checking whether the simulator | 3607 // Fast version of the dispatch loop without checking whether the simulator |
3699 // should be stopping at a particular executed instruction. | 3608 // should be stopping at a particular executed instruction. |
3700 while (program_counter != kEndSimulatingPC) { | 3609 while (program_counter != kEndSimulatingPC) { |
3701 Instr* instr = reinterpret_cast<Instr*>(program_counter); | 3610 Instr* instr = reinterpret_cast<Instr*>(program_counter); |
(...skipping 20 matching lines...) Expand all Loading... |
3722 } else if (IsIllegalAddress(program_counter)) { | 3631 } else if (IsIllegalAddress(program_counter)) { |
3723 HandleIllegalAccess(program_counter, instr); | 3632 HandleIllegalAccess(program_counter, instr); |
3724 } else { | 3633 } else { |
3725 InstructionDecode(instr); | 3634 InstructionDecode(instr); |
3726 } | 3635 } |
3727 program_counter = get_pc(); | 3636 program_counter = get_pc(); |
3728 } | 3637 } |
3729 } | 3638 } |
3730 } | 3639 } |
3731 | 3640 |
3732 | |
3733 int64_t Simulator::Call(int32_t entry, | 3641 int64_t Simulator::Call(int32_t entry, |
3734 int32_t parameter0, | 3642 int32_t parameter0, |
3735 int32_t parameter1, | 3643 int32_t parameter1, |
3736 int32_t parameter2, | 3644 int32_t parameter2, |
3737 int32_t parameter3, | 3645 int32_t parameter3, |
3738 bool fp_return, | 3646 bool fp_return, |
3739 bool fp_args) { | 3647 bool fp_args) { |
3740 // Save the SP register before the call so we can restore it. | 3648 // Save the SP register before the call so we can restore it. |
3741 int32_t sp_before_call = get_register(SP); | 3649 int32_t sp_before_call = get_register(SP); |
3742 | 3650 |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3884 int64_t return_value; | 3792 int64_t return_value; |
3885 if (fp_return) { | 3793 if (fp_return) { |
3886 ASSERT(TargetCPUFeatures::vfp_supported()); | 3794 ASSERT(TargetCPUFeatures::vfp_supported()); |
3887 return_value = bit_cast<int64_t, double>(get_dregister(D0)); | 3795 return_value = bit_cast<int64_t, double>(get_dregister(D0)); |
3888 } else { | 3796 } else { |
3889 return_value = Utils::LowHighTo64Bits(get_register(R0), get_register(R1)); | 3797 return_value = Utils::LowHighTo64Bits(get_register(R0), get_register(R1)); |
3890 } | 3798 } |
3891 return return_value; | 3799 return return_value; |
3892 } | 3800 } |
3893 | 3801 |
3894 | |
3895 void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) { | 3802 void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) { |
3896 // Walk over all setjmp buffers (simulated --> C++ transitions) | 3803 // Walk over all setjmp buffers (simulated --> C++ transitions) |
3897 // and try to find the setjmp associated with the simulated stack pointer. | 3804 // and try to find the setjmp associated with the simulated stack pointer. |
3898 SimulatorSetjmpBuffer* buf = last_setjmp_buffer(); | 3805 SimulatorSetjmpBuffer* buf = last_setjmp_buffer(); |
3899 while (buf->link() != NULL && buf->link()->sp() <= sp) { | 3806 while (buf->link() != NULL && buf->link()->sp() <= sp) { |
3900 buf = buf->link(); | 3807 buf = buf->link(); |
3901 } | 3808 } |
3902 ASSERT(buf != NULL); | 3809 ASSERT(buf != NULL); |
3903 | 3810 |
3904 // The C++ caller has not cleaned up the stack memory of C++ frames. | 3811 // The C++ caller has not cleaned up the stack memory of C++ frames. |
(...skipping 18 matching lines...) Expand all Loading... |
3923 set_register(CODE_REG, code); | 3830 set_register(CODE_REG, code); |
3924 set_register(PP, pp); | 3831 set_register(PP, pp); |
3925 buf->Longjmp(); | 3832 buf->Longjmp(); |
3926 } | 3833 } |
3927 | 3834 |
3928 } // namespace dart | 3835 } // namespace dart |
3929 | 3836 |
3930 #endif // defined(USING_SIMULATOR) | 3837 #endif // defined(USING_SIMULATOR) |
3931 | 3838 |
3932 #endif // defined TARGET_ARCH_ARM | 3839 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |