Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: runtime/vm/simulator_arm.cc

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/signal_handler_win.cc ('k') | runtime/vm/simulator_arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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", &reg_nr); 149 bool ok = SScanF(name, "s%d", &reg_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", &reg_nr); 158 bool ok = SScanF(name, "d%d", &reg_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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/signal_handler_win.cc ('k') | runtime/vm/simulator_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698