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 emitUint8(0x68); |
| 165 emitFixup(this->createFixup(Traits::FK_Abs, Label)); |
| 166 // In x86-32, the emitted value is an addend to the relocation. Therefore, we |
| 167 // must emit a 0 (because we're pushing an absolute relocation.) |
| 168 // In x86-64, the emitted value does not matter (the addend lives in the |
| 169 // relocation record as an extra field.) |
| 170 emitInt32(0); |
| 171 } |
| 172 |
| 173 template <typename TraitsType> |
155 void AssemblerX86Base<TraitsType>::popl(GPRRegister reg) { | 174 void AssemblerX86Base<TraitsType>::popl(GPRRegister reg) { |
156 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 175 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
157 // Any type that would not force a REX prefix to be emitted can be provided | 176 // Any type that would not force a REX prefix to be emitted can be provided |
158 // here. | 177 // here. |
159 emitRexB(RexTypeIrrelevant, reg); | 178 emitRexB(RexTypeIrrelevant, reg); |
160 emitUint8(0x58 + gprEncoding(reg)); | 179 emitUint8(0x58 + gprEncoding(reg)); |
161 } | 180 } |
162 | 181 |
163 template <typename TraitsType> | 182 template <typename TraitsType> |
164 void AssemblerX86Base<TraitsType>::popl(const Address &address) { | 183 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); | 394 assert(Traits::Is64Bit && SrcTy == IceType_i32); |
376 emitUint8(0x63); | 395 emitUint8(0x63); |
377 } | 396 } |
378 emitOperand(gprEncoding(dst), src); | 397 emitOperand(gprEncoding(dst), src); |
379 } | 398 } |
380 | 399 |
381 template <typename TraitsType> | 400 template <typename TraitsType> |
382 void AssemblerX86Base<TraitsType>::lea(Type Ty, GPRRegister dst, | 401 void AssemblerX86Base<TraitsType>::lea(Type Ty, GPRRegister dst, |
383 const Address &src) { | 402 const Address &src) { |
384 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 403 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
385 assert(Ty == IceType_i16 || Ty == IceType_i32); | 404 assert(Ty == IceType_i16 || Ty == IceType_i32 || |
| 405 (Traits::Is64Bit && Ty == IceType_i64)); |
386 if (Ty == IceType_i16) | 406 if (Ty == IceType_i16) |
387 emitOperandSizeOverride(); | 407 emitOperandSizeOverride(); |
388 emitAddrSizeOverridePrefix(); | 408 emitAddrSizeOverridePrefix(); |
389 emitRex(Ty, src, dst); | 409 emitRex(Ty, src, dst); |
390 emitUint8(0x8D); | 410 emitUint8(0x8D); |
391 emitOperand(gprEncoding(dst), src); | 411 emitOperand(gprEncoding(dst), src); |
392 } | 412 } |
393 | 413 |
394 template <typename TraitsType> | 414 template <typename TraitsType> |
395 void AssemblerX86Base<TraitsType>::cmov(Type Ty, BrCond cond, GPRRegister dst, | 415 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); | 3153 emitUint8(0xEB); |
3134 emitNearLabelLink(label); | 3154 emitNearLabelLink(label); |
3135 } else { | 3155 } else { |
3136 emitUint8(0xE9); | 3156 emitUint8(0xE9); |
3137 emitLabelLink(label); | 3157 emitLabelLink(label); |
3138 } | 3158 } |
3139 } | 3159 } |
3140 | 3160 |
3141 template <typename TraitsType> | 3161 template <typename TraitsType> |
3142 void AssemblerX86Base<TraitsType>::jmp(const ConstantRelocatable *label) { | 3162 void AssemblerX86Base<TraitsType>::jmp(const ConstantRelocatable *label) { |
3143 llvm::report_fatal_error("Untested - please verify and then reenable."); | |
3144 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3163 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
3145 emitUint8(0xE9); | 3164 emitUint8(0xE9); |
3146 emitFixup(this->createFixup(Traits::FK_PcRel, label)); | 3165 emitFixup(this->createFixup(Traits::FK_PcRel, label)); |
3147 emitInt32(-4); | 3166 emitInt32(-4); |
3148 } | 3167 } |
3149 | 3168 |
3150 template <typename TraitsType> void AssemblerX86Base<TraitsType>::mfence() { | 3169 template <typename TraitsType> void AssemblerX86Base<TraitsType>::mfence() { |
3151 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3170 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
3152 emitUint8(0x0F); | 3171 emitUint8(0x0F); |
3153 emitUint8(0xAE); | 3172 emitUint8(0xAE); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3300 nop(MAX_NOP_SIZE); | 3319 nop(MAX_NOP_SIZE); |
3301 bytes_needed -= MAX_NOP_SIZE; | 3320 bytes_needed -= MAX_NOP_SIZE; |
3302 } | 3321 } |
3303 if (bytes_needed) { | 3322 if (bytes_needed) { |
3304 nop(bytes_needed); | 3323 nop(bytes_needed); |
3305 } | 3324 } |
3306 assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0); | 3325 assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0); |
3307 } | 3326 } |
3308 | 3327 |
3309 template <typename TraitsType> | 3328 template <typename TraitsType> |
3310 void AssemblerX86Base<TraitsType>::bind(Label *label) { | 3329 void AssemblerX86Base<TraitsType>::bind(Label *L) { |
3311 intptr_t bound = Buffer.size(); | 3330 const intptr_t Bound = Buffer.size(); |
3312 assert(!label->isBound()); // Labels can only be bound once. | 3331 assert(!L->isBound()); // Labels can only be bound once. |
3313 while (label->isLinked()) { | 3332 while (L->isLinked()) { |
3314 intptr_t position = label->getLinkPosition(); | 3333 const intptr_t Position = L->getLinkPosition(); |
3315 intptr_t next = Buffer.load<int32_t>(position); | 3334 const intptr_t Next = Buffer.load<int32_t>(Position); |
3316 Buffer.store<int32_t>(position, bound - (position + 4)); | 3335 const intptr_t Offset = Bound - (Position + 4); |
3317 label->Position = next; | 3336 Buffer.store<int32_t>(Position, Offset); |
| 3337 L->Position = Next; |
3318 } | 3338 } |
3319 while (label->hasNear()) { | 3339 while (L->hasNear()) { |
3320 intptr_t position = label->getNearPosition(); | 3340 intptr_t Position = L->getNearPosition(); |
3321 intptr_t offset = bound - (position + 1); | 3341 const intptr_t Offset = Bound - (Position + 1); |
3322 assert(Utils::IsInt(8, offset)); | 3342 assert(Utils::IsInt(8, Offset)); |
3323 Buffer.store<int8_t>(position, offset); | 3343 Buffer.store<int8_t>(Position, Offset); |
3324 } | 3344 } |
3325 label->bindTo(bound); | 3345 L->bindTo(Bound); |
3326 } | 3346 } |
3327 | 3347 |
3328 template <typename TraitsType> | 3348 template <typename TraitsType> |
3329 void AssemblerX86Base<TraitsType>::emitOperand(int rm, const Operand &operand) { | 3349 void AssemblerX86Base<TraitsType>::emitOperand(int rm, const Operand &operand) { |
3330 assert(rm >= 0 && rm < 8); | 3350 assert(rm >= 0 && rm < 8); |
3331 const intptr_t length = operand.length_; | 3351 const intptr_t length = operand.length_; |
3332 assert(length > 0); | 3352 assert(length > 0); |
3333 intptr_t displacement_start = 1; | 3353 intptr_t displacement_start = 1; |
3334 // Emit the ModRM byte updated with the given RM value. | 3354 // Emit the ModRM byte updated with the given RM value. |
3335 assert((operand.encoding_[0] & 0x38) == 0); | 3355 assert((operand.encoding_[0] & 0x38) == 0); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3462 (void)shifter; | 3482 (void)shifter; |
3463 if (Ty == IceType_i16) | 3483 if (Ty == IceType_i16) |
3464 emitOperandSizeOverride(); | 3484 emitOperandSizeOverride(); |
3465 emitRexB(Ty, operand.rm()); | 3485 emitRexB(Ty, operand.rm()); |
3466 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); | 3486 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); |
3467 emitOperand(rm, operand); | 3487 emitOperand(rm, operand); |
3468 } | 3488 } |
3469 | 3489 |
3470 } // end of namespace X86NAMESPACE | 3490 } // end of namespace X86NAMESPACE |
3471 } // end of namespace Ice | 3491 } // end of namespace Ice |
OLD | NEW |