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_IA32_H_ | 5 #ifndef VM_ASSEMBLER_IA32_H_ |
6 #define VM_ASSEMBLER_IA32_H_ | 6 #define VM_ASSEMBLER_IA32_H_ |
7 | 7 |
8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
9 #error Do not include assembler_ia32.h directly; use assembler.h instead. | 9 #error Do not include assembler_ia32.h directly; use assembler.h instead. |
10 #endif | 10 #endif |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 length_ = 2; | 105 length_ = 2; |
106 } | 106 } |
107 | 107 |
108 void SetDisp8(int8_t disp) { | 108 void SetDisp8(int8_t disp) { |
109 ASSERT(length_ == 1 || length_ == 2); | 109 ASSERT(length_ == 1 || length_ == 2); |
110 encoding_[length_++] = static_cast<uint8_t>(disp); | 110 encoding_[length_++] = static_cast<uint8_t>(disp); |
111 } | 111 } |
112 | 112 |
113 void SetDisp32(int32_t disp) { | 113 void SetDisp32(int32_t disp) { |
114 ASSERT(length_ == 1 || length_ == 2); | 114 ASSERT(length_ == 1 || length_ == 2); |
115 int disp_size = sizeof(disp); | 115 intptr_t disp_size = sizeof(disp); |
116 memmove(&encoding_[length_], &disp, disp_size); | 116 memmove(&encoding_[length_], &disp, disp_size); |
117 length_ += disp_size; | 117 length_ += disp_size; |
118 } | 118 } |
119 | 119 |
120 private: | 120 private: |
121 uint8_t length_; | 121 uint8_t length_; |
122 uint8_t encoding_[6]; | 122 uint8_t encoding_[6]; |
123 uint8_t padding_; | 123 uint8_t padding_; |
124 | 124 |
125 explicit Operand(Register reg) { SetModRM(3, reg); } | 125 explicit Operand(Register reg) { SetModRM(3, reg); } |
126 | 126 |
127 // Get the operand encoding byte at the given index. | 127 // Get the operand encoding byte at the given index. |
128 uint8_t encoding_at(int index) const { | 128 uint8_t encoding_at(intptr_t index) const { |
129 ASSERT(index >= 0 && index < length_); | 129 ASSERT(index >= 0 && index < length_); |
130 return encoding_[index]; | 130 return encoding_[index]; |
131 } | 131 } |
132 | 132 |
133 // Returns whether or not this operand is really the given register in | 133 // Returns whether or not this operand is really the given register in |
134 // disguise. Used from the assembler to generate better encodings. | 134 // disguise. Used from the assembler to generate better encodings. |
135 bool IsRegister(Register reg) const { | 135 bool IsRegister(Register reg) const { |
136 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only. | 136 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only. |
137 && ((encoding_[0] & 0x07) == reg); // Register codes match. | 137 && ((encoding_[0] & 0x07) == reg); // Register codes match. |
138 } | 138 } |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 } | 228 } |
229 | 229 |
230 ~Label() { | 230 ~Label() { |
231 // Assert if label is being destroyed with unresolved branches pending. | 231 // Assert if label is being destroyed with unresolved branches pending. |
232 ASSERT(!IsLinked()); | 232 ASSERT(!IsLinked()); |
233 ASSERT(!HasNear()); | 233 ASSERT(!HasNear()); |
234 } | 234 } |
235 | 235 |
236 // Returns the position for bound labels. Cannot be used for unused or linked | 236 // Returns the position for bound labels. Cannot be used for unused or linked |
237 // labels. | 237 // labels. |
238 int Position() const { | 238 intptr_t Position() const { |
239 ASSERT(IsBound()); | 239 ASSERT(IsBound()); |
240 return -position_ - kWordSize; | 240 return -position_ - kWordSize; |
241 } | 241 } |
242 | 242 |
243 int LinkPosition() const { | 243 intptr_t LinkPosition() const { |
244 ASSERT(IsLinked()); | 244 ASSERT(IsLinked()); |
245 return position_ - kWordSize; | 245 return position_ - kWordSize; |
246 } | 246 } |
247 | 247 |
248 int NearPosition() { | 248 intptr_t NearPosition() { |
249 ASSERT(HasNear()); | 249 ASSERT(HasNear()); |
250 return unresolved_near_positions_[--unresolved_]; | 250 return unresolved_near_positions_[--unresolved_]; |
251 } | 251 } |
252 | 252 |
253 bool IsBound() const { return position_ < 0; } | 253 bool IsBound() const { return position_ < 0; } |
254 bool IsUnused() const { return (position_ == 0) && (unresolved_ == 0); } | 254 bool IsUnused() const { return (position_ == 0) && (unresolved_ == 0); } |
255 bool IsLinked() const { return position_ > 0; } | 255 bool IsLinked() const { return position_ > 0; } |
256 bool HasNear() const { return unresolved_ != 0; } | 256 bool HasNear() const { return unresolved_ != 0; } |
257 | 257 |
258 private: | 258 private: |
259 void BindTo(int position) { | 259 void BindTo(intptr_t position) { |
260 ASSERT(!IsBound()); | 260 ASSERT(!IsBound()); |
261 ASSERT(!HasNear()); | 261 ASSERT(!HasNear()); |
262 position_ = -position - kWordSize; | 262 position_ = -position - kWordSize; |
263 ASSERT(IsBound()); | 263 ASSERT(IsBound()); |
264 } | 264 } |
265 | 265 |
266 void LinkTo(int position) { | 266 void LinkTo(intptr_t position) { |
267 ASSERT(!IsBound()); | 267 ASSERT(!IsBound()); |
268 position_ = position + kWordSize; | 268 position_ = position + kWordSize; |
269 ASSERT(IsLinked()); | 269 ASSERT(IsLinked()); |
270 } | 270 } |
271 | 271 |
272 void NearLinkTo(int position) { | 272 void NearLinkTo(intptr_t position) { |
273 ASSERT(!IsBound()); | 273 ASSERT(!IsBound()); |
274 ASSERT(unresolved_ < kMaxUnresolvedBranches); | 274 ASSERT(unresolved_ < kMaxUnresolvedBranches); |
275 unresolved_near_positions_[unresolved_++] = position; | 275 unresolved_near_positions_[unresolved_++] = position; |
276 } | 276 } |
277 | 277 |
278 static const int kMaxUnresolvedBranches = 20; | 278 static const int kMaxUnresolvedBranches = 20; |
279 | 279 |
280 int position_; | 280 intptr_t position_; |
281 int unresolved_; | 281 intptr_t unresolved_; |
282 int unresolved_near_positions_[kMaxUnresolvedBranches]; | 282 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches]; |
283 | 283 |
284 friend class Assembler; | 284 friend class Assembler; |
285 DISALLOW_COPY_AND_ASSIGN(Label); | 285 DISALLOW_COPY_AND_ASSIGN(Label); |
286 }; | 286 }; |
287 | 287 |
288 | 288 |
289 class CPUFeatures : public AllStatic { | 289 class CPUFeatures : public AllStatic { |
290 public: | 290 public: |
291 static void InitOnce(); | 291 static void InitOnce(); |
292 static bool sse2_supported(); | 292 static bool sse2_supported(); |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 * Misc. functionality | 689 * Misc. functionality |
690 */ | 690 */ |
691 void SmiTag(Register reg) { | 691 void SmiTag(Register reg) { |
692 addl(reg, reg); | 692 addl(reg, reg); |
693 } | 693 } |
694 | 694 |
695 void SmiUntag(Register reg) { | 695 void SmiUntag(Register reg) { |
696 sarl(reg, Immediate(kSmiTagSize)); | 696 sarl(reg, Immediate(kSmiTagSize)); |
697 } | 697 } |
698 | 698 |
699 int PreferredLoopAlignment() { return 16; } | 699 intptr_t PreferredLoopAlignment() { return 16; } |
700 void Align(int alignment, int offset); | 700 void Align(intptr_t alignment, intptr_t offset); |
701 void Bind(Label* label); | 701 void Bind(Label* label); |
702 | 702 |
703 int CodeSize() const { return buffer_.Size(); } | 703 intptr_t CodeSize() const { return buffer_.Size(); } |
704 int prologue_offset() const { return prologue_offset_; } | 704 intptr_t prologue_offset() const { return prologue_offset_; } |
705 const ZoneGrowableArray<int>& GetPointerOffsets() const { | 705 const ZoneGrowableArray<intptr_t>& GetPointerOffsets() const { |
706 return buffer_.pointer_offsets(); | 706 return buffer_.pointer_offsets(); |
707 } | 707 } |
708 const GrowableObjectArray& object_pool() const { return object_pool_; } | 708 const GrowableObjectArray& object_pool() const { return object_pool_; } |
709 | 709 |
710 void FinalizeInstructions(const MemoryRegion& region) { | 710 void FinalizeInstructions(const MemoryRegion& region) { |
711 buffer_.FinalizeInstructions(region); | 711 buffer_.FinalizeInstructions(region); |
712 } | 712 } |
713 | 713 |
714 // Set up a Dart frame on entry with a frame pointer and PC information to | 714 // Set up a Dart frame on entry with a frame pointer and PC information to |
715 // enable easy access to the RawInstruction object of code corresponding | 715 // enable easy access to the RawInstruction object of code corresponding |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 Label* failure, | 767 Label* failure, |
768 bool near_jump, | 768 bool near_jump, |
769 Register instance_reg); | 769 Register instance_reg); |
770 | 770 |
771 // Debugging and bringup support. | 771 // Debugging and bringup support. |
772 void Stop(const char* message); | 772 void Stop(const char* message); |
773 void Unimplemented(const char* message); | 773 void Unimplemented(const char* message); |
774 void Untested(const char* message); | 774 void Untested(const char* message); |
775 void Unreachable(const char* message); | 775 void Unreachable(const char* message); |
776 | 776 |
777 static void InitializeMemoryWithBreakpoints(uword data, int length); | 777 static void InitializeMemoryWithBreakpoints(uword data, intptr_t length); |
778 | 778 |
779 void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); | 779 void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); |
780 const Code::Comments& GetCodeComments() const; | 780 const Code::Comments& GetCodeComments() const; |
781 | 781 |
782 static const char* RegisterName(Register reg); | 782 static const char* RegisterName(Register reg); |
783 static const char* FpuRegisterName(FpuRegister reg); | 783 static const char* FpuRegisterName(FpuRegister reg); |
784 | 784 |
785 private: | 785 private: |
786 AssemblerBuffer buffer_; | 786 AssemblerBuffer buffer_; |
787 GrowableObjectArray& object_pool_; // Object pool is not used on ia32. | 787 GrowableObjectArray& object_pool_; // Object pool is not used on ia32. |
788 int prologue_offset_; | 788 intptr_t prologue_offset_; |
789 | 789 |
790 class CodeComment : public ZoneAllocated { | 790 class CodeComment : public ZoneAllocated { |
791 public: | 791 public: |
792 CodeComment(intptr_t pc_offset, const String& comment) | 792 CodeComment(intptr_t pc_offset, const String& comment) |
793 : pc_offset_(pc_offset), comment_(comment) { } | 793 : pc_offset_(pc_offset), comment_(comment) { } |
794 | 794 |
795 intptr_t pc_offset() const { return pc_offset_; } | 795 intptr_t pc_offset() const { return pc_offset_; } |
796 const String& comment() const { return comment_; } | 796 const String& comment() const { return comment_; } |
797 | 797 |
798 private: | 798 private: |
799 intptr_t pc_offset_; | 799 intptr_t pc_offset_; |
800 const String& comment_; | 800 const String& comment_; |
801 | 801 |
802 DISALLOW_COPY_AND_ASSIGN(CodeComment); | 802 DISALLOW_COPY_AND_ASSIGN(CodeComment); |
803 }; | 803 }; |
804 | 804 |
805 GrowableArray<CodeComment*> comments_; | 805 GrowableArray<CodeComment*> comments_; |
806 | 806 |
807 inline void EmitUint8(uint8_t value); | 807 inline void EmitUint8(uint8_t value); |
808 inline void EmitInt32(int32_t value); | 808 inline void EmitInt32(int32_t value); |
809 inline void EmitRegisterOperand(int rm, int reg); | 809 inline void EmitRegisterOperand(int rm, int reg); |
810 inline void EmitXmmRegisterOperand(int rm, XmmRegister reg); | 810 inline void EmitXmmRegisterOperand(int rm, XmmRegister reg); |
811 inline void EmitFixup(AssemblerFixup* fixup); | 811 inline void EmitFixup(AssemblerFixup* fixup); |
812 inline void EmitOperandSizeOverride(); | 812 inline void EmitOperandSizeOverride(); |
813 | 813 |
814 void EmitOperand(int rm, const Operand& operand); | 814 void EmitOperand(int rm, const Operand& operand); |
815 void EmitImmediate(const Immediate& imm); | 815 void EmitImmediate(const Immediate& imm); |
816 void EmitComplex(int rm, const Operand& operand, const Immediate& immediate); | 816 void EmitComplex(int rm, const Operand& operand, const Immediate& immediate); |
817 void EmitLabel(Label* label, int instruction_size); | 817 void EmitLabel(Label* label, intptr_t instruction_size); |
818 void EmitLabelLink(Label* label); | 818 void EmitLabelLink(Label* label); |
819 void EmitNearLabelLink(Label* label); | 819 void EmitNearLabelLink(Label* label); |
820 | 820 |
821 void EmitGenericShift(int rm, Register reg, const Immediate& imm); | 821 void EmitGenericShift(int rm, Register reg, const Immediate& imm); |
822 void EmitGenericShift(int rm, const Operand& operand, Register shifter); | 822 void EmitGenericShift(int rm, const Operand& operand, Register shifter); |
823 | 823 |
824 void StoreIntoObjectFilter(Register object, Register value, Label* no_update); | 824 void StoreIntoObjectFilter(Register object, Register value, Label* no_update); |
825 | 825 |
826 // Shorter filtering sequence that assumes that value is not a smi. | 826 // Shorter filtering sequence that assumes that value is not a smi. |
827 void StoreIntoObjectFilterNoSmi(Register object, | 827 void StoreIntoObjectFilterNoSmi(Register object, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 } | 859 } |
860 | 860 |
861 | 861 |
862 inline void Assembler::EmitOperandSizeOverride() { | 862 inline void Assembler::EmitOperandSizeOverride() { |
863 EmitUint8(0x66); | 863 EmitUint8(0x66); |
864 } | 864 } |
865 | 865 |
866 } // namespace dart | 866 } // namespace dart |
867 | 867 |
868 #endif // VM_ASSEMBLER_IA32_H_ | 868 #endif // VM_ASSEMBLER_IA32_H_ |
OLD | NEW |