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 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
51 offset_ = other.offset_; | 51 offset_ = other.offset_; |
52 return *this; | 52 return *this; |
53 } | 53 } |
54 | 54 |
55 uint32_t encoding() const { | 55 uint32_t encoding() const { |
56 ASSERT(Utils::IsInt(16, offset_)); | 56 ASSERT(Utils::IsInt(16, offset_)); |
57 uint16_t imm_value = static_cast<uint16_t>(offset_); | 57 uint16_t imm_value = static_cast<uint16_t>(offset_); |
58 return (base_ << kRsShift) | imm_value; | 58 return (base_ << kRsShift) | imm_value; |
59 } | 59 } |
60 | 60 |
61 static bool CanHoldOffset(int32_t offset) { | |
62 return Utils::IsInt(16, offset); | |
63 } | |
64 | |
61 private: | 65 private: |
62 Register base_; | 66 Register base_; |
63 int32_t offset_; | 67 int32_t offset_; |
64 }; | 68 }; |
65 | 69 |
66 | 70 |
67 class FieldAddress : public Address { | 71 class FieldAddress : public Address { |
68 public: | 72 public: |
69 FieldAddress(Register base, int32_t disp) | 73 FieldAddress(Register base, int32_t disp) |
70 : Address(base, disp - kHeapObjectTag) { } | 74 : Address(base, disp - kHeapObjectTag) { } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
136 public: | 140 public: |
137 Assembler() | 141 Assembler() |
138 : buffer_(), | 142 : buffer_(), |
139 object_pool_(GrowableObjectArray::Handle()), | 143 object_pool_(GrowableObjectArray::Handle()), |
140 prologue_offset_(-1), | 144 prologue_offset_(-1), |
141 delay_slot_available_(false), | 145 delay_slot_available_(false), |
142 in_delay_slot_(false), | 146 in_delay_slot_(false), |
143 comments_() { } | 147 comments_() { } |
144 ~Assembler() { } | 148 ~Assembler() { } |
145 | 149 |
146 void PopRegister(Register r) { | 150 void PopRegister(Register r) { Pop(r); } |
147 UNIMPLEMENTED(); | |
148 } | |
149 | 151 |
150 void Bind(Label* label); | 152 void Bind(Label* label); |
151 | 153 |
152 // Misc. functionality | 154 // Misc. functionality |
153 int CodeSize() const { return buffer_.Size(); } | 155 int CodeSize() const { return buffer_.Size(); } |
154 int prologue_offset() const { return -1; } | 156 int prologue_offset() const { return -1; } |
155 const ZoneGrowableArray<int>& GetPointerOffsets() const { | 157 const ZoneGrowableArray<int>& GetPointerOffsets() const { |
156 return buffer_.pointer_offsets(); | 158 return buffer_.pointer_offsets(); |
157 } | 159 } |
158 const GrowableObjectArray& object_pool() const { return object_pool_; } | 160 const GrowableObjectArray& object_pool() const { return object_pool_; } |
(...skipping 24 matching lines...) Expand all Loading... | |
183 // Allocated instance is returned in 'instance_reg'. | 185 // Allocated instance is returned in 'instance_reg'. |
184 // Only the tags field of the object is initialized. | 186 // Only the tags field of the object is initialized. |
185 void TryAllocate(const Class& cls, | 187 void TryAllocate(const Class& cls, |
186 Label* failure, | 188 Label* failure, |
187 bool near_jump, | 189 bool near_jump, |
188 Register instance_reg) { | 190 Register instance_reg) { |
189 UNIMPLEMENTED(); | 191 UNIMPLEMENTED(); |
190 } | 192 } |
191 | 193 |
192 // Debugging and bringup support. | 194 // Debugging and bringup support. |
193 void Stop(const char* message) { UNIMPLEMENTED(); } | |
194 void Unimplemented(const char* message); | 195 void Unimplemented(const char* message); |
195 void Untested(const char* message); | 196 void Untested(const char* message); |
196 void Unreachable(const char* message); | 197 void Unreachable(const char* message); |
197 | 198 |
198 static void InitializeMemoryWithBreakpoints(uword data, int length); | 199 static void InitializeMemoryWithBreakpoints(uword data, int length); |
199 | 200 |
200 void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); | 201 void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); |
201 | 202 |
202 const Code::Comments& GetCodeComments() const; | 203 const Code::Comments& GetCodeComments() const; |
203 | 204 |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
496 | 497 |
497 void sw(Register rt, const Address& addr) { | 498 void sw(Register rt, const Address& addr) { |
498 EmitLoadStore(SW, rt, addr); | 499 EmitLoadStore(SW, rt, addr); |
499 } | 500 } |
500 | 501 |
501 void xor_(Register rd, Register rs, Register rt) { | 502 void xor_(Register rd, Register rs, Register rt) { |
502 EmitRType(SPECIAL, rs, rt, rd, 0, XOR); | 503 EmitRType(SPECIAL, rs, rt, rd, 0, XOR); |
503 } | 504 } |
504 | 505 |
505 // Macros in alphabetical order. | 506 // Macros in alphabetical order. |
507 | |
508 void Branch(const ExternalLabel* label) { | |
509 // Doesn't need to be patchable, so use the delay slot. | |
510 if (Utils::IsInt(16, label->address())) { | |
511 jr(TMP); | |
512 delay_slot()->addiu(TMP, ZR, Immediate(label->address())); | |
513 } else { | |
514 lui(TMP, Immediate((label->address() >> 16) & 0xffff)); | |
regis
2013/03/25 23:03:40
It would be a bit more readable to use Utils::Low1
zra
2013/03/25 23:39:17
Okay. So you've got to cast the result of High16Bi
| |
515 jr(TMP); | |
516 delay_slot()->ori(TMP, TMP, Immediate(label->address() & 0xffff)); | |
517 } | |
518 } | |
519 | |
520 void BranchLink(const ExternalLabel* label) { | |
521 // Doesn't need to be patchable, so use the delay slot. | |
522 if (Utils::IsInt(16, label->address())) { | |
523 jalr(TMP); | |
524 delay_slot()->addiu(TMP, ZR, Immediate(label->address())); | |
525 } else { | |
526 lui(TMP, Immediate((label->address() >> 16) & 0xffff)); | |
527 jalr(TMP); | |
528 delay_slot()->ori(TMP, TMP, Immediate(label->address() & 0xffff)); | |
529 } | |
530 } | |
531 | |
532 void BranchLinkPatchable(const ExternalLabel* label) { | |
533 const int32_t offset = | |
534 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag; | |
535 LoadWordFromPoolOffset(TMP, offset); | |
536 jalr(TMP); | |
537 } | |
538 | |
539 void BranchPatchable(const ExternalLabel* label) { | |
540 LoadImmediate(TMP, label->address()); | |
541 jr(TMP); | |
542 } | |
543 | |
544 void Drop(intptr_t stack_elements) { | |
545 ASSERT(stack_elements >= 0); | |
546 if (stack_elements > 0) { | |
547 addiu(SP, SP, Immediate(stack_elements * kWordSize)); | |
548 } | |
549 } | |
550 | |
506 void LoadImmediate(Register rd, int32_t value) { | 551 void LoadImmediate(Register rd, int32_t value) { |
507 if (Utils::IsInt(16, value)) { | 552 if (Utils::IsInt(16, value)) { |
508 addiu(rd, ZR, Immediate(value)); | 553 addiu(rd, ZR, Immediate(value)); |
509 } else { | 554 } else { |
510 lui(rd, Immediate((value >> 16) & 0xffff)); | 555 lui(rd, Immediate((value >> 16) & 0xffff)); |
511 ori(rd, rd, Immediate(value & 0xffff)); | 556 ori(rd, rd, Immediate(value & 0xffff)); |
512 } | 557 } |
513 } | 558 } |
514 | 559 |
560 void Push(Register rt) { | |
561 addiu(SP, SP, Immediate(-kWordSize)); | |
562 sw(rt, Address(SP)); | |
563 } | |
564 | |
565 void Pop(Register rt) { | |
566 lw(rt, Address(SP)); | |
567 addiu(SP, SP, Immediate(kWordSize)); | |
568 } | |
569 | |
570 void Ret() { | |
571 jr(RA); | |
572 } | |
573 | |
574 void Stop(const char* message) { | |
regis
2013/03/25 23:03:40
I would not implement this in the header.
zra
2013/03/25 23:39:17
Done.
| |
575 Label stop; | |
regis
2013/03/25 23:03:40
You are missing support for FLAG_print_stop_messag
zra
2013/03/25 23:39:17
Done.
| |
576 b(&stop); | |
577 Emit(reinterpret_cast<int32_t>(message)); | |
578 Bind(&stop); | |
579 break_(Instr::kStopMessageCode); | |
580 } | |
581 | |
582 void LoadWordFromPoolOffset(Register rd, int32_t offset); | |
583 void LoadObject(Register rd, const Object& object); | |
584 void PushObject(const Object& object); | |
585 | |
586 // Subtracts rn from location of object and places result in rd. | |
587 void CompareObject(Register rd, Register rn, const Object& object); | |
588 | |
515 private: | 589 private: |
516 AssemblerBuffer buffer_; | 590 AssemblerBuffer buffer_; |
517 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. | 591 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. |
518 int prologue_offset_; | 592 int prologue_offset_; |
519 | 593 |
520 bool delay_slot_available_; | 594 bool delay_slot_available_; |
521 bool in_delay_slot_; | 595 bool in_delay_slot_; |
522 | 596 |
597 int32_t AddObject(const Object& obj); | |
598 int32_t AddExternalLabel(const ExternalLabel* label); | |
599 | |
523 class CodeComment : public ZoneAllocated { | 600 class CodeComment : public ZoneAllocated { |
524 public: | 601 public: |
525 CodeComment(intptr_t pc_offset, const String& comment) | 602 CodeComment(intptr_t pc_offset, const String& comment) |
526 : pc_offset_(pc_offset), comment_(comment) { } | 603 : pc_offset_(pc_offset), comment_(comment) { } |
527 | 604 |
528 intptr_t pc_offset() const { return pc_offset_; } | 605 intptr_t pc_offset() const { return pc_offset_; } |
529 const String& comment() const { return comment_; } | 606 const String& comment() const { return comment_; } |
530 | 607 |
531 private: | 608 private: |
532 intptr_t pc_offset_; | 609 intptr_t pc_offset_; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
627 delay_slot_available_ = true; | 704 delay_slot_available_ = true; |
628 } | 705 } |
629 | 706 |
630 DISALLOW_ALLOCATION(); | 707 DISALLOW_ALLOCATION(); |
631 DISALLOW_COPY_AND_ASSIGN(Assembler); | 708 DISALLOW_COPY_AND_ASSIGN(Assembler); |
632 }; | 709 }; |
633 | 710 |
634 } // namespace dart | 711 } // namespace dart |
635 | 712 |
636 #endif // VM_ASSEMBLER_MIPS_H_ | 713 #endif // VM_ASSEMBLER_MIPS_H_ |
OLD | NEW |