diff options
Diffstat (limited to 'lib/Target/X86/AsmPrinter')
-rw-r--r-- | lib/Target/X86/AsmPrinter/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp | 491 | ||||
-rw-r--r-- | lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h | 23 | ||||
-rw-r--r-- | lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp | 6 | ||||
-rw-r--r-- | lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp | 7 |
5 files changed, 212 insertions, 316 deletions
diff --git a/lib/Target/X86/AsmPrinter/CMakeLists.txt b/lib/Target/X86/AsmPrinter/CMakeLists.txt index 2079a9f..a28c826 100644 --- a/lib/Target/X86/AsmPrinter/CMakeLists.txt +++ b/lib/Target/X86/AsmPrinter/CMakeLists.txt @@ -6,3 +6,4 @@ add_llvm_library(LLVMX86AsmPrinter X86AsmPrinter.cpp X86IntelAsmPrinter.cpp ) +add_dependencies(LLVMX86AsmPrinter X86CodeGenTable_gen)
\ No newline at end of file diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp index 60ed4f0..e75cfc5 100644 --- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp @@ -23,10 +23,13 @@ #include "llvm/CallingConv.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" +#include "llvm/MDNode.h" #include "llvm/Type.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCStreamer.h" #include "llvm/CodeGen/DwarfWriter.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/Support/CommandLine.h" @@ -41,18 +44,26 @@ STATISTIC(EmittedInsts, "Number of machine instrs printed"); static cl::opt<bool> NewAsmPrinter("experimental-asm-printer", cl::Hidden); -static std::string getPICLabelString(unsigned FnNum, - const TargetAsmInfo *TAI, - const X86Subtarget* Subtarget) { - std::string label; +//===----------------------------------------------------------------------===// +// Primitive Helper Functions. +//===----------------------------------------------------------------------===// + +void X86ATTAsmPrinter::PrintPICBaseSymbol() const { if (Subtarget->isTargetDarwin()) - label = "\"L" + utostr_32(FnNum) + "$pb\""; + O << "\"L" << getFunctionNumber() << "$pb\""; else if (Subtarget->isTargetELF()) - label = ".Lllvm$" + utostr_32(FnNum) + "." "$piclabel"; + O << ".Lllvm$" << getFunctionNumber() << "." "$piclabel"; else assert(0 && "Don't know how to print PIC label!\n"); +} - return label; +/// PrintUnmangledNameSafely - Print out the printable characters in the name. +/// Don't print things like \\n or \\0. +static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) { + for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen(); + Name != E; ++Name) + if (isprint(*Name)) + OS << *Name; } static X86MachineFunctionInfo calculateFunctionInfo(const Function *F, @@ -89,15 +100,6 @@ static X86MachineFunctionInfo calculateFunctionInfo(const Function *F, return Info; } -/// PrintUnmangledNameSafely - Print out the printable characters in the name. -/// Don't print things like \\n or \\0. -static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) { - for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen(); - Name != E; ++Name) - if (isprint(*Name)) - OS << *Name; -} - /// decorateName - Query FunctionInfoMap and use this information for various /// name decoration. void X86ATTAsmPrinter::decorateName(std::string &Name, @@ -152,6 +154,8 @@ void X86ATTAsmPrinter::decorateName(std::string &Name, } } + + void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) { const Function *F = MF.getFunction(); @@ -159,9 +163,12 @@ void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) { SwitchToSection(TAI->SectionForGlobal(F)); + // FIXME: A function's alignment should be part of MachineFunction. There + // shouldn't be a policy decision here. unsigned FnAlign = 4; if (F->hasFnAttr(Attribute::OptimizeForSize)) FnAlign = 1; + switch (F->getLinkage()) { default: assert(0 && "Unknown linkage type!"); case Function::InternalLinkage: // Symbols default to internal. @@ -283,13 +290,8 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { return false; } -static inline bool shouldPrintGOT(TargetMachine &TM, const X86Subtarget* ST) { - return ST->isPICStyleGOT() && TM.getRelocationModel() == Reloc::PIC_; -} - static inline bool shouldPrintPLT(TargetMachine &TM, const X86Subtarget* ST) { - return ST->isTargetELF() && TM.getRelocationModel() == Reloc::PIC_ && - (ST->isPICStyleRIPRel() || ST->isPICStyleGOT()); + return ST->isTargetELF() && TM.getRelocationModel() == Reloc::PIC_; } static inline bool shouldPrintStub(TargetMachine &TM, const X86Subtarget* ST) { @@ -324,6 +326,8 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) { } if (shouldPrintStub(TM, Subtarget)) { + // DARWIN/X86-32 in != static mode. + // Link-once, declaration, or Weakly-linked global variables need // non-lazily-resolved stubs if (GV->isDeclaration() || GV->isWeakForLinker()) { @@ -354,9 +358,8 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) { O << Name; } } else { - if (GV->hasDLLImportLinkage()) { + if (GV->hasDLLImportLinkage()) O << "__imp_"; - } O << Name; if (shouldPrintPLT(TM, Subtarget)) { @@ -370,9 +373,6 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) { FnStubs.insert(Name); } - if (GV->hasExternalWeakLinkage()) - ExtWeakSymbols.insert(GV); - printOffset(MO.getOffset()); if (needCloseParen) @@ -386,7 +386,9 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) { Name += MO.getSymbolName(); // Print function stub suffix unless it's Mac OS X 10.5 and up. if (shouldPrintStub(TM, Subtarget) && + // DARWIN/X86-32 in != static mode. !(Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9)) { + FnStubs.insert(Name); printSuffixedName(Name, "$stub"); return; @@ -401,23 +403,15 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) { O << Name; - if (shouldPrintPLT(TM, Subtarget)) { - std::string GOTName(TAI->getGlobalPrefix()); - GOTName+="_GLOBAL_OFFSET_TABLE_"; - if (Name == GOTName) - // HACK! Emit extra offset to PC during printing GOT offset to - // compensate for the size of popl instruction. The resulting code - // should look like: - // call .piclabel - // piclabel: - // popl %some_register - // addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], %some_register - O << " + [.-" - << getPICLabelString(getFunctionNumber(), TAI, Subtarget) << ']'; - - O << "@PLT"; + if (MO.getTargetFlags() == X86II::MO_GOT_ABSOLUTE_ADDRESS) { + O << " + [.-"; + PrintPICBaseSymbol(); + O << ']'; } + if (shouldPrintPLT(TM, Subtarget)) + O << "@PLT"; + if (needCloseParen) O << ')'; @@ -427,9 +421,10 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) { } void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, - const char *Modifier, bool NotRIPRel) { + const char *Modifier) { const MachineOperand &MO = MI->getOperand(OpNo); switch (MO.getType()) { + default: assert(0 && "unknown operand type!"); case MachineOperand::MO_Register: { assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && "Virtual registers should not make it this far!"); @@ -456,18 +451,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, if (!isMemOp) O << '$'; O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << MO.getIndex(); - - if (TM.getRelocationModel() == Reloc::PIC_) { - if (Subtarget->isPICStyleStub()) - O << "-\"" << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << "$pb\""; - else if (Subtarget->isPICStyleGOT()) - O << "@GOTOFF"; - } - - if (isMemOp && Subtarget->isPICStyleRIPRel() && !NotRIPRel) - O << "(%rip)"; - return; + break; } case MachineOperand::MO_ConstantPoolIndex: { bool isMemOp = Modifier && !strcmp(Modifier, "mem"); @@ -475,38 +459,17 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' << MO.getIndex(); - if (TM.getRelocationModel() == Reloc::PIC_) { - if (Subtarget->isPICStyleStub()) - O << "-\"" << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << "$pb\""; - else if (Subtarget->isPICStyleGOT()) - O << "@GOTOFF"; - } - printOffset(MO.getOffset()); - - if (isMemOp && Subtarget->isPICStyleRIPRel() && !NotRIPRel) - O << "(%rip)"; - return; + break; } case MachineOperand::MO_GlobalAddress: { bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - bool needCloseParen = false; const GlobalValue *GV = MO.getGlobal(); - const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV); - if (!GVar) { - // If GV is an alias then use the aliasee for determining - // thread-localness. - if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) - GVar =dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal(false)); - } - - bool isThreadLocal = GVar && GVar->isThreadLocal(); - std::string Name = Mang->getValueName(GV); decorateName(Name, GV); + bool needCloseParen = false; if (!isMemOp) O << '$'; else if (Name[0] == '$') { @@ -517,6 +480,8 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, } if (shouldPrintStub(TM, Subtarget)) { + // DARWIN/X86-32 in != static mode. + // Link-once, declaration, or Weakly-linked global variables need // non-lazily-resolved stubs if (GV->isDeclaration() || GV->isWeakForLinker()) { @@ -539,118 +504,59 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, O << Name; } - if (TM.getRelocationModel() == Reloc::PIC_) - O << '-' << getPICLabelString(getFunctionNumber(), TAI, Subtarget); + if (TM.getRelocationModel() == Reloc::PIC_) { + O << '-'; + PrintPICBaseSymbol(); + } } else { if (GV->hasDLLImportLinkage()) O << "__imp_"; O << Name; } - if (GV->hasExternalWeakLinkage()) - ExtWeakSymbols.insert(GV); - printOffset(MO.getOffset()); if (needCloseParen) O << ')'; - bool isRIPRelative = false; - if (isThreadLocal) { - TLSModel::Model model = getTLSModel(GVar, TM.getRelocationModel()); - switch (model) { - case TLSModel::GeneralDynamic: - O << "@TLSGD"; - break; - case TLSModel::LocalDynamic: - // O << "@TLSLD"; // local dynamic not implemented - O << "@TLSGD"; - break; - case TLSModel::InitialExec: - if (Subtarget->is64Bit()) { - assert (!NotRIPRel); - O << "@GOTTPOFF"; - isRIPRelative = true; - } else { - O << "@INDNTPOFF"; - } - break; - case TLSModel::LocalExec: - if (Subtarget->is64Bit()) - O << "@TPOFF"; - else - O << "@NTPOFF"; - break; - default: - assert (0 && "Unknown TLS model"); - } - } else if (isMemOp) { - if (shouldPrintGOT(TM, Subtarget)) { - if (Subtarget->GVRequiresExtraLoad(GV, TM, false)) - O << "@GOT"; - else - O << "@GOTOFF"; - } else if (Subtarget->isPICStyleRIPRel() && - !NotRIPRel) { - if (TM.getRelocationModel() != Reloc::Static) { - if (Subtarget->GVRequiresExtraLoad(GV, TM, false)) - O << "@GOTPCREL"; - } - - isRIPRelative = true; - } - } - - // Use rip when possible to reduce code size, except when - // index or base register are also part of the address. e.g. - // foo(%rip)(%rcx,%rax,4) is not legal. - if (isRIPRelative) - O << "(%rip)"; - - return; + break; } - case MachineOperand::MO_ExternalSymbol: { - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - bool needCloseParen = false; - std::string Name(TAI->getGlobalPrefix()); - Name += MO.getSymbolName(); - - // Print function stub suffix unless it's Mac OS X 10.5 and up. - if (!isMemOp) - O << '$'; - else if (Name[0] == '$') { - // The name begins with a dollar-sign. In order to avoid having it look - // like an integer immediate to the assembler, enclose it in parens. - O << '('; - needCloseParen = true; - } - - O << Name; - - if (shouldPrintPLT(TM, Subtarget)) { - std::string GOTName(TAI->getGlobalPrefix()); - GOTName+="_GLOBAL_OFFSET_TABLE_"; - if (Name == GOTName) - // HACK! Emit extra offset to PC during printing GOT offset to - // compensate for the size of popl instruction. The resulting code - // should look like: - // call .piclabel - // piclabel: - // popl %some_register - // addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], %some_register - O << " + [.-" - << getPICLabelString(getFunctionNumber(), TAI, Subtarget) << ']'; - } - - if (needCloseParen) - O << ')'; - - if (Subtarget->isPICStyleRIPRel()) - O << "(%rip)"; - return; + case MachineOperand::MO_ExternalSymbol: + /// NOTE: MO_ExternalSymbol in a non-pcrel_imm context is *only* generated + /// by _GLOBAL_OFFSET_TABLE_ on X86-32. All others are call operands, which + /// are pcrel_imm's. + assert(!Subtarget->is64Bit() && !Subtarget->isPICStyleRIPRel()); + // These are never used as memory operands. + assert(!(Modifier && !strcmp(Modifier, "mem"))); + + O << '$'; + O << TAI->getGlobalPrefix(); + O << MO.getSymbolName(); + break; } + + switch (MO.getTargetFlags()) { default: - O << "<unknown operand type>"; return; + assert(0 && "Unknown target flag on GV operand"); + case X86II::MO_NO_FLAG: + break; + case X86II::MO_GOT_ABSOLUTE_ADDRESS: + O << " + [.-"; + PrintPICBaseSymbol(); + O << ']'; + break; + case X86II::MO_PIC_BASE_OFFSET: + O << '-'; + PrintPICBaseSymbol(); + break; + case X86II::MO_TLSGD: O << "@TLSGD"; break; + case X86II::MO_GOTTPOFF: O << "@GOTTPOFF"; break; + case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break; + case X86II::MO_TPOFF: O << "@TPOFF"; break; + case X86II::MO_NTPOFF: O << "@NTPOFF"; break; + case X86II::MO_GOTPCREL: O << "@GOTPCREL"; break; + case X86II::MO_GOT: O << "@GOT"; break; + case X86II::MO_GOTOFF: O << "@GOTOFF"; break; } } @@ -670,25 +576,24 @@ void X86ATTAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) { } void X86ATTAsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier, - bool NotRIPRel) { + const char *Modifier) { MachineOperand BaseReg = MI->getOperand(Op); MachineOperand IndexReg = MI->getOperand(Op+2); const MachineOperand &DispSpec = MI->getOperand(Op+3); - NotRIPRel |= IndexReg.getReg() || BaseReg.getReg(); if (DispSpec.isGlobal() || DispSpec.isCPI() || DispSpec.isJTI() || DispSpec.isSymbol()) { - printOperand(MI, Op+3, "mem", NotRIPRel); + printOperand(MI, Op+3, "mem"); } else { int DispVal = DispSpec.getImm(); if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) O << DispVal; } - if (IndexReg.getReg() || BaseReg.getReg()) { + if ((IndexReg.getReg() || BaseReg.getReg()) && + (Modifier == 0 || strcmp(Modifier, "no-rip"))) { unsigned ScaleVal = MI->getOperand(Op+1).getImm(); unsigned BaseRegOperand = 0, IndexRegOperand = 2; @@ -716,14 +621,14 @@ void X86ATTAsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op, } void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier, bool NotRIPRel){ + const char *Modifier) { assert(isMem(MI, Op) && "Invalid memory reference!"); MachineOperand Segment = MI->getOperand(Op+4); if (Segment.getReg()) { printOperand(MI, Op+4, Modifier); O << ':'; } - printLeaMemReference(MI, Op, Modifier, NotRIPRel); + printLeaMemReference(MI, Op, Modifier); } void X86ATTAsmPrinter::printPICJumpTableSetLabel(unsigned uid, @@ -741,13 +646,19 @@ void X86ATTAsmPrinter::printPICJumpTableSetLabel(unsigned uid, if (Subtarget->isPICStyleRIPRel()) O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << uid << '\n'; - else - O << '-' << getPICLabelString(getFunctionNumber(), TAI, Subtarget) << '\n'; + else { + O << '-'; + PrintPICBaseSymbol(); + O << '\n'; + } } + void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { - std::string label = getPICLabelString(getFunctionNumber(), TAI, Subtarget); - O << label << '\n' << label << ':'; + PrintPICBaseSymbol(); + O << '\n'; + PrintPICBaseSymbol(); + O << ':'; } @@ -810,7 +721,7 @@ bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, switch (ExtraCode[0]) { default: return true; // Unknown modifier. case 'c': // Don't print "$" before a global var name or constant. - printOperand(MI, OpNo, "mem", /*NotRIPRel=*/true); + printOperand(MI, OpNo, "mem"); return false; case 'b': // Print QImode register case 'h': // Print QImode high register @@ -823,8 +734,19 @@ bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, return false; case 'P': // Don't print @PLT, but do print as memory. - printOperand(MI, OpNo, "mem", /*NotRIPRel=*/true); + printOperand(MI, OpNo, "mem"); return false; + + case 'n': { // Negate the immediate or print a '-' before the operand. + // Note: this is a temporary solution. It should be handled target + // independently as part of the 'MC' work. + const MachineOperand &MO = MI->getOperand(OpNo); + if (MO.isImm()) { + O << -MO.getImm(); + return false; + } + O << '-'; + } } } @@ -849,7 +771,7 @@ bool X86ATTAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, // These only apply to registers, ignore on mem. break; case 'P': // Don't print @PLT, but do print as memory. - printMemReference(MI, OpNo, "mem", /*NotRIPRel=*/true); + printMemReference(MI, OpNo, "no-rip"); return false; } } @@ -931,8 +853,13 @@ void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) { /// doInitialization bool X86ATTAsmPrinter::doInitialization(Module &M) { - if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling()) - MMI = getAnalysisIfAvailable<MachineModuleInfo>(); + if (NewAsmPrinter) { + Context = new MCContext(); + // FIXME: Send this to "O" instead of outs(). For now, we force it to + // stdout to make it easy to compare. + Streamer = createAsmStreamer(*Context, outs()); + } + return AsmPrinter::doInitialization(M); } @@ -956,6 +883,8 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { std::string name = Mang->getValueName(GVar); Constant *C = GVar->getInitializer(); + if (isa<MDNode>(C) || isa<MDString>(C)) + return; const Type *Type = C->getType(); unsigned Size = TD->getTypeAllocSize(Type); unsigned Align = TD->getPreferredAlignmentLog(GVar); @@ -1068,25 +997,6 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { EmitGlobalConstant(C); } -/// printGVStub - Print stub for a global value. -/// -void X86ATTAsmPrinter::printGVStub(const char *GV, const char *Prefix) { - printSuffixedName(GV, "$non_lazy_ptr", Prefix); - O << ":\n\t.indirect_symbol "; - if (Prefix) O << Prefix; - O << GV << "\n\t.long\t0\n"; -} - -/// printHiddenGVStub - Print stub for a hidden global value. -/// -void X86ATTAsmPrinter::printHiddenGVStub(const char *GV, const char *Prefix) { - EmitAlignment(2); - printSuffixedName(GV, "$non_lazy_ptr", Prefix); - if (Prefix) O << Prefix; - O << ":\n" << TAI->getData32bitsDirective() << GV << '\n'; -} - - bool X86ATTAsmPrinter::doFinalization(Module &M) { // Print out module-level global variables here. for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); @@ -1095,100 +1005,62 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) { if (I->hasDLLExportLinkage()) DLLExportedGVs.insert(Mang->makeNameProper(I->getName(),"")); - - // If the global is a extern weak symbol, remember to emit the weak - // reference! - // FIXME: This is rather hacky, since we'll emit references to ALL weak - // stuff, not used. But currently it's the only way to deal with extern weak - // initializers hidden deep inside constant expressions. - if (I->hasExternalWeakLinkage()) - ExtWeakSymbols.insert(I); - } - - for (Module::const_iterator I = M.begin(), E = M.end(); - I != E; ++I) { - // If the global is a extern weak symbol, remember to emit the weak - // reference! - // FIXME: This is rather hacky, since we'll emit references to ALL weak - // stuff, not used. But currently it's the only way to deal with extern weak - // initializers hidden deep inside constant expressions. - if (I->hasExternalWeakLinkage()) - ExtWeakSymbols.insert(I); } - // Output linker support code for dllexported globals - if (!DLLExportedGVs.empty()) - SwitchToDataSection(".section .drectve"); - - for (StringSet<>::iterator i = DLLExportedGVs.begin(), - e = DLLExportedGVs.end(); - i != e; ++i) - O << "\t.ascii \" -export:" << i->getKeyData() << ",data\"\n"; - - if (!DLLExportedFns.empty()) { - SwitchToDataSection(".section .drectve"); - } - - for (StringSet<>::iterator i = DLLExportedFns.begin(), - e = DLLExportedFns.end(); - i != e; ++i) - O << "\t.ascii \" -export:" << i->getKeyData() << "\"\n"; - if (Subtarget->isTargetDarwin()) { SwitchToDataSection(""); - - // Output stubs for dynamically-linked functions - for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end(); - i != e; ++i) { - SwitchToDataSection("\t.section __IMPORT,__jump_table,symbol_stubs," - "self_modifying_code+pure_instructions,5", 0); - const char *p = i->getKeyData(); - printSuffixedName(p, "$stub"); - O << ":\n" - "\t.indirect_symbol " << p << "\n" - "\thlt ; hlt ; hlt ; hlt ; hlt\n"; - } - - O << '\n'; - - // Print global value stubs. - bool InStubSection = false; + + // Add the (possibly multiple) personalities to the set of global value + // stubs. Only referenced functions get into the Personalities list. if (TAI->doesSupportExceptionHandling() && MMI && !Subtarget->is64Bit()) { - // Add the (possibly multiple) personalities to the set of global values. - // Only referenced functions get into the Personalities list. - const std::vector<Function *>& Personalities = MMI->getPersonalities(); - for (std::vector<Function *>::const_iterator I = Personalities.begin(), - E = Personalities.end(); I != E; ++I) { - if (!*I) + const std::vector<Function*> &Personalities = MMI->getPersonalities(); + for (unsigned i = 0, e = Personalities.size(); i != e; ++i) { + if (Personalities[i] == 0) continue; - if (!InStubSection) { - SwitchToDataSection( - "\t.section __IMPORT,__pointers,non_lazy_symbol_pointers"); - InStubSection = true; - } - printGVStub((*I)->getNameStart(), "_"); + std::string Name = Mang->getValueName(Personalities[i]); + decorateName(Name, Personalities[i]); + GVStubs.insert(Name); } } + // Output stubs for dynamically-linked functions + if (!FnStubs.empty()) { + for (StringSet<>::iterator I = FnStubs.begin(), E = FnStubs.end(); + I != E; ++I) { + SwitchToDataSection("\t.section __IMPORT,__jump_table,symbol_stubs," + "self_modifying_code+pure_instructions,5", 0); + const char *Name = I->getKeyData(); + printSuffixedName(Name, "$stub"); + O << ":\n" + "\t.indirect_symbol " << Name << "\n" + "\thlt ; hlt ; hlt ; hlt ; hlt\n"; + } + O << '\n'; + } + // Output stubs for external and common global variables. - if (!InStubSection && !GVStubs.empty()) + if (!GVStubs.empty()) { SwitchToDataSection( "\t.section __IMPORT,__pointers,non_lazy_symbol_pointers"); - for (StringSet<>::iterator i = GVStubs.begin(), e = GVStubs.end(); - i != e; ++i) - printGVStub(i->getKeyData()); + for (StringSet<>::iterator I = GVStubs.begin(), E = GVStubs.end(); + I != E; ++I) { + const char *Name = I->getKeyData(); + printSuffixedName(Name, "$non_lazy_ptr"); + O << ":\n\t.indirect_symbol " << Name << "\n\t.long\t0\n"; + } + } if (!HiddenGVStubs.empty()) { SwitchToSection(TAI->getDataSection()); - for (StringSet<>::iterator i = HiddenGVStubs.begin(), e = HiddenGVStubs.end(); - i != e; ++i) - printHiddenGVStub(i->getKeyData()); + EmitAlignment(2); + for (StringSet<>::iterator I = HiddenGVStubs.begin(), + E = HiddenGVStubs.end(); I != E; ++I) { + const char *Name = I->getKeyData(); + printSuffixedName(Name, "$non_lazy_ptr"); + O << ":\n" << TAI->getData32bitsDirective() << Name << '\n'; + } } - // Emit final debug information. - if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling()) - DW->EndModule(); - // Funny Darwin hack: This flag tells the linker that no global symbols // contain code that falls through to other global symbols (e.g. the obvious // implementation of multiple entry points). If this doesn't occur, the @@ -1204,17 +1076,40 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) { << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT) << ";\t.endef\n"; } - - // Emit final debug information. - if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling()) - DW->EndModule(); - } else if (Subtarget->isTargetELF()) { - // Emit final debug information. - if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling()) - DW->EndModule(); } - - return AsmPrinter::doFinalization(M); + + + // Output linker support code for dllexported globals on windows. + if (!DLLExportedGVs.empty()) { + SwitchToDataSection(".section .drectve"); + + for (StringSet<>::iterator i = DLLExportedGVs.begin(), + e = DLLExportedGVs.end(); i != e; ++i) + O << "\t.ascii \" -export:" << i->getKeyData() << ",data\"\n"; + } + + if (!DLLExportedFns.empty()) { + SwitchToDataSection(".section .drectve"); + + for (StringSet<>::iterator i = DLLExportedFns.begin(), + e = DLLExportedFns.end(); + i != e; ++i) + O << "\t.ascii \" -export:" << i->getKeyData() << "\"\n"; + } + + // Do common shutdown. + bool Changed = AsmPrinter::doFinalization(M); + + if (NewAsmPrinter) { + Streamer->Finish(); + + delete Streamer; + delete Context; + Streamer = 0; + Context = 0; + } + + return Changed; } // Include the auto-generated portion of the assembly writer. diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h index 68a6bc8..bd96115 100644 --- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h +++ b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h @@ -27,17 +27,23 @@ namespace llvm { class MachineJumpTableInfo; +class MCContext; class MCInst; +class MCStreamer; class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter { - MachineModuleInfo *MMI; const X86Subtarget *Subtarget; + + MCContext *Context; + MCStreamer *Streamer; public: explicit X86ATTAsmPrinter(raw_ostream &O, X86TargetMachine &TM, const TargetAsmInfo *T, CodeGenOpt::Level OL, bool V) - : AsmPrinter(O, TM, T, OL, V), MMI(0) { + : AsmPrinter(O, TM, T, OL, V) { Subtarget = &TM.getSubtarget<X86Subtarget>(); + Context = 0; + Streamer = 0; } virtual const char *getPassName() const { @@ -69,7 +75,7 @@ class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter { bool printInstruction(const MCInst *MI); void printOperand(const MCInst *MI, unsigned OpNo, - const char *Modifier = 0, bool NotRIPRel = false); + const char *Modifier = 0); void printMemReference(const MCInst *MI, unsigned Op); void printLeaMemReference(const MCInst *MI, unsigned Op); void printSSECC(const MCInst *MI, unsigned Op); @@ -117,7 +123,7 @@ class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter { // These methods are used by the tablegen'erated instruction printer. void printOperand(const MachineInstr *MI, unsigned OpNo, - const char *Modifier = 0, bool NotRIPRel = false); + const char *Modifier = 0); void print_pcrel_imm(const MachineInstr *MI, unsigned OpNo); void printi8mem(const MachineInstr *MI, unsigned OpNo) { printMemReference(MI, OpNo); @@ -165,9 +171,9 @@ class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter { void printMachineInstruction(const MachineInstr *MI); void printSSECC(const MachineInstr *MI, unsigned Op); void printMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier=NULL, bool NotRIPRel = false); + const char *Modifier=NULL); void printLeaMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier=NULL, bool NotRIPRel = false); + const char *Modifier=NULL); void printPICJumpTableSetLabel(unsigned uid, const MachineBasicBlock *MBB) const; void printPICJumpTableSetLabel(unsigned uid, unsigned uid2, @@ -181,9 +187,8 @@ class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter { void printPICLabel(const MachineInstr *MI, unsigned Op); void printModuleLevelGV(const GlobalVariable* GVar); - void printGVStub(const char *GV, const char *Prefix = NULL); - void printHiddenGVStub(const char *GV, const char *Prefix = NULL); - + void PrintPICBaseSymbol() const; + bool runOnMachineFunction(MachineFunction &F); void emitFunctionHeader(const MachineFunction &MF); diff --git a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp index 9d50edc..fa0ee75 100644 --- a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp @@ -65,7 +65,7 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo) { void X86ATTAsmPrinter::printOperand(const MCInst *MI, unsigned OpNo, - const char *Modifier, bool NotRIPRel) { + const char *Modifier) { assert(Modifier == 0 && "Modifiers should not be used"); const MCOperand &Op = MI->getOperand(OpNo); @@ -93,13 +93,11 @@ void X86ATTAsmPrinter::printOperand(const MCInst *MI, unsigned OpNo, } void X86ATTAsmPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) { - bool NotRIPRel = false; const MCOperand &BaseReg = MI->getOperand(Op); const MCOperand &IndexReg = MI->getOperand(Op+2); const MCOperand &DispSpec = MI->getOperand(Op+3); - NotRIPRel |= IndexReg.getReg() || BaseReg.getReg(); if (DispSpec.isImm()) { int64_t DispVal = DispSpec.getImm(); if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) @@ -108,7 +106,7 @@ void X86ATTAsmPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) { abort(); //assert(DispSpec.isGlobal() || DispSpec.isCPI() || // DispSpec.isJTI() || DispSpec.isSymbol()); - //printOperand(MI, Op+3, "mem", NotRIPRel); + //printOperand(MI, Op+3, "mem"); } if (IndexReg.getReg() || BaseReg.getReg()) { diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp index a39203b..d1623d6 100644 --- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp @@ -47,8 +47,5 @@ namespace { extern "C" int X86AsmPrinterForceLink; int X86AsmPrinterForceLink = 0; -// Force static initialization when called from -// llvm/InitializeAllAsmPrinters.h -namespace llvm { - void InitializeX86AsmPrinter() { } -} +// Force static initialization. +extern "C" void LLVMInitializeX86AsmPrinter() { } |