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

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

Issue 243773002: Adds Runtime call stub and Dart entry stub to ARM64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/simulator_arm64.h ('k') | runtime/vm/snapshot_test.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include <math.h> // for isnan. 5 #include <math.h> // for isnan.
6 #include <setjmp.h> 6 #include <setjmp.h>
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include "vm/globals.h" 9 #include "vm/globals.h"
10 #if defined(TARGET_ARCH_ARM64) 10 #if defined(TARGET_ARCH_ARM64)
(...skipping 17 matching lines...) Expand all
28 DEFINE_FLAG(int, stop_sim_at, 0, "Address to stop simulator at."); 28 DEFINE_FLAG(int, stop_sim_at, 0, "Address to stop simulator at.");
29 29
30 30
31 // This macro provides a platform independent use of sscanf. The reason for 31 // This macro provides a platform independent use of sscanf. The reason for
32 // SScanF not being implemented in a platform independent way through 32 // SScanF not being implemented in a platform independent way through
33 // OS in the same way as SNPrint is that the Windows C Run-Time 33 // OS in the same way as SNPrint is that the Windows C Run-Time
34 // Library does not provide vsscanf. 34 // Library does not provide vsscanf.
35 #define SScanF sscanf // NOLINT 35 #define SScanF sscanf // NOLINT
36 36
37 37
38 // SimulatorSetjmpBuffer are linked together, and the last created one
39 // is referenced by the Simulator. When an exception is thrown, the exception
40 // runtime looks at where to jump and finds the corresponding
41 // SimulatorSetjmpBuffer based on the stack pointer of the exception handler.
42 // The runtime then does a Longjmp on that buffer to return to the simulator.
43 class SimulatorSetjmpBuffer {
44 public:
45 int Setjmp() { return setjmp(buffer_); }
46 void Longjmp() {
47 // "This" is now the last setjmp buffer.
48 simulator_->set_last_setjmp_buffer(this);
49 longjmp(buffer_, 1);
50 }
51
52 explicit SimulatorSetjmpBuffer(Simulator* sim) {
53 simulator_ = sim;
54 link_ = sim->last_setjmp_buffer();
55 sim->set_last_setjmp_buffer(this);
56 sp_ = static_cast<uword>(sim->get_register(R31, R31IsSP));
57 native_sp_ = reinterpret_cast<uword>(&sim); // Current C++ stack pointer.
58 }
59
60 ~SimulatorSetjmpBuffer() {
61 ASSERT(simulator_->last_setjmp_buffer() == this);
62 simulator_->set_last_setjmp_buffer(link_);
63 }
64
65 SimulatorSetjmpBuffer* link() { return link_; }
66
67 uword sp() { return sp_; }
68 uword native_sp() { return native_sp_; }
69
70 private:
71 uword sp_;
72 uword native_sp_;
73 Simulator* simulator_;
74 SimulatorSetjmpBuffer* link_;
75 jmp_buf buffer_;
76
77 friend class Simulator;
78 };
79
80
38 // The SimulatorDebugger class is used by the simulator while debugging 81 // The SimulatorDebugger class is used by the simulator while debugging
39 // simulated ARM64 code. 82 // simulated ARM64 code.
40 class SimulatorDebugger { 83 class SimulatorDebugger {
41 public: 84 public:
42 explicit SimulatorDebugger(Simulator* sim); 85 explicit SimulatorDebugger(Simulator* sim);
43 ~SimulatorDebugger(); 86 ~SimulatorDebugger();
44 87
45 void Stop(Instr* instr, const char* message); 88 void Stop(Instr* instr, const char* message);
46 void Debug(); 89 void Debug();
47 char* ReadLine(const char* prompt); 90 char* ReadLine(const char* prompt);
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 425
383 Simulator::~Simulator() { 426 Simulator::~Simulator() {
384 delete[] stack_; 427 delete[] stack_;
385 Isolate* isolate = Isolate::Current(); 428 Isolate* isolate = Isolate::Current();
386 if (isolate != NULL) { 429 if (isolate != NULL) {
387 isolate->set_simulator(NULL); 430 isolate->set_simulator(NULL);
388 } 431 }
389 } 432 }
390 433
391 434
435 // When the generated code calls an external reference we need to catch that in
436 // the simulator. The external reference will be a function compiled for the
437 // host architecture. We need to call that function instead of trying to
438 // execute it with the simulator. We do that by redirecting the external
439 // reference to a svc (supervisor call) instruction that is handled by
440 // the simulator. We write the original destination of the jump just at a known
441 // offset from the svc instruction so the simulator knows what to call.
442 class Redirection {
443 public:
444 uword address_of_hlt_instruction() {
445 return reinterpret_cast<uword>(&hlt_instruction_);
446 }
447
448 uword external_function() const { return external_function_; }
449
450 Simulator::CallKind call_kind() const { return call_kind_; }
451
452 int argument_count() const { return argument_count_; }
453
454 static Redirection* Get(uword external_function,
455 Simulator::CallKind call_kind,
456 int argument_count) {
457 Redirection* current;
458 for (current = list_; current != NULL; current = current->next_) {
459 if (current->external_function_ == external_function) return current;
460 }
461 return new Redirection(external_function, call_kind, argument_count);
462 }
463
464 static Redirection* FromHltInstruction(Instr* hlt_instruction) {
465 char* addr_of_hlt = reinterpret_cast<char*>(hlt_instruction);
466 char* addr_of_redirection =
467 addr_of_hlt - OFFSET_OF(Redirection, hlt_instruction_);
468 return reinterpret_cast<Redirection*>(addr_of_redirection);
469 }
470
471 private:
472 static const int32_t kRedirectInstruction = Instr::kRedirectInstruction;
473 Redirection(uword external_function,
474 Simulator::CallKind call_kind,
475 int argument_count)
476 : external_function_(external_function),
477 call_kind_(call_kind),
478 argument_count_(argument_count),
479 hlt_instruction_(kRedirectInstruction),
480 next_(list_) {
481 list_ = this;
482 }
483
484 uword external_function_;
485 Simulator::CallKind call_kind_;
486 int argument_count_;
487 uint32_t hlt_instruction_;
488 Redirection* next_;
489 static Redirection* list_;
490 };
491
492
493 Redirection* Redirection::list_ = NULL;
494
495
496 uword Simulator::RedirectExternalReference(uword function,
497 CallKind call_kind,
498 int argument_count) {
499 Redirection* redirection =
500 Redirection::Get(function, call_kind, argument_count);
501 return redirection->address_of_hlt_instruction();
502 }
503
504
392 // Get the active Simulator for the current isolate. 505 // Get the active Simulator for the current isolate.
393 Simulator* Simulator::Current() { 506 Simulator* Simulator::Current() {
394 Simulator* simulator = Isolate::Current()->simulator(); 507 Simulator* simulator = Isolate::Current()->simulator();
395 if (simulator == NULL) { 508 if (simulator == NULL) {
396 simulator = new Simulator(); 509 simulator = new Simulator();
397 Isolate::Current()->set_simulator(simulator); 510 Isolate::Current()->set_simulator(simulator);
398 } 511 }
399 return simulator; 512 return simulator;
400 } 513 }
401 514
402 515
403 // Sets the register in the architecture state. 516 // Sets the register in the architecture state.
404 void Simulator::set_register(Register reg, int64_t value, R31Type r31t) { 517 void Simulator::set_register(Register reg, int64_t value, R31Type r31t) {
405 // register is in range, and if it is R31, a mode is specified. 518 // register is in range, and if it is R31, a mode is specified.
406 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); 519 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
407 ASSERT((reg != R31) || (r31t != R31IsUndef));
408 if ((reg != R31) || (r31t != R31IsZR)) { 520 if ((reg != R31) || (r31t != R31IsZR)) {
409 registers_[reg] = value; 521 registers_[reg] = value;
410 } 522 }
411 } 523 }
412 524
413 525
414 // Get the register from the architecture state. 526 // Get the register from the architecture state.
415 int64_t Simulator::get_register(Register reg, R31Type r31t) const { 527 int64_t Simulator::get_register(Register reg, R31Type r31t) const {
416 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); 528 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
417 ASSERT((reg != R31) || (r31t != R31IsUndef));
418 if ((reg == R31) && (r31t == R31IsZR)) { 529 if ((reg == R31) && (r31t == R31IsZR)) {
419 return 0; 530 return 0;
420 } else { 531 } else {
421 return registers_[reg]; 532 return registers_[reg];
422 } 533 }
423 } 534 }
424 535
425 536
426 void Simulator::set_wregister(Register reg, int32_t value, R31Type r31t) { 537 void Simulator::set_wregister(Register reg, int32_t value, R31Type r31t) {
427 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); 538 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
428 ASSERT((reg != R31) || (r31t != R31IsUndef));
429 // When setting in W mode, clear the high bits. 539 // When setting in W mode, clear the high bits.
430 if ((reg != R31) || (r31t != R31IsZR)) { 540 if ((reg != R31) || (r31t != R31IsZR)) {
431 registers_[reg] = Utils::LowHighTo64Bits(static_cast<uint32_t>(value), 0); 541 registers_[reg] = Utils::LowHighTo64Bits(static_cast<uint32_t>(value), 0);
432 } 542 }
433 } 543 }
434 544
435 545
436 // Get the register from the architecture state. 546 // Get the register from the architecture state.
437 int32_t Simulator::get_wregister(Register reg, R31Type r31t) const { 547 int32_t Simulator::get_wregister(Register reg, R31Type r31t) const {
438 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); 548 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
439 ASSERT((reg != R31) || (r31t != R31IsUndef));
440 if ((reg == R31) && (r31t == R31IsZR)) { 549 if ((reg == R31) && (r31t == R31IsZR)) {
441 return 0; 550 return 0;
442 } else { 551 } else {
443 return registers_[reg]; 552 return registers_[reg];
444 } 553 }
445 } 554 }
446 555
447 556
448 // Raw access to the PC register. 557 // Raw access to the PC register.
449 void Simulator::set_pc(int64_t value) { 558 void Simulator::set_pc(int64_t value) {
450 pc_modified_ = true; 559 pc_modified_ = true;
560 last_pc_ = pc_;
451 pc_ = value; 561 pc_ = value;
452 } 562 }
453 563
454 564
455 // Raw access to the PC register without the special adjustment when reading. 565 // Raw access to the pc.
456 int64_t Simulator::get_pc() const { 566 int64_t Simulator::get_pc() const {
457 return pc_; 567 return pc_;
458 } 568 }
459 569
460 570
571 int64_t Simulator::get_last_pc() const {
572 return last_pc_;
573 }
574
575
461 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) { 576 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) {
462 uword fault_pc = get_pc(); 577 uword fault_pc = get_pc();
578 uword last_pc = get_last_pc();
463 // TODO(zra): drop into debugger. 579 // TODO(zra): drop into debugger.
464 char buffer[128]; 580 char buffer[128];
465 snprintf(buffer, sizeof(buffer), 581 snprintf(buffer, sizeof(buffer),
466 "illegal memory access at 0x%" Px ", pc=0x%" Px "\n", 582 "illegal memory access at 0x%" Px ", pc=0x%" Px ", last_pc=0x%" Px"\n",
467 addr, fault_pc); 583 addr, fault_pc, last_pc);
584 SimulatorDebugger dbg(this);
585 dbg.Stop(instr, buffer);
468 // The debugger will return control in non-interactive mode. 586 // The debugger will return control in non-interactive mode.
469 FATAL("Cannot continue execution after illegal memory access."); 587 FATAL("Cannot continue execution after illegal memory access.");
470 } 588 }
471 589
472 590
473 // The ARMv8 manual advises that an unaligned access may generate a fault, 591 // The ARMv8 manual advises that an unaligned access may generate a fault,
474 // and if not, will likely take a number of additional cycles to execute, 592 // and if not, will likely take a number of additional cycles to execute,
475 // so let's just not generate any. 593 // so let's just not generate any.
476 void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) { 594 void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) {
477 char buffer[64]; 595 char buffer[64];
478 snprintf(buffer, sizeof(buffer), 596 snprintf(buffer, sizeof(buffer),
479 "unaligned %s at 0x%" Px ", pc=%p\n", msg, addr, instr); 597 "unaligned %s at 0x%" Px ", pc=%p\n", msg, addr, instr);
480 // TODO(zra): Drop into the simulator debugger when it exists. 598 SimulatorDebugger dbg(this);
599 dbg.Stop(instr, buffer);
481 // The debugger will not be able to single step past this instruction, but 600 // The debugger will not be able to single step past this instruction, but
482 // it will be possible to disassemble the code and inspect registers. 601 // it will be possible to disassemble the code and inspect registers.
483 FATAL("Cannot continue execution after unaligned access."); 602 FATAL("Cannot continue execution after unaligned access.");
484 } 603 }
485 604
486 605
487 void Simulator::UnimplementedInstruction(Instr* instr) { 606 void Simulator::UnimplementedInstruction(Instr* instr) {
488 char buffer[64]; 607 char buffer[64];
489 snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr); 608 snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr);
490 // TODO(zra): drop into debugger. 609 SimulatorDebugger dbg(this);
610 dbg.Stop(instr, buffer);
491 FATAL("Cannot continue execution after unimplemented instruction."); 611 FATAL("Cannot continue execution after unimplemented instruction.");
492 } 612 }
493 613
494 614
495 // Returns the top of the stack area to enable checking for stack pointer 615 // Returns the top of the stack area to enable checking for stack pointer
496 // validity. 616 // validity.
497 uword Simulator::StackTop() const { 617 uword Simulator::StackTop() const {
498 // To be safe in potential stack underflows we leave some buffer above and 618 // To be safe in potential stack underflows we leave some buffer above and
499 // set the stack top. 619 // set the stack top.
500 return reinterpret_cast<uword>(stack_) + 620 return reinterpret_cast<uword>(stack_) +
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
918 UnimplementedInstruction(instr); 1038 UnimplementedInstruction(instr);
919 } 1039 }
920 const int64_t imm19 = instr->SImm19Field(); 1040 const int64_t imm19 = instr->SImm19Field();
921 const int64_t dest = get_pc() + (imm19 << 2); 1041 const int64_t dest = get_pc() + (imm19 << 2);
922 if (ConditionallyExecute(instr)) { 1042 if (ConditionallyExecute(instr)) {
923 set_pc(dest); 1043 set_pc(dest);
924 } 1044 }
925 } 1045 }
926 1046
927 1047
1048 // Calls into the Dart runtime are based on this interface.
1049 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments);
1050
1051 // Calls to leaf Dart runtime functions are based on this interface.
1052 typedef int32_t (*SimulatorLeafRuntimeCall)(
1053 int64_t r0, int64_t r1, int64_t r2, int64_t r3,
1054 int64_t r4, int64_t r5, int64_t r6, int64_t r7);
1055
1056 // Calls to leaf float Dart runtime functions are based on this interface.
1057 typedef double (*SimulatorLeafFloatRuntimeCall)(
1058 double d0, double d1, double d2, double d3,
1059 double d4, double d5, double d6, double d7);
1060
1061 // Calls to native Dart functions are based on this interface.
1062 typedef void (*SimulatorBootstrapNativeCall)(NativeArguments* arguments);
1063 typedef void (*SimulatorNativeCall)(NativeArguments* arguments, uword target);
1064
1065
1066 void Simulator::DoRedirectedCall(Instr* instr) {
1067 SimulatorSetjmpBuffer buffer(this);
1068 if (!setjmp(buffer.buffer_)) {
1069 int64_t saved_lr = get_register(LR);
1070 Redirection* redirection = Redirection::FromHltInstruction(instr);
1071 uword external = redirection->external_function();
1072 if (FLAG_trace_sim) {
1073 OS::Print("Call to host function at 0x%" Pd "\n", external);
1074 }
1075
1076 if ((redirection->call_kind() == kRuntimeCall) ||
1077 (redirection->call_kind() == kBootstrapNativeCall) ||
1078 (redirection->call_kind() == kNativeCall)) {
1079 // Set the top_exit_frame_info of this simulator to the native stack.
1080 set_top_exit_frame_info(reinterpret_cast<uword>(&buffer));
1081 }
1082 if (redirection->call_kind() == kRuntimeCall) {
1083 NativeArguments arguments;
1084 ASSERT(sizeof(NativeArguments) == 4*kWordSize);
1085 arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0));
1086 arguments.argc_tag_ = get_register(R1);
1087 arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2));
1088 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3));
1089 SimulatorRuntimeCall target =
1090 reinterpret_cast<SimulatorRuntimeCall>(external);
1091 target(arguments);
1092 set_register(R0, icount_); // Zap result register from void function.
1093 set_register(R1, icount_);
1094 } else if (redirection->call_kind() == kLeafRuntimeCall) {
1095 ASSERT((0 <= redirection->argument_count()) &&
1096 (redirection->argument_count() <= 8));
1097 int64_t r0 = get_register(R0);
1098 int64_t r1 = get_register(R1);
1099 int64_t r2 = get_register(R2);
1100 int64_t r3 = get_register(R3);
1101 int64_t r4 = get_register(R4);
1102 int64_t r5 = get_register(R5);
1103 int64_t r6 = get_register(R6);
1104 int64_t r7 = get_register(R7);
1105 SimulatorLeafRuntimeCall target =
1106 reinterpret_cast<SimulatorLeafRuntimeCall>(external);
1107 r0 = target(r0, r1, r2, r3, r4, r5, r6, r7);
1108 set_register(R0, r0); // Set returned result from function.
1109 set_register(R1, icount_); // Zap unused result register.
1110 } else if (redirection->call_kind() == kLeafFloatRuntimeCall) {
1111 // TODO(zra): leaf float runtime calls.
1112 UNIMPLEMENTED();
1113 } else if (redirection->call_kind() == kBootstrapNativeCall) {
1114 NativeArguments* arguments;
1115 arguments = reinterpret_cast<NativeArguments*>(get_register(R0));
1116 SimulatorBootstrapNativeCall target =
1117 reinterpret_cast<SimulatorBootstrapNativeCall>(external);
1118 target(arguments);
1119 set_register(R0, icount_); // Zap result register from void function.
1120 } else {
1121 ASSERT(redirection->call_kind() == kNativeCall);
1122 NativeArguments* arguments;
1123 arguments = reinterpret_cast<NativeArguments*>(get_register(R0));
1124 uword target_func = get_register(R1);
1125 SimulatorNativeCall target =
1126 reinterpret_cast<SimulatorNativeCall>(external);
1127 target(arguments, target_func);
1128 set_register(R0, icount_); // Zap result register from void function.
1129 set_register(R1, icount_);
1130 }
1131 set_top_exit_frame_info(0);
1132
1133 // Zap caller-saved registers, since the actual runtime call could have
1134 // used them.
1135 set_register(R2, icount_);
1136 set_register(R3, icount_);
1137 set_register(R4, icount_);
1138 set_register(R5, icount_);
1139 set_register(R6, icount_);
1140 set_register(R7, icount_);
1141 set_register(R8, icount_);
1142 set_register(R9, icount_);
1143 set_register(R10, icount_);
1144 set_register(R11, icount_);
1145 set_register(R12, icount_);
1146 set_register(R13, icount_);
1147 set_register(R14, icount_);
1148 set_register(R15, icount_);
1149 set_register(IP0, icount_);
1150 set_register(IP1, icount_);
1151 set_register(R18, icount_);
1152 set_register(LR, icount_);
1153
1154 // TODO(zra): Zap caller-saved fpu registers.
1155
1156 // Return.
1157 set_pc(saved_lr);
1158 } else {
1159 // Coming via long jump from a throw. Continue to exception handler.
1160 set_top_exit_frame_info(0);
1161 }
1162 }
1163
1164
928 void Simulator::DecodeExceptionGen(Instr* instr) { 1165 void Simulator::DecodeExceptionGen(Instr* instr) {
929 if ((instr->Bits(0, 2) == 1) && (instr->Bits(2, 3) == 0) && 1166 if ((instr->Bits(0, 2) == 1) && (instr->Bits(2, 3) == 0) &&
930 (instr->Bits(21, 3) == 0)) { 1167 (instr->Bits(21, 3) == 0)) {
931 // Format(instr, "svc 'imm16"); 1168 // Format(instr, "svc 'imm16");
932 UnimplementedInstruction(instr); 1169 UnimplementedInstruction(instr);
933 } else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) && 1170 } else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) &&
934 (instr->Bits(21, 3) == 1)) { 1171 (instr->Bits(21, 3) == 1)) {
935 // Format(instr, "brk 'imm16"); 1172 // Format(instr, "brk 'imm16");
936 UnimplementedInstruction(instr); 1173 UnimplementedInstruction(instr);
937 } else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) && 1174 } else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) &&
938 (instr->Bits(21, 3) == 2)) { 1175 (instr->Bits(21, 3) == 2)) {
939 // Format(instr, "hlt 'imm16"); 1176 // Format(instr, "hlt 'imm16");
940 uint16_t imm = static_cast<uint16_t>(instr->Imm16Field()); 1177 uint16_t imm = static_cast<uint16_t>(instr->Imm16Field());
941 if (imm == kImmExceptionIsDebug) { 1178 if (imm == kImmExceptionIsDebug) {
942 SimulatorDebugger dbg(this); 1179 SimulatorDebugger dbg(this);
943 const char* message = *reinterpret_cast<const char**>( 1180 const char* message = *reinterpret_cast<const char**>(
944 reinterpret_cast<intptr_t>(instr) - 2 * Instr::kInstrSize); 1181 reinterpret_cast<intptr_t>(instr) - 2 * Instr::kInstrSize);
945 set_pc(get_pc() + Instr::kInstrSize); 1182 set_pc(get_pc() + Instr::kInstrSize);
946 dbg.Stop(instr, message); 1183 dbg.Stop(instr, message);
947 } else if (imm == kImmExceptionIsPrintf) { 1184 } else if (imm == kImmExceptionIsPrintf) {
948 const char* message = *reinterpret_cast<const char**>( 1185 const char* message = *reinterpret_cast<const char**>(
949 reinterpret_cast<intptr_t>(instr) - 2 * Instr::kInstrSize); 1186 reinterpret_cast<intptr_t>(instr) - 2 * Instr::kInstrSize);
950 OS::Print("Simulator hit: %s", message); 1187 OS::Print("Simulator hit: %s", message);
1188 } else if (imm == kImmExceptionIsRedirectedCall) {
1189 DoRedirectedCall(instr);
951 } else { 1190 } else {
952 UnimplementedInstruction(instr); 1191 UnimplementedInstruction(instr);
953 } 1192 }
954 } 1193 }
955 } 1194 }
956 1195
957 1196
958 void Simulator::DecodeSystem(Instr* instr) { 1197 void Simulator::DecodeSystem(Instr* instr) {
959 if ((instr->Bits(0, 8) == 0x5f) && (instr->Bits(12, 4) == 2) && 1198 if ((instr->Bits(0, 8) == 0x5f) && (instr->Bits(12, 4) == 2) &&
960 (instr->Bits(16, 3) == 3) && (instr->Bits(19, 2) == 0) && 1199 (instr->Bits(16, 3) == 3) && (instr->Bits(19, 2) == 0) &&
(...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after
1745 set_register(R21, r21_val); 1984 set_register(R21, r21_val);
1746 set_register(R22, r22_val); 1985 set_register(R22, r22_val);
1747 set_register(R23, r23_val); 1986 set_register(R23, r23_val);
1748 set_register(R24, r24_val); 1987 set_register(R24, r24_val);
1749 set_register(R25, r25_val); 1988 set_register(R25, r25_val);
1750 set_register(R26, r26_val); 1989 set_register(R26, r26_val);
1751 set_register(R27, r27_val); 1990 set_register(R27, r27_val);
1752 set_register(R28, r28_val); 1991 set_register(R28, r28_val);
1753 set_register(R29, r29_val); 1992 set_register(R29, r29_val);
1754 1993
1755 // Restore the SP register and return R1:R0. 1994 // Restore the SP register and return R0.
1756 set_register(R31, sp_before_call, R31IsSP); 1995 set_register(R31, sp_before_call, R31IsSP);
1757 int64_t return_value; 1996 int64_t return_value;
1758 return_value = get_register(R0); 1997 return_value = get_register(R0);
1759 return return_value; 1998 return return_value;
1760 } 1999 }
1761 2000
1762 } // namespace dart 2001 } // namespace dart
1763 2002
1764 #endif // !defined(HOST_ARCH_ARM64) 2003 #endif // !defined(HOST_ARCH_ARM64)
1765 2004
1766 #endif // defined TARGET_ARCH_ARM64 2005 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/simulator_arm64.h ('k') | runtime/vm/snapshot_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698