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

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

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month 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/simulator_mips.h ('k') | runtime/vm/snapshot.h » ('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_MIPS) 9 #if defined(TARGET_ARCH_MIPS)
10 10
11 // Only build the simulator if not compiling for real MIPS hardware. 11 // Only build the simulator if not compiling for real MIPS 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_mips.h" 17 #include "vm/constants_mips.h"
18 #include "vm/disassembler.h" 18 #include "vm/disassembler.h"
19 #include "vm/lockers.h" 19 #include "vm/lockers.h"
20 #include "vm/native_arguments.h" 20 #include "vm/native_arguments.h"
21 #include "vm/stack_frame.h" 21 #include "vm/stack_frame.h"
22 #include "vm/os_thread.h" 22 #include "vm/os_thread.h"
23 23
24 namespace dart { 24 namespace dart {
25 25
26 DEFINE_FLAG(uint64_t, trace_sim_after, ULLONG_MAX, 26 DEFINE_FLAG(uint64_t,
27 trace_sim_after,
28 ULLONG_MAX,
27 "Trace simulator execution after instruction count reached."); 29 "Trace simulator execution after instruction count reached.");
28 DEFINE_FLAG(uint64_t, stop_sim_at, ULLONG_MAX, 30 DEFINE_FLAG(uint64_t,
31 stop_sim_at,
32 ULLONG_MAX,
29 "Instruction address or instruction count to stop simulator at."); 33 "Instruction address or instruction count to stop simulator at.");
30 34
31 35
32 // 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
33 // SScanF not being implemented in a platform independent way through 37 // SScanF not being implemented in a platform independent way through
34 // 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
35 // Library does not provide vsscanf. 39 // Library does not provide vsscanf.
36 #define SScanF sscanf // NOLINT 40 #define SScanF sscanf // NOLINT
37 41
38 42
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 92
89 private: 93 private:
90 Simulator* sim_; 94 Simulator* sim_;
91 95
92 bool GetValue(char* desc, uint32_t* value); 96 bool GetValue(char* desc, uint32_t* value);
93 bool GetFValue(char* desc, double* value); 97 bool GetFValue(char* desc, double* value);
94 bool GetDValue(char* desc, double* value); 98 bool GetDValue(char* desc, double* value);
95 99
96 static TokenPosition GetApproximateTokenIndex(const Code& code, uword pc); 100 static TokenPosition GetApproximateTokenIndex(const Code& code, uword pc);
97 101
98 static void PrintDartFrame(uword pc, uword fp, uword sp, 102 static void PrintDartFrame(uword pc,
103 uword fp,
104 uword sp,
99 const Function& function, 105 const Function& function,
100 TokenPosition token_pos, 106 TokenPosition token_pos,
101 bool is_optimized, 107 bool is_optimized,
102 bool is_inlined); 108 bool is_inlined);
103 void PrintBacktrace(); 109 void PrintBacktrace();
104 110
105 // Set or delete a breakpoint. Returns true if successful. 111 // Set or delete a breakpoint. Returns true if successful.
106 bool SetBreakpoint(Instr* breakpc); 112 bool SetBreakpoint(Instr* breakpc);
107 bool DeleteBreakpoint(Instr* breakpc); 113 bool DeleteBreakpoint(Instr* breakpc);
108 114
109 // Undo and redo all breakpoints. This is needed to bracket disassembly and 115 // Undo and redo all breakpoints. This is needed to bracket disassembly and
110 // execution to skip past breakpoints when run from the debugger. 116 // execution to skip past breakpoints when run from the debugger.
111 void UndoBreakpoints(); 117 void UndoBreakpoints();
112 void RedoBreakpoints(); 118 void RedoBreakpoints();
113 }; 119 };
114 120
115 121
116 SimulatorDebugger::SimulatorDebugger(Simulator* sim) { 122 SimulatorDebugger::SimulatorDebugger(Simulator* sim) {
117 sim_ = sim; 123 sim_ = sim;
118 } 124 }
119 125
120 126
121 SimulatorDebugger::~SimulatorDebugger() { 127 SimulatorDebugger::~SimulatorDebugger() {}
122 }
123 128
124 129
125 void SimulatorDebugger::Stop(Instr* instr, const char* message) { 130 void SimulatorDebugger::Stop(Instr* instr, const char* message) {
126 OS::Print("Simulator hit %s\n", message); 131 OS::Print("Simulator hit %s\n", message);
127 Debug(); 132 Debug();
128 } 133 }
129 134
130 135
131 static Register LookupCpuRegisterByName(const char* name) { 136 static Register LookupCpuRegisterByName(const char* name) {
132 static const char* kNames[] = { 137 static const char* kNames[] = {
133 "r0", "r1", "r2", "r3", 138 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
134 "r4", "r5", "r6", "r7", 139 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
135 "r8", "r9", "r10", "r11", 140 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
136 "r12", "r13", "r14", "r15", 141 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
137 "r16", "r17", "r18", "r19",
138 "r20", "r21", "r22", "r23",
139 "r24", "r25", "r26", "r27",
140 "r28", "r29", "r30", "r31",
141 142
142 "zr", "at", "v0", "v1", 143 "zr", "at", "v0", "v1", "a0", "a1", "a2", "a3",
143 "a0", "a1", "a2", "a3", 144 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
144 "t0", "t1", "t2", "t3", 145 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
145 "t4", "t5", "t6", "t7", 146 "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"};
146 "s0", "s1", "s2", "s3",
147 "s4", "s5", "s6", "s7",
148 "t8", "t9", "k0", "k1",
149 "gp", "sp", "fp", "ra"
150 };
151 static const Register kRegisters[] = { 147 static const Register kRegisters[] = {
152 R0, R1, R2, R3, 148 R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10,
153 R4, R5, R6, R7, 149 R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21,
154 R8, R9, R10, R11, 150 R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
155 R12, R13, R14, R15,
156 R16, R17, R18, R19,
157 R20, R21, R22, R23,
158 R24, R25, R26, R27,
159 R28, R29, R30, R31,
160 151
161 ZR, AT, V0, V1, 152 ZR, AT, V0, V1, A0, A1, A2, A3, T0, T1, T2,
162 A0, A1, A2, A3, 153 T3, T4, T5, T6, T7, S0, S1, S2, S3, S4, S5,
163 T0, T1, T2, T3, 154 S6, S7, T8, T9, K0, K1, GP, SP, FP, RA};
164 T4, T5, T6, T7,
165 S0, S1, S2, S3,
166 S4, S5, S6, S7,
167 T8, T9, K0, K1,
168 GP, SP, FP, RA
169 };
170 ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters)); 155 ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters));
171 for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) { 156 for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) {
172 if (strcmp(kNames[i], name) == 0) { 157 if (strcmp(kNames[i], name) == 0) {
173 return kRegisters[i]; 158 return kRegisters[i];
174 } 159 }
175 } 160 }
176 return kNoRegister; 161 return kNoRegister;
177 } 162 }
178 163
179 164
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 } 234 }
250 *value = *(reinterpret_cast<double*>(addr)); 235 *value = *(reinterpret_cast<double*>(addr));
251 return true; 236 return true;
252 } 237 }
253 } 238 }
254 return false; 239 return false;
255 } 240 }
256 241
257 242
258 TokenPosition SimulatorDebugger::GetApproximateTokenIndex(const Code& code, 243 TokenPosition SimulatorDebugger::GetApproximateTokenIndex(const Code& code,
259 uword pc) { 244 uword pc) {
260 TokenPosition token_pos = TokenPosition::kNoSource; 245 TokenPosition token_pos = TokenPosition::kNoSource;
261 uword pc_offset = pc - code.PayloadStart(); 246 uword pc_offset = pc - code.PayloadStart();
262 const PcDescriptors& descriptors = 247 const PcDescriptors& descriptors =
263 PcDescriptors::Handle(code.pc_descriptors()); 248 PcDescriptors::Handle(code.pc_descriptors());
264 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); 249 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
265 while (iter.MoveNext()) { 250 while (iter.MoveNext()) {
266 if (iter.PcOffset() == pc_offset) { 251 if (iter.PcOffset() == pc_offset) {
267 return iter.TokenPos(); 252 return iter.TokenPos();
268 } else if (!token_pos.IsReal() && (iter.PcOffset() > pc_offset)) { 253 } else if (!token_pos.IsReal() && (iter.PcOffset() > pc_offset)) {
269 token_pos = iter.TokenPos(); 254 token_pos = iter.TokenPos();
270 } 255 }
271 } 256 }
272 return token_pos; 257 return token_pos;
273 } 258 }
274 259
275 260
276 void SimulatorDebugger::PrintDartFrame(uword pc, uword fp, uword sp, 261 void SimulatorDebugger::PrintDartFrame(uword pc,
262 uword fp,
263 uword sp,
277 const Function& function, 264 const Function& function,
278 TokenPosition token_pos, 265 TokenPosition token_pos,
279 bool is_optimized, 266 bool is_optimized,
280 bool is_inlined) { 267 bool is_inlined) {
281 const Script& script = Script::Handle(function.script()); 268 const Script& script = Script::Handle(function.script());
282 const String& func_name = String::Handle(function.QualifiedScrubbedName()); 269 const String& func_name = String::Handle(function.QualifiedScrubbedName());
283 const String& url = String::Handle(script.url()); 270 const String& url = String::Handle(script.url());
284 intptr_t line = -1; 271 intptr_t line = -1;
285 intptr_t column = -1; 272 intptr_t column = -1;
286 if (token_pos.IsReal()) { 273 if (token_pos.IsReal()) {
287 script.GetTokenLocation(token_pos, &line, &column); 274 script.GetTokenLocation(token_pos, &line, &column);
288 } 275 }
289 OS::Print("pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd 276 OS::Print(
290 ":%" Pd ")\n", 277 "pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd ":%" Pd ")\n", pc,
291 pc, fp, sp, 278 fp, sp, is_optimized ? (is_inlined ? "inlined " : "optimized ") : "",
292 is_optimized ? (is_inlined ? "inlined " : "optimized ") : "", 279 func_name.ToCString(), url.ToCString(), line, column);
293 func_name.ToCString(),
294 url.ToCString(),
295 line, column);
296 } 280 }
297 281
298 282
299 void SimulatorDebugger::PrintBacktrace() { 283 void SimulatorDebugger::PrintBacktrace() {
300 StackFrameIterator frames(sim_->get_register(FP), 284 StackFrameIterator frames(sim_->get_register(FP), sim_->get_register(SP),
301 sim_->get_register(SP),
302 sim_->get_pc(), 285 sim_->get_pc(),
303 StackFrameIterator::kDontValidateFrames); 286 StackFrameIterator::kDontValidateFrames);
304 StackFrame* frame = frames.NextFrame(); 287 StackFrame* frame = frames.NextFrame();
305 ASSERT(frame != NULL); 288 ASSERT(frame != NULL);
306 Function& function = Function::Handle(); 289 Function& function = Function::Handle();
307 Function& inlined_function = Function::Handle(); 290 Function& inlined_function = Function::Handle();
308 Code& code = Code::Handle(); 291 Code& code = Code::Handle();
309 Code& unoptimized_code = Code::Handle(); 292 Code& unoptimized_code = Code::Handle();
310 while (frame != NULL) { 293 while (frame != NULL) {
311 if (frame->IsDartFrame()) { 294 if (frame->IsDartFrame()) {
312 code = frame->LookupDartCode(); 295 code = frame->LookupDartCode();
313 function = code.function(); 296 function = code.function();
314 if (code.is_optimized()) { 297 if (code.is_optimized()) {
315 // For optimized frames, extract all the inlined functions if any 298 // For optimized frames, extract all the inlined functions if any
316 // into the stack trace. 299 // into the stack trace.
317 InlinedFunctionsIterator it(code, frame->pc()); 300 InlinedFunctionsIterator it(code, frame->pc());
318 while (!it.Done()) { 301 while (!it.Done()) {
319 // Print each inlined frame with its pc in the corresponding 302 // Print each inlined frame with its pc in the corresponding
320 // unoptimized frame. 303 // unoptimized frame.
321 inlined_function = it.function(); 304 inlined_function = it.function();
322 unoptimized_code = it.code(); 305 unoptimized_code = it.code();
323 uword unoptimized_pc = it.pc(); 306 uword unoptimized_pc = it.pc();
324 it.Advance(); 307 it.Advance();
325 if (!it.Done()) { 308 if (!it.Done()) {
326 PrintDartFrame(unoptimized_pc, frame->fp(), frame->sp(), 309 PrintDartFrame(
327 inlined_function, 310 unoptimized_pc, frame->fp(), frame->sp(), inlined_function,
328 GetApproximateTokenIndex(unoptimized_code, 311 GetApproximateTokenIndex(unoptimized_code, unoptimized_pc),
329 unoptimized_pc), 312 true, true);
330 true, true);
331 } 313 }
332 } 314 }
333 // Print the optimized inlining frame below. 315 // Print the optimized inlining frame below.
334 } 316 }
335 PrintDartFrame(frame->pc(), frame->fp(), frame->sp(), 317 PrintDartFrame(frame->pc(), frame->fp(), frame->sp(), function,
336 function,
337 GetApproximateTokenIndex(code, frame->pc()), 318 GetApproximateTokenIndex(code, frame->pc()),
338 code.is_optimized(), false); 319 code.is_optimized(), false);
339 } else { 320 } else {
340 OS::Print("pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s frame\n", 321 OS::Print("pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s frame\n",
341 frame->pc(), frame->fp(), frame->sp(), 322 frame->pc(), frame->fp(), frame->sp(),
342 frame->IsEntryFrame() ? "entry" : 323 frame->IsEntryFrame()
343 frame->IsExitFrame() ? "exit" : 324 ? "entry"
344 frame->IsStubFrame() ? "stub" : "invalid"); 325 : frame->IsExitFrame()
326 ? "exit"
327 : frame->IsStubFrame() ? "stub" : "invalid");
345 } 328 }
346 frame = frames.NextFrame(); 329 frame = frames.NextFrame();
347 } 330 }
348 } 331 }
349 332
350 333
351 bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) { 334 bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) {
352 // Check if a breakpoint can be set. If not return without any side-effects. 335 // Check if a breakpoint can be set. If not return without any side-effects.
353 if (sim_->break_pc_ != NULL) { 336 if (sim_->break_pc_ != NULL) {
354 return false; 337 return false;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 FATAL("ReadLine failed"); 412 FATAL("ReadLine failed");
430 } else { 413 } else {
431 // Use sscanf to parse the individual parts of the command line. At the 414 // Use sscanf to parse the individual parts of the command line. At the
432 // moment no command expects more than two parameters. 415 // moment no command expects more than two parameters.
433 int args = SScanF(line, 416 int args = SScanF(line,
434 "%" XSTR(COMMAND_SIZE) "s " 417 "%" XSTR(COMMAND_SIZE) "s "
435 "%" XSTR(ARG_SIZE) "s " 418 "%" XSTR(ARG_SIZE) "s "
436 "%" XSTR(ARG_SIZE) "s", 419 "%" XSTR(ARG_SIZE) "s",
437 cmd, arg1, arg2); 420 cmd, arg1, arg2);
438 if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) { 421 if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
439 OS::Print("c/cont -- continue execution\n" 422 OS::Print(
440 "disasm -- disassemble instrs at current pc location\n" 423 "c/cont -- continue execution\n"
441 " other variants are:\n" 424 "disasm -- disassemble instrs at current pc location\n"
442 " disasm <address>\n" 425 " other variants are:\n"
443 " disasm <address> <number_of_instructions>\n" 426 " disasm <address>\n"
444 " by default 10 instrs are disassembled\n" 427 " disasm <address> <number_of_instructions>\n"
445 "del -- delete breakpoints\n" 428 " by default 10 instrs are disassembled\n"
446 "gdb -- transfer control to gdb\n" 429 "del -- delete breakpoints\n"
447 "h/help -- print this help string\n" 430 "gdb -- transfer control to gdb\n"
448 "break <address> -- set break point at specified address\n" 431 "h/help -- print this help string\n"
449 "p/print <reg or icount or value or *addr> -- print integer\n" 432 "break <address> -- set break point at specified address\n"
450 "pf/printfloat <freg or *addr> -- print float value\n" 433 "p/print <reg or icount or value or *addr> -- print integer\n"
451 "po/printobject <*reg or *addr> -- print object\n" 434 "pf/printfloat <freg or *addr> -- print float value\n"
452 "si/stepi -- single step an instruction\n" 435 "po/printobject <*reg or *addr> -- print object\n"
453 "trace -- toggle execution tracing mode\n" 436 "si/stepi -- single step an instruction\n"
454 "bt -- print backtrace\n" 437 "trace -- toggle execution tracing mode\n"
455 "unstop -- if current pc is a stop instr make it a nop\n" 438 "bt -- print backtrace\n"
456 "q/quit -- Quit the debugger and exit the program\n"); 439 "unstop -- if current pc is a stop instr make it a nop\n"
440 "q/quit -- Quit the debugger and exit the program\n");
457 } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) { 441 } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) {
458 OS::Print("Quitting\n"); 442 OS::Print("Quitting\n");
459 OS::Exit(0); 443 OS::Exit(0);
460 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { 444 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
461 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 445 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
462 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { 446 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
463 // Execute the one instruction we broke at with breakpoints disabled. 447 // Execute the one instruction we broke at with breakpoints disabled.
464 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 448 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
465 // Leave the debugger shell. 449 // Leave the debugger shell.
466 done = true; 450 done = true;
467 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { 451 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
468 if (args == 2) { 452 if (args == 2) {
469 uint32_t value; 453 uint32_t value;
470 if (strcmp(arg1, "icount") == 0) { 454 if (strcmp(arg1, "icount") == 0) {
471 const uint64_t icount = sim_->get_icount(); 455 const uint64_t icount = sim_->get_icount();
472 OS::Print("icount: %" Pu64 " 0x%" Px64 "\n", icount, icount); 456 OS::Print("icount: %" Pu64 " 0x%" Px64 "\n", icount, icount);
473 } else if (GetValue(arg1, &value)) { 457 } else if (GetValue(arg1, &value)) {
474 OS::Print("%s: %u 0x%x\n", arg1, value, value); 458 OS::Print("%s: %u 0x%x\n", arg1, value, value);
475 } else { 459 } else {
476 OS::Print("%s unrecognized\n", arg1); 460 OS::Print("%s unrecognized\n", arg1);
477 } 461 }
478 } else { 462 } else {
479 OS::Print("print <reg or icount or value or *addr>\n"); 463 OS::Print("print <reg or icount or value or *addr>\n");
480 } 464 }
481 } else if ((strcmp(cmd, "pf") == 0) || 465 } else if ((strcmp(cmd, "pf") == 0) || (strcmp(cmd, "printfloat") == 0)) {
482 (strcmp(cmd, "printfloat") == 0)) {
483 if (args == 2) { 466 if (args == 2) {
484 double dvalue; 467 double dvalue;
485 if (GetFValue(arg1, &dvalue)) { 468 if (GetFValue(arg1, &dvalue)) {
486 uint64_t long_value = bit_cast<uint64_t, double>(dvalue); 469 uint64_t long_value = bit_cast<uint64_t, double>(dvalue);
487 OS::Print("%s: %llu 0x%llx %.8g\n", 470 OS::Print("%s: %llu 0x%llx %.8g\n", arg1, long_value, long_value,
488 arg1, long_value, long_value, dvalue); 471 dvalue);
489 } else { 472 } else {
490 OS::Print("%s unrecognized\n", arg1); 473 OS::Print("%s unrecognized\n", arg1);
491 } 474 }
492 } else { 475 } else {
493 OS::Print("printfloat <dreg or *addr>\n"); 476 OS::Print("printfloat <dreg or *addr>\n");
494 } 477 }
495 } else if ((strcmp(cmd, "pd") == 0) || 478 } else if ((strcmp(cmd, "pd") == 0) ||
496 (strcmp(cmd, "printdouble") == 0)) { 479 (strcmp(cmd, "printdouble") == 0)) {
497 if (args == 2) { 480 if (args == 2) {
498 double dvalue; 481 double dvalue;
499 if (GetDValue(arg1, &dvalue)) { 482 if (GetDValue(arg1, &dvalue)) {
500 uint64_t long_value = bit_cast<uint64_t, double>(dvalue); 483 uint64_t long_value = bit_cast<uint64_t, double>(dvalue);
501 OS::Print("%s: %llu 0x%llx %.8g\n", 484 OS::Print("%s: %llu 0x%llx %.8g\n", arg1, long_value, long_value,
502 arg1, long_value, long_value, dvalue); 485 dvalue);
503 } else { 486 } else {
504 OS::Print("%s unrecognized\n", arg1); 487 OS::Print("%s unrecognized\n", arg1);
505 } 488 }
506 } else { 489 } else {
507 OS::Print("printfloat <dreg or *addr>\n"); 490 OS::Print("printfloat <dreg or *addr>\n");
508 } 491 }
509 } else if ((strcmp(cmd, "po") == 0) || 492 } else if ((strcmp(cmd, "po") == 0) ||
510 (strcmp(cmd, "printobject") == 0)) { 493 (strcmp(cmd, "printobject") == 0)) {
511 if (args == 2) { 494 if (args == 2) {
512 uint32_t value; 495 uint32_t value;
513 // Make the dereferencing '*' optional. 496 // Make the dereferencing '*' optional.
514 if (((arg1[0] == '*') && GetValue(arg1 + 1, &value)) || 497 if (((arg1[0] == '*') && GetValue(arg1 + 1, &value)) ||
515 GetValue(arg1, &value)) { 498 GetValue(arg1, &value)) {
516 if (Isolate::Current()->heap()->Contains(value)) { 499 if (Isolate::Current()->heap()->Contains(value)) {
517 OS::Print("%s: \n", arg1); 500 OS::Print("%s: \n", arg1);
518 #if defined(DEBUG) 501 #if defined(DEBUG)
519 const Object& obj = Object::Handle( 502 const Object& obj =
520 reinterpret_cast<RawObject*>(value)); 503 Object::Handle(reinterpret_cast<RawObject*>(value));
521 obj.Print(); 504 obj.Print();
522 #endif // defined(DEBUG) 505 #endif // defined(DEBUG)
523 } else { 506 } else {
524 OS::Print("0x%x is not an object reference\n", value); 507 OS::Print("0x%x is not an object reference\n", value);
525 } 508 }
526 } else { 509 } else {
527 OS::Print("%s unrecognized\n", arg1); 510 OS::Print("%s unrecognized\n", arg1);
528 } 511 }
529 } else { 512 } else {
530 OS::Print("printobject <*reg or *addr>\n"); 513 OS::Print("printobject <*reg or *addr>\n");
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 OS::Print("%s", prompt); 616 OS::Print("%s", prompt);
634 while (keep_going) { 617 while (keep_going) {
635 if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) { 618 if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
636 // fgets got an error. Just give up. 619 // fgets got an error. Just give up.
637 if (result != NULL) { 620 if (result != NULL) {
638 delete[] result; 621 delete[] result;
639 } 622 }
640 return NULL; 623 return NULL;
641 } 624 }
642 intptr_t len = strlen(line_buf); 625 intptr_t len = strlen(line_buf);
643 if (len > 1 && 626 if (len > 1 && line_buf[len - 2] == '\\' && line_buf[len - 1] == '\n') {
644 line_buf[len - 2] == '\\' &&
645 line_buf[len - 1] == '\n') {
646 // When we read a line that ends with a "\" we remove the escape and 627 // When we read a line that ends with a "\" we remove the escape and
647 // append the remainder. 628 // append the remainder.
648 line_buf[len - 2] = '\n'; 629 line_buf[len - 2] = '\n';
649 line_buf[len - 1] = 0; 630 line_buf[len - 1] = 0;
650 len -= 1; 631 len -= 1;
651 } else if ((len > 0) && (line_buf[len - 1] == '\n')) { 632 } else if ((len > 0) && (line_buf[len - 1] == '\n')) {
652 // Since we read a new line we are done reading the line. This 633 // Since we read a new line we are done reading the line. This
653 // will exit the loop after copying this buffer into the result. 634 // will exit the loop after copying this buffer into the result.
654 keep_going = false; 635 keep_going = false;
655 } 636 }
(...skipping 25 matching lines...) Expand all
681 offset += len; 662 offset += len;
682 } 663 }
683 ASSERT(result != NULL); 664 ASSERT(result != NULL);
684 result[offset] = '\0'; 665 result[offset] = '\0';
685 return result; 666 return result;
686 } 667 }
687 668
688 669
689 // Synchronization primitives support. 670 // Synchronization primitives support.
690 Mutex* Simulator::exclusive_access_lock_ = NULL; 671 Mutex* Simulator::exclusive_access_lock_ = NULL;
691 Simulator::AddressTag Simulator::exclusive_access_state_[kNumAddressTags] = 672 Simulator::AddressTag Simulator::exclusive_access_state_[kNumAddressTags] = {
692 {{NULL, 0}}; 673 {NULL, 0}};
693 int Simulator::next_address_tag_ = 0; 674 int Simulator::next_address_tag_ = 0;
694 675
695 676
696 void Simulator::InitOnce() { 677 void Simulator::InitOnce() {
697 // Setup exclusive access state lock. 678 // Setup exclusive access state lock.
698 exclusive_access_lock_ = new Mutex(); 679 exclusive_access_lock_ = new Mutex();
699 } 680 }
700 681
701 682
702 Simulator::Simulator() { 683 Simulator::Simulator() {
703 // Setup simulator support first. Some of this information is needed to 684 // Setup simulator support first. Some of this information is needed to
704 // setup the architecture state. 685 // setup the architecture state.
705 // We allocate the stack here, the size is computed as the sum of 686 // We allocate the stack here, the size is computed as the sum of
706 // the size specified by the user and the buffer space needed for 687 // the size specified by the user and the buffer space needed for
707 // handling stack overflow exceptions. To be safe in potential 688 // handling stack overflow exceptions. To be safe in potential
708 // stack underflows we also add some underflow buffer space. 689 // stack underflows we also add some underflow buffer space.
709 stack_ = new char[(OSThread::GetSpecifiedStackSize() + 690 stack_ =
710 OSThread::kStackSizeBuffer + 691 new char[(OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer +
711 kSimulatorStackUnderflowSize)]; 692 kSimulatorStackUnderflowSize)];
712 icount_ = 0; 693 icount_ = 0;
713 delay_slot_ = false; 694 delay_slot_ = false;
714 break_pc_ = NULL; 695 break_pc_ = NULL;
715 break_instr_ = 0; 696 break_instr_ = 0;
716 last_setjmp_buffer_ = NULL; 697 last_setjmp_buffer_ = NULL;
717 top_exit_frame_info_ = 0; 698 top_exit_frame_info_ = 0;
718 699
719 // Setup architecture state. 700 // Setup architecture state.
720 // All registers are initialized to zero to start with. 701 // All registers are initialized to zero to start with.
721 for (int i = 0; i < kNumberOfCpuRegisters; i++) { 702 for (int i = 0; i < kNumberOfCpuRegisters; i++) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 : external_function_(external_function), 777 : external_function_(external_function),
797 call_kind_(call_kind), 778 call_kind_(call_kind),
798 argument_count_(argument_count), 779 argument_count_(argument_count),
799 break_instruction_(Instr::kSimulatorRedirectInstruction), 780 break_instruction_(Instr::kSimulatorRedirectInstruction),
800 next_(list_) { 781 next_(list_) {
801 // Atomically prepend this element to the front of the global list. 782 // Atomically prepend this element to the front of the global list.
802 // Note: Since elements are never removed, there is no ABA issue. 783 // Note: Since elements are never removed, there is no ABA issue.
803 Redirection* list_head = list_; 784 Redirection* list_head = list_;
804 do { 785 do {
805 next_ = list_head; 786 next_ = list_head;
806 list_head = reinterpret_cast<Redirection*>( 787 list_head =
807 AtomicOperations::CompareAndSwapWord( 788 reinterpret_cast<Redirection*>(AtomicOperations::CompareAndSwapWord(
808 reinterpret_cast<uword*>(&list_), 789 reinterpret_cast<uword*>(&list_), reinterpret_cast<uword>(next_),
809 reinterpret_cast<uword>(next_),
810 reinterpret_cast<uword>(this))); 790 reinterpret_cast<uword>(this)));
811 } while (list_head != next_); 791 } while (list_head != next_);
812 } 792 }
813 793
814 uword external_function_; 794 uword external_function_;
815 Simulator::CallKind call_kind_; 795 Simulator::CallKind call_kind_;
816 int argument_count_; 796 int argument_count_;
817 uint32_t break_instruction_; 797 uint32_t break_instruction_;
818 Redirection* next_; 798 Redirection* next_;
819 static Redirection* list_; 799 static Redirection* list_;
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 FATAL("Cannot continue execution after unimplemented instruction."); 949 FATAL("Cannot continue execution after unimplemented instruction.");
970 } 950 }
971 951
972 952
973 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) { 953 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) {
974 uword fault_pc = get_pc(); 954 uword fault_pc = get_pc();
975 // The debugger will not be able to single step past this instruction, but 955 // The debugger will not be able to single step past this instruction, but
976 // it will be possible to disassemble the code and inspect registers. 956 // it will be possible to disassemble the code and inspect registers.
977 char buffer[128]; 957 char buffer[128];
978 snprintf(buffer, sizeof(buffer), 958 snprintf(buffer, sizeof(buffer),
979 "illegal memory access at 0x%" Px ", pc=0x%" Px "\n", 959 "illegal memory access at 0x%" Px ", pc=0x%" Px "\n", addr,
980 addr, fault_pc); 960 fault_pc);
981 SimulatorDebugger dbg(this); 961 SimulatorDebugger dbg(this);
982 dbg.Stop(instr, buffer); 962 dbg.Stop(instr, buffer);
983 // The debugger will return control in non-interactive mode. 963 // The debugger will return control in non-interactive mode.
984 FATAL("Cannot continue execution after illegal memory access."); 964 FATAL("Cannot continue execution after illegal memory access.");
985 } 965 }
986 966
987 967
988 void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) { 968 void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) {
989 // The debugger will not be able to single step past this instruction, but 969 // The debugger will not be able to single step past this instruction, but
990 // it will be possible to disassemble the code and inspect registers. 970 // it will be possible to disassemble the code and inspect registers.
991 char buffer[128]; 971 char buffer[128];
992 snprintf(buffer, sizeof(buffer), 972 snprintf(buffer, sizeof(buffer), "pc=%p, unaligned %s at 0x%" Px "\n", instr,
993 "pc=%p, unaligned %s at 0x%" Px "\n", instr, msg, addr); 973 msg, addr);
994 SimulatorDebugger dbg(this); 974 SimulatorDebugger dbg(this);
995 dbg.Stop(instr, buffer); 975 dbg.Stop(instr, buffer);
996 // The debugger will return control in non-interactive mode. 976 // The debugger will return control in non-interactive mode.
997 FATAL("Cannot continue execution after unaligned access."); 977 FATAL("Cannot continue execution after unaligned access.");
998 } 978 }
999 979
1000 980
1001 // Returns the top of the stack area to enable checking for stack pointer 981 // Returns the top of the stack area to enable checking for stack pointer
1002 // validity. 982 // validity.
1003 uword Simulator::StackTop() const { 983 uword Simulator::StackTop() const {
1004 // To be safe in potential stack underflows we leave some buffer above and 984 // To be safe in potential stack underflows we leave some buffer above and
1005 // set the stack top. 985 // set the stack top.
1006 return StackBase() + 986 return StackBase() +
1007 (OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer); 987 (OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer);
1008 } 988 }
1009 989
1010 990
1011 bool Simulator::IsTracingExecution() const { 991 bool Simulator::IsTracingExecution() const {
1012 return icount_ > FLAG_trace_sim_after; 992 return icount_ > FLAG_trace_sim_after;
1013 } 993 }
1014 994
1015 995
1016 void Simulator::Format(Instr* instr, const char* format) { 996 void Simulator::Format(Instr* instr, const char* format) {
1017 OS::PrintErr("Simulator - unknown instruction: %s\n", format); 997 OS::PrintErr("Simulator - unknown instruction: %s\n", format);
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1205 return CompareExchange(reinterpret_cast<uword*>(address), 1185 return CompareExchange(reinterpret_cast<uword*>(address),
1206 static_cast<uword>(compare_value), 1186 static_cast<uword>(compare_value),
1207 static_cast<uword>(new_value)); 1187 static_cast<uword>(new_value));
1208 } 1188 }
1209 1189
1210 1190
1211 // Calls into the Dart runtime are based on this interface. 1191 // Calls into the Dart runtime are based on this interface.
1212 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments); 1192 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments);
1213 1193
1214 // Calls to leaf Dart runtime functions are based on this interface. 1194 // Calls to leaf Dart runtime functions are based on this interface.
1215 typedef int32_t (*SimulatorLeafRuntimeCall)( 1195 typedef int32_t (*SimulatorLeafRuntimeCall)(int32_t r0,
1216 int32_t r0, int32_t r1, int32_t r2, int32_t r3); 1196 int32_t r1,
1197 int32_t r2,
1198 int32_t r3);
1217 1199
1218 // Calls to leaf float Dart runtime functions are based on this interface. 1200 // Calls to leaf float Dart runtime functions are based on this interface.
1219 typedef double (*SimulatorLeafFloatRuntimeCall)(double d0, double d1); 1201 typedef double (*SimulatorLeafFloatRuntimeCall)(double d0, double d1);
1220 1202
1221 // Calls to native Dart functions are based on this interface. 1203 // Calls to native Dart functions are based on this interface.
1222 typedef void (*SimulatorBootstrapNativeCall)(NativeArguments* arguments); 1204 typedef void (*SimulatorBootstrapNativeCall)(NativeArguments* arguments);
1223 typedef void (*SimulatorNativeCall)(NativeArguments* arguments, uword target); 1205 typedef void (*SimulatorNativeCall)(NativeArguments* arguments, uword target);
1224 1206
1225 1207
1226 void Simulator::DoBreak(Instr *instr) { 1208 void Simulator::DoBreak(Instr* instr) {
1227 ASSERT(instr->OpcodeField() == SPECIAL); 1209 ASSERT(instr->OpcodeField() == SPECIAL);
1228 ASSERT(instr->FunctionField() == BREAK); 1210 ASSERT(instr->FunctionField() == BREAK);
1229 if (instr->BreakCodeField() == Instr::kStopMessageCode) { 1211 if (instr->BreakCodeField() == Instr::kStopMessageCode) {
1230 SimulatorDebugger dbg(this); 1212 SimulatorDebugger dbg(this);
1231 const char* message = *reinterpret_cast<const char**>( 1213 const char* message = *reinterpret_cast<const char**>(
1232 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize); 1214 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize);
1233 set_pc(get_pc() + Instr::kInstrSize); 1215 set_pc(get_pc() + Instr::kInstrSize);
1234 dbg.Stop(instr, message); 1216 dbg.Stop(instr, message);
1235 // Adjust for extra pc increment. 1217 // Adjust for extra pc increment.
1236 set_pc(get_pc() - Instr::kInstrSize); 1218 set_pc(get_pc() - Instr::kInstrSize);
1237 } else if (instr->BreakCodeField() == Instr::kSimulatorRedirectCode) { 1219 } else if (instr->BreakCodeField() == Instr::kSimulatorRedirectCode) {
1238 SimulatorSetjmpBuffer buffer(this); 1220 SimulatorSetjmpBuffer buffer(this);
1239 1221
1240 if (!setjmp(buffer.buffer_)) { 1222 if (!setjmp(buffer.buffer_)) {
1241 int32_t saved_ra = get_register(RA); 1223 int32_t saved_ra = get_register(RA);
1242 Redirection* redirection = Redirection::FromBreakInstruction(instr); 1224 Redirection* redirection = Redirection::FromBreakInstruction(instr);
1243 uword external = redirection->external_function(); 1225 uword external = redirection->external_function();
1244 if (IsTracingExecution()) { 1226 if (IsTracingExecution()) {
1245 THR_Print("Call to host function at 0x%" Pd "\n", external); 1227 THR_Print("Call to host function at 0x%" Pd "\n", external);
1246 } 1228 }
1247 1229
1248 if ((redirection->call_kind() == kRuntimeCall) || 1230 if ((redirection->call_kind() == kRuntimeCall) ||
1249 (redirection->call_kind() == kBootstrapNativeCall) || 1231 (redirection->call_kind() == kBootstrapNativeCall) ||
1250 (redirection->call_kind() == kNativeCall)) { 1232 (redirection->call_kind() == kNativeCall)) {
1251 // Set the top_exit_frame_info of this simulator to the native stack. 1233 // Set the top_exit_frame_info of this simulator to the native stack.
1252 set_top_exit_frame_info(Thread::GetCurrentStackPointer()); 1234 set_top_exit_frame_info(Thread::GetCurrentStackPointer());
1253 } 1235 }
1254 if (redirection->call_kind() == kRuntimeCall) { 1236 if (redirection->call_kind() == kRuntimeCall) {
1255 NativeArguments arguments; 1237 NativeArguments arguments;
1256 ASSERT(sizeof(NativeArguments) == 4*kWordSize); 1238 ASSERT(sizeof(NativeArguments) == 4 * kWordSize);
1257 arguments.thread_ = reinterpret_cast<Thread*>(get_register(A0)); 1239 arguments.thread_ = reinterpret_cast<Thread*>(get_register(A0));
1258 arguments.argc_tag_ = get_register(A1); 1240 arguments.argc_tag_ = get_register(A1);
1259 arguments.argv_ = reinterpret_cast<RawObject**>(get_register(A2)); 1241 arguments.argv_ = reinterpret_cast<RawObject**>(get_register(A2));
1260 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(A3)); 1242 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(A3));
1261 SimulatorRuntimeCall target = 1243 SimulatorRuntimeCall target =
1262 reinterpret_cast<SimulatorRuntimeCall>(external); 1244 reinterpret_cast<SimulatorRuntimeCall>(external);
1263 target(arguments); 1245 target(arguments);
1264 set_register(V0, icount_); // Zap result registers from void function. 1246 set_register(V0, icount_); // Zap result registers from void function.
1265 set_register(V1, icount_); 1247 set_register(V1, icount_);
1266 } else if (redirection->call_kind() == kLeafRuntimeCall) { 1248 } else if (redirection->call_kind() == kLeafRuntimeCall) {
1267 int32_t a0 = get_register(A0); 1249 int32_t a0 = get_register(A0);
1268 int32_t a1 = get_register(A1); 1250 int32_t a1 = get_register(A1);
1269 int32_t a2 = get_register(A2); 1251 int32_t a2 = get_register(A2);
1270 int32_t a3 = get_register(A3); 1252 int32_t a3 = get_register(A3);
1271 SimulatorLeafRuntimeCall target = 1253 SimulatorLeafRuntimeCall target =
1272 reinterpret_cast<SimulatorLeafRuntimeCall>(external); 1254 reinterpret_cast<SimulatorLeafRuntimeCall>(external);
1273 a0 = target(a0, a1, a2, a3); 1255 a0 = target(a0, a1, a2, a3);
1274 set_register(V0, a0); // Set returned result from function. 1256 set_register(V0, a0); // Set returned result from function.
1275 set_register(V1, icount_); // Zap second result register. 1257 set_register(V1, icount_); // Zap second result register.
1276 } else if (redirection->call_kind() == kLeafFloatRuntimeCall) { 1258 } else if (redirection->call_kind() == kLeafFloatRuntimeCall) {
1277 ASSERT((0 <= redirection->argument_count()) && 1259 ASSERT((0 <= redirection->argument_count()) &&
1278 (redirection->argument_count() <= 2)); 1260 (redirection->argument_count() <= 2));
1279 // double values are passed and returned in floating point registers. 1261 // double values are passed and returned in floating point registers.
1280 SimulatorLeafFloatRuntimeCall target = 1262 SimulatorLeafFloatRuntimeCall target =
1281 reinterpret_cast<SimulatorLeafFloatRuntimeCall>(external); 1263 reinterpret_cast<SimulatorLeafFloatRuntimeCall>(external);
1282 double d0 = 0.0; 1264 double d0 = 0.0;
1283 double d6 = get_fregister_double(F12); 1265 double d6 = get_fregister_double(F12);
1284 double d7 = get_fregister_double(F14); 1266 double d7 = get_fregister_double(F14);
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 } 1399 }
1418 set_lo_register(rs_val / rt_val); 1400 set_lo_register(rs_val / rt_val);
1419 set_hi_register(rs_val % rt_val); 1401 set_hi_register(rs_val % rt_val);
1420 break; 1402 break;
1421 } 1403 }
1422 case JALR: { 1404 case JALR: {
1423 ASSERT(instr->RtField() == R0); 1405 ASSERT(instr->RtField() == R0);
1424 ASSERT(instr->RsField() != instr->RdField()); 1406 ASSERT(instr->RsField() != instr->RdField());
1425 ASSERT(!delay_slot_); 1407 ASSERT(!delay_slot_);
1426 // Format(instr, "jalr'hint 'rd, rs"); 1408 // Format(instr, "jalr'hint 'rd, rs");
1427 set_register(instr->RdField(), pc_ + 2*Instr::kInstrSize); 1409 set_register(instr->RdField(), pc_ + 2 * Instr::kInstrSize);
1428 uword next_pc = get_register(instr->RsField()); 1410 uword next_pc = get_register(instr->RsField());
1429 ExecuteDelaySlot(); 1411 ExecuteDelaySlot();
1430 // Set return address to be the instruction after the delay slot. 1412 // Set return address to be the instruction after the delay slot.
1431 pc_ = next_pc - Instr::kInstrSize; // Account for regular PC increment. 1413 pc_ = next_pc - Instr::kInstrSize; // Account for regular PC increment.
1432 break; 1414 break;
1433 } 1415 }
1434 case JR: { 1416 case JR: {
1435 ASSERT(instr->RtField() == R0); 1417 ASSERT(instr->RtField() == R0);
1436 ASSERT(instr->RdField() == R0); 1418 ASSERT(instr->RdField() == R0);
1437 ASSERT(!delay_slot_); 1419 ASSERT(!delay_slot_);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1540 case OR: { 1522 case OR: {
1541 ASSERT(instr->SaField() == 0); 1523 ASSERT(instr->SaField() == 0);
1542 // Format(instr, "or 'rd, 'rs, 'rt"); 1524 // Format(instr, "or 'rd, 'rs, 'rt");
1543 int32_t rs_val = get_register(instr->RsField()); 1525 int32_t rs_val = get_register(instr->RsField());
1544 int32_t rt_val = get_register(instr->RtField()); 1526 int32_t rt_val = get_register(instr->RtField());
1545 set_register(instr->RdField(), rs_val | rt_val); 1527 set_register(instr->RdField(), rs_val | rt_val);
1546 break; 1528 break;
1547 } 1529 }
1548 case SLL: { 1530 case SLL: {
1549 ASSERT(instr->RsField() == 0); 1531 ASSERT(instr->RsField() == 0);
1550 if ((instr->RdField() == R0) && 1532 if ((instr->RdField() == R0) && (instr->RtField() == R0) &&
1551 (instr->RtField() == R0) &&
1552 (instr->SaField() == 0)) { 1533 (instr->SaField() == 0)) {
1553 // Format(instr, "nop"); 1534 // Format(instr, "nop");
1554 // Nothing to be done for NOP. 1535 // Nothing to be done for NOP.
1555 } else { 1536 } else {
1556 int32_t rt_val = get_register(instr->RtField()); 1537 int32_t rt_val = get_register(instr->RtField());
1557 int sa = instr->SaField(); 1538 int sa = instr->SaField();
1558 set_register(instr->RdField(), rt_val << sa); 1539 set_register(instr->RdField(), rt_val << sa);
1559 } 1540 }
1560 break; 1541 break;
1561 } 1542 }
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1738 switch (instr->RegImmFnField()) { 1719 switch (instr->RegImmFnField()) {
1739 case BGEZ: { 1720 case BGEZ: {
1740 // Format(instr, "bgez 'rs, 'dest"); 1721 // Format(instr, "bgez 'rs, 'dest");
1741 int32_t rs_val = get_register(instr->RsField()); 1722 int32_t rs_val = get_register(instr->RsField());
1742 DoBranch(instr, rs_val >= 0, false); 1723 DoBranch(instr, rs_val >= 0, false);
1743 break; 1724 break;
1744 } 1725 }
1745 case BGEZAL: { 1726 case BGEZAL: {
1746 int32_t rs_val = get_register(instr->RsField()); 1727 int32_t rs_val = get_register(instr->RsField());
1747 // Return address is one after the delay slot. 1728 // Return address is one after the delay slot.
1748 set_register(RA, pc_ + (2*Instr::kInstrSize)); 1729 set_register(RA, pc_ + (2 * Instr::kInstrSize));
1749 DoBranch(instr, rs_val >= 0, false); 1730 DoBranch(instr, rs_val >= 0, false);
1750 break; 1731 break;
1751 } 1732 }
1752 case BLTZAL: { 1733 case BLTZAL: {
1753 int32_t rs_val = get_register(instr->RsField()); 1734 int32_t rs_val = get_register(instr->RsField());
1754 // Return address is one after the delay slot. 1735 // Return address is one after the delay slot.
1755 set_register(RA, pc_ + (2*Instr::kInstrSize)); 1736 set_register(RA, pc_ + (2 * Instr::kInstrSize));
1756 DoBranch(instr, rs_val < 0, false); 1737 DoBranch(instr, rs_val < 0, false);
1757 break; 1738 break;
1758 } 1739 }
1759 case BGEZL: { 1740 case BGEZL: {
1760 // Format(instr, "bgezl 'rs, 'dest"); 1741 // Format(instr, "bgezl 'rs, 'dest");
1761 int32_t rs_val = get_register(instr->RsField()); 1742 int32_t rs_val = get_register(instr->RsField());
1762 DoBranch(instr, rs_val >= 0, true); 1743 DoBranch(instr, rs_val >= 0, true);
1763 break; 1744 break;
1764 } 1745 }
1765 case BLTZ: { 1746 case BLTZ: {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1851 case COP1_C_EQ: { 1832 case COP1_C_EQ: {
1852 ASSERT(instr->FormatField() == FMT_D); // Only D supported. 1833 ASSERT(instr->FormatField() == FMT_D); // Only D supported.
1853 ASSERT(instr->FdField() == F0); 1834 ASSERT(instr->FdField() == F0);
1854 set_fcsr_bit(fcsr_cc, (fs_val == ft_val)); 1835 set_fcsr_bit(fcsr_cc, (fs_val == ft_val));
1855 break; 1836 break;
1856 } 1837 }
1857 case COP1_C_UEQ: { 1838 case COP1_C_UEQ: {
1858 ASSERT(instr->FormatField() == FMT_D); // Only D supported. 1839 ASSERT(instr->FormatField() == FMT_D); // Only D supported.
1859 ASSERT(instr->FdField() == F0); 1840 ASSERT(instr->FdField() == F0);
1860 set_fcsr_bit(fcsr_cc, 1841 set_fcsr_bit(fcsr_cc,
1861 (fs_val == ft_val) || isnan(fs_val) || isnan(ft_val)); 1842 (fs_val == ft_val) || isnan(fs_val) || isnan(ft_val));
1862 break; 1843 break;
1863 } 1844 }
1864 case COP1_C_OLT: { 1845 case COP1_C_OLT: {
1865 ASSERT(instr->FormatField() == FMT_D); // Only D supported. 1846 ASSERT(instr->FormatField() == FMT_D); // Only D supported.
1866 ASSERT(instr->FdField() == F0); 1847 ASSERT(instr->FdField() == F0);
1867 set_fcsr_bit(fcsr_cc, (fs_val < ft_val)); 1848 set_fcsr_bit(fcsr_cc, (fs_val < ft_val));
1868 break; 1849 break;
1869 } 1850 }
1870 case COP1_C_ULT: { 1851 case COP1_C_ULT: {
1871 ASSERT(instr->FormatField() == FMT_D); // Only D supported. 1852 ASSERT(instr->FormatField() == FMT_D); // Only D supported.
1872 ASSERT(instr->FdField() == F0); 1853 ASSERT(instr->FdField() == F0);
1873 set_fcsr_bit(fcsr_cc, 1854 set_fcsr_bit(fcsr_cc,
1874 (fs_val < ft_val) || isnan(fs_val) || isnan(ft_val)); 1855 (fs_val < ft_val) || isnan(fs_val) || isnan(ft_val));
1875 break; 1856 break;
1876 } 1857 }
1877 case COP1_C_OLE: { 1858 case COP1_C_OLE: {
1878 ASSERT(instr->FormatField() == FMT_D); // Only D supported. 1859 ASSERT(instr->FormatField() == FMT_D); // Only D supported.
1879 ASSERT(instr->FdField() == F0); 1860 ASSERT(instr->FdField() == F0);
1880 set_fcsr_bit(fcsr_cc, (fs_val <= ft_val)); 1861 set_fcsr_bit(fcsr_cc, (fs_val <= ft_val));
1881 break; 1862 break;
1882 } 1863 }
1883 case COP1_C_ULE: { 1864 case COP1_C_ULE: {
1884 ASSERT(instr->FormatField() == FMT_D); // Only D supported. 1865 ASSERT(instr->FormatField() == FMT_D); // Only D supported.
1885 ASSERT(instr->FdField() == F0); 1866 ASSERT(instr->FdField() == F0);
1886 set_fcsr_bit(fcsr_cc, 1867 set_fcsr_bit(fcsr_cc,
1887 (fs_val <= ft_val) || isnan(fs_val) || isnan(ft_val)); 1868 (fs_val <= ft_val) || isnan(fs_val) || isnan(ft_val));
1888 break; 1869 break;
1889 } 1870 }
1890 case COP1_TRUNC_W: { 1871 case COP1_TRUNC_W: {
1891 switch (instr->FormatField()) { 1872 switch (instr->FormatField()) {
1892 case FMT_D: { 1873 case FMT_D: {
1893 double fs_dbl = get_fregister_double(instr->FsField()); 1874 double fs_dbl = get_fregister_double(instr->FsField());
1894 int32_t fs_int; 1875 int32_t fs_int;
1895 if (isnan(fs_dbl) || isinf(fs_dbl) || (fs_dbl > kMaxInt32) || 1876 if (isnan(fs_dbl) || isinf(fs_dbl) || (fs_dbl > kMaxInt32) ||
1896 (fs_dbl < kMinInt32)) { 1877 (fs_dbl < kMinInt32)) {
1897 fs_int = kMaxInt32; 1878 fs_int = kMaxInt32;
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
2303 } 2284 }
2304 case XORI: { 2285 case XORI: {
2305 // Format(instr, "xori 'rt, 'rs, 'immu"); 2286 // Format(instr, "xori 'rt, 'rs, 'immu");
2306 int32_t rs_val = get_register(instr->RsField()); 2287 int32_t rs_val = get_register(instr->RsField());
2307 set_register(instr->RtField(), rs_val ^ instr->UImmField()); 2288 set_register(instr->RtField(), rs_val ^ instr->UImmField());
2308 break; 2289 break;
2309 break; 2290 break;
2310 } 2291 }
2311 default: { 2292 default: {
2312 OS::PrintErr("Undecoded instruction: 0x%x at %p\n", 2293 OS::PrintErr("Undecoded instruction: 0x%x at %p\n",
2313 instr->InstructionBits(), instr); 2294 instr->InstructionBits(), instr);
2314 UnimplementedInstruction(instr); 2295 UnimplementedInstruction(instr);
2315 break; 2296 break;
2316 } 2297 }
2317 } 2298 }
2318 pc_ += Instr::kInstrSize; 2299 pc_ += Instr::kInstrSize;
2319 } 2300 }
2320 2301
2321 2302
2322 void Simulator::ExecuteDelaySlot() { 2303 void Simulator::ExecuteDelaySlot() {
2323 ASSERT(pc_ != kEndSimulatingPC); 2304 ASSERT(pc_ != kEndSimulatingPC);
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
2524 set_register(THR, reinterpret_cast<int32_t>(thread)); 2505 set_register(THR, reinterpret_cast<int32_t>(thread));
2525 // Set the tag. 2506 // Set the tag.
2526 thread->set_vm_tag(VMTag::kDartTagId); 2507 thread->set_vm_tag(VMTag::kDartTagId);
2527 // Clear top exit frame. 2508 // Clear top exit frame.
2528 thread->set_top_exit_frame_info(0); 2509 thread->set_top_exit_frame_info(0);
2529 2510
2530 ASSERT(raw_exception != Object::null()); 2511 ASSERT(raw_exception != Object::null());
2531 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); 2512 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception));
2532 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); 2513 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace));
2533 // Restore pool pointer. 2514 // Restore pool pointer.
2534 int32_t code = *reinterpret_cast<int32_t*>( 2515 int32_t code =
2535 fp + kPcMarkerSlotFromFp * kWordSize); 2516 *reinterpret_cast<int32_t*>(fp + kPcMarkerSlotFromFp * kWordSize);
2536 int32_t pp = *reinterpret_cast<int32_t*>( 2517 int32_t pp = *reinterpret_cast<int32_t*>(code + Code::object_pool_offset() -
2537 code + Code::object_pool_offset() - kHeapObjectTag); 2518 kHeapObjectTag);
2538 set_register(CODE_REG, code); 2519 set_register(CODE_REG, code);
2539 set_register(PP, pp); 2520 set_register(PP, pp);
2540 buf->Longjmp(); 2521 buf->Longjmp();
2541 } 2522 }
2542 2523
2543 } // namespace dart 2524 } // namespace dart
2544 2525
2545 #endif // defined(USING_SIMULATOR) 2526 #endif // defined(USING_SIMULATOR)
2546 2527
2547 #endif // defined TARGET_ARCH_MIPS 2528 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/simulator_mips.h ('k') | runtime/vm/snapshot.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698