mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-23 12:08:25 +00:00
Separate target specific asm properties from the asm printers.
llvm-svn: 30126
This commit is contained in:
parent
d9cebd5e48
commit
6b86ef852c
@ -7,9 +7,9 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@ -22,10 +22,14 @@
|
||||
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,
|
||||
@ -42,6 +46,10 @@ namespace llvm {
|
||||
/// Target machine description.
|
||||
///
|
||||
TargetMachine &TM;
|
||||
|
||||
/// Target Asm Printer information.
|
||||
///
|
||||
TargetAsmInfo *TAI;
|
||||
|
||||
/// Name-mangler for global names.
|
||||
///
|
||||
@ -51,163 +59,13 @@ namespace llvm {
|
||||
/// 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
|
||||
|
@ -48,6 +48,7 @@ class Module;
|
||||
class MRegisterInfo;
|
||||
class SubprogramDesc;
|
||||
class SourceLineInfo;
|
||||
class TargetAsmInfo;
|
||||
class TargetData;
|
||||
class Type;
|
||||
class TypeDesc;
|
||||
@ -70,7 +71,8 @@ public:
|
||||
// DwarfWriter - Emits Dwarf debug and exception handling directives.
|
||||
//
|
||||
class DwarfWriter {
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Core attributes used by the Dwarf writer.
|
||||
@ -85,6 +87,9 @@ protected:
|
||||
///
|
||||
AsmPrinter *Asm;
|
||||
|
||||
/// TAI - Target Asm Printer.
|
||||
TargetAsmInfo *TAI;
|
||||
|
||||
/// TD - Target data.
|
||||
const TargetData *TD;
|
||||
|
||||
@ -147,93 +152,14 @@ protected:
|
||||
/// 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;
|
||||
@ -461,9 +387,13 @@ private:
|
||||
|
||||
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);
|
||||
|
@ -20,51 +20,16 @@
|
||||
#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
|
||||
@ -74,7 +39,7 @@ void AsmPrinter::SwitchToTextSection(const char *NewSection,
|
||||
const GlobalValue *GV) {
|
||||
std::string NS;
|
||||
if (GV && GV->hasSection())
|
||||
NS = SwitchToSectionDirective + GV->getSection();
|
||||
NS = TAI->getSwitchToSectionDirective() + GV->getSection();
|
||||
else
|
||||
NS = NewSection;
|
||||
|
||||
@ -82,13 +47,13 @@ void AsmPrinter::SwitchToTextSection(const char *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
|
||||
@ -98,7 +63,7 @@ void AsmPrinter::SwitchToDataSection(const char *NewSection,
|
||||
const GlobalValue *GV) {
|
||||
std::string NS;
|
||||
if (GV && GV->hasSection())
|
||||
NS = SwitchToSectionDirective + GV->getSection();
|
||||
NS = TAI->getSwitchToSectionDirective() + GV->getSection();
|
||||
else
|
||||
NS = NewSection;
|
||||
|
||||
@ -106,23 +71,24 @@ void AsmPrinter::SwitchToDataSection(const char *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.
|
||||
|
||||
@ -163,13 +129,13 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) {
|
||||
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
|
||||
@ -177,10 +143,11 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) {
|
||||
}
|
||||
|
||||
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,
|
||||
@ -190,8 +157,8 @@ 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) {
|
||||
@ -215,16 +182,16 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI) {
|
||||
// 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()));
|
||||
|
||||
@ -235,13 +202,13 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI) {
|
||||
// the number of relocations the assembler will generate for the jump table.
|
||||
// Set directives are all printed before the jump table itself.
|
||||
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 << ' ';
|
||||
@ -251,12 +218,12 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI) {
|
||||
// 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);
|
||||
}
|
||||
@ -280,14 +247,14 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
|
||||
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;
|
||||
@ -342,22 +309,22 @@ void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV) const {
|
||||
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";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -382,10 +349,15 @@ void AsmPrinter::EmitConstantValueOnly(const Constant *CV) {
|
||||
// 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()) {
|
||||
@ -495,12 +467,12 @@ static void printAsCString(std::ostream &O, const ConstantArray *CVA,
|
||||
///
|
||||
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";
|
||||
@ -550,50 +522,50 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
|
||||
// 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;
|
||||
}
|
||||
@ -610,25 +582,26 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
|
||||
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.");
|
||||
@ -662,7 +635,7 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
|
||||
return;
|
||||
}
|
||||
|
||||
O << InlineAsmStart << "\n\t";
|
||||
O << TAI->getInlineAsmStart() << "\n\t";
|
||||
|
||||
// The variant of the current asmprinter: FIXME: change.
|
||||
int AsmPrinterVariant = 0;
|
||||
@ -810,7 +783,7 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
|
||||
break;
|
||||
}
|
||||
}
|
||||
O << "\n\t" << InlineAsmEnd << "\n";
|
||||
O << "\n\t" << TAI->getInlineAsmEnd() << "\n";
|
||||
}
|
||||
|
||||
/// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
|
||||
@ -834,24 +807,24 @@ bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
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';
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#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"
|
||||
@ -674,7 +675,7 @@ void DIEDwarfLabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
||||
/// SizeOf - Determine size of label value in bytes.
|
||||
///
|
||||
unsigned DIEDwarfLabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
||||
return DW.getAddressSize();
|
||||
return DW.getTargetAsmInfo()->getAddressSize();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -688,7 +689,7 @@ void DIEObjectLabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
||||
/// SizeOf - Determine size of label value in bytes.
|
||||
///
|
||||
unsigned DIEObjectLabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
||||
return DW.getAddressSize();
|
||||
return DW.getTargetAsmInfo()->getAddressSize();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -702,7 +703,7 @@ void DIEDelta::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
||||
/// SizeOf - Determine size of delta value in bytes.
|
||||
///
|
||||
unsigned DIEDelta::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
||||
return DW.getAddressSize();
|
||||
return DW.getTargetAsmInfo()->getAddressSize();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -957,7 +958,7 @@ void DwarfWriter::PrintHex(int Value) const {
|
||||
void DwarfWriter::EOL(const std::string &Comment) const {
|
||||
if (DwarfVerbose && !Comment.empty()) {
|
||||
O << "\t"
|
||||
<< Asm->CommentString
|
||||
<< TAI->getCommentString()
|
||||
<< " "
|
||||
<< Comment;
|
||||
}
|
||||
@ -967,17 +968,17 @@ void DwarfWriter::EOL(const std::string &Comment) const {
|
||||
/// 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);
|
||||
}
|
||||
}
|
||||
@ -985,11 +986,11 @@ void DwarfWriter::EmitULEB128Bytes(unsigned Value) const {
|
||||
/// 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);
|
||||
}
|
||||
}
|
||||
@ -1052,29 +1053,29 @@ unsigned DwarfWriter::SizeSLEB128(int 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";
|
||||
@ -1089,7 +1090,7 @@ void DwarfWriter::EmitInt64(uint64_t Value) const {
|
||||
/// 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];
|
||||
@ -1122,7 +1123,7 @@ void DwarfWriter::EmitString(const std::string &String) const {
|
||||
/// 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;
|
||||
@ -1138,18 +1139,18 @@ void DwarfWriter::EmitLabel(const char *Tag, unsigned Number) const {
|
||||
/// 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;
|
||||
}
|
||||
@ -1159,7 +1160,7 @@ void DwarfWriter::EmitReference(const std::string &Name) const {
|
||||
/// 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";
|
||||
@ -1170,19 +1171,19 @@ void DwarfWriter::EmitDifference(const char *TagHi, unsigned NumberHi,
|
||||
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 << "-";
|
||||
@ -1782,33 +1783,33 @@ void DwarfWriter::EmitInitial() {
|
||||
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.
|
||||
@ -1958,7 +1959,7 @@ void DwarfWriter::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
|
||||
int stackGrowth =
|
||||
Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
|
||||
TargetFrameInfo::StackGrowsUp ?
|
||||
AddressSize : -AddressSize;
|
||||
TAI->getAddressSize() : -TAI->getAddressSize();
|
||||
|
||||
// If advancing cfa.
|
||||
if (Dst.isRegister() && Dst.getRegister() == MachineLocation::VirtualFP) {
|
||||
@ -2013,7 +2014,7 @@ void DwarfWriter::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
|
||||
///
|
||||
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) {
|
||||
@ -2033,7 +2034,7 @@ void DwarfWriter::EmitDebugInfo() const {
|
||||
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());
|
||||
@ -2049,7 +2050,7 @@ void DwarfWriter::EmitAbbreviations() const {
|
||||
// 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);
|
||||
|
||||
@ -2083,7 +2084,7 @@ void DwarfWriter::EmitDebugLines() const {
|
||||
const int MaxLineDelta = 255 + MinLineDelta;
|
||||
|
||||
// Start the dwarf line section.
|
||||
Asm->SwitchToDataSection(DwarfLineSection, 0);
|
||||
Asm->SwitchToDataSection(TAI->getDwarfLineSection(), 0);
|
||||
|
||||
// Construct the section header.
|
||||
|
||||
@ -2148,7 +2149,7 @@ void DwarfWriter::EmitDebugLines() const {
|
||||
|
||||
if (DwarfVerbose) {
|
||||
O << "\t"
|
||||
<< Asm->CommentString << " "
|
||||
<< TAI->getCommentString() << " "
|
||||
<< "Section "
|
||||
<< SectionMap[j + 1].c_str() << "\n";
|
||||
}
|
||||
@ -2166,7 +2167,7 @@ void DwarfWriter::EmitDebugLines() const {
|
||||
const SourceFileInfo &SourceFile = SourceFiles[SourceID];
|
||||
unsigned DirectoryID = SourceFile.getDirectoryID();
|
||||
O << "\t"
|
||||
<< Asm->CommentString << " "
|
||||
<< TAI->getCommentString() << " "
|
||||
<< Directories[DirectoryID]
|
||||
<< SourceFile.getName() << ":"
|
||||
<< LineInfo->getLine() << "\n";
|
||||
@ -2233,10 +2234,10 @@ void DwarfWriter::EmitInitialDebugFrame() {
|
||||
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,
|
||||
@ -2266,7 +2267,7 @@ void DwarfWriter::EmitInitialDebugFrame() {
|
||||
/// 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);
|
||||
@ -2296,7 +2297,7 @@ void DwarfWriter::EmitFunctionDebugFrame() {
|
||||
///
|
||||
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) {
|
||||
@ -2343,7 +2344,7 @@ void DwarfWriter::EmitDebugStr() {
|
||||
// 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();
|
||||
@ -2363,7 +2364,7 @@ void DwarfWriter::EmitDebugStr() {
|
||||
///
|
||||
void DwarfWriter::EmitDebugLoc() {
|
||||
// Start the dwarf loc section.
|
||||
Asm->SwitchToDataSection(DwarfLocSection, 0);
|
||||
Asm->SwitchToDataSection(TAI->getDwarfLocSection(), 0);
|
||||
|
||||
O << "\n";
|
||||
}
|
||||
@ -2372,7 +2373,7 @@ void DwarfWriter::EmitDebugLoc() {
|
||||
///
|
||||
void DwarfWriter::EmitDebugARanges() {
|
||||
// Start the dwarf aranges section.
|
||||
Asm->SwitchToDataSection(DwarfARangesSection, 0);
|
||||
Asm->SwitchToDataSection(TAI->getDwarfARangesSection(), 0);
|
||||
|
||||
// FIXME - Mock up
|
||||
#if 0
|
||||
@ -2389,7 +2390,7 @@ void DwarfWriter::EmitDebugARanges() {
|
||||
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");
|
||||
|
||||
@ -2413,7 +2414,7 @@ void DwarfWriter::EmitDebugARanges() {
|
||||
///
|
||||
void DwarfWriter::EmitDebugRanges() {
|
||||
// Start the dwarf ranges section.
|
||||
Asm->SwitchToDataSection(DwarfRangesSection, 0);
|
||||
Asm->SwitchToDataSection(TAI->getDwarfRangesSection(), 0);
|
||||
|
||||
O << "\n";
|
||||
}
|
||||
@ -2422,7 +2423,7 @@ void DwarfWriter::EmitDebugRanges() {
|
||||
///
|
||||
void DwarfWriter::EmitDebugMacInfo() {
|
||||
// Start the dwarf macinfo section.
|
||||
Asm->SwitchToDataSection(DwarfMacInfoSection, 0);
|
||||
Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection(), 0);
|
||||
|
||||
O << "\n";
|
||||
}
|
||||
@ -2466,9 +2467,10 @@ void DwarfWriter::ConstructSubprogramDIEs() {
|
||||
// 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)
|
||||
@ -2484,24 +2486,6 @@ DwarfWriter::DwarfWriter(std::ostream &OS, AsmPrinter *A)
|
||||
, 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) {
|
||||
@ -2530,7 +2514,7 @@ void DwarfWriter::SetDebugInfo(MachineDebugInfo *DI) {
|
||||
ConstructSubprogramDIEs();
|
||||
|
||||
// Prime section data.
|
||||
SectionMap.insert(std::string("\t") + TextSection);
|
||||
SectionMap.insert(std::string("\t") + TAI->getTextSection());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2550,9 +2534,9 @@ void DwarfWriter::EndModule() {
|
||||
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.
|
||||
|
@ -23,6 +23,7 @@
|
||||
#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"
|
||||
@ -37,8 +38,8 @@ using namespace llvm;
|
||||
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;
|
||||
@ -47,6 +48,12 @@ namespace {
|
||||
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
|
||||
@ -106,7 +113,8 @@ namespace {
|
||||
///
|
||||
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()
|
||||
@ -187,7 +195,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
|
||||
abort();
|
||||
break;
|
||||
case MachineOperand::MO_ConstantPoolIndex:
|
||||
O << PrivateGlobalPrefix << "CPI" << getFunctionNumber()
|
||||
O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
|
||||
<< '_' << MO.getConstantPoolIndex();
|
||||
break;
|
||||
default:
|
||||
|
@ -19,6 +19,7 @@
|
||||
#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"
|
||||
@ -27,17 +28,22 @@ using namespace llvm;
|
||||
|
||||
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
|
||||
@ -76,7 +82,8 @@ namespace {
|
||||
///
|
||||
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"
|
||||
@ -115,7 +122,7 @@ void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
|
||||
return;
|
||||
|
||||
case MachineOperand::MO_ConstantPoolIndex:
|
||||
O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_"
|
||||
O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
|
||||
<< MO.getConstantPoolIndex();
|
||||
return;
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#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>
|
||||
@ -32,10 +33,8 @@ using namespace llvm;
|
||||
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
|
||||
@ -52,6 +51,14 @@ namespace {
|
||||
// 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";
|
||||
@ -185,7 +192,8 @@ void IA64AsmPrinter::printOp(const MachineOperand &MO,
|
||||
printBasicBlockLabel(MO.getMachineBasicBlock());
|
||||
return;
|
||||
case MachineOperand::MO_ConstantPoolIndex: {
|
||||
O << "@gprel(" << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_"
|
||||
O << "@gprel(" << TAI->getPrivateGlobalPrefix()
|
||||
<< "CPI" << getFunctionNumber() << "_"
|
||||
<< MO.getConstantPoolIndex() << ")";
|
||||
return;
|
||||
}
|
||||
@ -358,7 +366,8 @@ bool IA64AsmPrinter::doFinalization(Module &M) {
|
||||
///
|
||||
FunctionPass *llvm::createIA64CodePrinterPass(std::ostream &o,
|
||||
IA64TargetMachine &tm) {
|
||||
return new IA64AsmPrinter(o, tm);
|
||||
IA64TargetAsmInfo *TAI = new IA64TargetAsmInfo();
|
||||
return new IA64AsmPrinter(o, tm, TAI);
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,7 +26,8 @@ class MachineCodeEmitter;
|
||||
|
||||
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,
|
||||
|
@ -34,6 +34,7 @@
|
||||
#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"
|
||||
@ -46,12 +47,11 @@ using namespace llvm;
|
||||
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";
|
||||
@ -151,7 +151,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
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;
|
||||
@ -239,14 +239,28 @@ namespace {
|
||||
|
||||
};
|
||||
|
||||
/// 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";
|
||||
@ -258,8 +272,6 @@ namespace {
|
||||
DwarfARangesSection = ".section __DWARF,__debug_aranges";
|
||||
DwarfRangesSection = ".section __DWARF,__debug_ranges";
|
||||
DwarfMacInfoSection = ".section __DWARF,__debug_macinfo";
|
||||
TextSection = ".text";
|
||||
DataSection = ".data";
|
||||
}
|
||||
};
|
||||
|
||||
@ -267,29 +279,11 @@ namespace {
|
||||
/// 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 {
|
||||
@ -309,13 +303,14 @@ namespace {
|
||||
};
|
||||
} // 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
|
||||
@ -332,23 +327,23 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
|
||||
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.
|
||||
@ -561,7 +556,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
|
||||
<< 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;
|
||||
|
@ -117,7 +117,7 @@ bool PPCTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
|
||||
|
||||
bool PPCTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
|
||||
std::ostream &Out) {
|
||||
PM.add(createDarwinAsmPrinter(Out, *this));
|
||||
PM.add(createDarwinCodePrinterPass(Out, *this));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#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"
|
||||
@ -36,8 +37,8 @@ using namespace llvm;
|
||||
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.
|
||||
@ -45,6 +46,12 @@ namespace {
|
||||
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
|
||||
@ -78,7 +85,8 @@ namespace {
|
||||
///
|
||||
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()
|
||||
@ -167,7 +175,7 @@ void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
|
||||
O << MO.getSymbolName();
|
||||
break;
|
||||
case MachineOperand::MO_ConstantPoolIndex:
|
||||
O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_"
|
||||
O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
|
||||
<< MO.getConstantPoolIndex();
|
||||
break;
|
||||
default:
|
||||
|
@ -43,11 +43,11 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||
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;
|
||||
@ -101,7 +101,7 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||
// 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()) {
|
||||
@ -144,7 +144,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
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_)
|
||||
@ -154,7 +154,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
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_)
|
||||
@ -206,14 +206,14 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
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:
|
||||
@ -388,7 +388,7 @@ void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
|
||||
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;
|
||||
|
@ -20,8 +20,8 @@
|
||||
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";
|
||||
|
@ -26,10 +26,11 @@
|
||||
#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:"),
|
||||
@ -44,16 +45,11 @@ AsmWriterFlavor("x86-asm-syntax",
|
||||
#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;
|
||||
@ -73,6 +69,19 @@ bool X86SharedAsmPrinter::doInitialization(Module &M) {
|
||||
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 = "_";
|
||||
@ -88,6 +97,33 @@ bool X86SharedAsmPrinter::doInitialization(Module &M) {
|
||||
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);
|
||||
@ -127,25 +163,25 @@ bool X86SharedAsmPrinter::doFinalization(Module &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:
|
||||
@ -170,16 +206,16 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
|
||||
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);
|
||||
@ -234,13 +270,13 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
|
||||
/// 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);
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "llvm/CodeGen/DwarfWriter.h"
|
||||
#include "llvm/CodeGen/MachineDebugInfo.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Target/TargetAsmInfo.h"
|
||||
#include <set>
|
||||
|
||||
|
||||
@ -29,33 +30,16 @@ namespace llvm {
|
||||
|
||||
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>();
|
||||
}
|
||||
|
||||
@ -70,8 +54,6 @@ struct X86SharedAsmPrinter : public AsmPrinter {
|
||||
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
|
||||
|
@ -22,10 +22,6 @@
|
||||
#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.
|
||||
///
|
||||
@ -106,8 +102,8 @@ void X86IntelAsmPrinter::printOp(const MachineOperand &MO,
|
||||
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;
|
||||
@ -131,7 +127,7 @@ void X86IntelAsmPrinter::printOp(const MachineOperand &MO,
|
||||
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:
|
||||
@ -272,7 +268,7 @@ void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
|
||||
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;
|
||||
@ -284,30 +280,9 @@ void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
@ -365,7 +340,7 @@ bool X86IntelAsmPrinter::doFinalization(Module &M) {
|
||||
O << "\tpublic " << name << "\n";
|
||||
// FALL THROUGH
|
||||
case GlobalValue::InternalLinkage:
|
||||
SwitchToDataSection(DefaultDataSection, I);
|
||||
SwitchToDataSection(TAI->getDataSection(), I);
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Unknown linkage type!");
|
||||
@ -374,7 +349,8 @@ bool X86IntelAsmPrinter::doFinalization(Module &M) {
|
||||
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);
|
||||
|
||||
|
@ -21,7 +21,9 @@
|
||||
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";
|
||||
|
Loading…
Reference in New Issue
Block a user