OLD | NEW |
1 //===- subzero/src/IceAssemblerX86BaseImpl.h - base x86 assembler -*- C++ -*-=// | 1 //===- subzero/src/IceAssemblerX86BaseImpl.h - base x86 assembler -*- C++ -*-=// |
2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
5 // | 5 // |
6 // Modified by the Subzero authors. | 6 // Modified by the Subzero authors. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // The Subzero Code Generator | 10 // The Subzero Code Generator |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 } | 145 } |
146 | 146 |
147 template <typename TraitsType> | 147 template <typename TraitsType> |
148 void AssemblerX86Base<TraitsType>::pushl(GPRRegister reg) { | 148 void AssemblerX86Base<TraitsType>::pushl(GPRRegister reg) { |
149 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 149 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
150 emitRexB(RexTypeIrrelevant, reg); | 150 emitRexB(RexTypeIrrelevant, reg); |
151 emitUint8(0x50 + gprEncoding(reg)); | 151 emitUint8(0x50 + gprEncoding(reg)); |
152 } | 152 } |
153 | 153 |
154 template <typename TraitsType> | 154 template <typename TraitsType> |
| 155 void AssemblerX86Base<TraitsType>::pushl(const Immediate &Imm) { |
| 156 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 157 emitUint8(0x68); |
| 158 emitInt32(Imm.value()); |
| 159 } |
| 160 |
| 161 template <typename TraitsType> |
| 162 void AssemblerX86Base<TraitsType>::pushl(const ConstantRelocatable *Label) { |
| 163 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 164 intptr_t call_start = Buffer.getPosition(); |
| 165 emitUint8(0x68); |
| 166 emitFixup(this->createFixup(Traits::FK_Abs, Label)); |
| 167 emitInt32(-4); |
| 168 assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize); |
| 169 (void)call_start; |
| 170 } |
| 171 |
| 172 template <typename TraitsType> |
155 void AssemblerX86Base<TraitsType>::popl(GPRRegister reg) { | 173 void AssemblerX86Base<TraitsType>::popl(GPRRegister reg) { |
156 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 174 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
157 // Any type that would not force a REX prefix to be emitted can be provided | 175 // Any type that would not force a REX prefix to be emitted can be provided |
158 // here. | 176 // here. |
159 emitRexB(RexTypeIrrelevant, reg); | 177 emitRexB(RexTypeIrrelevant, reg); |
160 emitUint8(0x58 + gprEncoding(reg)); | 178 emitUint8(0x58 + gprEncoding(reg)); |
161 } | 179 } |
162 | 180 |
163 template <typename TraitsType> | 181 template <typename TraitsType> |
164 void AssemblerX86Base<TraitsType>::popl(const Address &address) { | 182 void AssemblerX86Base<TraitsType>::popl(const Address &address) { |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 assert(Traits::Is64Bit && SrcTy == IceType_i32); | 393 assert(Traits::Is64Bit && SrcTy == IceType_i32); |
376 emitUint8(0x63); | 394 emitUint8(0x63); |
377 } | 395 } |
378 emitOperand(gprEncoding(dst), src); | 396 emitOperand(gprEncoding(dst), src); |
379 } | 397 } |
380 | 398 |
381 template <typename TraitsType> | 399 template <typename TraitsType> |
382 void AssemblerX86Base<TraitsType>::lea(Type Ty, GPRRegister dst, | 400 void AssemblerX86Base<TraitsType>::lea(Type Ty, GPRRegister dst, |
383 const Address &src) { | 401 const Address &src) { |
384 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 402 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
385 assert(Ty == IceType_i16 || Ty == IceType_i32); | 403 assert(Ty == IceType_i16 || Ty == IceType_i32 || |
| 404 (Traits::Is64Bit && Ty == IceType_i64)); |
386 if (Ty == IceType_i16) | 405 if (Ty == IceType_i16) |
387 emitOperandSizeOverride(); | 406 emitOperandSizeOverride(); |
388 emitAddrSizeOverridePrefix(); | 407 emitAddrSizeOverridePrefix(); |
389 emitRex(Ty, src, dst); | 408 emitRex(Ty, src, dst); |
390 emitUint8(0x8D); | 409 emitUint8(0x8D); |
391 emitOperand(gprEncoding(dst), src); | 410 emitOperand(gprEncoding(dst), src); |
392 } | 411 } |
393 | 412 |
394 template <typename TraitsType> | 413 template <typename TraitsType> |
395 void AssemblerX86Base<TraitsType>::cmov(Type Ty, BrCond cond, GPRRegister dst, | 414 void AssemblerX86Base<TraitsType>::cmov(Type Ty, BrCond cond, GPRRegister dst, |
(...skipping 2737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3133 emitUint8(0xEB); | 3152 emitUint8(0xEB); |
3134 emitNearLabelLink(label); | 3153 emitNearLabelLink(label); |
3135 } else { | 3154 } else { |
3136 emitUint8(0xE9); | 3155 emitUint8(0xE9); |
3137 emitLabelLink(label); | 3156 emitLabelLink(label); |
3138 } | 3157 } |
3139 } | 3158 } |
3140 | 3159 |
3141 template <typename TraitsType> | 3160 template <typename TraitsType> |
3142 void AssemblerX86Base<TraitsType>::jmp(const ConstantRelocatable *label) { | 3161 void AssemblerX86Base<TraitsType>::jmp(const ConstantRelocatable *label) { |
3143 llvm::report_fatal_error("Untested - please verify and then reenable."); | |
3144 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3162 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
3145 emitUint8(0xE9); | 3163 emitUint8(0xE9); |
3146 emitFixup(this->createFixup(Traits::FK_PcRel, label)); | 3164 emitFixup(this->createFixup(Traits::FK_PcRel, label)); |
3147 emitInt32(-4); | 3165 emitInt32(-4); |
3148 } | 3166 } |
3149 | 3167 |
3150 template <typename TraitsType> void AssemblerX86Base<TraitsType>::mfence() { | 3168 template <typename TraitsType> void AssemblerX86Base<TraitsType>::mfence() { |
3151 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3169 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
3152 emitUint8(0x0F); | 3170 emitUint8(0x0F); |
3153 emitUint8(0xAE); | 3171 emitUint8(0xAE); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3301 bytes_needed -= MAX_NOP_SIZE; | 3319 bytes_needed -= MAX_NOP_SIZE; |
3302 } | 3320 } |
3303 if (bytes_needed) { | 3321 if (bytes_needed) { |
3304 nop(bytes_needed); | 3322 nop(bytes_needed); |
3305 } | 3323 } |
3306 assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0); | 3324 assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0); |
3307 } | 3325 } |
3308 | 3326 |
3309 template <typename TraitsType> | 3327 template <typename TraitsType> |
3310 void AssemblerX86Base<TraitsType>::bind(Label *label) { | 3328 void AssemblerX86Base<TraitsType>::bind(Label *label) { |
3311 intptr_t bound = Buffer.size(); | 3329 const intptr_t Bound = Buffer.size(); |
3312 assert(!label->isBound()); // Labels can only be bound once. | 3330 assert(!label->isBound()); // Labels can only be bound once. |
3313 while (label->isLinked()) { | 3331 while (label->isLinked()) { |
3314 intptr_t position = label->getLinkPosition(); | 3332 const intptr_t Position = label->getLinkPosition(); |
3315 intptr_t next = Buffer.load<int32_t>(position); | 3333 const intptr_t Next = Buffer.load<int32_t>(Position); |
3316 Buffer.store<int32_t>(position, bound - (position + 4)); | 3334 const intptr_t Offset = Bound - (Position + 4); |
3317 label->Position = next; | 3335 Buffer.store<int32_t>(Position, Offset); |
| 3336 label->Position = Next; |
3318 } | 3337 } |
3319 while (label->hasNear()) { | 3338 while (label->hasNear()) { |
3320 intptr_t position = label->getNearPosition(); | 3339 intptr_t Position = label->getNearPosition(); |
3321 intptr_t offset = bound - (position + 1); | 3340 const intptr_t Offset = Bound - (Position + 1); |
3322 assert(Utils::IsInt(8, offset)); | 3341 assert(Utils::IsInt(8, Offset)); |
3323 Buffer.store<int8_t>(position, offset); | 3342 Buffer.store<int8_t>(Position, Offset); |
3324 } | 3343 } |
3325 label->bindTo(bound); | 3344 label->bindTo(Bound); |
3326 } | 3345 } |
3327 | 3346 |
3328 template <typename TraitsType> | 3347 template <typename TraitsType> |
3329 void AssemblerX86Base<TraitsType>::emitOperand(int rm, const Operand &operand) { | 3348 void AssemblerX86Base<TraitsType>::emitOperand(int rm, const Operand &operand) { |
3330 assert(rm >= 0 && rm < 8); | 3349 assert(rm >= 0 && rm < 8); |
3331 const intptr_t length = operand.length_; | 3350 const intptr_t length = operand.length_; |
3332 assert(length > 0); | 3351 assert(length > 0); |
3333 intptr_t displacement_start = 1; | 3352 intptr_t displacement_start = 1; |
3334 // Emit the ModRM byte updated with the given RM value. | 3353 // Emit the ModRM byte updated with the given RM value. |
3335 assert((operand.encoding_[0] & 0x38) == 0); | 3354 assert((operand.encoding_[0] & 0x38) == 0); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3462 (void)shifter; | 3481 (void)shifter; |
3463 if (Ty == IceType_i16) | 3482 if (Ty == IceType_i16) |
3464 emitOperandSizeOverride(); | 3483 emitOperandSizeOverride(); |
3465 emitRexB(Ty, operand.rm()); | 3484 emitRexB(Ty, operand.rm()); |
3466 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); | 3485 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); |
3467 emitOperand(rm, operand); | 3486 emitOperand(rm, operand); |
3468 } | 3487 } |
3469 | 3488 |
3470 } // end of namespace X86NAMESPACE | 3489 } // end of namespace X86NAMESPACE |
3471 } // end of namespace Ice | 3490 } // end of namespace Ice |
OLD | NEW |