X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FAsmPrinter.cpp;h=6b773c2e0208f91f8702962d60eadbdafdd51602;hb=fffb7266fe9c5c95d859ff5b3aeb5386cbd0cd1e;hp=f6d77309e1af51d644f0e278adf449984da5d843;hpb=968ff1196768c0b6dbcc5508025a2923bfa73fab;p=oota-llvm.git diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index f6d77309e1a..6b773c2e020 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -18,7 +18,9 @@ #include "llvm/Module.h" #include "llvm/CodeGen/GCMetadataPrinter.h" #include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/DwarfWriter.h" #include "llvm/Analysis/DebugInfo.h" @@ -30,7 +32,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/Mangler.h" -#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetLoweringObjectFile.h" @@ -48,14 +50,14 @@ AsmVerbose("asm-verbose", cl::desc("Add comments to directives."), char AsmPrinter::ID = 0; AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm, - const TargetAsmInfo *T, bool VDef) + const MCAsmInfo *T, bool VDef) : MachineFunctionPass(&ID), FunctionNumber(0), O(o), - TM(tm), TAI(T), TRI(tm.getRegisterInfo()), + TM(tm), MAI(T), TRI(tm.getRegisterInfo()), OutContext(*new MCContext()), - OutStreamer(*createAsmStreamer(OutContext, O)), + OutStreamer(*createAsmStreamer(OutContext, O, *T, this)), - IsInTextSection(false), LastMI(0), LastFn(0), Counter(~0U), + LastMI(0), LastFn(0), Counter(~0U), PrevDLT(0, ~0U, ~0U) { DW = 0; MMI = 0; switch (AsmVerbose) { @@ -74,104 +76,22 @@ AsmPrinter::~AsmPrinter() { delete &OutContext; } -const TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const { +TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const { return TM.getTargetLowering()->getObjFileLowering(); } - -/// SwitchToTextSection - Switch to the specified text section of the executable -/// if we are not already in it! -/// -void AsmPrinter::SwitchToTextSection(const char *NewSection, - const GlobalValue *GV) { - std::string NS; - if (GV && GV->hasSection()) - NS = TAI->getSwitchToSectionDirective() + GV->getSection(); - else - NS = NewSection; - - // If we're already in this section, we're done. - if (CurrentSection == NS) return; - - // Close the current section, if applicable. - if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty()) - O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << '\n'; - - CurrentSection = NS; - - if (!CurrentSection.empty()) - O << CurrentSection << TAI->getTextSectionStartSuffix() << '\n'; - - IsInTextSection = true; +/// getCurrentSection() - Return the current section we are emitting to. +const MCSection *AsmPrinter::getCurrentSection() const { + return OutStreamer.getCurrentSection(); } -/// SwitchToDataSection - Switch to the specified data section of the executable -/// if we are not already in it! -/// -void AsmPrinter::SwitchToDataSection(const char *NewSection, - const GlobalValue *GV) { - std::string NS; - if (GV && GV->hasSection()) - NS = TAI->getSwitchToSectionDirective() + GV->getSection(); - else - NS = NewSection; - - // If we're already in this section, we're done. - if (CurrentSection == NS) return; - - // Close the current section, if applicable. - if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty()) - O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << '\n'; - - CurrentSection = NS; - - if (!CurrentSection.empty()) - O << CurrentSection << TAI->getDataSectionStartSuffix() << '\n'; - - IsInTextSection = false; -} - -/// SwitchToSection - Switch to the specified section of the executable if we -/// are not already in it! -void AsmPrinter::SwitchToSection(const MCSection *NS) { - const std::string &NewSection = NS->getName(); - - // If we're already in this section, we're done. - if (CurrentSection == NewSection) return; - - // Close the current section, if applicable. - if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty()) - O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << '\n'; - - // FIXME: Make CurrentSection a Section* in the future - CurrentSection = NewSection; - CurrentSection_ = NS; - - if (!CurrentSection.empty()) { - // If section is named we need to switch into it via special '.section' - // directive and also append funky flags. Otherwise - section name is just - // some magic assembler directive. - if (!NS->isDirective()) { - SmallString<32> FlagsStr; - - getObjFileLowering().getSectionFlagsAsString(NS->getKind(), FlagsStr); - - O << TAI->getSwitchToSectionDirective() - << CurrentSection - << FlagsStr.c_str(); - } else { - O << CurrentSection; - } - O << TAI->getDataSectionStartSuffix() << '\n'; - } - - IsInTextSection = NS->getKind().isText(); -} void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); MachineFunctionPass::getAnalysisUsage(AU); AU.addRequired(); + if (VerboseAsm) + AU.addRequired(); } bool AsmPrinter::doInitialization(Module &M) { @@ -179,16 +99,16 @@ bool AsmPrinter::doInitialization(Module &M) { const_cast(getObjFileLowering()) .Initialize(OutContext, TM); - Mang = new Mangler(M, TAI->getGlobalPrefix(), TAI->getPrivateGlobalPrefix(), - TAI->getLinkerPrivateGlobalPrefix()); + Mang = new Mangler(M, MAI->getGlobalPrefix(), MAI->getPrivateGlobalPrefix(), + MAI->getLinkerPrivateGlobalPrefix()); - if (TAI->doesAllowQuotesInName()) + if (MAI->doesAllowQuotesInName()) Mang->setUseQuotes(true); GCModuleInfo *MI = getAnalysisIfAvailable(); assert(MI && "AsmPrinter didn't require GCModuleInfo?"); - if (TAI->hasSingleParameterDotFile()) { + if (MAI->hasSingleParameterDotFile()) { /* Very minimal debug info. It is ignored if we emit actual debug info. If we don't, this at helps the user find where a function came from. */ @@ -197,24 +117,22 @@ bool AsmPrinter::doInitialization(Module &M) { for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I) if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I)) - MP->beginAssembly(O, *this, *TAI); + MP->beginAssembly(O, *this, *MAI); if (!M.getModuleInlineAsm().empty()) - O << TAI->getCommentString() << " Start of file scope inline assembly\n" + O << MAI->getCommentString() << " Start of file scope inline assembly\n" << M.getModuleInlineAsm() - << '\n' << TAI->getCommentString() + << '\n' << MAI->getCommentString() << " End of file scope inline assembly\n"; - SwitchToDataSection(""); // Reset back to no section. - - if (TAI->doesSupportDebugInformation() || - TAI->doesSupportExceptionHandling()) { + if (MAI->doesSupportDebugInformation() || + MAI->doesSupportExceptionHandling()) { MMI = getAnalysisIfAvailable(); if (MMI) MMI->AnalyzeModule(M); DW = getAnalysisIfAvailable(); if (DW) - DW->BeginModule(&M, MMI, O, this, TAI); + DW->BeginModule(&M, MMI, O, this, MAI); } return false; @@ -227,32 +145,30 @@ bool AsmPrinter::doFinalization(Module &M) { PrintGlobalVariable(I); // Emit final debug information. - if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling()) + if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling()) DW->EndModule(); // If the target wants to know about weak references, print them all. - if (TAI->getWeakRefDirective()) { + if (MAI->getWeakRefDirective()) { // FIXME: This is not lazy, it would be nice to only print weak references // to stuff that is actually used. Note that doing so would require targets // to notice uses in operands (due to constant exprs etc). This should // happen with the MC stuff eventually. - SwitchToDataSection(""); // Print out module-level global variables here. for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { if (I->hasExternalWeakLinkage()) - O << TAI->getWeakRefDirective() << Mang->getMangledName(I) << '\n'; + O << MAI->getWeakRefDirective() << Mang->getMangledName(I) << '\n'; } - for (Module::const_iterator I = M.begin(), E = M.end(); - I != E; ++I) { + for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) { if (I->hasExternalWeakLinkage()) - O << TAI->getWeakRefDirective() << Mang->getMangledName(I) << '\n'; + O << MAI->getWeakRefDirective() << Mang->getMangledName(I) << '\n'; } } - if (TAI->getSetDirective()) { + if (MAI->getSetDirective()) { O << '\n'; for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) { @@ -261,16 +177,16 @@ bool AsmPrinter::doFinalization(Module &M) { const GlobalValue *GV = cast(I->getAliasedGlobal()); std::string Target = Mang->getMangledName(GV); - if (I->hasExternalLinkage() || !TAI->getWeakRefDirective()) + if (I->hasExternalLinkage() || !MAI->getWeakRefDirective()) O << "\t.globl\t" << Name << '\n'; else if (I->hasWeakLinkage()) - O << TAI->getWeakRefDirective() << Name << '\n'; + O << MAI->getWeakRefDirective() << Name << '\n'; else if (!I->hasLocalLinkage()) llvm_unreachable("Invalid alias linkage"); printVisibility(Name, I->getVisibility()); - O << TAI->getSetDirective() << ' ' << Name << ", " << Target << '\n'; + O << MAI->getSetDirective() << ' ' << Name << ", " << Target << '\n'; } } @@ -278,14 +194,14 @@ bool AsmPrinter::doFinalization(Module &M) { assert(MI && "AsmPrinter didn't require GCModuleInfo?"); for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; ) if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I)) - MP->finishAssembly(O, *this, *TAI); + MP->finishAssembly(O, *this, *MAI); // If we don't have any trampolines, then we don't require stack memory // to be executable. Some targets have a directive to declare this. Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline"); if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty()) - if (TAI->getNonexecutableStackDirective()) - O << TAI->getNonexecutableStackDirective() << '\n'; + if (MAI->getNonexecutableStackDirective()) + O << MAI->getNonexecutableStackDirective() << '\n'; delete Mang; Mang = 0; DW = 0; MMI = 0; @@ -298,13 +214,17 @@ std::string AsmPrinter::getCurrentFunctionEHName(const MachineFunction *MF) const { assert(MF && "No machine function?"); return Mang->getMangledName(MF->getFunction(), ".eh", - TAI->is_EHSymbolPrivate()); + MAI->is_EHSymbolPrivate()); } void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { // What's my mangled name? CurrentFnName = Mang->getMangledName(MF.getFunction()); IncrementFunctionNumber(); + + if (VerboseAsm) { + LI = &getAnalysis(); + } } namespace { @@ -336,21 +256,20 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) { SectionKind Kind; switch (CPE.getRelocationInfo()) { default: llvm_unreachable("Unknown section kind"); - case 2: Kind = SectionKind::get(SectionKind::ReadOnlyWithRel); break; + case 2: Kind = SectionKind::getReadOnlyWithRel(); break; case 1: - Kind = SectionKind::get(SectionKind::ReadOnlyWithRelLocal); + Kind = SectionKind::getReadOnlyWithRelLocal(); break; case 0: switch (TM.getTargetData()->getTypeAllocSize(CPE.getType())) { - case 4: Kind = SectionKind::get(SectionKind::MergeableConst4); break; - case 8: Kind = SectionKind::get(SectionKind::MergeableConst8); break; - case 16: Kind = SectionKind::get(SectionKind::MergeableConst16);break; - default: Kind = SectionKind::get(SectionKind::MergeableConst); break; + case 4: Kind = SectionKind::getMergeableConst4(); break; + case 8: Kind = SectionKind::getMergeableConst8(); break; + case 16: Kind = SectionKind::getMergeableConst16();break; + default: Kind = SectionKind::getMergeableConst(); break; } } - const MCSection *S = - getObjFileLowering().getSectionForMergeableConstant(Kind); + const MCSection *S = getObjFileLowering().getSectionForConstant(Kind); // The number of sections are small, just do a linear search from the // last section to the first. @@ -374,7 +293,7 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) { // Now print stuff into the calculated sections. for (unsigned i = 0, e = CPSections.size(); i != e; ++i) { - SwitchToSection(CPSections[i].S); + OutStreamer.SwitchSection(CPSections[i].S); EmitAlignment(Log2_32(CPSections[i].Alignment)); unsigned Offset = 0; @@ -390,11 +309,12 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) { const Type *Ty = CPE.getType(); Offset = NewOffset + TM.getTargetData()->getTypeAllocSize(Ty); - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' - << CPI << ":\t\t\t\t\t"; + O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' + << CPI << ':'; if (VerboseAsm) { - O << TAI->getCommentString() << ' '; - WriteTypeSymbolic(O, CPE.getType(), 0); + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << " constant "; + WriteTypeSymbolic(O, CPE.getType(), MF->getFunction()->getParent()); } O << '\n'; if (CPE.isMachineConstantPoolEntry()) @@ -419,22 +339,21 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI, // the appropriate section. TargetLowering *LoweringInfo = TM.getTargetLowering(); - const char *JumpTableDataSection = TAI->getJumpTableDataSection(); const Function *F = MF.getFunction(); - - const MCSection *FuncSection = - getObjFileLowering().SectionForGlobal(F, Mang, TM); - bool JTInDiffSection = false; - if ((IsPic && !(LoweringInfo && LoweringInfo->usesGlobalOffsetTable())) || - !JumpTableDataSection || F->isWeakForLinker()) { + if (F->isWeakForLinker() || + (IsPic && !LoweringInfo->usesGlobalOffsetTable())) { // In PIC mode, we need to emit the jump table to the same section as the // function body itself, otherwise the label differences won't make sense. // We should also do if the section name is NULL or function is declared in // discardable section. - SwitchToSection(FuncSection); + OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, + TM)); } else { - SwitchToDataSection(JumpTableDataSection); + // Otherwise, drop it in the readonly section. + const MCSection *ReadOnlySection = + getObjFileLowering().getSectionForConstant(SectionKind::getReadOnly()); + OutStreamer.SwitchSection(ReadOnlySection); JTInDiffSection = true; } @@ -450,7 +369,7 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI, // the number of relocations the assembler will generate for the jump table. // Set directives are all printed before the jump table itself. SmallPtrSet EmittedSets; - if (TAI->getSetDirective() && IsPic) + if (MAI->getSetDirective() && IsPic) for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) if (EmittedSets.insert(JTBBs[ii])) printPICJumpTableSetLabel(i, JTBBs[ii]); @@ -460,11 +379,11 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI, // the assembler and linker the extents of the jump table object. The // second label is actually referenced by the code. if (JTInDiffSection) { - if (const char *JTLabelPrefix = TAI->getJumpTableSpecialLabelPrefix()) + if (const char *JTLabelPrefix = MAI->getJumpTableSpecialLabelPrefix()) O << JTLabelPrefix << "JTI" << getFunctionNumber() << '_' << i << ":\n"; } - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() + O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << i << ":\n"; for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { @@ -477,15 +396,15 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI, void AsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB, unsigned uid) const { - bool IsPic = TM.getRelocationModel() == Reloc::PIC_; + bool isPIC = TM.getRelocationModel() == Reloc::PIC_; // Use JumpTableDirective otherwise honor the entry size from the jump table // info. - const char *JTEntryDirective = TAI->getJumpTableDirective(); + const char *JTEntryDirective = MAI->getJumpTableDirective(isPIC); bool HadJTEntryDirective = JTEntryDirective != NULL; if (!HadJTEntryDirective) { JTEntryDirective = MJTI->getEntrySize() == 4 ? - TAI->getData32bitsDirective() : TAI->getData64bitsDirective(); + MAI->getData32bitsDirective() : MAI->getData64bitsDirective(); } O << JTEntryDirective << ' '; @@ -495,20 +414,18 @@ void AsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, // emit the table entries as differences between two text section labels. // If we're emitting non-PIC code, then emit the entries as direct // references to the target basic blocks. - if (IsPic) { - if (TAI->getSetDirective()) { - O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << '_' << uid << "_set_" << MBB->getNumber(); - } else { - printBasicBlockLabel(MBB, false, false, false); - // If the arch uses custom Jump Table directives, don't calc relative to - // JT - if (!HadJTEntryDirective) - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" - << getFunctionNumber() << '_' << uid; - } + if (!isPIC) { + printBasicBlockLabel(MBB, false, false, false); + } else if (MAI->getSetDirective()) { + O << MAI->getPrivateGlobalPrefix() << getFunctionNumber() + << '_' << uid << "_set_" << MBB->getNumber(); } else { printBasicBlockLabel(MBB, false, false, false); + // If the arch uses custom Jump Table directives, don't calc relative to + // JT + if (!HadJTEntryDirective) + O << '-' << MAI->getPrivateGlobalPrefix() << "JTI" + << getFunctionNumber() << '_' << uid; } } @@ -518,7 +435,7 @@ void AsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, /// do nothing and return false. bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { if (GV->getName() == "llvm.used") { - if (TAI->getUsedDirective() != 0) // No need to emit this at all. + if (MAI->getUsedDirective() != 0) // No need to emit this at all. EmitLLVMUsedList(GV->getInitializer()); return true; } @@ -535,14 +452,14 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { const TargetData *TD = TM.getTargetData(); unsigned Align = Log2_32(TD->getPointerPrefAlignment()); if (GV->getName() == "llvm.global_ctors") { - SwitchToDataSection(TAI->getStaticCtorsSection()); + OutStreamer.SwitchSection(getObjFileLowering().getStaticCtorSection()); EmitAlignment(Align, 0); EmitXXStructorList(GV->getInitializer()); return true; } if (GV->getName() == "llvm.global_dtors") { - SwitchToDataSection(TAI->getStaticDtorsSection()); + OutStreamer.SwitchSection(getObjFileLowering().getStaticDtorSection()); EmitAlignment(Align, 0); EmitXXStructorList(GV->getInitializer()); return true; @@ -551,11 +468,11 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { return false; } -/// EmitLLVMUsedList - For targets that define a TAI::UsedDirective, mark each +/// EmitLLVMUsedList - For targets that define a MAI::UsedDirective, mark each /// global in the specified llvm.used list for which emitUsedDirectiveFor /// is true, as being used with this directive. void AsmPrinter::EmitLLVMUsedList(Constant *List) { - const char *Directive = TAI->getUsedDirective(); + const char *Directive = MAI->getUsedDirective(); // Should be an array of 'i8*'. ConstantArray *InitList = dyn_cast(List); @@ -596,13 +513,13 @@ void AsmPrinter::EmitXXStructorList(Constant *List) { const std::string &AsmPrinter::getGlobalLinkName(const GlobalVariable *GV, std::string &LinkName) const { if (isa(GV)) { - LinkName += TAI->getFunctionAddrPrefix(); + LinkName += MAI->getFunctionAddrPrefix(); LinkName += Mang->getMangledName(GV); - LinkName += TAI->getFunctionAddrSuffix(); + LinkName += MAI->getFunctionAddrSuffix(); } else { - LinkName += TAI->getGlobalVarAddrPrefix(); + LinkName += MAI->getGlobalVarAddrPrefix(); LinkName += Mang->getMangledName(GV); - LinkName += TAI->getGlobalVarAddrSuffix(); + LinkName += MAI->getGlobalVarAddrSuffix(); } return LinkName; @@ -669,8 +586,8 @@ void AsmPrinter::EOL() const { void AsmPrinter::EOL(const std::string &Comment) const { if (VerboseAsm && !Comment.empty()) { - O << '\t' - << TAI->getCommentString() + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << ' ' << Comment; } @@ -679,22 +596,202 @@ void AsmPrinter::EOL(const std::string &Comment) const { void AsmPrinter::EOL(const char* Comment) const { if (VerboseAsm && *Comment) { - O << '\t' - << TAI->getCommentString() + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << ' ' << Comment; } O << '\n'; } +static const char *GetDataFormatName(unsigned DataFormat) { +#ifndef HAVE_DESIGNATED_INITIALIZERS +#define HAVE_DESIGNATED_INITIALIZERS \ + ((!defined(__cplusplus) && (GCC_VERSION >= 2007)) \ + || (__STDC_VERSION__ >= 199901L)) +#endif + +#if HAVE_DESIGNATED_INITIALIZERS +#define S(p, v) [p] = v, +#else +#define S(p, v) case p: return v; +#endif + +#if HAVE_DESIGNATED_INITIALIZERS + __extension__ static const char * const FormatNames[256] = { +#else + switch (DataFormat) { +#endif + + S(dwarf::DW_EH_PE_absptr, "absolute") + S(dwarf::DW_EH_PE_omit, "omit") + S(dwarf::DW_EH_PE_aligned, "aligned absolute") + + S(dwarf::DW_EH_PE_uleb128, "uleb128") + S(dwarf::DW_EH_PE_udata2, "udata2") + S(dwarf::DW_EH_PE_udata4, "udata4") + S(dwarf::DW_EH_PE_udata8, "udata8") + S(dwarf::DW_EH_PE_sleb128, "sleb128") + S(dwarf::DW_EH_PE_sdata2, "sdata2") + S(dwarf::DW_EH_PE_sdata4, "sdata4") + S(dwarf::DW_EH_PE_sdata8, "sdata8") + + S(dwarf::DW_EH_PE_absptr | dwarf::DW_EH_PE_pcrel, "pcrel") + S(dwarf::DW_EH_PE_uleb128 | dwarf::DW_EH_PE_pcrel, "pcrel uleb128") + S(dwarf::DW_EH_PE_udata2 | dwarf::DW_EH_PE_pcrel, "pcrel udata2") + S(dwarf::DW_EH_PE_udata4 | dwarf::DW_EH_PE_pcrel, "pcrel udata4") + S(dwarf::DW_EH_PE_udata8 | dwarf::DW_EH_PE_pcrel, "pcrel udata8") + S(dwarf::DW_EH_PE_sleb128 | dwarf::DW_EH_PE_pcrel, "pcrel sleb128") + S(dwarf::DW_EH_PE_sdata2 | dwarf::DW_EH_PE_pcrel, "pcrel sdata2") + S(dwarf::DW_EH_PE_sdata4 | dwarf::DW_EH_PE_pcrel, "pcrel sdata4") + S(dwarf::DW_EH_PE_sdata8 | dwarf::DW_EH_PE_pcrel, "pcrel sdata8") + + S(dwarf::DW_EH_PE_absptr | dwarf::DW_EH_PE_textrel, "textrel") + S(dwarf::DW_EH_PE_uleb128 | dwarf::DW_EH_PE_textrel, "textrel uleb128") + S(dwarf::DW_EH_PE_udata2 | dwarf::DW_EH_PE_textrel, "textrel udata2") + S(dwarf::DW_EH_PE_udata4 | dwarf::DW_EH_PE_textrel, "textrel udata4") + S(dwarf::DW_EH_PE_udata8 | dwarf::DW_EH_PE_textrel, "textrel udata8") + S(dwarf::DW_EH_PE_sleb128 | dwarf::DW_EH_PE_textrel, "textrel sleb128") + S(dwarf::DW_EH_PE_sdata2 | dwarf::DW_EH_PE_textrel, "textrel sdata2") + S(dwarf::DW_EH_PE_sdata4 | dwarf::DW_EH_PE_textrel, "textrel sdata4") + S(dwarf::DW_EH_PE_sdata8 | dwarf::DW_EH_PE_textrel, "textrel sdata8") + + S(dwarf::DW_EH_PE_absptr | dwarf::DW_EH_PE_datarel, "datarel") + S(dwarf::DW_EH_PE_uleb128 | dwarf::DW_EH_PE_datarel, "datarel uleb128") + S(dwarf::DW_EH_PE_udata2 | dwarf::DW_EH_PE_datarel, "datarel udata2") + S(dwarf::DW_EH_PE_udata4 | dwarf::DW_EH_PE_datarel, "datarel udata4") + S(dwarf::DW_EH_PE_udata8 | dwarf::DW_EH_PE_datarel, "datarel udata8") + S(dwarf::DW_EH_PE_sleb128 | dwarf::DW_EH_PE_datarel, "datarel sleb128") + S(dwarf::DW_EH_PE_sdata2 | dwarf::DW_EH_PE_datarel, "datarel sdata2") + S(dwarf::DW_EH_PE_sdata4 | dwarf::DW_EH_PE_datarel, "datarel sdata4") + S(dwarf::DW_EH_PE_sdata8 | dwarf::DW_EH_PE_datarel, "datarel sdata8") + + S(dwarf::DW_EH_PE_absptr | dwarf::DW_EH_PE_funcrel, "funcrel") + S(dwarf::DW_EH_PE_uleb128 | dwarf::DW_EH_PE_funcrel, "funcrel uleb128") + S(dwarf::DW_EH_PE_udata2 | dwarf::DW_EH_PE_funcrel, "funcrel udata2") + S(dwarf::DW_EH_PE_udata4 | dwarf::DW_EH_PE_funcrel, "funcrel udata4") + S(dwarf::DW_EH_PE_udata8 | dwarf::DW_EH_PE_funcrel, "funcrel udata8") + S(dwarf::DW_EH_PE_sleb128 | dwarf::DW_EH_PE_funcrel, "funcrel sleb128") + S(dwarf::DW_EH_PE_sdata2 | dwarf::DW_EH_PE_funcrel, "funcrel sdata2") + S(dwarf::DW_EH_PE_sdata4 | dwarf::DW_EH_PE_funcrel, "funcrel sdata4") + S(dwarf::DW_EH_PE_sdata8 | dwarf::DW_EH_PE_funcrel, "funcrel sdata8") + + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_absptr |dwarf::DW_EH_PE_pcrel, + "indirect pcrel") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_uleb128 |dwarf::DW_EH_PE_pcrel, + "indirect pcrel uleb128") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_udata2 |dwarf::DW_EH_PE_pcrel, + "indirect pcrel udata2") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_udata4 |dwarf::DW_EH_PE_pcrel, + "indirect pcrel udata4") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_udata8 |dwarf::DW_EH_PE_pcrel, + "indirect pcrel udata8") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sleb128 |dwarf::DW_EH_PE_pcrel, + "indirect pcrel sleb128") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sdata2 |dwarf::DW_EH_PE_pcrel, + "indirect pcrel sdata2") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sdata4 |dwarf::DW_EH_PE_pcrel, + "indirect pcrel sdata4") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sdata8 |dwarf::DW_EH_PE_pcrel, + "indirect pcrel sdata8") + + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_absptr |dwarf::DW_EH_PE_textrel, + "indirect textrel") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_uleb128 |dwarf::DW_EH_PE_textrel, + "indirect textrel uleb128") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_udata2 |dwarf::DW_EH_PE_textrel, + "indirect textrel udata2") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_udata4 |dwarf::DW_EH_PE_textrel, + "indirect textrel udata4") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_udata8 |dwarf::DW_EH_PE_textrel, + "indirect textrel udata8") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sleb128 |dwarf::DW_EH_PE_textrel, + "indirect textrel sleb128") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sdata2 |dwarf::DW_EH_PE_textrel, + "indirect textrel sdata2") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sdata4 |dwarf::DW_EH_PE_textrel, + "indirect textrel sdata4") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sdata8 |dwarf::DW_EH_PE_textrel, + "indirect textrel sdata8") + + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_absptr |dwarf::DW_EH_PE_datarel, + "indirect datarel") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_uleb128 |dwarf::DW_EH_PE_datarel, + "indirect datarel uleb128") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_udata2 |dwarf::DW_EH_PE_datarel, + "indirect datarel udata2") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_udata4 |dwarf::DW_EH_PE_datarel, + "indirect datarel udata4") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_udata8 |dwarf::DW_EH_PE_datarel, + "indirect datarel udata8") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sleb128 |dwarf::DW_EH_PE_datarel, + "indirect datarel sleb128") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sdata2 |dwarf::DW_EH_PE_datarel, + "indirect datarel sdata2") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sdata4 |dwarf::DW_EH_PE_datarel, + "indirect datarel sdata4") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sdata8 |dwarf::DW_EH_PE_datarel, + "indirect datarel sdata8") + + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_absptr |dwarf::DW_EH_PE_funcrel, + "indirect funcrel") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_uleb128 |dwarf::DW_EH_PE_funcrel, + "indirect funcrel uleb128") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_udata2 |dwarf::DW_EH_PE_funcrel, + "indirect funcrel udata2") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_udata4 |dwarf::DW_EH_PE_funcrel, + "indirect funcrel udata4") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_udata8 |dwarf::DW_EH_PE_funcrel, + "indirect funcrel udata8") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sleb128 |dwarf::DW_EH_PE_funcrel, + "indirect funcrel sleb128") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sdata2 |dwarf::DW_EH_PE_funcrel, + "indirect funcrel sdata2") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sdata4 |dwarf::DW_EH_PE_funcrel, + "indirect funcrel sdata4") + S(dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_sdata8 |dwarf::DW_EH_PE_funcrel, + "indirect funcrel sdata8") + +#if HAVE_DESIGNATED_INITIALIZERS + }; + + assert(DataFormat >= 0 && DataFormat < 0x100 && FormatNames[DataFormat] && + "Invalid DWARF data format!"); + return FormatNames[DataFormat]; +#else + } + llvm_unreachable("Invalid DWARF data format!"); + return 0; +#endif +#undef HAVE_DESIGNATED_INITIALIZERS +} + +void AsmPrinter::EOL(const std::string &Comment, unsigned DataFormat) const { + if (VerboseAsm && !Comment.empty()) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << ' ' << Comment << " (" << GetDataFormatName(DataFormat) << ')'; + } + O << '\n'; +} + +void AsmPrinter::EOL(const char* Comment, unsigned DataFormat) const { + if (VerboseAsm && *Comment) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << ' ' << Comment << " (" << GetDataFormatName(DataFormat) << ')'; + } + O << '\n'; +} + /// EmitULEB128Bytes - Emit an assembler byte data directive to compose an /// unsigned leb128 value. void AsmPrinter::EmitULEB128Bytes(unsigned Value) const { - if (TAI->hasLEB128()) { + if (MAI->hasLEB128()) { O << "\t.uleb128\t" << Value; } else { - O << TAI->getData8bitsDirective(); + O << MAI->getData8bitsDirective(); PrintULEB128(Value); } } @@ -702,11 +799,11 @@ void AsmPrinter::EmitULEB128Bytes(unsigned Value) const { /// EmitSLEB128Bytes - print an assembler byte data directive to compose a /// signed leb128 value. void AsmPrinter::EmitSLEB128Bytes(int Value) const { - if (TAI->hasLEB128()) { + if (MAI->hasLEB128()) { O << "\t.sleb128\t" << Value; } else { - O << TAI->getData8bitsDirective(); + O << MAI->getData8bitsDirective(); PrintSLEB128(Value); } } @@ -714,29 +811,29 @@ void AsmPrinter::EmitSLEB128Bytes(int Value) const { /// EmitInt8 - Emit a byte directive and value. /// void AsmPrinter::EmitInt8(int Value) const { - O << TAI->getData8bitsDirective(); + O << MAI->getData8bitsDirective(); PrintHex(Value & 0xFF); } /// EmitInt16 - Emit a short directive and value. /// void AsmPrinter::EmitInt16(int Value) const { - O << TAI->getData16bitsDirective(); + O << MAI->getData16bitsDirective(); PrintHex(Value & 0xFFFF); } /// EmitInt32 - Emit a long directive and value. /// void AsmPrinter::EmitInt32(int Value) const { - O << TAI->getData32bitsDirective(); + O << MAI->getData32bitsDirective(); PrintHex(Value); } /// EmitInt64 - Emit a long long directive and value. /// void AsmPrinter::EmitInt64(uint64_t Value) const { - if (TAI->getData64bitsDirective()) { - O << TAI->getData64bitsDirective(); + if (MAI->getData64bitsDirective()) { + O << MAI->getData64bitsDirective(); PrintHex(Value); } else { if (TM.getTargetData()->isBigEndian()) { @@ -789,11 +886,11 @@ void AsmPrinter::EmitString(const std::string &String) const { } void AsmPrinter::EmitString(const char *String, unsigned Size) const { - const char* AscizDirective = TAI->getAscizDirective(); + const char* AscizDirective = MAI->getAscizDirective(); if (AscizDirective) O << AscizDirective; else - O << TAI->getAsciiDirective(); + O << MAI->getAsciiDirective(); O << '\"'; for (unsigned i = 0; i < Size; ++i) printStringChar(O, String[i]); @@ -836,51 +933,26 @@ void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV, NumBits = std::max(NumBits, ForcedAlignBits); if (NumBits == 0) return; // No need to emit alignment. - if (TAI->getAlignmentIsInBytes()) NumBits = 1 << NumBits; - O << TAI->getAlignDirective() << NumBits; - - unsigned FillValue = TAI->getTextAlignFillValue(); - UseFillExpr &= IsInTextSection && FillValue; - if (UseFillExpr) { - O << ','; - PrintHex(FillValue); - } - O << '\n'; -} - -/// PadToColumn - This gets called every time a tab is emitted. If -/// column padding is turned on, we replace the tab with the -/// appropriate amount of padding. If not, we replace the tab with a -/// space, except for the first operand so that initial operands are -/// always lined up by tabs. -void AsmPrinter::PadToColumn(unsigned Operand) const { - if (TAI->getOperandColumn(Operand) > 0) { - O.PadToColumn(TAI->getOperandColumn(Operand), 1); - } - else { - if (Operand == 1) { - // Emit the tab after the mnemonic. - O << '\t'; - } - else { - // Replace the tab with a space. - O << ' '; - } - } + + unsigned FillValue = 0; + if (getCurrentSection()->getKind().isText()) + FillValue = MAI->getTextAlignFillValue(); + + OutStreamer.EmitValueToAlignment(1 << NumBits, FillValue, 1, 0); } /// EmitZeros - Emit a block of zeros. /// void AsmPrinter::EmitZeros(uint64_t NumZeros, unsigned AddrSpace) const { if (NumZeros) { - if (TAI->getZeroDirective()) { - O << TAI->getZeroDirective() << NumZeros; - if (TAI->getZeroDirectiveSuffix()) - O << TAI->getZeroDirectiveSuffix(); + if (MAI->getZeroDirective()) { + O << MAI->getZeroDirective() << NumZeros; + if (MAI->getZeroDirectiveSuffix()) + O << MAI->getZeroDirectiveSuffix(); O << '\n'; } else { for (; NumZeros; --NumZeros) - O << TAI->getData8bitsDirective(AddrSpace) << "0\n"; + O << MAI->getData8bitsDirective(AddrSpace) << "0\n"; } } } @@ -898,18 +970,28 @@ void AsmPrinter::EmitConstantValueOnly(const Constant *CV) { // decorating it with GlobalVarAddrPrefix/Suffix or // FunctionAddrPrefix/Suffix (these all default to "" ) if (isa(GV)) { - O << TAI->getFunctionAddrPrefix() + O << MAI->getFunctionAddrPrefix() << Mang->getMangledName(GV) - << TAI->getFunctionAddrSuffix(); + << MAI->getFunctionAddrSuffix(); } else { - O << TAI->getGlobalVarAddrPrefix() + O << MAI->getGlobalVarAddrPrefix() << Mang->getMangledName(GV) - << TAI->getGlobalVarAddrSuffix(); + << MAI->getGlobalVarAddrSuffix(); } } else if (const ConstantExpr *CE = dyn_cast(CV)) { const TargetData *TD = TM.getTargetData(); unsigned Opcode = CE->getOpcode(); switch (Opcode) { + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + llvm_unreachable("FIXME: Don't support this constant cast expr"); case Instruction::GetElementPtr: { // generate a symbolic expression for the byte address const Constant *ptrVal = CE->getOperand(0); @@ -934,17 +1016,6 @@ void AsmPrinter::EmitConstantValueOnly(const Constant *CV) { } break; } - case Instruction::Trunc: - case Instruction::ZExt: - case Instruction::SExt: - case Instruction::FPTrunc: - case Instruction::FPExt: - case Instruction::UIToFP: - case Instruction::SIToFP: - case Instruction::FPToUI: - case Instruction::FPToSI: - llvm_unreachable("FIXME: Don't yet support this kind of constant cast expr"); - break; case Instruction::BitCast: return EmitConstantValueOnly(CE->getOperand(0)); @@ -952,7 +1023,8 @@ void AsmPrinter::EmitConstantValueOnly(const Constant *CV) { // Handle casts to pointers by changing them into casts to the appropriate // integer type. This promotes constant folding and simplifies this code. Constant *Op = CE->getOperand(0); - Op = ConstantExpr::getIntegerCast(Op, TD->getIntPtrType(), false/*ZExt*/); + Op = ConstantExpr::getIntegerCast(Op, TD->getIntPtrType(CV->getContext()), + false/*ZExt*/); return EmitConstantValueOnly(Op); } @@ -965,16 +1037,17 @@ void AsmPrinter::EmitConstantValueOnly(const Constant *CV) { // We can emit the pointer value into this slot if the slot is an // integer slot greater or equal to the size of the pointer. - if (TD->getTypeAllocSize(Ty) >= TD->getTypeAllocSize(Op->getType())) + if (TD->getTypeAllocSize(Ty) == TD->getTypeAllocSize(Op->getType())) return EmitConstantValueOnly(Op); O << "(("; EmitConstantValueOnly(Op); - APInt ptrMask = APInt::getAllOnesValue(TD->getTypeAllocSizeInBits(Ty)); + APInt ptrMask = + APInt::getAllOnesValue(TD->getTypeAllocSizeInBits(Op->getType())); SmallString<40> S; ptrMask.toStringUnsigned(S); - O << ") & " << S.c_str() << ')'; + O << ") & " << S.str() << ')'; break; } case Instruction::Add: @@ -1036,12 +1109,12 @@ static void printAsCString(formatted_raw_ostream &O, const ConstantArray *CVA, /// void AsmPrinter::EmitString(const ConstantArray *CVA) const { unsigned NumElts = CVA->getNumOperands(); - if (TAI->getAscizDirective() && NumElts && + if (MAI->getAscizDirective() && NumElts && cast(CVA->getOperand(NumElts-1))->getZExtValue() == 0) { - O << TAI->getAscizDirective(); + O << MAI->getAscizDirective(); printAsCString(O, CVA, NumElts-1); } else { - O << TAI->getAsciiDirective(); + O << MAI->getAsciiDirective(); printAsCString(O, CVA, NumElts); } O << '\n'; @@ -1096,48 +1169,61 @@ void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace) { // FP Constants are printed as integer constants to avoid losing // precision... + LLVMContext &Context = CFP->getContext(); const TargetData *TD = TM.getTargetData(); - if (CFP->getType() == Type::DoubleTy) { + if (CFP->getType() == Type::getDoubleTy(Context)) { double Val = CFP->getValueAPF().convertToDouble(); // for comment only uint64_t i = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); - if (TAI->getData64bitsDirective(AddrSpace)) { - O << TAI->getData64bitsDirective(AddrSpace) << i; - if (VerboseAsm) - O << '\t' << TAI->getCommentString() << " double value: " << Val; + if (MAI->getData64bitsDirective(AddrSpace)) { + O << MAI->getData64bitsDirective(AddrSpace) << i; + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << " double " << Val; + } O << '\n'; } else if (TD->isBigEndian()) { - O << TAI->getData32bitsDirective(AddrSpace) << unsigned(i >> 32); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " double most significant word " << Val; + O << MAI->getData32bitsDirective(AddrSpace) << unsigned(i >> 32); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " most significant word of double " << Val; + } O << '\n'; - O << TAI->getData32bitsDirective(AddrSpace) << unsigned(i); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " double least significant word " << Val; + O << MAI->getData32bitsDirective(AddrSpace) << unsigned(i); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " least significant word of double " << Val; + } O << '\n'; } else { - O << TAI->getData32bitsDirective(AddrSpace) << unsigned(i); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " double least significant word " << Val; + O << MAI->getData32bitsDirective(AddrSpace) << unsigned(i); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " least significant word of double " << Val; + } O << '\n'; - O << TAI->getData32bitsDirective(AddrSpace) << unsigned(i >> 32); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " double most significant word " << Val; + O << MAI->getData32bitsDirective(AddrSpace) << unsigned(i >> 32); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " most significant word of double " << Val; + } O << '\n'; } return; - } else if (CFP->getType() == Type::FloatTy) { + } else if (CFP->getType() == Type::getFloatTy(Context)) { float Val = CFP->getValueAPF().convertToFloat(); // for comment only - O << TAI->getData32bitsDirective(AddrSpace) + O << MAI->getData32bitsDirective(AddrSpace) << CFP->getValueAPF().bitcastToAPInt().getZExtValue(); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() << " float " << Val; + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << " float " << Val; + } O << '\n'; return; - } else if (CFP->getType() == Type::X86_FP80Ty) { + } else if (CFP->getType() == Type::getX86_FP80Ty(Context)) { // all long double variants are printed as hex // api needed to prevent premature destruction APInt api = CFP->getValueAPF().bitcastToAPInt(); @@ -1148,106 +1234,142 @@ void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP, DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored); if (TD->isBigEndian()) { - O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1]); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " long double most significant halfword of ~" + O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1]); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " most significant halfword of x86_fp80 ~" << DoubleVal.convertToDouble(); + } O << '\n'; - O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 48); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() << " long double next halfword"; + O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 48); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << " next halfword"; + } O << '\n'; - O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 32); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() << " long double next halfword"; + O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 32); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << " next halfword"; + } O << '\n'; - O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 16); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() << " long double next halfword"; + O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 16); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << " next halfword"; + } O << '\n'; - O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0]); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " long double least significant halfword"; + O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0]); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " least significant halfword"; + } O << '\n'; } else { - O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0]); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " long double least significant halfword of ~" + O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0]); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " least significant halfword of x86_fp80 ~" << DoubleVal.convertToDouble(); + } O << '\n'; - O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 16); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " long double next halfword"; + O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 16); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " next halfword"; + } O << '\n'; - O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 32); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " long double next halfword"; + O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 32); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " next halfword"; + } O << '\n'; - O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 48); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " long double next halfword"; + O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 48); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " next halfword"; + } O << '\n'; - O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1]); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " long double most significant halfword"; + O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1]); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " most significant halfword"; + } O << '\n'; } - EmitZeros(TD->getTypeAllocSize(Type::X86_FP80Ty) - - TD->getTypeStoreSize(Type::X86_FP80Ty), AddrSpace); + EmitZeros(TD->getTypeAllocSize(Type::getX86_FP80Ty(Context)) - + TD->getTypeStoreSize(Type::getX86_FP80Ty(Context)), AddrSpace); return; - } else if (CFP->getType() == Type::PPC_FP128Ty) { + } else if (CFP->getType() == Type::getPPC_FP128Ty(Context)) { // all long double variants are printed as hex // api needed to prevent premature destruction APInt api = CFP->getValueAPF().bitcastToAPInt(); const uint64_t *p = api.getRawData(); if (TD->isBigEndian()) { - O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0] >> 32); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " long double most significant word"; + O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0] >> 32); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " most significant word of ppc_fp128"; + } O << '\n'; - O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0]); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " long double next word"; + O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0]); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " next word"; + } O << '\n'; - O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1] >> 32); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " long double next word"; + O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1] >> 32); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " next word"; + } O << '\n'; - O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1]); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " long double least significant word"; + O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1]); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " least significant word"; + } O << '\n'; } else { - O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1]); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " long double least significant word"; + O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1]); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " least significant word of ppc_fp128"; + } O << '\n'; - O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1] >> 32); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " long double next word"; + O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1] >> 32); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " next word"; + } O << '\n'; - O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0]); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " long double next word"; + O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0]); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " next word"; + } O << '\n'; - O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0] >> 32); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " long double most significant word"; + O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0] >> 32); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " most significant word"; + } O << '\n'; } return; @@ -1272,29 +1394,37 @@ void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI, else Val = RawData[i]; - if (TAI->getData64bitsDirective(AddrSpace)) - O << TAI->getData64bitsDirective(AddrSpace) << Val << '\n'; + if (MAI->getData64bitsDirective(AddrSpace)) + O << MAI->getData64bitsDirective(AddrSpace) << Val << '\n'; else if (TD->isBigEndian()) { - O << TAI->getData32bitsDirective(AddrSpace) << unsigned(Val >> 32); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " Double-word most significant word " << Val; + O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val >> 32); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " most significant half of i64 " << Val; + } O << '\n'; - O << TAI->getData32bitsDirective(AddrSpace) << unsigned(Val); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " Double-word least significant word " << Val; + O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " least significant half of i64 " << Val; + } O << '\n'; } else { - O << TAI->getData32bitsDirective(AddrSpace) << unsigned(Val); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " Double-word least significant word " << Val; + O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " least significant half of i64 " << Val; + } O << '\n'; - O << TAI->getData32bitsDirective(AddrSpace) << unsigned(Val >> 32); - if (VerboseAsm) - O << '\t' << TAI->getCommentString() - << " Double-word most significant word " << Val; + O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val >> 32); + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << " most significant half of i64 " << Val; + } O << '\n'; } } @@ -1335,7 +1465,8 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) { if (const ConstantInt *CI = dyn_cast(CV)) { SmallString<40> S; CI->getValue().toStringUnsigned(S, 16); - O << "\t\t\t" << TAI->getCommentString() << " 0x" << S.c_str(); + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << " 0x" << S.str(); } } O << '\n'; @@ -1354,10 +1485,10 @@ void AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { /// for their own strange codes. void AsmPrinter::PrintSpecial(const MachineInstr *MI, const char *Code) const { if (!strcmp(Code, "private")) { - O << TAI->getPrivateGlobalPrefix(); + O << MAI->getPrivateGlobalPrefix(); } else if (!strcmp(Code, "comment")) { if (VerboseAsm) - O << TAI->getCommentString(); + O << MAI->getCommentString(); } else if (!strcmp(Code, "uid")) { // Comparing the address of MI isn't sufficient, because machineinstrs may // be allocated to the same address across functions. @@ -1382,7 +1513,10 @@ void AsmPrinter::PrintSpecial(const MachineInstr *MI, const char *Code) const { /// processDebugLoc - Processes the debug information of each machine /// instruction's DebugLoc. void AsmPrinter::processDebugLoc(DebugLoc DL) { - if (TAI->doesSupportDebugInformation() && DW->ShouldEmitDwarfDebug()) { + if (!MAI || !DW) + return; + + if (MAI->doesSupportDebugInformation() && DW->ShouldEmitDwarfDebug()) { if (!DL.isUnknown()) { DebugLocTuple CurDLT = MF->getDebugLocTuple(DL); @@ -1414,14 +1548,15 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const { // If this asmstr is empty, just print the #APP/#NOAPP markers. // These are useful to see where empty asm's wound up. if (AsmStr[0] == 0) { - O << TAI->getInlineAsmStart() << "\n\t" << TAI->getInlineAsmEnd() << '\n'; + O << MAI->getCommentString() << MAI->getInlineAsmStart() << "\n\t"; + O << MAI->getCommentString() << MAI->getInlineAsmEnd() << '\n'; return; } - O << TAI->getInlineAsmStart() << "\n\t"; + O << MAI->getCommentString() << MAI->getInlineAsmStart() << "\n\t"; // The variant of the current asmprinter. - int AsmPrinterVariant = TAI->getAssemblerDialect(); + int AsmPrinterVariant = MAI->getAssemblerDialect(); int CurVariant = -1; // The number of the {.|.|.} region we are in. const char *LastEmitted = AsmStr; // One past the last character emitted. @@ -1589,15 +1724,17 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const { } } } - O << "\n\t" << TAI->getInlineAsmEnd() << '\n'; + O << "\n\t" << MAI->getCommentString() << MAI->getInlineAsmEnd() << '\n'; } /// printImplicitDef - This method prints the specified machine instruction /// that is an implicit def. void AsmPrinter::printImplicitDef(const MachineInstr *MI) const { - if (VerboseAsm) - O << '\t' << TAI->getCommentString() << " implicit-def: " + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << " implicit-def: " << TRI->getAsmName(MI->getOperand(0).getReg()) << '\n'; + } } /// printLabel - This method prints a local label used by debug and @@ -1607,17 +1744,7 @@ void AsmPrinter::printLabel(const MachineInstr *MI) const { } void AsmPrinter::printLabel(unsigned Id) const { - O << TAI->getPrivateGlobalPrefix() << "label" << Id << ":\n"; -} - -/// printDeclare - This method prints a local variable declaration used by -/// debug tables. -/// FIXME: It doesn't really print anything rather it inserts a DebugVariable -/// entry into dwarf table. -void AsmPrinter::printDeclare(const MachineInstr *MI) const { - unsigned FI = MI->getOperand(0).getIndex(); - GlobalValue *GV = MI->getOperand(1).getGlobal(); - DW->RecordVariable(cast(GV), FI, MI); + O << MAI->getPrivateGlobalPrefix() << "label" << Id << ":\n"; } /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM @@ -1648,39 +1775,47 @@ void AsmPrinter::printBasicBlockLabel(const MachineBasicBlock *MBB, EmitAlignment(Log2_32(Align)); } - O << TAI->getPrivateGlobalPrefix() << "BB" << getFunctionNumber() << '_' + O << MAI->getPrivateGlobalPrefix() << "BB" << getFunctionNumber() << '_' << MBB->getNumber(); if (printColon) O << ':'; - if (printComment && MBB->getBasicBlock()) - O << '\t' << TAI->getCommentString() << ' ' - << MBB->getBasicBlock()->getNameStr(); + if (printComment) { + if (const BasicBlock *BB = MBB->getBasicBlock()) + if (BB->hasName()) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << ' '; + WriteAsOperand(O, BB, /*PrintType=*/false); + } + + if (printColon) + EmitComments(*MBB); + } } /// printPICJumpTableSetLabel - This method prints a set label for the /// specified MachineBasicBlock for a jumptable entry. void AsmPrinter::printPICJumpTableSetLabel(unsigned uid, const MachineBasicBlock *MBB) const { - if (!TAI->getSetDirective()) + if (!MAI->getSetDirective()) return; - O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() + O << MAI->getSetDirective() << ' ' << MAI->getPrivateGlobalPrefix() << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ','; printBasicBlockLabel(MBB, false, false, false); - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() + O << '-' << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << uid << '\n'; } void AsmPrinter::printPICJumpTableSetLabel(unsigned uid, unsigned uid2, const MachineBasicBlock *MBB) const { - if (!TAI->getSetDirective()) + if (!MAI->getSetDirective()) return; - O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() + O << MAI->getSetDirective() << ' ' << MAI->getPrivateGlobalPrefix() << getFunctionNumber() << '_' << uid << '_' << uid2 << "_set_" << MBB->getNumber() << ','; printBasicBlockLabel(MBB, false, false, false); - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() + O << '-' << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << uid << '_' << uid2 << '\n'; } @@ -1697,15 +1832,15 @@ void AsmPrinter::printDataDirective(const Type *type, unsigned AddrSpace) { case Type::IntegerTyID: { unsigned BitWidth = cast(type)->getBitWidth(); if (BitWidth <= 8) - O << TAI->getData8bitsDirective(AddrSpace); + O << MAI->getData8bitsDirective(AddrSpace); else if (BitWidth <= 16) - O << TAI->getData16bitsDirective(AddrSpace); + O << MAI->getData16bitsDirective(AddrSpace); else if (BitWidth <= 32) - O << TAI->getData32bitsDirective(AddrSpace); + O << MAI->getData32bitsDirective(AddrSpace); else if (BitWidth <= 64) { - assert(TAI->getData64bitsDirective(AddrSpace) && + assert(MAI->getData64bitsDirective(AddrSpace) && "Target cannot handle 64-bit constant exprs!"); - O << TAI->getData64bitsDirective(AddrSpace); + O << MAI->getData64bitsDirective(AddrSpace); } else { llvm_unreachable("Target cannot handle given data directive width!"); } @@ -1713,15 +1848,15 @@ void AsmPrinter::printDataDirective(const Type *type, unsigned AddrSpace) { } case Type::PointerTyID: if (TD->getPointerSize() == 8) { - assert(TAI->getData64bitsDirective(AddrSpace) && + assert(MAI->getData64bitsDirective(AddrSpace) && "Target cannot handle 64-bit pointer exprs!"); - O << TAI->getData64bitsDirective(AddrSpace); + O << MAI->getData64bitsDirective(AddrSpace); } else if (TD->getPointerSize() == 2) { - O << TAI->getData16bitsDirective(AddrSpace); + O << MAI->getData16bitsDirective(AddrSpace); } else if (TD->getPointerSize() == 1) { - O << TAI->getData8bitsDirective(AddrSpace); + O << MAI->getData8bitsDirective(AddrSpace); } else { - O << TAI->getData32bitsDirective(AddrSpace); + O << MAI->getData32bitsDirective(AddrSpace); } break; } @@ -1730,10 +1865,10 @@ void AsmPrinter::printDataDirective(const Type *type, unsigned AddrSpace) { void AsmPrinter::printVisibility(const std::string& Name, unsigned Visibility) const { if (Visibility == GlobalValue::HiddenVisibility) { - if (const char *Directive = TAI->getHiddenDirective()) + if (const char *Directive = MAI->getHiddenDirective()) O << Directive << Name << '\n'; } else if (Visibility == GlobalValue::ProtectedVisibility) { - if (const char *Directive = TAI->getProtectedDirective()) + if (const char *Directive = MAI->getProtectedDirective()) O << Directive << Name << '\n'; } } @@ -1745,6 +1880,10 @@ void AsmPrinter::printOffset(int64_t Offset) const { O << Offset; } +void AsmPrinter::printMCInst(const MCInst *MI) { + llvm_unreachable("MCInst printing unavailable on this target!"); +} + GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) { if (!S->usesMetadata()) return 0; @@ -1765,54 +1904,129 @@ GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) { return GMP; } - cerr << "no GCMetadataPrinter registered for GC: " << Name << "\n"; + errs() << "no GCMetadataPrinter registered for GC: " << Name << "\n"; llvm_unreachable(0); } /// EmitComments - Pretty-print comments for instructions -void AsmPrinter::EmitComments(const MachineInstr &MI) const -{ - if (VerboseAsm) { - if (!MI.getDebugLoc().isUnknown()) { - DebugLocTuple DLT = MF->getDebugLocTuple(MI.getDebugLoc()); - - // Print source line info - O.PadToColumn(TAI->getCommentColumn(), 1); - O << TAI->getCommentString() << " SrcLine "; - if (DLT.CompileUnit->hasInitializer()) { - Constant *Name = DLT.CompileUnit->getInitializer(); - if (ConstantArray *NameString = dyn_cast(Name)) - if (NameString->isString()) { - O << NameString->getAsString() << " "; - } - } - O << DLT.Line; - if (DLT.Col != 0) - O << ":" << DLT.Col; - } +void AsmPrinter::EmitComments(const MachineInstr &MI) const { + if (!VerboseAsm || + MI.getDebugLoc().isUnknown()) + return; + + DebugLocTuple DLT = MF->getDebugLocTuple(MI.getDebugLoc()); + + // Print source line info. + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << " SrcLine "; + if (DLT.CompileUnit->hasInitializer()) { + Constant *Name = DLT.CompileUnit->getInitializer(); + if (ConstantArray *NameString = dyn_cast(Name)) + if (NameString->isString()) + O << NameString->getAsString() << " "; } + O << DLT.Line; + if (DLT.Col != 0) + O << ":" << DLT.Col; } /// EmitComments - Pretty-print comments for instructions -void AsmPrinter::EmitComments(const MCInst &MI) const +void AsmPrinter::EmitComments(const MCInst &MI) const { + if (!VerboseAsm || + MI.getDebugLoc().isUnknown()) + return; + + DebugLocTuple DLT = MF->getDebugLocTuple(MI.getDebugLoc()); + + // Print source line info + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << " SrcLine "; + if (DLT.CompileUnit->hasInitializer()) { + Constant *Name = DLT.CompileUnit->getInitializer(); + if (ConstantArray *NameString = dyn_cast(Name)) + if (NameString->isString()) + O << NameString->getAsString() << " "; + } + O << DLT.Line; + if (DLT.Col != 0) + O << ":" << DLT.Col; +} + +/// PrintChildLoopComment - Print comments about child loops within +/// the loop for this basic block, with nesting. +/// +static void PrintChildLoopComment(formatted_raw_ostream &O, + const MachineLoop *loop, + const MCAsmInfo *MAI, + int FunctionNumber) { + // Add child loop information + for(MachineLoop::iterator cl = loop->begin(), + clend = loop->end(); + cl != clend; + ++cl) { + MachineBasicBlock *Header = (*cl)->getHeader(); + assert(Header && "No header for loop"); + + O << '\n'; + O.PadToColumn(MAI->getCommentColumn()); + + O << MAI->getCommentString(); + O.indent(((*cl)->getLoopDepth()-1)*2) + << " Child Loop BB" << FunctionNumber << "_" + << Header->getNumber() << " Depth " << (*cl)->getLoopDepth(); + + PrintChildLoopComment(O, *cl, MAI, FunctionNumber); + } +} + +/// EmitComments - Pretty-print comments for basic blocks +void AsmPrinter::EmitComments(const MachineBasicBlock &MBB) const { if (VerboseAsm) { - if (!MI.getDebugLoc().isUnknown()) { - DebugLocTuple DLT = MF->getDebugLocTuple(MI.getDebugLoc()); - - // Print source line info - O.PadToColumn(TAI->getCommentColumn(), 1); - O << TAI->getCommentString() << " SrcLine "; - if (DLT.CompileUnit->hasInitializer()) { - Constant *Name = DLT.CompileUnit->getInitializer(); - if (ConstantArray *NameString = dyn_cast(Name)) - if (NameString->isString()) { - O << NameString->getAsString() << " "; - } + // Add loop depth information + const MachineLoop *loop = LI->getLoopFor(&MBB); + + if (loop) { + // Print a newline after bb# annotation. + O << "\n"; + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << " Loop Depth " << loop->getLoopDepth() + << '\n'; + + O.PadToColumn(MAI->getCommentColumn()); + + MachineBasicBlock *Header = loop->getHeader(); + assert(Header && "No header for loop"); + + if (Header == &MBB) { + O << MAI->getCommentString() << " Loop Header"; + PrintChildLoopComment(O, loop, MAI, getFunctionNumber()); + } + else { + O << MAI->getCommentString() << " Loop Header is BB" + << getFunctionNumber() << "_" << loop->getHeader()->getNumber(); + } + + if (loop->empty()) { + O << '\n'; + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << " Inner Loop"; + } + + // Add parent loop information + for (const MachineLoop *CurLoop = loop->getParentLoop(); + CurLoop; + CurLoop = CurLoop->getParentLoop()) { + MachineBasicBlock *Header = CurLoop->getHeader(); + assert(Header && "No header for loop"); + + O << '\n'; + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString(); + O.indent((CurLoop->getLoopDepth()-1)*2) + << " Inside Loop BB" << getFunctionNumber() << "_" + << Header->getNumber() << " Depth " << CurLoop->getLoopDepth(); } - O << DLT.Line; - if (DLT.Col != 0) - O << ":" << DLT.Col; } } }