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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 emitRex(RexTypeIrrelevant, address, RexRegIrrelevant); | 127 emitRex(RexTypeIrrelevant, address, RexRegIrrelevant); |
128 emitUint8(0xFF); | 128 emitUint8(0xFF); |
129 emitOperand(2, address); | 129 emitOperand(2, address); |
130 } | 130 } |
131 | 131 |
132 template <typename TraitsType> | 132 template <typename TraitsType> |
133 void AssemblerX86Base<TraitsType>::call(const ConstantRelocatable *label) { | 133 void AssemblerX86Base<TraitsType>::call(const ConstantRelocatable *label) { |
134 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 134 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
135 intptr_t call_start = Buffer.getPosition(); | 135 intptr_t call_start = Buffer.getPosition(); |
136 emitUint8(0xE8); | 136 emitUint8(0xE8); |
137 emitFixup(this->createFixup(Traits::FK_PcRel, label)); | 137 auto *Fixup = this->createFixup(Traits::FK_PcRel, label); |
138 emitInt32(-4); | 138 Fixup->set_addend(-4); |
| 139 emitFixup(Fixup); |
| 140 emitInt32(0); |
139 assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize); | 141 assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize); |
140 (void)call_start; | 142 (void)call_start; |
141 } | 143 } |
142 | 144 |
143 template <typename TraitsType> | 145 template <typename TraitsType> |
144 void AssemblerX86Base<TraitsType>::call(const Immediate &abs_address) { | 146 void AssemblerX86Base<TraitsType>::call(const Immediate &abs_address) { |
145 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 147 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
146 intptr_t call_start = Buffer.getPosition(); | 148 intptr_t call_start = Buffer.getPosition(); |
147 emitUint8(0xE8); | 149 emitUint8(0xE8); |
148 emitFixup(this->createFixup(Traits::FK_PcRel, AssemblerFixup::NullSymbol)); | 150 auto *Fixup = this->createFixup(Traits::FK_PcRel, AssemblerFixup::NullSymbol); |
149 emitInt32(abs_address.value() - 4); | 151 Fixup->set_addend(abs_address.value() - 4); |
| 152 emitFixup(Fixup); |
| 153 emitInt32(0); |
150 assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize); | 154 assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize); |
151 (void)call_start; | 155 (void)call_start; |
152 } | 156 } |
153 | 157 |
154 template <typename TraitsType> | 158 template <typename TraitsType> |
155 void AssemblerX86Base<TraitsType>::pushl(GPRRegister reg) { | 159 void AssemblerX86Base<TraitsType>::pushl(GPRRegister reg) { |
156 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 160 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
157 emitRexB(RexTypeIrrelevant, reg); | 161 emitRexB(RexTypeIrrelevant, reg); |
158 emitUint8(0x50 + gprEncoding(reg)); | 162 emitUint8(0x50 + gprEncoding(reg)); |
159 } | 163 } |
(...skipping 2973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3133 } | 3137 } |
3134 } | 3138 } |
3135 | 3139 |
3136 template <typename TraitsType> | 3140 template <typename TraitsType> |
3137 void AssemblerX86Base<TraitsType>::j(BrCond condition, | 3141 void AssemblerX86Base<TraitsType>::j(BrCond condition, |
3138 const ConstantRelocatable *label) { | 3142 const ConstantRelocatable *label) { |
3139 llvm::report_fatal_error("Untested - please verify and then reenable."); | 3143 llvm::report_fatal_error("Untested - please verify and then reenable."); |
3140 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3144 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
3141 emitUint8(0x0F); | 3145 emitUint8(0x0F); |
3142 emitUint8(0x80 + condition); | 3146 emitUint8(0x80 + condition); |
3143 emitFixup(this->createFixup(Traits::FK_PcRel, label)); | 3147 auto *Fixup = this->createFixup(Traits::FK_PcRel, label); |
3144 emitInt32(-4); | 3148 Fixup->set_addend(-4); |
| 3149 emitFixup(Fixup); |
| 3150 emitInt32(0); |
3145 } | 3151 } |
3146 | 3152 |
3147 template <typename TraitsType> | 3153 template <typename TraitsType> |
3148 void AssemblerX86Base<TraitsType>::jmp(GPRRegister reg) { | 3154 void AssemblerX86Base<TraitsType>::jmp(GPRRegister reg) { |
3149 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3155 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
3150 emitRexB(RexTypeIrrelevant, reg); | 3156 emitRexB(RexTypeIrrelevant, reg); |
3151 emitUint8(0xFF); | 3157 emitUint8(0xFF); |
3152 emitRegisterOperand(4, gprEncoding(reg)); | 3158 emitRegisterOperand(4, gprEncoding(reg)); |
3153 } | 3159 } |
3154 | 3160 |
(...skipping 18 matching lines...) Expand all Loading... |
3173 } else { | 3179 } else { |
3174 emitUint8(0xE9); | 3180 emitUint8(0xE9); |
3175 emitLabelLink(label); | 3181 emitLabelLink(label); |
3176 } | 3182 } |
3177 } | 3183 } |
3178 | 3184 |
3179 template <typename TraitsType> | 3185 template <typename TraitsType> |
3180 void AssemblerX86Base<TraitsType>::jmp(const ConstantRelocatable *label) { | 3186 void AssemblerX86Base<TraitsType>::jmp(const ConstantRelocatable *label) { |
3181 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3187 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
3182 emitUint8(0xE9); | 3188 emitUint8(0xE9); |
3183 emitFixup(this->createFixup(Traits::FK_PcRel, label)); | 3189 auto *Fixup = this->createFixup(Traits::FK_PcRel, label); |
3184 emitInt32(-4); | 3190 Fixup->set_addend(-4); |
| 3191 emitFixup(Fixup); |
| 3192 emitInt32(0); |
3185 } | 3193 } |
3186 | 3194 |
3187 template <typename TraitsType> | 3195 template <typename TraitsType> |
3188 void AssemblerX86Base<TraitsType>::jmp(const Immediate &abs_address) { | 3196 void AssemblerX86Base<TraitsType>::jmp(const Immediate &abs_address) { |
3189 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3197 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
3190 emitUint8(0xE9); | 3198 emitUint8(0xE9); |
3191 AssemblerFixup *Fixup = | 3199 AssemblerFixup *Fixup = |
3192 this->createFixup(Traits::FK_PcRel, AssemblerFixup::NullSymbol); | 3200 createFixup(Traits::FK_PcRel, AssemblerFixup::NullSymbol); |
3193 Fixup->set_addend(abs_address.value()); | 3201 Fixup->set_addend(abs_address.value() - 4); |
3194 emitFixup(Fixup); | 3202 emitFixup(Fixup); |
3195 emitInt32(abs_address.value() - 4); | 3203 emitInt32(0); |
3196 } | 3204 } |
3197 | 3205 |
3198 template <typename TraitsType> void AssemblerX86Base<TraitsType>::mfence() { | 3206 template <typename TraitsType> void AssemblerX86Base<TraitsType>::mfence() { |
3199 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3207 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
3200 emitUint8(0x0F); | 3208 emitUint8(0x0F); |
3201 emitUint8(0xAE); | 3209 emitUint8(0xAE); |
3202 emitUint8(0xF0); | 3210 emitUint8(0xF0); |
3203 } | 3211 } |
3204 | 3212 |
3205 template <typename TraitsType> void AssemblerX86Base<TraitsType>::lock() { | 3213 template <typename TraitsType> void AssemblerX86Base<TraitsType>::lock() { |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3384 // Emit the ModRM byte updated with the given RM value. | 3392 // Emit the ModRM byte updated with the given RM value. |
3385 assert((operand.encoding_[0] & 0x38) == 0); | 3393 assert((operand.encoding_[0] & 0x38) == 0); |
3386 emitUint8(operand.encoding_[0] + (rm << 3)); | 3394 emitUint8(operand.encoding_[0] + (rm << 3)); |
3387 // Whenever the addressing mode is not register indirect, using esp == 0x4 | 3395 // Whenever the addressing mode is not register indirect, using esp == 0x4 |
3388 // as the register operation indicates an SIB byte follows. | 3396 // as the register operation indicates an SIB byte follows. |
3389 if (((operand.encoding_[0] & 0xc0) != 0xc0) && | 3397 if (((operand.encoding_[0] & 0xc0) != 0xc0) && |
3390 ((operand.encoding_[0] & 0x07) == 0x04)) { | 3398 ((operand.encoding_[0] & 0x07) == 0x04)) { |
3391 emitUint8(operand.encoding_[1]); | 3399 emitUint8(operand.encoding_[1]); |
3392 displacement_start = 2; | 3400 displacement_start = 2; |
3393 } | 3401 } |
3394 // Emit the displacement and the fixup that affects it, if any. | 3402 |
3395 AssemblerFixup *Fixup = operand.fixup(); | 3403 AssemblerFixup *Fixup = operand.fixup(); |
3396 if (Fixup != nullptr) { | 3404 if (Fixup == nullptr) { |
3397 emitFixup(Fixup); | 3405 for (intptr_t i = displacement_start; i < length; i++) { |
3398 assert(length - displacement_start == 4); | 3406 emitUint8(operand.encoding_[i]); |
3399 if (fixupIsPCRel(Fixup->kind())) { | |
3400 Fixup->set_addend(-Addend); | |
3401 int32_t Offset; | |
3402 memmove(&Offset, &operand.encoding_[displacement_start], sizeof(Offset)); | |
3403 Offset -= Addend; | |
3404 emitInt32(Offset); | |
3405 return; | |
3406 } | 3407 } |
| 3408 return; |
3407 } | 3409 } |
3408 for (intptr_t i = displacement_start; i < length; i++) { | 3410 |
3409 emitUint8(operand.encoding_[i]); | 3411 // Emit the fixup, and a dummy 4-byte immediate. Note that the Disp32 in |
| 3412 // operand.encoding_[i, i+1, i+2, i+3] is part of the constant relocatable |
| 3413 // used to create the fixup, so there's no need to add it to the addend. |
| 3414 assert(length - displacement_start == 4); |
| 3415 if (fixupIsPCRel(Fixup->kind())) { |
| 3416 Fixup->set_addend(Fixup->get_addend() - Addend); |
| 3417 } else { |
| 3418 Fixup->set_addend(Fixup->get_addend()); |
3410 } | 3419 } |
| 3420 emitFixup(Fixup); |
| 3421 emitInt32(0); |
3411 } | 3422 } |
3412 | 3423 |
3413 template <typename TraitsType> | 3424 template <typename TraitsType> |
3414 void AssemblerX86Base<TraitsType>::emitImmediate(Type Ty, | 3425 void AssemblerX86Base<TraitsType>::emitImmediate(Type Ty, |
3415 const Immediate &imm) { | 3426 const Immediate &imm) { |
3416 auto *const Fixup = imm.fixup(); | 3427 auto *const Fixup = imm.fixup(); |
3417 if (Ty == IceType_i16) { | 3428 if (Ty == IceType_i16) { |
3418 assert(Fixup == nullptr); | 3429 assert(Fixup == nullptr); |
3419 emitInt16(imm.value()); | 3430 emitInt16(imm.value()); |
3420 return; | 3431 return; |
3421 } | 3432 } |
3422 | 3433 |
3423 if (Fixup != nullptr) { | 3434 if (Fixup == nullptr) { |
3424 emitFixup(Fixup); | 3435 emitInt32(imm.value()); |
| 3436 return; |
3425 } | 3437 } |
3426 emitInt32(imm.value()); | 3438 |
| 3439 Fixup->set_addend(Fixup->get_addend() + imm.value()); |
| 3440 emitFixup(Fixup); |
| 3441 emitInt32(0); |
3427 } | 3442 } |
3428 | 3443 |
3429 template <typename TraitsType> | 3444 template <typename TraitsType> |
3430 void AssemblerX86Base<TraitsType>::emitComplexI8(int rm, const Operand &operand, | 3445 void AssemblerX86Base<TraitsType>::emitComplexI8(int rm, const Operand &operand, |
3431 const Immediate &immediate) { | 3446 const Immediate &immediate) { |
3432 assert(rm >= 0 && rm < 8); | 3447 assert(rm >= 0 && rm < 8); |
3433 assert(immediate.is_int8()); | 3448 assert(immediate.is_int8()); |
3434 if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) { | 3449 if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) { |
3435 // Use short form if the destination is al. | 3450 // Use short form if the destination is al. |
3436 emitUint8(0x04 + (rm << 3)); | 3451 emitUint8(0x04 + (rm << 3)); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3527 (void)shifter; | 3542 (void)shifter; |
3528 if (Ty == IceType_i16) | 3543 if (Ty == IceType_i16) |
3529 emitOperandSizeOverride(); | 3544 emitOperandSizeOverride(); |
3530 emitRexB(Ty, operand.rm()); | 3545 emitRexB(Ty, operand.rm()); |
3531 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); | 3546 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); |
3532 emitOperand(rm, operand); | 3547 emitOperand(rm, operand); |
3533 } | 3548 } |
3534 | 3549 |
3535 } // end of namespace X86NAMESPACE | 3550 } // end of namespace X86NAMESPACE |
3536 } // end of namespace Ice | 3551 } // end of namespace Ice |
OLD | NEW |