//
//===----------------------------------------------------------------------===//
//
-// This class is intended to be used as a base class for target-specific
-// asmwriters. This class primarily takes care of printing global constants,
-// which are printed in a very similar way across all targets.
+// This file contains a class to be used as the base class for target specific
+// asm writers. This class primarily handles common functionality used by
+// all asm writers.
//
//===----------------------------------------------------------------------===//
namespace llvm {
class Constant;
class ConstantArray;
- class Mangler;
class GlobalVariable;
class MachineConstantPoolEntry;
+ class Mangler;
+ class TargetAsmInfo;
+
+ /// AsmPrinter - This class is intended to be used as a driving class for all
+ /// asm writers.
class AsmPrinter : public MachineFunctionPass {
/// FunctionNumber - This provides a unique ID for each function emitted in
/// this translation unit. It is autoincremented by SetupMachineFunction,
/// Target machine description.
///
TargetMachine &TM;
+
+ /// Target Asm Printer information.
+ ///
+ TargetAsmInfo *TAI;
/// Name-mangler for global names.
///
/// beginning of each call to runOnMachineFunction().
///
std::string CurrentFnName;
-
- //===------------------------------------------------------------------===//
- // Properties to be set by the derived class ctor, used to configure the
- // asmwriter.
-
- /// CommentString - This indicates the comment character used by the
- /// assembler.
- const char *CommentString; // Defaults to "#"
-
- /// GlobalPrefix - If this is set to a non-empty string, it is prepended
- /// onto all global symbols. This is often used for "_" or ".".
- const char *GlobalPrefix; // Defaults to ""
-
- /// PrivateGlobalPrefix - This prefix is used for globals like constant
- /// pool entries that are completely private to the .o file and should not
- /// have names in the .o file. This is often "." or "L".
- const char *PrivateGlobalPrefix; // Defaults to "."
-
- /// GlobalVarAddrPrefix/Suffix - If these are nonempty, these strings
- /// will enclose any GlobalVariable (that isn't a function)
- ///
- const char *GlobalVarAddrPrefix; // Defaults to ""
- const char *GlobalVarAddrSuffix; // Defaults to ""
-
- /// FunctionAddrPrefix/Suffix - If these are nonempty, these strings
- /// will enclose any GlobalVariable that points to a function.
- /// For example, this is used by the IA64 backend to materialize
- /// function descriptors, by decorating the ".data8" object with the
- /// \literal @fptr( ) \endliteral
- /// link-relocation operator.
- ///
- const char *FunctionAddrPrefix; // Defaults to ""
- const char *FunctionAddrSuffix; // Defaults to ""
-
- /// InlineAsmStart/End - If these are nonempty, they contain a directive to
- /// emit before and after an inline assmebly statement.
- const char *InlineAsmStart; // Defaults to "#APP\n"
- const char *InlineAsmEnd; // Defaults to "#NO_APP\n"
-
- //===--- Data Emission Directives -------------------------------------===//
-
- /// ZeroDirective - this should be set to the directive used to get some
- /// number of zero bytes emitted to the current section. Common cases are
- /// "\t.zero\t" and "\t.space\t". If this is set to null, the
- /// Data*bitsDirective's will be used to emit zero bytes.
- const char *ZeroDirective; // Defaults to "\t.zero\t"
- const char *ZeroDirectiveSuffix; // Defaults to ""
-
- /// AsciiDirective - This directive allows emission of an ascii string with
- /// the standard C escape characters embedded into it.
- const char *AsciiDirective; // Defaults to "\t.ascii\t"
-
- /// AscizDirective - If not null, this allows for special handling of
- /// zero terminated strings on this target. This is commonly supported as
- /// ".asciz". If a target doesn't support this, it can be set to null.
- const char *AscizDirective; // Defaults to "\t.asciz\t"
-
- /// DataDirectives - These directives are used to output some unit of
- /// integer data to the current section. If a data directive is set to
- /// null, smaller data directives will be used to emit the large sizes.
- const char *Data8bitsDirective; // Defaults to "\t.byte\t"
- const char *Data16bitsDirective; // Defaults to "\t.short\t"
- const char *Data32bitsDirective; // Defaults to "\t.long\t"
- const char *Data64bitsDirective; // Defaults to "\t.quad\t"
-
- //===--- Alignment Information ----------------------------------------===//
-
- /// AlignDirective - The directive used to emit round up to an alignment
- /// boundary.
- ///
- const char *AlignDirective; // Defaults to "\t.align\t"
-
- /// AlignmentIsInBytes - If this is true (the default) then the asmprinter
- /// emits ".align N" directives, where N is the number of bytes to align to.
- /// Otherwise, it emits ".align log2(N)", e.g. 3 to align to an 8 byte
- /// boundary.
- bool AlignmentIsInBytes; // Defaults to true
-
- //===--- Section Switching Directives ---------------------------------===//
/// CurrentSection - The current section we are emitting to. This is
/// controlled and used by the SwitchSection method.
std::string CurrentSection;
-
- /// SwitchToSectionDirective - This is the directive used when we want to
- /// emit a global to an arbitrary section. The section name is emited after
- /// this.
- const char *SwitchToSectionDirective; // Defaults to "\t.section\t"
-
- /// TextSectionStartSuffix - This is printed after each start of section
- /// directive for text sections.
- const char *TextSectionStartSuffix; // Defaults to "".
-
- /// DataSectionStartSuffix - This is printed after each start of section
- /// directive for data sections.
- const char *DataSectionStartSuffix; // Defaults to "".
-
- /// SectionEndDirectiveSuffix - If non-null, the asm printer will close each
- /// section with the section name and this suffix printed.
- const char *SectionEndDirectiveSuffix; // Defaults to null.
-
- /// ConstantPoolSection - This is the section that we SwitchToSection right
- /// before emitting the constant pool for a function.
- const char *ConstantPoolSection; // Defaults to "\t.section .rodata\n"
-
- /// JumpTableDataSection - This is the section that we SwitchToSection right
- /// before emitting the jump tables for a function when the relocation model
- /// is not PIC.
- const char *JumpTableDataSection; // Defaults to "\t.section .rodata\n"
-
- /// JumpTableTextSection - This is the section that we SwitchToSection right
- /// before emitting the jump tables for a function when the relocation model
- /// is PIC.
- const char *JumpTableTextSection; // Defaults to "\t.text\n"
-
- /// StaticCtorsSection - This is the directive that is emitted to switch to
- /// a section to emit the static constructor list.
- /// Defaults to "\t.section .ctors,\"aw\",@progbits".
- const char *StaticCtorsSection;
-
- /// StaticDtorsSection - This is the directive that is emitted to switch to
- /// a section to emit the static destructor list.
- /// Defaults to "\t.section .dtors,\"aw\",@progbits".
- const char *StaticDtorsSection;
-
- /// FourByteConstantSection, EightByteConstantSection,
- /// SixteenByteConstantSection - These are special sections where we place
- /// 4-, 8-, and 16- byte constant literals.
- const char *FourByteConstantSection;
- const char *EightByteConstantSection;
- const char *SixteenByteConstantSection;
-
- //===--- Global Variable Emission Directives --------------------------===//
-
- /// SetDirective - This is the name of a directive that can be used to tell
- /// the assembler to set the value of a variable to some expression.
- const char *SetDirective; // Defaults to null.
-
- /// LCOMMDirective - This is the name of a directive (if supported) that can
- /// be used to efficiently declare a local (internal) block of zero
- /// initialized data in the .bss/.data section. The syntax expected is:
- /// \literal <LCOMMDirective> SYMBOLNAME LENGTHINBYTES, ALIGNMENT
- /// \endliteral
- const char *LCOMMDirective; // Defaults to null.
-
- const char *COMMDirective; // Defaults to "\t.comm\t".
-
- /// COMMDirectiveTakesAlignment - True if COMMDirective take a third
- /// argument that specifies the alignment of the declaration.
- bool COMMDirectiveTakesAlignment; // Defaults to true.
-
- /// HasDotTypeDotSizeDirective - True if the target has .type and .size
- /// directives, this is true for most ELF targets.
- bool HasDotTypeDotSizeDirective; // Defaults to true.
protected:
- AsmPrinter(std::ostream &o, TargetMachine &TM);
+ AsmPrinter(std::ostream &o, TargetMachine &TM, TargetAsmInfo *T);
public:
/// SwitchToTextSection - Switch to the specified section of the executable
class MRegisterInfo;
class SubprogramDesc;
class SourceLineInfo;
+class TargetAsmInfo;
class TargetData;
class Type;
class TypeDesc;
// DwarfWriter - Emits Dwarf debug and exception handling directives.
//
class DwarfWriter {
-protected:
+
+private:
//===--------------------------------------------------------------------===//
// Core attributes used by the Dwarf writer.
///
AsmPrinter *Asm;
+ /// TAI - Target Asm Printer.
+ TargetAsmInfo *TAI;
+
/// TD - Target data.
const TargetData *TD;
/// SectionSourceLines - Tracks line numbers per text section.
///
std::vector<std::vector<SourceLineInfo *> > SectionSourceLines;
-
- //===--------------------------------------------------------------------===//
- // Properties to be set by the derived class ctor, used to configure the
- // Dwarf writer.
- //
-
- /// AddressSize - Size of addresses used in file.
- ///
- unsigned AddressSize;
- /// hasLEB128 - True if target asm supports leb128 directives.
- ///
- bool hasLEB128; /// Defaults to false.
-
- /// hasDotLoc - True if target asm supports .loc directives.
- ///
- bool hasDotLoc; /// Defaults to false.
-
- /// hasDotFile - True if target asm supports .file directives.
- ///
- bool hasDotFile; /// Defaults to false.
-
- /// needsSet - True if target asm can't compute addresses on data
- /// directives.
- bool needsSet; /// Defaults to false.
-
- /// DwarfAbbrevSection - Section directive for Dwarf abbrev.
- ///
- const char *DwarfAbbrevSection; /// Defaults to ".debug_abbrev".
-
- /// DwarfInfoSection - Section directive for Dwarf info.
- ///
- const char *DwarfInfoSection; /// Defaults to ".debug_info".
- /// DwarfLineSection - Section directive for Dwarf info.
- ///
- const char *DwarfLineSection; /// Defaults to ".debug_line".
-
- /// DwarfFrameSection - Section directive for Dwarf info.
- ///
- const char *DwarfFrameSection; /// Defaults to ".debug_frame".
-
- /// DwarfPubNamesSection - Section directive for Dwarf info.
- ///
- const char *DwarfPubNamesSection; /// Defaults to ".debug_pubnames".
-
- /// DwarfPubTypesSection - Section directive for Dwarf info.
- ///
- const char *DwarfPubTypesSection; /// Defaults to ".debug_pubtypes".
-
- /// DwarfStrSection - Section directive for Dwarf info.
- ///
- const char *DwarfStrSection; /// Defaults to ".debug_str".
-
- /// DwarfLocSection - Section directive for Dwarf info.
- ///
- const char *DwarfLocSection; /// Defaults to ".debug_loc".
-
- /// DwarfARangesSection - Section directive for Dwarf info.
- ///
- const char *DwarfARangesSection; /// Defaults to ".debug_aranges".
-
- /// DwarfRangesSection - Section directive for Dwarf info.
- ///
- const char *DwarfRangesSection; /// Defaults to ".debug_ranges".
-
- /// DwarfMacInfoSection - Section directive for Dwarf info.
- ///
- const char *DwarfMacInfoSection; /// Defaults to ".debug_macinfo".
-
- /// TextSection - Section directive for standard text.
- ///
- const char *TextSection; /// Defaults to ".text".
-
- /// DataSection - Section directive for standard data.
- ///
- const char *DataSection; /// Defaults to ".data".
+public:
//===--------------------------------------------------------------------===//
// Emission and print routines
//
-public:
- /// getAddressSize - Return the size of a target address in bytes.
- ///
- unsigned getAddressSize() const { return AddressSize; }
-
/// PrintHex - Print a value as a hexidecimal value.
///
void PrintHex(int Value) const;
public:
- DwarfWriter(std::ostream &OS, AsmPrinter *A);
+ DwarfWriter(std::ostream &OS, AsmPrinter *A, TargetAsmInfo *T);
virtual ~DwarfWriter();
+ // Accessors.
+ //
+ TargetAsmInfo *getTargetAsmInfo() const { return TAI; }
+
/// SetDebugInfo - Set DebugInfo when it's known that pass manager has
/// created it. Set by the target AsmPrinter.
void SetDebugInfo(MachineDebugInfo *DI);
#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';
}
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Mangler.h"
+#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/MRegisterInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
/// SizeOf - Determine size of label value in bytes.
///
unsigned DIEDwarfLabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
- return DW.getAddressSize();
+ return DW.getTargetAsmInfo()->getAddressSize();
}
//===----------------------------------------------------------------------===//
/// SizeOf - Determine size of label value in bytes.
///
unsigned DIEObjectLabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
- return DW.getAddressSize();
+ return DW.getTargetAsmInfo()->getAddressSize();
}
//===----------------------------------------------------------------------===//
/// SizeOf - Determine size of delta value in bytes.
///
unsigned DIEDelta::SizeOf(const DwarfWriter &DW, unsigned Form) const {
- return DW.getAddressSize();
+ return DW.getTargetAsmInfo()->getAddressSize();
}
//===----------------------------------------------------------------------===//
void DwarfWriter::EOL(const std::string &Comment) const {
if (DwarfVerbose && !Comment.empty()) {
O << "\t"
- << Asm->CommentString
+ << TAI->getCommentString()
<< " "
<< Comment;
}
/// EmitAlign - Print a align directive.
///
void DwarfWriter::EmitAlign(unsigned Alignment) const {
- O << Asm->AlignDirective << Alignment << "\n";
+ O << TAI->getAlignDirective() << Alignment << "\n";
}
/// EmitULEB128Bytes - Emit an assembler byte data directive to compose an
/// unsigned leb128 value.
void DwarfWriter::EmitULEB128Bytes(unsigned Value) const {
- if (hasLEB128) {
+ if (TAI->hasLEB128()) {
O << "\t.uleb128\t"
<< Value;
} else {
- O << Asm->Data8bitsDirective;
+ O << TAI->getData8bitsDirective();
PrintULEB128(Value);
}
}
/// EmitSLEB128Bytes - Emit an assembler byte data directive to compose a
/// signed leb128 value.
void DwarfWriter::EmitSLEB128Bytes(int Value) const {
- if (hasLEB128) {
+ if (TAI->hasLEB128()) {
O << "\t.sleb128\t"
<< Value;
} else {
- O << Asm->Data8bitsDirective;
+ O << TAI->getData8bitsDirective();
PrintSLEB128(Value);
}
}
/// EmitInt8 - Emit a byte directive and value.
///
void DwarfWriter::EmitInt8(int Value) const {
- O << Asm->Data8bitsDirective;
+ O << TAI->getData8bitsDirective();
PrintHex(Value & 0xFF);
}
/// EmitInt16 - Emit a short directive and value.
///
void DwarfWriter::EmitInt16(int Value) const {
- O << Asm->Data16bitsDirective;
+ O << TAI->getData16bitsDirective();
PrintHex(Value & 0xFFFF);
}
/// EmitInt32 - Emit a long directive and value.
///
void DwarfWriter::EmitInt32(int Value) const {
- O << Asm->Data32bitsDirective;
+ O << TAI->getData32bitsDirective();
PrintHex(Value);
}
/// EmitInt64 - Emit a long long directive and value.
///
void DwarfWriter::EmitInt64(uint64_t Value) const {
- if (Asm->Data64bitsDirective) {
- O << Asm->Data64bitsDirective << "0x" << std::hex << Value << std::dec;
+ if (TAI->getData64bitsDirective()) {
+ O << TAI->getData64bitsDirective() << "0x" << std::hex << Value << std::dec;
} else {
if (TD->isBigEndian()) {
EmitInt32(unsigned(Value >> 32)); O << "\n";
/// EmitString - Emit a string with quotes and a null terminator.
/// Special characters are emitted properly. (Eg. '\t')
void DwarfWriter::EmitString(const std::string &String) const {
- O << Asm->AsciiDirective
+ O << TAI->getAsciiDirective()
<< "\"";
for (unsigned i = 0, N = String.size(); i < N; ++i) {
unsigned char C = String[i];
/// PrintLabelName - Print label name in form used by Dwarf writer.
///
void DwarfWriter::PrintLabelName(const char *Tag, unsigned Number) const {
- O << Asm->PrivateGlobalPrefix
+ O << TAI->getPrivateGlobalPrefix()
<< "debug_"
<< Tag;
if (Number) O << Number;
/// EmitReference - Emit a reference to a label.
///
void DwarfWriter::EmitReference(const char *Tag, unsigned Number) const {
- if (AddressSize == 4)
- O << Asm->Data32bitsDirective;
+ if (TAI->getAddressSize() == 4)
+ O << TAI->getData32bitsDirective();
else
- O << Asm->Data64bitsDirective;
+ O << TAI->getData64bitsDirective();
PrintLabelName(Tag, Number);
}
void DwarfWriter::EmitReference(const std::string &Name) const {
- if (AddressSize == 4)
- O << Asm->Data32bitsDirective;
+ if (TAI->getAddressSize() == 4)
+ O << TAI->getData32bitsDirective();
else
- O << Asm->Data64bitsDirective;
+ O << TAI->getData64bitsDirective();
O << Name;
}
/// is an option (needsSet) to use an intermediary 'set' expression.
void DwarfWriter::EmitDifference(const char *TagHi, unsigned NumberHi,
const char *TagLo, unsigned NumberLo) const {
- if (needsSet) {
+ if (TAI->getNeedsSet()) {
static unsigned SetCounter = 0;
O << "\t.set\t";
PrintLabelName(TagLo, NumberLo);
O << "\n";
- if (AddressSize == sizeof(int32_t))
- O << Asm->Data32bitsDirective;
+ if (TAI->getAddressSize() == sizeof(int32_t))
+ O << TAI->getData32bitsDirective();
else
- O << Asm->Data64bitsDirective;
+ O << TAI->getData64bitsDirective();
PrintLabelName("set", SetCounter);
++SetCounter;
} else {
- if (AddressSize == sizeof(int32_t))
- O << Asm->Data32bitsDirective;
+ if (TAI->getAddressSize() == sizeof(int32_t))
+ O << TAI->getData32bitsDirective();
else
- O << Asm->Data64bitsDirective;
+ O << TAI->getData64bitsDirective();
PrintLabelName(TagHi, NumberHi);
O << "-";
didInitial = true;
// Dwarf sections base addresses.
- Asm->SwitchToDataSection(DwarfFrameSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfFrameSection(), 0);
EmitLabel("section_frame", 0);
- Asm->SwitchToDataSection(DwarfInfoSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfInfoSection(), 0);
EmitLabel("section_info", 0);
EmitLabel("info", 0);
- Asm->SwitchToDataSection(DwarfAbbrevSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfAbbrevSection(), 0);
EmitLabel("section_abbrev", 0);
EmitLabel("abbrev", 0);
- Asm->SwitchToDataSection(DwarfARangesSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfARangesSection(), 0);
EmitLabel("section_aranges", 0);
- Asm->SwitchToDataSection(DwarfMacInfoSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection(), 0);
EmitLabel("section_macinfo", 0);
- Asm->SwitchToDataSection(DwarfLineSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfLineSection(), 0);
EmitLabel("section_line", 0);
EmitLabel("line", 0);
- Asm->SwitchToDataSection(DwarfLocSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfLocSection(), 0);
EmitLabel("section_loc", 0);
- Asm->SwitchToDataSection(DwarfPubNamesSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfPubNamesSection(), 0);
EmitLabel("section_pubnames", 0);
- Asm->SwitchToDataSection(DwarfStrSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfStrSection(), 0);
EmitLabel("section_str", 0);
- Asm->SwitchToDataSection(DwarfRangesSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfRangesSection(), 0);
EmitLabel("section_ranges", 0);
- Asm->SwitchToTextSection(TextSection, 0);
+ Asm->SwitchToTextSection(TAI->getTextSection(), 0);
EmitLabel("text_begin", 0);
- Asm->SwitchToDataSection(DataSection, 0);
+ Asm->SwitchToDataSection(TAI->getDataSection(), 0);
EmitLabel("data_begin", 0);
// Emit common frame information.
int stackGrowth =
Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
TargetFrameInfo::StackGrowsUp ?
- AddressSize : -AddressSize;
+ TAI->getAddressSize() : -TAI->getAddressSize();
// If advancing cfa.
if (Dst.isRegister() && Dst.getRegister() == MachineLocation::VirtualFP) {
///
void DwarfWriter::EmitDebugInfo() const {
// Start debug info section.
- Asm->SwitchToDataSection(DwarfInfoSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfInfoSection(), 0);
// Process each compile unit.
for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) {
EmitInt16(DWARF_VERSION); EOL("DWARF version number");
EmitDifference("abbrev_begin", 0, "section_abbrev", 0);
EOL("Offset Into Abbrev. Section");
- EmitInt8(AddressSize); EOL("Address Size (in bytes)");
+ EmitInt8(TAI->getAddressSize()); EOL("Address Size (in bytes)");
EmitDIE(Die);
EmitLabel("info_end", Unit->getID());
// Check to see if it is worth the effort.
if (!Abbreviations.empty()) {
// Start the debug abbrev section.
- Asm->SwitchToDataSection(DwarfAbbrevSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfAbbrevSection(), 0);
EmitLabel("abbrev_begin", 0);
const int MaxLineDelta = 255 + MinLineDelta;
// Start the dwarf line section.
- Asm->SwitchToDataSection(DwarfLineSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfLineSection(), 0);
// Construct the section header.
if (DwarfVerbose) {
O << "\t"
- << Asm->CommentString << " "
+ << TAI->getCommentString() << " "
<< "Section "
<< SectionMap[j + 1].c_str() << "\n";
}
const SourceFileInfo &SourceFile = SourceFiles[SourceID];
unsigned DirectoryID = SourceFile.getDirectoryID();
O << "\t"
- << Asm->CommentString << " "
+ << TAI->getCommentString() << " "
<< Directories[DirectoryID]
<< SourceFile.getName() << ":"
<< LineInfo->getLine() << "\n";
int stackGrowth =
Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
TargetFrameInfo::StackGrowsUp ?
- AddressSize : -AddressSize;
+ TAI->getAddressSize() : -TAI->getAddressSize();
// Start the dwarf frame section.
- Asm->SwitchToDataSection(DwarfFrameSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfFrameSection(), 0);
EmitLabel("frame_common", 0);
EmitDifference("frame_common_end", 0,
/// section.
void DwarfWriter::EmitFunctionDebugFrame() {
// Start the dwarf frame section.
- Asm->SwitchToDataSection(DwarfFrameSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfFrameSection(), 0);
EmitDifference("frame_end", SubprogramCount,
"frame_begin", SubprogramCount);
///
void DwarfWriter::EmitDebugPubNames() {
// Start the dwarf pubnames section.
- Asm->SwitchToDataSection(DwarfPubNamesSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfPubNamesSection(), 0);
// Process each compile unit.
for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) {
// Check to see if it is worth the effort.
if (!StringPool.empty()) {
// Start the dwarf str section.
- Asm->SwitchToDataSection(DwarfStrSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfStrSection(), 0);
// For each of strings in the string pool.
for (unsigned StringID = 1, N = StringPool.size();
///
void DwarfWriter::EmitDebugLoc() {
// Start the dwarf loc section.
- Asm->SwitchToDataSection(DwarfLocSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfLocSection(), 0);
O << "\n";
}
///
void DwarfWriter::EmitDebugARanges() {
// Start the dwarf aranges section.
- Asm->SwitchToDataSection(DwarfARangesSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfARangesSection(), 0);
// FIXME - Mock up
#if 0
EmitReference("info_begin", Unit->getID());
EOL("Offset of Compilation Unit Info");
- EmitInt8(AddressSize); EOL("Size of Address");
+ EmitInt8(TAI->getAddressSize()); EOL("Size of Address");
EmitInt8(0); EOL("Size of Segment Descriptor");
///
void DwarfWriter::EmitDebugRanges() {
// Start the dwarf ranges section.
- Asm->SwitchToDataSection(DwarfRangesSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfRangesSection(), 0);
O << "\n";
}
///
void DwarfWriter::EmitDebugMacInfo() {
// Start the dwarf macinfo section.
- Asm->SwitchToDataSection(DwarfMacInfoSection, 0);
+ Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection(), 0);
O << "\n";
}
// Main entry points.
//
-DwarfWriter::DwarfWriter(std::ostream &OS, AsmPrinter *A)
+DwarfWriter::DwarfWriter(std::ostream &OS, AsmPrinter *A, TargetAsmInfo *T)
: O(OS)
, Asm(A)
+, TAI(T)
, TD(Asm->TM.getTargetData())
, RI(Asm->TM.getRegisterInfo())
, M(NULL)
, DescToDieMap()
, SectionMap()
, SectionSourceLines()
-, AddressSize(sizeof(int32_t))
-, hasLEB128(false)
-, hasDotLoc(false)
-, hasDotFile(false)
-, needsSet(false)
-, DwarfAbbrevSection(".debug_abbrev")
-, DwarfInfoSection(".debug_info")
-, DwarfLineSection(".debug_line")
-, DwarfFrameSection(".debug_frame")
-, DwarfPubNamesSection(".debug_pubnames")
-, DwarfPubTypesSection(".debug_pubtypes")
-, DwarfStrSection(".debug_str")
-, DwarfLocSection(".debug_loc")
-, DwarfARangesSection(".debug_aranges")
-, DwarfRangesSection(".debug_ranges")
-, DwarfMacInfoSection(".debug_macinfo")
-, TextSection(".text")
-, DataSection(".data")
{}
DwarfWriter::~DwarfWriter() {
for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) {
ConstructSubprogramDIEs();
// Prime section data.
- SectionMap.insert(std::string("\t") + TextSection);
+ SectionMap.insert(std::string("\t") + TAI->getTextSection());
}
}
EOL("Dwarf End Module");
// Standard sections final addresses.
- Asm->SwitchToTextSection(TextSection, 0);
+ Asm->SwitchToTextSection(TAI->getTextSection(), 0);
EmitLabel("text_end", 0);
- Asm->SwitchToDataSection(DataSection, 0);
+ Asm->SwitchToDataSection(TAI->getDataSection(), 0);
EmitLabel("data_end", 0);
// End text sections.
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Mangler.h"
namespace {
Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
- struct ARMAsmPrinter : public AsmPrinter {
- ARMAsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) {
+ struct VISIBILITY_HIDDEN ARMTargetAsmInfo : public TargetAsmInfo {
+ ARMTargetAsmInfo() {
Data16bitsDirective = "\t.half\t";
Data32bitsDirective = "\t.word\t";
Data64bitsDirective = 0;
ConstantPoolSection = "\t.text\n";
AlignmentIsInBytes = false;
}
+ };
+
+ struct VISIBILITY_HIDDEN ARMAsmPrinter : public AsmPrinter {
+ ARMAsmPrinter(std::ostream &O, TargetMachine &TM, TargetAsmInfo *T)
+ : AsmPrinter(O, TM, T) {
+ }
/// We name each basic block in a Function with a unique number, so
/// that we can consistently refer to them later. This is cleared
///
FunctionPass *llvm::createARMCodePrinterPass(std::ostream &o,
TargetMachine &tm) {
- return new ARMAsmPrinter(o, tm);
+ ARMTargetAsmInfo *TAI = new ARMTargetAsmInfo();
+ return new ARMAsmPrinter(o, tm, TAI);
}
/// runOnMachineFunction - This uses the printMachineInstruction()
abort();
break;
case MachineOperand::MO_ConstantPoolIndex:
- O << PrivateGlobalPrefix << "CPI" << getFunctionNumber()
+ O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
<< '_' << MO.getConstantPoolIndex();
break;
default:
#include "llvm/Type.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Mangler.h"
#include "llvm/ADT/Statistic.h"
namespace {
Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
+
+ struct VISIBILITY_HIDDEN AlphaTargetAsmInfo : public TargetAsmInfo {
+ AlphaTargetAsmInfo() {
+ AlignmentIsInBytes = false;
+ PrivateGlobalPrefix = "$";
+ }
+ };
- struct AlphaAsmPrinter : public AsmPrinter {
+ struct VISIBILITY_HIDDEN AlphaAsmPrinter : public AsmPrinter {
/// Unique incrementer for label values for referencing Global values.
///
unsigned LabelNumber;
- AlphaAsmPrinter(std::ostream &o, TargetMachine &tm)
- : AsmPrinter(o, tm), LabelNumber(0) {
- AlignmentIsInBytes = false;
- PrivateGlobalPrefix = "$";
+ AlphaAsmPrinter(std::ostream &o, TargetMachine &tm, TargetAsmInfo *T)
+ : AsmPrinter(o, tm, T), LabelNumber(0) {
}
/// We name each basic block in a Function with a unique number, so
///
FunctionPass *llvm::createAlphaCodePrinterPass (std::ostream &o,
TargetMachine &tm) {
- return new AlphaAsmPrinter(o, tm);
+ AlphaTargetAsmInfo *TAI = new AlphaTargetAsmInfo();
+ return new AlphaAsmPrinter(o, tm, TAI);
}
#include "AlphaGenAsmWriter.inc"
return;
case MachineOperand::MO_ConstantPoolIndex:
- O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_"
+ O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
<< MO.getConstantPoolIndex();
return;
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Support/Mangler.h"
#include "llvm/ADT/Statistic.h"
#include <iostream>
namespace {
Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
- struct IA64AsmPrinter : public AsmPrinter {
- std::set<std::string> ExternalFunctionNames, ExternalObjectNames;
-
- IA64AsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) {
+ struct VISIBILITY_HIDDEN IA64TargetAsmInfo : public TargetAsmInfo {
+ IA64TargetAsmInfo() {
CommentString = "//";
Data8bitsDirective = "\tdata1\t"; // FIXME: check that we are
Data16bitsDirective = "\tdata2.ua\t"; // disabling auto-alignment
// FIXME: would be nice to have rodata (no 'w') when appropriate?
ConstantPoolSection = "\n\t.section .data, \"aw\", \"progbits\"\n";
}
+ };
+
+ struct IA64AsmPrinter : public AsmPrinter {
+ std::set<std::string> ExternalFunctionNames, ExternalObjectNames;
+
+ IA64AsmPrinter(std::ostream &O, TargetMachine &TM, TargetAsmInfo *T)
+ : AsmPrinter(O, TM, T) {
+ }
virtual const char *getPassName() const {
return "IA64 Assembly Printer";
printBasicBlockLabel(MO.getMachineBasicBlock());
return;
case MachineOperand::MO_ConstantPoolIndex: {
- O << "@gprel(" << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_"
+ O << "@gprel(" << TAI->getPrivateGlobalPrefix()
+ << "CPI" << getFunctionNumber() << "_"
<< MO.getConstantPoolIndex() << ")";
return;
}
///
FunctionPass *llvm::createIA64CodePrinterPass(std::ostream &o,
IA64TargetMachine &tm) {
- return new IA64AsmPrinter(o, tm);
+ IA64TargetAsmInfo *TAI = new IA64TargetAsmInfo();
+ return new IA64AsmPrinter(o, tm, TAI);
}
FunctionPass *createPPCBranchSelectionPass();
FunctionPass *createPPCISelDag(PPCTargetMachine &TM);
-FunctionPass *createDarwinAsmPrinter(std::ostream &OS, PPCTargetMachine &TM);
+FunctionPass *createDarwinCodePrinterPass(std::ostream &OS,
+ PPCTargetMachine &TM);
FunctionPass *createPPCCodeEmitterPass(PPCTargetMachine &TM,
MachineCodeEmitter &MCE);
void addPPCMachOObjectWriterPass(FunctionPassManager &FPM, std::ostream &o,
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/MRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetOptions.h"
namespace {
Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
- class VISIBILITY_HIDDEN PPCAsmPrinter : public AsmPrinter {
- public:
+ struct VISIBILITY_HIDDEN PPCAsmPrinter : public AsmPrinter {
std::set<std::string> FnStubs, GVStubs;
- PPCAsmPrinter(std::ostream &O, TargetMachine &TM)
- : AsmPrinter(O, TM) {}
+ PPCAsmPrinter(std::ostream &O, TargetMachine &TM, TargetAsmInfo *T)
+ : AsmPrinter(O, TM, T) {}
virtual const char *getPassName() const {
return "PowerPC Assembly Printer";
}
}
if (MO.getType() == MachineOperand::MO_ExternalSymbol) {
- std::string Name(GlobalPrefix); Name += MO.getSymbolName();
+ std::string Name(TAI->getGlobalPrefix()); Name += MO.getSymbolName();
FnStubs.insert(Name);
O << "L" << Name << "$stub";
return;
};
- /// DarwinDwarfWriter - Dwarf debug info writer customized for Darwin/Mac OS X
- ///
- struct VISIBILITY_HIDDEN DarwinDwarfWriter : public DwarfWriter {
- // Ctor.
- DarwinDwarfWriter(std::ostream &o, AsmPrinter *ap)
- : DwarfWriter(o, ap)
- {
- needsSet = true;
+ struct VISIBILITY_HIDDEN DarwinTargetAsmInfo : public TargetAsmInfo {
+ DarwinTargetAsmInfo(PPCTargetMachine &TM) {
+ bool isPPC64 = TM.getSubtargetImpl()->isPPC64();
+
+ CommentString = ";";
+ GlobalPrefix = "_";
+ PrivateGlobalPrefix = "L";
+ ZeroDirective = "\t.space\t";
+ SetDirective = "\t.set";
+ Data64bitsDirective = isPPC64 ? ".quad\t" : 0;
+ AlignmentIsInBytes = false;
+ ConstantPoolSection = "\t.const\t";
+ JumpTableDataSection = ".const";
+ JumpTableTextSection = "\t.text";
+ LCOMMDirective = "\t.lcomm\t";
+ StaticCtorsSection = ".mod_init_func";
+ StaticDtorsSection = ".mod_term_func";
+ InlineAsmStart = "# InlineAsm Start";
+ InlineAsmEnd = "# InlineAsm End";
+
+ NeedsSet = true;
+ AddressSize = isPPC64 ? 8 : 4;
DwarfAbbrevSection = ".section __DWARF,__debug_abbrev";
DwarfInfoSection = ".section __DWARF,__debug_info";
DwarfLineSection = ".section __DWARF,__debug_line";
DwarfARangesSection = ".section __DWARF,__debug_aranges";
DwarfRangesSection = ".section __DWARF,__debug_ranges";
DwarfMacInfoSection = ".section __DWARF,__debug_macinfo";
- TextSection = ".text";
- DataSection = ".data";
}
};
/// X
struct VISIBILITY_HIDDEN DarwinAsmPrinter : public PPCAsmPrinter {
- DarwinDwarfWriter DW;
+ DwarfWriter DW;
- DarwinAsmPrinter(std::ostream &O, PPCTargetMachine &TM)
- : PPCAsmPrinter(O, TM), DW(O, this) {
+ DarwinAsmPrinter(std::ostream &O, PPCTargetMachine &TM, TargetAsmInfo *T)
+ : PPCAsmPrinter(O, TM, T), DW(O, this, T) {
bool isPPC64 = TM.getSubtargetImpl()->isPPC64();
- CommentString = ";";
- GlobalPrefix = "_";
- PrivateGlobalPrefix = "L"; // Marker for constant pool idxs
- ZeroDirective = "\t.space\t"; // ".space N" emits N zeros.
- SetDirective = "\t.set";
- if (isPPC64)
- Data64bitsDirective = ".quad\t"; // we can't emit a 64-bit unit
- else
- Data64bitsDirective = 0; // we can't emit a 64-bit unit
- AlignmentIsInBytes = false; // Alignment is by power of 2.
- ConstantPoolSection = "\t.const\t";
- JumpTableDataSection = ".const";
- JumpTableTextSection = "\t.text";
- LCOMMDirective = "\t.lcomm\t";
- StaticCtorsSection = ".mod_init_func";
- StaticDtorsSection = ".mod_term_func";
- InlineAsmStart = "# InlineAsm Start";
- InlineAsmEnd = "# InlineAsm End";
}
virtual const char *getPassName() const {
};
} // end of anonymous namespace
-/// createDarwinAsmPrinterPass - Returns a pass that prints the PPC assembly
+/// createDarwinCodePrinterPass - Returns a pass that prints the PPC assembly
/// code for a MachineFunction to the given output stream, in a format that the
/// Darwin assembler can deal with.
///
-FunctionPass *llvm::createDarwinAsmPrinter(std::ostream &o,
- PPCTargetMachine &tm) {
- return new DarwinAsmPrinter(o, tm);
+FunctionPass *llvm::createDarwinCodePrinterPass(std::ostream &o,
+ PPCTargetMachine &tm) {
+ TargetAsmInfo *TAI = new DarwinTargetAsmInfo(tm);
+ return new DarwinAsmPrinter(o, tm, TAI);
}
// Include the auto-generated portion of the assembly writer
printBasicBlockLabel(MO.getMachineBasicBlock());
return;
case MachineOperand::MO_JumpTableIndex:
- O << PrivateGlobalPrefix << "JTI" << getFunctionNumber()
+ O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
<< '_' << MO.getJumpTableIndex();
// FIXME: PIC relocation model
return;
case MachineOperand::MO_ConstantPoolIndex:
- O << PrivateGlobalPrefix << "CPI" << getFunctionNumber()
+ O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
<< '_' << MO.getConstantPoolIndex();
return;
case MachineOperand::MO_ExternalSymbol:
// Computing the address of an external symbol, not calling it.
if (TM.getRelocationModel() != Reloc::Static) {
- std::string Name(GlobalPrefix); Name += MO.getSymbolName();
+ std::string Name(TAI->getGlobalPrefix()); Name += MO.getSymbolName();
GVStubs.insert(Name);
O << "L" << Name << "$non_lazy_ptr";
return;
}
- O << GlobalPrefix << MO.getSymbolName();
+ O << TAI->getGlobalPrefix() << MO.getSymbolName();
return;
case MachineOperand::MO_GlobalAddress: {
// Computing the address of a global symbol, not calling it.
<< Size << ", " << Align;
} else if (I->hasInternalLinkage()) {
SwitchToDataSection("\t.data", I);
- O << LCOMMDirective << name << "," << Size << "," << Align;
+ O << TAI->getLCOMMDirective() << name << "," << Size << "," << Align;
} else {
SwitchToDataSection("\t.data", I);
O << ".comm " << name << "," << Size;
bool PPCTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
std::ostream &Out) {
- PM.add(createDarwinAsmPrinter(Out, *this));
+ PM.add(createDarwinCodePrinterPass(Out, *this));
return false;
}
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Mangler.h"
namespace {
Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
- struct SparcAsmPrinter : public AsmPrinter {
- SparcAsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) {
+ struct VISIBILITY_HIDDEN SparcTargetAsmInfo : public TargetAsmInfo {
+ SparcTargetAsmInfo() {
Data16bitsDirective = "\t.half\t";
Data32bitsDirective = "\t.word\t";
Data64bitsDirective = 0; // .xword is only supported by V9.
CommentString = "!";
ConstantPoolSection = "\t.section \".rodata\",#alloc\n";
}
+ };
+
+ struct VISIBILITY_HIDDEN SparcAsmPrinter : public AsmPrinter {
+ SparcAsmPrinter(std::ostream &O, TargetMachine &TM, TargetAsmInfo *T)
+ : AsmPrinter(O, TM, T) {
+ }
/// We name each basic block in a Function with a unique number, so
/// that we can consistently refer to them later. This is cleared
///
FunctionPass *llvm::createSparcCodePrinterPass(std::ostream &o,
TargetMachine &tm) {
- return new SparcAsmPrinter(o, tm);
+ SparcTargetAsmInfo *TAI = new SparcTargetAsmInfo();
+ return new SparcAsmPrinter(o, tm, TAI);
}
/// runOnMachineFunction - This uses the printMachineInstruction()
O << MO.getSymbolName();
break;
case MachineOperand::MO_ConstantPoolIndex:
- O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_"
+ O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
<< MO.getConstantPoolIndex();
break;
default:
switch (F->getLinkage()) {
default: assert(0 && "Unknown linkage type!");
case Function::InternalLinkage: // Symbols default to internal.
- SwitchToTextSection(DefaultTextSection, F);
+ SwitchToTextSection(TAI->getTextSection(), F);
EmitAlignment(4, F); // FIXME: This should be parameterized somewhere.
break;
case Function::ExternalLinkage:
- SwitchToTextSection(DefaultTextSection, F);
+ SwitchToTextSection(TAI->getTextSection(), F);
EmitAlignment(4, F); // FIXME: This should be parameterized somewhere.
O << "\t.globl\t" << CurrentFnName << "\n";
break;
// lables that are used in jump table expressions (e.g. LBB1_1-LJT1_0).
EmitJumpTableInfo(MF.getJumpTableInfo());
- if (HasDotTypeDotSizeDirective)
+ if (TAI->hasDotTypeDotSizeDirective())
O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n";
if (Subtarget->isTargetDarwin()) {
case MachineOperand::MO_JumpTableIndex: {
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
if (!isMemOp) O << '$';
- O << PrivateGlobalPrefix << "JTI" << getFunctionNumber() << "_"
+ O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << "_"
<< MO.getJumpTableIndex();
if (Subtarget->isTargetDarwin() &&
TM.getRelocationModel() == Reloc::PIC_)
case MachineOperand::MO_ConstantPoolIndex: {
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
if (!isMemOp) O << '$';
- O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_"
+ O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
<< MO.getConstantPoolIndex();
if (Subtarget->isTargetDarwin() &&
TM.getRelocationModel() == Reloc::PIC_)
if (isCallOp &&
Subtarget->isTargetDarwin() &&
TM.getRelocationModel() != Reloc::Static) {
- std::string Name(GlobalPrefix);
+ std::string Name(TAI->getGlobalPrefix());
Name += MO.getSymbolName();
FnStubs.insert(Name);
O << "L" << Name << "$stub";
return;
}
if (!isCallOp) O << '$';
- O << GlobalPrefix << MO.getSymbolName();
+ O << TAI->getGlobalPrefix() << MO.getSymbolName();
return;
}
default:
Reg1 = getX86SubSuperRegister(Reg1, MVT::i16);
else
Reg1 = getX86SubSuperRegister(Reg1, MVT::i8);
- O << CommentString << " TRUNCATE ";
+ O << TAI->getCommentString() << " TRUNCATE ";
if (Reg0 != Reg1)
O << "\n\t";
break;
namespace llvm {
struct X86ATTAsmPrinter : public X86SharedAsmPrinter {
- X86ATTAsmPrinter(std::ostream &O, X86TargetMachine &TM)
- : X86SharedAsmPrinter(O, TM) { }
+ X86ATTAsmPrinter(std::ostream &O, X86TargetMachine &TM, TargetAsmInfo *T)
+ : X86SharedAsmPrinter(O, TM, T) { }
virtual const char *getPassName() const {
return "X86 AT&T-Style Assembly Printer";
#include "llvm/Support/CommandLine.h"
using namespace llvm;
+enum AsmWriterFlavorTy { att, intel };
+
Statistic<> llvm::EmittedInsts("asm-printer",
"Number of machine instrs printed");
-enum AsmWriterFlavorTy { att, intel };
cl::opt<AsmWriterFlavorTy>
AsmWriterFlavor("x86-asm-syntax",
cl::desc("Choose style of code to emit from X86 backend:"),
#endif
);
-// Out of line virtual function to home classes.
-void X86DwarfWriter::virtfn() {}
-
-
-/// doInitialization
-bool X86SharedAsmPrinter::doInitialization(Module &M) {
- PrivateGlobalPrefix = ".L";
- DefaultTextSection = ".text";
- DefaultDataSection = ".data";
+X86TargetAsmInfo::X86TargetAsmInfo(X86TargetMachine &TM) {
+ const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();
+ //FIXME - Should to be simplified.
+
switch (Subtarget->TargetType) {
case X86Subtarget::isDarwin:
AlignmentIsInBytes = false;
InlineAsmStart = "# InlineAsm Start";
InlineAsmEnd = "# InlineAsm End";
SetDirective = "\t.set";
+
+ NeedsSet = true;
+ DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug";
+ DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug";
+ DwarfLineSection = ".section __DWARF,__debug_line,regular,debug";
+ DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug";
+ DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug";
+ DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug";
+ DwarfStrSection = ".section __DWARF,__debug_str,regular,debug";
+ DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug";
+ DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug";
+ DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug";
+ DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug";
break;
case X86Subtarget::isCygwin:
GlobalPrefix = "_";
default: break;
}
+ if (AsmWriterFlavor == intel) {
+ GlobalPrefix = "_";
+ CommentString = ";";
+
+ PrivateGlobalPrefix = "$";
+ AlignDirective = "\talign\t";
+ ZeroDirective = "\tdb\t";
+ ZeroDirectiveSuffix = " dup(0)";
+ AsciiDirective = "\tdb\t";
+ AscizDirective = 0;
+ Data8bitsDirective = "\tdb\t";
+ Data16bitsDirective = "\tdw\t";
+ Data32bitsDirective = "\tdd\t";
+ Data64bitsDirective = "\tdq\t";
+ HasDotTypeDotSizeDirective = false;
+
+ TextSection = "_text";
+ DataSection = "_data";
+ SwitchToSectionDirective = "";
+ TextSectionStartSuffix = "\tsegment 'CODE'";
+ DataSectionStartSuffix = "\tsegment 'DATA'";
+ SectionEndDirectiveSuffix = "\tends\n";
+ }
+}
+
+/// doInitialization
+bool X86SharedAsmPrinter::doInitialization(Module &M) {
if (Subtarget->isTargetDarwin()) {
// Emit initial debug information.
DW.BeginModule(&M);
O << "\t.zerofill __DATA__, __common, " << name << ", "
<< Size << ", " << Align;
} else {
- SwitchToDataSection(DefaultDataSection, I);
- if (LCOMMDirective != NULL) {
+ SwitchToDataSection(TAI->getDataSection(), I);
+ if (TAI->getLCOMMDirective() != NULL) {
if (I->hasInternalLinkage()) {
- O << LCOMMDirective << name << "," << Size;
+ O << TAI->getLCOMMDirective() << name << "," << Size;
if (Subtarget->isTargetDarwin())
- O << "," << (AlignmentIsInBytes ? (1 << Align) : Align);
+ O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
} else
- O << COMMDirective << name << "," << Size;
+ O << TAI->getCOMMDirective() << name << "," << Size;
} else {
if (Subtarget->TargetType != X86Subtarget::isCygwin) {
if (I->hasInternalLinkage())
O << "\t.local\t" << name << "\n";
}
- O << COMMDirective << name << "," << Size;
- if (COMMDirectiveTakesAlignment)
- O << "," << (AlignmentIsInBytes ? (1 << Align) : Align);
+ O << TAI->getCOMMDirective() << name << "," << Size;
+ if (TAI->getCOMMDirectiveTakesAlignment())
+ O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
}
}
- O << "\t\t" << CommentString << " " << I->getName() << "\n";
+ O << "\t\t" << TAI->getCommentString() << " " << I->getName() << "\n";
} else {
switch (I->getLinkage()) {
case GlobalValue::LinkOnceLinkage:
O << "\t.globl " << name << "\n";
// FALL THROUGH
case GlobalValue::InternalLinkage:
- SwitchToDataSection(DefaultDataSection, I);
+ SwitchToDataSection(TAI->getDataSection(), I);
break;
default:
assert(0 && "Unknown linkage type!");
}
EmitAlignment(Align, I);
- O << name << ":\t\t\t\t" << CommentString << " " << I->getName()
+ O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName()
<< "\n";
- if (HasDotTypeDotSizeDirective)
+ if (TAI->hasDotTypeDotSizeDirective())
O << "\t.size " << name << ", " << Size << "\n";
EmitGlobalConstant(C);
/// machine description.
///
FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,
- X86TargetMachine &tm){
+ X86TargetMachine &tm) {
+ TargetAsmInfo *TAI = new X86TargetAsmInfo(tm);
+
switch (AsmWriterFlavor) {
default:
assert(0 && "Unknown asm flavor!");
- case intel:
- return new X86IntelAsmPrinter(o, tm);
- case att:
- return new X86ATTAsmPrinter(o, tm);
+ case intel: return new X86IntelAsmPrinter(o, tm, TAI);
+ case att: return new X86ATTAsmPrinter(o, tm, TAI);
}
}
#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineDebugInfo.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/Target/TargetAsmInfo.h"
#include <set>
extern Statistic<> EmittedInsts;
-/// X86DwarfWriter - Dwarf debug info writer customized for Darwin/Mac OS X
-///
-struct X86DwarfWriter : public DwarfWriter {
- X86DwarfWriter(std::ostream &o, AsmPrinter *ap) : DwarfWriter(o, ap) {
- needsSet = true;
- DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug";
- DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug";
- DwarfLineSection = ".section __DWARF,__debug_line,regular,debug";
- DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug";
- DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug";
- DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug";
- DwarfStrSection = ".section __DWARF,__debug_str,regular,debug";
- DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug";
- DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug";
- DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug";
- DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug";
- TextSection = ".text";
- DataSection = ".data";
- }
- virtual void virtfn(); // out of line virtual fn.
+struct VISIBILITY_HIDDEN X86TargetAsmInfo : public TargetAsmInfo {
+ X86TargetAsmInfo(X86TargetMachine &TM);
};
-struct X86SharedAsmPrinter : public AsmPrinter {
- X86DwarfWriter DW;
+struct VISIBILITY_HIDDEN X86SharedAsmPrinter : public AsmPrinter {
+ DwarfWriter DW;
- X86SharedAsmPrinter(std::ostream &O, X86TargetMachine &TM)
- : AsmPrinter(O, TM), DW(O, this) {
+ X86SharedAsmPrinter(std::ostream &O, X86TargetMachine &TM,
+ TargetAsmInfo *T)
+ : AsmPrinter(O, TM, T), DW(O, this, T) {
Subtarget = &TM.getSubtarget<X86Subtarget>();
}
MachineFunctionPass::getAnalysisUsage(AU);
}
- const char *DefaultTextSection; // "_text" for MASM, ".text" for others.
- const char *DefaultDataSection; // "_data" for MASM, ".data" for others.
const X86Subtarget *Subtarget;
// Necessary for Darwin to print out the apprioriate types of linker stubs
#include "llvm/Target/TargetOptions.h"
using namespace llvm;
-X86IntelAsmPrinter::X86IntelAsmPrinter(std::ostream &O, X86TargetMachine &TM)
- : X86SharedAsmPrinter(O, TM) {
-}
-
/// runOnMachineFunction - This uses the printMachineInstruction()
/// method to print assembly for each instruction.
///
case MachineOperand::MO_ConstantPoolIndex: {
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
if (!isMemOp) O << "OFFSET ";
- O << "[" << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_"
- << MO.getConstantPoolIndex();
+ O << "[" << TAI->getPrivateGlobalPrefix() << "CPI"
+ << getFunctionNumber() << "_" << MO.getConstantPoolIndex();
int Offset = MO.getOffset();
if (Offset > 0)
O << " + " << Offset;
case MachineOperand::MO_ExternalSymbol: {
bool isCallOp = Modifier && !strcmp(Modifier, "call");
if (!isCallOp) O << "OFFSET ";
- O << GlobalPrefix << MO.getSymbolName();
+ O << TAI->getGlobalPrefix() << MO.getSymbolName();
return;
}
default:
Reg1 = getX86SubSuperRegister(Reg1, MVT::i16);
else
Reg1 = getX86SubSuperRegister(Reg1, MVT::i8);
- O << CommentString << " TRUNCATE ";
+ O << TAI->getCommentString() << " TRUNCATE ";
if (Reg0 != Reg1)
O << "\n\t";
break;
}
bool X86IntelAsmPrinter::doInitialization(Module &M) {
- GlobalPrefix = "_";
- CommentString = ";";
-
X86SharedAsmPrinter::doInitialization(M);
-
- PrivateGlobalPrefix = "$";
- AlignDirective = "\talign\t";
- ZeroDirective = "\tdb\t";
- ZeroDirectiveSuffix = " dup(0)";
- AsciiDirective = "\tdb\t";
- AscizDirective = 0;
- Data8bitsDirective = "\tdb\t";
- Data16bitsDirective = "\tdw\t";
- Data32bitsDirective = "\tdd\t";
- Data64bitsDirective = "\tdq\t";
- HasDotTypeDotSizeDirective = false;
- Mang->markCharUnacceptable('.');
- DefaultTextSection = "_text";
- DefaultDataSection = "_data";
- SwitchToSectionDirective = "";
- TextSectionStartSuffix = "\tsegment 'CODE'";
- DataSectionStartSuffix = "\tsegment 'DATA'";
- SectionEndDirectiveSuffix = "\tends\n";
+ Mang->markCharUnacceptable('.');
O << "\t.686\n\t.model flat\n\n";
O << "\tpublic " << name << "\n";
// FALL THROUGH
case GlobalValue::InternalLinkage:
- SwitchToDataSection(DefaultDataSection, I);
+ SwitchToDataSection(TAI->getDataSection(), I);
break;
default:
assert(0 && "Unknown linkage type!");
if (!bCustomSegment)
EmitAlignment(Align, I);
- O << name << ":\t\t\t\t" << CommentString << " " << I->getName() << '\n';
+ O << name << ":\t\t\t\t" << TAI->getCommentString()
+ << " " << I->getName() << '\n';
EmitGlobalConstant(C);
namespace llvm {
struct X86IntelAsmPrinter : public X86SharedAsmPrinter {
- X86IntelAsmPrinter(std::ostream &O, X86TargetMachine &TM);
+ X86IntelAsmPrinter(std::ostream &O, X86TargetMachine &TM, TargetAsmInfo *T)
+ : X86SharedAsmPrinter(O, TM, T) {
+ }
virtual const char *getPassName() const {
return "X86 Intel-Style Assembly Printer";