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 |