Skip to content
AsmPrinter.cpp 60.3 KiB
Newer Older
//===-- AsmPrinter.cpp - Common AsmPrinter code ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the AsmPrinter class.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/GCMetadataPrinter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/Support/ErrorHandling.h"
David Greene's avatar
 
David Greene committed
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Mangler.h"
David Greene's avatar
 
David Greene committed
#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringExtras.h"
static cl::opt<cl::boolOrDefault>
AsmVerbose("asm-verbose", cl::desc("Add comments to directives."),
           cl::init(cl::BOU_UNSET));

Devang Patel's avatar
Devang Patel committed
char AsmPrinter::ID = 0;
David Greene's avatar
 
David Greene committed
AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm,
                       const TargetAsmInfo *T, bool VDef)
  : MachineFunctionPass(&ID), FunctionNumber(0), O(o),
    TM(tm), TAI(T), TRI(tm.getRegisterInfo()),
    IsInTextSection(false), LastMI(0), LastFn(0), Counter(~0U),
    PrevDLT(0, ~0U, ~0U) {
  switch (AsmVerbose) {
  case cl::BOU_UNSET: VerboseAsm = VDef;  break;
  case cl::BOU_TRUE:  VerboseAsm = true;  break;
  case cl::BOU_FALSE: VerboseAsm = false; break;
  }
}
AsmPrinter::~AsmPrinter() {
  for (gcp_iterator I = GCMetadataPrinters.begin(),
                    E = GCMetadataPrinters.end(); I != E; ++I)
    delete I->second;
}
/// 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) {
  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';
/// 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;
    NS = TAI->getSwitchToSectionDirective() + GV->getSection();
  // 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';
    O << CurrentSection << TAI->getDataSectionStartSuffix() << '\n';
/// SwitchToSection - Switch to the specified section of the executable if we
/// are not already in it!
void AsmPrinter::SwitchToSection(const Section* 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->isNamed())
      O << TAI->getSwitchToSectionDirective()
        << CurrentSection
        << TAI->getSectionFlags(NS->getFlags());
    else
      O << CurrentSection;
    O << TAI->getDataSectionStartSuffix() << '\n';
  }

  IsInTextSection = (NS->getFlags() & SectionFlags::Code);
}
void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
  MachineFunctionPass::getAnalysisUsage(AU);
bool AsmPrinter::doInitialization(Module &M) {
  Mang = new Mangler(M, TAI->getGlobalPrefix(), TAI->getPrivateGlobalPrefix());
  if (TAI->doesAllowQuotesInName())
    Mang->setUseQuotes(true);
  
  GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
  assert(MI && "AsmPrinter didn't require GCModuleInfo?");
Rafael Espindola's avatar
Rafael Espindola committed

  if (TAI->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. */
    O << "\t.file\t\"" << M.getModuleIdentifier() << "\"\n";
  }

  for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I)
    if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I))
      MP->beginAssembly(O, *this, *TAI);
Chris Lattner's avatar
Chris Lattner committed
  if (!M.getModuleInlineAsm().empty())
    O << TAI->getCommentString() << " Start of file scope inline assembly\n"
Chris Lattner's avatar
Chris Lattner committed
      << M.getModuleInlineAsm()
      << '\n' << TAI->getCommentString()
      << " End of file scope inline assembly\n";
  SwitchToDataSection("");   // Reset back to no section.
  if (TAI->doesSupportDebugInformation() ||
      TAI->doesSupportExceptionHandling()) {
    MMI = getAnalysisIfAvailable<MachineModuleInfo>();
    if (MMI)
    DW = getAnalysisIfAvailable<DwarfWriter>();
    if (DW)
      DW->BeginModule(&M, MMI, O, this, TAI);
  return false;
}

bool AsmPrinter::doFinalization(Module &M) {
  // Emit final debug information.
  if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling())
    DW->EndModule();
  
Loading
Loading full blame...