diff options
Diffstat (limited to 'llvm/lib/Target/X86/X86AsmPrinter.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/X86AsmPrinter.cpp | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp index 0c2c6bf7f8b7..f01e47b41cf5 100644 --- a/llvm/lib/Target/X86/X86AsmPrinter.cpp +++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp @@ -28,6 +28,7 @@ #include "llvm/CodeGenTypes/MachineValueType.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InlineAsm.h" +#include "llvm/IR/InstIterator.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" @@ -975,6 +976,33 @@ static void emitNonLazyStubs(MachineModuleInfo *MMI, MCStreamer &OutStreamer) { } } +/// True if this module is being built for windows/msvc, and uses floating +/// point. This is used to emit an undefined reference to _fltused. This is +/// needed in Windows kernel or driver contexts to find and prevent code from +/// modifying non-GPR registers. +/// +/// TODO: It would be better if this was computed from MIR by looking for +/// selected floating-point instructions. +static bool usesMSVCFloatingPoint(const Triple &TT, const Module &M) { + // Only needed for MSVC + if (!TT.isWindowsMSVCEnvironment()) + return false; + + for (const Function &F : M) { + for (const Instruction &I : instructions(F)) { + if (I.getType()->isFPOrFPVectorTy()) + return true; + + for (const auto &Op : I.operands()) { + if (Op->getType()->isFPOrFPVectorTy()) + return true; + } + } + } + + return false; +} + void X86AsmPrinter::emitEndOfAsmFile(Module &M) { const Triple &TT = TM.getTargetTriple(); @@ -993,7 +1021,7 @@ void X86AsmPrinter::emitEndOfAsmFile(Module &M) { // safe to set. OutStreamer->emitAssemblerFlag(MCAF_SubsectionsViaSymbols); } else if (TT.isOSBinFormatCOFF()) { - if (MMI->usesMSVCFloatingPoint()) { + if (usesMSVCFloatingPoint(TT, M)) { // In Windows' libcmt.lib, there is a file which is linked in only if the // symbol _fltused is referenced. Linking this in causes some // side-effects: @@ -1039,7 +1067,7 @@ void X86AsmPrinter::emitEndOfAsmFile(Module &M) { //===----------------------------------------------------------------------===// // Force static initialization. -extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86AsmPrinter() { +extern "C" LLVM_C_ABI void LLVMInitializeX86AsmPrinter() { RegisterAsmPrinter<X86AsmPrinter> X(getTheX86_32Target()); RegisterAsmPrinter<X86AsmPrinter> Y(getTheX86_64Target()); } |
