| 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 RUNTIME_VM_ASSEMBLER_X64_H_ | 5 #ifndef RUNTIME_VM_ASSEMBLER_X64_H_ |
| 6 #define RUNTIME_VM_ASSEMBLER_X64_H_ | 6 #define RUNTIME_VM_ASSEMBLER_X64_H_ |
| 7 | 7 |
| 8 #ifndef RUNTIME_VM_ASSEMBLER_H_ | 8 #ifndef RUNTIME_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 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 bool is_int32() const { return Utils::IsInt(32, value_); } | 35 bool is_int32() const { return Utils::IsInt(32, value_); } |
| 36 | 36 |
| 37 private: | 37 private: |
| 38 const int64_t value_; | 38 const int64_t value_; |
| 39 | 39 |
| 40 // TODO(5411081): Add DISALLOW_COPY_AND_ASSIGN(Immediate) once the mac | 40 // TODO(5411081): Add DISALLOW_COPY_AND_ASSIGN(Immediate) once the mac |
| 41 // build issue is resolved. | 41 // build issue is resolved. |
| 42 // And remove the unnecessary copy constructor. | 42 // And remove the unnecessary copy constructor. |
| 43 }; | 43 }; |
| 44 | 44 |
| 45 | |
| 46 class Operand : public ValueObject { | 45 class Operand : public ValueObject { |
| 47 public: | 46 public: |
| 48 uint8_t rex() const { return rex_; } | 47 uint8_t rex() const { return rex_; } |
| 49 | 48 |
| 50 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; } | 49 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; } |
| 51 | 50 |
| 52 Register rm() const { | 51 Register rm() const { |
| 53 int rm_rex = (rex_ & REX_B) << 3; | 52 int rm_rex = (rex_ & REX_B) << 3; |
| 54 return static_cast<Register>(rm_rex + (encoding_at(0) & 7)); | 53 return static_cast<Register>(rm_rex + (encoding_at(0) & 7)); |
| 55 } | 54 } |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 // disguise. Used from the assembler to generate better encodings. | 150 // disguise. Used from the assembler to generate better encodings. |
| 152 bool IsRegister(Register reg) const { | 151 bool IsRegister(Register reg) const { |
| 153 return ((reg > 7 ? 1 : 0) == (rex_ & REX_B)) // REX.B match. | 152 return ((reg > 7 ? 1 : 0) == (rex_ & REX_B)) // REX.B match. |
| 154 && ((encoding_at(0) & 0xF8) == 0xC0) // Addressing mode is register. | 153 && ((encoding_at(0) & 0xF8) == 0xC0) // Addressing mode is register. |
| 155 && ((encoding_at(0) & 0x07) == reg); // Register codes match. | 154 && ((encoding_at(0) & 0x07) == reg); // Register codes match. |
| 156 } | 155 } |
| 157 | 156 |
| 158 friend class Assembler; | 157 friend class Assembler; |
| 159 }; | 158 }; |
| 160 | 159 |
| 161 | |
| 162 class Address : public Operand { | 160 class Address : public Operand { |
| 163 public: | 161 public: |
| 164 Address(Register base, int32_t disp) { | 162 Address(Register base, int32_t disp) { |
| 165 if ((disp == 0) && ((base & 7) != RBP)) { | 163 if ((disp == 0) && ((base & 7) != RBP)) { |
| 166 SetModRM(0, base); | 164 SetModRM(0, base); |
| 167 if ((base & 7) == RSP) { | 165 if ((base & 7) == RSP) { |
| 168 SetSIB(TIMES_1, RSP, base); | 166 SetSIB(TIMES_1, RSP, base); |
| 169 } | 167 } |
| 170 } else if (Utils::IsInt(8, disp)) { | 168 } else if (Utils::IsInt(8, disp)) { |
| 171 SetModRM(1, base); | 169 SetModRM(1, base); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 explicit RIPRelativeDisp(int32_t disp) : disp_(disp) {} | 243 explicit RIPRelativeDisp(int32_t disp) : disp_(disp) {} |
| 246 const int32_t disp_; | 244 const int32_t disp_; |
| 247 }; | 245 }; |
| 248 | 246 |
| 249 explicit Address(const RIPRelativeDisp& disp) { | 247 explicit Address(const RIPRelativeDisp& disp) { |
| 250 SetModRM(0, static_cast<Register>(0x5)); | 248 SetModRM(0, static_cast<Register>(0x5)); |
| 251 SetDisp32(disp.disp_); | 249 SetDisp32(disp.disp_); |
| 252 } | 250 } |
| 253 }; | 251 }; |
| 254 | 252 |
| 255 | |
| 256 class FieldAddress : public Address { | 253 class FieldAddress : public Address { |
| 257 public: | 254 public: |
| 258 FieldAddress(Register base, int32_t disp) | 255 FieldAddress(Register base, int32_t disp) |
| 259 : Address(base, disp - kHeapObjectTag) {} | 256 : Address(base, disp - kHeapObjectTag) {} |
| 260 | 257 |
| 261 // This addressing mode does not exist. | 258 // This addressing mode does not exist. |
| 262 FieldAddress(Register base, Register r); | 259 FieldAddress(Register base, Register r); |
| 263 | 260 |
| 264 FieldAddress(Register base, Register index, ScaleFactor scale, int32_t disp) | 261 FieldAddress(Register base, Register index, ScaleFactor scale, int32_t disp) |
| 265 : Address(base, index, scale, disp - kHeapObjectTag) {} | 262 : Address(base, index, scale, disp - kHeapObjectTag) {} |
| 266 | 263 |
| 267 // This addressing mode does not exist. | 264 // This addressing mode does not exist. |
| 268 FieldAddress(Register base, Register index, ScaleFactor scale, Register r); | 265 FieldAddress(Register base, Register index, ScaleFactor scale, Register r); |
| 269 | 266 |
| 270 FieldAddress(const FieldAddress& other) : Address(other) {} | 267 FieldAddress(const FieldAddress& other) : Address(other) {} |
| 271 | 268 |
| 272 FieldAddress& operator=(const FieldAddress& other) { | 269 FieldAddress& operator=(const FieldAddress& other) { |
| 273 Address::operator=(other); | 270 Address::operator=(other); |
| 274 return *this; | 271 return *this; |
| 275 } | 272 } |
| 276 }; | 273 }; |
| 277 | 274 |
| 278 | |
| 279 class Label : public ValueObject { | 275 class Label : public ValueObject { |
| 280 public: | 276 public: |
| 281 Label() : position_(0), unresolved_(0) { | 277 Label() : position_(0), unresolved_(0) { |
| 282 #ifdef DEBUG | 278 #ifdef DEBUG |
| 283 for (int i = 0; i < kMaxUnresolvedBranches; i++) { | 279 for (int i = 0; i < kMaxUnresolvedBranches; i++) { |
| 284 unresolved_near_positions_[i] = -1; | 280 unresolved_near_positions_[i] = -1; |
| 285 } | 281 } |
| 286 #endif // DEBUG | 282 #endif // DEBUG |
| 287 } | 283 } |
| 288 | 284 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 static const int kMaxUnresolvedBranches = 20; | 333 static const int kMaxUnresolvedBranches = 20; |
| 338 | 334 |
| 339 intptr_t position_; | 335 intptr_t position_; |
| 340 intptr_t unresolved_; | 336 intptr_t unresolved_; |
| 341 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches]; | 337 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches]; |
| 342 | 338 |
| 343 friend class Assembler; | 339 friend class Assembler; |
| 344 DISALLOW_COPY_AND_ASSIGN(Label); | 340 DISALLOW_COPY_AND_ASSIGN(Label); |
| 345 }; | 341 }; |
| 346 | 342 |
| 347 | |
| 348 class Assembler : public ValueObject { | 343 class Assembler : public ValueObject { |
| 349 public: | 344 public: |
| 350 explicit Assembler(bool use_far_branches = false); | 345 explicit Assembler(bool use_far_branches = false); |
| 351 | 346 |
| 352 ~Assembler() {} | 347 ~Assembler() {} |
| 353 | 348 |
| 354 static const bool kNearJump = true; | 349 static const bool kNearJump = true; |
| 355 static const bool kFarJump = false; | 350 static const bool kFarJump = false; |
| 356 | 351 |
| 357 /* | 352 /* |
| (...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1071 void MoveImmediate(const Address& dst, const Immediate& imm); | 1066 void MoveImmediate(const Address& dst, const Immediate& imm); |
| 1072 | 1067 |
| 1073 void ComputeCounterAddressesForCid(intptr_t cid, | 1068 void ComputeCounterAddressesForCid(intptr_t cid, |
| 1074 Heap::Space space, | 1069 Heap::Space space, |
| 1075 Address* count_address, | 1070 Address* count_address, |
| 1076 Address* size_address); | 1071 Address* size_address); |
| 1077 DISALLOW_ALLOCATION(); | 1072 DISALLOW_ALLOCATION(); |
| 1078 DISALLOW_COPY_AND_ASSIGN(Assembler); | 1073 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 1079 }; | 1074 }; |
| 1080 | 1075 |
| 1081 | |
| 1082 inline void Assembler::EmitUint8(uint8_t value) { | 1076 inline void Assembler::EmitUint8(uint8_t value) { |
| 1083 buffer_.Emit<uint8_t>(value); | 1077 buffer_.Emit<uint8_t>(value); |
| 1084 } | 1078 } |
| 1085 | 1079 |
| 1086 | |
| 1087 inline void Assembler::EmitInt32(int32_t value) { | 1080 inline void Assembler::EmitInt32(int32_t value) { |
| 1088 buffer_.Emit<int32_t>(value); | 1081 buffer_.Emit<int32_t>(value); |
| 1089 } | 1082 } |
| 1090 | 1083 |
| 1091 | |
| 1092 inline void Assembler::EmitInt64(int64_t value) { | 1084 inline void Assembler::EmitInt64(int64_t value) { |
| 1093 buffer_.Emit<int64_t>(value); | 1085 buffer_.Emit<int64_t>(value); |
| 1094 } | 1086 } |
| 1095 | 1087 |
| 1096 | |
| 1097 inline void Assembler::EmitRegisterREX(Register reg, uint8_t rex) { | 1088 inline void Assembler::EmitRegisterREX(Register reg, uint8_t rex) { |
| 1098 ASSERT(reg != kNoRegister); | 1089 ASSERT(reg != kNoRegister); |
| 1099 rex |= (reg > 7 ? REX_B : REX_NONE); | 1090 rex |= (reg > 7 ? REX_B : REX_NONE); |
| 1100 if (rex != REX_NONE) EmitUint8(REX_PREFIX | rex); | 1091 if (rex != REX_NONE) EmitUint8(REX_PREFIX | rex); |
| 1101 } | 1092 } |
| 1102 | 1093 |
| 1103 | |
| 1104 inline void Assembler::EmitOperandREX(int rm, | 1094 inline void Assembler::EmitOperandREX(int rm, |
| 1105 const Operand& operand, | 1095 const Operand& operand, |
| 1106 uint8_t rex) { | 1096 uint8_t rex) { |
| 1107 rex |= (rm > 7 ? REX_R : REX_NONE) | operand.rex(); | 1097 rex |= (rm > 7 ? REX_R : REX_NONE) | operand.rex(); |
| 1108 if (rex != REX_NONE) EmitUint8(REX_PREFIX | rex); | 1098 if (rex != REX_NONE) EmitUint8(REX_PREFIX | rex); |
| 1109 } | 1099 } |
| 1110 | 1100 |
| 1111 | |
| 1112 inline void Assembler::EmitREX_RB(XmmRegister reg, | 1101 inline void Assembler::EmitREX_RB(XmmRegister reg, |
| 1113 XmmRegister base, | 1102 XmmRegister base, |
| 1114 uint8_t rex) { | 1103 uint8_t rex) { |
| 1115 if (reg > 7) rex |= REX_R; | 1104 if (reg > 7) rex |= REX_R; |
| 1116 if (base > 7) rex |= REX_B; | 1105 if (base > 7) rex |= REX_B; |
| 1117 if (rex != REX_NONE) EmitUint8(REX_PREFIX | rex); | 1106 if (rex != REX_NONE) EmitUint8(REX_PREFIX | rex); |
| 1118 } | 1107 } |
| 1119 | 1108 |
| 1120 | |
| 1121 inline void Assembler::EmitREX_RB(XmmRegister reg, | 1109 inline void Assembler::EmitREX_RB(XmmRegister reg, |
| 1122 const Operand& operand, | 1110 const Operand& operand, |
| 1123 uint8_t rex) { | 1111 uint8_t rex) { |
| 1124 if (reg > 7) rex |= REX_R; | 1112 if (reg > 7) rex |= REX_R; |
| 1125 rex |= operand.rex(); | 1113 rex |= operand.rex(); |
| 1126 if (rex != REX_NONE) EmitUint8(REX_PREFIX | rex); | 1114 if (rex != REX_NONE) EmitUint8(REX_PREFIX | rex); |
| 1127 } | 1115 } |
| 1128 | 1116 |
| 1129 | |
| 1130 inline void Assembler::EmitREX_RB(XmmRegister reg, Register base, uint8_t rex) { | 1117 inline void Assembler::EmitREX_RB(XmmRegister reg, Register base, uint8_t rex) { |
| 1131 if (reg > 7) rex |= REX_R; | 1118 if (reg > 7) rex |= REX_R; |
| 1132 if (base > 7) rex |= REX_B; | 1119 if (base > 7) rex |= REX_B; |
| 1133 if (rex != REX_NONE) EmitUint8(REX_PREFIX | rex); | 1120 if (rex != REX_NONE) EmitUint8(REX_PREFIX | rex); |
| 1134 } | 1121 } |
| 1135 | 1122 |
| 1136 | |
| 1137 inline void Assembler::EmitREX_RB(Register reg, XmmRegister base, uint8_t rex) { | 1123 inline void Assembler::EmitREX_RB(Register reg, XmmRegister base, uint8_t rex) { |
| 1138 if (reg > 7) rex |= REX_R; | 1124 if (reg > 7) rex |= REX_R; |
| 1139 if (base > 7) rex |= REX_B; | 1125 if (base > 7) rex |= REX_B; |
| 1140 if (rex != REX_NONE) EmitUint8(REX_PREFIX | rex); | 1126 if (rex != REX_NONE) EmitUint8(REX_PREFIX | rex); |
| 1141 } | 1127 } |
| 1142 | 1128 |
| 1143 | |
| 1144 inline void Assembler::EmitFixup(AssemblerFixup* fixup) { | 1129 inline void Assembler::EmitFixup(AssemblerFixup* fixup) { |
| 1145 buffer_.EmitFixup(fixup); | 1130 buffer_.EmitFixup(fixup); |
| 1146 } | 1131 } |
| 1147 | 1132 |
| 1148 | |
| 1149 inline void Assembler::EmitOperandSizeOverride() { | 1133 inline void Assembler::EmitOperandSizeOverride() { |
| 1150 EmitUint8(0x66); | 1134 EmitUint8(0x66); |
| 1151 } | 1135 } |
| 1152 | 1136 |
| 1153 } // namespace dart | 1137 } // namespace dart |
| 1154 | 1138 |
| 1155 #endif // RUNTIME_VM_ASSEMBLER_X64_H_ | 1139 #endif // RUNTIME_VM_ASSEMBLER_X64_H_ |
| OLD | NEW |