| 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 |
| 11 | 11 |
| 12 #include "platform/assert.h" | 12 #include "platform/assert.h" |
| 13 #include "platform/utils.h" | 13 #include "platform/utils.h" |
| 14 #include "vm/constants_ia32.h" | 14 #include "vm/constants_ia32.h" |
| 15 | 15 |
| 16 namespace dart { | 16 namespace dart { |
| 17 | 17 |
| 18 // Forward declarations. | 18 // Forward declarations. |
| 19 class RuntimeEntry; | 19 class RuntimeEntry; |
| 20 | 20 |
| 21 class Immediate : public ValueObject { | 21 class Immediate : public ValueObject { |
| 22 public: | 22 public: |
| 23 explicit Immediate(int32_t value) : value_(value) { } | 23 explicit Immediate(int32_t value) : value_(value) { } |
| 24 | 24 |
| 25 Immediate(const Immediate& other) : ValueObject(), value_(other.value_) { } | |
| 26 | |
| 27 int32_t value() const { return value_; } | 25 int32_t value() const { return value_; } |
| 28 | 26 |
| 29 bool is_int8() const { return Utils::IsInt(8, value_); } | 27 bool is_int8() const { return Utils::IsInt(8, value_); } |
| 30 bool is_uint8() const { return Utils::IsUint(8, value_); } | 28 bool is_uint8() const { return Utils::IsUint(8, value_); } |
| 31 bool is_uint16() const { return Utils::IsUint(16, value_); } | 29 bool is_uint16() const { return Utils::IsUint(16, value_); } |
| 32 | 30 |
| 33 private: | 31 private: |
| 34 const int32_t value_; | 32 const int32_t value_; |
| 35 | 33 |
| 36 // TODO(5411081): Add DISALLOW_COPY_AND_ASSIGN(Immediate) once the mac | 34 DISALLOW_COPY_AND_ASSIGN(Immediate); |
| 37 // build issue is resolved. | |
| 38 // And remove the unnecessary copy constructor. | |
| 39 }; | 35 }; |
| 40 | 36 |
| 41 | 37 |
| 42 class Operand : public ValueObject { | 38 class Operand : public ValueObject { |
| 43 public: | 39 public: |
| 44 uint8_t mod() const { | 40 uint8_t mod() const { |
| 45 return (encoding_at(0) >> 6) & 3; | 41 return (encoding_at(0) >> 6) & 3; |
| 46 } | 42 } |
| 47 | 43 |
| 48 Register rm() const { | 44 Register rm() const { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 64 int8_t disp8() const { | 60 int8_t disp8() const { |
| 65 ASSERT(length_ >= 2); | 61 ASSERT(length_ >= 2); |
| 66 return static_cast<int8_t>(encoding_[length_ - 1]); | 62 return static_cast<int8_t>(encoding_[length_ - 1]); |
| 67 } | 63 } |
| 68 | 64 |
| 69 int32_t disp32() const { | 65 int32_t disp32() const { |
| 70 ASSERT(length_ >= 5); | 66 ASSERT(length_ >= 5); |
| 71 return bit_copy<int32_t>(encoding_[length_ - 4]); | 67 return bit_copy<int32_t>(encoding_[length_ - 4]); |
| 72 } | 68 } |
| 73 | 69 |
| 74 Operand(const Operand& other) : ValueObject(), length_(other.length_) { | |
| 75 memmove(&encoding_[0], &other.encoding_[0], other.length_); | |
| 76 } | |
| 77 | |
| 78 Operand& operator=(const Operand& other) { | |
| 79 length_ = other.length_; | |
| 80 memmove(&encoding_[0], &other.encoding_[0], other.length_); | |
| 81 return *this; | |
| 82 } | |
| 83 | |
| 84 protected: | 70 protected: |
| 85 Operand() : length_(0) { } // Needed by subclass Address. | 71 Operand() : length_(0), encoding_() { } // Needed by subclass Address. |
| 86 | 72 |
| 87 void SetModRM(int mod, Register rm) { | 73 void SetModRM(int mod, Register rm) { |
| 88 ASSERT((mod & ~3) == 0); | 74 ASSERT((mod & ~3) == 0); |
| 89 encoding_[0] = (mod << 6) | rm; | 75 encoding_[0] = (mod << 6) | rm; |
| 90 length_ = 1; | 76 length_ = 1; |
| 91 } | 77 } |
| 92 | 78 |
| 93 void SetSIB(ScaleFactor scale, Register index, Register base) { | 79 void SetSIB(ScaleFactor scale, Register index, Register base) { |
| 94 ASSERT(length_ == 1); | 80 ASSERT(length_ == 1); |
| 95 ASSERT((scale & ~3) == 0); | 81 ASSERT((scale & ~3) == 0); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 SetModRM(1, ESP); | 152 SetModRM(1, ESP); |
| 167 SetSIB(scale, index, base); | 153 SetSIB(scale, index, base); |
| 168 SetDisp8(disp); | 154 SetDisp8(disp); |
| 169 } else { | 155 } else { |
| 170 SetModRM(2, ESP); | 156 SetModRM(2, ESP); |
| 171 SetSIB(scale, index, base); | 157 SetSIB(scale, index, base); |
| 172 SetDisp32(disp); | 158 SetDisp32(disp); |
| 173 } | 159 } |
| 174 } | 160 } |
| 175 | 161 |
| 176 Address(const Address& other) : Operand(other) { } | |
| 177 | |
| 178 Address& operator=(const Address& other) { | |
| 179 Operand::operator=(other); | |
| 180 return *this; | |
| 181 } | |
| 182 | |
| 183 static Address Absolute(const uword addr) { | 162 static Address Absolute(const uword addr) { |
| 184 Address result; | 163 Address result; |
| 185 result.SetModRM(0, EBP); | 164 result.SetModRM(0, EBP); |
| 186 result.SetDisp32(addr); | 165 result.SetDisp32(addr); |
| 187 return result; | 166 return result; |
| 188 } | 167 } |
| 189 | 168 |
| 190 private: | 169 private: |
| 191 Address() { } // Needed by Address::Absolute. | 170 Address() { } // Needed by Address::Absolute. |
| 192 }; | 171 }; |
| 193 | 172 |
| 194 | 173 |
| 195 class FieldAddress : public Address { | 174 class FieldAddress : public Address { |
| 196 public: | 175 public: |
| 197 FieldAddress(Register base, int32_t disp) | 176 FieldAddress(Register base, int32_t disp) |
| 198 : Address(base, disp - kHeapObjectTag) { } | 177 : Address(base, disp - kHeapObjectTag) { } |
| 199 | 178 |
| 200 FieldAddress(Register base, Register index, ScaleFactor scale, int32_t disp) | 179 FieldAddress(Register base, Register index, ScaleFactor scale, int32_t disp) |
| 201 : Address(base, index, scale, disp - kHeapObjectTag) { } | 180 : Address(base, index, scale, disp - kHeapObjectTag) { } |
| 202 | |
| 203 FieldAddress(const FieldAddress& other) : Address(other) { } | |
| 204 | |
| 205 FieldAddress& operator=(const FieldAddress& other) { | |
| 206 Address::operator=(other); | |
| 207 return *this; | |
| 208 } | |
| 209 }; | 181 }; |
| 210 | 182 |
| 211 | 183 |
| 212 class Label : public ValueObject { | 184 class Label : public ValueObject { |
| 213 public: | 185 public: |
| 214 Label() : position_(0), unresolved_(0) { | 186 Label() : position_(0), unresolved_(0) { |
| 215 #ifdef DEBUG | 187 #ifdef DEBUG |
| 216 for (int i = 0; i < kMaxUnresolvedBranches; i++) { | 188 for (int i = 0; i < kMaxUnresolvedBranches; i++) { |
| 217 unresolved_near_positions_[i] = -1; | 189 unresolved_near_positions_[i] = -1; |
| 218 } | 190 } |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 void EmitComplex(int rm, const Operand& operand, const Immediate& immediate); | 704 void EmitComplex(int rm, const Operand& operand, const Immediate& immediate); |
| 733 void EmitLabel(Label* label, int instruction_size); | 705 void EmitLabel(Label* label, int instruction_size); |
| 734 void EmitLabelLink(Label* label); | 706 void EmitLabelLink(Label* label); |
| 735 void EmitNearLabelLink(Label* label); | 707 void EmitNearLabelLink(Label* label); |
| 736 | 708 |
| 737 void EmitGenericShift(int rm, Register reg, const Immediate& imm); | 709 void EmitGenericShift(int rm, Register reg, const Immediate& imm); |
| 738 void EmitGenericShift(int rm, const Operand& operand, Register shifter); | 710 void EmitGenericShift(int rm, const Operand& operand, Register shifter); |
| 739 | 711 |
| 740 void StoreIntoObjectFilter(Register object, Register value, Label* no_update); | 712 void StoreIntoObjectFilter(Register object, Register value, Label* no_update); |
| 741 | 713 |
| 742 DISALLOW_ALLOCATION(); | |
| 743 DISALLOW_COPY_AND_ASSIGN(Assembler); | 714 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 744 }; | 715 }; |
| 745 | 716 |
| 746 | 717 |
| 747 inline void Assembler::EmitUint8(uint8_t value) { | 718 inline void Assembler::EmitUint8(uint8_t value) { |
| 748 buffer_.Emit<uint8_t>(value); | 719 buffer_.Emit<uint8_t>(value); |
| 749 } | 720 } |
| 750 | 721 |
| 751 | 722 |
| 752 inline void Assembler::EmitInt32(int32_t value) { | 723 inline void Assembler::EmitInt32(int32_t value) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 770 } | 741 } |
| 771 | 742 |
| 772 | 743 |
| 773 inline void Assembler::EmitOperandSizeOverride() { | 744 inline void Assembler::EmitOperandSizeOverride() { |
| 774 EmitUint8(0x66); | 745 EmitUint8(0x66); |
| 775 } | 746 } |
| 776 | 747 |
| 777 } // namespace dart | 748 } // namespace dart |
| 778 | 749 |
| 779 #endif // VM_ASSEMBLER_IA32_H_ | 750 #endif // VM_ASSEMBLER_IA32_H_ |
| OLD | NEW |