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

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
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)); 520 ASSERT((reg != R31) || (r31t != R31IsUndef));
408 if ((reg != R31) || (r31t != R31IsZR)) { 521 if ((reg != R31) || (r31t != R31IsZR)) {
409 registers_[reg] = value; 522 registers_[reg] = value;
410 } 523 }
411 } 524 }
412 525
413 526
414 // Get the register from the architecture state. 527 // Get the register from the architecture state.
415 int64_t Simulator::get_register(Register reg, R31Type r31t) const { 528 int64_t Simulator::get_register(Register reg, R31Type r31t) const {
416 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); 529 ASSERT(((reg >= 0) && (reg < kNumberOfCpuRegisters)) || (reg == SPREG));
417 ASSERT((reg != R31) || (r31t != R31IsUndef)); 530 ASSERT((reg != R31) || (r31t != R31IsUndef));
418 if ((reg == R31) && (r31t == R31IsZR)) { 531 if ((reg == R31) && (r31t == R31IsZR)) {
419 return 0; 532 return 0;
533 } else if (reg == SPREG) {
534 // SPREG is used from architecture independent code. It is only ever passed
535 // to Simulator::get_register(). Calls to get_register() from architecture
536 // independent code don't include an R31Type, so if we were to define
537 // SPREG to be R31, we wouldn't be able to distinguish from ZR. Therefore we
538 // use another value, and check for it in get_register().
539 return registers_[R31];
420 } else { 540 } else {
421 return registers_[reg]; 541 return registers_[reg];
422 } 542 }
423 } 543 }
424 544
425 545
426 void Simulator::set_wregister(Register reg, int32_t value, R31Type r31t) { 546 void Simulator::set_wregister(Register reg, int32_t value, R31Type r31t) {
427 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); 547 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
428 ASSERT((reg != R31) || (r31t != R31IsUndef)); 548 ASSERT((reg != R31) || (r31t != R31IsUndef));
429 // When setting in W mode, clear the high bits. 549 // When setting in W mode, clear the high bits.
(...skipping 11 matching lines...) Expand all
441 return 0; 561 return 0;
442 } else { 562 } else {
443 return registers_[reg]; 563 return registers_[reg];
444 } 564 }
445 } 565 }
446 566
447 567
448 // Raw access to the PC register. 568 // Raw access to the PC register.
449 void Simulator::set_pc(int64_t value) { 569 void Simulator::set_pc(int64_t value) {
450 pc_modified_ = true; 570 pc_modified_ = true;
571 last_pc_ = pc_;
451 pc_ = value; 572 pc_ = value;
452 } 573 }
453 574
454 575
455 // Raw access to the PC register without the special adjustment when reading. 576 // Raw access to the pc.
456 int64_t Simulator::get_pc() const { 577 int64_t Simulator::get_pc() const {
457 return pc_; 578 return pc_;
458 } 579 }
459 580
460 581
582 int64_t Simulator::get_last_pc() const {
583 return last_pc_;
584 }
585
586
461 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) { 587 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) {
462 uword fault_pc = get_pc(); 588 uword fault_pc = get_pc();
589 uword last_pc = get_last_pc();
463 // TODO(zra): drop into debugger. 590 // TODO(zra): drop into debugger.
464 char buffer[128]; 591 char buffer[128];
465 snprintf(buffer, sizeof(buffer), 592 snprintf(buffer, sizeof(buffer),
466 "illegal memory access at 0x%" Px ", pc=0x%" Px "\n", 593 "illegal memory access at 0x%" Px ", pc=0x%" Px ", last_pc=0x%" Px"\n",
467 addr, fault_pc); 594 addr, fault_pc, last_pc);
595 SimulatorDebugger dbg(this);
596 dbg.Stop(instr, buffer);
468 // The debugger will return control in non-interactive mode. 597 // The debugger will return control in non-interactive mode.
469 FATAL("Cannot continue execution after illegal memory access."); 598 FATAL("Cannot continue execution after illegal memory access.");
470 } 599 }
471 600
472 601
473 // The ARMv8 manual advises that an unaligned access may generate a fault, 602 // 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, 603 // and if not, will likely take a number of additional cycles to execute,
475 // so let's just not generate any. 604 // so let's just not generate any.
476 void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) { 605 void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) {
477 char buffer[64]; 606 char buffer[64];
478 snprintf(buffer, sizeof(buffer), 607 snprintf(buffer, sizeof(buffer),
479 "unaligned %s at 0x%" Px ", pc=%p\n", msg, addr, instr); 608 "unaligned %s at 0x%" Px ", pc=%p\n", msg, addr, instr);
480 // TODO(zra): Drop into the simulator debugger when it exists. 609 SimulatorDebugger dbg(this);
610 dbg.Stop(instr, buffer);
481 // The debugger will not be able to single step past this instruction, but 611 // 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. 612 // it will be possible to disassemble the code and inspect registers.
483 FATAL("Cannot continue execution after unaligned access."); 613 FATAL("Cannot continue execution after unaligned access.");
484 } 614 }
485 615
486 616
487 void Simulator::UnimplementedInstruction(Instr* instr) { 617 void Simulator::UnimplementedInstruction(Instr* instr) {
488 char buffer[64]; 618 char buffer[64];
489 snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr); 619 snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr);
490 // TODO(zra): drop into debugger. 620 SimulatorDebugger dbg(this);
621 dbg.Stop(instr, buffer);
491 FATAL("Cannot continue execution after unimplemented instruction."); 622 FATAL("Cannot continue execution after unimplemented instruction.");
492 } 623 }
493 624
494 625
495 // Returns the top of the stack area to enable checking for stack pointer 626 // Returns the top of the stack area to enable checking for stack pointer
496 // validity. 627 // validity.
497 uword Simulator::StackTop() const { 628 uword Simulator::StackTop() const {
498 // To be safe in potential stack underflows we leave some buffer above and 629 // To be safe in potential stack underflows we leave some buffer above and
499 // set the stack top. 630 // set the stack top.
500 return reinterpret_cast<uword>(stack_) + 631 return reinterpret_cast<uword>(stack_) +
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
918 UnimplementedInstruction(instr); 1049 UnimplementedInstruction(instr);
919 } 1050 }
920 const int64_t imm19 = instr->SImm19Field(); 1051 const int64_t imm19 = instr->SImm19Field();
921 const int64_t dest = get_pc() + (imm19 << 2); 1052 const int64_t dest = get_pc() + (imm19 << 2);
922 if (ConditionallyExecute(instr)) { 1053 if (ConditionallyExecute(instr)) {
923 set_pc(dest); 1054 set_pc(dest);
924 } 1055 }
925 } 1056 }
926 1057
927 1058
1059 // Calls into the Dart runtime are based on this interface.
1060 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments);
1061
1062 // Calls to leaf Dart runtime functions are based on this interface.
1063 typedef int32_t (*SimulatorLeafRuntimeCall)(
1064 int64_t r0, int64_t r1, int64_t r2, int64_t r3);
1065
1066 // Calls to leaf float Dart runtime functions are based on this interface.
1067 typedef double (*SimulatorLeafFloatRuntimeCall)(double d0, double d1);
1068
1069 // Calls to native Dart functions are based on this interface.
1070 typedef void (*SimulatorBootstrapNativeCall)(NativeArguments* arguments);
1071 typedef void (*SimulatorNativeCall)(NativeArguments* arguments, uword target);
1072
1073
1074 void Simulator::DoRedirectedCall(Instr* instr) {
1075 SimulatorSetjmpBuffer buffer(this);
1076 if (!setjmp(buffer.buffer_)) {
1077 int64_t saved_lr = get_register(LR);
1078 Redirection* redirection = Redirection::FromHltInstruction(instr);
1079 uword external = redirection->external_function();
1080 if (FLAG_trace_sim) {
1081 OS::Print("Call to host function at 0x%" Pd "\n", external);
1082 }
1083
1084 if ((redirection->call_kind() == kRuntimeCall) ||
1085 (redirection->call_kind() == kBootstrapNativeCall) ||
1086 (redirection->call_kind() == kNativeCall)) {
1087 // Set the top_exit_frame_info of this simulator to the native stack.
1088 set_top_exit_frame_info(reinterpret_cast<uword>(&buffer));
1089 }
1090 if (redirection->call_kind() == kRuntimeCall) {
1091 NativeArguments arguments;
1092 ASSERT(sizeof(NativeArguments) == 4*kWordSize);
1093 arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0));
1094 arguments.argc_tag_ = get_register(R1);
1095 arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2));
1096 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3));
1097 SimulatorRuntimeCall target =
1098 reinterpret_cast<SimulatorRuntimeCall>(external);
1099 target(arguments);
1100 set_register(R0, icount_); // Zap result register from void function.
1101 set_register(R1, icount_);
1102 } else if (redirection->call_kind() == kLeafRuntimeCall) {
1103 ASSERT((0 <= redirection->argument_count()) &&
1104 (redirection->argument_count() <= 4));
1105 int64_t r0 = get_register(R0);
1106 int64_t r1 = get_register(R1);
1107 int64_t r2 = get_register(R2);
1108 int64_t r3 = get_register(R3);
1109 SimulatorLeafRuntimeCall target =
1110 reinterpret_cast<SimulatorLeafRuntimeCall>(external);
1111 r0 = target(r0, r1, r2, r3);
1112 set_register(R0, r0); // Set returned result from function.
1113 set_register(R1, icount_); // Zap unused result register.
1114 } else if (redirection->call_kind() == kLeafFloatRuntimeCall) {
1115 // TODO(zra): leaf float runtime calls.
1116 UNIMPLEMENTED();
1117 } else if (redirection->call_kind() == kBootstrapNativeCall) {
1118 NativeArguments* arguments;
1119 arguments = reinterpret_cast<NativeArguments*>(get_register(R0));
1120 SimulatorBootstrapNativeCall target =
1121 reinterpret_cast<SimulatorBootstrapNativeCall>(external);
1122 target(arguments);
1123 set_register(R0, icount_); // Zap result register from void function.
1124 } else {
1125 ASSERT(redirection->call_kind() == kNativeCall);
1126 NativeArguments* arguments;
1127 arguments = reinterpret_cast<NativeArguments*>(get_register(R0));
1128 uword target_func = get_register(R1);
1129 SimulatorNativeCall target =
1130 reinterpret_cast<SimulatorNativeCall>(external);
1131 target(arguments, target_func);
1132 set_register(R0, icount_); // Zap result register from void function.
1133 set_register(R1, icount_);
1134 }
1135 set_top_exit_frame_info(0);
1136
1137 // Zap caller-saved registers, since the actual runtime call could have
1138 // used them.
1139 set_register(R2, icount_);
1140 set_register(R3, icount_);
1141 set_register(R4, icount_);
1142 set_register(R5, icount_);
1143 set_register(R6, icount_);
1144 set_register(R7, icount_);
1145 set_register(R8, icount_);
1146 set_register(R9, icount_);
1147 set_register(R10, icount_);
1148 set_register(R11, icount_);
1149 set_register(R12, icount_);
1150 set_register(R13, icount_);
1151 set_register(R14, icount_);
1152 set_register(R15, icount_);
1153 set_register(IP0, icount_);
1154 set_register(IP1, icount_);
1155 set_register(R18, icount_);
1156 set_register(LR, icount_);
1157
1158 // TODO(zra): Zap caller-saved fpu registers.
1159
1160 // Return.
1161 set_pc(saved_lr);
1162 } else {
1163 // Coming via long jump from a throw. Continue to exception handler.
1164 set_top_exit_frame_info(0);
1165 }
1166 }
1167
1168
928 void Simulator::DecodeExceptionGen(Instr* instr) { 1169 void Simulator::DecodeExceptionGen(Instr* instr) {
929 if ((instr->Bits(0, 2) == 1) && (instr->Bits(2, 3) == 0) && 1170 if ((instr->Bits(0, 2) == 1) && (instr->Bits(2, 3) == 0) &&
930 (instr->Bits(21, 3) == 0)) { 1171 (instr->Bits(21, 3) == 0)) {
931 // Format(instr, "svc 'imm16"); 1172 // Format(instr, "svc 'imm16");
932 UnimplementedInstruction(instr); 1173 UnimplementedInstruction(instr);
933 } 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) &&
934 (instr->Bits(21, 3) == 1)) { 1175 (instr->Bits(21, 3) == 1)) {
935 // Format(instr, "brk 'imm16"); 1176 // Format(instr, "brk 'imm16");
936 UnimplementedInstruction(instr); 1177 UnimplementedInstruction(instr);
937 } else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) && 1178 } else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) &&
938 (instr->Bits(21, 3) == 2)) { 1179 (instr->Bits(21, 3) == 2)) {
939 // Format(instr, "hlt 'imm16"); 1180 // Format(instr, "hlt 'imm16");
940 uint16_t imm = static_cast<uint16_t>(instr->Imm16Field()); 1181 uint16_t imm = static_cast<uint16_t>(instr->Imm16Field());
941 if (imm == kImmExceptionIsDebug) { 1182 if (imm == kImmExceptionIsDebug) {
942 SimulatorDebugger dbg(this); 1183 SimulatorDebugger dbg(this);
943 const char* message = *reinterpret_cast<const char**>( 1184 const char* message = *reinterpret_cast<const char**>(
944 reinterpret_cast<intptr_t>(instr) - 2 * Instr::kInstrSize); 1185 reinterpret_cast<intptr_t>(instr) - 2 * Instr::kInstrSize);
945 set_pc(get_pc() + Instr::kInstrSize); 1186 set_pc(get_pc() + Instr::kInstrSize);
946 dbg.Stop(instr, message); 1187 dbg.Stop(instr, message);
947 } else if (imm == kImmExceptionIsPrintf) { 1188 } else if (imm == kImmExceptionIsPrintf) {
948 const char* message = *reinterpret_cast<const char**>( 1189 const char* message = *reinterpret_cast<const char**>(
949 reinterpret_cast<intptr_t>(instr) - 2 * Instr::kInstrSize); 1190 reinterpret_cast<intptr_t>(instr) - 2 * Instr::kInstrSize);
950 OS::Print("Simulator hit: %s", message); 1191 OS::Print("Simulator hit: %s", message);
1192 } else if (imm == kImmExceptionIsRedirectedCall) {
1193 DoRedirectedCall(instr);
951 } else { 1194 } else {
952 UnimplementedInstruction(instr); 1195 UnimplementedInstruction(instr);
953 } 1196 }
954 } 1197 }
955 } 1198 }
956 1199
957 1200
958 void Simulator::DecodeSystem(Instr* instr) { 1201 void Simulator::DecodeSystem(Instr* instr) {
959 if ((instr->Bits(0, 8) == 0x5f) && (instr->Bits(12, 4) == 2) && 1202 if ((instr->Bits(0, 8) == 0x5f) && (instr->Bits(12, 4) == 2) &&
960 (instr->Bits(16, 3) == 3) && (instr->Bits(19, 2) == 0) && 1203 (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); 1988 set_register(R21, r21_val);
1746 set_register(R22, r22_val); 1989 set_register(R22, r22_val);
1747 set_register(R23, r23_val); 1990 set_register(R23, r23_val);
1748 set_register(R24, r24_val); 1991 set_register(R24, r24_val);
1749 set_register(R25, r25_val); 1992 set_register(R25, r25_val);
1750 set_register(R26, r26_val); 1993 set_register(R26, r26_val);
1751 set_register(R27, r27_val); 1994 set_register(R27, r27_val);
1752 set_register(R28, r28_val); 1995 set_register(R28, r28_val);
1753 set_register(R29, r29_val); 1996 set_register(R29, r29_val);
1754 1997
1755 // Restore the SP register and return R1:R0. 1998 // Restore the SP register and return R0.
1756 set_register(R31, sp_before_call, R31IsSP); 1999 set_register(R31, sp_before_call, R31IsSP);
1757 int64_t return_value; 2000 int64_t return_value;
1758 return_value = get_register(R0); 2001 return_value = get_register(R0);
1759 return return_value; 2002 return return_value;
1760 } 2003 }
1761 2004
1762 } // namespace dart 2005 } // namespace dart
1763 2006
1764 #endif // !defined(HOST_ARCH_ARM64) 2007 #endif // !defined(HOST_ARCH_ARM64)
1765 2008
1766 #endif // defined TARGET_ARCH_ARM64 2009 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698