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_IA32_H_ | 5 #ifndef RUNTIME_VM_ASSEMBLER_IA32_H_ |
6 #define RUNTIME_VM_ASSEMBLER_IA32_H_ | 6 #define RUNTIME_VM_ASSEMBLER_IA32_H_ |
7 | 7 |
8 #ifndef RUNTIME_VM_ASSEMBLER_H_ | 8 #ifndef RUNTIME_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 21 matching lines...) Expand all Loading... |
32 bool is_uint16() const { return Utils::IsUint(16, value_); } | 32 bool is_uint16() const { return Utils::IsUint(16, value_); } |
33 | 33 |
34 private: | 34 private: |
35 const int32_t value_; | 35 const int32_t value_; |
36 | 36 |
37 // TODO(5411081): Add DISALLOW_COPY_AND_ASSIGN(Immediate) once the mac | 37 // TODO(5411081): Add DISALLOW_COPY_AND_ASSIGN(Immediate) once the mac |
38 // build issue is resolved. | 38 // build issue is resolved. |
39 // And remove the unnecessary copy constructor. | 39 // And remove the unnecessary copy constructor. |
40 }; | 40 }; |
41 | 41 |
42 | |
43 class Operand : public ValueObject { | 42 class Operand : public ValueObject { |
44 public: | 43 public: |
45 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; } | 44 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; } |
46 | 45 |
47 Register rm() const { return static_cast<Register>(encoding_at(0) & 7); } | 46 Register rm() const { return static_cast<Register>(encoding_at(0) & 7); } |
48 | 47 |
49 ScaleFactor scale() const { | 48 ScaleFactor scale() const { |
50 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3); | 49 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3); |
51 } | 50 } |
52 | 51 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 // Returns whether or not this operand is really the given register in | 127 // Returns whether or not this operand is really the given register in |
129 // disguise. Used from the assembler to generate better encodings. | 128 // disguise. Used from the assembler to generate better encodings. |
130 bool IsRegister(Register reg) const { | 129 bool IsRegister(Register reg) const { |
131 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only. | 130 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only. |
132 && ((encoding_[0] & 0x07) == reg); // Register codes match. | 131 && ((encoding_[0] & 0x07) == reg); // Register codes match. |
133 } | 132 } |
134 | 133 |
135 friend class Assembler; | 134 friend class Assembler; |
136 }; | 135 }; |
137 | 136 |
138 | |
139 class Address : public Operand { | 137 class Address : public Operand { |
140 public: | 138 public: |
141 Address(Register base, int32_t disp) { | 139 Address(Register base, int32_t disp) { |
142 if (disp == 0 && base != EBP) { | 140 if (disp == 0 && base != EBP) { |
143 SetModRM(0, base); | 141 SetModRM(0, base); |
144 if (base == ESP) SetSIB(TIMES_1, ESP, base); | 142 if (base == ESP) SetSIB(TIMES_1, ESP, base); |
145 } else if (Utils::IsInt(8, disp)) { | 143 } else if (Utils::IsInt(8, disp)) { |
146 SetModRM(1, base); | 144 SetModRM(1, base); |
147 if (base == ESP) SetSIB(TIMES_1, ESP, base); | 145 if (base == ESP) SetSIB(TIMES_1, ESP, base); |
148 SetDisp8(disp); | 146 SetDisp8(disp); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 Address result; | 191 Address result; |
194 result.SetModRM(0, EBP); | 192 result.SetModRM(0, EBP); |
195 result.SetDisp32(addr); | 193 result.SetDisp32(addr); |
196 return result; | 194 return result; |
197 } | 195 } |
198 | 196 |
199 private: | 197 private: |
200 Address() {} // Needed by Address::Absolute. | 198 Address() {} // Needed by Address::Absolute. |
201 }; | 199 }; |
202 | 200 |
203 | |
204 class FieldAddress : public Address { | 201 class FieldAddress : public Address { |
205 public: | 202 public: |
206 FieldAddress(Register base, int32_t disp) | 203 FieldAddress(Register base, int32_t disp) |
207 : Address(base, disp - kHeapObjectTag) {} | 204 : Address(base, disp - kHeapObjectTag) {} |
208 | 205 |
209 // This addressing mode does not exist. | 206 // This addressing mode does not exist. |
210 FieldAddress(Register base, Register r); | 207 FieldAddress(Register base, Register r); |
211 | 208 |
212 FieldAddress(Register base, Register index, ScaleFactor scale, int32_t disp) | 209 FieldAddress(Register base, Register index, ScaleFactor scale, int32_t disp) |
213 : Address(base, index, scale, disp - kHeapObjectTag) {} | 210 : Address(base, index, scale, disp - kHeapObjectTag) {} |
214 | 211 |
215 // This addressing mode does not exist. | 212 // This addressing mode does not exist. |
216 FieldAddress(Register base, Register index, ScaleFactor scale, Register r); | 213 FieldAddress(Register base, Register index, ScaleFactor scale, Register r); |
217 | 214 |
218 FieldAddress(const FieldAddress& other) : Address(other) {} | 215 FieldAddress(const FieldAddress& other) : Address(other) {} |
219 | 216 |
220 FieldAddress& operator=(const FieldAddress& other) { | 217 FieldAddress& operator=(const FieldAddress& other) { |
221 Address::operator=(other); | 218 Address::operator=(other); |
222 return *this; | 219 return *this; |
223 } | 220 } |
224 }; | 221 }; |
225 | 222 |
226 | |
227 class Label : public ValueObject { | 223 class Label : public ValueObject { |
228 public: | 224 public: |
229 Label() : position_(0), unresolved_(0) { | 225 Label() : position_(0), unresolved_(0) { |
230 #ifdef DEBUG | 226 #ifdef DEBUG |
231 for (int i = 0; i < kMaxUnresolvedBranches; i++) { | 227 for (int i = 0; i < kMaxUnresolvedBranches; i++) { |
232 unresolved_near_positions_[i] = -1; | 228 unresolved_near_positions_[i] = -1; |
233 } | 229 } |
234 #endif // DEBUG | 230 #endif // DEBUG |
235 } | 231 } |
236 | 232 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 static const int kMaxUnresolvedBranches = 20; | 281 static const int kMaxUnresolvedBranches = 20; |
286 | 282 |
287 intptr_t position_; | 283 intptr_t position_; |
288 intptr_t unresolved_; | 284 intptr_t unresolved_; |
289 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches]; | 285 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches]; |
290 | 286 |
291 friend class Assembler; | 287 friend class Assembler; |
292 DISALLOW_COPY_AND_ASSIGN(Label); | 288 DISALLOW_COPY_AND_ASSIGN(Label); |
293 }; | 289 }; |
294 | 290 |
295 | |
296 class Assembler : public ValueObject { | 291 class Assembler : public ValueObject { |
297 public: | 292 public: |
298 explicit Assembler(bool use_far_branches = false) | 293 explicit Assembler(bool use_far_branches = false) |
299 : buffer_(), | 294 : buffer_(), |
300 prologue_offset_(-1), | 295 prologue_offset_(-1), |
301 jit_cookie_(0), | 296 jit_cookie_(0), |
302 comments_(), | 297 comments_(), |
303 code_(Code::ZoneHandle()) { | 298 code_(Code::ZoneHandle()) { |
304 // This mode is only needed and implemented for ARM. | 299 // This mode is only needed and implemented for ARM. |
305 ASSERT(!use_far_branches); | 300 ASSERT(!use_far_branches); |
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
934 intptr_t pc_offset() const { return pc_offset_; } | 929 intptr_t pc_offset() const { return pc_offset_; } |
935 const String& comment() const { return comment_; } | 930 const String& comment() const { return comment_; } |
936 | 931 |
937 private: | 932 private: |
938 intptr_t pc_offset_; | 933 intptr_t pc_offset_; |
939 const String& comment_; | 934 const String& comment_; |
940 | 935 |
941 DISALLOW_COPY_AND_ASSIGN(CodeComment); | 936 DISALLOW_COPY_AND_ASSIGN(CodeComment); |
942 }; | 937 }; |
943 | 938 |
944 | |
945 inline void EmitUint8(uint8_t value); | 939 inline void EmitUint8(uint8_t value); |
946 inline void EmitInt32(int32_t value); | 940 inline void EmitInt32(int32_t value); |
947 inline void EmitRegisterOperand(int rm, int reg); | 941 inline void EmitRegisterOperand(int rm, int reg); |
948 inline void EmitXmmRegisterOperand(int rm, XmmRegister reg); | 942 inline void EmitXmmRegisterOperand(int rm, XmmRegister reg); |
949 inline void EmitFixup(AssemblerFixup* fixup); | 943 inline void EmitFixup(AssemblerFixup* fixup); |
950 inline void EmitOperandSizeOverride(); | 944 inline void EmitOperandSizeOverride(); |
951 | 945 |
952 void EmitOperand(int rm, const Operand& operand); | 946 void EmitOperand(int rm, const Operand& operand); |
953 void EmitImmediate(const Immediate& imm); | 947 void EmitImmediate(const Immediate& imm); |
954 void EmitComplex(int rm, const Operand& operand, const Immediate& immediate); | 948 void EmitComplex(int rm, const Operand& operand, const Immediate& immediate); |
(...skipping 18 matching lines...) Expand all Loading... |
973 ObjectPoolWrapper object_pool_wrapper_; | 967 ObjectPoolWrapper object_pool_wrapper_; |
974 intptr_t prologue_offset_; | 968 intptr_t prologue_offset_; |
975 int32_t jit_cookie_; | 969 int32_t jit_cookie_; |
976 GrowableArray<CodeComment*> comments_; | 970 GrowableArray<CodeComment*> comments_; |
977 Code& code_; | 971 Code& code_; |
978 | 972 |
979 DISALLOW_ALLOCATION(); | 973 DISALLOW_ALLOCATION(); |
980 DISALLOW_COPY_AND_ASSIGN(Assembler); | 974 DISALLOW_COPY_AND_ASSIGN(Assembler); |
981 }; | 975 }; |
982 | 976 |
983 | |
984 inline void Assembler::EmitUint8(uint8_t value) { | 977 inline void Assembler::EmitUint8(uint8_t value) { |
985 buffer_.Emit<uint8_t>(value); | 978 buffer_.Emit<uint8_t>(value); |
986 } | 979 } |
987 | 980 |
988 | |
989 inline void Assembler::EmitInt32(int32_t value) { | 981 inline void Assembler::EmitInt32(int32_t value) { |
990 buffer_.Emit<int32_t>(value); | 982 buffer_.Emit<int32_t>(value); |
991 } | 983 } |
992 | 984 |
993 | |
994 inline void Assembler::EmitRegisterOperand(int rm, int reg) { | 985 inline void Assembler::EmitRegisterOperand(int rm, int reg) { |
995 ASSERT(rm >= 0 && rm < 8); | 986 ASSERT(rm >= 0 && rm < 8); |
996 buffer_.Emit<uint8_t>(0xC0 + (rm << 3) + reg); | 987 buffer_.Emit<uint8_t>(0xC0 + (rm << 3) + reg); |
997 } | 988 } |
998 | 989 |
999 | |
1000 inline void Assembler::EmitXmmRegisterOperand(int rm, XmmRegister reg) { | 990 inline void Assembler::EmitXmmRegisterOperand(int rm, XmmRegister reg) { |
1001 EmitRegisterOperand(rm, static_cast<Register>(reg)); | 991 EmitRegisterOperand(rm, static_cast<Register>(reg)); |
1002 } | 992 } |
1003 | 993 |
1004 | |
1005 inline void Assembler::EmitFixup(AssemblerFixup* fixup) { | 994 inline void Assembler::EmitFixup(AssemblerFixup* fixup) { |
1006 buffer_.EmitFixup(fixup); | 995 buffer_.EmitFixup(fixup); |
1007 } | 996 } |
1008 | 997 |
1009 | |
1010 inline void Assembler::EmitOperandSizeOverride() { | 998 inline void Assembler::EmitOperandSizeOverride() { |
1011 EmitUint8(0x66); | 999 EmitUint8(0x66); |
1012 } | 1000 } |
1013 | 1001 |
1014 } // namespace dart | 1002 } // namespace dart |
1015 | 1003 |
1016 #endif // RUNTIME_VM_ASSEMBLER_IA32_H_ | 1004 #endif // RUNTIME_VM_ASSEMBLER_IA32_H_ |
OLD | NEW |