| 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 |