Update SwiftShader to April code dump.
April code dump from Transgaming. Adds new shader compiler.
diff --git a/src/LLVM/include/llvm/MC/EDInstInfo.h b/src/LLVM/include/llvm/MC/EDInstInfo.h
index dded255..0b9d3f6 100644
--- a/src/LLVM/include/llvm/MC/EDInstInfo.h
+++ b/src/LLVM/include/llvm/MC/EDInstInfo.h
@@ -9,7 +9,7 @@
#ifndef EDINSTINFO_H
#define EDINSTINFO_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -21,7 +21,7 @@
uint8_t numOperands;
uint8_t operandTypes[EDIS_MAX_OPERANDS];
uint8_t operandFlags[EDIS_MAX_OPERANDS];
- const char operandOrders[EDIS_MAX_SYNTAXES][EDIS_MAX_OPERANDS];
+ const signed char operandOrders[EDIS_MAX_SYNTAXES][EDIS_MAX_OPERANDS];
};
} // namespace llvm
diff --git a/src/LLVM/include/llvm/MC/MCAsmBackend.h b/src/LLVM/include/llvm/MC/MCAsmBackend.h
new file mode 100644
index 0000000..4a0cf37
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCAsmBackend.h
@@ -0,0 +1,131 @@
+//===-- llvm/MC/MCAsmBack.h - MC Asm Backend --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMBACKEND_H
+#define LLVM_MC_MCASMBACKEND_H
+
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCFixupKindInfo.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+class MCELFObjectTargetWriter;
+class MCFixup;
+class MCInst;
+class MCObjectWriter;
+class MCSection;
+template<typename T>
+class SmallVectorImpl;
+class raw_ostream;
+
+/// MCAsmBackend - Generic interface to target specific assembler backends.
+class MCAsmBackend {
+ MCAsmBackend(const MCAsmBackend &); // DO NOT IMPLEMENT
+ void operator=(const MCAsmBackend &); // DO NOT IMPLEMENT
+protected: // Can only create subclasses.
+ MCAsmBackend();
+
+ unsigned HasReliableSymbolDifference : 1;
+
+public:
+ virtual ~MCAsmBackend();
+
+ /// createObjectWriter - Create a new MCObjectWriter instance for use by the
+ /// assembler backend to emit the final object file.
+ virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0;
+
+ /// createELFObjectTargetWriter - Create a new ELFObjectTargetWriter to enable
+ /// non-standard ELFObjectWriters.
+ virtual MCELFObjectTargetWriter *createELFObjectTargetWriter() const {
+ assert(0 && "createELFObjectTargetWriter is not supported by asm backend");
+ return 0;
+ }
+
+ /// hasReliableSymbolDifference - Check whether this target implements
+ /// accurate relocations for differences between symbols. If not, differences
+ /// between symbols will always be relocatable expressions and any references
+ /// to temporary symbols will be assumed to be in the same atom, unless they
+ /// reside in a different section.
+ ///
+ /// This should always be true (since it results in fewer relocations with no
+ /// loss of functionality), but is currently supported as a way to maintain
+ /// exact object compatibility with Darwin 'as' (on non-x86_64). It should
+ /// eventually should be eliminated.
+ bool hasReliableSymbolDifference() const {
+ return HasReliableSymbolDifference;
+ }
+
+ /// doesSectionRequireSymbols - Check whether the given section requires that
+ /// all symbols (even temporaries) have symbol table entries.
+ virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
+ return false;
+ }
+
+ /// isSectionAtomizable - Check whether the given section can be split into
+ /// atoms.
+ ///
+ /// \see MCAssembler::isSymbolLinkerVisible().
+ virtual bool isSectionAtomizable(const MCSection &Section) const {
+ return true;
+ }
+
+ /// @name Target Fixup Interfaces
+ /// @{
+
+ /// getNumFixupKinds - Get the number of target specific fixup kinds.
+ virtual unsigned getNumFixupKinds() const = 0;
+
+ /// getFixupKindInfo - Get information on a fixup kind.
+ virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const;
+
+ /// @}
+
+ /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided
+ /// data fragment, at the offset specified by the fixup and following the
+ /// fixup kind as appropriate.
+ virtual void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
+ uint64_t Value) const = 0;
+
+ /// @}
+
+ /// @name Target Relaxation Interfaces
+ /// @{
+
+ /// MayNeedRelaxation - Check whether the given instruction may need
+ /// relaxation.
+ ///
+ /// \param Inst - The instruction to test.
+ virtual bool MayNeedRelaxation(const MCInst &Inst) const = 0;
+
+ /// RelaxInstruction - Relax the instruction in the given fragment to the next
+ /// wider instruction.
+ ///
+ /// \param Inst - The instruction to relax, which may be the same as the
+ /// output.
+ /// \parm Res [output] - On return, the relaxed instruction.
+ virtual void RelaxInstruction(const MCInst &Inst, MCInst &Res) const = 0;
+
+ /// @}
+
+ /// WriteNopData - Write an (optimal) nop sequence of Count bytes to the given
+ /// output. If the target cannot generate such a sequence, it should return an
+ /// error.
+ ///
+ /// \return - True on success.
+ virtual bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const = 0;
+
+ /// HandleAssemblerFlag - Handle any target-specific assembler flags.
+ /// By default, do nothing.
+ virtual void HandleAssemblerFlag(MCAssemblerFlag Flag) {}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/MCAsmInfo.h b/src/LLVM/include/llvm/MC/MCAsmInfo.h
index 8516de0..c3c296e 100644
--- a/src/LLVM/include/llvm/MC/MCAsmInfo.h
+++ b/src/LLVM/include/llvm/MC/MCAsmInfo.h
@@ -16,53 +16,89 @@
#ifndef LLVM_TARGET_ASM_INFO_H
#define LLVM_TARGET_ASM_INFO_H
+#include "llvm/MC/MachineLocation.h"
#include "llvm/MC/MCDirectives.h"
#include <cassert>
+#include <vector>
namespace llvm {
+ class MCExpr;
class MCSection;
+ class MCStreamer;
+ class MCSymbol;
class MCContext;
-
+
+ namespace ExceptionHandling {
+ enum ExceptionsType { None, DwarfCFI, SjLj, ARM, Win64 };
+ }
+
+ namespace LCOMM {
+ enum LCOMMType { None, NoAlignment, ByteAlignment };
+ }
+
+ namespace Structors {
+ enum OutputOrder { None, PriorityOrder, ReversePriorityOrder };
+ }
+
/// MCAsmInfo - This class is intended to be used as a base class for asm
/// properties and features specific to the target.
- namespace ExceptionHandling { enum ExceptionsType { None, Dwarf, SjLj }; }
-
class MCAsmInfo {
protected:
//===------------------------------------------------------------------===//
// Properties to be set by the target writer, used to configure asm printer.
//
+
+ /// PointerSize - Pointer size in bytes.
+ /// Default is 4.
+ unsigned PointerSize;
+
+ /// IsLittleEndian - True if target is little endian.
+ /// Default is true.
+ bool IsLittleEndian;
+
+ /// StackGrowsUp - True if target stack grow up.
+ /// Default is false.
+ bool StackGrowsUp;
/// HasSubsectionsViaSymbols - True if this target has the MachO
/// .subsections_via_symbols directive.
bool HasSubsectionsViaSymbols; // Default is false.
-
+
/// HasMachoZeroFillDirective - True if this is a MachO target that supports
/// the macho-specific .zerofill directive for emitting BSS Symbols.
bool HasMachoZeroFillDirective; // Default is false.
-
+
/// HasMachoTBSSDirective - True if this is a MachO target that supports
/// the macho-specific .tbss directive for emitting thread local BSS Symbols
bool HasMachoTBSSDirective; // Default is false.
-
+
+ /// StructorOutputOrder - Whether the static ctor/dtor list should be output
+ /// in no particular order, in order of increasing priority or the reverse:
+ /// in order of decreasing priority (the default).
+ Structors::OutputOrder StructorOutputOrder; // Default is reverse order.
+
/// HasStaticCtorDtorReferenceInStaticMode - True if the compiler should
/// emit a ".reference .constructors_used" or ".reference .destructors_used"
/// directive after the a static ctor/dtor list. This directive is only
/// emitted in Static relocation model.
bool HasStaticCtorDtorReferenceInStaticMode; // Default is false.
-
+
+ /// LinkerRequiresNonEmptyDwarfLines - True if the linker has a bug and
+ /// requires that the debug_line section be of a minimum size. In practice
+ /// such a linker requires a non empty line sequence if a file is present.
+ bool LinkerRequiresNonEmptyDwarfLines; // Default to false.
+
/// MaxInstLength - This is the maximum possible length of an instruction,
/// which is needed to compute the size of an inline asm.
unsigned MaxInstLength; // Defaults to 4.
-
+
/// PCSymbol - The symbol used to represent the current PC. Used in PC
/// relative expressions.
const char *PCSymbol; // Defaults to "$".
- /// SeparatorChar - This character, if specified, is used to separate
- /// instructions from each other when on the same line. This is used to
- /// measure inline asm instructions.
- char SeparatorChar; // Defaults to ';'
+ /// SeparatorString - This string, if specified, is used to separate
+ /// instructions from each other when on the same line.
+ const char *SeparatorString; // Defaults to ';'
/// CommentColumn - This indicates the comment num (zero-based) at
/// which asm comments should be printed.
@@ -72,6 +108,9 @@
/// assembler.
const char *CommentString; // Defaults to "#"
+ /// LabelSuffix - This is appended to emitted labels.
+ const char *LabelSuffix; // 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 ""
@@ -80,17 +119,24 @@
/// pool entries that are completely private to the .s file and should not
/// have names in the .o file. This is often "." or "L".
const char *PrivateGlobalPrefix; // Defaults to "."
-
+
/// LinkerPrivateGlobalPrefix - This prefix is used for symbols that should
/// be passed through the assembler but be removed by the linker. This
/// is "l" on Darwin, currently used for some ObjC metadata.
const char *LinkerPrivateGlobalPrefix; // Defaults to ""
-
+
/// InlineAsmStart/End - If these are nonempty, they contain a directive to
/// emit before and after an inline assembly statement.
const char *InlineAsmStart; // Defaults to "#APP\n"
const char *InlineAsmEnd; // Defaults to "#NO_APP\n"
+ /// Code16Directive, Code32Directive, Code64Directive - These are assembly
+ /// directives that tells the assembler to interpret the following
+ /// instructions differently.
+ const char *Code16Directive; // Defaults to ".code16"
+ const char *Code32Directive; // Defaults to ".code32"
+ const char *Code64Directive; // Defaults to ".code64"
+
/// AssemblerDialect - Which dialect of an assembler variant to use.
unsigned AssemblerDialect; // Defaults to 0
@@ -117,7 +163,7 @@
/// 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.
@@ -131,11 +177,23 @@
const char *Data32bitsDirective; // Defaults to "\t.long\t"
const char *Data64bitsDirective; // Defaults to "\t.quad\t"
+ /// [Data|Code]Begin - These magic labels are used to marked a region as
+ /// data or code, and are used to provide additional information for
+ /// correct disassembly on targets that like to mix data and code within
+ /// a segment. These labels will be implicitly suffixed by the streamer
+ /// to give them unique names.
+ const char *DataBegin; // Defaults to "$d."
+ const char *CodeBegin; // Defaults to "$a."
+ const char *JT8Begin; // Defaults to "$a."
+ const char *JT16Begin; // Defaults to "$a."
+ const char *JT32Begin; // Defaults to "$a."
+ bool SupportsDataRegions;
+
/// GPRel32Directive - if non-null, a directive that is used to emit a word
/// which should be relocated as a 32-bit GP-relative offset, e.g. .gpword
/// on Mips or .gprel32 on Alpha.
const char *GPRel32Directive; // Defaults to NULL.
-
+
/// getDataASDirective - Return the directive that should be used to emit
/// data of the specified size to the specified numeric address space.
virtual const char *getDataASDirective(unsigned Size, unsigned AS) const {
@@ -149,15 +207,15 @@
bool SunStyleELFSectionSwitchSyntax; // Defaults to false.
/// UsesELFSectionDirectiveForBSS - This is true if this target uses ELF
- /// '.section' directive before the '.bss' one. It's used for PPC/Linux
+ /// '.section' directive before the '.bss' one. It's used for PPC/Linux
/// which doesn't support the '.bss' directive only.
bool UsesELFSectionDirectiveForBSS; // Defaults to false.
-
+
/// HasMicrosoftFastStdCallMangling - True if this target uses microsoft
/// style mangling for functions with X86_StdCall/X86_FastCall calling
/// convention.
bool HasMicrosoftFastStdCallMangling; // Defaults to false.
-
+
//===--- Alignment Information ----------------------------------------===//
/// AlignDirective - The directive used to emit round up to an alignment
@@ -176,27 +234,34 @@
unsigned TextAlignFillValue; // Defaults to 0
//===--- Global Variable Emission Directives --------------------------===//
-
+
/// GlobalDirective - This is the directive used to declare a global entity.
///
const char *GlobalDirective; // Defaults to NULL.
- /// ExternDirective - This is the directive used to declare external
+ /// ExternDirective - This is the directive used to declare external
/// globals.
///
const char *ExternDirective; // Defaults to NULL.
-
+
/// HasSetDirective - True if the assembler supports the .set directive.
bool HasSetDirective; // Defaults to true.
-
- /// HasLCOMMDirective - This is true if the target supports the .lcomm
- /// directive.
- bool HasLCOMMDirective; // Defaults to false.
-
+
+ /// HasAggressiveSymbolFolding - False if the assembler requires that we use
+ /// Lc = a - b
+ /// .long Lc
+ /// instead of
+ /// .long a - b
+ bool HasAggressiveSymbolFolding; // Defaults to true.
+
+ /// LCOMMDirectiveType - Describes if the target supports the .lcomm
+ /// directive and whether it has an alignment parameter.
+ LCOMM::LCOMMType LCOMMDirectiveType; // Defaults to LCOMM::None.
+
/// COMMDirectiveAlignmentIsInBytes - True is COMMDirective's optional
/// alignment is to be specified in bytes instead of log2(n).
bool COMMDirectiveAlignmentIsInBytes; // 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.
@@ -209,10 +274,14 @@
/// directive.
bool HasNoDeadStrip; // Defaults to false.
+ /// HasSymbolResolver - True if this target supports the MachO
+ /// .symbol_resolver directive.
+ bool HasSymbolResolver; // Defaults to false.
+
/// WeakRefDirective - This directive, if non-null, is used to declare a
/// global as being a weak undefined symbol.
const char *WeakRefDirective; // Defaults to NULL.
-
+
/// WeakDefDirective - This directive, if non-null, is used to declare a
/// global as being a weak defined symbol.
const char *WeakDefDirective; // Defaults to NULL.
@@ -220,11 +289,16 @@
/// LinkOnceDirective - This directive, if non-null is used to declare a
/// global as being a weak defined symbol. This is used on cygwin/mingw.
const char *LinkOnceDirective; // Defaults to NULL.
-
+
/// HiddenVisibilityAttr - This attribute, if not MCSA_Invalid, is used to
/// declare a symbol as having hidden visibility.
MCSymbolAttr HiddenVisibilityAttr; // Defaults to MCSA_Hidden.
+ /// HiddenDeclarationVisibilityAttr - This attribute, if not MCSA_Invalid,
+ /// is used to declare an undefined symbol as having hidden visibility.
+ MCSymbolAttr HiddenDeclarationVisibilityAttr; // Defaults to MCSA_Hidden.
+
+
/// ProtectedVisibilityAttr - This attribute, if not MCSA_Invalid, is used
/// to declare a symbol as having protected visibility.
MCSymbolAttr ProtectedVisibilityAttr; // Defaults to MCSA_Protected
@@ -234,10 +308,6 @@
/// HasLEB128 - True if target asm supports leb128 directives.
bool HasLEB128; // Defaults to false.
- /// hasDotLocAndDotFile - True if target asm supports .loc and .file
- /// directives for emitting debugging information.
- bool HasDotLocAndDotFile; // Defaults to false.
-
/// SupportsDebugInformation - True if target supports emission of debugging
/// information.
bool SupportsDebugInformation; // Defaults to false.
@@ -245,20 +315,33 @@
/// SupportsExceptionHandling - True if target supports exception handling.
ExceptionHandling::ExceptionsType ExceptionsType; // Defaults to None
- /// RequiresFrameSection - true if the Dwarf2 output needs a frame section
- bool DwarfRequiresFrameSection; // Defaults to true.
-
/// DwarfUsesInlineInfoSection - True if DwarfDebugInlineSection is used to
/// encode inline subroutine information.
bool DwarfUsesInlineInfoSection; // Defaults to false.
/// DwarfSectionOffsetDirective - Special section offset directive.
const char* DwarfSectionOffsetDirective; // Defaults to NULL
-
+
+ /// DwarfRequiresRelocationForSectionOffset - True if we need to produce a
+ // relocation when we want a section offset in dwarf.
+ bool DwarfRequiresRelocationForSectionOffset; // Defaults to true;
+
+ // DwarfUsesLabelOffsetDifference - True if Dwarf2 output can
+ // use EmitLabelOffsetDifference.
+ bool DwarfUsesLabelOffsetForRanges;
+
+ /// DwarfRegNumForCFI - True if dwarf register numbers are printed
+ /// instead of symbolic register names in .cfi_* directives.
+ bool DwarfRegNumForCFI; // Defaults to false;
+
//===--- CBE Asm Translation Table -----------------------------------===//
const char *const *AsmTransCBE; // Defaults to empty
+ //===--- Prologue State ----------------------------------------------===//
+
+ std::vector<MachineMove> InitialFrameState;
+
public:
explicit MCAsmInfo();
virtual ~MCAsmInfo();
@@ -267,8 +350,23 @@
static unsigned getSLEB128Size(int Value);
static unsigned getULEB128Size(unsigned Value);
+ /// getPointerSize - Get the pointer size in bytes.
+ unsigned getPointerSize() const {
+ return PointerSize;
+ }
+
+ /// islittleendian - True if the target is little endian.
+ bool isLittleEndian() const {
+ return IsLittleEndian;
+ }
+
+ /// isStackGrowthDirectionUp - True if target stack grow up.
+ bool isStackGrowthDirectionUp() const {
+ return StackGrowsUp;
+ }
+
bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
-
+
// Data directive accessors.
//
const char *getData8bitsDirective(unsigned AS = 0) const {
@@ -285,17 +383,35 @@
}
const char *getGPRel32Directive() const { return GPRel32Directive; }
+ /// [Code|Data]Begin label name accessors.
+ const char *getCodeBeginLabelName() const { return CodeBegin; }
+ const char *getDataBeginLabelName() const { return DataBegin; }
+ const char *getJumpTable8BeginLabelName() const { return JT8Begin; }
+ const char *getJumpTable16BeginLabelName() const { return JT16Begin; }
+ const char *getJumpTable32BeginLabelName() const { return JT32Begin; }
+ bool getSupportsDataRegions() const { return SupportsDataRegions; }
+
/// getNonexecutableStackSection - Targets can implement this method to
/// specify a section to switch to if the translation unit doesn't have any
/// trampolines that require an executable stack.
virtual const MCSection *getNonexecutableStackSection(MCContext &Ctx) const{
return 0;
}
-
+
+ virtual const MCExpr *
+ getExprForPersonalitySymbol(const MCSymbol *Sym,
+ unsigned Encoding,
+ MCStreamer &Streamer) const;
+
+ const MCExpr *
+ getExprForFDESymbol(const MCSymbol *Sym,
+ unsigned Encoding,
+ MCStreamer &Streamer) const;
+
bool usesSunStyleELFSectionSwitchSyntax() const {
return SunStyleELFSectionSwitchSyntax;
}
-
+
bool usesELFSectionDirectiveForBSS() const {
return UsesELFSectionDirectiveForBSS;
}
@@ -303,22 +419,28 @@
bool hasMicrosoftFastStdCallMangling() const {
return HasMicrosoftFastStdCallMangling;
}
-
+
// Accessors.
//
bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; }
bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; }
+ Structors::OutputOrder getStructorOutputOrder() const {
+ return StructorOutputOrder;
+ }
bool hasStaticCtorDtorReferenceInStaticMode() const {
return HasStaticCtorDtorReferenceInStaticMode;
}
+ bool getLinkerRequiresNonEmptyDwarfLines() const {
+ return LinkerRequiresNonEmptyDwarfLines;
+ }
unsigned getMaxInstLength() const {
return MaxInstLength;
}
const char *getPCSymbol() const {
return PCSymbol;
}
- char getSeparatorChar() const {
- return SeparatorChar;
+ const char *getSeparatorString() const {
+ return SeparatorString;
}
unsigned getCommentColumn() const {
return CommentColumn;
@@ -326,6 +448,9 @@
const char *getCommentString() const {
return CommentString;
}
+ const char *getLabelSuffix() const {
+ return LabelSuffix;
+ }
const char *getGlobalPrefix() const {
return GlobalPrefix;
}
@@ -341,6 +466,15 @@
const char *getInlineAsmEnd() const {
return InlineAsmEnd;
}
+ const char *getCode16Directive() const {
+ return Code16Directive;
+ }
+ const char *getCode32Directive() const {
+ return Code32Directive;
+ }
+ const char *getCode64Directive() const {
+ return Code64Directive;
+ }
unsigned getAssemblerDialect() const {
return AssemblerDialect;
}
@@ -378,27 +512,33 @@
return ExternDirective;
}
bool hasSetDirective() const { return HasSetDirective; }
- bool hasLCOMMDirective() const { return HasLCOMMDirective; }
+ bool hasAggressiveSymbolFolding() const {
+ return HasAggressiveSymbolFolding;
+ }
+ LCOMM::LCOMMType getLCOMMDirectiveType() const {
+ return LCOMMDirectiveType;
+ }
bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;}
bool getCOMMDirectiveAlignmentIsInBytes() const {
return COMMDirectiveAlignmentIsInBytes;
}
bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; }
bool hasNoDeadStrip() const { return HasNoDeadStrip; }
+ bool hasSymbolResolver() const { return HasSymbolResolver; }
const char *getWeakRefDirective() const { return WeakRefDirective; }
const char *getWeakDefDirective() const { return WeakDefDirective; }
const char *getLinkOnceDirective() const { return LinkOnceDirective; }
-
+
MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr;}
+ MCSymbolAttr getHiddenDeclarationVisibilityAttr() const {
+ return HiddenDeclarationVisibilityAttr;
+ }
MCSymbolAttr getProtectedVisibilityAttr() const {
return ProtectedVisibilityAttr;
}
bool hasLEB128() const {
return HasLEB128;
}
- bool hasDotLocAndDotFile() const {
- return HasDotLocAndDotFile;
- }
bool doesSupportDebugInformation() const {
return SupportsDebugInformation;
}
@@ -408,8 +548,11 @@
ExceptionHandling::ExceptionsType getExceptionHandlingType() const {
return ExceptionsType;
}
- bool doesDwarfRequireFrameSection() const {
- return DwarfRequiresFrameSection;
+ bool isExceptionHandlingDwarf() const {
+ return
+ (ExceptionsType == ExceptionHandling::DwarfCFI ||
+ ExceptionsType == ExceptionHandling::ARM ||
+ ExceptionsType == ExceptionHandling::Win64);
}
bool doesDwarfUsesInlineInfoSection() const {
return DwarfUsesInlineInfoSection;
@@ -417,9 +560,26 @@
const char *getDwarfSectionOffsetDirective() const {
return DwarfSectionOffsetDirective;
}
+ bool doesDwarfRequireRelocationForSectionOffset() const {
+ return DwarfRequiresRelocationForSectionOffset;
+ }
+ bool doesDwarfUsesLabelOffsetForRanges() const {
+ return DwarfUsesLabelOffsetForRanges;
+ }
+ bool useDwarfRegNumForCFI() const {
+ return DwarfRegNumForCFI;
+ }
const char *const *getAsmCBE() const {
return AsmTransCBE;
}
+
+ void addInitialFrameState(MCSymbol *label, const MachineLocation &D,
+ const MachineLocation &S) {
+ InitialFrameState.push_back(MachineMove(label, D, S));
+ }
+ const std::vector<MachineMove> &getInitialFrameState() const {
+ return InitialFrameState;
+ }
};
}
diff --git a/src/LLVM/include/llvm/MC/MCAsmInfoDarwin.h b/src/LLVM/include/llvm/MC/MCAsmInfoDarwin.h
index c85aa3d..1f6c499 100644
--- a/src/LLVM/include/llvm/MC/MCAsmInfoDarwin.h
+++ b/src/LLVM/include/llvm/MC/MCAsmInfoDarwin.h
@@ -18,11 +18,6 @@
#include "llvm/MC/MCAsmInfo.h"
namespace llvm {
- class GlobalValue;
- class GlobalVariable;
- class Type;
- class Mangler;
-
struct MCAsmInfoDarwin : public MCAsmInfo {
explicit MCAsmInfoDarwin();
};
diff --git a/src/LLVM/include/llvm/MC/MCAsmLayout.h b/src/LLVM/include/llvm/MC/MCAsmLayout.h
index b9565ba..a4585d1 100644
--- a/src/LLVM/include/llvm/MC/MCAsmLayout.h
+++ b/src/LLVM/include/llvm/MC/MCAsmLayout.h
@@ -36,16 +36,15 @@
/// List of sections in layout order.
llvm::SmallVector<MCSectionData*, 16> SectionOrder;
- /// The last fragment which was layed out, or 0 if nothing has been layed
- /// out. Fragments are always layed out in order, so all fragments with a
+ /// The last fragment which was laid out, or 0 if nothing has been laid
+ /// out. Fragments are always laid out in order, so all fragments with a
/// lower ordinal will be up to date.
- mutable MCFragment *LastValidFragment;
+ mutable DenseMap<const MCSectionData*, MCFragment *> LastValidFragment;
/// \brief Make sure that the layout for the given fragment is valid, lazily
/// computing it if necessary.
void EnsureValid(const MCFragment *F) const;
- bool isSectionUpToDate(const MCSectionData *SD) const;
bool isFragmentUpToDate(const MCFragment *F) const;
public:
@@ -54,27 +53,15 @@
/// Get the assembler object this is a layout for.
MCAssembler &getAssembler() const { return Assembler; }
- /// \brief Update the layout because a fragment has been resized. The
- /// fragments size should have already been updated, the \arg SlideAmount is
- /// the delta from the old size.
- void UpdateForSlide(MCFragment *F, int SlideAmount);
-
- /// \brief Update the layout because a fragment has been replaced.
- void FragmentReplaced(MCFragment *Src, MCFragment *Dst);
-
- /// \brief Perform a full layout.
- void LayoutFile();
+ /// \brief Invalidate all following fragments because a fragment has been
+ /// resized. The fragments size should have already been updated.
+ void Invalidate(MCFragment *F);
/// \brief Perform layout for a single fragment, assuming that the previous
- /// fragment has already been layed out correctly, and the parent section has
+ /// fragment has already been laid out correctly, and the parent section has
/// been initialized.
void LayoutFragment(MCFragment *Fragment);
- /// \brief Performs initial layout for a single section, assuming that the
- /// previous section (including its fragments) has already been layed out
- /// correctly.
- void LayoutSection(MCSectionData *SD);
-
/// @name Section Access (in layout order)
/// @{
@@ -89,28 +76,13 @@
/// @name Fragment Layout Data
/// @{
- /// \brief Get the effective size of the given fragment, as computed in the
- /// current layout.
- uint64_t getFragmentEffectiveSize(const MCFragment *F) const;
-
/// \brief Get the offset of the given fragment inside its containing section.
uint64_t getFragmentOffset(const MCFragment *F) const;
/// @}
- /// @name Section Layout Data
- /// @{
-
- /// \brief Get the computed address of the given section.
- uint64_t getSectionAddress(const MCSectionData *SD) const;
-
- /// @}
/// @name Utility Functions
/// @{
- /// \brief Get the address of the given fragment, as computed in the current
- /// layout.
- uint64_t getFragmentAddress(const MCFragment *F) const;
-
/// \brief Get the address space size of the given section, as it effects
/// layout. This may differ from the size reported by \see getSectionSize() by
/// not including section tail padding.
@@ -120,12 +92,9 @@
/// file. This may include additional padding, or be 0 for virtual sections.
uint64_t getSectionFileSize(const MCSectionData *SD) const;
- /// \brief Get the logical data size of the given section.
- uint64_t getSectionSize(const MCSectionData *SD) const;
-
- /// \brief Get the address of the given symbol, as computed in the current
+ /// \brief Get the offset of the given symbol, as computed in the current
/// layout.
- uint64_t getSymbolAddress(const MCSymbolData *SD) const;
+ uint64_t getSymbolOffset(const MCSymbolData *SD) const;
/// @}
};
diff --git a/src/LLVM/include/llvm/MC/MCAssembler.h b/src/LLVM/include/llvm/MC/MCAssembler.h
index 50cb73b..b8f8cc4 100644
--- a/src/LLVM/include/llvm/MC/MCAssembler.h
+++ b/src/LLVM/include/llvm/MC/MCAssembler.h
@@ -10,20 +10,22 @@
#ifndef LLVM_MC_MCASSEMBLER_H
#define LLVM_MC_MCASSEMBLER_H
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCInst.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/Support/Casting.h"
-#include "llvm/MC/MCFixup.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <vector> // FIXME: Shouldn't be needed.
namespace llvm {
class raw_ostream;
class MCAsmLayout;
class MCAssembler;
+class MCBinaryExpr;
class MCContext;
class MCCodeEmitter;
class MCExpr;
@@ -34,7 +36,7 @@
class MCSymbol;
class MCSymbolData;
class MCValue;
-class TargetAsmBackend;
+class MCAsmBackend;
class MCFragment : public ilist_node<MCFragment> {
friend class MCAsmLayout;
@@ -48,7 +50,10 @@
FT_Data,
FT_Fill,
FT_Inst,
- FT_Org
+ FT_Org,
+ FT_Dwarf,
+ FT_DwarfFrame,
+ FT_LEB
};
private:
@@ -71,12 +76,7 @@
/// initialized.
uint64_t Offset;
- /// EffectiveSize - The compute size of this section. This is ~0 until
- /// initialized.
- uint64_t EffectiveSize;
-
- /// LayoutOrder - The global layout order of this fragment. This is the index
- /// across all fragments in the file, not just within the section.
+ /// LayoutOrder - The layout order of this fragment.
unsigned LayoutOrder;
/// @}
@@ -163,7 +163,7 @@
/// Inst - The instruction this is a fragment for.
MCInst Inst;
- /// InstSize - The size of the currently encoded instruction.
+ /// Code - Binary data for the currently encoded instruction.
SmallString<8> Code;
/// Fixups - The list of fixups in this fragment.
@@ -233,19 +233,12 @@
/// target dependent.
bool EmitNops : 1;
- /// OnlyAlignAddress - Flag to indicate that this align is only used to adjust
- /// the address space size of a section and that it should not be included as
- /// part of the section size. This flag can only be used on the last fragment
- /// in a section.
- bool OnlyAlignAddress : 1;
-
public:
MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
: MCFragment(FT_Align, SD), Alignment(_Alignment),
Value(_Value),ValueSize(_ValueSize),
- MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false),
- OnlyAlignAddress(false) {}
+ MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
/// @name Accessors
/// @{
@@ -261,9 +254,6 @@
bool hasEmitNops() const { return EmitNops; }
void setEmitNops(bool Value) { EmitNops = Value; }
- bool hasOnlyAlignAddress() const { return OnlyAlignAddress; }
- void setOnlyAlignAddress(bool Value) { OnlyAlignAddress = Value; }
-
/// @}
static bool classof(const MCFragment *F) {
@@ -336,6 +326,100 @@
static bool classof(const MCOrgFragment *) { return true; }
};
+class MCLEBFragment : public MCFragment {
+ /// Value - The value this fragment should contain.
+ const MCExpr *Value;
+
+ /// IsSigned - True if this is a sleb128, false if uleb128.
+ bool IsSigned;
+
+ SmallString<8> Contents;
+public:
+ MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD)
+ : MCFragment(FT_LEB, SD),
+ Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
+
+ /// @name Accessors
+ /// @{
+
+ const MCExpr &getValue() const { return *Value; }
+
+ bool isSigned() const { return IsSigned; }
+
+ SmallString<8> &getContents() { return Contents; }
+ const SmallString<8> &getContents() const { return Contents; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_LEB;
+ }
+ static bool classof(const MCLEBFragment *) { return true; }
+};
+
+class MCDwarfLineAddrFragment : public MCFragment {
+ /// LineDelta - the value of the difference between the two line numbers
+ /// between two .loc dwarf directives.
+ int64_t LineDelta;
+
+ /// AddrDelta - The expression for the difference of the two symbols that
+ /// make up the address delta between two .loc dwarf directives.
+ const MCExpr *AddrDelta;
+
+ SmallString<8> Contents;
+
+public:
+ MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
+ MCSectionData *SD)
+ : MCFragment(FT_Dwarf, SD),
+ LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
+
+ /// @name Accessors
+ /// @{
+
+ int64_t getLineDelta() const { return LineDelta; }
+
+ const MCExpr &getAddrDelta() const { return *AddrDelta; }
+
+ SmallString<8> &getContents() { return Contents; }
+ const SmallString<8> &getContents() const { return Contents; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Dwarf;
+ }
+ static bool classof(const MCDwarfLineAddrFragment *) { return true; }
+};
+
+class MCDwarfCallFrameFragment : public MCFragment {
+ /// AddrDelta - The expression for the difference of the two symbols that
+ /// make up the address delta between two .cfi_* dwarf directives.
+ const MCExpr *AddrDelta;
+
+ SmallString<8> Contents;
+
+public:
+ MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD)
+ : MCFragment(FT_DwarfFrame, SD),
+ AddrDelta(&_AddrDelta) { Contents.push_back(0); }
+
+ /// @name Accessors
+ /// @{
+
+ const MCExpr &getAddrDelta() const { return *AddrDelta; }
+
+ SmallString<8> &getContents() { return Contents; }
+ const SmallString<8> &getContents() const { return Contents; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_DwarfFrame;
+ }
+ static bool classof(const MCDwarfCallFrameFragment *) { return true; }
+};
+
// FIXME: Should this be a separate class, or just merged into MCSection? Since
// we anticipate the fast path being through an MCAssembler, the only reason to
// keep it out is for API abstraction.
@@ -372,10 +456,6 @@
//
// FIXME: This could all be kept private to the assembler implementation.
- /// Address - The computed address of this section. This is ~0 until
- /// initialized.
- uint64_t Address;
-
/// HasInstructions - Whether this section has had instructions emitted into
/// it.
unsigned HasInstructions : 1;
@@ -453,6 +533,10 @@
// common symbol can never get a definition.
uint64_t CommonSize;
+ /// SymbolSize - An expression describing how to calculate the size of
+ /// a symbol. If a symbol has no size this field will be NULL.
+ const MCExpr *SymbolSize;
+
/// CommonAlign - The alignment of the symbol, if it is 'common'.
//
// FIXME: Pack this in with other fields?
@@ -510,6 +594,15 @@
return CommonSize;
}
+ void setSize(const MCExpr *SS) {
+ SymbolSize = SS;
+ }
+
+ const MCExpr *getSize() const {
+ return SymbolSize;
+ }
+
+
/// getCommonAlignment - Return the alignment of a 'common' symbol.
unsigned getCommonAlignment() const {
assert(isCommon() && "Not a 'common' symbol!");
@@ -567,10 +660,12 @@
MCContext &Context;
- TargetAsmBackend &Backend;
+ MCAsmBackend &Backend;
MCCodeEmitter &Emitter;
+ MCObjectWriter &Writer;
+
raw_ostream &OS;
iplist<MCSectionData> Sections;
@@ -589,7 +684,17 @@
std::vector<IndirectSymbolData> IndirectSymbols;
+ /// The set of function symbols for which a .thumb_func directive has
+ /// been seen.
+ //
+ // FIXME: We really would like this in target specific code rather than
+ // here. Maybe when the relocation stuff moves to target specific,
+ // this can go with it? The streamer would need some target specific
+ // refactoring too.
+ SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
+
unsigned RelaxAll : 1;
+ unsigned NoExecStack : 1;
unsigned SubsectionsViaSymbols : 1;
private:
@@ -601,7 +706,7 @@
/// \param DF The fragment the fixup is inside.
/// \param Target [out] On return, the relocatable expression the fixup
/// evaluates to.
- /// \param Value [out] On return, the value of the fixup as currently layed
+ /// \param Value [out] On return, the value of the fixup as currently laid
/// out.
/// \return Whether the fixup value was fully resolved. This is true if the
/// \arg Value result is fixed, otherwise the value may change due to
@@ -619,24 +724,34 @@
bool FragmentNeedsRelaxation(const MCInstFragment *IF,
const MCAsmLayout &Layout) const;
- /// Compute the effective fragment size assuming it is layed out at the given
- /// \arg SectionAddress and \arg FragmentOffset.
- uint64_t ComputeFragmentSize(MCAsmLayout &Layout, const MCFragment &F,
- uint64_t SectionAddress,
- uint64_t FragmentOffset) const;
-
/// LayoutOnce - Perform one layout iteration and return true if any offsets
/// were adjusted.
bool LayoutOnce(MCAsmLayout &Layout);
+ bool LayoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD);
+
+ bool RelaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF);
+
+ bool RelaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
+
+ bool RelaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF);
+ bool RelaxDwarfCallFrameFragment(MCAsmLayout &Layout,
+ MCDwarfCallFrameFragment &DF);
+
/// FinishLayout - Finalize a layout, including fragment lowering.
void FinishLayout(MCAsmLayout &Layout);
+ uint64_t HandleFixup(const MCAsmLayout &Layout,
+ MCFragment &F, const MCFixup &Fixup);
+
public:
+ /// Compute the effective fragment size assuming it is laid out at the given
+ /// \arg SectionAddress and \arg FragmentOffset.
+ uint64_t ComputeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const;
+
/// Find the symbol which defines the atom containing the given symbol, or
/// null if there is no such symbol.
- const MCSymbolData *getAtom(const MCAsmLayout &Layout,
- const MCSymbolData *Symbol) const;
+ const MCSymbolData *getAtom(const MCSymbolData *Symbol) const;
/// Check whether a particular symbol is visible to the linker and is required
/// in the symbol table, or whether it can be discarded by the assembler. This
@@ -645,10 +760,16 @@
bool isSymbolLinkerVisible(const MCSymbol &SD) const;
/// Emit the section contents using the given object writer.
- //
- // FIXME: Should MCAssembler always have a reference to the object writer?
- void WriteSectionData(const MCSectionData *Section, const MCAsmLayout &Layout,
- MCObjectWriter *OW) const;
+ void WriteSectionData(const MCSectionData *Section,
+ const MCAsmLayout &Layout) const;
+
+ /// Check whether a given symbol has been flagged with .thumb_func.
+ bool isThumbFunc(const MCSymbol *Func) const {
+ return ThumbFuncs.count(Func);
+ }
+
+ /// Flag a function symbol as the target of a .thumb_func directive.
+ void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
public:
/// Construct a new assembler instance.
@@ -659,20 +780,23 @@
// concrete and require clients to pass in a target like object. The other
// option is to make this abstract, and have targets provide concrete
// implementations as we do with AsmParser.
- MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend,
- MCCodeEmitter &_Emitter, raw_ostream &OS);
+ MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
+ MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
+ raw_ostream &OS);
~MCAssembler();
MCContext &getContext() const { return Context; }
- TargetAsmBackend &getBackend() const { return Backend; }
+ MCAsmBackend &getBackend() const { return Backend; }
MCCodeEmitter &getEmitter() const { return Emitter; }
+ MCObjectWriter &getWriter() const { return Writer; }
+
/// Finish - Do final processing and write the object to the output stream.
/// \arg Writer is used for custom object writer (as the MCJIT does),
/// if not specified it is automatically created from backend.
- void Finish(MCObjectWriter *Writer = 0);
+ void Finish();
// FIXME: This does not belong here.
bool getSubsectionsViaSymbols() const {
@@ -685,6 +809,9 @@
bool getRelaxAll() const { return RelaxAll; }
void setRelaxAll(bool Value) { RelaxAll = Value; }
+ bool getNoExecStack() const { return NoExecStack; }
+ void setNoExecStack(bool Value) { NoExecStack = Value; }
+
/// @name Section List Access
/// @{
diff --git a/src/LLVM/include/llvm/MC/MCAtom.h b/src/LLVM/include/llvm/MC/MCAtom.h
new file mode 100644
index 0000000..682cf7c
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCAtom.h
@@ -0,0 +1,68 @@
+//===-- llvm/MC/MCAtom.h - MCAtom class ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCAtom class, which is used to
+// represent a contiguous region in a decoded object that is uniformly data or
+// instructions;
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCATOM_H
+#define LLVM_MC_MCATOM_H
+
+#include "llvm/MC/MCInst.h"
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+
+class MCModule;
+
+/// MCData - An entry in a data MCAtom.
+// NOTE: This may change to a more complex type in the future.
+typedef uint8_t MCData;
+
+/// MCAtom - Represents a contiguous range of either instructions (a TextAtom)
+/// or data (a DataAtom). Address ranges are expressed as _closed_ intervals.
+class MCAtom {
+ friend class MCModule;
+ typedef enum { TextAtom, DataAtom } AtomType;
+
+ AtomType Type;
+ MCModule *Parent;
+ uint64_t Begin, End;
+
+ std::vector<std::pair<uint64_t, MCInst> > Text;
+ std::vector<MCData> Data;
+
+ // Private constructor - only callable by MCModule
+ MCAtom(AtomType T, MCModule *P, uint64_t B, uint64_t E)
+ : Type(T), Parent(P), Begin(B), End(E) { }
+
+public:
+ bool isTextAtom() { return Type == TextAtom; }
+ bool isDataAtom() { return Type == DataAtom; }
+
+ void addInst(const MCInst &I, uint64_t Address, unsigned Size);
+ void addData(const MCData &D);
+
+ /// split - Splits the atom in two at a given address, which must align with
+ /// and instruction boundary if this is a TextAtom. Returns the newly created
+ /// atom representing the high part of the split.
+ MCAtom *split(uint64_t SplitPt);
+
+ /// truncate - Truncates an atom so that TruncPt is the last byte address
+ /// contained in the atom.
+ void truncate(uint64_t TruncPt);
+};
+
+}
+
+#endif
+
diff --git a/src/LLVM/include/llvm/MC/MCCodeEmitter.h b/src/LLVM/include/llvm/MC/MCCodeEmitter.h
index 010a2e5..bc63241 100644
--- a/src/LLVM/include/llvm/MC/MCCodeEmitter.h
+++ b/src/LLVM/include/llvm/MC/MCCodeEmitter.h
@@ -20,33 +20,6 @@
class raw_ostream;
template<typename T> class SmallVectorImpl;
-/// MCFixupKindInfo - Target independent information on a fixup kind.
-struct MCFixupKindInfo {
- enum FixupKindFlags {
- /// Is this fixup kind PCrelative. This is used by the assembler backend to
- /// evaluate fixup values in a target independent manner when possible.
- FKF_IsPCRel = (1 << 0)
- };
-
- /// A target specific name for the fixup kind. The names will be unique for
- /// distinct kinds on any given target.
- const char *Name;
-
- /// The bit offset to write the relocation into.
- //
- // FIXME: These two fields are under-specified and not general enough, but it
- // is covers many things, and is enough to let the AsmStreamer pretty-print
- // the encoding.
- unsigned TargetOffset;
-
- /// The number of bits written by this fixup. The bits are assumed to be
- /// contiguous.
- unsigned TargetSize;
-
- /// Flags describing additional information on this fixup kind.
- unsigned Flags;
-};
-
/// MCCodeEmitter - Generic instruction encoding interface.
class MCCodeEmitter {
private:
@@ -58,17 +31,6 @@
public:
virtual ~MCCodeEmitter();
- /// @name Target Independent Fixup Information
- /// @{
-
- /// getNumFixupKinds - Get the number of target specific fixup kinds.
- virtual unsigned getNumFixupKinds() const = 0;
-
- /// getFixupKindInfo - Get information on a fixup kind.
- virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const;
-
- /// @}
-
/// EncodeInstruction - Encode the given \arg Inst to bytes on the output
/// stream \arg OS.
virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS,
diff --git a/src/LLVM/include/llvm/MC/MCCodeGenInfo.h b/src/LLVM/include/llvm/MC/MCCodeGenInfo.h
new file mode 100644
index 0000000..1c54c47
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCCodeGenInfo.h
@@ -0,0 +1,41 @@
+//===-- llvm/MC/MCCodeGenInfo.h - Target CodeGen Info -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tracks information about the target which can affect codegen,
+// asm parsing, and asm printing. For example, relocation model.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCCODEGENINFO_H
+#define LLVM_MC_MCCODEGENINFO_H
+
+#include "llvm/Support/CodeGen.h"
+
+namespace llvm {
+
+ class MCCodeGenInfo {
+ /// RelocationModel - Relocation model: statcic, pic, etc.
+ ///
+ Reloc::Model RelocationModel;
+
+ /// CMModel - Code model.
+ ///
+ CodeModel::Model CMModel;
+
+ public:
+ void InitMCCodeGenInfo(Reloc::Model RM = Reloc::Default,
+ CodeModel::Model CM = CodeModel::Default);
+
+ Reloc::Model getRelocationModel() const { return RelocationModel; }
+
+ CodeModel::Model getCodeModel() const { return CMModel; }
+ };
+} // namespace llvm
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/MCContext.h b/src/LLVM/include/llvm/MC/MCContext.h
index 4db0491..a49a35c 100644
--- a/src/LLVM/include/llvm/MC/MCContext.h
+++ b/src/LLVM/include/llvm/MC/MCContext.h
@@ -11,6 +11,7 @@
#define LLVM_MC_MCCONTEXT_H
#include "llvm/MC/SectionKind.h"
+#include "llvm/MC/MCDwarf.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Allocator.h"
@@ -24,9 +25,14 @@
class MCSymbol;
class MCLabel;
class MCDwarfFile;
+ class MCDwarfLoc;
+ class MCObjectFileInfo;
+ class MCRegisterInfo;
+ class MCLineSection;
class StringRef;
class Twine;
class MCSectionMachO;
+ class MCSectionELF;
/// MCContext - Context object for machine code objects. This class owns all
/// of the sections that it creates.
@@ -34,12 +40,31 @@
class MCContext {
MCContext(const MCContext&); // DO NOT IMPLEMENT
MCContext &operator=(const MCContext&); // DO NOT IMPLEMENT
+ public:
+ typedef StringMap<MCSymbol*, BumpPtrAllocator&> SymbolTable;
+ private:
/// The MCAsmInfo for this target.
const MCAsmInfo &MAI;
+ /// The MCRegisterInfo for this target.
+ const MCRegisterInfo &MRI;
+
+ /// The MCObjectFileInfo for this target.
+ const MCObjectFileInfo *MOFI;
+
+ /// Allocator - Allocator object used for creating machine code objects.
+ ///
+ /// We use a bump pointer allocator to avoid the need to track all allocated
+ /// objects.
+ BumpPtrAllocator Allocator;
+
/// Symbols - Bindings of names to symbols.
- StringMap<MCSymbol*> Symbols;
+ SymbolTable Symbols;
+
+ /// UsedNames - Keeps tracks of names that were used both for used declared
+ /// and artificial symbols.
+ StringMap<bool, BumpPtrAllocator&> UsedNames;
/// NextUniqueID - The next ID to dole out to an unnamed assembler temporary
/// symbol.
@@ -53,8 +78,8 @@
/// GetInstance() gets the current instance of the directional local label
/// for the LocalLabelVal and adds it to the map if needed.
unsigned GetInstance(int64_t LocalLabelVal);
-
- /// The file name of the log file from the enviromment variable
+
+ /// The file name of the log file from the environment variable
/// AS_SECURE_LOG_FILE. Which must be set before the .secure_log_unique
/// directive is used or it is an error.
char *SecureLogFile;
@@ -69,28 +94,48 @@
std::vector<MCDwarfFile *> MCDwarfFiles;
std::vector<StringRef> MCDwarfDirs;
- /// Allocator - Allocator object used for creating machine code objects.
- ///
- /// We use a bump pointer allocator to avoid the need to track all allocated
- /// objects.
- BumpPtrAllocator Allocator;
-
+ /// The current dwarf line information from the last dwarf .loc directive.
+ MCDwarfLoc CurrentDwarfLoc;
+ bool DwarfLocSeen;
+
+ /// Honor temporary labels, this is useful for debugging semantic
+ /// differences between temporary and non-temporary labels (primarily on
+ /// Darwin).
+ bool AllowTemporaryLabels;
+
+ /// The dwarf line information from the .loc directives for the sections
+ /// with assembled machine instructions have after seeing .loc directives.
+ DenseMap<const MCSection *, MCLineSection *> MCLineSections;
+ /// We need a deterministic iteration order, so we remember the order
+ /// the elements were added.
+ std::vector<const MCSection *> MCLineSectionOrder;
+
void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
+
+ MCSymbol *CreateSymbol(StringRef Name);
+
public:
- explicit MCContext(const MCAsmInfo &MAI);
+ explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI,
+ const MCObjectFileInfo *MOFI);
~MCContext();
-
+
const MCAsmInfo &getAsmInfo() const { return MAI; }
- /// @name Symbol Managment
+ const MCRegisterInfo &getRegisterInfo() const { return MRI; }
+
+ const MCObjectFileInfo *getObjectFileInfo() const { return MOFI; }
+
+ void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; }
+
+ /// @name Symbol Management
/// @{
-
+
/// CreateTempSymbol - Create and return a new assembler temporary symbol
/// with a unique but unspecified name.
MCSymbol *CreateTempSymbol();
- /// CreateDirectionalLocalSymbol - Create the defintion of a directional
- /// local symbol for numbered label (used for "1:" defintions).
+ /// CreateDirectionalLocalSymbol - Create the definition of a directional
+ /// local symbol for numbered label (used for "1:" definitions).
MCSymbol *CreateDirectionalLocalSymbol(int64_t LocalLabelVal);
/// GetDirectionalLocalSymbol - Create and return a directional local
@@ -108,9 +153,17 @@
/// LookupSymbol - Get the symbol for \p Name, or null.
MCSymbol *LookupSymbol(StringRef Name) const;
+ /// getSymbols - Get a reference for the symbol table for clients that
+ /// want to, for example, iterate over all symbols. 'const' because we
+ /// still want any modifications to the table itself to use the MCContext
+ /// APIs.
+ const SymbolTable &getSymbols() const {
+ return Symbols;
+ }
+
/// @}
-
- /// @name Section Managment
+
+ /// @name Section Management
/// @{
/// getMachOSection - Return the MCSection for the specified mach-o section.
@@ -126,10 +179,15 @@
SectionKind K) {
return getMachOSection(Segment, Section, TypeAndAttributes, 0, K);
}
-
- const MCSection *getELFSection(StringRef Section, unsigned Type,
- unsigned Flags, SectionKind Kind,
- bool IsExplicit = false);
+
+ const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, SectionKind Kind);
+
+ const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, SectionKind Kind,
+ unsigned EntrySize, StringRef Group);
+
+ const MCSectionELF *CreateELFGroupSection();
const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
int Selection, SectionKind Kind);
@@ -139,15 +197,21 @@
return getCOFFSection (Section, Characteristics, 0, Kind);
}
-
+
/// @}
- /// @name Dwarf Managment
+ /// @name Dwarf Management
/// @{
/// GetDwarfFile - creates an entry in the dwarf file and directory tables.
unsigned GetDwarfFile(StringRef FileName, unsigned FileNumber);
+ bool isValidDwarfFileNumber(unsigned FileNumber);
+
+ bool hasDwarfFiles() const {
+ return !MCDwarfFiles.empty();
+ }
+
const std::vector<MCDwarfFile *> &getMCDwarfFiles() {
return MCDwarfFiles;
}
@@ -155,6 +219,38 @@
return MCDwarfDirs;
}
+ const DenseMap<const MCSection *, MCLineSection *>
+ &getMCLineSections() const {
+ return MCLineSections;
+ }
+ const std::vector<const MCSection *> &getMCLineSectionOrder() const {
+ return MCLineSectionOrder;
+ }
+ void addMCLineSection(const MCSection *Sec, MCLineSection *Line) {
+ MCLineSections[Sec] = Line;
+ MCLineSectionOrder.push_back(Sec);
+ }
+
+ /// setCurrentDwarfLoc - saves the information from the currently parsed
+ /// dwarf .loc directive and sets DwarfLocSeen. When the next instruction
+ /// is assembled an entry in the line number table with this information and
+ /// the address of the instruction will be created.
+ void setCurrentDwarfLoc(unsigned FileNum, unsigned Line, unsigned Column,
+ unsigned Flags, unsigned Isa,
+ unsigned Discriminator) {
+ CurrentDwarfLoc.setFileNum(FileNum);
+ CurrentDwarfLoc.setLine(Line);
+ CurrentDwarfLoc.setColumn(Column);
+ CurrentDwarfLoc.setFlags(Flags);
+ CurrentDwarfLoc.setIsa(Isa);
+ CurrentDwarfLoc.setDiscriminator(Discriminator);
+ DwarfLocSeen = true;
+ }
+ void ClearDwarfLocSeen() { DwarfLocSeen = false; }
+
+ bool getDwarfLocSeen() { return DwarfLocSeen; }
+ const MCDwarfLoc &getCurrentDwarfLoc() { return CurrentDwarfLoc; }
+
/// @}
char *getSecureLogFile() { return SecureLogFile; }
diff --git a/src/LLVM/include/llvm/MC/MCDirectives.h b/src/LLVM/include/llvm/MC/MCDirectives.h
index 223b09e..9180d1b 100644
--- a/src/LLVM/include/llvm/MC/MCDirectives.h
+++ b/src/LLVM/include/llvm/MC/MCDirectives.h
@@ -26,6 +26,7 @@
MCSA_ELF_TypeTLS, ///< .type _foo, STT_TLS # aka @tls_object
MCSA_ELF_TypeCommon, ///< .type _foo, STT_COMMON # aka @common
MCSA_ELF_TypeNoType, ///< .type _foo, STT_NOTYPE # aka @notype
+ MCSA_ELF_TypeGnuUniqueObject, /// .type _foo, @gnu_unique_object
MCSA_Global, ///< .globl
MCSA_Hidden, ///< .hidden (ELF)
MCSA_IndirectSymbol, ///< .indirect_symbol (MachO)
@@ -33,6 +34,7 @@
MCSA_LazyReference, ///< .lazy_reference (MachO)
MCSA_Local, ///< .local (ELF)
MCSA_NoDeadStrip, ///< .no_dead_strip (MachO)
+ MCSA_SymbolResolver, ///< .symbol_resolver (MachO)
MCSA_PrivateExtern, ///< .private_extern (MachO)
MCSA_Protected, ///< .protected (ELF)
MCSA_Reference, ///< .reference (MachO)
@@ -43,9 +45,13 @@
};
enum MCAssemblerFlag {
- MCAF_SubsectionsViaSymbols ///< .subsections_via_symbols (MachO)
+ MCAF_SyntaxUnified, ///< .syntax (ARM/ELF)
+ MCAF_SubsectionsViaSymbols, ///< .subsections_via_symbols (MachO)
+ MCAF_Code16, ///< .code16 (X86) / .code 16 (ARM)
+ MCAF_Code32, ///< .code32 (X86) / .code 32 (ARM)
+ MCAF_Code64 ///< .code64 (X86)
};
-
+
} // end namespace llvm
#endif
diff --git a/src/LLVM/include/llvm/MC/MCDisassembler.h b/src/LLVM/include/llvm/MC/MCDisassembler.h
index dfb8ed5..454277d 100644
--- a/src/LLVM/include/llvm/MC/MCDisassembler.h
+++ b/src/LLVM/include/llvm/MC/MCDisassembler.h
@@ -9,13 +9,16 @@
#ifndef MCDISASSEMBLER_H
#define MCDISASSEMBLER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm-c/Disassembler.h"
namespace llvm {
class MCInst;
+class MCSubtargetInfo;
class MemoryObject;
class raw_ostream;
+class MCContext;
struct EDInstInfo;
@@ -23,8 +26,38 @@
/// and provides an array of assembly instructions.
class MCDisassembler {
public:
+ /// Ternary decode status. Most backends will just use Fail and
+ /// Success, however some have a concept of an instruction with
+ /// understandable semantics but which is architecturally
+ /// incorrect. An example of this is ARM UNPREDICTABLE instructions
+ /// which are disassemblable but cause undefined behaviour.
+ ///
+ /// Because it makes sense to disassemble these instructions, there
+ /// is a "soft fail" failure mode that indicates the MCInst& is
+ /// valid but architecturally incorrect.
+ ///
+ /// The enum numbers are deliberately chosen such that reduction
+ /// from Success->SoftFail ->Fail can be done with a simple
+ /// bitwise-AND:
+ ///
+ /// LEFT & TOP = | Success Unpredictable Fail
+ /// --------------+-----------------------------------
+ /// Success | Success Unpredictable Fail
+ /// Unpredictable | Unpredictable Unpredictable Fail
+ /// Fail | Fail Fail Fail
+ ///
+ /// An easy way of encoding this is as 0b11, 0b01, 0b00 for
+ /// Success, SoftFail, Fail respectively.
+ enum DecodeStatus {
+ Fail = 0,
+ SoftFail = 1,
+ Success = 3
+ };
+
/// Constructor - Performs initial setup for the disassembler.
- MCDisassembler() {}
+ MCDisassembler(const MCSubtargetInfo &STI) : GetOpInfo(0), SymbolLookUp(0),
+ DisInfo(0), Ctx(0),
+ STI(STI), CommentStream(0) {}
virtual ~MCDisassembler();
@@ -39,20 +72,63 @@
/// @param address - The address, in the memory space of region, of the first
/// byte of the instruction.
/// @param vStream - The stream to print warnings and diagnostic messages on.
- /// @return - True if the instruction is valid; false otherwise.
- virtual bool getInstruction(MCInst& instr,
+ /// @param cStream - The stream to print comments and annotations on.
+ /// @return - MCDisassembler::Success if the instruction is valid,
+ /// MCDisassembler::SoftFail if the instruction was
+ /// disassemblable but invalid,
+ /// MCDisassembler::Fail if the instruction was invalid.
+ virtual DecodeStatus getInstruction(MCInst& instr,
uint64_t& size,
const MemoryObject ®ion,
uint64_t address,
- raw_ostream &vStream) const = 0;
+ raw_ostream &vStream,
+ raw_ostream &cStream) const = 0;
- /// getEDInfo - Returns the enhanced insturction information corresponding to
+ /// getEDInfo - Returns the enhanced instruction information corresponding to
/// the disassembler.
///
/// @return - An array of instruction information, with one entry for
/// each MCInst opcode this disassembler returns.
/// NULL if there is no info for this target.
virtual EDInstInfo *getEDInfo() const { return (EDInstInfo*)0; }
+
+private:
+ //
+ // Hooks for symbolic disassembly via the public 'C' interface.
+ //
+ // The function to get the symbolic information for operands.
+ LLVMOpInfoCallback GetOpInfo;
+ // The function to lookup a symbol name.
+ LLVMSymbolLookupCallback SymbolLookUp;
+ // The pointer to the block of symbolic information for above call back.
+ void *DisInfo;
+ // The assembly context for creating symbols and MCExprs in place of
+ // immediate operands when there is symbolic information.
+ MCContext *Ctx;
+protected:
+ // Subtarget information, for instruction decoding predicates if required.
+ const MCSubtargetInfo &STI;
+
+public:
+ void setupForSymbolicDisassembly(LLVMOpInfoCallback getOpInfo,
+ LLVMSymbolLookupCallback symbolLookUp,
+ void *disInfo,
+ MCContext *ctx) {
+ GetOpInfo = getOpInfo;
+ SymbolLookUp = symbolLookUp;
+ DisInfo = disInfo;
+ Ctx = ctx;
+ }
+ LLVMOpInfoCallback getLLVMOpInfoCallback() const { return GetOpInfo; }
+ LLVMSymbolLookupCallback getLLVMSymbolLookupCallback() const {
+ return SymbolLookUp;
+ }
+ void *getDisInfoBlock() const { return DisInfo; }
+ MCContext *getMCContext() const { return Ctx; }
+
+ // Marked mutable because we cache it inside the disassembler, rather than
+ // having to pass it around as an argument through all the autogenerated code.
+ mutable raw_ostream *CommentStream;
};
} // namespace llvm
diff --git a/src/LLVM/include/llvm/MC/MCDwarf.h b/src/LLVM/include/llvm/MC/MCDwarf.h
index e21b42f..431e3c4 100644
--- a/src/LLVM/include/llvm/MC/MCDwarf.h
+++ b/src/LLVM/include/llvm/MC/MCDwarf.h
@@ -8,8 +8,7 @@
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of the MCDwarfFile to support the dwarf
-// .file directive.
-// TODO: add the support needed for the .loc directive.
+// .file directive and the .loc directive.
//
//===----------------------------------------------------------------------===//
@@ -17,9 +16,20 @@
#define LLVM_MC_MCDWARF_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MachineLocation.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Dwarf.h"
+#include <vector>
namespace llvm {
class MCContext;
+ class MCExpr;
+ class MCSection;
+ class MCSectionData;
+ class MCStreamer;
+ class MCSymbol;
+ class MCObjectStreamer;
class raw_ostream;
/// MCDwarfFile - Instances of this class represent the name of the dwarf
@@ -61,6 +71,220 @@
DwarfFile.print(OS);
return OS;
}
+
+ /// MCDwarfLoc - Instances of this class represent the information from a
+ /// dwarf .loc directive.
+ class MCDwarfLoc {
+ // FileNum - the file number.
+ unsigned FileNum;
+ // Line - the line number.
+ unsigned Line;
+ // Column - the column position.
+ unsigned Column;
+ // Flags (see #define's below)
+ unsigned Flags;
+ // Isa
+ unsigned Isa;
+ // Discriminator
+ unsigned Discriminator;
+
+// Flag that indicates the initial value of the is_stmt_start flag.
+#define DWARF2_LINE_DEFAULT_IS_STMT 1
+
+#define DWARF2_FLAG_IS_STMT (1 << 0)
+#define DWARF2_FLAG_BASIC_BLOCK (1 << 1)
+#define DWARF2_FLAG_PROLOGUE_END (1 << 2)
+#define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3)
+
+ private: // MCContext manages these
+ friend class MCContext;
+ friend class MCLineEntry;
+ MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
+ unsigned isa, unsigned discriminator)
+ : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa),
+ Discriminator(discriminator) {}
+
+ // Allow the default copy constructor and assignment operator to be used
+ // for an MCDwarfLoc object.
+
+ public:
+ /// getFileNum - Get the FileNum of this MCDwarfLoc.
+ unsigned getFileNum() const { return FileNum; }
+
+ /// getLine - Get the Line of this MCDwarfLoc.
+ unsigned getLine() const { return Line; }
+
+ /// getColumn - Get the Column of this MCDwarfLoc.
+ unsigned getColumn() const { return Column; }
+
+ /// getFlags - Get the Flags of this MCDwarfLoc.
+ unsigned getFlags() const { return Flags; }
+
+ /// getIsa - Get the Isa of this MCDwarfLoc.
+ unsigned getIsa() const { return Isa; }
+
+ /// getDiscriminator - Get the Discriminator of this MCDwarfLoc.
+ unsigned getDiscriminator() const { return Discriminator; }
+
+ /// setFileNum - Set the FileNum of this MCDwarfLoc.
+ void setFileNum(unsigned fileNum) { FileNum = fileNum; }
+
+ /// setLine - Set the Line of this MCDwarfLoc.
+ void setLine(unsigned line) { Line = line; }
+
+ /// setColumn - Set the Column of this MCDwarfLoc.
+ void setColumn(unsigned column) { Column = column; }
+
+ /// setFlags - Set the Flags of this MCDwarfLoc.
+ void setFlags(unsigned flags) { Flags = flags; }
+
+ /// setIsa - Set the Isa of this MCDwarfLoc.
+ void setIsa(unsigned isa) { Isa = isa; }
+
+ /// setDiscriminator - Set the Discriminator of this MCDwarfLoc.
+ void setDiscriminator(unsigned discriminator) {
+ Discriminator = discriminator;
+ }
+ };
+
+ /// MCLineEntry - Instances of this class represent the line information for
+ /// the dwarf line table entries. Which is created after a machine
+ /// instruction is assembled and uses an address from a temporary label
+ /// created at the current address in the current section and the info from
+ /// the last .loc directive seen as stored in the context.
+ class MCLineEntry : public MCDwarfLoc {
+ MCSymbol *Label;
+
+ private:
+ // Allow the default copy constructor and assignment operator to be used
+ // for an MCLineEntry object.
+
+ public:
+ // Constructor to create an MCLineEntry given a symbol and the dwarf loc.
+ MCLineEntry(MCSymbol *label, const MCDwarfLoc loc) : MCDwarfLoc(loc),
+ Label(label) {}
+
+ MCSymbol *getLabel() const { return Label; }
+
+ // This is called when an instruction is assembled into the specified
+ // section and if there is information from the last .loc directive that
+ // has yet to have a line entry made for it is made.
+ static void Make(MCStreamer *MCOS, const MCSection *Section);
+ };
+
+ /// MCLineSection - Instances of this class represent the line information
+ /// for a section where machine instructions have been assembled after seeing
+ /// .loc directives. This is the information used to build the dwarf line
+ /// table for a section.
+ class MCLineSection {
+
+ private:
+ MCLineSection(const MCLineSection&); // DO NOT IMPLEMENT
+ void operator=(const MCLineSection&); // DO NOT IMPLEMENT
+
+ public:
+ // Constructor to create an MCLineSection with an empty MCLineEntries
+ // vector.
+ MCLineSection() {}
+
+ // addLineEntry - adds an entry to this MCLineSection's line entries
+ void addLineEntry(const MCLineEntry &LineEntry) {
+ MCLineEntries.push_back(LineEntry);
+ }
+
+ typedef std::vector<MCLineEntry> MCLineEntryCollection;
+ typedef MCLineEntryCollection::iterator iterator;
+ typedef MCLineEntryCollection::const_iterator const_iterator;
+
+ private:
+ MCLineEntryCollection MCLineEntries;
+
+ public:
+ const MCLineEntryCollection *getMCLineEntries() const {
+ return &MCLineEntries;
+ }
+ };
+
+ class MCDwarfFileTable {
+ public:
+ //
+ // This emits the Dwarf file and the line tables.
+ //
+ static void Emit(MCStreamer *MCOS);
+ };
+
+ class MCDwarfLineAddr {
+ public:
+ /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
+ static void Encode(int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS);
+
+ /// Utility function to emit the encoding to a streamer.
+ static void Emit(MCStreamer *MCOS,
+ int64_t LineDelta,uint64_t AddrDelta);
+
+ /// Utility function to write the encoding to an object writer.
+ static void Write(MCObjectWriter *OW,
+ int64_t LineDelta, uint64_t AddrDelta);
+ };
+
+ class MCCFIInstruction {
+ public:
+ enum OpType { SameValue, Remember, Restore, Move, RelMove };
+ private:
+ OpType Operation;
+ MCSymbol *Label;
+ // Move to & from location.
+ MachineLocation Destination;
+ MachineLocation Source;
+ public:
+ MCCFIInstruction(OpType Op, MCSymbol *L)
+ : Operation(Op), Label(L) {
+ assert(Op == Remember || Op == Restore);
+ }
+ MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register)
+ : Operation(Op), Label(L), Destination(Register) {
+ assert(Op == SameValue);
+ }
+ MCCFIInstruction(MCSymbol *L, const MachineLocation &D,
+ const MachineLocation &S)
+ : Operation(Move), Label(L), Destination(D), Source(S) {
+ }
+ MCCFIInstruction(OpType Op, MCSymbol *L, const MachineLocation &D,
+ const MachineLocation &S)
+ : Operation(Op), Label(L), Destination(D), Source(S) {
+ assert(Op == RelMove);
+ }
+ OpType getOperation() const { return Operation; }
+ MCSymbol *getLabel() const { return Label; }
+ const MachineLocation &getDestination() const { return Destination; }
+ const MachineLocation &getSource() const { return Source; }
+ };
+
+ struct MCDwarfFrameInfo {
+ MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0),
+ Function(0), Instructions(), PersonalityEncoding(),
+ LsdaEncoding(0), CompactUnwindEncoding(0) {}
+ MCSymbol *Begin;
+ MCSymbol *End;
+ const MCSymbol *Personality;
+ const MCSymbol *Lsda;
+ const MCSymbol *Function;
+ std::vector<MCCFIInstruction> Instructions;
+ unsigned PersonalityEncoding;
+ unsigned LsdaEncoding;
+ uint32_t CompactUnwindEncoding;
+ };
+
+ class MCDwarfFrameEmitter {
+ public:
+ //
+ // This emits the frame info section.
+ //
+ static void Emit(MCStreamer &streamer, bool usingCFI,
+ bool isEH);
+ static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta);
+ static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS);
+ };
} // end namespace llvm
#endif
diff --git a/src/LLVM/include/llvm/MC/MCELFObjectWriter.h b/src/LLVM/include/llvm/MC/MCELFObjectWriter.h
new file mode 100644
index 0000000..3c150dc
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCELFObjectWriter.h
@@ -0,0 +1,47 @@
+//===-- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCELFOBJECTWRITER_H
+#define LLVM_MC_MCELFOBJECTWRITER_H
+
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+class MCELFObjectTargetWriter {
+ const Triple::OSType OSType;
+ const uint16_t EMachine;
+ const unsigned HasRelocationAddend : 1;
+ const unsigned Is64Bit : 1;
+protected:
+ MCELFObjectTargetWriter(bool Is64Bit_, Triple::OSType OSType_,
+ uint16_t EMachine_, bool HasRelocationAddend_);
+
+public:
+ virtual ~MCELFObjectTargetWriter();
+
+ /// @name Accessors
+ /// @{
+ Triple::OSType getOSType() { return OSType; }
+ uint16_t getEMachine() { return EMachine; }
+ bool hasRelocationAddend() { return HasRelocationAddend; }
+ bool is64Bit() { return Is64Bit; }
+ /// @}
+};
+
+/// \brief Construct a new ELF writer instance.
+///
+/// \param MOTW - The target specific ELF writer subclass.
+/// \param OS - The stream to write to.
+/// \returns The constructed object writer.
+MCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
+ raw_ostream &OS, bool IsLittleEndian);
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/MCELFSymbolFlags.h b/src/LLVM/include/llvm/MC/MCELFSymbolFlags.h
new file mode 100644
index 0000000..2225ea0
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCELFSymbolFlags.h
@@ -0,0 +1,58 @@
+//===- MCELFSymbolFlags.h - ELF Symbol Flags ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SymbolFlags used for the ELF target.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCELFSYMBOLFLAGS_H
+#define LLVM_MC_MCELFSYMBOLFLAGS_H
+
+#include "llvm/Support/ELF.h"
+
+// Because all the symbol flags need to be stored in the MCSymbolData
+// 'flags' variable we need to provide shift constants per flag type.
+
+namespace llvm {
+ enum {
+ ELF_STT_Shift = 0, // Shift value for STT_* flags.
+ ELF_STB_Shift = 4, // Shift value for STB_* flags.
+ ELF_STV_Shift = 8, // Shift value for STV_* flags.
+ ELF_Other_Shift = 10 // Shift value for other flags.
+ };
+
+ enum SymbolFlags {
+ ELF_STB_Local = (ELF::STB_LOCAL << ELF_STB_Shift),
+ ELF_STB_Global = (ELF::STB_GLOBAL << ELF_STB_Shift),
+ ELF_STB_Weak = (ELF::STB_WEAK << ELF_STB_Shift),
+ ELF_STB_Loproc = (ELF::STB_LOPROC << ELF_STB_Shift),
+ ELF_STB_Hiproc = (ELF::STB_HIPROC << ELF_STB_Shift),
+
+ ELF_STT_Notype = (ELF::STT_NOTYPE << ELF_STT_Shift),
+ ELF_STT_Object = (ELF::STT_OBJECT << ELF_STT_Shift),
+ ELF_STT_Func = (ELF::STT_FUNC << ELF_STT_Shift),
+ ELF_STT_Section = (ELF::STT_SECTION << ELF_STT_Shift),
+ ELF_STT_File = (ELF::STT_FILE << ELF_STT_Shift),
+ ELF_STT_Common = (ELF::STT_COMMON << ELF_STT_Shift),
+ ELF_STT_Tls = (ELF::STT_TLS << ELF_STT_Shift),
+ ELF_STT_Loproc = (ELF::STT_LOPROC << ELF_STT_Shift),
+ ELF_STT_Hiproc = (ELF::STT_HIPROC << ELF_STT_Shift),
+
+ ELF_STV_Default = (ELF::STV_DEFAULT << ELF_STV_Shift),
+ ELF_STV_Internal = (ELF::STV_INTERNAL << ELF_STV_Shift),
+ ELF_STV_Hidden = (ELF::STV_HIDDEN << ELF_STV_Shift),
+ ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift),
+
+ ELF_Other_Weakref = (1 << ELF_Other_Shift),
+ ELF_Other_ThumbFunc = (2 << ELF_Other_Shift)
+ };
+
+} // end namespace llvm
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/MCExpr.h b/src/LLVM/include/llvm/MC/MCExpr.h
index 1f9b8f2..0f28599 100644
--- a/src/LLVM/include/llvm/MC/MCExpr.h
+++ b/src/LLVM/include/llvm/MC/MCExpr.h
@@ -10,17 +10,22 @@
#ifndef LLVM_MC_MCEXPR_H
#define LLVM_MC_MCEXPR_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Casting.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class MCAsmInfo;
class MCAsmLayout;
+class MCAssembler;
class MCContext;
+class MCSection;
+class MCSectionData;
class MCSymbol;
class MCValue;
class raw_ostream;
class StringRef;
+typedef DenseMap<const MCSectionData*, uint64_t> SectionAddrMap;
/// MCExpr - Base class for the full range of assembler expressions which are
/// needed for parsing.
@@ -40,9 +45,16 @@
MCExpr(const MCExpr&); // DO NOT IMPLEMENT
void operator=(const MCExpr&); // DO NOT IMPLEMENT
+ bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
+ const MCAsmLayout *Layout,
+ const SectionAddrMap *Addrs) const;
protected:
explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {}
+ bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
+ const MCAsmLayout *Layout,
+ const SectionAddrMap *Addrs,
+ bool InSet) const;
public:
/// @name Accessors
/// @{
@@ -67,7 +79,11 @@
/// values. If not given, then only non-symbolic expressions will be
/// evaluated.
/// @result - True on success.
- bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout *Layout = 0) const;
+ bool EvaluateAsAbsolute(int64_t &Res) const;
+ bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
+ bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
+ bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout,
+ const SectionAddrMap &Addrs) const;
/// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable
/// value, i.e. an expression of the fixed form (a - b + constant).
@@ -75,7 +91,13 @@
/// @param Res - The relocatable value, if evaluation succeeds.
/// @param Layout - The assembler layout object to use for evaluating values.
/// @result - True on success.
- bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout = 0) const;
+ bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout &Layout) const;
+
+ /// FindAssociatedSection - Find the "associated section" for this expression,
+ /// which is currently defined as the absolute section for constants, or
+ /// otherwise the section associated with the first defined symbol in the
+ /// expression.
+ const MCSection *FindAssociatedSection() const;
/// @}
@@ -132,12 +154,27 @@
VK_GOTTPOFF,
VK_INDNTPOFF,
VK_NTPOFF,
+ VK_GOTNTPOFF,
VK_PLT,
VK_TLSGD,
+ VK_TLSLD,
+ VK_TLSLDM,
VK_TPOFF,
- VK_ARM_HI16, // The R_ARM_MOVT_ABS relocation (:upper16: in the asm file)
- VK_ARM_LO16, // The R_ARM_MOVW_ABS_NC relocation (:lower16: in the asm file)
- VK_TLVP // Mach-O thread local variable relocation
+ VK_DTPOFF,
+ VK_TLVP, // Mach-O thread local variable relocation
+ // FIXME: We'd really like to use the generic Kinds listed above for these.
+ VK_ARM_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT
+ VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF
+ VK_ARM_GOT,
+ VK_ARM_GOTOFF,
+ VK_ARM_TPOFF,
+ VK_ARM_GOTTPOFF,
+
+ VK_PPC_TOC,
+ VK_PPC_DARWIN_HA16, // ha16(symbol)
+ VK_PPC_DARWIN_LO16, // lo16(symbol)
+ VK_PPC_GAS_HA16, // symbol@ha
+ VK_PPC_GAS_LO16 // symbol@l
};
private:
@@ -162,7 +199,7 @@
MCContext &Ctx);
static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind,
MCContext &Ctx);
-
+
/// @}
/// @name Accessors
/// @{
@@ -391,7 +428,8 @@
virtual void PrintImpl(raw_ostream &OS) const = 0;
virtual bool EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const = 0;
-
+ virtual void AddValueSymbols(MCAssembler *) const = 0;
+ virtual const MCSection *FindAssociatedSection() const = 0;
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Target;
diff --git a/src/LLVM/include/llvm/MC/MCFixup.h b/src/LLVM/include/llvm/MC/MCFixup.h
index eed4c34..6fde797 100644
--- a/src/LLVM/include/llvm/MC/MCFixup.h
+++ b/src/LLVM/include/llvm/MC/MCFixup.h
@@ -10,7 +10,7 @@
#ifndef LLVM_MC_MCFIXUP_H
#define LLVM_MC_MCFIXUP_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
@@ -22,6 +22,10 @@
FK_Data_2, ///< A two-byte fixup.
FK_Data_4, ///< A four-byte fixup.
FK_Data_8, ///< A eight-byte fixup.
+ FK_PCRel_1, ///< A one-byte pc relative fixup.
+ FK_PCRel_2, ///< A two-byte pc relative fixup.
+ FK_PCRel_4, ///< A four-byte pc relative fixup.
+ FK_PCRel_8, ///< A eight-byte pc relative fixup.
FirstTargetFixupKind = 128,
@@ -77,13 +81,13 @@
/// getKindForSize - Return the generic fixup kind for a value with the given
/// size. It is an error to pass an unsupported size.
- static MCFixupKind getKindForSize(unsigned Size) {
+ static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) {
switch (Size) {
default: assert(0 && "Invalid generic fixup size!");
- case 1: return FK_Data_1;
- case 2: return FK_Data_2;
- case 4: return FK_Data_4;
- case 8: return FK_Data_8;
+ case 1: return isPCRel ? FK_PCRel_1 : FK_Data_1;
+ case 2: return isPCRel ? FK_PCRel_2 : FK_Data_2;
+ case 4: return isPCRel ? FK_PCRel_4 : FK_Data_4;
+ case 8: return isPCRel ? FK_PCRel_8 : FK_Data_8;
}
}
};
diff --git a/src/LLVM/include/llvm/MC/MCFixupKindInfo.h b/src/LLVM/include/llvm/MC/MCFixupKindInfo.h
new file mode 100644
index 0000000..1961687
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCFixupKindInfo.h
@@ -0,0 +1,43 @@
+//===-- llvm/MC/MCFixupKindInfo.h - Fixup Descriptors -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCFIXUPKINDINFO_H
+#define LLVM_MC_MCFIXUPKINDINFO_H
+
+namespace llvm {
+
+/// MCFixupKindInfo - Target independent information on a fixup kind.
+struct MCFixupKindInfo {
+ enum FixupKindFlags {
+ /// Is this fixup kind PCrelative? This is used by the assembler backend to
+ /// evaluate fixup values in a target independent manner when possible.
+ FKF_IsPCRel = (1 << 0),
+
+ /// Should this fixup kind force a 4-byte aligned effective PC value?
+ FKF_IsAlignedDownTo32Bits = (1 << 1)
+ };
+
+ /// A target specific name for the fixup kind. The names will be unique for
+ /// distinct kinds on any given target.
+ const char *Name;
+
+ /// The bit offset to write the relocation into.
+ unsigned TargetOffset;
+
+ /// The number of bits written by this fixup. The bits are assumed to be
+ /// contiguous.
+ unsigned TargetSize;
+
+ /// Flags describing additional information on this fixup kind.
+ unsigned Flags;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/MCInst.h b/src/LLVM/include/llvm/MC/MCInst.h
index dc630fe..d384764 100644
--- a/src/LLVM/include/llvm/MC/MCInst.h
+++ b/src/LLVM/include/llvm/MC/MCInst.h
@@ -18,7 +18,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class raw_ostream;
@@ -33,24 +33,27 @@
kInvalid, ///< Uninitialized.
kRegister, ///< Register operand.
kImmediate, ///< Immediate operand.
+ kFPImmediate, ///< Floating-point immediate operand.
kExpr ///< Relocatable immediate operand.
};
unsigned char Kind;
-
+
union {
unsigned RegVal;
int64_t ImmVal;
+ double FPImmVal;
const MCExpr *ExprVal;
};
public:
-
- MCOperand() : Kind(kInvalid) {}
+
+ MCOperand() : Kind(kInvalid), FPImmVal(0.0) {}
bool isValid() const { return Kind != kInvalid; }
bool isReg() const { return Kind == kRegister; }
bool isImm() const { return Kind == kImmediate; }
+ bool isFPImm() const { return Kind == kFPImmediate; }
bool isExpr() const { return Kind == kExpr; }
-
+
/// getReg - Returns the register number.
unsigned getReg() const {
assert(isReg() && "This is not a register operand!");
@@ -62,7 +65,7 @@
assert(isReg() && "This is not a register operand!");
RegVal = Reg;
}
-
+
int64_t getImm() const {
assert(isImm() && "This is not an immediate");
return ImmVal;
@@ -71,7 +74,17 @@
assert(isImm() && "This is not an immediate");
ImmVal = Val;
}
-
+
+ double getFPImm() const {
+ assert(isFPImm() && "This is not an FP immediate");
+ return FPImmVal;
+ }
+
+ void setFPImm(double Val) {
+ assert(isFPImm() && "This is not an FP immediate");
+ FPImmVal = Val;
+ }
+
const MCExpr *getExpr() const {
assert(isExpr() && "This is not an expression");
return ExprVal;
@@ -80,7 +93,7 @@
assert(isExpr() && "This is not an expression");
ExprVal = Val;
}
-
+
static MCOperand CreateReg(unsigned Reg) {
MCOperand Op;
Op.Kind = kRegister;
@@ -93,6 +106,12 @@
Op.ImmVal = Val;
return Op;
}
+ static MCOperand CreateFPImm(double Val) {
+ MCOperand Op;
+ Op.Kind = kFPImmediate;
+ Op.FPImmVal = Val;
+ return Op;
+ }
static MCOperand CreateExpr(const MCExpr *Val) {
MCOperand Op;
Op.Kind = kExpr;
@@ -104,27 +123,37 @@
void dump() const;
};
-
+
/// MCInst - Instances of this class represent a single low-level machine
-/// instruction.
+/// instruction.
class MCInst {
unsigned Opcode;
SmallVector<MCOperand, 8> Operands;
public:
MCInst() : Opcode(0) {}
-
+
void setOpcode(unsigned Op) { Opcode = Op; }
-
+
unsigned getOpcode() const { return Opcode; }
const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
MCOperand &getOperand(unsigned i) { return Operands[i]; }
unsigned getNumOperands() const { return Operands.size(); }
-
+
void addOperand(const MCOperand &Op) {
Operands.push_back(Op);
}
+ void clear() { Operands.clear(); }
+ size_t size() { return Operands.size(); }
+
+ typedef SmallVector<MCOperand, 8>::iterator iterator;
+ iterator begin() { return Operands.begin(); }
+ iterator end() { return Operands.end(); }
+ iterator insert(iterator I, const MCOperand &Op) {
+ return Operands.insert(I, Op);
+ }
+
void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
void dump() const;
@@ -136,6 +165,15 @@
StringRef Separator = " ") const;
};
+inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
+ MO.print(OS, 0);
+ return OS;
+}
+
+inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
+ MI.print(OS, 0);
+ return OS;
+}
} // end namespace llvm
diff --git a/src/LLVM/include/llvm/MC/MCInstPrinter.h b/src/LLVM/include/llvm/MC/MCInstPrinter.h
index 4839a83..01ad2d3 100644
--- a/src/LLVM/include/llvm/MC/MCInstPrinter.h
+++ b/src/LLVM/include/llvm/MC/MCInstPrinter.h
@@ -25,24 +25,37 @@
/// assembly emission is disable.
raw_ostream *CommentStream;
const MCAsmInfo &MAI;
+
+ /// The current set of available features.
+ unsigned AvailableFeatures;
+
+ /// Utility function for printing annotations.
+ void printAnnotation(raw_ostream &OS, StringRef Annot);
public:
MCInstPrinter(const MCAsmInfo &mai)
- : CommentStream(0), MAI(mai) {}
-
+ : CommentStream(0), MAI(mai), AvailableFeatures(0) {}
+
virtual ~MCInstPrinter();
/// setCommentStream - Specify a stream to emit comments to.
void setCommentStream(raw_ostream &OS) { CommentStream = &OS; }
-
+
/// printInst - Print the specified MCInst to the specified raw_ostream.
///
- virtual void printInst(const MCInst *MI, raw_ostream &OS) = 0;
-
+ virtual void printInst(const MCInst *MI, raw_ostream &OS,
+ StringRef Annot) = 0;
+
/// getOpcodeName - Return the name of the specified opcode enum (e.g.
/// "MOV32ri") or empty if we can't resolve it.
virtual StringRef getOpcodeName(unsigned Opcode) const;
+
+ /// printRegName - Print the assembler register name.
+ virtual void printRegName(raw_ostream &OS, unsigned RegNo) const;
+
+ unsigned getAvailableFeatures() const { return AvailableFeatures; }
+ void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
};
-
+
} // namespace llvm
#endif
diff --git a/src/LLVM/include/llvm/MC/MCInstrAnalysis.h b/src/LLVM/include/llvm/MC/MCInstrAnalysis.h
new file mode 100644
index 0000000..8f3c499
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCInstrAnalysis.h
@@ -0,0 +1,61 @@
+//===-- llvm/MC/MCInstrAnalysis.h - InstrDesc target hooks ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MCInstrAnalysis class which the MCTargetDescs can
+// derive from to give additional information to MC.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/MC/MCInstrInfo.h"
+
+namespace llvm {
+
+class MCInstrAnalysis {
+protected:
+ friend class Target;
+ const MCInstrInfo *Info;
+
+public:
+ MCInstrAnalysis(const MCInstrInfo *Info) : Info(Info) {}
+
+ virtual ~MCInstrAnalysis() {}
+
+ virtual bool isBranch(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isBranch();
+ }
+
+ virtual bool isConditionalBranch(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isBranch();
+ }
+
+ virtual bool isUnconditionalBranch(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isUnconditionalBranch();
+ }
+
+ virtual bool isIndirectBranch(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isIndirectBranch();
+ }
+
+ virtual bool isCall(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isCall();
+ }
+
+ virtual bool isReturn(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isReturn();
+ }
+
+ /// evaluateBranch - Given a branch instruction try to get the address the
+ /// branch targets. Otherwise return -1.
+ virtual uint64_t
+ evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size) const;
+};
+
+}
diff --git a/src/LLVM/include/llvm/MC/MCInstrDesc.h b/src/LLVM/include/llvm/MC/MCInstrDesc.h
new file mode 100644
index 0000000..aafa800
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCInstrDesc.h
@@ -0,0 +1,537 @@
+//===-- llvm/Mc/McInstrDesc.h - Instruction Descriptors -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MCOperandInfo and MCInstrDesc classes, which
+// are used to describe target instructions and their operands.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRDESC_H
+#define LLVM_MC_MCINSTRDESC_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Machine Operand Flags and Description
+//===----------------------------------------------------------------------===//
+
+namespace MCOI {
+ // Operand constraints
+ enum OperandConstraint {
+ TIED_TO = 0, // Must be allocated the same register as.
+ EARLY_CLOBBER // Operand is an early clobber register operand
+ };
+
+ /// OperandFlags - These are flags set on operands, but should be considered
+ /// private, all access should go through the MCOperandInfo accessors.
+ /// See the accessors for a description of what these are.
+ enum OperandFlags {
+ LookupPtrRegClass = 0,
+ Predicate,
+ OptionalDef
+ };
+
+ /// Operand Type - Operands are tagged with one of the values of this enum.
+ enum OperandType {
+ OPERAND_UNKNOWN,
+ OPERAND_IMMEDIATE,
+ OPERAND_REGISTER,
+ OPERAND_MEMORY,
+ OPERAND_PCREL
+ };
+}
+
+/// MCOperandInfo - This holds information about one operand of a machine
+/// instruction, indicating the register class for register operands, etc.
+///
+class MCOperandInfo {
+public:
+ /// RegClass - This specifies the register class enumeration of the operand
+ /// if the operand is a register. If isLookupPtrRegClass is set, then this is
+ /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to
+ /// get a dynamic register class.
+ short RegClass;
+
+ /// Flags - These are flags from the MCOI::OperandFlags enum.
+ unsigned short Flags;
+
+ /// Lower 16 bits are used to specify which constraints are set. The higher 16
+ /// bits are used to specify the value of constraints (4 bits each).
+ unsigned Constraints;
+
+ /// OperandType - Information about the type of the operand.
+ MCOI::OperandType OperandType;
+ /// Currently no other information.
+
+ /// isLookupPtrRegClass - Set if this operand is a pointer value and it
+ /// requires a callback to look up its register class.
+ bool isLookupPtrRegClass() const {return Flags&(1 <<MCOI::LookupPtrRegClass);}
+
+ /// isPredicate - Set if this is one of the operands that made up of
+ /// the predicate operand that controls an isPredicable() instruction.
+ bool isPredicate() const { return Flags & (1 << MCOI::Predicate); }
+
+ /// isOptionalDef - Set if this operand is a optional def.
+ ///
+ bool isOptionalDef() const { return Flags & (1 << MCOI::OptionalDef); }
+};
+
+
+//===----------------------------------------------------------------------===//
+// Machine Instruction Flags and Description
+//===----------------------------------------------------------------------===//
+
+/// MCInstrDesc flags - These should be considered private to the
+/// implementation of the MCInstrDesc class. Clients should use the predicate
+/// methods on MCInstrDesc, not use these directly. These all correspond to
+/// bitfields in the MCInstrDesc::Flags field.
+namespace MCID {
+ enum {
+ Variadic = 0,
+ HasOptionalDef,
+ Pseudo,
+ Return,
+ Call,
+ Barrier,
+ Terminator,
+ Branch,
+ IndirectBranch,
+ Compare,
+ MoveImm,
+ Bitcast,
+ DelaySlot,
+ FoldableAsLoad,
+ MayLoad,
+ MayStore,
+ Predicable,
+ NotDuplicable,
+ UnmodeledSideEffects,
+ Commutable,
+ ConvertibleTo3Addr,
+ UsesCustomInserter,
+ HasPostISelHook,
+ Rematerializable,
+ CheapAsAMove,
+ ExtraSrcRegAllocReq,
+ ExtraDefRegAllocReq
+ };
+}
+
+/// MCInstrDesc - Describe properties that are true of each instruction in the
+/// target description file. This captures information about side effects,
+/// register use and many other things. There is one instance of this struct
+/// for each target instruction class, and the MachineInstr class points to
+/// this struct directly to describe itself.
+class MCInstrDesc {
+public:
+ unsigned short Opcode; // The opcode number
+ unsigned short NumOperands; // Num of args (may be more if variable_ops)
+ unsigned short NumDefs; // Num of args that are definitions
+ unsigned short SchedClass; // enum identifying instr sched class
+ unsigned short Size; // Number of bytes in encoding.
+ const char * Name; // Name of the instruction record in td file
+ unsigned Flags; // Flags identifying machine instr class
+ uint64_t TSFlags; // Target Specific Flag values
+ const unsigned *ImplicitUses; // Registers implicitly read by this instr
+ const unsigned *ImplicitDefs; // Registers implicitly defined by this instr
+ const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands
+
+ /// getOperandConstraint - Returns the value of the specific constraint if
+ /// it is set. Returns -1 if it is not set.
+ int getOperandConstraint(unsigned OpNum,
+ MCOI::OperandConstraint Constraint) const {
+ if (OpNum < NumOperands &&
+ (OpInfo[OpNum].Constraints & (1 << Constraint))) {
+ unsigned Pos = 16 + Constraint * 4;
+ return (int)(OpInfo[OpNum].Constraints >> Pos) & 0xf;
+ }
+ return -1;
+ }
+
+ /// getOpcode - Return the opcode number for this descriptor.
+ unsigned getOpcode() const {
+ return Opcode;
+ }
+
+ /// getName - Return the name of the record in the .td file for this
+ /// instruction, for example "ADD8ri".
+ const char *getName() const {
+ return Name;
+ }
+
+ /// getNumOperands - Return the number of declared MachineOperands for this
+ /// MachineInstruction. Note that variadic (isVariadic() returns true)
+ /// instructions may have additional operands at the end of the list, and note
+ /// that the machine instruction may include implicit register def/uses as
+ /// well.
+ unsigned getNumOperands() const {
+ return NumOperands;
+ }
+
+ /// getNumDefs - Return the number of MachineOperands that are register
+ /// definitions. Register definitions always occur at the start of the
+ /// machine operand list. This is the number of "outs" in the .td file,
+ /// and does not include implicit defs.
+ unsigned getNumDefs() const {
+ return NumDefs;
+ }
+
+ /// isVariadic - Return true if this instruction can have a variable number of
+ /// operands. In this case, the variable operands will be after the normal
+ /// operands but before the implicit definitions and uses (if any are
+ /// present).
+ bool isVariadic() const {
+ return Flags & (1 << MCID::Variadic);
+ }
+
+ /// hasOptionalDef - Set if this instruction has an optional definition, e.g.
+ /// ARM instructions which can set condition code if 's' bit is set.
+ bool hasOptionalDef() const {
+ return Flags & (1 << MCID::HasOptionalDef);
+ }
+
+ /// getImplicitUses - Return a list of registers that are potentially
+ /// read by any instance of this machine instruction. For example, on X86,
+ /// the "adc" instruction adds two register operands and adds the carry bit in
+ /// from the flags register. In this case, the instruction is marked as
+ /// implicitly reading the flags. Likewise, the variable shift instruction on
+ /// X86 is marked as implicitly reading the 'CL' register, which it always
+ /// does.
+ ///
+ /// This method returns null if the instruction has no implicit uses.
+ const unsigned *getImplicitUses() const {
+ return ImplicitUses;
+ }
+
+ /// getNumImplicitUses - Return the number of implicit uses this instruction
+ /// has.
+ unsigned getNumImplicitUses() const {
+ if (ImplicitUses == 0) return 0;
+ unsigned i = 0;
+ for (; ImplicitUses[i]; ++i) /*empty*/;
+ return i;
+ }
+
+ /// getImplicitDefs - Return a list of registers that are potentially
+ /// written by any instance of this machine instruction. For example, on X86,
+ /// many instructions implicitly set the flags register. In this case, they
+ /// are marked as setting the FLAGS. Likewise, many instructions always
+ /// deposit their result in a physical register. For example, the X86 divide
+ /// instruction always deposits the quotient and remainder in the EAX/EDX
+ /// registers. For that instruction, this will return a list containing the
+ /// EAX/EDX/EFLAGS registers.
+ ///
+ /// This method returns null if the instruction has no implicit defs.
+ const unsigned *getImplicitDefs() const {
+ return ImplicitDefs;
+ }
+
+ /// getNumImplicitDefs - Return the number of implicit defs this instruction
+ /// has.
+ unsigned getNumImplicitDefs() const {
+ if (ImplicitDefs == 0) return 0;
+ unsigned i = 0;
+ for (; ImplicitDefs[i]; ++i) /*empty*/;
+ return i;
+ }
+
+ /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly
+ /// uses the specified physical register.
+ bool hasImplicitUseOfPhysReg(unsigned Reg) const {
+ if (const unsigned *ImpUses = ImplicitUses)
+ for (; *ImpUses; ++ImpUses)
+ if (*ImpUses == Reg) return true;
+ return false;
+ }
+
+ /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly
+ /// defines the specified physical register.
+ bool hasImplicitDefOfPhysReg(unsigned Reg) const {
+ if (const unsigned *ImpDefs = ImplicitDefs)
+ for (; *ImpDefs; ++ImpDefs)
+ if (*ImpDefs == Reg) return true;
+ return false;
+ }
+
+ /// getSchedClass - Return the scheduling class for this instruction. The
+ /// scheduling class is an index into the InstrItineraryData table. This
+ /// returns zero if there is no known scheduling information for the
+ /// instruction.
+ ///
+ unsigned getSchedClass() const {
+ return SchedClass;
+ }
+
+ /// getSize - Return the number of bytes in the encoding of this instruction,
+ /// or zero if the encoding size cannot be known from the opcode.
+ unsigned getSize() const {
+ return Size;
+ }
+
+ /// isPseudo - Return true if this is a pseudo instruction that doesn't
+ /// correspond to a real machine instruction.
+ ///
+ bool isPseudo() const {
+ return Flags & (1 << MCID::Pseudo);
+ }
+
+ bool isReturn() const {
+ return Flags & (1 << MCID::Return);
+ }
+
+ bool isCall() const {
+ return Flags & (1 << MCID::Call);
+ }
+
+ /// isBarrier - Returns true if the specified instruction stops control flow
+ /// from executing the instruction immediately following it. Examples include
+ /// unconditional branches and return instructions.
+ bool isBarrier() const {
+ return Flags & (1 << MCID::Barrier);
+ }
+
+ /// findFirstPredOperandIdx() - Find the index of the first operand in the
+ /// operand list that is used to represent the predicate. It returns -1 if
+ /// none is found.
+ int findFirstPredOperandIdx() const {
+ if (isPredicable()) {
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ if (OpInfo[i].isPredicate())
+ return i;
+ }
+ return -1;
+ }
+
+ /// isTerminator - Returns true if this instruction part of the terminator for
+ /// a basic block. Typically this is things like return and branch
+ /// instructions.
+ ///
+ /// Various passes use this to insert code into the bottom of a basic block,
+ /// but before control flow occurs.
+ bool isTerminator() const {
+ return Flags & (1 << MCID::Terminator);
+ }
+
+ /// isBranch - Returns true if this is a conditional, unconditional, or
+ /// indirect branch. Predicates below can be used to discriminate between
+ /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to
+ /// get more information.
+ bool isBranch() const {
+ return Flags & (1 << MCID::Branch);
+ }
+
+ /// isIndirectBranch - Return true if this is an indirect branch, such as a
+ /// branch through a register.
+ bool isIndirectBranch() const {
+ return Flags & (1 << MCID::IndirectBranch);
+ }
+
+ /// isConditionalBranch - Return true if this is a branch which may fall
+ /// through to the next instruction or may transfer control flow to some other
+ /// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more
+ /// information about this branch.
+ bool isConditionalBranch() const {
+ return isBranch() & !isBarrier() & !isIndirectBranch();
+ }
+
+ /// isUnconditionalBranch - Return true if this is a branch which always
+ /// transfers control flow to some other block. The
+ /// TargetInstrInfo::AnalyzeBranch method can be used to get more information
+ /// about this branch.
+ bool isUnconditionalBranch() const {
+ return isBranch() & isBarrier() & !isIndirectBranch();
+ }
+
+ // isPredicable - Return true if this instruction has a predicate operand that
+ // controls execution. It may be set to 'always', or may be set to other
+ /// values. There are various methods in TargetInstrInfo that can be used to
+ /// control and modify the predicate in this instruction.
+ bool isPredicable() const {
+ return Flags & (1 << MCID::Predicable);
+ }
+
+ /// isCompare - Return true if this instruction is a comparison.
+ bool isCompare() const {
+ return Flags & (1 << MCID::Compare);
+ }
+
+ /// isMoveImmediate - Return true if this instruction is a move immediate
+ /// (including conditional moves) instruction.
+ bool isMoveImmediate() const {
+ return Flags & (1 << MCID::MoveImm);
+ }
+
+ /// isBitcast - Return true if this instruction is a bitcast instruction.
+ ///
+ bool isBitcast() const {
+ return Flags & (1 << MCID::Bitcast);
+ }
+
+ /// isNotDuplicable - Return true if this instruction cannot be safely
+ /// duplicated. For example, if the instruction has a unique labels attached
+ /// to it, duplicating it would cause multiple definition errors.
+ bool isNotDuplicable() const {
+ return Flags & (1 << MCID::NotDuplicable);
+ }
+
+ /// hasDelaySlot - Returns true if the specified instruction has a delay slot
+ /// which must be filled by the code generator.
+ bool hasDelaySlot() const {
+ return Flags & (1 << MCID::DelaySlot);
+ }
+
+ /// canFoldAsLoad - Return true for instructions that can be folded as
+ /// memory operands in other instructions. The most common use for this
+ /// is instructions that are simple loads from memory that don't modify
+ /// the loaded value in any way, but it can also be used for instructions
+ /// that can be expressed as constant-pool loads, such as V_SETALLONES
+ /// on x86, to allow them to be folded when it is beneficial.
+ /// This should only be set on instructions that return a value in their
+ /// only virtual register definition.
+ bool canFoldAsLoad() const {
+ return Flags & (1 << MCID::FoldableAsLoad);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Side Effect Analysis
+ //===--------------------------------------------------------------------===//
+
+ /// mayLoad - Return true if this instruction could possibly read memory.
+ /// Instructions with this flag set are not necessarily simple load
+ /// instructions, they may load a value and modify it, for example.
+ bool mayLoad() const {
+ return Flags & (1 << MCID::MayLoad);
+ }
+
+
+ /// mayStore - Return true if this instruction could possibly modify memory.
+ /// Instructions with this flag set are not necessarily simple store
+ /// instructions, they may store a modified value based on their operands, or
+ /// may not actually modify anything, for example.
+ bool mayStore() const {
+ return Flags & (1 << MCID::MayStore);
+ }
+
+ /// hasUnmodeledSideEffects - Return true if this instruction has side
+ /// effects that are not modeled by other flags. This does not return true
+ /// for instructions whose effects are captured by:
+ ///
+ /// 1. Their operand list and implicit definition/use list. Register use/def
+ /// info is explicit for instructions.
+ /// 2. Memory accesses. Use mayLoad/mayStore.
+ /// 3. Calling, branching, returning: use isCall/isReturn/isBranch.
+ ///
+ /// Examples of side effects would be modifying 'invisible' machine state like
+ /// a control register, flushing a cache, modifying a register invisible to
+ /// LLVM, etc.
+ ///
+ bool hasUnmodeledSideEffects() const {
+ return Flags & (1 << MCID::UnmodeledSideEffects);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Flags that indicate whether an instruction can be modified by a method.
+ //===--------------------------------------------------------------------===//
+
+ /// isCommutable - Return true if this may be a 2- or 3-address
+ /// instruction (of the form "X = op Y, Z, ..."), which produces the same
+ /// result if Y and Z are exchanged. If this flag is set, then the
+ /// TargetInstrInfo::commuteInstruction method may be used to hack on the
+ /// instruction.
+ ///
+ /// Note that this flag may be set on instructions that are only commutable
+ /// sometimes. In these cases, the call to commuteInstruction will fail.
+ /// Also note that some instructions require non-trivial modification to
+ /// commute them.
+ bool isCommutable() const {
+ return Flags & (1 << MCID::Commutable);
+ }
+
+ /// isConvertibleTo3Addr - Return true if this is a 2-address instruction
+ /// which can be changed into a 3-address instruction if needed. Doing this
+ /// transformation can be profitable in the register allocator, because it
+ /// means that the instruction can use a 2-address form if possible, but
+ /// degrade into a less efficient form if the source and dest register cannot
+ /// be assigned to the same register. For example, this allows the x86
+ /// backend to turn a "shl reg, 3" instruction into an LEA instruction, which
+ /// is the same speed as the shift but has bigger code size.
+ ///
+ /// If this returns true, then the target must implement the
+ /// TargetInstrInfo::convertToThreeAddress method for this instruction, which
+ /// is allowed to fail if the transformation isn't valid for this specific
+ /// instruction (e.g. shl reg, 4 on x86).
+ ///
+ bool isConvertibleTo3Addr() const {
+ return Flags & (1 << MCID::ConvertibleTo3Addr);
+ }
+
+ /// usesCustomInsertionHook - Return true if this instruction requires
+ /// custom insertion support when the DAG scheduler is inserting it into a
+ /// machine basic block. If this is true for the instruction, it basically
+ /// means that it is a pseudo instruction used at SelectionDAG time that is
+ /// expanded out into magic code by the target when MachineInstrs are formed.
+ ///
+ /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method
+ /// is used to insert this into the MachineBasicBlock.
+ bool usesCustomInsertionHook() const {
+ return Flags & (1 << MCID::UsesCustomInserter);
+ }
+
+ /// hasPostISelHook - Return true if this instruction requires *adjustment*
+ /// after instruction selection by calling a target hook. For example, this
+ /// can be used to fill in ARM 's' optional operand depending on whether
+ /// the conditional flag register is used.
+ bool hasPostISelHook() const {
+ return Flags & (1 << MCID::HasPostISelHook);
+ }
+
+ /// isRematerializable - Returns true if this instruction is a candidate for
+ /// remat. This flag is deprecated, please don't use it anymore. If this
+ /// flag is set, the isReallyTriviallyReMaterializable() method is called to
+ /// verify the instruction is really rematable.
+ bool isRematerializable() const {
+ return Flags & (1 << MCID::Rematerializable);
+ }
+
+ /// isAsCheapAsAMove - Returns true if this instruction has the same cost (or
+ /// less) than a move instruction. This is useful during certain types of
+ /// optimizations (e.g., remat during two-address conversion or machine licm)
+ /// where we would like to remat or hoist the instruction, but not if it costs
+ /// more than moving the instruction into the appropriate register. Note, we
+ /// are not marking copies from and to the same register class with this flag.
+ bool isAsCheapAsAMove() const {
+ return Flags & (1 << MCID::CheapAsAMove);
+ }
+
+ /// hasExtraSrcRegAllocReq - Returns true if this instruction source operands
+ /// have special register allocation requirements that are not captured by the
+ /// operand register classes. e.g. ARM::STRD's two source registers must be an
+ /// even / odd pair, ARM::STM registers have to be in ascending order.
+ /// Post-register allocation passes should not attempt to change allocations
+ /// for sources of instructions with this flag.
+ bool hasExtraSrcRegAllocReq() const {
+ return Flags & (1 << MCID::ExtraSrcRegAllocReq);
+ }
+
+ /// hasExtraDefRegAllocReq - Returns true if this instruction def operands
+ /// have special register allocation requirements that are not captured by the
+ /// operand register classes. e.g. ARM::LDRD's two def registers must be an
+ /// even / odd pair, ARM::LDM registers have to be in ascending order.
+ /// Post-register allocation passes should not attempt to change allocations
+ /// for definitions of instructions with this flag.
+ bool hasExtraDefRegAllocReq() const {
+ return Flags & (1 << MCID::ExtraDefRegAllocReq);
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/MCInstrInfo.h b/src/LLVM/include/llvm/MC/MCInstrInfo.h
new file mode 100644
index 0000000..a63e5fa
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCInstrInfo.h
@@ -0,0 +1,51 @@
+//===-- llvm/MC/MCInstrInfo.h - Target Instruction Info ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the target machine instruction set.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRINFO_H
+#define LLVM_MC_MCINSTRINFO_H
+
+#include "llvm/MC/MCInstrDesc.h"
+#include <cassert>
+
+namespace llvm {
+
+//---------------------------------------------------------------------------
+///
+/// MCInstrInfo - Interface to description of machine instruction set
+///
+class MCInstrInfo {
+ const MCInstrDesc *Desc; // Raw array to allow static init'n
+ unsigned NumOpcodes; // Number of entries in the desc array
+
+public:
+ /// InitMCInstrInfo - Initialize MCInstrInfo, called by TableGen
+ /// auto-generated routines. *DO NOT USE*.
+ void InitMCInstrInfo(const MCInstrDesc *D, unsigned NO) {
+ Desc = D;
+ NumOpcodes = NO;
+ }
+
+ unsigned getNumOpcodes() const { return NumOpcodes; }
+
+ /// get - Return the machine instruction descriptor that corresponds to the
+ /// specified instruction opcode.
+ ///
+ const MCInstrDesc &get(unsigned Opcode) const {
+ assert(Opcode < NumOpcodes && "Invalid opcode!");
+ return Desc[Opcode];
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/MCInstrItineraries.h b/src/LLVM/include/llvm/MC/MCInstrItineraries.h
new file mode 100644
index 0000000..e942892
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCInstrItineraries.h
@@ -0,0 +1,253 @@
+//===-- llvm/MC/MCInstrItineraries.h - Scheduling ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the structures used for instruction
+// itineraries, stages, and operand reads/writes. This is used by
+// schedulers to determine instruction stages and latencies.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRITINERARIES_H
+#define LLVM_MC_MCINSTRITINERARIES_H
+
+#include <algorithm>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// Instruction stage - These values represent a non-pipelined step in
+/// the execution of an instruction. Cycles represents the number of
+/// discrete time slots needed to complete the stage. Units represent
+/// the choice of functional units that can be used to complete the
+/// stage. Eg. IntUnit1, IntUnit2. NextCycles indicates how many
+/// cycles should elapse from the start of this stage to the start of
+/// the next stage in the itinerary. A value of -1 indicates that the
+/// next stage should start immediately after the current one.
+/// For example:
+///
+/// { 1, x, -1 }
+/// indicates that the stage occupies FU x for 1 cycle and that
+/// the next stage starts immediately after this one.
+///
+/// { 2, x|y, 1 }
+/// indicates that the stage occupies either FU x or FU y for 2
+/// consecuative cycles and that the next stage starts one cycle
+/// after this stage starts. That is, the stage requirements
+/// overlap in time.
+///
+/// { 1, x, 0 }
+/// indicates that the stage occupies FU x for 1 cycle and that
+/// the next stage starts in this same cycle. This can be used to
+/// indicate that the instruction requires multiple stages at the
+/// same time.
+///
+/// FU reservation can be of two different kinds:
+/// - FUs which instruction actually requires
+/// - FUs which instruction just reserves. Reserved unit is not available for
+/// execution of other instruction. However, several instructions can reserve
+/// the same unit several times.
+/// Such two types of units reservation is used to model instruction domain
+/// change stalls, FUs using the same resource (e.g. same register file), etc.
+
+struct InstrStage {
+ enum ReservationKinds {
+ Required = 0,
+ Reserved = 1
+ };
+
+ unsigned Cycles_; ///< Length of stage in machine cycles
+ unsigned Units_; ///< Choice of functional units
+ int NextCycles_; ///< Number of machine cycles to next stage
+ ReservationKinds Kind_; ///< Kind of the FU reservation
+
+ /// getCycles - returns the number of cycles the stage is occupied
+ unsigned getCycles() const {
+ return Cycles_;
+ }
+
+ /// getUnits - returns the choice of FUs
+ unsigned getUnits() const {
+ return Units_;
+ }
+
+ ReservationKinds getReservationKind() const {
+ return Kind_;
+ }
+
+ /// getNextCycles - returns the number of cycles from the start of
+ /// this stage to the start of the next stage in the itinerary
+ unsigned getNextCycles() const {
+ return (NextCycles_ >= 0) ? (unsigned)NextCycles_ : Cycles_;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+/// Instruction itinerary - An itinerary represents the scheduling
+/// information for an instruction. This includes a set of stages
+/// occupies by the instruction, and the pipeline cycle in which
+/// operands are read and written.
+///
+struct InstrItinerary {
+ unsigned NumMicroOps; ///< # of micro-ops, 0 means it's variable
+ unsigned FirstStage; ///< Index of first stage in itinerary
+ unsigned LastStage; ///< Index of last + 1 stage in itinerary
+ unsigned FirstOperandCycle; ///< Index of first operand rd/wr
+ unsigned LastOperandCycle; ///< Index of last + 1 operand rd/wr
+};
+
+
+//===----------------------------------------------------------------------===//
+/// Instruction itinerary Data - Itinerary data supplied by a subtarget to be
+/// used by a target.
+///
+class InstrItineraryData {
+public:
+ const InstrStage *Stages; ///< Array of stages selected
+ const unsigned *OperandCycles; ///< Array of operand cycles selected
+ const unsigned *Forwardings; ///< Array of pipeline forwarding pathes
+ const InstrItinerary *Itineraries; ///< Array of itineraries selected
+ unsigned IssueWidth; ///< Max issue per cycle. 0=Unknown.
+
+ /// Ctors.
+ ///
+ InstrItineraryData() : Stages(0), OperandCycles(0), Forwardings(0),
+ Itineraries(0), IssueWidth(0) {}
+
+ InstrItineraryData(const InstrStage *S, const unsigned *OS,
+ const unsigned *F, const InstrItinerary *I)
+ : Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I),
+ IssueWidth(0) {}
+
+ /// isEmpty - Returns true if there are no itineraries.
+ ///
+ bool isEmpty() const { return Itineraries == 0; }
+
+ /// isEndMarker - Returns true if the index is for the end marker
+ /// itinerary.
+ ///
+ bool isEndMarker(unsigned ItinClassIndx) const {
+ return ((Itineraries[ItinClassIndx].FirstStage == ~0U) &&
+ (Itineraries[ItinClassIndx].LastStage == ~0U));
+ }
+
+ /// beginStage - Return the first stage of the itinerary.
+ ///
+ const InstrStage *beginStage(unsigned ItinClassIndx) const {
+ unsigned StageIdx = Itineraries[ItinClassIndx].FirstStage;
+ return Stages + StageIdx;
+ }
+
+ /// endStage - Return the last+1 stage of the itinerary.
+ ///
+ const InstrStage *endStage(unsigned ItinClassIndx) const {
+ unsigned StageIdx = Itineraries[ItinClassIndx].LastStage;
+ return Stages + StageIdx;
+ }
+
+ /// getStageLatency - Return the total stage latency of the given
+ /// class. The latency is the maximum completion time for any stage
+ /// in the itinerary.
+ ///
+ unsigned getStageLatency(unsigned ItinClassIndx) const {
+ // If the target doesn't provide itinerary information, use a simple
+ // non-zero default value for all instructions. Some target's provide a
+ // dummy (Generic) itinerary which should be handled as if it's itinerary is
+ // empty. We identify this by looking for a reference to stage zero (invalid
+ // stage). This is different from beginStage == endState != 0, which could
+ // be used for zero-latency pseudo ops.
+ if (isEmpty() || Itineraries[ItinClassIndx].FirstStage == 0)
+ return 1;
+
+ // Calculate the maximum completion time for any stage.
+ unsigned Latency = 0, StartCycle = 0;
+ for (const InstrStage *IS = beginStage(ItinClassIndx),
+ *E = endStage(ItinClassIndx); IS != E; ++IS) {
+ Latency = std::max(Latency, StartCycle + IS->getCycles());
+ StartCycle += IS->getNextCycles();
+ }
+
+ return Latency;
+ }
+
+ /// getOperandCycle - Return the cycle for the given class and
+ /// operand. Return -1 if no cycle is specified for the operand.
+ ///
+ int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const {
+ if (isEmpty())
+ return -1;
+
+ unsigned FirstIdx = Itineraries[ItinClassIndx].FirstOperandCycle;
+ unsigned LastIdx = Itineraries[ItinClassIndx].LastOperandCycle;
+ if ((FirstIdx + OperandIdx) >= LastIdx)
+ return -1;
+
+ return (int)OperandCycles[FirstIdx + OperandIdx];
+ }
+
+ /// hasPipelineForwarding - Return true if there is a pipeline forwarding
+ /// between instructions of itinerary classes DefClass and UseClasses so that
+ /// value produced by an instruction of itinerary class DefClass, operand
+ /// index DefIdx can be bypassed when it's read by an instruction of
+ /// itinerary class UseClass, operand index UseIdx.
+ bool hasPipelineForwarding(unsigned DefClass, unsigned DefIdx,
+ unsigned UseClass, unsigned UseIdx) const {
+ unsigned FirstDefIdx = Itineraries[DefClass].FirstOperandCycle;
+ unsigned LastDefIdx = Itineraries[DefClass].LastOperandCycle;
+ if ((FirstDefIdx + DefIdx) >= LastDefIdx)
+ return false;
+ if (Forwardings[FirstDefIdx + DefIdx] == 0)
+ return false;
+
+ unsigned FirstUseIdx = Itineraries[UseClass].FirstOperandCycle;
+ unsigned LastUseIdx = Itineraries[UseClass].LastOperandCycle;
+ if ((FirstUseIdx + UseIdx) >= LastUseIdx)
+ return false;
+
+ return Forwardings[FirstDefIdx + DefIdx] ==
+ Forwardings[FirstUseIdx + UseIdx];
+ }
+
+ /// getOperandLatency - Compute and return the use operand latency of a given
+ /// itinerary class and operand index if the value is produced by an
+ /// instruction of the specified itinerary class and def operand index.
+ int getOperandLatency(unsigned DefClass, unsigned DefIdx,
+ unsigned UseClass, unsigned UseIdx) const {
+ if (isEmpty())
+ return -1;
+
+ int DefCycle = getOperandCycle(DefClass, DefIdx);
+ if (DefCycle == -1)
+ return -1;
+
+ int UseCycle = getOperandCycle(UseClass, UseIdx);
+ if (UseCycle == -1)
+ return -1;
+
+ UseCycle = DefCycle - UseCycle + 1;
+ if (UseCycle > 0 &&
+ hasPipelineForwarding(DefClass, DefIdx, UseClass, UseIdx))
+ // FIXME: This assumes one cycle benefit for every pipeline forwarding.
+ --UseCycle;
+ return UseCycle;
+ }
+
+ /// isMicroCoded - Return true if the instructions in the given class decode
+ /// to more than one micro-ops.
+ bool isMicroCoded(unsigned ItinClassIndx) const {
+ if (isEmpty())
+ return false;
+ return Itineraries[ItinClassIndx].NumMicroOps != 1;
+ }
+};
+
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/MCMachOSymbolFlags.h b/src/LLVM/include/llvm/MC/MCMachOSymbolFlags.h
index c938c81..696436d 100644
--- a/src/LLVM/include/llvm/MC/MCMachOSymbolFlags.h
+++ b/src/LLVM/include/llvm/MC/MCMachOSymbolFlags.h
@@ -34,9 +34,11 @@
SF_ReferenceTypePrivateUndefinedLazy = 0x0005,
// Other 'desc' flags.
+ SF_ThumbFunc = 0x0008,
SF_NoDeadStrip = 0x0020,
SF_WeakReference = 0x0040,
- SF_WeakDefinition = 0x0080
+ SF_WeakDefinition = 0x0080,
+ SF_SymbolResolver = 0x0100
};
} // end namespace llvm
diff --git a/src/LLVM/include/llvm/MC/MCMachObjectWriter.h b/src/LLVM/include/llvm/MC/MCMachObjectWriter.h
new file mode 100644
index 0000000..9bb598f
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCMachObjectWriter.h
@@ -0,0 +1,257 @@
+//===-- llvm/MC/MCMachObjectWriter.h - Mach Object Writer -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCMACHOBJECTWRITER_H
+#define LLVM_MC_MCMACHOBJECTWRITER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Object/MachOFormat.h"
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+
+class MCSectionData;
+class MachObjectWriter;
+
+class MCMachObjectTargetWriter {
+ const unsigned Is64Bit : 1;
+ const uint32_t CPUType;
+ const uint32_t CPUSubtype;
+ // FIXME: Remove this, we should just always use it once we no longer care
+ // about Darwin 'as' compatibility.
+ const unsigned UseAggressiveSymbolFolding : 1;
+ unsigned LocalDifference_RIT;
+
+protected:
+ MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_,
+ uint32_t CPUSubtype_,
+ bool UseAggressiveSymbolFolding_ = false);
+
+ void setLocalDifferenceRelocationType(unsigned Type) {
+ LocalDifference_RIT = Type;
+ }
+
+public:
+ virtual ~MCMachObjectTargetWriter();
+
+ /// @name Accessors
+ /// @{
+
+ bool is64Bit() const { return Is64Bit; }
+ bool useAggressiveSymbolFolding() const { return UseAggressiveSymbolFolding; }
+ uint32_t getCPUType() const { return CPUType; }
+ uint32_t getCPUSubtype() const { return CPUSubtype; }
+ unsigned getLocalDifferenceRelocationType() const {
+ return LocalDifference_RIT;
+ }
+
+ /// @}
+
+ /// @name API
+ /// @{
+
+ virtual void RecordRelocation(MachObjectWriter *Writer,
+ const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup,
+ MCValue Target,
+ uint64_t &FixedValue) = 0;
+
+ /// @}
+};
+
+class MachObjectWriter : public MCObjectWriter {
+ /// MachSymbolData - Helper struct for containing some precomputed information
+ /// on symbols.
+ struct MachSymbolData {
+ MCSymbolData *SymbolData;
+ uint64_t StringIndex;
+ uint8_t SectionIndex;
+
+ // Support lexicographic sorting.
+ bool operator<(const MachSymbolData &RHS) const;
+ };
+
+ /// The target specific Mach-O writer instance.
+ llvm::OwningPtr<MCMachObjectTargetWriter> TargetObjectWriter;
+
+ /// @name Relocation Data
+ /// @{
+
+ llvm::DenseMap<const MCSectionData*,
+ std::vector<object::macho::RelocationEntry> > Relocations;
+ llvm::DenseMap<const MCSectionData*, unsigned> IndirectSymBase;
+
+ /// @}
+ /// @name Symbol Table Data
+ /// @{
+
+ SmallString<256> StringTable;
+ std::vector<MachSymbolData> LocalSymbolData;
+ std::vector<MachSymbolData> ExternalSymbolData;
+ std::vector<MachSymbolData> UndefinedSymbolData;
+
+ /// @}
+
+public:
+ MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS,
+ bool _IsLittleEndian)
+ : MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) {
+ }
+
+ /// @name Utility Methods
+ /// @{
+
+ bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
+
+ SectionAddrMap SectionAddress;
+
+ SectionAddrMap &getSectionAddressMap() { return SectionAddress; }
+
+ uint64_t getSectionAddress(const MCSectionData* SD) const {
+ return SectionAddress.lookup(SD);
+ }
+ uint64_t getSymbolAddress(const MCSymbolData* SD,
+ const MCAsmLayout &Layout) const;
+
+ uint64_t getFragmentAddress(const MCFragment *Fragment,
+ const MCAsmLayout &Layout) const;
+
+ uint64_t getPaddingSize(const MCSectionData *SD,
+ const MCAsmLayout &Layout) const;
+
+ bool doesSymbolRequireExternRelocation(const MCSymbolData *SD);
+
+ /// @}
+
+ /// @name Target Writer Proxy Accessors
+ /// @{
+
+ bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
+ bool isARM() const {
+ uint32_t CPUType = TargetObjectWriter->getCPUType() &
+ ~object::mach::CTFM_ArchMask;
+ return CPUType == object::mach::CTM_ARM;
+ }
+
+ /// @}
+
+ void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize,
+ bool SubsectionsViaSymbols);
+
+ /// WriteSegmentLoadCommand - Write a segment load command.
+ ///
+ /// \arg NumSections - The number of sections in this segment.
+ /// \arg SectionDataSize - The total size of the sections.
+ void WriteSegmentLoadCommand(unsigned NumSections,
+ uint64_t VMSize,
+ uint64_t SectionDataStartOffset,
+ uint64_t SectionDataSize);
+
+ void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCSectionData &SD, uint64_t FileOffset,
+ uint64_t RelocationsStart, unsigned NumRelocations);
+
+ void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
+ uint32_t StringTableOffset,
+ uint32_t StringTableSize);
+
+ void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
+ uint32_t NumLocalSymbols,
+ uint32_t FirstExternalSymbol,
+ uint32_t NumExternalSymbols,
+ uint32_t FirstUndefinedSymbol,
+ uint32_t NumUndefinedSymbols,
+ uint32_t IndirectSymbolOffset,
+ uint32_t NumIndirectSymbols);
+
+ void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout);
+
+ // FIXME: We really need to improve the relocation validation. Basically, we
+ // want to implement a separate computation which evaluates the relocation
+ // entry as the linker would, and verifies that the resultant fixup value is
+ // exactly what the encoder wanted. This will catch several classes of
+ // problems:
+ //
+ // - Relocation entry bugs, the two algorithms are unlikely to have the same
+ // exact bug.
+ //
+ // - Relaxation issues, where we forget to relax something.
+ //
+ // - Input errors, where something cannot be correctly encoded. 'as' allows
+ // these through in many cases.
+
+ void addRelocation(const MCSectionData *SD,
+ object::macho::RelocationEntry &MRE) {
+ Relocations[SD].push_back(MRE);
+ }
+
+ void RecordScatteredRelocation(const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup, MCValue Target,
+ unsigned Log2Size,
+ uint64_t &FixedValue);
+
+ void RecordTLVPRelocation(const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup, MCValue Target,
+ uint64_t &FixedValue);
+
+ void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCFragment *Fragment, const MCFixup &Fixup,
+ MCValue Target, uint64_t &FixedValue);
+
+ void BindIndirectSymbols(MCAssembler &Asm);
+
+ /// ComputeSymbolTable - Compute the symbol table data
+ ///
+ /// \param StringTable [out] - The string table data.
+ /// \param StringIndexMap [out] - Map from symbol names to offsets in the
+ /// string table.
+ void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
+ std::vector<MachSymbolData> &LocalSymbolData,
+ std::vector<MachSymbolData> &ExternalSymbolData,
+ std::vector<MachSymbolData> &UndefinedSymbolData);
+
+ void computeSectionAddresses(const MCAssembler &Asm,
+ const MCAsmLayout &Layout);
+
+ void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout);
+
+ virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const;
+
+ void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
+};
+
+
+/// \brief Construct a new Mach-O writer instance.
+///
+/// This routine takes ownership of the target writer subclass.
+///
+/// \param MOTW - The target specific Mach-O writer subclass.
+/// \param OS - The stream to write to.
+/// \returns The constructed object writer.
+MCObjectWriter *createMachObjectWriter(MCMachObjectTargetWriter *MOTW,
+ raw_ostream &OS, bool IsLittleEndian);
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/MCModule.h b/src/LLVM/include/llvm/MC/MCModule.h
new file mode 100644
index 0000000..755fa02
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCModule.h
@@ -0,0 +1,58 @@
+//===-- llvm/MC/MCModule.h - MCModule class ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCModule class, which is used to
+// represent a complete, disassembled object file or executable.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCMODULE_H
+#define LLVM_MC_MCMODULE_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntervalMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class MCAtom;
+
+/// MCModule - This class represent a completely disassembled object file or
+/// executable. It comprises a list of MCAtom's, and a branch target table.
+/// Each atom represents a contiguous range of either instructions or data.
+class MCModule {
+ /// AtomAllocationTracker - An MCModule owns its component MCAtom's, so it
+ /// must track them in order to ensure they are properly freed as atoms are
+ /// merged or otherwise manipulated.
+ SmallPtrSet<MCAtom*, 8> AtomAllocationTracker;
+
+ /// OffsetMap - Efficiently maps offset ranges to MCAtom's.
+ IntervalMap<uint64_t, MCAtom*> OffsetMap;
+
+ /// BranchTargetMap - Maps offsets that are determined to be branches and
+ /// can be statically resolved to their target offsets.
+ DenseMap<uint64_t, MCAtom*> BranchTargetMap;
+
+ friend class MCAtom;
+
+ /// remap - Update the interval mapping for an MCAtom.
+ void remap(MCAtom *Atom, uint64_t NewBegin, uint64_t NewEnd);
+
+public:
+ MCModule(IntervalMap<uint64_t, MCAtom*>::Allocator &A) : OffsetMap(A) { }
+
+ /// createAtom - Creates a new MCAtom covering the specified offset range.
+ MCAtom *createAtom(MCAtom::AtomType Type, uint64_t Begin, uint64_t End);
+};
+
+}
+
+#endif
+
diff --git a/src/LLVM/include/llvm/MC/MCObjectFileInfo.h b/src/LLVM/include/llvm/MC/MCObjectFileInfo.h
new file mode 100644
index 0000000..060d508
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCObjectFileInfo.h
@@ -0,0 +1,294 @@
+//===-- llvm/MC/MCObjectFileInfo.h - Object File Info -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes common object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCBJECTFILEINFO_H
+#define LLVM_MC_MCBJECTFILEINFO_H
+
+#include "llvm/MC/MCCodeGenInfo.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/SectionKind.h"
+
+namespace llvm {
+class MCContext;
+class MCSection;
+class Triple;
+
+class MCObjectFileInfo {
+protected:
+ /// CommDirectiveSupportsAlignment - True if .comm supports alignment. This
+ /// is a hack for as long as we support 10.4 Tiger, whose assembler doesn't
+ /// support alignment on comm.
+ bool CommDirectiveSupportsAlignment;
+
+ /// SupportsWeakEmptyEHFrame - True if target object file supports a
+ /// weak_definition of constant 0 for an omitted EH frame.
+ bool SupportsWeakOmittedEHFrame;
+
+ /// IsFunctionEHFrameSymbolPrivate - This flag is set to true if the
+ /// "EH_frame" symbol for EH information should be an assembler temporary (aka
+ /// private linkage, aka an L or .L label) or false if it should be a normal
+ /// non-.globl label. This defaults to true.
+ bool IsFunctionEHFrameSymbolPrivate;
+
+ /// PersonalityEncoding, LSDAEncoding, FDEEncoding, TTypeEncoding - Some
+ /// encoding values for EH.
+ unsigned PersonalityEncoding;
+ unsigned LSDAEncoding;
+ unsigned FDEEncoding;
+ unsigned FDECFIEncoding;
+ unsigned TTypeEncoding;
+
+ /// TextSection - Section directive for standard text.
+ ///
+ const MCSection *TextSection;
+
+ /// DataSection - Section directive for standard data.
+ ///
+ const MCSection *DataSection;
+
+ /// BSSSection - Section that is default initialized to zero.
+ const MCSection *BSSSection;
+
+ /// ReadOnlySection - Section that is readonly and can contain arbitrary
+ /// initialized data. Targets are not required to have a readonly section.
+ /// If they don't, various bits of code will fall back to using the data
+ /// section for constants.
+ const MCSection *ReadOnlySection;
+
+ /// StaticCtorSection - This section contains the static constructor pointer
+ /// list.
+ const MCSection *StaticCtorSection;
+
+ /// StaticDtorSection - This section contains the static destructor pointer
+ /// list.
+ const MCSection *StaticDtorSection;
+
+ /// LSDASection - If exception handling is supported by the target, this is
+ /// the section the Language Specific Data Area information is emitted to.
+ const MCSection *LSDASection;
+
+ /// CompactUnwindSection - If exception handling is supported by the target
+ /// and the target can support a compact representation of the CIE and FDE,
+ /// this is the section to emit them into.
+ const MCSection *CompactUnwindSection;
+
+ // Dwarf sections for debug info. If a target supports debug info, these must
+ // be set.
+ const MCSection *DwarfAbbrevSection;
+ const MCSection *DwarfInfoSection;
+ const MCSection *DwarfLineSection;
+ const MCSection *DwarfFrameSection;
+ const MCSection *DwarfPubNamesSection;
+ const MCSection *DwarfPubTypesSection;
+ const MCSection *DwarfDebugInlineSection;
+ const MCSection *DwarfStrSection;
+ const MCSection *DwarfLocSection;
+ const MCSection *DwarfARangesSection;
+ const MCSection *DwarfRangesSection;
+ const MCSection *DwarfMacroInfoSection;
+
+ // Extra TLS Variable Data section. If the target needs to put additional
+ // information for a TLS variable, it'll go here.
+ const MCSection *TLSExtraDataSection;
+
+ /// TLSDataSection - Section directive for Thread Local data.
+ /// ELF and MachO only.
+ const MCSection *TLSDataSection; // Defaults to ".tdata".
+
+ /// TLSBSSSection - Section directive for Thread Local uninitialized data.
+ /// Null if this target doesn't support a BSS section.
+ /// ELF and MachO only.
+ const MCSection *TLSBSSSection; // Defaults to ".tbss".
+
+
+ /// EHFrameSection - EH frame section. It is initialized on demand so it
+ /// can be overwritten (with uniquing).
+ const MCSection *EHFrameSection;
+
+ /// ELF specific sections.
+ ///
+ const MCSection *DataRelSection;
+ const MCSection *DataRelLocalSection;
+ const MCSection *DataRelROSection;
+ const MCSection *DataRelROLocalSection;
+ const MCSection *MergeableConst4Section;
+ const MCSection *MergeableConst8Section;
+ const MCSection *MergeableConst16Section;
+
+ /// MachO specific sections.
+ ///
+
+ /// TLSTLVSection - Section for thread local structure information.
+ /// Contains the source code name of the variable, visibility and a pointer
+ /// to the initial value (.tdata or .tbss).
+ const MCSection *TLSTLVSection; // Defaults to ".tlv".
+
+ /// TLSThreadInitSection - Section for thread local data initialization
+ /// functions.
+ const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func".
+
+ const MCSection *CStringSection;
+ const MCSection *UStringSection;
+ const MCSection *TextCoalSection;
+ const MCSection *ConstTextCoalSection;
+ const MCSection *ConstDataSection;
+ const MCSection *DataCoalSection;
+ const MCSection *DataCommonSection;
+ const MCSection *DataBSSSection;
+ const MCSection *FourByteConstantSection;
+ const MCSection *EightByteConstantSection;
+ const MCSection *SixteenByteConstantSection;
+ const MCSection *LazySymbolPointerSection;
+ const MCSection *NonLazySymbolPointerSection;
+
+ /// COFF specific sections.
+ ///
+ const MCSection *DrectveSection;
+ const MCSection *PDataSection;
+ const MCSection *XDataSection;
+
+public:
+ void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM,
+ MCContext &ctx);
+
+ bool isFunctionEHFrameSymbolPrivate() const {
+ return IsFunctionEHFrameSymbolPrivate;
+ }
+ bool getSupportsWeakOmittedEHFrame() const {
+ return SupportsWeakOmittedEHFrame;
+ }
+ bool getCommDirectiveSupportsAlignment() const {
+ return CommDirectiveSupportsAlignment;
+ }
+
+ unsigned getPersonalityEncoding() const { return PersonalityEncoding; }
+ unsigned getLSDAEncoding() const { return LSDAEncoding; }
+ unsigned getFDEEncoding(bool CFI) const {
+ return CFI ? FDECFIEncoding : FDEEncoding;
+ }
+ unsigned getTTypeEncoding() const { return TTypeEncoding; }
+
+ const MCSection *getTextSection() const { return TextSection; }
+ const MCSection *getDataSection() const { return DataSection; }
+ const MCSection *getBSSSection() const { return BSSSection; }
+ const MCSection *getStaticCtorSection() const { return StaticCtorSection; }
+ const MCSection *getStaticDtorSection() const { return StaticDtorSection; }
+ const MCSection *getLSDASection() const { return LSDASection; }
+ const MCSection *getCompactUnwindSection() const{
+ return CompactUnwindSection;
+ }
+ const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; }
+ const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; }
+ const MCSection *getDwarfLineSection() const { return DwarfLineSection; }
+ const MCSection *getDwarfFrameSection() const { return DwarfFrameSection; }
+ const MCSection *getDwarfPubNamesSection() const{return DwarfPubNamesSection;}
+ const MCSection *getDwarfPubTypesSection() const{return DwarfPubTypesSection;}
+ const MCSection *getDwarfDebugInlineSection() const {
+ return DwarfDebugInlineSection;
+ }
+ const MCSection *getDwarfStrSection() const { return DwarfStrSection; }
+ const MCSection *getDwarfLocSection() const { return DwarfLocSection; }
+ const MCSection *getDwarfARangesSection() const { return DwarfARangesSection;}
+ const MCSection *getDwarfRangesSection() const { return DwarfRangesSection; }
+ const MCSection *getDwarfMacroInfoSection() const {
+ return DwarfMacroInfoSection;
+ }
+ const MCSection *getTLSExtraDataSection() const {
+ return TLSExtraDataSection;
+ }
+ const MCSection *getTLSDataSection() const { return TLSDataSection; }
+ const MCSection *getTLSBSSSection() const { return TLSBSSSection; }
+
+ /// ELF specific sections.
+ ///
+ const MCSection *getDataRelSection() const { return DataRelSection; }
+ const MCSection *getDataRelLocalSection() const {
+ return DataRelLocalSection;
+ }
+ const MCSection *getDataRelROSection() const { return DataRelROSection; }
+ const MCSection *getDataRelROLocalSection() const {
+ return DataRelROLocalSection;
+ }
+ const MCSection *getMergeableConst4Section() const {
+ return MergeableConst4Section;
+ }
+ const MCSection *getMergeableConst8Section() const {
+ return MergeableConst8Section;
+ }
+ const MCSection *getMergeableConst16Section() const {
+ return MergeableConst16Section;
+ }
+
+ /// MachO specific sections.
+ ///
+ const MCSection *getTLSTLVSection() const { return TLSTLVSection; }
+ const MCSection *getTLSThreadInitSection() const {
+ return TLSThreadInitSection;
+ }
+ const MCSection *getCStringSection() const { return CStringSection; }
+ const MCSection *getUStringSection() const { return UStringSection; }
+ const MCSection *getTextCoalSection() const { return TextCoalSection; }
+ const MCSection *getConstTextCoalSection() const {
+ return ConstTextCoalSection;
+ }
+ const MCSection *getConstDataSection() const { return ConstDataSection; }
+ const MCSection *getDataCoalSection() const { return DataCoalSection; }
+ const MCSection *getDataCommonSection() const { return DataCommonSection; }
+ const MCSection *getDataBSSSection() const { return DataBSSSection; }
+ const MCSection *getFourByteConstantSection() const {
+ return FourByteConstantSection;
+ }
+ const MCSection *getEightByteConstantSection() const {
+ return EightByteConstantSection;
+ }
+ const MCSection *getSixteenByteConstantSection() const {
+ return SixteenByteConstantSection;
+ }
+ const MCSection *getLazySymbolPointerSection() const {
+ return LazySymbolPointerSection;
+ }
+ const MCSection *getNonLazySymbolPointerSection() const {
+ return NonLazySymbolPointerSection;
+ }
+
+ /// COFF specific sections.
+ ///
+ const MCSection *getDrectveSection() const { return DrectveSection; }
+ const MCSection *getPDataSection() const { return PDataSection; }
+ const MCSection *getXDataSection() const { return XDataSection; }
+
+ const MCSection *getEHFrameSection() {
+ if (!EHFrameSection)
+ InitEHFrameSection();
+ return EHFrameSection;
+ }
+
+private:
+ enum Environment { IsMachO, IsELF, IsCOFF };
+ Environment Env;
+ Reloc::Model RelocM;
+ CodeModel::Model CMModel;
+ MCContext *Ctx;
+
+ void InitMachOMCObjectFileInfo(Triple T);
+ void InitELFMCObjectFileInfo(Triple T);
+ void InitCOFFMCObjectFileInfo(Triple T);
+
+ /// InitEHFrameSection - Initialize EHFrameSection on demand.
+ ///
+ void InitEHFrameSection();
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/MCObjectStreamer.h b/src/LLVM/include/llvm/MC/MCObjectStreamer.h
index ea6d9c1..f897e64 100644
--- a/src/LLVM/include/llvm/MC/MCObjectStreamer.h
+++ b/src/LLVM/include/llvm/MC/MCObjectStreamer.h
@@ -19,7 +19,7 @@
class MCExpr;
class MCFragment;
class MCDataFragment;
-class TargetAsmBackend;
+class MCAsmBackend;
class raw_ostream;
/// \brief Streaming object file generation interface.
@@ -33,9 +33,14 @@
MCAssembler *Assembler;
MCSectionData *CurSectionData;
+ virtual void EmitInstToData(const MCInst &Inst) = 0;
+
protected:
- MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB,
+ MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
raw_ostream &_OS, MCCodeEmitter *_Emitter);
+ MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
+ raw_ostream &_OS, MCCodeEmitter *_Emitter,
+ MCAssembler *_Assembler);
~MCObjectStreamer();
MCSectionData *getCurrentSectionData() const {
@@ -56,7 +61,22 @@
/// @name MCStreamer Interface
/// @{
- virtual void SwitchSection(const MCSection *Section);
+ virtual void EmitLabel(MCSymbol *Symbol);
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace);
+ virtual void EmitULEB128Value(const MCExpr *Value);
+ virtual void EmitSLEB128Value(const MCExpr *Value);
+ virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
+ virtual void ChangeSection(const MCSection *Section);
+ virtual void EmitInstruction(const MCInst &Inst);
+ virtual void EmitInstToFragment(const MCInst &Inst);
+ virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value);
+ virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
+ const MCSymbol *LastLabel,
+ const MCSymbol *Label,
+ unsigned PointerSize);
+ virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
+ const MCSymbol *Label);
virtual void Finish();
/// @}
diff --git a/src/LLVM/include/llvm/MC/MCObjectWriter.h b/src/LLVM/include/llvm/MC/MCObjectWriter.h
index 22eea7e..782d844 100644
--- a/src/LLVM/include/llvm/MC/MCObjectWriter.h
+++ b/src/LLVM/include/llvm/MC/MCObjectWriter.h
@@ -10,8 +10,9 @@
#ifndef LLVM_MC_MCOBJECTWRITER_H
#define LLVM_MC_MCOBJECTWRITER_H
+#include "llvm/ADT/Triple.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
@@ -19,6 +20,9 @@
class MCAssembler;
class MCFixup;
class MCFragment;
+class MCSymbol;
+class MCSymbolData;
+class MCSymbolRefExpr;
class MCValue;
class raw_ostream;
@@ -61,7 +65,8 @@
///
/// This routine is called by the assembler after layout and relaxation is
/// complete.
- virtual void ExecutePostLayoutBinding(MCAssembler &Asm) = 0;
+ virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) = 0;
/// Record a relocation entry.
///
@@ -75,12 +80,31 @@
const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue) = 0;
+ /// \brief Check whether the difference (A - B) between two symbol
+ /// references is fully resolved.
+ ///
+ /// Clients are not required to answer precisely and may conservatively return
+ /// false, even when a difference is fully resolved.
+ bool
+ IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
+ const MCSymbolRefExpr *A,
+ const MCSymbolRefExpr *B,
+ bool InSet) const;
+
+ virtual bool
+ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const;
+
+
/// Write the object file.
///
/// This routine is called by the assembler after layout and relaxation is
/// complete, fixups have been evaluated and applied, and relocations
/// generated.
- virtual void WriteObject(const MCAssembler &Asm,
+ virtual void WriteObject(MCAssembler &Asm,
const MCAsmLayout &Layout) = 0;
/// @}
@@ -160,9 +184,14 @@
}
/// @}
+
+ /// Utility function to encode a SLEB128 value.
+ static void EncodeSLEB128(int64_t Value, raw_ostream &OS);
+ /// Utility function to encode a ULEB128 value.
+ static void EncodeULEB128(uint64_t Value, raw_ostream &OS);
};
-MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS);
+MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS, bool is64Bit);
} // End llvm namespace
diff --git a/src/LLVM/include/llvm/MC/MCParser/AsmLexer.h b/src/LLVM/include/llvm/MC/MCParser/AsmLexer.h
index 2187889..dcecfb6 100644
--- a/src/LLVM/include/llvm/MC/MCParser/AsmLexer.h
+++ b/src/LLVM/include/llvm/MC/MCParser/AsmLexer.h
@@ -17,7 +17,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <string>
#include <cassert>
@@ -29,10 +29,11 @@
/// AsmLexer - Lexer class for assembly files.
class AsmLexer : public MCAsmLexer {
const MCAsmInfo &MAI;
-
+
const char *CurPtr;
const MemoryBuffer *CurBuf;
-
+ bool isAtStartOfLine;
+
void operator=(const AsmLexer&); // DO NOT IMPLEMENT
AsmLexer(const AsmLexer&); // DO NOT IMPLEMENT
@@ -43,13 +44,15 @@
public:
AsmLexer(const MCAsmInfo &MAI);
~AsmLexer();
-
+
void setBuffer(const MemoryBuffer *buf, const char *ptr = NULL);
-
+
virtual StringRef LexUntilEndOfStatement();
+ StringRef LexUntilEndOfLine();
bool isAtStartOfComment(char Char);
-
+ bool isAtStatementSeparator(const char *Ptr);
+
const MCAsmInfo &getMAI() const { return MAI; }
private:
@@ -60,9 +63,11 @@
AsmToken LexSlash();
AsmToken LexLineComment();
AsmToken LexDigit();
+ AsmToken LexSingleQuote();
AsmToken LexQuote();
+ AsmToken LexFloatLiteral();
};
-
+
} // end namespace llvm
#endif
diff --git a/src/LLVM/include/llvm/MC/MCParser/MCAsmLexer.h b/src/LLVM/include/llvm/MC/MCParser/MCAsmLexer.h
index d690e81..9bbb755 100644
--- a/src/LLVM/include/llvm/MC/MCParser/MCAsmLexer.h
+++ b/src/LLVM/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -11,13 +11,12 @@
#define LLVM_MC_MCASMLEXER_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/SMLoc.h"
namespace llvm {
class MCAsmLexer;
class MCInst;
-class Target;
/// AsmToken - Target independent representation for an assembler token.
class AsmToken {
@@ -29,22 +28,26 @@
// String values.
Identifier,
String,
-
+
// Integer values.
Integer,
-
- // Register values (stored in IntVal). Only used by TargetAsmLexer.
+
+ // Real values.
+ Real,
+
+ // Register values (stored in IntVal). Only used by MCTargetAsmLexer.
Register,
-
+
// No-value.
EndOfStatement,
Colon,
Plus, Minus, Tilde,
Slash, // '/'
+ BackSlash, // '\'
LParen, RParen, LBrac, RBrac, LCurly, RCurly,
Star, Dot, Comma, Dollar, Equal, EqualEqual,
-
- Pipe, PipePipe, Caret,
+
+ Pipe, PipePipe, Caret,
Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash,
Less, LessEqual, LessLess, LessGreater,
Greater, GreaterEqual, GreaterGreater, At
@@ -70,7 +73,7 @@
SMLoc getLoc() const;
/// getStringContents - Get the contents of a string token (without quotes).
- StringRef getStringContents() const {
+ StringRef getStringContents() const {
assert(Kind == String && "This token isn't a string!");
return Str.slice(1, Str.size() - 1);
}
@@ -95,11 +98,11 @@
// FIXME: Don't compute this in advance, it makes every token larger, and is
// also not generally what we want (it is nicer for recovery etc. to lex 123br
// as a single token, then diagnose as an invalid number).
- int64_t getIntVal() const {
+ int64_t getIntVal() const {
assert(Kind == Integer && "This token isn't an integer!");
- return IntVal;
+ return IntVal;
}
-
+
/// getRegVal - Get the register number for the current token, which should
/// be a register.
unsigned getRegVal() const {
@@ -113,7 +116,7 @@
class MCAsmLexer {
/// The current token, stored in the base class for faster access.
AsmToken CurTok;
-
+
/// The location and description of the current error
SMLoc ErrLoc;
std::string Err;
@@ -126,12 +129,12 @@
MCAsmLexer();
virtual AsmToken LexToken() = 0;
-
+
void SetError(const SMLoc &errLoc, const std::string &err) {
ErrLoc = errLoc;
Err = err;
}
-
+
public:
virtual ~MCAsmLexer();
@@ -152,12 +155,12 @@
const AsmToken &getTok() {
return CurTok;
}
-
+
/// getErrLoc - Get the current error location
const SMLoc &getErrLoc() {
return ErrLoc;
}
-
+
/// getErr - Get the current error string
const std::string &getErr() {
return Err;
diff --git a/src/LLVM/include/llvm/MC/MCParser/MCAsmParser.h b/src/LLVM/include/llvm/MC/MCParser/MCAsmParser.h
index 9457987..6ff1753 100644
--- a/src/LLVM/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/src/LLVM/include/llvm/MC/MCParser/MCAsmParser.h
@@ -10,7 +10,7 @@
#ifndef LLVM_MC_MCASMPARSER_H
#define LLVM_MC_MCASMPARSER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class AsmToken;
@@ -20,11 +20,10 @@
class MCContext;
class MCExpr;
class MCStreamer;
+class MCTargetAsmParser;
class SMLoc;
class SourceMgr;
class StringRef;
-class Target;
-class TargetAsmParser;
class Twine;
/// MCAsmParser - Generic assembler parser interface, for use by target specific
@@ -37,7 +36,9 @@
MCAsmParser(const MCAsmParser &); // DO NOT IMPLEMENT
void operator=(const MCAsmParser &); // DO NOT IMPLEMENT
- TargetAsmParser *TargetParser;
+ MCTargetAsmParser *TargetParser;
+
+ unsigned ShowParsedOperands : 1;
protected: // Can only create subclasses.
MCAsmParser();
@@ -58,15 +59,20 @@
/// getStreamer - Return the output streamer for the assembler.
virtual MCStreamer &getStreamer() = 0;
- TargetAsmParser &getTargetParser() const { return *TargetParser; }
- void setTargetParser(TargetAsmParser &P);
+ MCTargetAsmParser &getTargetParser() const { return *TargetParser; }
+ void setTargetParser(MCTargetAsmParser &P);
+
+ bool getShowParsedOperands() const { return ShowParsedOperands; }
+ void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; }
/// Run - Run the parser on the input source buffer.
virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0;
/// Warning - Emit a warning at the location \arg L, with the message \arg
/// Msg.
- virtual void Warning(SMLoc L, const Twine &Msg) = 0;
+ ///
+ /// \return The return value is true, if warnings are fatal.
+ virtual bool Warning(SMLoc L, const Twine &Msg) = 0;
/// Error - Emit an error at the location \arg L, with the message \arg
/// Msg.
@@ -94,6 +100,10 @@
/// will be either the EndOfStatement or EOF.
virtual StringRef ParseStringToEndOfStatement() = 0;
+ /// EatToEndOfStatement - Skip to the end of the current statement, for error
+ /// recovery.
+ virtual void EatToEndOfStatement() = 0;
+
/// ParseExpression - Parse an arbitrary expression.
///
/// @param Res - The value of the expression. The result is undefined
@@ -120,7 +130,7 @@
};
/// \brief Create an MCAsmParser instance.
-MCAsmParser *createMCAsmParser(const Target &, SourceMgr &, MCContext &,
+MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &,
MCStreamer &, const MCAsmInfo &);
} // End llvm namespace
diff --git a/src/LLVM/include/llvm/MC/MCParser/MCAsmParserExtension.h b/src/LLVM/include/llvm/MC/MCParser/MCAsmParserExtension.h
index 95184cd..4e2aee9 100644
--- a/src/LLVM/include/llvm/MC/MCParser/MCAsmParserExtension.h
+++ b/src/LLVM/include/llvm/MC/MCParser/MCAsmParserExtension.h
@@ -38,6 +38,8 @@
return (Obj->*Handler)(Directive, DirectiveLoc);
}
+ bool BracketExpressionsSupported;
+
public:
virtual ~MCAsmParserExtension();
@@ -54,7 +56,7 @@
MCAsmParser &getParser() { return *Parser; }
SourceMgr &getSourceManager() { return getParser().getSourceManager(); }
MCStreamer &getStreamer() { return getParser().getStreamer(); }
- void Warning(SMLoc L, const Twine &Msg) {
+ bool Warning(SMLoc L, const Twine &Msg) {
return getParser().Warning(L, Msg);
}
bool Error(SMLoc L, const Twine &Msg) {
@@ -68,6 +70,8 @@
const AsmToken &getTok() { return getParser().getTok(); }
+ bool HasBracketExpressions() const { return BracketExpressionsSupported; }
+
/// @}
};
diff --git a/src/LLVM/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/src/LLVM/include/llvm/MC/MCParser/MCParsedAsmOperand.h
index 7c2f5be..2556e5f 100644
--- a/src/LLVM/include/llvm/MC/MCParser/MCParsedAsmOperand.h
+++ b/src/LLVM/include/llvm/MC/MCParser/MCParsedAsmOperand.h
@@ -12,22 +12,36 @@
namespace llvm {
class SMLoc;
+class raw_ostream;
/// MCParsedAsmOperand - This abstract class represents a source-level assembly
/// instruction operand. It should be subclassed by target-specific code. This
/// base class is used by target-independent clients and is the interface
/// between parsing an asm instruction and recognizing it.
class MCParsedAsmOperand {
-public:
+public:
MCParsedAsmOperand() {}
virtual ~MCParsedAsmOperand() {}
-
+
/// getStartLoc - Get the location of the first token of this operand.
- virtual SMLoc getStartLoc() const;
+ virtual SMLoc getStartLoc() const = 0;
/// getEndLoc - Get the location of the last token of this operand.
- virtual SMLoc getEndLoc() const;
+ virtual SMLoc getEndLoc() const = 0;
+
+ /// print - Print a debug representation of the operand to the given stream.
+ virtual void print(raw_ostream &OS) const = 0;
+ /// dump - Print to the debug stream.
+ virtual void dump() const;
};
+//===----------------------------------------------------------------------===//
+// Debugging Support
+
+inline raw_ostream& operator<<(raw_ostream &OS, const MCParsedAsmOperand &MO) {
+ MO.print(OS);
+ return OS;
+}
+
} // end namespace llvm.
#endif
diff --git a/src/LLVM/include/llvm/MC/MCRegisterInfo.h b/src/LLVM/include/llvm/MC/MCRegisterInfo.h
new file mode 100644
index 0000000..ada5ae8
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCRegisterInfo.h
@@ -0,0 +1,307 @@
+//=== MC/MCRegisterInfo.h - Target Register Description ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes an abstract interface used to get information about a
+// target machines register file. This information is used for a variety of
+// purposed, especially register allocation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCREGISTERINFO_H
+#define LLVM_MC_MCREGISTERINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include <cassert>
+
+namespace llvm {
+
+/// MCRegisterClass - Base class of TargetRegisterClass.
+class MCRegisterClass {
+public:
+ typedef const unsigned* iterator;
+ typedef const unsigned* const_iterator;
+private:
+ unsigned ID;
+ const char *Name;
+ const unsigned RegSize, Alignment; // Size & Alignment of register in bytes
+ const int CopyCost;
+ const bool Allocatable;
+ const iterator RegsBegin, RegsEnd;
+ const unsigned char *const RegSet;
+ const unsigned RegSetSize;
+public:
+ MCRegisterClass(unsigned id, const char *name,
+ unsigned RS, unsigned Al, int CC, bool Allocable,
+ iterator RB, iterator RE, const unsigned char *Bits,
+ unsigned NumBytes)
+ : ID(id), Name(name), RegSize(RS), Alignment(Al), CopyCost(CC),
+ Allocatable(Allocable), RegsBegin(RB), RegsEnd(RE), RegSet(Bits),
+ RegSetSize(NumBytes) {
+ for (iterator i = RegsBegin; i != RegsEnd; ++i)
+ assert(contains(*i) && "Bit field corrupted.");
+ }
+
+ /// getID() - Return the register class ID number.
+ ///
+ unsigned getID() const { return ID; }
+
+ /// getName() - Return the register class name for debugging.
+ ///
+ const char *getName() const { return Name; }
+
+ /// begin/end - Return all of the registers in this class.
+ ///
+ iterator begin() const { return RegsBegin; }
+ iterator end() const { return RegsEnd; }
+
+ /// getNumRegs - Return the number of registers in this class.
+ ///
+ unsigned getNumRegs() const { return (unsigned)(RegsEnd-RegsBegin); }
+
+ /// getRegister - Return the specified register in the class.
+ ///
+ unsigned getRegister(unsigned i) const {
+ assert(i < getNumRegs() && "Register number out of range!");
+ return RegsBegin[i];
+ }
+
+ /// contains - Return true if the specified register is included in this
+ /// register class. This does not include virtual registers.
+ bool contains(unsigned Reg) const {
+ unsigned InByte = Reg % 8;
+ unsigned Byte = Reg / 8;
+ if (Byte >= RegSetSize)
+ return false;
+ return (RegSet[Byte] & (1 << InByte)) != 0;
+ }
+
+ /// contains - Return true if both registers are in this class.
+ bool contains(unsigned Reg1, unsigned Reg2) const {
+ return contains(Reg1) && contains(Reg2);
+ }
+
+ /// getSize - Return the size of the register in bytes, which is also the size
+ /// of a stack slot allocated to hold a spilled copy of this register.
+ unsigned getSize() const { return RegSize; }
+
+ /// getAlignment - Return the minimum required alignment for a register of
+ /// this class.
+ unsigned getAlignment() const { return Alignment; }
+
+ /// getCopyCost - Return the cost of copying a value between two registers in
+ /// this class. A negative number means the register class is very expensive
+ /// to copy e.g. status flag register classes.
+ int getCopyCost() const { return CopyCost; }
+
+ /// isAllocatable - Return true if this register class may be used to create
+ /// virtual registers.
+ bool isAllocatable() const { return Allocatable; }
+};
+
+/// MCRegisterDesc - This record contains all of the information known about
+/// a particular register. The Overlaps field contains a pointer to a zero
+/// terminated array of registers that this register aliases, starting with
+/// itself. This is needed for architectures like X86 which have AL alias AX
+/// alias EAX. The SubRegs field is a zero terminated array of registers that
+/// are sub-registers of the specific register, e.g. AL, AH are sub-registers of
+/// AX. The SuperRegs field is a zero terminated array of registers that are
+/// super-registers of the specific register, e.g. RAX, EAX, are super-registers
+/// of AX.
+///
+struct MCRegisterDesc {
+ const char *Name; // Printable name for the reg (for debugging)
+ const unsigned *Overlaps; // Overlapping registers, described above
+ const unsigned *SubRegs; // Sub-register set, described above
+ const unsigned *SuperRegs; // Super-register set, described above
+};
+
+/// MCRegisterInfo base class - We assume that the target defines a static
+/// array of MCRegisterDesc objects that represent all of the machine
+/// registers that the target has. As such, we simply have to track a pointer
+/// to this array so that we can turn register number into a register
+/// descriptor.
+///
+/// Note this class is designed to be a base class of TargetRegisterInfo, which
+/// is the interface used by codegen. However, specific targets *should never*
+/// specialize this class. MCRegisterInfo should only contain getters to access
+/// TableGen generated physical register data. It must not be extended with
+/// virtual methods.
+///
+class MCRegisterInfo {
+public:
+ typedef const MCRegisterClass *regclass_iterator;
+private:
+ const MCRegisterDesc *Desc; // Pointer to the descriptor array
+ unsigned NumRegs; // Number of entries in the array
+ unsigned RAReg; // Return address register
+ const MCRegisterClass *Classes; // Pointer to the regclass array
+ unsigned NumClasses; // Number of entries in the array
+ DenseMap<unsigned, int> L2DwarfRegs; // LLVM to Dwarf regs mapping
+ DenseMap<unsigned, int> EHL2DwarfRegs; // LLVM to Dwarf regs mapping EH
+ DenseMap<unsigned, unsigned> Dwarf2LRegs; // Dwarf to LLVM regs mapping
+ DenseMap<unsigned, unsigned> EHDwarf2LRegs; // Dwarf to LLVM regs mapping EH
+ DenseMap<unsigned, int> L2SEHRegs; // LLVM to SEH regs mapping
+
+public:
+ /// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen
+ /// auto-generated routines. *DO NOT USE*.
+ void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA,
+ const MCRegisterClass *C, unsigned NC) {
+ Desc = D;
+ NumRegs = NR;
+ RAReg = RA;
+ Classes = C;
+ NumClasses = NC;
+ }
+
+ /// mapLLVMRegToDwarfReg - Used to initialize LLVM register to Dwarf
+ /// register number mapping. Called by TableGen auto-generated routines.
+ /// *DO NOT USE*.
+ void mapLLVMRegToDwarfReg(unsigned LLVMReg, int DwarfReg, bool isEH) {
+ if (isEH)
+ EHL2DwarfRegs[LLVMReg] = DwarfReg;
+ else
+ L2DwarfRegs[LLVMReg] = DwarfReg;
+ }
+
+ /// mapDwarfRegToLLVMReg - Used to initialize Dwarf register to LLVM
+ /// register number mapping. Called by TableGen auto-generated routines.
+ /// *DO NOT USE*.
+ void mapDwarfRegToLLVMReg(unsigned DwarfReg, unsigned LLVMReg, bool isEH) {
+ if (isEH)
+ EHDwarf2LRegs[DwarfReg] = LLVMReg;
+ else
+ Dwarf2LRegs[DwarfReg] = LLVMReg;
+ }
+
+ /// mapLLVMRegToSEHReg - Used to initialize LLVM register to SEH register
+ /// number mapping. By default the SEH register number is just the same
+ /// as the LLVM register number.
+ /// FIXME: TableGen these numbers. Currently this requires target specific
+ /// initialization code.
+ void mapLLVMRegToSEHReg(unsigned LLVMReg, int SEHReg) {
+ L2SEHRegs[LLVMReg] = SEHReg;
+ }
+
+ /// getRARegister - This method should return the register where the return
+ /// address can be found.
+ unsigned getRARegister() const {
+ return RAReg;
+ }
+
+ const MCRegisterDesc &operator[](unsigned RegNo) const {
+ assert(RegNo < NumRegs &&
+ "Attempting to access record for invalid register number!");
+ return Desc[RegNo];
+ }
+
+ /// Provide a get method, equivalent to [], but more useful if we have a
+ /// pointer to this object.
+ ///
+ const MCRegisterDesc &get(unsigned RegNo) const {
+ return operator[](RegNo);
+ }
+
+ /// getAliasSet - Return the set of registers aliased by the specified
+ /// register, or a null list of there are none. The list returned is zero
+ /// terminated.
+ ///
+ const unsigned *getAliasSet(unsigned RegNo) const {
+ // The Overlaps set always begins with Reg itself.
+ return get(RegNo).Overlaps + 1;
+ }
+
+ /// getOverlaps - Return a list of registers that overlap Reg, including
+ /// itself. This is the same as the alias set except Reg is included in the
+ /// list.
+ /// These are exactly the registers in { x | regsOverlap(x, Reg) }.
+ ///
+ const unsigned *getOverlaps(unsigned RegNo) const {
+ return get(RegNo).Overlaps;
+ }
+
+ /// getSubRegisters - Return the list of registers that are sub-registers of
+ /// the specified register, or a null list of there are none. The list
+ /// returned is zero terminated and sorted according to super-sub register
+ /// relations. e.g. X86::RAX's sub-register list is EAX, AX, AL, AH.
+ ///
+ const unsigned *getSubRegisters(unsigned RegNo) const {
+ return get(RegNo).SubRegs;
+ }
+
+ /// getSuperRegisters - Return the list of registers that are super-registers
+ /// of the specified register, or a null list of there are none. The list
+ /// returned is zero terminated and sorted according to super-sub register
+ /// relations. e.g. X86::AL's super-register list is AX, EAX, RAX.
+ ///
+ const unsigned *getSuperRegisters(unsigned RegNo) const {
+ return get(RegNo).SuperRegs;
+ }
+
+ /// getName - Return the human-readable symbolic target-specific name for the
+ /// specified physical register.
+ const char *getName(unsigned RegNo) const {
+ return get(RegNo).Name;
+ }
+
+ /// getNumRegs - Return the number of registers this target has (useful for
+ /// sizing arrays holding per register information)
+ unsigned getNumRegs() const {
+ return NumRegs;
+ }
+
+ /// getDwarfRegNum - Map a target register to an equivalent dwarf register
+ /// number. Returns -1 if there is no equivalent value. The second
+ /// parameter allows targets to use different numberings for EH info and
+ /// debugging info.
+ int getDwarfRegNum(unsigned RegNum, bool isEH) const {
+ const DenseMap<unsigned, int> &M = isEH ? EHL2DwarfRegs : L2DwarfRegs;
+ const DenseMap<unsigned, int>::const_iterator I = M.find(RegNum);
+ if (I == M.end()) return -1;
+ return I->second;
+ }
+
+ /// getLLVMRegNum - Map a dwarf register back to a target register.
+ ///
+ int getLLVMRegNum(unsigned RegNum, bool isEH) const {
+ const DenseMap<unsigned, unsigned> &M = isEH ? EHDwarf2LRegs : Dwarf2LRegs;
+ const DenseMap<unsigned, unsigned>::const_iterator I = M.find(RegNum);
+ if (I == M.end()) {
+ assert(0 && "Invalid RegNum");
+ return -1;
+ }
+ return I->second;
+ }
+
+ /// getSEHRegNum - Map a target register to an equivalent SEH register
+ /// number. Returns LLVM register number if there is no equivalent value.
+ int getSEHRegNum(unsigned RegNum) const {
+ const DenseMap<unsigned, int>::const_iterator I = L2SEHRegs.find(RegNum);
+ if (I == L2SEHRegs.end()) return (int)RegNum;
+ return I->second;
+ }
+
+ regclass_iterator regclass_begin() const { return Classes; }
+ regclass_iterator regclass_end() const { return Classes+NumClasses; }
+
+ unsigned getNumRegClasses() const {
+ return (unsigned)(regclass_end()-regclass_begin());
+ }
+
+ /// getRegClass - Returns the register class associated with the enumeration
+ /// value. See class MCOperandInfo.
+ const MCRegisterClass getRegClass(unsigned i) const {
+ assert(i < getNumRegClasses() && "Register Class ID out of range");
+ return Classes[i];
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/MCSection.h b/src/LLVM/include/llvm/MC/MCSection.h
index 5c99735..5700817 100644
--- a/src/LLVM/include/llvm/MC/MCSection.h
+++ b/src/LLVM/include/llvm/MC/MCSection.h
@@ -14,7 +14,6 @@
#ifndef LLVM_MC_MCSECTION_H
#define LLVM_MC_MCSECTION_H
-#include <string>
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Casting.h"
@@ -32,8 +31,7 @@
enum SectionVariant {
SV_COFF = 0,
SV_ELF,
- SV_MachO,
- SV_PIC16
+ SV_MachO
};
private:
@@ -61,6 +59,14 @@
return false;
}
+ // UseCodeAlign - Return true if a .align directive should use
+ // "optimized nops" to fill instead of 0s.
+ virtual bool UseCodeAlign() const = 0;
+
+ /// isVirtualSection - Check whether this section is "virtual", that is
+ /// has no actual object file contents.
+ virtual bool isVirtualSection() const = 0;
+
static bool classof(const MCSection *) { return true; }
};
diff --git a/src/LLVM/include/llvm/MC/MCSectionCOFF.h b/src/LLVM/include/llvm/MC/MCSectionCOFF.h
index f828e10..b154cf5 100644
--- a/src/LLVM/include/llvm/MC/MCSectionCOFF.h
+++ b/src/LLVM/include/llvm/MC/MCSectionCOFF.h
@@ -19,12 +19,12 @@
#include "llvm/Support/COFF.h"
namespace llvm {
-
+
/// MCSectionCOFF - This represents a section on Windows
class MCSectionCOFF : public MCSection {
// The memory for this string is stored in the same MCContext as *this.
StringRef SectionName;
-
+
/// Characteristics - This is the Characteristics field of a section,
// drawn from the enums below.
unsigned Characteristics;
@@ -52,9 +52,11 @@
StringRef getSectionName() const { return SectionName; }
unsigned getCharacteristics() const { return Characteristics; }
int getSelection () const { return Selection; }
-
+
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const;
+ virtual bool UseCodeAlign() const;
+ virtual bool isVirtualSection() const;
static bool classof(const MCSection *S) {
return S->getVariant() == SV_COFF;
diff --git a/src/LLVM/include/llvm/MC/MCSectionELF.h b/src/LLVM/include/llvm/MC/MCSectionELF.h
index 5fe8171..c82de71 100644
--- a/src/LLVM/include/llvm/MC/MCSectionELF.h
+++ b/src/LLVM/include/llvm/MC/MCSectionELF.h
@@ -15,33 +15,39 @@
#define LLVM_MC_MCSECTIONELF_H
#include "llvm/MC/MCSection.h"
+#include "llvm/Support/ELF.h"
namespace llvm {
-
+
+class MCSymbol;
+
/// MCSectionELF - This represents a section on linux, lots of unix variants
/// and some bare metal systems.
class MCSectionELF : public MCSection {
/// SectionName - This is the name of the section. The referenced memory is
/// owned by TargetLoweringObjectFileELF's ELFUniqueMap.
StringRef SectionName;
-
+
/// Type - This is the sh_type field of a section, drawn from the enums below.
unsigned Type;
-
+
/// Flags - This is the sh_flags field of a section, drawn from the enums.
/// below.
unsigned Flags;
- /// IsExplicit - Indicates that this section comes from globals with an
- /// explicit section specified.
- bool IsExplicit;
-
+ /// EntrySize - The size of each entry in this section. This size only
+ /// makes sense for sections that contain fixed-sized entries. If a
+ /// section does not contain fixed-sized entries 'EntrySize' will be 0.
+ unsigned EntrySize;
+
+ const MCSymbol *Group;
+
private:
friend class MCContext;
MCSectionELF(StringRef Section, unsigned type, unsigned flags,
- SectionKind K, bool isExplicit)
+ SectionKind K, unsigned entrySize, const MCSymbol *group)
: MCSection(SV_ELF, K), SectionName(Section), Type(type), Flags(flags),
- IsExplicit(isExplicit) {}
+ EntrySize(entrySize), Group(group) {}
~MCSectionELF();
public:
@@ -49,140 +55,31 @@
/// should be printed before the section name
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
- /// ShouldPrintSectionType - Only prints the section type if supported
- bool ShouldPrintSectionType(unsigned Ty) const;
-
- /// HasCommonSymbols - True if this section holds common symbols, this is
- /// indicated on the ELF object file by a symbol with SHN_COMMON section
- /// header index.
- bool HasCommonSymbols() const;
-
- /// These are the section type and flags fields. An ELF section can have
- /// only one Type, but can have more than one of the flags specified.
- ///
- /// Valid section types.
- enum {
- // This value marks the section header as inactive.
- SHT_NULL = 0x00U,
-
- // Holds information defined by the program, with custom format and meaning.
- SHT_PROGBITS = 0x01U,
-
- // This section holds a symbol table.
- SHT_SYMTAB = 0x02U,
-
- // The section holds a string table.
- SHT_STRTAB = 0x03U,
-
- // The section holds relocation entries with explicit addends.
- SHT_RELA = 0x04U,
-
- // The section holds a symbol hash table.
- SHT_HASH = 0x05U,
-
- // Information for dynamic linking.
- SHT_DYNAMIC = 0x06U,
-
- // The section holds information that marks the file in some way.
- SHT_NOTE = 0x07U,
-
- // A section of this type occupies no space in the file.
- SHT_NOBITS = 0x08U,
-
- // The section holds relocation entries without explicit addends.
- SHT_REL = 0x09U,
-
- // This section type is reserved but has unspecified semantics.
- SHT_SHLIB = 0x0AU,
-
- // This section holds a symbol table.
- SHT_DYNSYM = 0x0BU,
-
- // This section contains an array of pointers to initialization functions.
- SHT_INIT_ARRAY = 0x0EU,
-
- // This section contains an array of pointers to termination functions.
- SHT_FINI_ARRAY = 0x0FU,
-
- // This section contains an array of pointers to functions that are invoked
- // before all other initialization functions.
- SHT_PREINIT_ARRAY = 0x10U,
-
- // A section group is a set of sections that are related and that must be
- // treated specially by the linker.
- SHT_GROUP = 0x11U,
-
- // This section is associated with a section of type SHT_SYMTAB, when the
- // referenced symbol table contain the escape value SHN_XINDEX
- SHT_SYMTAB_SHNDX = 0x12U,
-
- LAST_KNOWN_SECTION_TYPE = SHT_SYMTAB_SHNDX
- };
-
- /// Valid section flags.
- enum {
- // The section contains data that should be writable.
- SHF_WRITE = 0x1U,
-
- // The section occupies memory during execution.
- SHF_ALLOC = 0x2U,
-
- // The section contains executable machine instructions.
- SHF_EXECINSTR = 0x4U,
-
- // The data in the section may be merged to eliminate duplication.
- SHF_MERGE = 0x10U,
-
- // Elements in the section consist of null-terminated character strings.
- SHF_STRINGS = 0x20U,
-
- // A field in this section holds a section header table index.
- SHF_INFO_LINK = 0x40U,
-
- // Adds special ordering requirements for link editors.
- SHF_LINK_ORDER = 0x80U,
-
- // This section requires special OS-specific processing to avoid incorrect
- // behavior.
- SHF_OS_NONCONFORMING = 0x100U,
-
- // This section is a member of a section group.
- SHF_GROUP = 0x200U,
-
- // This section holds Thread-Local Storage.
- SHF_TLS = 0x400U,
-
-
- // Start of target-specific flags.
-
- /// XCORE_SHF_CP_SECTION - All sections with the "c" flag are grouped
- /// together by the linker to form the constant pool and the cp register is
- /// set to the start of the constant pool by the boot code.
- XCORE_SHF_CP_SECTION = 0x800U,
-
- /// XCORE_SHF_DP_SECTION - All sections with the "d" flag are grouped
- /// together by the linker to form the data section and the dp register is
- /// set to the start of the section by the boot code.
- XCORE_SHF_DP_SECTION = 0x1000U
- };
-
StringRef getSectionName() const { return SectionName; }
unsigned getType() const { return Type; }
unsigned getFlags() const { return Flags; }
-
+ unsigned getEntrySize() const { return EntrySize; }
+ const MCSymbol *getGroup() const { return Group; }
+
void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const;
-
+ virtual bool UseCodeAlign() const;
+ virtual bool isVirtualSection() const;
+
/// isBaseAddressKnownZero - We know that non-allocatable sections (like
/// debug info) have a base of zero.
virtual bool isBaseAddressKnownZero() const {
- return (getFlags() & SHF_ALLOC) == 0;
+ return (getFlags() & ELF::SHF_ALLOC) == 0;
}
static bool classof(const MCSection *S) {
return S->getVariant() == SV_ELF;
}
static bool classof(const MCSectionELF *) { return true; }
+
+ // Return the entry size for sections with fixed-width data.
+ static unsigned DetermineEntrySize(SectionKind Kind);
+
};
} // end namespace llvm
diff --git a/src/LLVM/include/llvm/MC/MCSectionMachO.h b/src/LLVM/include/llvm/MC/MCSectionMachO.h
index 2d9d133..bdb17e9 100644
--- a/src/LLVM/include/llvm/MC/MCSectionMachO.h
+++ b/src/LLVM/include/llvm/MC/MCSectionMachO.h
@@ -17,36 +17,36 @@
#include "llvm/MC/MCSection.h"
namespace llvm {
-
+
/// MCSectionMachO - This represents a section on a Mach-O system (used by
/// Mac OS X). On a Mac system, these are also described in
/// /usr/include/mach-o/loader.h.
class MCSectionMachO : public MCSection {
char SegmentName[16]; // Not necessarily null terminated!
char SectionName[16]; // Not necessarily null terminated!
-
+
/// TypeAndAttributes - This is the SECTION_TYPE and SECTION_ATTRIBUTES
/// field of a section, drawn from the enums below.
unsigned TypeAndAttributes;
-
+
/// Reserved2 - The 'reserved2' field of a section, used to represent the
/// size of stubs, for example.
unsigned Reserved2;
-
+
MCSectionMachO(StringRef Segment, StringRef Section,
- unsigned TAA, unsigned reserved2, SectionKind K);
+ unsigned TAA, unsigned reserved2, SectionKind K);
friend class MCContext;
public:
-
+
/// These are the section type and attributes fields. A MachO section can
/// have only one Type, but can have any of the attributes specified.
enum {
// TypeAndAttributes bitmasks.
SECTION_TYPE = 0x000000FFU,
SECTION_ATTRIBUTES = 0xFFFFFF00U,
-
+
// Valid section types.
-
+
/// S_REGULAR - Regular section.
S_REGULAR = 0x00U,
/// S_ZEROFILL - Zero fill on demand section.
@@ -66,10 +66,10 @@
/// S_SYMBOL_STUBS - Section with symbol stubs, byte size of stub in
/// the Reserved2 field.
S_SYMBOL_STUBS = 0x08U,
- /// S_SYMBOL_STUBS - Section with only function pointers for
+ /// S_MOD_INIT_FUNC_POINTERS - Section with only function pointers for
/// initialization.
S_MOD_INIT_FUNC_POINTERS = 0x09U,
- /// S_MOD_INIT_FUNC_POINTERS - Section with only function pointers for
+ /// S_MOD_TERM_FUNC_POINTERS - Section with only function pointers for
/// termination.
S_MOD_TERM_FUNC_POINTERS = 0x0AU,
/// S_COALESCED - Section contains symbols that are to be coalesced.
@@ -101,10 +101,10 @@
S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15U,
LAST_KNOWN_SECTION_TYPE = S_THREAD_LOCAL_INIT_FUNCTION_POINTERS,
-
+
// Valid section attributes.
-
+
/// S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine
/// instructions.
S_ATTR_PURE_INSTRUCTIONS = 1U << 31,
@@ -157,14 +157,18 @@
/// flavored .s file. If successful, this fills in the specified Out
/// parameters and returns an empty string. When an invalid section
/// specifier is present, this returns a string indicating the problem.
+ /// If no TAA was parsed, TAA is not altered, and TAAWasSet becomes false.
static std::string ParseSectionSpecifier(StringRef Spec, // In.
StringRef &Segment, // Out.
StringRef &Section, // Out.
unsigned &TAA, // Out.
+ bool &TAAParsed, // Out.
unsigned &StubSize); // Out.
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const;
+ virtual bool UseCodeAlign() const;
+ virtual bool isVirtualSection() const;
static bool classof(const MCSection *S) {
return S->getVariant() == SV_MachO;
diff --git a/src/LLVM/include/llvm/MC/MCStreamer.h b/src/LLVM/include/llvm/MC/MCStreamer.h
index 5767a94..451efbf 100644
--- a/src/LLVM/include/llvm/MC/MCStreamer.h
+++ b/src/LLVM/include/llvm/MC/MCStreamer.h
@@ -14,10 +14,15 @@
#ifndef LLVM_MC_MCSTREAMER_H
#define LLVM_MC_MCSTREAMER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCWin64EH.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
namespace llvm {
+ class MCAsmBackend;
class MCAsmInfo;
class MCCodeEmitter;
class MCContext;
@@ -27,7 +32,7 @@
class MCSection;
class MCSymbol;
class StringRef;
- class TargetAsmBackend;
+ class TargetLoweringObjectFile;
class Twine;
class raw_ostream;
class formatted_raw_ostream;
@@ -47,25 +52,85 @@
MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT
MCStreamer &operator=(const MCStreamer&); // DO NOT IMPLEMENT
+ bool EmitEHFrame;
+ bool EmitDebugFrame;
+
+ std::vector<MCDwarfFrameInfo> FrameInfos;
+ MCDwarfFrameInfo *getCurrentFrameInfo();
+ void EnsureValidFrame();
+
+ std::vector<MCWin64EHUnwindInfo *> W64UnwindInfos;
+ MCWin64EHUnwindInfo *CurrentW64UnwindInfo;
+ void setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame);
+ void EnsureValidW64UnwindInfo();
+
+ MCSymbol* LastSymbol;
+
+ /// SectionStack - This is stack of current and previous section
+ /// values saved by PushSection.
+ SmallVector<std::pair<const MCSection *,
+ const MCSection *>, 4> SectionStack;
+
+ unsigned UniqueCodeBeginSuffix;
+ unsigned UniqueDataBeginSuffix;
+
protected:
+ /// Indicator of whether the previous data-or-code indicator was for
+ /// code or not. Used to determine when we need to emit a new indicator.
+ enum DataType {
+ Data,
+ Code,
+ JumpTable8,
+ JumpTable16,
+ JumpTable32
+ };
+ DataType RegionIndicator;
+
+
MCStreamer(MCContext &Ctx);
- /// CurSection - This is the current section code is being emitted to, it is
- /// kept up to date by SwitchSection.
- const MCSection *CurSection;
+ const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A,
+ const MCSymbol *B);
+
+ const MCExpr *ForceExpAbs(const MCExpr* Expr);
+
+ void EmitFrames(bool usingCFI);
+
+ MCWin64EHUnwindInfo *getCurrentW64UnwindInfo(){return CurrentW64UnwindInfo;}
+ void EmitW64Tables();
public:
virtual ~MCStreamer();
MCContext &getContext() const { return Context; }
+ unsigned getNumFrameInfos() {
+ return FrameInfos.size();
+ }
+
+ const MCDwarfFrameInfo &getFrameInfo(unsigned i) {
+ return FrameInfos[i];
+ }
+
+ ArrayRef<MCDwarfFrameInfo> getFrameInfos() {
+ return FrameInfos;
+ }
+
+ unsigned getNumW64UnwindInfos() {
+ return W64UnwindInfos.size();
+ }
+
+ MCWin64EHUnwindInfo &getW64UnwindInfo(unsigned i) {
+ return *W64UnwindInfos[i];
+ }
+
/// @name Assembly File Formatting.
/// @{
-
+
/// isVerboseAsm - Return true if this streamer supports verbose assembly
/// and if it is enabled.
virtual bool isVerboseAsm() const { return false; }
-
+
/// hasRawTextSupport - Return true if this asm streamer supports emitting
/// unformatted text to the .s file with EmitRawText.
virtual bool hasRawTextSupport() const { return false; }
@@ -78,30 +143,92 @@
/// If the comment includes embedded \n's, they will each get the comment
/// prefix as appropriate. The added comment should not end with a \n.
virtual void AddComment(const Twine &T) {}
-
+
/// GetCommentOS - Return a raw_ostream that comments can be written to.
/// Unlike AddComment, you are required to terminate comments with \n if you
/// use this method.
virtual raw_ostream &GetCommentOS();
-
+
/// AddBlankLine - Emit a blank line to a .s file to pretty it up.
virtual void AddBlankLine() {}
-
+
/// @}
-
+
/// @name Symbol & Section Management
/// @{
-
+
/// getCurrentSection - Return the current section that the streamer is
/// emitting code to.
- const MCSection *getCurrentSection() const { return CurSection; }
+ const MCSection *getCurrentSection() const {
+ if (!SectionStack.empty())
+ return SectionStack.back().first;
+ return NULL;
+ }
+
+ /// getPreviousSection - Return the previous section that the streamer is
+ /// emitting code to.
+ const MCSection *getPreviousSection() const {
+ if (!SectionStack.empty())
+ return SectionStack.back().second;
+ return NULL;
+ }
+
+ /// ChangeSection - Update streamer for a new active section.
+ ///
+ /// This is called by PopSection and SwitchSection, if the current
+ /// section changes.
+ virtual void ChangeSection(const MCSection *) = 0;
+
+ /// pushSection - Save the current and previous section on the
+ /// section stack.
+ void PushSection() {
+ SectionStack.push_back(std::make_pair(getCurrentSection(),
+ getPreviousSection()));
+ }
+
+ /// popSection - Restore the current and previous section from
+ /// the section stack. Calls ChangeSection as needed.
+ ///
+ /// Returns false if the stack was empty.
+ bool PopSection() {
+ if (SectionStack.size() <= 1)
+ return false;
+ const MCSection *oldSection = SectionStack.pop_back_val().first;
+ const MCSection *curSection = SectionStack.back().first;
+
+ if (oldSection != curSection)
+ ChangeSection(curSection);
+ return true;
+ }
/// SwitchSection - Set the current section where code is being emitted to
/// @p Section. This is required to update CurSection.
///
/// This corresponds to assembler directives like .section, .text, etc.
- virtual void SwitchSection(const MCSection *Section) = 0;
-
+ void SwitchSection(const MCSection *Section) {
+ assert(Section && "Cannot switch to a null section!");
+ const MCSection *curSection = SectionStack.back().first;
+ SectionStack.back().second = curSection;
+ if (Section != curSection) {
+ SectionStack.back().first = Section;
+ ChangeSection(Section);
+ }
+ }
+
+ /// SwitchSectionNoChange - Set the current section where code is being
+ /// emitted to @p Section. This is required to update CurSection. This
+ /// version does not call ChangeSection.
+ void SwitchSectionNoChange(const MCSection *Section) {
+ assert(Section && "Cannot switch to a null section!");
+ const MCSection *curSection = SectionStack.back().first;
+ SectionStack.back().second = curSection;
+ if (Section != curSection)
+ SectionStack.back().first = Section;
+ }
+
+ /// InitSections - Create the default sections and set the initial one.
+ virtual void InitSections() = 0;
+
/// EmitLabel - Emit a label for @p Symbol into the current section.
///
/// This corresponds to an assembler statement such as:
@@ -110,11 +237,53 @@
/// @param Symbol - The symbol to emit. A given symbol should only be
/// emitted as a label once, and symbols emitted as a label should never be
/// used in an assignment.
- virtual void EmitLabel(MCSymbol *Symbol) = 0;
+ virtual void EmitLabel(MCSymbol *Symbol);
+
+ /// EmitDataRegion - Emit a label that marks the beginning of a data
+ /// region.
+ /// On ELF targets, this corresponds to an assembler statement such as:
+ /// $d.1:
+ virtual void EmitDataRegion();
+
+ /// EmitJumpTable8Region - Emit a label that marks the beginning of a
+ /// jump table composed of 8-bit offsets.
+ /// On ELF targets, this corresponds to an assembler statement such as:
+ /// $d.1:
+ virtual void EmitJumpTable8Region();
+
+ /// EmitJumpTable16Region - Emit a label that marks the beginning of a
+ /// jump table composed of 16-bit offsets.
+ /// On ELF targets, this corresponds to an assembler statement such as:
+ /// $d.1:
+ virtual void EmitJumpTable16Region();
+
+ /// EmitJumpTable32Region - Emit a label that marks the beginning of a
+ /// jump table composed of 32-bit offsets.
+ /// On ELF targets, this corresponds to an assembler statement such as:
+ /// $d.1:
+ virtual void EmitJumpTable32Region();
+
+ /// EmitCodeRegion - Emit a label that marks the beginning of a code
+ /// region.
+ /// On ELF targets, this corresponds to an assembler statement such as:
+ /// $a.1:
+ virtual void EmitCodeRegion();
+
+ /// ForceCodeRegion - Forcibly sets the current region mode to code. Used
+ /// at function entry points.
+ void ForceCodeRegion() { RegionIndicator = Code; }
+
+
+ virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
+ MCSymbol *EHSymbol);
/// EmitAssemblerFlag - Note in the output the specified @p Flag
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0;
+ /// EmitThumbFunc - Note in the output that the specified @p Func is
+ /// a Thumb mode function (ARM target only).
+ virtual void EmitThumbFunc(MCSymbol *Func) = 0;
+
/// EmitAssignment - Emit an assignment of @p Value to @p Symbol.
///
/// This corresponds to an assembler statement such as:
@@ -128,6 +297,15 @@
/// @param Value - The value for the symbol.
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) = 0;
+ /// EmitWeakReference - Emit an weak reference from @p Alias to @p Symbol.
+ ///
+ /// This corresponds to an assembler statement such as:
+ /// .weakref alias, symbol
+ ///
+ /// @param Alias - The alias that is being created.
+ /// @param Symbol - The symbol being aliased.
+ virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) = 0;
+
/// EmitSymbolAttribute - Add the given @p Attribute to @p Symbol.
virtual void EmitSymbolAttribute(MCSymbol *Symbol,
MCSymbolAttr Attribute) = 0;
@@ -162,7 +340,7 @@
/// .size symbol, expression
///
virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) = 0;
-
+
/// EmitCommonSymbol - Emit a common symbol.
///
/// @param Symbol - The common symbol to emit.
@@ -176,8 +354,10 @@
///
/// @param Symbol - The common symbol to emit.
/// @param Size - The size of the common symbol.
- virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) = 0;
-
+ /// @param ByteAlignment - The alignment of the common symbol in bytes.
+ virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) = 0;
+
/// EmitZerofill - Emit the zerofill section and an optional symbol.
///
/// @param Section - The zerofill section to create and or to put the symbol
@@ -196,7 +376,8 @@
/// @param ByteAlignment - The alignment of the thread local common symbol
/// if non-zero. This must be a power of 2 on some targets.
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size, unsigned ByteAlignment = 0) = 0;
+ uint64_t Size, unsigned ByteAlignment = 0) = 0;
+
/// @}
/// @name Generating Data
/// @{
@@ -216,38 +397,59 @@
/// @param Value - The value to emit.
/// @param Size - The size of the integer (in bytes) to emit. This must
/// match a native machine width.
- virtual void EmitValue(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace = 0) = 0;
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace) = 0;
+
+ void EmitValue(const MCExpr *Value, unsigned Size, unsigned AddrSpace = 0);
/// EmitIntValue - Special case of EmitValue that avoids the client having
/// to pass in a MCExpr for constant integers.
virtual void EmitIntValue(uint64_t Value, unsigned Size,
unsigned AddrSpace = 0);
-
+
+ /// EmitAbsValue - Emit the Value, but try to avoid relocations. On MachO
+ /// this is done by producing
+ /// foo = value
+ /// .long foo
+ void EmitAbsValue(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace = 0);
+
+ virtual void EmitULEB128Value(const MCExpr *Value) = 0;
+
+ virtual void EmitSLEB128Value(const MCExpr *Value) = 0;
+
+ /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
+ /// client having to pass in a MCExpr for constant integers.
+ void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0);
+
+ /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
+ /// client having to pass in a MCExpr for constant integers.
+ void EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace = 0);
+
/// EmitSymbolValue - Special case of EmitValue that avoids the client
/// having to pass in a MCExpr for MCSymbols.
- virtual void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
- unsigned AddrSpace);
-
+ void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
+ unsigned AddrSpace = 0);
+
/// EmitGPRel32Value - Emit the expression @p Value into the output as a
/// gprel32 (32-bit GP relative) value.
///
/// This is used to implement assembler directives such as .gprel32 on
/// targets that support them.
- virtual void EmitGPRel32Value(const MCExpr *Value) = 0;
-
+ virtual void EmitGPRel32Value(const MCExpr *Value);
+
/// EmitFill - Emit NumBytes bytes worth of the value specified by
/// FillValue. This implements directives such as '.space'.
virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
unsigned AddrSpace);
-
+
/// EmitZeros - Emit NumBytes worth of zeros. This is a convenience
/// function that just wraps EmitFill.
void EmitZeros(uint64_t NumBytes, unsigned AddrSpace) {
EmitFill(NumBytes, 0, AddrSpace);
}
-
+
/// EmitValueToAlignment - Emit some number of copies of @p Value until
/// the byte alignment @p ByteAlignment is reached.
///
@@ -293,17 +495,68 @@
/// @param Value - The value to use when filling bytes.
virtual void EmitValueToOffset(const MCExpr *Offset,
unsigned char Value = 0) = 0;
-
+
/// @}
-
+
/// EmitFileDirective - Switch to a new logical file. This is used to
/// implement the '.file "foo.c"' assembler directive.
virtual void EmitFileDirective(StringRef Filename) = 0;
-
+
/// EmitDwarfFileDirective - Associate a filename with a specified logical
/// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler
/// directive.
- virtual void EmitDwarfFileDirective(unsigned FileNo,StringRef Filename) = 0;
+ virtual bool EmitDwarfFileDirective(unsigned FileNo,StringRef Filename);
+
+ /// EmitDwarfLocDirective - This implements the DWARF2
+ // '.loc fileno lineno ...' assembler directive.
+ virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
+ unsigned Column, unsigned Flags,
+ unsigned Isa,
+ unsigned Discriminator,
+ StringRef FileName);
+
+ virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
+ const MCSymbol *LastLabel,
+ const MCSymbol *Label,
+ unsigned PointerSize) = 0;
+
+ virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
+ const MCSymbol *Label) {
+ }
+
+ void EmitDwarfSetLineAddr(int64_t LineDelta, const MCSymbol *Label,
+ int PointerSize);
+
+ virtual void EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding);
+ virtual void EmitCFISections(bool EH, bool Debug);
+ virtual void EmitCFIStartProc();
+ virtual void EmitCFIEndProc();
+ virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
+ virtual void EmitCFIDefCfaOffset(int64_t Offset);
+ virtual void EmitCFIDefCfaRegister(int64_t Register);
+ virtual void EmitCFIOffset(int64_t Register, int64_t Offset);
+ virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
+ virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
+ virtual void EmitCFIRememberState();
+ virtual void EmitCFIRestoreState();
+ virtual void EmitCFISameValue(int64_t Register);
+ virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
+ virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
+
+ virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
+ virtual void EmitWin64EHEndProc();
+ virtual void EmitWin64EHStartChained();
+ virtual void EmitWin64EHEndChained();
+ virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
+ bool Except);
+ virtual void EmitWin64EHHandlerData();
+ virtual void EmitWin64EHPushReg(unsigned Register);
+ virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset);
+ virtual void EmitWin64EHAllocStack(unsigned Size);
+ virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset);
+ virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset);
+ virtual void EmitWin64EHPushFrame(bool Code);
+ virtual void EmitWin64EHEndProlog();
/// EmitInstruction - Emit the given @p Instruction into the current
/// section.
@@ -314,7 +567,20 @@
/// indicated by the hasRawTextSupport() predicate. By default this aborts.
virtual void EmitRawText(StringRef String);
void EmitRawText(const Twine &String);
-
+
+ /// ARM-related methods.
+ /// FIXME: Eventually we should have some "target MC streamer" and move
+ /// these methods there.
+ virtual void EmitFnStart();
+ virtual void EmitFnEnd();
+ virtual void EmitCantUnwind();
+ virtual void EmitPersonality(const MCSymbol *Personality);
+ virtual void EmitHandlerData();
+ virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
+ virtual void EmitPad(int64_t Offset);
+ virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
+ bool isVector);
+
/// Finish - Finish emission of machine code.
virtual void Finish() = 0;
};
@@ -334,19 +600,29 @@
/// \param CE - If given, a code emitter to use to show the instruction
/// encoding inline with the assembly. This method takes ownership of \arg CE.
///
+ /// \param TAB - If given, a target asm backend to use to show the fixup
+ /// information in conjunction with encoding information. This method takes
+ /// ownership of \arg TAB.
+ ///
/// \param ShowInst - Whether to show the MCInst representation inline with
/// the assembly.
+ ///
+ /// \param DecodeLSDA - If true, emit comments that translates the LSDA into a
+ /// human readable format. Only usable with CFI.
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
- bool isLittleEndian, bool isVerboseAsm,
+ bool isVerboseAsm,
+ bool useLoc,
+ bool useCFI,
MCInstPrinter *InstPrint = 0,
MCCodeEmitter *CE = 0,
+ MCAsmBackend *TAB = 0,
bool ShowInst = false);
/// createMachOStreamer - Create a machine code streamer which will generate
/// Mach-O format object files.
///
/// Takes ownership of \arg TAB and \arg CE.
- MCStreamer *createMachOStreamer(MCContext &Ctx, TargetAsmBackend &TAB,
+ MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *CE,
bool RelaxAll = false);
@@ -355,16 +631,29 @@
///
/// Takes ownership of \arg TAB and \arg CE.
MCStreamer *createWinCOFFStreamer(MCContext &Ctx,
- TargetAsmBackend &TAB,
+ MCAsmBackend &TAB,
MCCodeEmitter &CE, raw_ostream &OS,
bool RelaxAll = false);
+ /// createELFStreamer - Create a machine code streamer which will generate
+ /// ELF format object files.
+ MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *CE,
+ bool RelaxAll, bool NoExecStack);
+
/// createLoggingStreamer - Create a machine code streamer which just logs the
/// API calls and then dispatches to another streamer.
///
/// The new streamer takes ownership of the \arg Child.
MCStreamer *createLoggingStreamer(MCStreamer *Child, raw_ostream &OS);
+ /// createPureStreamer - Create a machine code streamer which will generate
+ /// "pure" MC object files, for use with MC-JIT and testing tools.
+ ///
+ /// Takes ownership of \arg TAB and \arg CE.
+ MCStreamer *createPureStreamer(MCContext &Ctx, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *CE);
+
} // end namespace llvm
#endif
diff --git a/src/LLVM/include/llvm/MC/MCSubtargetInfo.h b/src/LLVM/include/llvm/MC/MCSubtargetInfo.h
new file mode 100644
index 0000000..3b53f20
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCSubtargetInfo.h
@@ -0,0 +1,79 @@
+//==-- llvm/MC/MCSubtargetInfo.h - Subtarget Information ---------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the subtarget options of a Target machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSUBTARGET_H
+#define LLVM_MC_MCSUBTARGET_H
+
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/MC/MCInstrItineraries.h"
+#include <string>
+
+namespace llvm {
+
+class StringRef;
+
+//===----------------------------------------------------------------------===//
+///
+/// MCSubtargetInfo - Generic base class for all target subtargets.
+///
+class MCSubtargetInfo {
+ std::string TargetTriple; // Target triple
+ const SubtargetFeatureKV *ProcFeatures; // Processor feature list
+ const SubtargetFeatureKV *ProcDesc; // Processor descriptions
+ const SubtargetInfoKV *ProcItins; // Scheduling itineraries
+ const InstrStage *Stages; // Instruction stages
+ const unsigned *OperandCycles; // Operand cycles
+ const unsigned *ForwardingPathes; // Forwarding pathes
+ unsigned NumFeatures; // Number of processor features
+ unsigned NumProcs; // Number of processors
+ uint64_t FeatureBits; // Feature bits for current CPU + FS
+
+public:
+ void InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
+ const SubtargetFeatureKV *PF,
+ const SubtargetFeatureKV *PD,
+ const SubtargetInfoKV *PI, const InstrStage *IS,
+ const unsigned *OC, const unsigned *FP,
+ unsigned NF, unsigned NP);
+
+ /// getTargetTriple - Return the target triple string.
+ StringRef getTargetTriple() const {
+ return TargetTriple;
+ }
+
+ /// getFeatureBits - Return the feature bits.
+ ///
+ uint64_t getFeatureBits() const {
+ return FeatureBits;
+ }
+
+ /// ReInitMCSubtargetInfo - Change CPU (and optionally supplemented with
+ /// feature string), recompute and return feature bits.
+ uint64_t ReInitMCSubtargetInfo(StringRef CPU, StringRef FS);
+
+ /// ToggleFeature - Toggle a feature and returns the re-computed feature
+ /// bits. This version does not change the implied bits.
+ uint64_t ToggleFeature(uint64_t FB);
+
+ /// ToggleFeature - Toggle a feature and returns the re-computed feature
+ /// bits. This version will also change all implied bits.
+ uint64_t ToggleFeature(StringRef FS);
+
+ /// getInstrItineraryForCPU - Get scheduling itinerary of a CPU.
+ ///
+ InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/MCSymbol.h b/src/LLVM/include/llvm/MC/MCSymbol.h
index 1b432c2..0583ce5 100644
--- a/src/LLVM/include/llvm/MC/MCSymbol.h
+++ b/src/LLVM/include/llvm/MC/MCSymbol.h
@@ -52,15 +52,15 @@
/// "Lfoo" or ".foo".
unsigned IsTemporary : 1;
- /// IsUsedInExpr - True if this symbol has been used in an expression and
- /// cannot be redefined.
- unsigned IsUsedInExpr : 1;
+ /// IsUsed - True if this symbol has been used.
+ mutable unsigned IsUsed : 1;
private: // MCContext creates and uniques these.
+ friend class MCExpr;
friend class MCContext;
MCSymbol(StringRef name, bool isTemporary)
: Name(name), Section(0), Value(0),
- IsTemporary(isTemporary), IsUsedInExpr(false) {}
+ IsTemporary(isTemporary), IsUsed(false) {}
MCSymbol(const MCSymbol&); // DO NOT IMPLEMENT
void operator=(const MCSymbol&); // DO NOT IMPLEMENT
@@ -74,9 +74,9 @@
/// isTemporary - Check if this is an assembler temporary symbol.
bool isTemporary() const { return IsTemporary; }
- /// isUsedInExpr - Check if this is an assembler temporary symbol.
- bool isUsedInExpr() const { return IsUsedInExpr; }
- void setUsedInExpr(bool Value) { IsUsedInExpr = Value; }
+ /// isUsed - Check if this is used.
+ bool isUsed() const { return IsUsed; }
+ void setUsed(bool Value) const { IsUsed = Value; }
/// @}
/// @name Associated Sections
@@ -135,9 +135,15 @@
/// getValue() - Get the value for variable symbols.
const MCExpr *getVariableValue() const {
assert(isVariable() && "Invalid accessor!");
+ IsUsed = true;
return Value;
}
+ // AliasedSymbol() - If this is an alias (a = b), return the symbol
+ // we ultimately point to. For a non alias, this just returns the symbol
+ // itself.
+ const MCSymbol &AliasedSymbol() const;
+
void setVariableValue(const MCExpr *Value);
/// @}
diff --git a/src/LLVM/include/llvm/MC/MCTargetAsmLexer.h b/src/LLVM/include/llvm/MC/MCTargetAsmLexer.h
new file mode 100644
index 0000000..acb3d4d
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCTargetAsmLexer.h
@@ -0,0 +1,89 @@
+//===-- llvm/MC/MCTargetAsmLexer.h - Target Assembly Lexer ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCTARGETASMLEXER_H
+#define LLVM_MC_MCTARGETASMLEXER_H
+
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+
+namespace llvm {
+class Target;
+
+/// MCTargetAsmLexer - Generic interface to target specific assembly lexers.
+class MCTargetAsmLexer {
+ /// The current token
+ AsmToken CurTok;
+
+ /// The location and description of the current error
+ SMLoc ErrLoc;
+ std::string Err;
+
+ MCTargetAsmLexer(const MCTargetAsmLexer &); // DO NOT IMPLEMENT
+ void operator=(const MCTargetAsmLexer &); // DO NOT IMPLEMENT
+protected: // Can only create subclasses.
+ MCTargetAsmLexer(const Target &);
+
+ virtual AsmToken LexToken() = 0;
+
+ void SetError(const SMLoc &errLoc, const std::string &err) {
+ ErrLoc = errLoc;
+ Err = err;
+ }
+
+ /// TheTarget - The Target that this machine was created for.
+ const Target &TheTarget;
+ MCAsmLexer *Lexer;
+
+public:
+ virtual ~MCTargetAsmLexer();
+
+ const Target &getTarget() const { return TheTarget; }
+
+ /// InstallLexer - Set the lexer to get tokens from lower-level lexer \arg L.
+ void InstallLexer(MCAsmLexer &L) {
+ Lexer = &L;
+ }
+
+ MCAsmLexer *getLexer() {
+ return Lexer;
+ }
+
+ /// Lex - Consume the next token from the input stream and return it.
+ const AsmToken &Lex() {
+ return CurTok = LexToken();
+ }
+
+ /// getTok - Get the current (last) lexed token.
+ const AsmToken &getTok() {
+ return CurTok;
+ }
+
+ /// getErrLoc - Get the current error location
+ const SMLoc &getErrLoc() {
+ return ErrLoc;
+ }
+
+ /// getErr - Get the current error string
+ const std::string &getErr() {
+ return Err;
+ }
+
+ /// getKind - Get the kind of current token.
+ AsmToken::TokenKind getKind() const { return CurTok.getKind(); }
+
+ /// is - Check if the current token has kind \arg K.
+ bool is(AsmToken::TokenKind K) const { return CurTok.is(K); }
+
+ /// isNot - Check if the current token has kind \arg K.
+ bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/MCTargetAsmParser.h b/src/LLVM/include/llvm/MC/MCTargetAsmParser.h
new file mode 100644
index 0000000..4e3fd0d
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCTargetAsmParser.h
@@ -0,0 +1,103 @@
+//===-- llvm/MC/MCTargetAsmParser.h - Target Assembly Parser ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_TARGETPARSER_H
+#define LLVM_MC_TARGETPARSER_H
+
+#include "llvm/MC/MCParser/MCAsmParserExtension.h"
+
+namespace llvm {
+class MCStreamer;
+class StringRef;
+class SMLoc;
+class AsmToken;
+class MCParsedAsmOperand;
+class MCInst;
+template <typename T> class SmallVectorImpl;
+
+/// MCTargetAsmParser - Generic interface to target specific assembly parsers.
+class MCTargetAsmParser : public MCAsmParserExtension {
+public:
+ enum MatchResultTy {
+ Match_ConversionFail,
+ Match_InvalidOperand,
+ Match_MissingFeature,
+ Match_MnemonicFail,
+ Match_Success,
+ FIRST_TARGET_MATCH_RESULT_TY
+ };
+
+private:
+ MCTargetAsmParser(const MCTargetAsmParser &); // DO NOT IMPLEMENT
+ void operator=(const MCTargetAsmParser &); // DO NOT IMPLEMENT
+protected: // Can only create subclasses.
+ MCTargetAsmParser();
+
+ /// AvailableFeatures - The current set of available features.
+ unsigned AvailableFeatures;
+
+public:
+ virtual ~MCTargetAsmParser();
+
+ unsigned getAvailableFeatures() const { return AvailableFeatures; }
+ void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
+
+ virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
+ SMLoc &EndLoc) = 0;
+
+ /// ParseInstruction - Parse one assembly instruction.
+ ///
+ /// The parser is positioned following the instruction name. The target
+ /// specific instruction parser should parse the entire instruction and
+ /// construct the appropriate MCInst, or emit an error. On success, the entire
+ /// line should be parsed up to and including the end-of-statement token. On
+ /// failure, the parser is not required to read to the end of the line.
+ //
+ /// \param Name - The instruction name.
+ /// \param NameLoc - The source location of the name.
+ /// \param Operands [out] - The list of parsed operands, this returns
+ /// ownership of them to the caller.
+ /// \return True on failure.
+ virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
+
+ /// ParseDirective - Parse a target specific assembler directive
+ ///
+ /// The parser is positioned following the directive name. The target
+ /// specific directive parser should parse the entire directive doing or
+ /// recording any target specific work, or return true and do nothing if the
+ /// directive is not target specific. If the directive is specific for
+ /// the target, the entire line is parsed up to and including the
+ /// end-of-statement token and false is returned.
+ ///
+ /// \param DirectiveID - the identifier token of the directive.
+ virtual bool ParseDirective(AsmToken DirectiveID) = 0;
+
+ /// MatchAndEmitInstruction - Recognize a series of operands of a parsed
+ /// instruction as an actual MCInst and emit it to the specified MCStreamer.
+ /// This returns false on success and returns true on failure to match.
+ ///
+ /// On failure, the target parser is responsible for emitting a diagnostic
+ /// explaining the match failure.
+ virtual bool
+ MatchAndEmitInstruction(SMLoc IDLoc,
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ MCStreamer &Out) = 0;
+
+ /// checkTargetMatchPredicate - Validate the instruction match against
+ /// any complex target predicates not expressible via match classes.
+ virtual unsigned checkTargetMatchPredicate(MCInst &Inst) {
+ return Match_Success;
+ }
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/MCValue.h b/src/LLVM/include/llvm/MC/MCValue.h
index 11b6c2a..8352ed1 100644
--- a/src/LLVM/include/llvm/MC/MCValue.h
+++ b/src/LLVM/include/llvm/MC/MCValue.h
@@ -14,7 +14,7 @@
#ifndef LLVM_MC_MCVALUE_H
#define LLVM_MC_MCVALUE_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/MC/MCSymbol.h"
#include <cassert>
@@ -46,16 +46,6 @@
/// isAbsolute - Is this an absolute (as opposed to relocatable) value.
bool isAbsolute() const { return !SymA && !SymB; }
- /// getAssociatedSection - For relocatable values, return the section the
- /// value is associated with.
- ///
- /// @result - The value's associated section, or null for external or constant
- /// values.
- //
- // FIXME: Switch to a tagged section, so this can return the tagged section
- // value.
- const MCSection *getAssociatedSection() const;
-
/// print - Print the value to the stream \arg OS.
void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
diff --git a/src/LLVM/include/llvm/MC/MCWin64EH.h b/src/LLVM/include/llvm/MC/MCWin64EH.h
new file mode 100644
index 0000000..eb4665a
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MCWin64EH.h
@@ -0,0 +1,93 @@
+//===- MCWin64EH.h - Machine Code Win64 EH support --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains declarations to support the Win64 Exception Handling
+// scheme in MC.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCWIN64EH_H
+#define LLVM_MC_MCWIN64EH_H
+
+#include "llvm/Support/Win64EH.h"
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+ class StringRef;
+ class MCStreamer;
+ class MCSymbol;
+
+ class MCWin64EHInstruction {
+ public:
+ typedef Win64EH::UnwindOpcodes OpType;
+ private:
+ OpType Operation;
+ MCSymbol *Label;
+ unsigned Offset;
+ unsigned Register;
+ public:
+ MCWin64EHInstruction(OpType Op, MCSymbol *L, unsigned Reg)
+ : Operation(Op), Label(L), Offset(0), Register(Reg) {
+ assert(Op == Win64EH::UOP_PushNonVol);
+ }
+ MCWin64EHInstruction(MCSymbol *L, unsigned Size)
+ : Operation(Size>128 ? Win64EH::UOP_AllocLarge : Win64EH::UOP_AllocSmall),
+ Label(L), Offset(Size) { }
+ MCWin64EHInstruction(OpType Op, MCSymbol *L, unsigned Reg, unsigned Off)
+ : Operation(Op), Label(L), Offset(Off), Register(Reg) {
+ assert(Op == Win64EH::UOP_SetFPReg ||
+ Op == Win64EH::UOP_SaveNonVol ||
+ Op == Win64EH::UOP_SaveNonVolBig ||
+ Op == Win64EH::UOP_SaveXMM128 ||
+ Op == Win64EH::UOP_SaveXMM128Big);
+ }
+ MCWin64EHInstruction(OpType Op, MCSymbol *L, bool Code)
+ : Operation(Op), Label(L), Offset(Code ? 1 : 0) {
+ assert(Op == Win64EH::UOP_PushMachFrame);
+ }
+ OpType getOperation() const { return Operation; }
+ MCSymbol *getLabel() const { return Label; }
+ unsigned getOffset() const { return Offset; }
+ unsigned getSize() const { return Offset; }
+ unsigned getRegister() const { return Register; }
+ bool isPushCodeFrame() const { return Offset == 1; }
+ };
+
+ struct MCWin64EHUnwindInfo {
+ MCWin64EHUnwindInfo() : Begin(0), End(0), ExceptionHandler(0),
+ Function(0), PrologEnd(0), Symbol(0),
+ HandlesUnwind(false), HandlesExceptions(false),
+ LastFrameInst(-1), ChainedParent(0),
+ Instructions() {}
+ MCSymbol *Begin;
+ MCSymbol *End;
+ const MCSymbol *ExceptionHandler;
+ const MCSymbol *Function;
+ MCSymbol *PrologEnd;
+ MCSymbol *Symbol;
+ bool HandlesUnwind;
+ bool HandlesExceptions;
+ int LastFrameInst;
+ MCWin64EHUnwindInfo *ChainedParent;
+ std::vector<MCWin64EHInstruction> Instructions;
+ };
+
+ class MCWin64EHUnwindEmitter {
+ public:
+ static StringRef GetSectionSuffix(const MCSymbol *func);
+ //
+ // This emits the unwind info sections (.pdata and .xdata in PE/COFF).
+ //
+ static void Emit(MCStreamer &streamer);
+ static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info);
+ };
+} // end namespace llvm
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/MachineLocation.h b/src/LLVM/include/llvm/MC/MachineLocation.h
new file mode 100644
index 0000000..8ddfdbc
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/MachineLocation.h
@@ -0,0 +1,98 @@
+//===-- llvm/MC/MachineLocation.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// The MachineLocation class is used to represent a simple location in a machine
+// frame. Locations will be one of two forms; a register or an address formed
+// from a base address plus an offset. Register indirection can be specified by
+// using an offset of zero.
+//
+// The MachineMove class is used to represent abstract move operations in the
+// prolog/epilog of a compiled function. A collection of these objects can be
+// used by a debug consumer to track the location of values when unwinding stack
+// frames.
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_MC_MACHINELOCATION_H
+#define LLVM_MC_MACHINELOCATION_H
+
+namespace llvm {
+ class MCSymbol;
+
+class MachineLocation {
+private:
+ bool IsRegister; // True if location is a register.
+ unsigned Register; // gcc/gdb register number.
+ int Offset; // Displacement if not register.
+public:
+ enum {
+ // The target register number for an abstract frame pointer. The value is
+ // an arbitrary value that doesn't collide with any real target register.
+ VirtualFP = ~0U
+ };
+ MachineLocation()
+ : IsRegister(false), Register(0), Offset(0) {}
+ explicit MachineLocation(unsigned R)
+ : IsRegister(true), Register(R), Offset(0) {}
+ MachineLocation(unsigned R, int O)
+ : IsRegister(false), Register(R), Offset(O) {}
+
+ bool operator==(const MachineLocation &Other) const {
+ return IsRegister == Other.IsRegister && Register == Other.Register &&
+ Offset == Other.Offset;
+ }
+
+ // Accessors
+ bool isReg() const { return IsRegister; }
+ unsigned getReg() const { return Register; }
+ int getOffset() const { return Offset; }
+ void setIsRegister(bool Is) { IsRegister = Is; }
+ void setRegister(unsigned R) { Register = R; }
+ void setOffset(int O) { Offset = O; }
+ void set(unsigned R) {
+ IsRegister = true;
+ Register = R;
+ Offset = 0;
+ }
+ void set(unsigned R, int O) {
+ IsRegister = false;
+ Register = R;
+ Offset = O;
+ }
+
+#ifndef NDEBUG
+ void dump();
+#endif
+};
+
+/// MachineMove - This class represents the save or restore of a callee saved
+/// register that exception or debug info needs to know about.
+class MachineMove {
+private:
+ /// Label - Symbol for post-instruction address when result of move takes
+ /// effect.
+ MCSymbol *Label;
+
+ // Move to & from location.
+ MachineLocation Destination, Source;
+public:
+ MachineMove() : Label(0) {}
+
+ MachineMove(MCSymbol *label, const MachineLocation &D,
+ const MachineLocation &S)
+ : Label(label), Destination(D), Source(S) {}
+
+ // Accessors
+ MCSymbol *getLabel() const { return Label; }
+ const MachineLocation &getDestination() const { return Destination; }
+ const MachineLocation &getSource() const { return Source; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/src/LLVM/include/llvm/MC/SubtargetFeature.h b/src/LLVM/include/llvm/MC/SubtargetFeature.h
new file mode 100644
index 0000000..1a7dc92
--- /dev/null
+++ b/src/LLVM/include/llvm/MC/SubtargetFeature.h
@@ -0,0 +1,115 @@
+//===-- llvm/MC/SubtargetFeature.h - CPU characteristics --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines and manages user or tool specified CPU characteristics.
+// The intent is to be able to package specific features that should or should
+// not be used on a specific target processor. A tool, such as llc, could, as
+// as example, gather chip info from the command line, a long with features
+// that should be used on that chip.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_SUBTARGETFEATURE_H
+#define LLVM_MC_SUBTARGETFEATURE_H
+
+#include <vector>
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+ class raw_ostream;
+ class StringRef;
+
+//===----------------------------------------------------------------------===//
+///
+/// SubtargetFeatureKV - Used to provide key value pairs for feature and
+/// CPU bit flags.
+//
+struct SubtargetFeatureKV {
+ const char *Key; // K-V key string
+ const char *Desc; // Help descriptor
+ uint64_t Value; // K-V integer value
+ uint64_t Implies; // K-V bit mask
+
+ // Compare routine for std binary search
+ bool operator<(const SubtargetFeatureKV &S) const {
+ return strcmp(Key, S.Key) < 0;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+///
+/// SubtargetInfoKV - Used to provide key value pairs for CPU and arbitrary
+/// pointers.
+//
+struct SubtargetInfoKV {
+ const char *Key; // K-V key string
+ void *Value; // K-V pointer value
+
+ // Compare routine for std binary search
+ bool operator<(const SubtargetInfoKV &S) const {
+ return strcmp(Key, S.Key) < 0;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+///
+/// SubtargetFeatures - Manages the enabling and disabling of subtarget
+/// specific features. Features are encoded as a string of the form
+/// "cpu,+attr1,+attr2,-attr3,...,+attrN"
+/// A comma separates each feature from the next (all lowercase.)
+/// The first feature is always the CPU subtype (eg. pentiumm). If the CPU
+/// value is "generic" then the CPU subtype should be generic for the target.
+/// Each of the remaining features is prefixed with + or - indicating whether
+/// that feature should be enabled or disabled contrary to the cpu
+/// specification.
+///
+
+class SubtargetFeatures {
+ std::vector<std::string> Features; // Subtarget features as a vector
+public:
+ explicit SubtargetFeatures(const StringRef Initial = "");
+
+ /// Features string accessors.
+ std::string getString() const;
+
+ /// Adding Features.
+ void AddFeature(const StringRef String, bool IsEnabled = true);
+
+ /// ToggleFeature - Toggle a feature and returns the newly updated feature
+ /// bits.
+ uint64_t ToggleFeature(uint64_t Bits, const StringRef String,
+ const SubtargetFeatureKV *FeatureTable,
+ size_t FeatureTableSize);
+
+ /// Get feature bits of a CPU.
+ uint64_t getFeatureBits(const StringRef CPU,
+ const SubtargetFeatureKV *CPUTable,
+ size_t CPUTableSize,
+ const SubtargetFeatureKV *FeatureTable,
+ size_t FeatureTableSize);
+
+ /// Get scheduling itinerary of a CPU.
+ void *getItinerary(const StringRef CPU,
+ const SubtargetInfoKV *Table, size_t TableSize);
+
+ /// Print feature string.
+ void print(raw_ostream &OS) const;
+
+ // Dump feature info.
+ void dump() const;
+
+ /// Retrieve a formatted string of the default features for the specified
+ /// target triple.
+ void getDefaultSubtargetFeatures(const Triple& Triple);
+};
+
+} // End namespace llvm
+
+#endif