Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// | 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 /// | 9 /// |
| 10 /// \file | 10 /// \file |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 #include "IceLiveness.h" | 26 #include "IceLiveness.h" |
| 27 #include "IceOperand.h" | 27 #include "IceOperand.h" |
| 28 #include "IcePhiLoweringImpl.h" | 28 #include "IcePhiLoweringImpl.h" |
| 29 #include "IceUtils.h" | 29 #include "IceUtils.h" |
| 30 #include "IceInstX86Base.h" | 30 #include "IceInstX86Base.h" |
| 31 #include "llvm/Support/MathExtras.h" | 31 #include "llvm/Support/MathExtras.h" |
| 32 | 32 |
| 33 #include <stack> | 33 #include <stack> |
| 34 | 34 |
| 35 namespace Ice { | 35 namespace Ice { |
| 36 namespace X86 { | |
| 37 template <typename T> struct PoolTypeConverter {}; | |
| 38 | |
| 39 template <> struct PoolTypeConverter<float> { | |
| 40 using PrimitiveIntType = uint32_t; | |
| 41 using IceType = ConstantFloat; | |
| 42 static const Type Ty = IceType_f32; | |
| 43 static const char *TypeName; | |
| 44 static const char *AsmTag; | |
| 45 static const char *PrintfString; | |
| 46 }; | |
| 47 | |
| 48 template <> struct PoolTypeConverter<double> { | |
| 49 using PrimitiveIntType = uint64_t; | |
| 50 using IceType = ConstantDouble; | |
| 51 static const Type Ty = IceType_f64; | |
| 52 static const char *TypeName; | |
| 53 static const char *AsmTag; | |
| 54 static const char *PrintfString; | |
| 55 }; | |
| 56 | |
| 57 // Add converter for int type constant pooling | |
| 58 template <> struct PoolTypeConverter<uint32_t> { | |
| 59 using PrimitiveIntType = uint32_t; | |
| 60 using IceType = ConstantInteger32; | |
| 61 static const Type Ty = IceType_i32; | |
| 62 static const char *TypeName; | |
| 63 static const char *AsmTag; | |
| 64 static const char *PrintfString; | |
| 65 }; | |
| 66 | |
| 67 // Add converter for int type constant pooling | |
| 68 template <> struct PoolTypeConverter<uint16_t> { | |
| 69 using PrimitiveIntType = uint32_t; | |
| 70 using IceType = ConstantInteger32; | |
| 71 static const Type Ty = IceType_i16; | |
| 72 static const char *TypeName; | |
| 73 static const char *AsmTag; | |
| 74 static const char *PrintfString; | |
| 75 }; | |
| 76 | |
| 77 // Add converter for int type constant pooling | |
| 78 template <> struct PoolTypeConverter<uint8_t> { | |
| 79 using PrimitiveIntType = uint32_t; | |
| 80 using IceType = ConstantInteger32; | |
| 81 static const Type Ty = IceType_i8; | |
| 82 static const char *TypeName; | |
| 83 static const char *AsmTag; | |
| 84 static const char *PrintfString; | |
| 85 }; | |
| 86 } // end of namespace X86 | |
| 87 | |
| 36 namespace X86NAMESPACE { | 88 namespace X86NAMESPACE { |
| 37 | 89 |
| 38 /// A helper class to ease the settings of RandomizationPoolingPause to disable | 90 /// A helper class to ease the settings of RandomizationPoolingPause to disable |
| 39 /// constant blinding or pooling for some translation phases. | 91 /// constant blinding or pooling for some translation phases. |
| 40 class BoolFlagSaver { | 92 class BoolFlagSaver { |
| 41 BoolFlagSaver() = delete; | 93 BoolFlagSaver() = delete; |
| 42 BoolFlagSaver(const BoolFlagSaver &) = delete; | 94 BoolFlagSaver(const BoolFlagSaver &) = delete; |
| 43 BoolFlagSaver &operator=(const BoolFlagSaver &) = delete; | 95 BoolFlagSaver &operator=(const BoolFlagSaver &) = delete; |
| 44 | 96 |
| 45 public: | 97 public: |
| (...skipping 7176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7222 0, MemOperand->getSegmentRegister()); | 7274 0, MemOperand->getSegmentRegister()); |
| 7223 _lea(RegTemp, CalculateOperand); | 7275 _lea(RegTemp, CalculateOperand); |
| 7224 } | 7276 } |
| 7225 X86OperandMem *NewMemOperand = X86OperandMem::create( | 7277 X86OperandMem *NewMemOperand = X86OperandMem::create( |
| 7226 Func, MemOperand->getType(), RegTemp, nullptr, MemOperand->getIndex(), | 7278 Func, MemOperand->getType(), RegTemp, nullptr, MemOperand->getIndex(), |
| 7227 MemOperand->getShift(), MemOperand->getSegmentRegister()); | 7279 MemOperand->getShift(), MemOperand->getSegmentRegister()); |
| 7228 return NewMemOperand; | 7280 return NewMemOperand; |
| 7229 } | 7281 } |
| 7230 } | 7282 } |
| 7231 } | 7283 } |
| 7284 | |
| 7285 template <typename TraitsType> | |
| 7286 void TargetX86Base<TraitsType>::emitJumpTable( | |
| 7287 const Cfg *Func, const InstJumpTable *JumpTable) const { | |
| 7288 if (!BuildDefs::dump()) | |
| 7289 return; | |
| 7290 Ostream &Str = Ctx->getStrEmit(); | |
| 7291 const bool UseNonsfi = Ctx->getFlags().getUseNonsfi(); | |
| 7292 const IceString MangledName = Ctx->mangleName(Func->getFunctionName()); | |
| 7293 const IceString Prefix = UseNonsfi ? ".data.rel.ro." : ".rodata."; | |
| 7294 Str << "\t.section\t" << Prefix << MangledName | |
| 7295 << "$jumptable,\"a\",@progbits\n"; | |
| 7296 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; | |
| 7297 Str << InstJumpTable::makeName(MangledName, JumpTable->getId()) << ":"; | |
| 7298 | |
| 7299 // On X86 ILP32 pointers are 32-bit hence the use of .long | |
| 7300 for (SizeT I = 0; I < JumpTable->getNumTargets(); ++I) | |
| 7301 Str << "\n\t.long\t" << JumpTable->getTarget(I)->getAsmName(); | |
| 7302 Str << "\n"; | |
| 7303 } | |
| 7304 | |
| 7305 template <typename TraitsType> | |
| 7306 template <typename T> | |
| 7307 void TargetDataX86<TraitsType>::emitConstantPool(GlobalContext *Ctx) { | |
| 7308 if (!BuildDefs::dump()) | |
| 7309 return; | |
| 7310 Ostream &Str = Ctx->getStrEmit(); | |
| 7311 Type Ty = T::Ty; | |
| 7312 SizeT Align = typeAlignInBytes(Ty); | |
| 7313 ConstantList Pool = Ctx->getConstantPool(Ty); | |
| 7314 | |
| 7315 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align | |
| 7316 << "\n"; | |
| 7317 Str << "\t.align\t" << Align << "\n"; | |
| 7318 | |
| 7319 // If reorder-pooled-constants option is set to true, we need to shuffle the | |
| 7320 // constant pool before emitting it. | |
| 7321 if (Ctx->getFlags().shouldReorderPooledConstants() && !Pool.empty()) { | |
| 7322 // Use the constant's kind value as the salt for creating random number | |
| 7323 // generator. | |
| 7324 Operand::OperandKind K = (*Pool.begin())->getKind(); | |
| 7325 RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(), | |
| 7326 RPE_PooledConstantReordering, K); | |
| 7327 RandomShuffle(Pool.begin(), Pool.end(), | |
| 7328 [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); }); | |
| 7329 } | |
| 7330 | |
| 7331 for (Constant *C : Pool) { | |
| 7332 if (!C->getShouldBePooled()) | |
| 7333 continue; | |
| 7334 auto *Const = llvm::cast<typename T::IceType>(C); | |
| 7335 typename T::IceType::PrimType Value = Const->getValue(); | |
| 7336 // Use memcpy() to copy bits from Value into RawValue in a way that avoids | |
| 7337 // breaking strict-aliasing rules. | |
| 7338 typename T::PrimitiveIntType RawValue; | |
| 7339 memcpy(&RawValue, &Value, sizeof(Value)); | |
| 7340 char buf[30]; | |
| 7341 int CharsPrinted = | |
| 7342 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); | |
| 7343 assert(CharsPrinted >= 0 && | |
|
Jim Stichnoth
2016/01/22 05:52:10
This is better split into two separate asserts.
sehr
2016/01/22 07:06:23
Done.
| |
| 7344 (size_t)CharsPrinted < llvm::array_lengthof(buf)); | |
| 7345 (void)CharsPrinted; // avoid warnings if asserts are disabled | |
| 7346 Const->emitPoolLabel(Str, Ctx); | |
| 7347 Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t/* " << T::TypeName << " " | |
| 7348 << Value << " */\n"; | |
| 7349 } | |
| 7350 } | |
| 7351 | |
| 7352 template <typename TraitsType> | |
| 7353 void TargetDataX86<TraitsType>::lowerConstants() { | |
| 7354 if (Ctx->getFlags().getDisableTranslation()) | |
| 7355 return; | |
| 7356 // No need to emit constants from the int pool since (for x86) they are | |
|
Jim Stichnoth
2016/01/22 05:52:10
This comment seems wrong and should probably be de
sehr
2016/01/22 07:06:23
Deleted.
| |
| 7357 // embedded as immediates in the instructions, just emit float/double. | |
| 7358 switch (Ctx->getFlags().getOutFileType()) { | |
| 7359 case FT_Elf: { | |
| 7360 ELFObjectWriter *Writer = Ctx->getObjectWriter(); | |
| 7361 | |
| 7362 Writer->writeConstantPool<ConstantInteger32>(IceType_i8); | |
| 7363 Writer->writeConstantPool<ConstantInteger32>(IceType_i16); | |
| 7364 Writer->writeConstantPool<ConstantInteger32>(IceType_i32); | |
| 7365 | |
| 7366 Writer->writeConstantPool<ConstantFloat>(IceType_f32); | |
| 7367 Writer->writeConstantPool<ConstantDouble>(IceType_f64); | |
| 7368 } break; | |
| 7369 case FT_Asm: | |
| 7370 case FT_Iasm: { | |
| 7371 OstreamLocker L(Ctx); | |
| 7372 | |
| 7373 emitConstantPool<PoolTypeConverter<uint8_t>>(Ctx); | |
| 7374 emitConstantPool<PoolTypeConverter<uint16_t>>(Ctx); | |
| 7375 emitConstantPool<PoolTypeConverter<uint32_t>>(Ctx); | |
| 7376 | |
| 7377 emitConstantPool<PoolTypeConverter<float>>(Ctx); | |
| 7378 emitConstantPool<PoolTypeConverter<double>>(Ctx); | |
| 7379 } break; | |
| 7380 } | |
| 7381 } | |
| 7382 | |
| 7383 template <typename TraitsType> | |
| 7384 void TargetDataX86<TraitsType>::lowerJumpTables() { | |
| 7385 const bool IsPIC = Ctx->getFlags().getUseNonsfi(); | |
| 7386 switch (Ctx->getFlags().getOutFileType()) { | |
| 7387 case FT_Elf: { | |
| 7388 ELFObjectWriter *Writer = Ctx->getObjectWriter(); | |
| 7389 for (const JumpTableData &JT : Ctx->getJumpTables()) | |
| 7390 Writer->writeJumpTable(JT, Traits::FK_Abs, IsPIC); | |
| 7391 } break; | |
| 7392 case FT_Asm: | |
| 7393 // Already emitted from Cfg | |
| 7394 break; | |
| 7395 case FT_Iasm: { | |
| 7396 if (!BuildDefs::dump()) | |
| 7397 return; | |
| 7398 Ostream &Str = Ctx->getStrEmit(); | |
| 7399 const IceString Prefix = IsPIC ? ".data.rel.ro." : ".rodata."; | |
| 7400 for (const JumpTableData &JT : Ctx->getJumpTables()) { | |
| 7401 Str << "\t.section\t" << Prefix << JT.getFunctionName() | |
| 7402 << "$jumptable,\"a\",@progbits\n"; | |
| 7403 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; | |
| 7404 Str << InstJumpTable::makeName(JT.getFunctionName(), JT.getId()) << ":"; | |
| 7405 | |
| 7406 // On X8664 ILP32 pointers are 32-bit hence the use of .long | |
| 7407 for (intptr_t TargetOffset : JT.getTargetOffsets()) | |
| 7408 Str << "\n\t.long\t" << JT.getFunctionName() << "+" << TargetOffset; | |
| 7409 Str << "\n"; | |
| 7410 } | |
| 7411 } break; | |
| 7412 } | |
| 7413 } | |
| 7414 | |
| 7415 template <typename TraitsType> | |
| 7416 void TargetDataX86<TraitsType>::lowerGlobals( | |
| 7417 const VariableDeclarationList &Vars, const IceString &SectionSuffix) { | |
| 7418 const bool IsPIC = Ctx->getFlags().getUseNonsfi(); | |
| 7419 switch (Ctx->getFlags().getOutFileType()) { | |
| 7420 case FT_Elf: { | |
| 7421 ELFObjectWriter *Writer = Ctx->getObjectWriter(); | |
| 7422 Writer->writeDataSection(Vars, Traits::FK_Abs, SectionSuffix, IsPIC); | |
| 7423 } break; | |
| 7424 case FT_Asm: | |
| 7425 case FT_Iasm: { | |
| 7426 const IceString &TranslateOnly = Ctx->getFlags().getTranslateOnly(); | |
| 7427 OstreamLocker L(Ctx); | |
| 7428 for (const VariableDeclaration *Var : Vars) { | |
| 7429 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { | |
| 7430 emitGlobal(*Var, SectionSuffix); | |
| 7431 } | |
| 7432 } | |
| 7433 } break; | |
| 7434 } | |
| 7435 } | |
| 7232 } // end of namespace X86NAMESPACE | 7436 } // end of namespace X86NAMESPACE |
| 7233 } // end of namespace Ice | 7437 } // end of namespace Ice |
| 7234 | 7438 |
| 7235 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 7439 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
| OLD | NEW |