//===-- AsmPrinter.cpp - Common AsmPrinter code ---------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the AsmPrinter class.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
#include <iostream>
#include <cerrno>
using namespace llvm;
AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm,
const TargetAsmInfo *T)
: FunctionNumber(0), O(o), TM(tm), TAI(T)
{}
std::string AsmPrinter::getSectionForFunction(const Function &F) const {
return TAI->getTextSection();
}
/// 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';
}
/// 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';
}
bool AsmPrinter::doInitialization(Module &M) {
Mang = new Mangler(M, TAI->getGlobalPrefix());
if (!M.getModuleInlineAsm().empty())
O << TAI->getCommentString() << " Start of file scope inline assembly\n"
<< M.getModuleInlineAsm()
<< "\n" << TAI->getCommentString()
<< " End of file scope inline assembly\n";
SwitchToDataSection(""); // Reset back to no section.
if (MachineDebugInfo *DebugInfo = getAnalysisToUpdate<MachineDebugInfo>()) {
DebugInfo->AnalyzeModule(M);
}
return false;
}
bool AsmPrinter::doFinalization(Module &M) {
delete Mang; Mang = 0;
return false;
}
void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
// What's my mangled name?
CurrentFnName = Mang->getValueName(MF.getFunction());
IncrementFunctionNumber();
}
/// EmitConstantPool - Print to the current output stream assembly
/// representations of the constants in the constant pool MCP. This is
/// used to print out constants which have been "spilled to memory" by
/// the code generator.
///
void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) {
const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
if (CP.empty()) return;
// Some targets require 4-, 8-, and 16- byte constant literals to be placed
// in special sections.
std::vector<std::pair<MachineConstantPoolEntry,unsigned> > FourByteCPs;
std::vector<std::pair<MachineConstantPoolEntry,unsigned> > EightByteCPs;
std::vector<std::pair<MachineConstantPoolEntry,unsigned> > SixteenByteCPs;
std::vector<std::pair<MachineConstantPoolEntry,unsigned> > OtherCPs;
std::vector<std::pair<MachineConstantPoolEntry,unsigned> > TargetCPs;
for (unsigned