X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FX86%2FX86AsmPrinter.cpp;h=f9756f046f6214397e6e715236c1c80652d2096c;hb=99e635ca69200009d899dce03258237ec1484dfe;hp=5c28fac10cf1ee3d5588184f2199dbe8a23ac231;hpb=39e9c09763d06b3c2133bcf0d8fec02120d63b93;p=oota-llvm.git diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index 5c28fac10cf..f9756f046f6 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -24,6 +24,7 @@ #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/Module.h" +#include "llvm/DerivedTypes.h" #include "llvm/Type.h" #include "llvm/Assembly/Writer.h" #include "llvm/Support/Mangler.h" @@ -31,9 +32,9 @@ #include "llvm/Target/TargetOptions.h" using namespace llvm; -static X86FunctionInfo calculateFunctionInfo(const Function *F, - const TargetData *TD) { - X86FunctionInfo Info; +static X86MachineFunctionInfo calculateFunctionInfo(const Function *F, + const TargetData *TD) { + X86MachineFunctionInfo Info; uint64_t Size = 0; switch (F->getCallingConv()) { @@ -49,10 +50,8 @@ static X86FunctionInfo calculateFunctionInfo(const Function *F, for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); AI != AE; ++AI) - Size += TD->getTypeSize(AI->getType()); - - // Size should be aligned to DWORD boundary - Size = ((Size + 3)/4)*4; + // Size should be aligned to DWORD boundary + Size += ((TD->getABITypeSize(AI->getType()) + 3)/4)*4; // We're not supporting tooooo huge arguments :) Info.setBytesToPopOnReturn((unsigned int)Size); @@ -71,10 +70,14 @@ void X86SharedAsmPrinter::decorateName(std::string &Name, unsigned CC = F->getCallingConv(); if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall) return; + + // Decorate names only when we're targeting Cygwin/Mingw32 targets + if (!Subtarget->isTargetCygMing()) + return; FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F); - const X86FunctionInfo *Info; + const X86MachineFunctionInfo *Info; if (info_item == FunctionInfoMap.end()) { // Calculate apropriate function info and populate map FunctionInfoMap[F] = calculateFunctionInfo(F, TM.getTargetData()); @@ -82,16 +85,21 @@ void X86SharedAsmPrinter::decorateName(std::string &Name, } else { Info = &info_item->second; } - + + const FunctionType *FT = F->getFunctionType(); switch (Info->getDecorationStyle()) { case None: break; case StdCall: - if (!F->isVarArg()) // Variadic functions do not receive @0 suffix. + // "Pure" variadic functions do not receive @0 suffix. + if (!FT->isVarArg() || (FT->getNumParams() == 0) || + (FT->getNumParams() == 1 && F->isStructReturn())) Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); break; case FastCall: - if (!F->isVarArg()) // Variadic functions do not receive @0 suffix. + // "Pure" variadic functions do not receive @0 suffix. + if (!FT->isVarArg() || (FT->getNumParams() == 0) || + (FT->getNumParams() == 1 && F->isStructReturn())) Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); if (Name[0] == '_') { @@ -107,14 +115,18 @@ void X86SharedAsmPrinter::decorateName(std::string &Name, /// doInitialization bool X86SharedAsmPrinter::doInitialization(Module &M) { - if (Subtarget->isTargetELF() || - Subtarget->isTargetCygMing() || - Subtarget->isTargetDarwin()) { + if (TAI->doesSupportDebugInformation()) { // Emit initial debug information. DW.BeginModule(&M); } - return AsmPrinter::doInitialization(M); + bool Result = AsmPrinter::doInitialization(M); + + // Darwin wants symbols to be quoted if they have complex names. + if (Subtarget->isTargetDarwin()) + Mang->setUseQuotes(true); + + return Result; } bool X86SharedAsmPrinter::doFinalization(Module &M) { @@ -130,31 +142,45 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { continue; // External global require no code // Check to see if this is a special global used by LLVM, if so, emit it. - if (EmitSpecialLLVMGlobal(I)) + if (EmitSpecialLLVMGlobal(I)) { + if (Subtarget->isTargetDarwin() && + TM.getRelocationModel() == Reloc::Static) { + if (I->getName() == "llvm.global_ctors") + O << ".reference .constructors_used\n"; + else if (I->getName() == "llvm.global_dtors") + O << ".reference .destructors_used\n"; + } continue; + } std::string name = Mang->getValueName(I); Constant *C = I->getInitializer(); - unsigned Size = TD->getTypeSize(C->getType()); + const Type *Type = C->getType(); + unsigned Size = TD->getABITypeSize(Type); unsigned Align = TD->getPreferredAlignmentLog(I); - if (I->hasHiddenVisibility()) + if (I->hasHiddenVisibility()) { if (const char *Directive = TAI->getHiddenDirective()) O << Directive << name << "\n"; + } else if (I->hasProtectedVisibility()) { + if (const char *Directive = TAI->getProtectedDirective()) + O << Directive << name << "\n"; + } + if (Subtarget->isTargetELF()) - O << "\t.type " << name << ",@object\n"; + O << "\t.type\t" << name << ",@object\n"; - if (C->isNullValue()) { + if (C->isNullValue() && !I->hasSection()) { if (I->hasExternalLinkage()) { if (const char *Directive = TAI->getZeroFillDirective()) { - O << "\t.globl\t" << name << "\n"; + O << "\t.globl " << name << "\n"; O << Directive << "__DATA__, __common, " << name << ", " << Size << ", " << Align << "\n"; continue; } } - if (!I->hasSection() && + if (!I->isThreadLocal() && (I->hasInternalLinkage() || I->hasWeakLinkage() || I->hasLinkOnceLinkage())) { if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. @@ -167,8 +193,13 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { O << TAI->getLCOMMDirective() << name << "," << Size; if (Subtarget->isTargetDarwin()) O << "," << Align; - } else + } else { O << TAI->getCOMMDirective() << name << "," << Size; + + // Leopard and above support aligned common symbols. + if (Subtarget->getDarwinVers() >= 9) + O << "," << Align; + } } else { if (!Subtarget->isTargetCygMing()) { if (I->hasInternalLinkage()) @@ -188,29 +219,29 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { case GlobalValue::WeakLinkage: if (Subtarget->isTargetDarwin()) { O << "\t.globl " << name << "\n" - << "\t.weak_definition " << name << "\n"; - SwitchToDataSection(".section __DATA,__const_coal,coalesced", I); + << TAI->getWeakDefDirective() << name << "\n"; + SwitchToDataSection("\t.section __DATA,__datacoal_nt,coalesced", I); } else if (Subtarget->isTargetCygMing()) { std::string SectionName(".section\t.data$linkonce." + name + ",\"aw\""); SwitchToDataSection(SectionName.c_str(), I); - O << "\t.globl " << name << "\n" + O << "\t.globl\t" << name << "\n" << "\t.linkonce same_size\n"; } else { std::string SectionName("\t.section\t.llvm.linkonce.d." + name + ",\"aw\",@progbits"); SwitchToDataSection(SectionName.c_str(), I); - O << "\t.weak " << name << "\n"; + O << "\t.weak\t" << name << "\n"; } break; - 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::AppendingLinkage: + // FIXME: appending linkage variables should go into a section of + // their name or something. For now, just emit them as external. case GlobalValue::ExternalLinkage: // If external or appending, declare as a global symbol O << "\t.globl " << name << "\n"; @@ -239,9 +270,34 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { SwitchToDataSection(SectionName.c_str()); } else { if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection()) - SwitchToDataSection(TAI->getBSSSection(), I); - else - SwitchToDataSection(TAI->getDataSection(), I); + SwitchToDataSection(I->isThreadLocal() ? TAI->getTLSBSSSection() : + TAI->getBSSSection(), I); + else if (!I->isConstant()) + SwitchToDataSection(I->isThreadLocal() ? TAI->getTLSDataSection() : + TAI->getDataSection(), I); + else if (I->isThreadLocal()) + SwitchToDataSection(TAI->getTLSDataSection()); + else { + // Read-only data. + bool HasReloc = C->ContainsRelocations(); + if (HasReloc && + Subtarget->isTargetDarwin() && + TM.getRelocationModel() != Reloc::Static) + SwitchToDataSection("\t.const_data\n"); + else if (!HasReloc && Size == 4 && + TAI->getFourByteConstantSection()) + SwitchToDataSection(TAI->getFourByteConstantSection(), I); + else if (!HasReloc && Size == 8 && + TAI->getEightByteConstantSection()) + SwitchToDataSection(TAI->getEightByteConstantSection(), I); + else if (!HasReloc && Size == 16 && + TAI->getSixteenByteConstantSection()) + SwitchToDataSection(TAI->getSixteenByteConstantSection(), I); + else if (TAI->getReadOnlySection()) + SwitchToDataSection(TAI->getReadOnlySection(), I); + else + SwitchToDataSection(TAI->getDataSection(), I); + } } break; @@ -254,7 +310,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName() << "\n"; if (TAI->hasDotTypeDotSizeDirective()) - O << "\t.size " << name << ", " << Size << "\n"; + O << "\t.size\t" << name << ", " << Size << "\n"; // If the initializer is a extern weak symbol, remember to emit the weak // reference! if (const GlobalValue *GV = dyn_cast(C)) @@ -262,11 +318,10 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { ExtWeakSymbols.insert(GV); EmitGlobalConstant(C); - O << '\n'; } // Output linker support code for dllexported globals - if (DLLExportedGVs.begin() != DLLExportedGVs.end()) { + if (!DLLExportedGVs.empty()) { SwitchToDataSection(".section .drectve"); } @@ -276,7 +331,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { O << "\t.ascii \" -export:" << *i << ",data\"\n"; } - if (DLLExportedFns.begin() != DLLExportedFns.end()) { + if (!DLLExportedFns.empty()) { SwitchToDataSection(".section .drectve"); } @@ -293,7 +348,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { unsigned j = 1; for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); i != e; ++i, ++j) { - SwitchToDataSection(".section __IMPORT,__jump_table,symbol_stubs," + SwitchToDataSection("\t.section __IMPORT,__jump_table,symbol_stubs," "self_modifying_code+pure_instructions,5", 0); O << "L" << *i << "$stub:\n"; O << "\t.indirect_symbol " << *i << "\n"; @@ -302,10 +357,20 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { O << "\n"; + if (ExceptionHandling && TAI->doesSupportExceptionHandling() && MMI && + !Subtarget->is64Bit()) { + // Add the (possibly multiple) personalities to the set of global values. + const std::vector& Personalities = MMI->getPersonalities(); + + for (std::vector::const_iterator I = Personalities.begin(), + E = Personalities.end(); I != E; ++I) + if (*I) GVStubs.insert("_" + (*I)->getName()); + } + // Output stubs for external and common global variables. - if (GVStubs.begin() != GVStubs.end()) + if (!GVStubs.empty()) SwitchToDataSection( - ".section __IMPORT,__pointers,non_lazy_symbol_pointers"); + "\t.section __IMPORT,__pointers,non_lazy_symbol_pointers"); for (std::set::iterator i = GVStubs.begin(), e = GVStubs.end(); i != e; ++i) { O << "L" << *i << "$non_lazy_ptr:\n"; @@ -339,8 +404,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { DW.EndModule(); } - AsmPrinter::doFinalization(M); - return false; // success + return AsmPrinter::doFinalization(M); } /// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code