#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/TargetMachine.h"
#include <iostream>
#include <cerrno>
using namespace llvm;
-AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm)
-: FunctionNumber(0), O(o), TM(tm),
- CommentString("#"),
- GlobalPrefix(""),
- PrivateGlobalPrefix("."),
- GlobalVarAddrPrefix(""),
- GlobalVarAddrSuffix(""),
- FunctionAddrPrefix(""),
- FunctionAddrSuffix(""),
- InlineAsmStart("#APP"),
- InlineAsmEnd("#NO_APP"),
- ZeroDirective("\t.zero\t"),
- ZeroDirectiveSuffix(0),
- AsciiDirective("\t.ascii\t"),
- AscizDirective("\t.asciz\t"),
- Data8bitsDirective("\t.byte\t"),
- Data16bitsDirective("\t.short\t"),
- Data32bitsDirective("\t.long\t"),
- Data64bitsDirective("\t.quad\t"),
- AlignDirective("\t.align\t"),
- AlignmentIsInBytes(true),
- SwitchToSectionDirective("\t.section\t"),
- TextSectionStartSuffix(""),
- DataSectionStartSuffix(""),
- SectionEndDirectiveSuffix(0),
- ConstantPoolSection("\t.section .rodata\n"),
- JumpTableDataSection("\t.section .rodata\n"),
- JumpTableTextSection("\t.text\n"),
- StaticCtorsSection("\t.section .ctors,\"aw\",@progbits"),
- StaticDtorsSection("\t.section .dtors,\"aw\",@progbits"),
- FourByteConstantSection(0),
- EightByteConstantSection(0),
- SixteenByteConstantSection(0),
- SetDirective(0),
- LCOMMDirective(0),
- COMMDirective("\t.comm\t"),
- COMMDirectiveTakesAlignment(true),
- HasDotTypeDotSizeDirective(true) {
-}
+AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm, TargetAsmInfo *T)
+: FunctionNumber(0), O(o), TM(tm), TAI(T)
+{}
/// SwitchToTextSection - Switch to the specified text section of the executable
const GlobalValue *GV) {
std::string NS;
if (GV && GV->hasSection())
- NS = SwitchToSectionDirective + GV->getSection();
+ NS = TAI->getSwitchToSectionDirective() + GV->getSection();
else
NS = NewSection;
if (CurrentSection == NS) return;
// Close the current section, if applicable.
- if (SectionEndDirectiveSuffix && !CurrentSection.empty())
- O << CurrentSection << SectionEndDirectiveSuffix << "\n";
+ if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty())
+ O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << "\n";
CurrentSection = NS;
if (!CurrentSection.empty())
- O << CurrentSection << TextSectionStartSuffix << '\n';
+ O << CurrentSection << TAI->getTextSectionStartSuffix() << '\n';
}
/// SwitchToDataSection - Switch to the specified data section of the executable
const GlobalValue *GV) {
std::string NS;
if (GV && GV->hasSection())
- NS = SwitchToSectionDirective + GV->getSection();
+ NS = TAI->getSwitchToSectionDirective() + GV->getSection();
else
NS = NewSection;
if (CurrentSection == NS) return;
// Close the current section, if applicable.
- if (SectionEndDirectiveSuffix && !CurrentSection.empty())
- O << CurrentSection << SectionEndDirectiveSuffix << "\n";
+ if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty())
+ O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << "\n";
CurrentSection = NS;
if (!CurrentSection.empty())
- O << CurrentSection << DataSectionStartSuffix << '\n';
+ O << CurrentSection << TAI->getDataSectionStartSuffix() << '\n';
}
bool AsmPrinter::doInitialization(Module &M) {
- Mang = new Mangler(M, GlobalPrefix);
+ Mang = new Mangler(M, TAI->getGlobalPrefix());
if (!M.getModuleInlineAsm().empty())
- O << CommentString << " Start of file scope inline assembly\n"
+ O << TAI->getCommentString() << " Start of file scope inline assembly\n"
<< M.getModuleInlineAsm()
- << "\n" << CommentString << " End of file scope inline assembly\n";
+ << "\n" << TAI->getCommentString()
+ << " End of file scope inline assembly\n";
SwitchToDataSection("", 0); // Reset back to no section.
MachineConstantPoolEntry CPE = CP[i];
const Constant *CV = CPE.Val;
const Type *Ty = CV->getType();
- if (FourByteConstantSection &&
+ if (TAI->getFourByteConstantSection() &&
TM.getTargetData()->getTypeSize(Ty) == 4)
FourByteCPs.push_back(std::make_pair(CPE, i));
- else if (EightByteConstantSection &&
+ else if (TAI->getSectionEndDirectiveSuffix() &&
TM.getTargetData()->getTypeSize(Ty) == 8)
EightByteCPs.push_back(std::make_pair(CPE, i));
- else if (SixteenByteConstantSection &&
+ else if (TAI->getSectionEndDirectiveSuffix() &&
TM.getTargetData()->getTypeSize(Ty) == 16)
SixteenByteCPs.push_back(std::make_pair(CPE, i));
else
}
unsigned Alignment = MCP->getConstantPoolAlignment();
- EmitConstantPool(Alignment, FourByteConstantSection, FourByteCPs);
- EmitConstantPool(Alignment, EightByteConstantSection, EightByteCPs);
- EmitConstantPool(Alignment, SixteenByteConstantSection, SixteenByteCPs);
- EmitConstantPool(Alignment, ConstantPoolSection, OtherCPs);
+ EmitConstantPool(Alignment, TAI->getFourByteConstantSection(), FourByteCPs);
+ EmitConstantPool(Alignment, TAI->getEightByteConstantSection(), EightByteCPs);
+ EmitConstantPool(Alignment, TAI->getSixteenByteConstantSection(),
+ SixteenByteCPs);
+ EmitConstantPool(Alignment, TAI->getConstantPoolSection(), OtherCPs);
}
void AsmPrinter::EmitConstantPool(unsigned Alignment, const char *Section,
SwitchToDataSection(Section, 0);
EmitAlignment(Alignment);
for (unsigned i = 0, e = CP.size(); i != e; ++i) {
- O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << '_'
- << CP[i].second << ":\t\t\t\t\t" << CommentString << " ";
+ O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
+ << CP[i].second << ":\t\t\t\t\t" << TAI->getCommentString() << " ";
WriteTypeSymbolic(O, CP[i].first.Val->getType(), 0) << '\n';
EmitGlobalConstant(CP[i].first.Val);
if (i != e-1) {
// JTEntryDirective is a string to print sizeof(ptr) for non-PIC jump tables,
// and 32 bits for PIC since PIC jump table entries are differences, not
// pointers to blocks.
- const char *JTEntryDirective = Data32bitsDirective;
+ const char *JTEntryDirective = TAI->getData32bitsDirective();
// Pick the directive to use to print the jump table entries, and switch to
// the appropriate section.
if (TM.getRelocationModel() == Reloc::PIC_) {
- SwitchToTextSection(JumpTableTextSection, 0);
+ SwitchToTextSection(TAI->getJumpTableTextSection(), 0);
} else {
- SwitchToDataSection(JumpTableDataSection, 0);
+ SwitchToDataSection(TAI->getJumpTableDataSection(), 0);
if (TD->getPointerSize() == 8)
- JTEntryDirective = Data64bitsDirective;
+ JTEntryDirective = TAI->getData64bitsDirective();
}
EmitAlignment(Log2_32(TD->getPointerAlignment()));
// the number of relocations the assembler will generate for the jump table.
// Set directives are all printed before the jump table itself.
std::set<MachineBasicBlock*> EmittedSets;
- if (SetDirective && TM.getRelocationModel() == Reloc::PIC_)
+ if (TAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_)
for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii)
if (EmittedSets.insert(JTBBs[ii]).second)
printSetLabel(i, JTBBs[ii]);
- O << PrivateGlobalPrefix << "JTI" << getFunctionNumber() << '_' << i
- << ":\n";
+ O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
+ << '_' << i << ":\n";
for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) {
O << JTEntryDirective << ' ';
// If we're emitting non-PIC code, then emit the entries as direct
// references to the target basic blocks.
if (!EmittedSets.empty()) {
- O << PrivateGlobalPrefix << getFunctionNumber() << '_' << i << "_set_"
- << JTBBs[ii]->getNumber();
+ O << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
+ << '_' << i << "_set_" << JTBBs[ii]->getNumber();
} else if (TM.getRelocationModel() == Reloc::PIC_) {
printBasicBlockLabel(JTBBs[ii], false, false);
- O << '-' << PrivateGlobalPrefix << "JTI" << getFunctionNumber()
- << '_' << i;
+ O << '-' << TAI->getPrivateGlobalPrefix() << "JTI"
+ << getFunctionNumber() << '_' << i;
} else {
printBasicBlockLabel(JTBBs[ii], false, false);
}
return true; // No need to emit this at all.
if (GV->getName() == "llvm.global_ctors" && GV->use_empty()) {
- SwitchToDataSection(StaticCtorsSection, 0);
+ SwitchToDataSection(TAI->getStaticCtorsSection(), 0);
EmitAlignment(2, 0);
EmitXXStructorList(GV->getInitializer());
return true;
}
if (GV->getName() == "llvm.global_dtors" && GV->use_empty()) {
- SwitchToDataSection(StaticDtorsSection, 0);
+ SwitchToDataSection(TAI->getStaticDtorsSection(), 0);
EmitAlignment(2, 0);
EmitXXStructorList(GV->getInitializer());
return true;
if (GV && GV->getAlignment())
NumBits = Log2_32(GV->getAlignment());
if (NumBits == 0) return; // No need to emit alignment.
- if (AlignmentIsInBytes) NumBits = 1 << NumBits;
- O << AlignDirective << NumBits << "\n";
+ if (TAI->getAlignmentIsInBytes()) NumBits = 1 << NumBits;
+ O << TAI->getAlignDirective() << NumBits << "\n";
}
/// EmitZeros - Emit a block of zeros.
///
void AsmPrinter::EmitZeros(uint64_t NumZeros) const {
if (NumZeros) {
- if (ZeroDirective) {
- O << ZeroDirective << NumZeros;
- if (ZeroDirectiveSuffix)
- O << ZeroDirectiveSuffix;
+ if (TAI->getZeroDirective()) {
+ O << TAI->getZeroDirective() << NumZeros;
+ if (TAI->getZeroDirectiveSuffix())
+ O << TAI->getZeroDirectiveSuffix();
O << "\n";
} else {
for (; NumZeros; --NumZeros)
- O << Data8bitsDirective << "0\n";
+ O << TAI->getData8bitsDirective() << "0\n";
}
}
}
// name of the variable or function as the address value, possibly
// decorating it with GlobalVarAddrPrefix/Suffix or
// FunctionAddrPrefix/Suffix (these all default to "" )
- if (isa<Function>(GV))
- O << FunctionAddrPrefix << Mang->getValueName(GV) << FunctionAddrSuffix;
- else
- O << GlobalVarAddrPrefix << Mang->getValueName(GV) << GlobalVarAddrSuffix;
+ if (isa<Function>(GV)) {
+ O << TAI->getFunctionAddrPrefix()
+ << Mang->getValueName(GV)
+ << TAI->getFunctionAddrSuffix();
+ } else {
+ O << TAI->getGlobalVarAddrPrefix()
+ << Mang->getValueName(GV)
+ << TAI->getGlobalVarAddrSuffix();
+ }
} else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
const TargetData *TD = TM.getTargetData();
switch(CE->getOpcode()) {
///
void AsmPrinter::EmitString(const ConstantArray *CVA) const {
unsigned NumElts = CVA->getNumOperands();
- if (AscizDirective && NumElts &&
+ if (TAI->getAscizDirective() && NumElts &&
cast<ConstantInt>(CVA->getOperand(NumElts-1))->getRawValue() == 0) {
- O << AscizDirective;
+ O << TAI->getAscizDirective();
printAsCString(O, CVA, NumElts-1);
} else {
- O << AsciiDirective;
+ O << TAI->getAsciiDirective();
printAsCString(O, CVA, NumElts);
}
O << "\n";
// precision...
double Val = CFP->getValue();
if (CFP->getType() == Type::DoubleTy) {
- if (Data64bitsDirective)
- O << Data64bitsDirective << DoubleToBits(Val) << "\t" << CommentString
- << " double value: " << Val << "\n";
+ if (TAI->getData64bitsDirective())
+ O << TAI->getData64bitsDirective() << DoubleToBits(Val) << "\t"
+ << TAI->getCommentString() << " double value: " << Val << "\n";
else if (TD->isBigEndian()) {
- O << Data32bitsDirective << unsigned(DoubleToBits(Val) >> 32)
- << "\t" << CommentString << " double most significant word "
- << Val << "\n";
- O << Data32bitsDirective << unsigned(DoubleToBits(Val))
- << "\t" << CommentString << " double least significant word "
- << Val << "\n";
+ O << TAI->getData32bitsDirective() << unsigned(DoubleToBits(Val) >> 32)
+ << "\t" << TAI->getCommentString()
+ << " double most significant word " << Val << "\n";
+ O << TAI->getData32bitsDirective() << unsigned(DoubleToBits(Val))
+ << "\t" << TAI->getCommentString()
+ << " double least significant word " << Val << "\n";
} else {
- O << Data32bitsDirective << unsigned(DoubleToBits(Val))
- << "\t" << CommentString << " double least significant word " << Val
- << "\n";
- O << Data32bitsDirective << unsigned(DoubleToBits(Val) >> 32)
- << "\t" << CommentString << " double most significant word " << Val
- << "\n";
+ O << TAI->getData32bitsDirective() << unsigned(DoubleToBits(Val))
+ << "\t" << TAI->getCommentString()
+ << " double least significant word " << Val << "\n";
+ O << TAI->getData32bitsDirective() << unsigned(DoubleToBits(Val) >> 32)
+ << "\t" << TAI->getCommentString()
+ << " double most significant word " << Val << "\n";
}
return;
} else {
- O << Data32bitsDirective << FloatToBits(Val) << "\t" << CommentString
- << " float " << Val << "\n";
+ O << TAI->getData32bitsDirective() << FloatToBits(Val)
+ << "\t" << TAI->getCommentString() << " float " << Val << "\n";
return;
}
} else if (CV->getType() == Type::ULongTy || CV->getType() == Type::LongTy) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
uint64_t Val = CI->getRawValue();
- if (Data64bitsDirective)
- O << Data64bitsDirective << Val << "\n";
+ if (TAI->getData64bitsDirective())
+ O << TAI->getData64bitsDirective() << Val << "\n";
else if (TD->isBigEndian()) {
- O << Data32bitsDirective << unsigned(Val >> 32)
- << "\t" << CommentString << " Double-word most significant word "
- << Val << "\n";
- O << Data32bitsDirective << unsigned(Val)
- << "\t" << CommentString << " Double-word least significant word "
- << Val << "\n";
+ O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
+ << "\t" << TAI->getCommentString()
+ << " Double-word most significant word " << Val << "\n";
+ O << TAI->getData32bitsDirective() << unsigned(Val)
+ << "\t" << TAI->getCommentString()
+ << " Double-word least significant word " << Val << "\n";
} else {
- O << Data32bitsDirective << unsigned(Val)
- << "\t" << CommentString << " Double-word least significant word "
- << Val << "\n";
- O << Data32bitsDirective << unsigned(Val >> 32)
- << "\t" << CommentString << " Double-word most significant word "
- << Val << "\n";
+ O << TAI->getData32bitsDirective() << unsigned(Val)
+ << "\t" << TAI->getCommentString()
+ << " Double-word least significant word " << Val << "\n";
+ O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
+ << "\t" << TAI->getCommentString()
+ << " Double-word most significant word " << Val << "\n";
}
return;
}
switch (type->getTypeID()) {
case Type::BoolTyID:
case Type::UByteTyID: case Type::SByteTyID:
- O << Data8bitsDirective;
+ O << TAI->getData8bitsDirective();
break;
case Type::UShortTyID: case Type::ShortTyID:
- O << Data16bitsDirective;
+ O << TAI->getData16bitsDirective();
break;
case Type::PointerTyID:
if (TD->getPointerSize() == 8) {
- assert(Data64bitsDirective &&
+ assert(TAI->getData64bitsDirective() &&
"Target cannot handle 64-bit pointer exprs!");
- O << Data64bitsDirective;
+ O << TAI->getData64bitsDirective();
break;
}
//Fall through for pointer size == int size
case Type::UIntTyID: case Type::IntTyID:
- O << Data32bitsDirective;
+ O << TAI->getData32bitsDirective();
break;
case Type::ULongTyID: case Type::LongTyID:
- assert(Data64bitsDirective &&"Target cannot handle 64-bit constant exprs!");
- O << Data64bitsDirective;
+ assert(TAI->getData64bitsDirective() &&
+ "Target cannot handle 64-bit constant exprs!");
+ O << TAI->getData64bitsDirective();
break;
case Type::FloatTyID: case Type::DoubleTyID:
assert (0 && "Should have already output floating point constant.");
return;
}
- O << InlineAsmStart << "\n\t";
+ O << TAI->getInlineAsmStart() << "\n\t";
// The variant of the current asmprinter: FIXME: change.
int AsmPrinterVariant = 0;
break;
}
}
- O << "\n\t" << InlineAsmEnd << "\n";
+ O << "\n\t" << TAI->getInlineAsmEnd() << "\n";
}
/// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
void AsmPrinter::printBasicBlockLabel(const MachineBasicBlock *MBB,
bool printColon,
bool printComment) const {
- O << PrivateGlobalPrefix << "BB" << FunctionNumber << "_"
+ O << TAI->getPrivateGlobalPrefix() << "BB" << FunctionNumber << "_"
<< MBB->getNumber();
if (printColon)
O << ':';
if (printComment)
- O << '\t' << CommentString << MBB->getBasicBlock()->getName();
+ O << '\t' << TAI->getCommentString() << MBB->getBasicBlock()->getName();
}
/// printSetLabel - This method prints a set label for the specified
/// MachineBasicBlock
void AsmPrinter::printSetLabel(unsigned uid,
const MachineBasicBlock *MBB) const {
- if (!SetDirective)
+ if (!TAI->getSetDirective())
return;
- O << SetDirective << ' ' << PrivateGlobalPrefix << getFunctionNumber()
- << '_' << uid << "_set_" << MBB->getNumber() << ',';
+ O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix()
+ << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ',';
printBasicBlockLabel(MBB, false, false);
- O << '-' << PrivateGlobalPrefix << "JTI" << getFunctionNumber()
+ O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
<< '_' << uid << '\n';
}