| 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_X64_H_ | 5 #ifndef VM_ASSEMBLER_X64_H_ |
| 6 #define VM_ASSEMBLER_X64_H_ | 6 #define VM_ASSEMBLER_X64_H_ |
| 7 | 7 |
| 8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
| 9 #error Do not include assembler_x64.h directly; use assembler.h instead. | 9 #error Do not include assembler_x64.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_x64.h" | 14 #include "vm/constants_x64.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(int64_t value) : value_(value) { } | 23 explicit Immediate(int64_t value) : value_(value) { } |
| 24 | 24 |
| 25 Immediate(const Immediate& other) : ValueObject(), value_(other.value_) { } | |
| 26 | |
| 27 int64_t value() const { return value_; } | 25 int64_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 bool is_int32() const { return Utils::IsInt(32, value_); } | 30 bool is_int32() const { return Utils::IsInt(32, value_); } |
| 33 | 31 |
| 34 private: | 32 private: |
| 35 const int64_t value_; | 33 const int64_t value_; |
| 36 | 34 |
| 37 // TODO(5411081): Add DISALLOW_COPY_AND_ASSIGN(Immediate) once the mac | 35 DISALLOW_COPY_AND_ASSIGN(Immediate); |
| 38 // build issue is resolved. | |
| 39 // And remove the unnecessary copy constructor. | |
| 40 }; | 36 }; |
| 41 | 37 |
| 42 | 38 |
| 43 class Operand : public ValueObject { | 39 class Operand : public ValueObject { |
| 44 public: | 40 public: |
| 45 uint8_t rex() const { | 41 uint8_t rex() const { |
| 46 return rex_; | 42 return rex_; |
| 47 } | 43 } |
| 48 | 44 |
| 49 uint8_t mod() const { | 45 uint8_t mod() const { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 72 int8_t disp8() const { | 68 int8_t disp8() const { |
| 73 ASSERT(length_ >= 2); | 69 ASSERT(length_ >= 2); |
| 74 return static_cast<int8_t>(encoding_[length_ - 1]); | 70 return static_cast<int8_t>(encoding_[length_ - 1]); |
| 75 } | 71 } |
| 76 | 72 |
| 77 int32_t disp32() const { | 73 int32_t disp32() const { |
| 78 ASSERT(length_ >= 5); | 74 ASSERT(length_ >= 5); |
| 79 return bit_copy<int32_t>(encoding_[length_ - 4]); | 75 return bit_copy<int32_t>(encoding_[length_ - 4]); |
| 80 } | 76 } |
| 81 | 77 |
| 82 Operand(const Operand& other) | |
| 83 : ValueObject(), length_(other.length_), rex_(other.rex_) { | |
| 84 memmove(&encoding_[0], &other.encoding_[0], other.length_); | |
| 85 } | |
| 86 | |
| 87 Operand& operator=(const Operand& other) { | |
| 88 length_ = other.length_; | |
| 89 rex_ = other.rex_; | |
| 90 memmove(&encoding_[0], &other.encoding_[0], other.length_); | |
| 91 return *this; | |
| 92 } | |
| 93 | |
| 94 protected: | 78 protected: |
| 95 Operand() : length_(0), rex_(REX_NONE) { } // Needed by subclass Address. | 79 // Needed by subclass Address. |
| 80 Operand() : length_(0), rex_(REX_NONE), encoding_() { } |
| 96 | 81 |
| 97 void SetModRM(int mod, Register rm) { | 82 void SetModRM(int mod, Register rm) { |
| 98 ASSERT((mod & ~3) == 0); | 83 ASSERT((mod & ~3) == 0); |
| 99 if ((rm > 7) && !((rm == R12) && (mod != 3))) { | 84 if ((rm > 7) && !((rm == R12) && (mod != 3))) { |
| 100 rex_ |= REX_B; | 85 rex_ |= REX_B; |
| 101 } | 86 } |
| 102 encoding_[0] = (mod << 6) | (rm & 7); | 87 encoding_[0] = (mod << 6) | (rm & 7); |
| 103 length_ = 1; | 88 length_ = 1; |
| 104 } | 89 } |
| 105 | 90 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 } else if (Utils::IsInt(8, disp)) { | 174 } else if (Utils::IsInt(8, disp)) { |
| 190 SetModRM(1, RSP); | 175 SetModRM(1, RSP); |
| 191 SetSIB(scale, index, base); | 176 SetSIB(scale, index, base); |
| 192 SetDisp8(disp); | 177 SetDisp8(disp); |
| 193 } else { | 178 } else { |
| 194 SetModRM(2, RSP); | 179 SetModRM(2, RSP); |
| 195 SetSIB(scale, index, base); | 180 SetSIB(scale, index, base); |
| 196 SetDisp32(disp); | 181 SetDisp32(disp); |
| 197 } | 182 } |
| 198 } | 183 } |
| 199 | |
| 200 Address(const Address& other) : Operand(other) { } | |
| 201 | |
| 202 Address& operator=(const Address& other) { | |
| 203 Operand::operator=(other); | |
| 204 return *this; | |
| 205 } | |
| 206 }; | 184 }; |
| 207 | 185 |
| 208 | 186 |
| 209 class FieldAddress : public Address { | 187 class FieldAddress : public Address { |
| 210 public: | 188 public: |
| 211 FieldAddress(Register base, int32_t disp) | 189 FieldAddress(Register base, int32_t disp) |
| 212 : Address(base, disp - kHeapObjectTag) { } | 190 : Address(base, disp - kHeapObjectTag) { } |
| 213 | 191 |
| 214 FieldAddress(Register base, Register index, ScaleFactor scale, int32_t disp) | 192 FieldAddress(Register base, Register index, ScaleFactor scale, int32_t disp) |
| 215 : Address(base, index, scale, disp - kHeapObjectTag) { } | 193 : Address(base, index, scale, disp - kHeapObjectTag) { } |
| 216 | |
| 217 FieldAddress(const FieldAddress& other) : Address(other) { } | |
| 218 | |
| 219 FieldAddress& operator=(const FieldAddress& other) { | |
| 220 Address::operator=(other); | |
| 221 return *this; | |
| 222 } | |
| 223 }; | 194 }; |
| 224 | 195 |
| 225 | 196 |
| 226 class Label : public ValueObject { | 197 class Label : public ValueObject { |
| 227 public: | 198 public: |
| 228 Label() : position_(0), unresolved_(0) { | 199 Label() : position_(0), unresolved_(0) { |
| 229 #ifdef DEBUG | 200 #ifdef DEBUG |
| 230 for (int i = 0; i < kMaxUnresolvedBranches; i++) { | 201 for (int i = 0; i < kMaxUnresolvedBranches; i++) { |
| 231 unresolved_near_positions_[i] = -1; | 202 unresolved_near_positions_[i] = -1; |
| 232 } | 203 } |
| (...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 763 void EmitComplex(int rm, const Operand& operand, const Immediate& immediate); | 734 void EmitComplex(int rm, const Operand& operand, const Immediate& immediate); |
| 764 void EmitLabel(Label* label, int instruction_size); | 735 void EmitLabel(Label* label, int instruction_size); |
| 765 void EmitLabelLink(Label* label); | 736 void EmitLabelLink(Label* label); |
| 766 void EmitNearLabelLink(Label* label); | 737 void EmitNearLabelLink(Label* label); |
| 767 | 738 |
| 768 void EmitGenericShift(bool wide, int rm, Register reg, const Immediate& imm); | 739 void EmitGenericShift(bool wide, int rm, Register reg, const Immediate& imm); |
| 769 void EmitGenericShift(bool wide, int rm, Register operand, Register shifter); | 740 void EmitGenericShift(bool wide, int rm, Register operand, Register shifter); |
| 770 | 741 |
| 771 void StoreIntoObjectFilter(Register object, Register value, Label* no_update); | 742 void StoreIntoObjectFilter(Register object, Register value, Label* no_update); |
| 772 | 743 |
| 773 DISALLOW_ALLOCATION(); | |
| 774 DISALLOW_COPY_AND_ASSIGN(Assembler); | 744 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 775 }; | 745 }; |
| 776 | 746 |
| 777 | 747 |
| 778 inline void Assembler::EmitUint8(uint8_t value) { | 748 inline void Assembler::EmitUint8(uint8_t value) { |
| 779 buffer_.Emit<uint8_t>(value); | 749 buffer_.Emit<uint8_t>(value); |
| 780 } | 750 } |
| 781 | 751 |
| 782 | 752 |
| 783 inline void Assembler::EmitInt32(int32_t value) { | 753 inline void Assembler::EmitInt32(int32_t value) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 } | 816 } |
| 847 | 817 |
| 848 | 818 |
| 849 inline void Assembler::EmitOperandSizeOverride() { | 819 inline void Assembler::EmitOperandSizeOverride() { |
| 850 EmitUint8(0x66); | 820 EmitUint8(0x66); |
| 851 } | 821 } |
| 852 | 822 |
| 853 } // namespace dart | 823 } // namespace dart |
| 854 | 824 |
| 855 #endif // VM_ASSEMBLER_X64_H_ | 825 #endif // VM_ASSEMBLER_X64_H_ |
| OLD | NEW |