| OLD | NEW |
| 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 Loading... |
| 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, | 358 void Assembler::LoadWordFromPoolOffset(Register rd, int32_t offset) { |
| 359 int32_t offset, | 359 ASSERT(constant_pool_allowed()); |
| 360 Register pp) { | |
| 361 ASSERT((pp != PP) || constant_pool_allowed()); | |
| 362 ASSERT(!in_delay_slot_); | 360 ASSERT(!in_delay_slot_); |
| 363 ASSERT(rd != pp); | 361 ASSERT(rd != PP); |
| 364 if (Address::CanHoldOffset(offset)) { | 362 if (Address::CanHoldOffset(offset)) { |
| 365 lw(rd, Address(pp, offset)); | 363 lw(rd, Address(PP, offset)); |
| 366 } else { | 364 } else { |
| 367 const int16_t offset_low = Utils::Low16Bits(offset); // Signed. | 365 const int16_t offset_low = Utils::Low16Bits(offset); // Signed. |
| 368 offset -= offset_low; | 366 offset -= offset_low; |
| 369 const uint16_t offset_high = Utils::High16Bits(offset); // Unsigned. | 367 const uint16_t offset_high = Utils::High16Bits(offset); // Unsigned. |
| 370 if (offset_high != 0) { | 368 if (offset_high != 0) { |
| 371 lui(rd, Immediate(offset_high)); | 369 lui(rd, Immediate(offset_high)); |
| 372 addu(rd, rd, pp); | 370 addu(rd, rd, PP); |
| 373 lw(rd, Address(rd, offset_low)); | 371 lw(rd, Address(rd, offset_low)); |
| 374 } else { | 372 } else { |
| 375 lw(rd, Address(pp, offset_low)); | 373 lw(rd, Address(PP, offset_low)); |
| 376 } | 374 } |
| 377 } | 375 } |
| 378 } | 376 } |
| 379 | 377 |
| 380 | 378 |
| 381 void Assembler::AdduDetectOverflow(Register rd, Register rs, Register rt, | 379 void Assembler::AdduDetectOverflow(Register rd, Register rs, Register rt, |
| 382 Register ro, Register scratch) { | 380 Register ro, Register scratch) { |
| 383 ASSERT(!in_delay_slot_); | 381 ASSERT(!in_delay_slot_); |
| 384 ASSERT(rd != ro); | 382 ASSERT(rd != ro); |
| 385 ASSERT(rd != TMP); | 383 ASSERT(rd != TMP); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 and_(ro, TMP, ro); | 450 and_(ro, TMP, ro); |
| 453 } else { | 451 } else { |
| 454 subu(rd, rs, rt); | 452 subu(rd, rs, rt); |
| 455 xor_(ro, rd, rs); | 453 xor_(ro, rd, rs); |
| 456 xor_(TMP, rs, rt); | 454 xor_(TMP, rs, rt); |
| 457 and_(ro, TMP, ro); | 455 and_(ro, TMP, ro); |
| 458 } | 456 } |
| 459 } | 457 } |
| 460 | 458 |
| 461 | 459 |
| 462 void Assembler::CheckCodePointer() { | 460 void Assembler::Branch(const StubEntry& stub_entry) { |
| 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) { | |
| 492 ASSERT(!in_delay_slot_); | 461 ASSERT(!in_delay_slot_); |
| 493 const Code& target_code = Code::Handle(stub_entry.code()); | 462 LoadImmediate(TMP, stub_entry.label().address()); |
| 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())); | |
| 498 jr(TMP); | 463 jr(TMP); |
| 499 } | 464 } |
| 500 | 465 |
| 501 | 466 |
| 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 |
| 502 void Assembler::BranchLink(const ExternalLabel* label) { | 479 void Assembler::BranchLink(const ExternalLabel* label) { |
| 503 ASSERT(!in_delay_slot_); | 480 ASSERT(!in_delay_slot_); |
| 504 LoadImmediate(T9, label->address()); | 481 LoadImmediate(T9, label->address()); |
| 505 jalr(T9); | 482 jalr(T9); |
| 506 } | 483 } |
| 507 | 484 |
| 508 | 485 |
| 509 void Assembler::BranchLink(const ExternalLabel* label, Patchability patchable) { | 486 void Assembler::BranchLink(const ExternalLabel* label, Patchability patchable) { |
| 510 ASSERT(!in_delay_slot_); | 487 ASSERT(!in_delay_slot_); |
| 511 const int32_t offset = ObjectPool::element_offset( | 488 const int32_t offset = ObjectPool::element_offset( |
| 512 object_pool_wrapper_.FindExternalLabel(label, patchable)); | 489 object_pool_wrapper_.FindExternalLabel(label, patchable)); |
| 513 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag); | 490 LoadWordFromPoolOffset(T9, offset - kHeapObjectTag); |
| 514 lw(T9, FieldAddress(CODE_REG, Code::entry_point_offset())); | |
| 515 jalr(T9); | 491 jalr(T9); |
| 516 if (patchable == kPatchable) { | 492 if (patchable == kPatchable) { |
| 517 delay_slot_available_ = false; // CodePatcher expects a nop. | 493 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. | |
| 531 } | 494 } |
| 532 } | 495 } |
| 533 | 496 |
| 534 | 497 |
| 535 void Assembler::BranchLink(const StubEntry& stub_entry, | 498 void Assembler::BranchLink(const StubEntry& stub_entry, |
| 536 Patchability patchable) { | 499 Patchability patchable) { |
| 537 BranchLink(Code::Handle(stub_entry.code()), patchable); | 500 BranchLink(&stub_entry.label(), patchable); |
| 538 } | 501 } |
| 539 | 502 |
| 540 | 503 |
| 541 void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) { | 504 void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) { |
| 542 BranchLink(Code::Handle(stub_entry.code()), kPatchable); | 505 BranchLink(&stub_entry.label(), kPatchable); |
| 543 } | 506 } |
| 544 | 507 |
| 545 | 508 |
| 546 void Assembler::LoadObjectHelper(Register rd, | 509 void Assembler::LoadObjectHelper(Register rd, |
| 547 const Object& object, | 510 const Object& object, |
| 548 bool is_unique) { | 511 bool is_unique) { |
| 549 // Load common VM constants from the thread. This works also in places where | 512 // Load common VM constants from the thread. This works also in places where |
| 550 // no constant pool is set up (e.g. intrinsic code). | 513 // no constant pool is set up (e.g. intrinsic code). |
| 551 if (Thread::CanLoadFromThread(object)) { | 514 if (Thread::CanLoadFromThread(object)) { |
| 552 lw(rd, Address(THR, Thread::OffsetFromThread(object))); | 515 lw(rd, Address(THR, Thread::OffsetFromThread(object))); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 | 550 |
| 588 void Assembler::LoadExternalLabel(Register rd, | 551 void Assembler::LoadExternalLabel(Register rd, |
| 589 const ExternalLabel* label, | 552 const ExternalLabel* label, |
| 590 Patchability patchable) { | 553 Patchability patchable) { |
| 591 const int32_t offset = ObjectPool::element_offset( | 554 const int32_t offset = ObjectPool::element_offset( |
| 592 object_pool_wrapper_.FindExternalLabel(label, patchable)); | 555 object_pool_wrapper_.FindExternalLabel(label, patchable)); |
| 593 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag); | 556 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag); |
| 594 } | 557 } |
| 595 | 558 |
| 596 | 559 |
| 597 void Assembler::LoadFunctionFromCalleePool(Register dst, | |
| 598 const Function& function, | |
| 599 Register new_pp) { | |
| 600 const int32_t offset = | |
| 601 ObjectPool::element_offset(object_pool_wrapper_.FindObject(function)); | |
| 602 LoadWordFromPoolOffset(dst, offset - kHeapObjectTag, new_pp); | |
| 603 } | |
| 604 | |
| 605 | |
| 606 void Assembler::LoadNativeEntry(Register rd, | 560 void Assembler::LoadNativeEntry(Register rd, |
| 607 const ExternalLabel* label, | 561 const ExternalLabel* label, |
| 608 Patchability patchable) { | 562 Patchability patchable) { |
| 609 const int32_t offset = ObjectPool::element_offset( | 563 const int32_t offset = ObjectPool::element_offset( |
| 610 object_pool_wrapper_.FindNativeEntry(label, patchable)); | 564 object_pool_wrapper_.FindNativeEntry(label, patchable)); |
| 611 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag); | 565 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag); |
| 612 } | 566 } |
| 613 | 567 |
| 614 | 568 |
| 615 void Assembler::PushObject(const Object& object) { | 569 void Assembler::PushObject(const Object& object) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 // Preserve T0. | 627 // Preserve T0. |
| 674 addiu(SP, SP, Immediate(-2 * kWordSize)); | 628 addiu(SP, SP, Immediate(-2 * kWordSize)); |
| 675 sw(T0, Address(SP, 1 * kWordSize)); | 629 sw(T0, Address(SP, 1 * kWordSize)); |
| 676 } else { | 630 } else { |
| 677 addiu(SP, SP, Immediate(-1 * kWordSize)); | 631 addiu(SP, SP, Immediate(-1 * kWordSize)); |
| 678 } | 632 } |
| 679 sw(RA, Address(SP, 0 * kWordSize)); | 633 sw(RA, Address(SP, 0 * kWordSize)); |
| 680 if (object != T0) { | 634 if (object != T0) { |
| 681 mov(T0, object); | 635 mov(T0, object); |
| 682 } | 636 } |
| 683 lw(CODE_REG, Address(THR, Thread::update_store_buffer_code_offset())); | |
| 684 lw(T9, Address(THR, Thread::update_store_buffer_entry_point_offset())); | 637 lw(T9, Address(THR, Thread::update_store_buffer_entry_point_offset())); |
| 685 jalr(T9); | 638 jalr(T9); |
| 686 lw(RA, Address(SP, 0 * kWordSize)); | 639 lw(RA, Address(SP, 0 * kWordSize)); |
| 687 if (value != T0) { | 640 if (value != T0) { |
| 688 // Restore T0. | 641 // Restore T0. |
| 689 lw(T0, Address(SP, 1 * kWordSize)); | 642 lw(T0, Address(SP, 1 * kWordSize)); |
| 690 addiu(SP, SP, Immediate(2 * kWordSize)); | 643 addiu(SP, SP, Immediate(2 * kWordSize)); |
| 691 } else { | 644 } else { |
| 692 addiu(SP, SP, Immediate(1 * kWordSize)); | 645 addiu(SP, SP, Immediate(1 * kWordSize)); |
| 693 } | 646 } |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 void Assembler::LeaveFrameAndReturn() { | 821 void Assembler::LeaveFrameAndReturn() { |
| 869 ASSERT(!in_delay_slot_); | 822 ASSERT(!in_delay_slot_); |
| 870 mov(SP, FP); | 823 mov(SP, FP); |
| 871 lw(RA, Address(SP, 1 * kWordSize)); | 824 lw(RA, Address(SP, 1 * kWordSize)); |
| 872 lw(FP, Address(SP, 0 * kWordSize)); | 825 lw(FP, Address(SP, 0 * kWordSize)); |
| 873 Ret(); | 826 Ret(); |
| 874 delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize)); | 827 delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize)); |
| 875 } | 828 } |
| 876 | 829 |
| 877 | 830 |
| 878 void Assembler::EnterStubFrame(intptr_t frame_size) { | 831 void Assembler::EnterStubFrame() { |
| 879 EnterDartFrame(frame_size); | 832 ASSERT(!in_delay_slot_); |
| 833 SetPrologueOffset(); |
| 834 addiu(SP, SP, Immediate(-4 * kWordSize)); |
| 835 sw(ZR, Address(SP, 3 * kWordSize)); // PC marker is 0 in stubs. |
| 836 sw(RA, Address(SP, 2 * kWordSize)); |
| 837 sw(FP, Address(SP, 1 * kWordSize)); |
| 838 sw(PP, Address(SP, 0 * kWordSize)); |
| 839 addiu(FP, SP, Immediate(1 * kWordSize)); |
| 840 // Setup pool pointer for this stub. |
| 841 LoadPoolPointer(); |
| 880 } | 842 } |
| 881 | 843 |
| 882 | 844 |
| 883 void Assembler::LeaveStubFrame() { | 845 void Assembler::LeaveStubFrame() { |
| 884 LeaveDartFrame(); | 846 LeaveDartFrame(); |
| 885 } | 847 } |
| 886 | 848 |
| 887 | 849 |
| 888 void Assembler::LeaveStubFrameAndReturn(Register ra) { | 850 void Assembler::LeaveStubFrameAndReturn(Register ra) { |
| 889 LeaveDartFrameAndReturn(ra); | 851 ASSERT(!in_delay_slot_); |
| 852 addiu(SP, FP, Immediate(-1 * kWordSize)); |
| 853 lw(RA, Address(SP, 2 * kWordSize)); |
| 854 lw(FP, Address(SP, 1 * kWordSize)); |
| 855 lw(PP, Address(SP, 0 * kWordSize)); |
| 856 jr(ra); |
| 857 delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); |
| 890 } | 858 } |
| 891 | 859 |
| 892 | 860 |
| 893 void Assembler::UpdateAllocationStats(intptr_t cid, | 861 void Assembler::UpdateAllocationStats(intptr_t cid, |
| 894 Register temp_reg, | 862 Register temp_reg, |
| 895 Heap::Space space, | 863 Heap::Space space, |
| 896 bool inline_isolate) { | 864 bool inline_isolate) { |
| 897 ASSERT(!in_delay_slot_); | 865 ASSERT(!in_delay_slot_); |
| 898 ASSERT(temp_reg != kNoRegister); | 866 ASSERT(temp_reg != kNoRegister); |
| 899 ASSERT(temp_reg != TMP); | 867 ASSERT(temp_reg != TMP); |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1099 | 1067 |
| 1100 | 1068 |
| 1101 void Assembler::CallRuntime(const RuntimeEntry& entry, | 1069 void Assembler::CallRuntime(const RuntimeEntry& entry, |
| 1102 intptr_t argument_count) { | 1070 intptr_t argument_count) { |
| 1103 entry.Call(this, argument_count); | 1071 entry.Call(this, argument_count); |
| 1104 } | 1072 } |
| 1105 | 1073 |
| 1106 | 1074 |
| 1107 void Assembler::EnterDartFrame(intptr_t frame_size) { | 1075 void Assembler::EnterDartFrame(intptr_t frame_size) { |
| 1108 ASSERT(!in_delay_slot_); | 1076 ASSERT(!in_delay_slot_); |
| 1077 const intptr_t offset = CodeSize(); |
| 1109 | 1078 |
| 1110 SetPrologueOffset(); | 1079 SetPrologueOffset(); |
| 1111 | 1080 |
| 1112 addiu(SP, SP, Immediate(-4 * kWordSize)); | 1081 addiu(SP, SP, Immediate(-4 * kWordSize)); |
| 1113 sw(RA, Address(SP, 3 * kWordSize)); | 1082 sw(RA, Address(SP, 2 * kWordSize)); |
| 1114 sw(FP, Address(SP, 2 * kWordSize)); | 1083 sw(FP, Address(SP, 1 * kWordSize)); |
| 1115 sw(CODE_REG, Address(SP, 1 * kWordSize)); | |
| 1116 sw(PP, Address(SP, 0 * kWordSize)); | 1084 sw(PP, Address(SP, 0 * kWordSize)); |
| 1117 | 1085 |
| 1086 GetNextPC(TMP); // TMP gets the address of the next instruction. |
| 1087 |
| 1088 // Calculate the offset of the pool pointer from the PC. |
| 1089 const intptr_t object_pool_pc_dist = |
| 1090 Instructions::HeaderSize() - Instructions::object_pool_offset() + |
| 1091 CodeSize(); |
| 1092 |
| 1093 // Save PC in frame for fast identification of corresponding code. |
| 1094 AddImmediate(TMP, -offset); |
| 1095 sw(TMP, Address(SP, 3 * kWordSize)); |
| 1096 |
| 1118 // Set FP to the saved previous FP. | 1097 // Set FP to the saved previous FP. |
| 1119 addiu(FP, SP, Immediate(2 * kWordSize)); | 1098 addiu(FP, SP, Immediate(kWordSize)); |
| 1120 | 1099 |
| 1121 LoadPoolPointer(); | 1100 // Load the pool pointer. offset has already been subtracted from TMP. |
| 1101 lw(PP, Address(TMP, -object_pool_pc_dist + offset)); |
| 1122 | 1102 |
| 1123 // Reserve space for locals. | 1103 // Reserve space for locals. |
| 1124 AddImmediate(SP, -frame_size); | 1104 AddImmediate(SP, -frame_size); |
| 1125 } | 1105 } |
| 1126 | 1106 |
| 1127 | 1107 |
| 1128 // On entry to a function compiled for OSR, the caller's frame pointer, the | 1108 // On entry to a function compiled for OSR, the caller's frame pointer, the |
| 1129 // stack locals, and any copied parameters are already in place. The frame | 1109 // stack locals, and any copied parameters are already in place. The frame |
| 1130 // pointer is already set up. The PC marker is not correct for the | 1110 // pointer is already set up. The PC marker is not correct for the |
| 1131 // optimized function and there may be extra space for spill slots to | 1111 // optimized function and there may be extra space for spill slots to |
| 1132 // allocate. We must also set up the pool pointer for the function. | 1112 // allocate. We must also set up the pool pointer for the function. |
| 1133 void Assembler::EnterOsrFrame(intptr_t extra_size) { | 1113 void Assembler::EnterOsrFrame(intptr_t extra_size) { |
| 1134 ASSERT(!in_delay_slot_); | 1114 ASSERT(!in_delay_slot_); |
| 1135 Comment("EnterOsrFrame"); | 1115 Comment("EnterOsrFrame"); |
| 1136 | 1116 |
| 1117 GetNextPC(TMP); // TMP gets the address of the next instruction. |
| 1118 |
| 1119 // The runtime system assumes that the code marker address is |
| 1120 // kEntryPointToPcMarkerOffset bytes from the entry. Since there is no |
| 1121 // code to set up the frame pointer, etc., the address needs to be adjusted. |
| 1122 const intptr_t offset = EntryPointToPcMarkerOffset() - CodeSize(); |
| 1123 // Calculate the offset of the pool pointer from the PC. |
| 1124 const intptr_t object_pool_pc_dist = |
| 1125 Instructions::HeaderSize() - Instructions::object_pool_offset() + |
| 1126 CodeSize(); |
| 1127 |
| 1128 // Adjust PC by the offset, and store it in the stack frame. |
| 1129 AddImmediate(TMP, TMP, offset); |
| 1130 sw(TMP, Address(FP, kPcMarkerSlotFromFp * kWordSize)); |
| 1131 |
| 1137 // Restore return address. | 1132 // Restore return address. |
| 1138 lw(RA, Address(FP, 1 * kWordSize)); | 1133 lw(RA, Address(FP, 1 * kWordSize)); |
| 1139 | 1134 |
| 1140 // Load the pool pointer. offset has already been subtracted from temp. | 1135 // Load the pool pointer. offset has already been subtracted from temp. |
| 1141 RestoreCodePointer(); | 1136 lw(PP, Address(TMP, -object_pool_pc_dist - offset)); |
| 1142 LoadPoolPointer(); | |
| 1143 | 1137 |
| 1144 // Reserve space for locals. | 1138 // Reserve space for locals. |
| 1145 AddImmediate(SP, -extra_size); | 1139 AddImmediate(SP, -extra_size); |
| 1146 } | 1140 } |
| 1147 | 1141 |
| 1148 | 1142 |
| 1149 void Assembler::LeaveDartFrame(RestorePP restore_pp) { | 1143 void Assembler::LeaveDartFrame() { |
| 1150 ASSERT(!in_delay_slot_); | 1144 ASSERT(!in_delay_slot_); |
| 1151 addiu(SP, FP, Immediate(-2 * kWordSize)); | 1145 addiu(SP, FP, Immediate(-kWordSize)); |
| 1152 | 1146 |
| 1153 lw(RA, Address(SP, 3 * kWordSize)); | 1147 lw(RA, Address(SP, 2 * kWordSize)); |
| 1154 lw(FP, Address(SP, 2 * kWordSize)); | 1148 lw(FP, Address(SP, 1 * kWordSize)); |
| 1155 if (restore_pp == kRestoreCallerPP) { | 1149 lw(PP, Address(SP, 0 * kWordSize)); |
| 1156 lw(PP, Address(SP, 0 * kWordSize)); | |
| 1157 } | |
| 1158 | 1150 |
| 1159 // Adjust SP for PC, RA, FP, PP pushed in EnterDartFrame. | 1151 // Adjust SP for PC, RA, FP, PP pushed in EnterDartFrame. |
| 1160 addiu(SP, SP, Immediate(4 * kWordSize)); | 1152 addiu(SP, SP, Immediate(4 * kWordSize)); |
| 1161 } | 1153 } |
| 1162 | 1154 |
| 1163 | 1155 |
| 1164 void Assembler::LeaveDartFrameAndReturn(Register ra) { | 1156 void Assembler::LeaveDartFrameAndReturn() { |
| 1165 ASSERT(!in_delay_slot_); | 1157 ASSERT(!in_delay_slot_); |
| 1166 addiu(SP, FP, Immediate(-2 * kWordSize)); | 1158 addiu(SP, FP, Immediate(-kWordSize)); |
| 1167 | 1159 |
| 1168 lw(RA, Address(SP, 3 * kWordSize)); | 1160 lw(RA, Address(SP, 2 * kWordSize)); |
| 1169 lw(FP, Address(SP, 2 * kWordSize)); | 1161 lw(FP, Address(SP, 1 * kWordSize)); |
| 1170 lw(PP, Address(SP, 0 * kWordSize)); | 1162 lw(PP, Address(SP, 0 * kWordSize)); |
| 1171 | 1163 |
| 1172 // Adjust SP for PC, RA, FP, PP pushed in EnterDartFrame, and return. | 1164 // Adjust SP for PC, RA, FP, PP pushed in EnterDartFrame, and return. |
| 1173 jr(ra); | 1165 Ret(); |
| 1174 delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); | 1166 delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); |
| 1175 } | 1167 } |
| 1176 | 1168 |
| 1177 | 1169 |
| 1178 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { | 1170 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { |
| 1179 ASSERT(!in_delay_slot_); | 1171 ASSERT(!in_delay_slot_); |
| 1180 // Reserve space for arguments and align frame before entering | 1172 // Reserve space for arguments and align frame before entering |
| 1181 // the C++ world. | 1173 // the C++ world. |
| 1182 AddImmediate(SP, -frame_space); | 1174 AddImmediate(SP, -frame_space); |
| 1183 if (OS::ActivationFrameAlignment() > 1) { | 1175 if (OS::ActivationFrameAlignment() > 1) { |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1342 Label stop; | 1334 Label stop; |
| 1343 b(&stop); | 1335 b(&stop); |
| 1344 Emit(reinterpret_cast<int32_t>(message)); | 1336 Emit(reinterpret_cast<int32_t>(message)); |
| 1345 Bind(&stop); | 1337 Bind(&stop); |
| 1346 break_(Instr::kStopMessageCode); | 1338 break_(Instr::kStopMessageCode); |
| 1347 } | 1339 } |
| 1348 | 1340 |
| 1349 } // namespace dart | 1341 } // namespace dart |
| 1350 | 1342 |
| 1351 #endif // defined TARGET_ARCH_MIPS | 1343 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |