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