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

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

Issue 1192103004: VM: New calling convention for generated code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fixed comments Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/assembler_mips.h ('k') | runtime/vm/assembler_mips_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) 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 "vm/globals.h" // NOLINT 5 #include "vm/globals.h" // NOLINT
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/longjump.h" 9 #include "vm/longjump.h"
10 #include "vm/runtime_entry.h" 10 #include "vm/runtime_entry.h"
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 const int32_t encoded = EncodeBranchOffset(dest, next); 348 const int32_t encoded = EncodeBranchOffset(dest, next);
349 buffer_.Store<int32_t>(position, encoded); 349 buffer_.Store<int32_t>(position, encoded);
350 label->position_ = DecodeBranchOffset(next); 350 label->position_ = DecodeBranchOffset(next);
351 } 351 }
352 } 352 }
353 label->BindTo(bound_pc); 353 label->BindTo(bound_pc);
354 delay_slot_available_ = false; 354 delay_slot_available_ = false;
355 } 355 }
356 356
357 357
358 void Assembler::LoadWordFromPoolOffset(Register rd, int32_t offset) { 358 void Assembler::LoadWordFromPoolOffset(Register rd,
359 ASSERT(constant_pool_allowed()); 359 int32_t offset,
360 Register pp) {
361 ASSERT((pp != PP) || constant_pool_allowed());
360 ASSERT(!in_delay_slot_); 362 ASSERT(!in_delay_slot_);
361 ASSERT(rd != PP); 363 ASSERT(rd != pp);
362 if (Address::CanHoldOffset(offset)) { 364 if (Address::CanHoldOffset(offset)) {
363 lw(rd, Address(PP, offset)); 365 lw(rd, Address(pp, offset));
364 } else { 366 } else {
365 const int16_t offset_low = Utils::Low16Bits(offset); // Signed. 367 const int16_t offset_low = Utils::Low16Bits(offset); // Signed.
366 offset -= offset_low; 368 offset -= offset_low;
367 const uint16_t offset_high = Utils::High16Bits(offset); // Unsigned. 369 const uint16_t offset_high = Utils::High16Bits(offset); // Unsigned.
368 if (offset_high != 0) { 370 if (offset_high != 0) {
369 lui(rd, Immediate(offset_high)); 371 lui(rd, Immediate(offset_high));
370 addu(rd, rd, PP); 372 addu(rd, rd, pp);
371 lw(rd, Address(rd, offset_low)); 373 lw(rd, Address(rd, offset_low));
372 } else { 374 } else {
373 lw(rd, Address(PP, offset_low)); 375 lw(rd, Address(pp, offset_low));
374 } 376 }
375 } 377 }
376 } 378 }
377 379
378 380
379 void Assembler::AdduDetectOverflow(Register rd, Register rs, Register rt, 381 void Assembler::AdduDetectOverflow(Register rd, Register rs, Register rt,
380 Register ro, Register scratch) { 382 Register ro, Register scratch) {
381 ASSERT(!in_delay_slot_); 383 ASSERT(!in_delay_slot_);
382 ASSERT(rd != ro); 384 ASSERT(rd != ro);
383 ASSERT(rd != TMP); 385 ASSERT(rd != TMP);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 and_(ro, TMP, ro); 452 and_(ro, TMP, ro);
451 } else { 453 } else {
452 subu(rd, rs, rt); 454 subu(rd, rs, rt);
453 xor_(ro, rd, rs); 455 xor_(ro, rd, rs);
454 xor_(TMP, rs, rt); 456 xor_(TMP, rs, rt);
455 and_(ro, TMP, ro); 457 and_(ro, TMP, ro);
456 } 458 }
457 } 459 }
458 460
459 461
460 void Assembler::Branch(const StubEntry& stub_entry) { 462 void Assembler::CheckCodePointer() {
463 #ifdef DEBUG
464 Label cid_ok, instructions_ok;
465 Push(CMPRES1);
466 Push(CMPRES2);
467 LoadClassId(CMPRES1, CODE_REG);
468 BranchEqual(CMPRES1, Immediate(kCodeCid), &cid_ok);
469 break_(0);
470 Bind(&cid_ok);
471 GetNextPC(CMPRES1, TMP);
472 const intptr_t entry_offset = CodeSize() - Instr::kInstrSize +
473 Instructions::HeaderSize() - kHeapObjectTag;
474 AddImmediate(CMPRES1, CMPRES1, -entry_offset);
475 lw(CMPRES2, FieldAddress(CODE_REG, Code::saved_instructions_offset()));
476 BranchEqual(CMPRES1, CMPRES2, &instructions_ok);
477 break_(1);
478 Bind(&instructions_ok);
479 Pop(CMPRES2);
480 Pop(CMPRES1);
481 #endif
482 }
483
484
485 void Assembler::RestoreCodePointer() {
486 lw(CODE_REG, Address(FP, kPcMarkerSlotFromFp * kWordSize));
487 CheckCodePointer();
488 }
489
490
491 void Assembler::Branch(const StubEntry& stub_entry, Register pp) {
461 ASSERT(!in_delay_slot_); 492 ASSERT(!in_delay_slot_);
462 LoadImmediate(TMP, stub_entry.label().address()); 493 const Code& target_code = Code::Handle(stub_entry.code());
494 const int32_t offset = ObjectPool::element_offset(
495 object_pool_wrapper_.FindObject(target_code, kPatchable));
496 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, pp);
497 lw(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
463 jr(TMP); 498 jr(TMP);
464 } 499 }
465 500
466 501
467 void Assembler::BranchPatchable(const StubEntry& stub_entry) {
468 ASSERT(!in_delay_slot_);
469 const ExternalLabel& label = stub_entry.label();
470 const uint16_t low = Utils::Low16Bits(label.address());
471 const uint16_t high = Utils::High16Bits(label.address());
472 lui(T9, Immediate(high));
473 ori(T9, T9, Immediate(low));
474 jr(T9);
475 delay_slot_available_ = false; // CodePatcher expects a nop.
476 }
477
478
479 void Assembler::BranchLink(const ExternalLabel* label) { 502 void Assembler::BranchLink(const ExternalLabel* label) {
480 ASSERT(!in_delay_slot_); 503 ASSERT(!in_delay_slot_);
481 LoadImmediate(T9, label->address()); 504 LoadImmediate(T9, label->address());
482 jalr(T9); 505 jalr(T9);
483 } 506 }
484 507
485 508
486 void Assembler::BranchLink(const ExternalLabel* label, Patchability patchable) { 509 void Assembler::BranchLink(const ExternalLabel* label, Patchability patchable) {
487 ASSERT(!in_delay_slot_); 510 ASSERT(!in_delay_slot_);
488 const int32_t offset = ObjectPool::element_offset( 511 const int32_t offset = ObjectPool::element_offset(
489 object_pool_wrapper_.FindExternalLabel(label, patchable)); 512 object_pool_wrapper_.FindExternalLabel(label, patchable));
490 LoadWordFromPoolOffset(T9, offset - kHeapObjectTag); 513 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
514 lw(T9, FieldAddress(CODE_REG, Code::entry_point_offset()));
491 jalr(T9); 515 jalr(T9);
492 if (patchable == kPatchable) { 516 if (patchable == kPatchable) {
493 delay_slot_available_ = false; // CodePatcher expects a nop. 517 delay_slot_available_ = false; // CodePatcher expects a nop.
518 }
519 }
520
521
522 void Assembler::BranchLink(const Code& target, Patchability patchable) {
523 ASSERT(!in_delay_slot_);
524 const int32_t offset = ObjectPool::element_offset(
525 object_pool_wrapper_.FindObject(target, patchable));
526 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
527 lw(T9, FieldAddress(CODE_REG, Code::entry_point_offset()));
528 jalr(T9);
529 if (patchable == kPatchable) {
530 delay_slot_available_ = false; // CodePatcher expects a nop.
494 } 531 }
495 } 532 }
496 533
497 534
498 void Assembler::BranchLink(const StubEntry& stub_entry, 535 void Assembler::BranchLink(const StubEntry& stub_entry,
499 Patchability patchable) { 536 Patchability patchable) {
500 BranchLink(&stub_entry.label(), patchable); 537 BranchLink(Code::Handle(stub_entry.code()), patchable);
501 } 538 }
502 539
503 540
504 void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) { 541 void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) {
505 BranchLink(&stub_entry.label(), kPatchable); 542 BranchLink(Code::Handle(stub_entry.code()), kPatchable);
506 } 543 }
507 544
508 545
509 bool Assembler::CanLoadFromObjectPool(const Object& object) const { 546 bool Assembler::CanLoadFromObjectPool(const Object& object) const {
510 ASSERT(!Thread::CanLoadFromThread(object)); 547 ASSERT(!Thread::CanLoadFromThread(object));
511 if (!constant_pool_allowed()) { 548 if (!constant_pool_allowed()) {
512 return false; 549 return false;
513 } 550 }
514 551
515 ASSERT(object.IsNotTemporaryScopedHandle()); 552 ASSERT(object.IsNotTemporaryScopedHandle());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 598
562 void Assembler::LoadExternalLabel(Register rd, 599 void Assembler::LoadExternalLabel(Register rd,
563 const ExternalLabel* label, 600 const ExternalLabel* label,
564 Patchability patchable) { 601 Patchability patchable) {
565 const int32_t offset = ObjectPool::element_offset( 602 const int32_t offset = ObjectPool::element_offset(
566 object_pool_wrapper_.FindExternalLabel(label, patchable)); 603 object_pool_wrapper_.FindExternalLabel(label, patchable));
567 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag); 604 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag);
568 } 605 }
569 606
570 607
608 void Assembler::LoadFunctionFromCalleePool(Register dst,
609 const Function& function,
610 Register new_pp) {
611 const int32_t offset =
612 ObjectPool::element_offset(object_pool_wrapper_.FindObject(function));
613 LoadWordFromPoolOffset(dst, offset - kHeapObjectTag, new_pp);
614 }
615
616
571 void Assembler::LoadNativeEntry(Register rd, 617 void Assembler::LoadNativeEntry(Register rd,
572 const ExternalLabel* label, 618 const ExternalLabel* label,
573 Patchability patchable) { 619 Patchability patchable) {
574 const int32_t offset = ObjectPool::element_offset( 620 const int32_t offset = ObjectPool::element_offset(
575 object_pool_wrapper_.FindNativeEntry(label, patchable)); 621 object_pool_wrapper_.FindNativeEntry(label, patchable));
576 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag); 622 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag);
577 } 623 }
578 624
579 625
580 void Assembler::PushObject(const Object& object) { 626 void Assembler::PushObject(const Object& object) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 // Preserve T0. 684 // Preserve T0.
639 addiu(SP, SP, Immediate(-2 * kWordSize)); 685 addiu(SP, SP, Immediate(-2 * kWordSize));
640 sw(T0, Address(SP, 1 * kWordSize)); 686 sw(T0, Address(SP, 1 * kWordSize));
641 } else { 687 } else {
642 addiu(SP, SP, Immediate(-1 * kWordSize)); 688 addiu(SP, SP, Immediate(-1 * kWordSize));
643 } 689 }
644 sw(RA, Address(SP, 0 * kWordSize)); 690 sw(RA, Address(SP, 0 * kWordSize));
645 if (object != T0) { 691 if (object != T0) {
646 mov(T0, object); 692 mov(T0, object);
647 } 693 }
694 lw(CODE_REG, Address(THR, Thread::update_store_buffer_code_offset()));
648 lw(T9, Address(THR, Thread::update_store_buffer_entry_point_offset())); 695 lw(T9, Address(THR, Thread::update_store_buffer_entry_point_offset()));
649 jalr(T9); 696 jalr(T9);
650 lw(RA, Address(SP, 0 * kWordSize)); 697 lw(RA, Address(SP, 0 * kWordSize));
651 if (value != T0) { 698 if (value != T0) {
652 // Restore T0. 699 // Restore T0.
653 lw(T0, Address(SP, 1 * kWordSize)); 700 lw(T0, Address(SP, 1 * kWordSize));
654 addiu(SP, SP, Immediate(2 * kWordSize)); 701 addiu(SP, SP, Immediate(2 * kWordSize));
655 } else { 702 } else {
656 addiu(SP, SP, Immediate(1 * kWordSize)); 703 addiu(SP, SP, Immediate(1 * kWordSize));
657 } 704 }
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 void Assembler::LeaveFrameAndReturn() { 879 void Assembler::LeaveFrameAndReturn() {
833 ASSERT(!in_delay_slot_); 880 ASSERT(!in_delay_slot_);
834 mov(SP, FP); 881 mov(SP, FP);
835 lw(RA, Address(SP, 1 * kWordSize)); 882 lw(RA, Address(SP, 1 * kWordSize));
836 lw(FP, Address(SP, 0 * kWordSize)); 883 lw(FP, Address(SP, 0 * kWordSize));
837 Ret(); 884 Ret();
838 delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize)); 885 delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize));
839 } 886 }
840 887
841 888
842 void Assembler::EnterStubFrame() { 889 void Assembler::EnterStubFrame(intptr_t frame_size) {
843 ASSERT(!in_delay_slot_); 890 EnterDartFrame(frame_size);
844 SetPrologueOffset();
845 addiu(SP, SP, Immediate(-4 * kWordSize));
846 sw(ZR, Address(SP, 3 * kWordSize)); // PC marker is 0 in stubs.
847 sw(RA, Address(SP, 2 * kWordSize));
848 sw(FP, Address(SP, 1 * kWordSize));
849 sw(PP, Address(SP, 0 * kWordSize));
850 addiu(FP, SP, Immediate(1 * kWordSize));
851 // Setup pool pointer for this stub.
852 LoadPoolPointer();
853 } 891 }
854 892
855 893
856 void Assembler::LeaveStubFrame() { 894 void Assembler::LeaveStubFrame() {
857 LeaveDartFrame(); 895 LeaveDartFrame();
858 } 896 }
859 897
860 898
861 void Assembler::LeaveStubFrameAndReturn(Register ra) { 899 void Assembler::LeaveStubFrameAndReturn(Register ra) {
862 ASSERT(!in_delay_slot_); 900 LeaveDartFrameAndReturn(ra);
863 addiu(SP, FP, Immediate(-1 * kWordSize));
864 lw(RA, Address(SP, 2 * kWordSize));
865 lw(FP, Address(SP, 1 * kWordSize));
866 lw(PP, Address(SP, 0 * kWordSize));
867 jr(ra);
868 delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize));
869 } 901 }
870 902
871 903
872 void Assembler::UpdateAllocationStats(intptr_t cid, 904 void Assembler::UpdateAllocationStats(intptr_t cid,
873 Register temp_reg, 905 Register temp_reg,
874 Heap::Space space, 906 Heap::Space space,
875 bool inline_isolate) { 907 bool inline_isolate) {
876 ASSERT(!in_delay_slot_); 908 ASSERT(!in_delay_slot_);
877 ASSERT(temp_reg != kNoRegister); 909 ASSERT(temp_reg != kNoRegister);
878 ASSERT(temp_reg != TMP); 910 ASSERT(temp_reg != TMP);
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1078 1110
1079 1111
1080 void Assembler::CallRuntime(const RuntimeEntry& entry, 1112 void Assembler::CallRuntime(const RuntimeEntry& entry,
1081 intptr_t argument_count) { 1113 intptr_t argument_count) {
1082 entry.Call(this, argument_count); 1114 entry.Call(this, argument_count);
1083 } 1115 }
1084 1116
1085 1117
1086 void Assembler::EnterDartFrame(intptr_t frame_size) { 1118 void Assembler::EnterDartFrame(intptr_t frame_size) {
1087 ASSERT(!in_delay_slot_); 1119 ASSERT(!in_delay_slot_);
1088 const intptr_t offset = CodeSize();
1089 1120
1090 SetPrologueOffset(); 1121 SetPrologueOffset();
1091 1122
1092 addiu(SP, SP, Immediate(-4 * kWordSize)); 1123 addiu(SP, SP, Immediate(-4 * kWordSize));
1093 sw(RA, Address(SP, 2 * kWordSize)); 1124 sw(RA, Address(SP, 3 * kWordSize));
1094 sw(FP, Address(SP, 1 * kWordSize)); 1125 sw(FP, Address(SP, 2 * kWordSize));
1126 sw(CODE_REG, Address(SP, 1 * kWordSize));
1095 sw(PP, Address(SP, 0 * kWordSize)); 1127 sw(PP, Address(SP, 0 * kWordSize));
1096 1128
1097 GetNextPC(TMP); // TMP gets the address of the next instruction. 1129 // Set FP to the saved previous FP.
1130 addiu(FP, SP, Immediate(2 * kWordSize));
1098 1131
1099 // Calculate the offset of the pool pointer from the PC. 1132 LoadPoolPointer();
1100 const intptr_t object_pool_pc_dist =
1101 Instructions::HeaderSize() - Instructions::object_pool_offset() +
1102 CodeSize();
1103
1104 // Save PC in frame for fast identification of corresponding code.
1105 AddImmediate(TMP, -offset);
1106 sw(TMP, Address(SP, 3 * kWordSize));
1107
1108 // Set FP to the saved previous FP.
1109 addiu(FP, SP, Immediate(kWordSize));
1110
1111 // Load the pool pointer. offset has already been subtracted from TMP.
1112 lw(PP, Address(TMP, -object_pool_pc_dist + offset));
1113 1133
1114 // Reserve space for locals. 1134 // Reserve space for locals.
1115 AddImmediate(SP, -frame_size); 1135 AddImmediate(SP, -frame_size);
1116 } 1136 }
1117 1137
1118 1138
1119 // On entry to a function compiled for OSR, the caller's frame pointer, the 1139 // On entry to a function compiled for OSR, the caller's frame pointer, the
1120 // stack locals, and any copied parameters are already in place. The frame 1140 // stack locals, and any copied parameters are already in place. The frame
1121 // pointer is already set up. The PC marker is not correct for the 1141 // pointer is already set up. The PC marker is not correct for the
1122 // optimized function and there may be extra space for spill slots to 1142 // optimized function and there may be extra space for spill slots to
1123 // allocate. We must also set up the pool pointer for the function. 1143 // allocate. We must also set up the pool pointer for the function.
1124 void Assembler::EnterOsrFrame(intptr_t extra_size) { 1144 void Assembler::EnterOsrFrame(intptr_t extra_size) {
1125 ASSERT(!in_delay_slot_); 1145 ASSERT(!in_delay_slot_);
1126 Comment("EnterOsrFrame"); 1146 Comment("EnterOsrFrame");
1127 1147
1128 GetNextPC(TMP); // TMP gets the address of the next instruction.
1129
1130 // The runtime system assumes that the code marker address is
1131 // kEntryPointToPcMarkerOffset bytes from the entry. Since there is no
1132 // code to set up the frame pointer, etc., the address needs to be adjusted.
1133 const intptr_t offset = EntryPointToPcMarkerOffset() - CodeSize();
1134 // Calculate the offset of the pool pointer from the PC.
1135 const intptr_t object_pool_pc_dist =
1136 Instructions::HeaderSize() - Instructions::object_pool_offset() +
1137 CodeSize();
1138
1139 // Adjust PC by the offset, and store it in the stack frame.
1140 AddImmediate(TMP, TMP, offset);
1141 sw(TMP, Address(FP, kPcMarkerSlotFromFp * kWordSize));
1142
1143 // Restore return address. 1148 // Restore return address.
1144 lw(RA, Address(FP, 1 * kWordSize)); 1149 lw(RA, Address(FP, 1 * kWordSize));
1145 1150
1146 // Load the pool pointer. offset has already been subtracted from temp. 1151 // Load the pool pointer. offset has already been subtracted from temp.
1147 lw(PP, Address(TMP, -object_pool_pc_dist - offset)); 1152 RestoreCodePointer();
1153 LoadPoolPointer();
1148 1154
1149 // Reserve space for locals. 1155 // Reserve space for locals.
1150 AddImmediate(SP, -extra_size); 1156 AddImmediate(SP, -extra_size);
1151 } 1157 }
1152 1158
1153 1159
1154 void Assembler::LeaveDartFrame() { 1160 void Assembler::LeaveDartFrame(RestorePP restore_pp) {
1155 ASSERT(!in_delay_slot_); 1161 ASSERT(!in_delay_slot_);
1156 addiu(SP, FP, Immediate(-kWordSize)); 1162 addiu(SP, FP, Immediate(-2 * kWordSize));
1157 1163
1158 lw(RA, Address(SP, 2 * kWordSize)); 1164 lw(RA, Address(SP, 3 * kWordSize));
1159 lw(FP, Address(SP, 1 * kWordSize)); 1165 lw(FP, Address(SP, 2 * kWordSize));
1160 lw(PP, Address(SP, 0 * kWordSize)); 1166 if (restore_pp == kRestoreCallerPP) {
1167 lw(PP, Address(SP, 0 * kWordSize));
1168 }
1161 1169
1162 // Adjust SP for PC, RA, FP, PP pushed in EnterDartFrame. 1170 // Adjust SP for PC, RA, FP, PP pushed in EnterDartFrame.
1163 addiu(SP, SP, Immediate(4 * kWordSize)); 1171 addiu(SP, SP, Immediate(4 * kWordSize));
1164 } 1172 }
1165 1173
1166 1174
1167 void Assembler::LeaveDartFrameAndReturn() { 1175 void Assembler::LeaveDartFrameAndReturn(Register ra) {
1168 ASSERT(!in_delay_slot_); 1176 ASSERT(!in_delay_slot_);
1169 addiu(SP, FP, Immediate(-kWordSize)); 1177 addiu(SP, FP, Immediate(-2 * kWordSize));
1170 1178
1171 lw(RA, Address(SP, 2 * kWordSize)); 1179 lw(RA, Address(SP, 3 * kWordSize));
1172 lw(FP, Address(SP, 1 * kWordSize)); 1180 lw(FP, Address(SP, 2 * kWordSize));
1173 lw(PP, Address(SP, 0 * kWordSize)); 1181 lw(PP, Address(SP, 0 * kWordSize));
1174 1182
1175 // Adjust SP for PC, RA, FP, PP pushed in EnterDartFrame, and return. 1183 // Adjust SP for PC, RA, FP, PP pushed in EnterDartFrame, and return.
1176 Ret(); 1184 jr(ra);
1177 delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); 1185 delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize));
1178 } 1186 }
1179 1187
1180 1188
1181 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { 1189 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
1182 ASSERT(!in_delay_slot_); 1190 ASSERT(!in_delay_slot_);
1183 // Reserve space for arguments and align frame before entering 1191 // Reserve space for arguments and align frame before entering
1184 // the C++ world. 1192 // the C++ world.
1185 AddImmediate(SP, -frame_space); 1193 AddImmediate(SP, -frame_space);
1186 if (OS::ActivationFrameAlignment() > 1) { 1194 if (OS::ActivationFrameAlignment() > 1) {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1345 Label stop; 1353 Label stop;
1346 b(&stop); 1354 b(&stop);
1347 Emit(reinterpret_cast<int32_t>(message)); 1355 Emit(reinterpret_cast<int32_t>(message));
1348 Bind(&stop); 1356 Bind(&stop);
1349 break_(Instr::kStopMessageCode); 1357 break_(Instr::kStopMessageCode);
1350 } 1358 }
1351 1359
1352 } // namespace dart 1360 } // namespace dart
1353 1361
1354 #endif // defined TARGET_ARCH_MIPS 1362 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/assembler_mips.h ('k') | runtime/vm/assembler_mips_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698