Chromium Code Reviews| 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); |
|
Jim Stichnoth
2016/02/03 23:18:27
AssemblerFixup *Fixup
here and below
John
2016/02/04 18:28:50
Discussed offline. Leaving as is.
| |
| 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 |