diff options
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/Alpha/AlphaAsmPrinter.cpp | 8 | ||||
-rw-r--r-- | lib/Target/CBackend/CBackend.cpp | 13 | ||||
-rw-r--r-- | lib/Target/CBackend/Writer.cpp | 13 | ||||
-rw-r--r-- | lib/Target/IA64/IA64AsmPrinter.cpp | 8 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcAsmPrinter.cpp | 8 | ||||
-rwxr-xr-x | lib/Target/X86/X86ATTAsmPrinter.cpp | 28 | ||||
-rw-r--r-- | lib/Target/X86/X86AsmPrinter.cpp | 24 | ||||
-rwxr-xr-x | lib/Target/X86/X86AsmPrinter.h | 3 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 16 | ||||
-rwxr-xr-x | lib/Target/X86/X86IntelAsmPrinter.cpp | 59 | ||||
-rw-r--r-- | lib/Target/X86/X86Subtarget.h | 2 |
11 files changed, 171 insertions, 11 deletions
diff --git a/lib/Target/Alpha/AlphaAsmPrinter.cpp b/lib/Target/Alpha/AlphaAsmPrinter.cpp index 2ce4865404..52e2bb6d34 100644 --- a/lib/Target/Alpha/AlphaAsmPrinter.cpp +++ b/lib/Target/Alpha/AlphaAsmPrinter.cpp @@ -258,6 +258,14 @@ bool AlphaAsmPrinter::doFinalization(Module &M) { case GlobalValue::GhostLinkage: std::cerr << "GhostLinkage cannot appear in AlphaAsmPrinter!\n"; abort(); + case GlobalValue::DLLImportLinkage: + std::cerr << "DLLImport linkage is not supported by this target!\n"; + abort(); + case GlobalValue::DLLExportLinkage: + std::cerr << "DLLExport linkage is not supported by this target!\n"; + abort(); + default: + assert(0 && "Unknown linkage type!"); } EmitAlignment(Align); diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 330a7bc53f..2aa36270bf 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -1054,7 +1054,11 @@ bool CWriter::doInitialization(Module &M) { Out << "extern "; printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); Out << ";\n"; - } + } else if (I->hasDLLImportLinkage()) { + Out << "__declspec(dllimport) "; + printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); + Out << ";\n"; + } } } @@ -1118,6 +1122,11 @@ bool CWriter::doInitialization(Module &M) { if (I->hasInternalLinkage()) Out << "static "; + else if (I->hasDLLImportLinkage()) + Out << "__declspec(dllimport) "; + else if (I->hasDLLExportLinkage()) + Out << "__declspec(dllexport) "; + printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); if (I->hasLinkOnceLinkage()) Out << " __attribute__((common))"; @@ -1267,6 +1276,8 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) { bool isCStructReturn = F->getCallingConv() == CallingConv::CSRet; if (F->hasInternalLinkage()) Out << "static "; + if (F->hasDLLImportLinkage()) Out << "__declspec(dllimport) "; + if (F->hasDLLExportLinkage()) Out << "__declspec(dllexport) "; // Loop over the arguments, printing them... const FunctionType *FT = cast<FunctionType>(F->getFunctionType()); diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index 330a7bc53f..2aa36270bf 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -1054,7 +1054,11 @@ bool CWriter::doInitialization(Module &M) { Out << "extern "; printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); Out << ";\n"; - } + } else if (I->hasDLLImportLinkage()) { + Out << "__declspec(dllimport) "; + printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); + Out << ";\n"; + } } } @@ -1118,6 +1122,11 @@ bool CWriter::doInitialization(Module &M) { if (I->hasInternalLinkage()) Out << "static "; + else if (I->hasDLLImportLinkage()) + Out << "__declspec(dllimport) "; + else if (I->hasDLLExportLinkage()) + Out << "__declspec(dllexport) "; + printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); if (I->hasLinkOnceLinkage()) Out << " __attribute__((common))"; @@ -1267,6 +1276,8 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) { bool isCStructReturn = F->getCallingConv() == CallingConv::CSRet; if (F->hasInternalLinkage()) Out << "static "; + if (F->hasDLLImportLinkage()) Out << "__declspec(dllimport) "; + if (F->hasDLLExportLinkage()) Out << "__declspec(dllexport) "; // Loop over the arguments, printing them... const FunctionType *FT = cast<FunctionType>(F->getFunctionType()); diff --git a/lib/Target/IA64/IA64AsmPrinter.cpp b/lib/Target/IA64/IA64AsmPrinter.cpp index 4a16777f9b..5fcc86f50e 100644 --- a/lib/Target/IA64/IA64AsmPrinter.cpp +++ b/lib/Target/IA64/IA64AsmPrinter.cpp @@ -306,6 +306,14 @@ bool IA64AsmPrinter::doFinalization(Module &M) { case GlobalValue::GhostLinkage: std::cerr << "GhostLinkage cannot appear in IA64AsmPrinter!\n"; abort(); + case GlobalValue::DLLImportLinkage: + std::cerr << "DLLImport linkage is not supported by this target!\n"; + abort(); + case GlobalValue::DLLExportLinkage: + std::cerr << "DLLExport linkage is not supported by this target!\n"; + abort(); + default: + assert(0 && "Unknown linkage type!"); } EmitAlignment(Align); diff --git a/lib/Target/Sparc/SparcAsmPrinter.cpp b/lib/Target/Sparc/SparcAsmPrinter.cpp index 1e6efcbeaf..f8efc9ee54 100644 --- a/lib/Target/Sparc/SparcAsmPrinter.cpp +++ b/lib/Target/Sparc/SparcAsmPrinter.cpp @@ -271,6 +271,14 @@ bool SparcAsmPrinter::doFinalization(Module &M) { case GlobalValue::GhostLinkage: std::cerr << "Should not have any unmaterialized functions!\n"; abort(); + case GlobalValue::DLLImportLinkage: + std::cerr << "DLLImport linkage is not supported by this target!\n"; + abort(); + case GlobalValue::DLLExportLinkage: + std::cerr << "DLLExport linkage is not supported by this target!\n"; + abort(); + default: + assert(0 && "Unknown linkage type!"); } O << "\t.align " << Align << "\n"; diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp index b17cde18de..1ce24fda0c 100755 --- a/lib/Target/X86/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/X86ATTAsmPrinter.cpp @@ -48,10 +48,13 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { SwitchToTextSection(TAI->getTextSection(), F); EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. break; + case Function::DLLExportLinkage: + DLLExportedFns.insert(Mang->makeNameProper(F->getName(), "")); + //FALLS THROUGH case Function::ExternalLinkage: SwitchToTextSection(TAI->getTextSection(), F); EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. - O << "\t.globl\t" << CurrentFnName << "\n"; + O << "\t.globl\t" << CurrentFnName << "\n"; break; case Function::WeakLinkage: case Function::LinkOnceLinkage: @@ -179,8 +182,9 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp && !isCallOp) O << '$'; - GlobalValue *GV = MO.getGlobal(); + GlobalValue *GV = MO.getGlobal(); std::string Name = Mang->getValueName(GV); + bool isExt = (GV->isExternal() || GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()); if (X86PICStyle == PICStyle::Stub && @@ -196,13 +200,27 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, GVStubs.insert(Name); O << "L" << Name << "$non_lazy_ptr"; } - } else + } else { + if (GV->hasDLLImportLinkage()) { + // FIXME: This should be fixed with full support of stdcall & fastcall + // CC's + O << "__imp_"; + } O << Name; + } + if (!isCallOp && TM.getRelocationModel() == Reloc::PIC_) O << "-\"L" << getFunctionNumber() << "$pb\""; - } else + } else { + if (GV->hasDLLImportLinkage()) { + // FIXME: This should be fixed with full support of stdcall & fastcall + // CC's + O << "__imp_"; + } O << Name; - + + } + int Offset = MO.getOffset(); if (Offset > 0) O << "+" << Offset; diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index b634d13ea4..08dc7b2650 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -112,6 +112,9 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { case GlobalValue::AppendingLinkage: // FIXME: appending linkage variables should go into a section of // their name or something. For now, just emit them as external. + case GlobalValue::DLLExportLinkage: + DLLExportedGVs.insert(Mang->makeNameProper(I->getName(),"")); + // FALL THROUGH case GlobalValue::ExternalLinkage: // If external or appending, declare as a global symbol O << "\t.globl " << name << "\n"; @@ -134,6 +137,27 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { } } + // Output linker support code for dllexported globals + if (DLLExportedGVs.begin() != DLLExportedGVs.end()) { + SwitchToDataSection(".section .drectve", 0); + } + + for (std::set<std::string>::iterator i = DLLExportedGVs.begin(), + e = DLLExportedGVs.end(); + i != e; ++i) { + O << "\t.ascii \" -export:" << *i << ",data\"\n"; + } + + if (DLLExportedFns.begin() != DLLExportedFns.end()) { + SwitchToDataSection(".section .drectve", 0); + } + + for (std::set<std::string>::iterator i = DLLExportedFns.begin(), + e = DLLExportedFns.end(); + i != e; ++i) { + O << "\t.ascii \" -export:" << *i << "\"\n"; + } + if (Subtarget->isTargetDarwin()) { SwitchToDataSection("", 0); diff --git a/lib/Target/X86/X86AsmPrinter.h b/lib/Target/X86/X86AsmPrinter.h index 6db9e45dc3..ae03ca5382 100755 --- a/lib/Target/X86/X86AsmPrinter.h +++ b/lib/Target/X86/X86AsmPrinter.h @@ -63,6 +63,9 @@ struct VISIBILITY_HIDDEN X86SharedAsmPrinter : public AsmPrinter { // Necessary for Darwin to print out the apprioriate types of linker stubs std::set<std::string> FnStubs, GVStubs, LinkOnceStubs; + // Necessary for dllexport support + std::set<std::string> DLLExportedFns, DLLExportedGVs; + inline static bool isScale(const MachineOperand &MO) { return MO.isImmediate() && (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 || diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index dfd7aa5904..166345c2b2 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1964,6 +1964,15 @@ static bool DarwinGVRequiresExtraLoad(GlobalValue *GV) { (GV->isExternal() && !GV->hasNotBeenReadFromBytecode())); } +/// WinndowsGVRequiresExtraLoad - true if accessing the GV requires an extra +/// load. For Windows, dllimported variables (not functions!) are indirect, +/// loading the value at address GV rather then the value of GV itself. This +/// means that the GlobalAddress must be in the base or index register of the +/// address, not the GV offset field. +static bool WindowsGVRequiresExtraLoad(GlobalValue *GV) { + return (isa<GlobalVariable>((Value*)GV) && GV->hasDLLImportLinkage()); +} + /// isUndefOrInRange - Op is either an undef node or a ConstantSDNode. Return /// true if Op is undef or if its value falls within the specified range (L, H]. static bool isUndefOrInRange(SDOperand Op, unsigned Low, unsigned Hi) { @@ -3376,7 +3385,14 @@ X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) { DarwinGVRequiresExtraLoad(GV)) Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, DAG.getSrcValue(NULL)); + } else if (Subtarget->isTargetCygwin() || Subtarget->isTargetWindows()) { + // FIXME: What's about PIC? + if (WindowsGVRequiresExtraLoad(GV)) { + Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), + Result, DAG.getSrcValue(NULL)); + } } + return Result; } diff --git a/lib/Target/X86/X86IntelAsmPrinter.cpp b/lib/Target/X86/X86IntelAsmPrinter.cpp index 24dbb15941..44a218ca1e 100755 --- a/lib/Target/X86/X86IntelAsmPrinter.cpp +++ b/lib/Target/X86/X86IntelAsmPrinter.cpp @@ -35,10 +35,23 @@ bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) { EmitConstantPool(MF.getConstantPool()); // Print out labels for the function. - SwitchToTextSection("_text", MF.getFunction()); - EmitAlignment(4); - if (MF.getFunction()->getLinkage() == GlobalValue::ExternalLinkage) + const Function* F = MF.getFunction(); + switch (F->getLinkage()) { + default: assert(0 && "Unsupported linkage type!"); + case Function::InternalLinkage: + SwitchToTextSection("_text", F); + EmitAlignment(4); + break; + case Function::DLLExportLinkage: + DLLExportedFns.insert(CurrentFnName); + //FALLS THROUGH + case Function::ExternalLinkage: O << "\tpublic " << CurrentFnName << "\n"; + SwitchToTextSection("_text", F); + EmitAlignment(4); + break; + } + O << CurrentFnName << "\tproc near\n"; // Print out code for the function. @@ -118,8 +131,15 @@ void X86IntelAsmPrinter::printOp(const MachineOperand &MO, case MachineOperand::MO_GlobalAddress: { bool isCallOp = Modifier && !strcmp(Modifier, "call"); bool isMemOp = Modifier && !strcmp(Modifier, "mem"); + GlobalValue *GV = MO.getGlobal(); + if (!isMemOp && !isCallOp) O << "OFFSET "; - O << Mang->getValueName(MO.getGlobal()); + if (GV->hasDLLImportLinkage()) { + // FIXME: This should be fixed with full support of stdcall & fastcall + // CC's + O << "__imp_"; + } + O << Mang->getValueName(GV); int Offset = MO.getOffset(); if (Offset > 0) O << " + " << Offset; @@ -350,6 +370,9 @@ bool X86IntelAsmPrinter::doFinalization(Module &M) { // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256 // are also available. break; + case GlobalValue::DLLExportLinkage: + DLLExportedGVs.insert(name); + // FALL THROUGH case GlobalValue::ExternalLinkage: O << "\tpublic " << name << "\n"; // FALL THROUGH @@ -371,6 +394,34 @@ bool X86IntelAsmPrinter::doFinalization(Module &M) { if (bCustomSegment) O << name << "?\tends\n"; } + + // Output linker support code for dllexported globals + if ((DLLExportedGVs.begin() != DLLExportedGVs.end()) || + (DLLExportedFns.begin() != DLLExportedFns.end())) { + SwitchToDataSection("", 0); + O << "; WARNING: The following code is valid only with MASM v8.x and (possible) higher\n" + << "; This version of MASM is usually shipped with Microsoft Visual Studio 2005\n" + << "; or (possible) further versions. Unfortunately, there is no way to support\n" + << "; dllexported symbols in the earlier versions of MASM in fully automatic way\n\n"; + O << "_drectve\t segment info alias('.drectve')\n"; + } + + for (std::set<std::string>::iterator i = DLLExportedGVs.begin(), + e = DLLExportedGVs.end(); + i != e; ++i) { + O << "\t db ' /EXPORT:" << *i << ",data'\n"; + } + + for (std::set<std::string>::iterator i = DLLExportedFns.begin(), + e = DLLExportedFns.end(); + i != e; ++i) { + O << "\t db ' /EXPORT:" << *i << "'\n"; + } + + if ((DLLExportedGVs.begin() != DLLExportedGVs.end()) || + (DLLExportedFns.begin() != DLLExportedFns.end())) { + O << "_drectve\t ends\n"; + } // Bypass X86SharedAsmPrinter::doFinalization(). AsmPrinter::doFinalization(M); diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h index 224ebcd308..6e0d1dbae6 100644 --- a/lib/Target/X86/X86Subtarget.h +++ b/lib/Target/X86/X86Subtarget.h @@ -99,6 +99,8 @@ public: bool isTargetDarwin() const { return TargetType == isDarwin; } bool isTargetELF() const { return TargetType == isELF; } + bool isTargetWindows() const { return TargetType == isWindows; } + bool isTargetCygwin() const { return TargetType == isCygwin; } }; } // End llvm namespace |