| 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 #ifndef VM_ASSEMBLER_MIPS_H_ | 5 #ifndef VM_ASSEMBLER_MIPS_H_ |
| 6 #define VM_ASSEMBLER_MIPS_H_ | 6 #define VM_ASSEMBLER_MIPS_H_ |
| 7 | 7 |
| 8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
| 9 #error Do not include assembler_mips.h directly; use assembler.h instead. | 9 #error Do not include assembler_mips.h directly; use assembler.h instead. |
| 10 #endif | 10 #endif |
| 11 | 11 |
| 12 #include "platform/assert.h" | 12 #include "platform/assert.h" |
| 13 #include "platform/utils.h" |
| 13 #include "vm/constants_mips.h" | 14 #include "vm/constants_mips.h" |
| 15 #include "vm/simulator.h" |
| 14 | 16 |
| 15 // References to documentation in this file refer to: | 17 // References to documentation in this file refer to: |
| 16 // "MIPS® Architecture For Programmers Volume I-A: | 18 // "MIPS® Architecture For Programmers Volume I-A: |
| 17 // Introduction to the MIPS32® Architecture" in short "VolI-A" | 19 // Introduction to the MIPS32® Architecture" in short "VolI-A" |
| 18 // and | 20 // and |
| 19 // "MIPS® Architecture For Programmers Volume II-A: | 21 // "MIPS® Architecture For Programmers Volume II-A: |
| 20 // The MIPS32® Instruction Set" in short "VolII-A" | 22 // The MIPS32® Instruction Set" in short "VolII-A" |
| 21 namespace dart { | 23 namespace dart { |
| 22 | 24 |
| 25 // Forward declarations. |
| 26 class RuntimeEntry; |
| 27 |
| 23 class Immediate : public ValueObject { | 28 class Immediate : public ValueObject { |
| 24 public: | 29 public: |
| 25 explicit Immediate(int32_t value) : value_(value) { } | 30 explicit Immediate(int32_t value) : value_(value) { } |
| 26 | 31 |
| 27 Immediate(const Immediate& other) : ValueObject(), value_(other.value_) { } | 32 Immediate(const Immediate& other) : ValueObject(), value_(other.value_) { } |
| 28 Immediate& operator=(const Immediate& other) { | 33 Immediate& operator=(const Immediate& other) { |
| 29 value_ = other.value_; | 34 value_ = other.value_; |
| 30 return *this; | 35 return *this; |
| 31 } | 36 } |
| 32 | 37 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 } | 168 } |
| 164 | 169 |
| 165 // Set up a stub frame so that the stack traversal code can easily identify | 170 // Set up a stub frame so that the stack traversal code can easily identify |
| 166 // a stub frame. | 171 // a stub frame. |
| 167 void EnterStubFrame(); | 172 void EnterStubFrame(); |
| 168 void LeaveStubFrame(); | 173 void LeaveStubFrame(); |
| 169 | 174 |
| 170 // Instruction pattern from entrypoint is used in dart frame prologs | 175 // Instruction pattern from entrypoint is used in dart frame prologs |
| 171 // to set up the frame and save a PC which can be used to figure out the | 176 // to set up the frame and save a PC which can be used to figure out the |
| 172 // RawInstruction object corresponding to the code running in the frame. | 177 // RawInstruction object corresponding to the code running in the frame. |
| 173 static const intptr_t kOffsetOfSavedPCfromEntrypoint = -1; // UNIMPLEMENTED. | 178 // See EnterDartFrame. There are 6 instructions before we know the PC. |
| 179 static const intptr_t kOffsetOfSavedPCfromEntrypoint = 6 * Instr::kInstrSize; |
| 174 | 180 |
| 175 // Inlined allocation of an instance of class 'cls', code has no runtime | 181 // Inlined allocation of an instance of class 'cls', code has no runtime |
| 176 // calls. Jump to 'failure' if the instance cannot be allocated here. | 182 // calls. Jump to 'failure' if the instance cannot be allocated here. |
| 177 // Allocated instance is returned in 'instance_reg'. | 183 // Allocated instance is returned in 'instance_reg'. |
| 178 // Only the tags field of the object is initialized. | 184 // Only the tags field of the object is initialized. |
| 179 void TryAllocate(const Class& cls, | 185 void TryAllocate(const Class& cls, |
| 180 Label* failure, | 186 Label* failure, |
| 181 bool near_jump, | 187 bool near_jump, |
| 182 Register instance_reg) { | 188 Register instance_reg) { |
| 183 UNIMPLEMENTED(); | 189 UNIMPLEMENTED(); |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 EmitLoadStore(SW, rt, addr); | 504 EmitLoadStore(SW, rt, addr); |
| 499 } | 505 } |
| 500 | 506 |
| 501 void xor_(Register rd, Register rs, Register rt) { | 507 void xor_(Register rd, Register rs, Register rt) { |
| 502 EmitRType(SPECIAL, rs, rt, rd, 0, XOR); | 508 EmitRType(SPECIAL, rs, rt, rd, 0, XOR); |
| 503 } | 509 } |
| 504 | 510 |
| 505 // Macros in alphabetical order. | 511 // Macros in alphabetical order. |
| 506 | 512 |
| 507 void Branch(const ExternalLabel* label) { | 513 void Branch(const ExternalLabel* label) { |
| 508 // Doesn't need to be patchable, so use the delay slot. | 514 LoadImmediate(TMP, label->address()); |
| 509 if (Utils::IsInt(16, label->address())) { | 515 jr(TMP); |
| 510 jr(TMP); | |
| 511 delay_slot()->addiu(TMP, ZR, Immediate(label->address())); | |
| 512 } else { | |
| 513 const uint16_t low = Utils::Low16Bits(label->address()); | |
| 514 const uint16_t high = Utils::High16Bits(label->address()); | |
| 515 lui(TMP, Immediate(high)); | |
| 516 jr(TMP); | |
| 517 delay_slot()->ori(TMP, TMP, Immediate(low)); | |
| 518 } | |
| 519 } | 516 } |
| 520 | 517 |
| 521 void BranchLink(const ExternalLabel* label) { | 518 void BranchLink(const ExternalLabel* label) { |
| 522 // Doesn't need to be patchable, so use the delay slot. | 519 LoadImmediate(TMP, label->address()); |
| 523 if (Utils::IsInt(16, label->address())) { | 520 jalr(TMP); |
| 524 jalr(TMP); | |
| 525 delay_slot()->addiu(TMP, ZR, Immediate(label->address())); | |
| 526 } else { | |
| 527 const uint16_t low = Utils::Low16Bits(label->address()); | |
| 528 const uint16_t high = Utils::High16Bits(label->address()); | |
| 529 lui(TMP, Immediate(high)); | |
| 530 jalr(TMP); | |
| 531 delay_slot()->ori(TMP, TMP, Immediate(low)); | |
| 532 } | |
| 533 } | 521 } |
| 534 | 522 |
| 535 void BranchLinkPatchable(const ExternalLabel* label) { | 523 void BranchLinkPatchable(const ExternalLabel* label) { |
| 536 const int32_t offset = | 524 const int32_t offset = |
| 537 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag; | 525 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag; |
| 538 LoadWordFromPoolOffset(TMP, offset); | 526 LoadWordFromPoolOffset(TMP, offset); |
| 539 jalr(TMP); | 527 jalr(TMP); |
| 540 } | 528 } |
| 541 | 529 |
| 542 void BranchPatchable(const ExternalLabel* label) { | |
| 543 LoadImmediate(TMP, label->address()); | |
| 544 jr(TMP); | |
| 545 } | |
| 546 | |
| 547 // If the signed value in rs is less than value, rd is 1, and 0 otherwise. | 530 // If the signed value in rs is less than value, rd is 1, and 0 otherwise. |
| 548 void LessThanSImmediate(Register rd, Register rs, int32_t value) { | 531 void LessThanSImmediate(Register rd, Register rs, int32_t value) { |
| 549 LoadImmediate(TMP, value); | 532 LoadImmediate(TMP, value); |
| 550 slt(rd, rs, TMP); | 533 slt(rd, rs, TMP); |
| 551 } | 534 } |
| 552 | 535 |
| 553 // If the unsigned value in rs is less than value, rd is 1, and 0 otherwise. | 536 // If the unsigned value in rs is less than value, rd is 1, and 0 otherwise. |
| 554 void LessThanUImmediate(Register rd, Register rs, uint32_t value) { | 537 void LessThanUImmediate(Register rd, Register rs, uint32_t value) { |
| 555 LoadImmediate(TMP, value); | 538 LoadImmediate(TMP, value); |
| 556 sltu(rd, rs, TMP); | 539 sltu(rd, rs, TMP); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 } | 572 } |
| 590 | 573 |
| 591 void SmiTag(Register reg) { | 574 void SmiTag(Register reg) { |
| 592 sll(reg, reg, kSmiTagSize); | 575 sll(reg, reg, kSmiTagSize); |
| 593 } | 576 } |
| 594 | 577 |
| 595 void SmiUntag(Register reg) { | 578 void SmiUntag(Register reg) { |
| 596 sra(reg, reg, kSmiTagSize); | 579 sra(reg, reg, kSmiTagSize); |
| 597 } | 580 } |
| 598 | 581 |
| 582 void ReserveAlignedFrameSpace(intptr_t frame_space); |
| 583 |
| 599 void LoadWordFromPoolOffset(Register rd, int32_t offset); | 584 void LoadWordFromPoolOffset(Register rd, int32_t offset); |
| 600 void LoadObject(Register rd, const Object& object); | 585 void LoadObject(Register rd, const Object& object); |
| 601 void PushObject(const Object& object); | 586 void PushObject(const Object& object); |
| 602 | 587 |
| 603 // Sets register rd to zero if the object is equal to register rn, | 588 // Sets register rd to zero if the object is equal to register rn, |
| 604 // set to non-zero otherwise. | 589 // set to non-zero otherwise. |
| 605 void CompareObject(Register rd, Register rn, const Object& object); | 590 void CompareObject(Register rd, Register rn, const Object& object); |
| 606 | 591 |
| 592 void CallRuntime(const RuntimeEntry& entry); |
| 593 |
| 607 // Set up a Dart frame on entry with a frame pointer and PC information to | 594 // Set up a Dart frame on entry with a frame pointer and PC information to |
| 608 // enable easy access to the RawInstruction object of code corresponding | 595 // enable easy access to the RawInstruction object of code corresponding |
| 609 // to this frame. | 596 // to this frame. |
| 610 void EnterDartFrame(intptr_t frame_size); | 597 void EnterDartFrame(intptr_t frame_size); |
| 611 void LeaveDartFrame(); | 598 void LeaveDartFrame(); |
| 612 | 599 |
| 613 private: | 600 private: |
| 614 AssemblerBuffer buffer_; | 601 AssemblerBuffer buffer_; |
| 615 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. | 602 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. |
| 616 int prologue_offset_; | 603 int prologue_offset_; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 delay_slot_available_ = true; | 717 delay_slot_available_ = true; |
| 731 } | 718 } |
| 732 | 719 |
| 733 DISALLOW_ALLOCATION(); | 720 DISALLOW_ALLOCATION(); |
| 734 DISALLOW_COPY_AND_ASSIGN(Assembler); | 721 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 735 }; | 722 }; |
| 736 | 723 |
| 737 } // namespace dart | 724 } // namespace dart |
| 738 | 725 |
| 739 #endif // VM_ASSEMBLER_MIPS_H_ | 726 #endif // VM_ASSEMBLER_MIPS_H_ |
| OLD | NEW |