This commit is contained in:
nephacks
2025-06-04 03:22:50 +02:00
parent f234f23848
commit f12416cffd
14243 changed files with 6446499 additions and 26 deletions

View File

@@ -0,0 +1,29 @@
//===-- llvm/MC/EDInstInfo.h - EDis instruction info ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef EDINSTINFO_H
#define EDINSTINFO_H
#include "llvm/Support/DataTypes.h"
namespace llvm {
#define EDIS_MAX_OPERANDS 13
#define EDIS_MAX_SYNTAXES 2
struct EDInstInfo {
uint8_t instructionType;
uint8_t numOperands;
uint8_t operandTypes[EDIS_MAX_OPERANDS];
uint8_t operandFlags[EDIS_MAX_OPERANDS];
const signed char operandOrders[EDIS_MAX_SYNTAXES][EDIS_MAX_OPERANDS];
};
} // namespace llvm
#endif

View File

@@ -0,0 +1,167 @@
//===-- 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/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
class MCAsmLayout;
class MCAssembler;
class MCELFObjectTargetWriter;
struct MCFixupKindInfo;
class MCFragment;
class MCInst;
class MCRelaxableFragment;
class MCObjectWriter;
class MCSection;
class MCValue;
class raw_ostream;
/// MCAsmBackend - Generic interface to target specific assembler backends.
class MCAsmBackend {
MCAsmBackend(const MCAsmBackend &) LLVM_DELETED_FUNCTION;
void operator=(const MCAsmBackend &) LLVM_DELETED_FUNCTION;
protected: // Can only create subclasses.
MCAsmBackend();
unsigned HasReliableSymbolDifference : 1;
unsigned HasDataInCodeSupport : 1;
public:
virtual ~MCAsmBackend();
/// lifetime management
virtual void reset() { }
/// 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 {
llvm_unreachable("createELFObjectTargetWriter is not supported by asm "
"backend");
}
/// 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;
}
/// hasDataInCodeSupport - Check whether this target implements data-in-code
/// markers. If not, data region directives will be ignored.
bool hasDataInCodeSupport() const {
return HasDataInCodeSupport;
}
/// 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;
/// processFixupValue - Target hook to adjust the literal value of a fixup
/// if necessary. IsResolved signals whether the caller believes a relocation
/// is needed; the target can modify the value. The default does nothing.
virtual void processFixupValue(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFixup &Fixup, const MCFragment *DF,
MCValue &Target, uint64_t &Value,
bool &IsResolved) {}
/// @}
/// applyFixup - Apply the \p Value for given \p 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;
/// fixupNeedsRelaxation - Target specific predicate for whether a given
/// fixup requires the associated instruction to be relaxed.
virtual bool fixupNeedsRelaxation(const MCFixup &Fixup,
uint64_t Value,
const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) 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.
/// \param [out] Res On return, the relaxed instruction.
virtual void relaxInstruction(const MCInst &Inst, MCInst &Res) const = 0;
/// @}
/// getMinimumNopSize - Returns the minimum size of a nop in bytes on this
/// target. The assembler will use this to emit excess padding in situations
/// where the padding required for simple alignment would be less than the
/// minimum nop size.
///
virtual unsigned getMinimumNopSize() const { return 1; }
/// 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

View File

@@ -0,0 +1,580 @@
//===-- llvm/MC/MCAsmInfo.h - Asm 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 contains a class to be used as the basis for target specific
// asm writers. This class primarily takes care of global printing constants,
// which are used in very similar ways across all targets.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCASMINFO_H
#define LLVM_MC_MCASMINFO_H
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MachineLocation.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 { NoAlignment, ByteAlignment, Log2Alignment };
}
/// MCAsmInfo - This class is intended to be used as a base class for asm
/// properties and features specific to the target.
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;
/// CalleeSaveStackSlotSize - Size of the stack slot reserved for
/// callee-saved registers, in bytes.
/// Default is same as pointer size.
unsigned CalleeSaveStackSlotSize;
/// 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.
/// 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 "$".
/// 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.
unsigned CommentColumn; // Defaults to 40
/// CommentString - This indicates the comment character used by the
/// assembler.
const char *CommentString; // Defaults to "#"
/// LabelSuffix - This is appended to emitted labels.
const char *LabelSuffix; // Defaults to ":"
/// LabelSuffix - This is appended to emitted labels.
const char *DebugLabelSuffix; // Defaults to ":"
/// GlobalPrefix - If this is set to a non-empty string, it is prepended
/// onto all global symbols. This is often used for "_" or ".".
const char *GlobalPrefix; // Defaults to ""
/// PrivateGlobalPrefix - This prefix is used for globals like constant
/// pool entries that are completely private to the .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
/// AllowQuotesInName - This is true if the assembler allows for complex
/// symbol names to be surrounded in quotes. This defaults to false.
bool AllowQuotesInName;
/// AllowNameToStartWithDigit - This is true if the assembler allows symbol
/// names to start with a digit (e.g., "0x0021"). This defaults to false.
bool AllowNameToStartWithDigit;
/// AllowPeriodsInName - This is true if the assembler allows periods in
/// symbol names. This defaults to true.
bool AllowPeriodsInName;
/// AllowUTF8 - This is true if the assembler accepts UTF-8 input.
// FIXME: Make this a more general encoding setting?
bool AllowUTF8;
/// UseDataRegionDirectives - This is true if data region markers should
/// be printed as ".data_region/.end_data_region" directives. If false,
/// use "$d/$a" labels instead.
bool UseDataRegionDirectives;
//===--- Data Emission Directives -------------------------------------===//
/// ZeroDirective - this should be set to the directive used to get some
/// number of zero bytes emitted to the current section. Common cases are
/// "\t.zero\t" and "\t.space\t". If this is set to null, the
/// Data*bitsDirective's will be used to emit zero bytes.
const char *ZeroDirective; // Defaults to "\t.zero\t"
/// AsciiDirective - This directive allows emission of an ascii string with
/// the standard C escape characters embedded into it.
const char *AsciiDirective; // Defaults to "\t.ascii\t"
/// AscizDirective - If not null, this allows for special handling of
/// zero terminated strings on this target. This is commonly supported as
/// ".asciz". If a target doesn't support this, it can be set to null.
const char *AscizDirective; // Defaults to "\t.asciz\t"
/// DataDirectives - These directives are used to output some unit of
/// integer data to the current section. If a data directive is set to
/// null, smaller data directives will be used to emit the large sizes.
const char *Data8bitsDirective; // Defaults to "\t.byte\t"
const char *Data16bitsDirective; // Defaults to "\t.short\t"
const char *Data32bitsDirective; // Defaults to "\t.long\t"
const char *Data64bitsDirective; // Defaults to "\t.quad\t"
/// GPRel64Directive - if non-null, a directive that is used to emit a word
/// which should be relocated as a 64-bit GP-relative offset, e.g. .gpdword
/// on Mips.
const char *GPRel64Directive; // Defaults to NULL.
/// 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 {
assert(AS != 0 && "Don't know the directives for default addr space");
return 0;
}
/// SunStyleELFSectionSwitchSyntax - This is true if this target uses "Sun
/// Style" syntax for section switching ("#alloc,#write" etc) instead of the
/// normal ELF syntax (,"a,w") in .section directives.
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
/// 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
/// boundary.
///
const char *AlignDirective; // Defaults to "\t.align\t"
/// AlignmentIsInBytes - If this is true (the default) then the asmprinter
/// emits ".align N" directives, where N is the number of bytes to align to.
/// Otherwise, it emits ".align log2(N)", e.g. 3 to align to an 8 byte
/// boundary.
bool AlignmentIsInBytes; // Defaults to true
/// TextAlignFillValue - If non-zero, this is used to fill the executable
/// space created as the result of a alignment directive.
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
/// globals.
///
const char *ExternDirective; // Defaults to NULL.
/// HasSetDirective - True if the assembler supports the .set directive.
bool HasSetDirective; // Defaults to true.
/// HasAggressiveSymbolFolding - False if the assembler requires that we use
/// Lc = a - b
/// .long Lc
/// instead of
/// .long a - b
bool HasAggressiveSymbolFolding; // Defaults to true.
/// COMMDirectiveAlignmentIsInBytes - True is .comm's and .lcomms optional
/// alignment is to be specified in bytes instead of log2(n).
bool COMMDirectiveAlignmentIsInBytes; // Defaults to true;
/// LCOMMDirectiveAlignment - Describes if the .lcomm directive for the
/// target supports an alignment argument and how it is interpreted.
LCOMM::LCOMMType LCOMMDirectiveAlignmentType; // Defaults to NoAlignment.
/// HasDotTypeDotSizeDirective - True if the target has .type and .size
/// directives, this is true for most ELF targets.
bool HasDotTypeDotSizeDirective; // Defaults to true.
/// HasSingleParameterDotFile - True if the target has a single parameter
/// .file directive, this is true for ELF targets.
bool HasSingleParameterDotFile; // Defaults to true.
/// HasNoDeadStrip - True if this target supports the MachO .no_dead_strip
/// 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.
/// 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
//===--- Dwarf Emission Directives -----------------------------------===//
/// HasLEB128 - True if target asm supports leb128 directives.
bool HasLEB128; // Defaults to false.
/// SupportsDebugInformation - True if target supports emission of debugging
/// information.
bool SupportsDebugInformation; // Defaults to false.
/// SupportsExceptionHandling - True if target supports exception handling.
ExceptionHandling::ExceptionsType ExceptionsType; // Defaults to None
/// 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
/// DwarfUsesRelocationsAcrossSections - True if Dwarf2 output generally
/// uses relocations for references to other .debug_* sections.
bool DwarfUsesRelocationsAcrossSections;
/// DwarfRegNumForCFI - True if dwarf register numbers are printed
/// instead of symbolic register names in .cfi_* directives.
bool DwarfRegNumForCFI; // Defaults to false;
//===--- Prologue State ----------------------------------------------===//
std::vector<MachineMove> InitialFrameState;
public:
explicit MCAsmInfo();
virtual ~MCAsmInfo();
// FIXME: move these methods to DwarfPrinter when the JIT stops using them.
static unsigned getSLEB128Size(int Value);
static unsigned getULEB128Size(unsigned Value);
/// getPointerSize - Get the pointer size in bytes.
unsigned getPointerSize() const {
return PointerSize;
}
/// getCalleeSaveStackSlotSize - Get the callee-saved register stack slot
/// size in bytes.
unsigned getCalleeSaveStackSlotSize() const {
return CalleeSaveStackSlotSize;
}
/// 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 {
return AS == 0 ? Data8bitsDirective : getDataASDirective(8, AS);
}
const char *getData16bitsDirective(unsigned AS = 0) const {
return AS == 0 ? Data16bitsDirective : getDataASDirective(16, AS);
}
const char *getData32bitsDirective(unsigned AS = 0) const {
return AS == 0 ? Data32bitsDirective : getDataASDirective(32, AS);
}
const char *getData64bitsDirective(unsigned AS = 0) const {
return AS == 0 ? Data64bitsDirective : getDataASDirective(64, AS);
}
const char *getGPRel64Directive() const { return GPRel64Directive; }
const char *getGPRel32Directive() const { return GPRel32Directive; }
/// 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;
}
bool hasMicrosoftFastStdCallMangling() const {
return HasMicrosoftFastStdCallMangling;
}
// Accessors.
//
bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; }
bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; }
bool hasStaticCtorDtorReferenceInStaticMode() const {
return HasStaticCtorDtorReferenceInStaticMode;
}
bool getLinkerRequiresNonEmptyDwarfLines() const {
return LinkerRequiresNonEmptyDwarfLines;
}
unsigned getMaxInstLength() const {
return MaxInstLength;
}
const char *getPCSymbol() const {
return PCSymbol;
}
const char *getSeparatorString() const {
return SeparatorString;
}
unsigned getCommentColumn() const {
return CommentColumn;
}
const char *getCommentString() const {
return CommentString;
}
const char *getLabelSuffix() const {
return LabelSuffix;
}
const char *getDebugLabelSuffix() const {
return DebugLabelSuffix;
}
const char *getGlobalPrefix() const {
return GlobalPrefix;
}
const char *getPrivateGlobalPrefix() const {
return PrivateGlobalPrefix;
}
const char *getLinkerPrivateGlobalPrefix() const {
return LinkerPrivateGlobalPrefix;
}
const char *getInlineAsmStart() const {
return InlineAsmStart;
}
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;
}
bool doesAllowQuotesInName() const {
return AllowQuotesInName;
}
bool doesAllowNameToStartWithDigit() const {
return AllowNameToStartWithDigit;
}
bool doesAllowPeriodsInName() const {
return AllowPeriodsInName;
}
bool doesAllowUTF8() const {
return AllowUTF8;
}
bool doesSupportDataRegionDirectives() const {
return UseDataRegionDirectives;
}
const char *getZeroDirective() const {
return ZeroDirective;
}
const char *getAsciiDirective() const {
return AsciiDirective;
}
const char *getAscizDirective() const {
return AscizDirective;
}
const char *getAlignDirective() const {
return AlignDirective;
}
bool getAlignmentIsInBytes() const {
return AlignmentIsInBytes;
}
unsigned getTextAlignFillValue() const {
return TextAlignFillValue;
}
const char *getGlobalDirective() const {
return GlobalDirective;
}
const char *getExternDirective() const {
return ExternDirective;
}
bool hasSetDirective() const { return HasSetDirective; }
bool hasAggressiveSymbolFolding() const {
return HasAggressiveSymbolFolding;
}
bool getCOMMDirectiveAlignmentIsInBytes() const {
return COMMDirectiveAlignmentIsInBytes;
}
LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const {
return LCOMMDirectiveAlignmentType;
}
bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;}
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 doesSupportDebugInformation() const {
return SupportsDebugInformation;
}
bool doesSupportExceptionHandling() const {
return ExceptionsType != ExceptionHandling::None;
}
ExceptionHandling::ExceptionsType getExceptionHandlingType() const {
return ExceptionsType;
}
bool isExceptionHandlingDwarf() const {
return
(ExceptionsType == ExceptionHandling::DwarfCFI ||
ExceptionsType == ExceptionHandling::ARM ||
ExceptionsType == ExceptionHandling::Win64);
}
bool doesDwarfUseInlineInfoSection() const {
return DwarfUsesInlineInfoSection;
}
const char *getDwarfSectionOffsetDirective() const {
return DwarfSectionOffsetDirective;
}
bool doesDwarfUseRelocationsAcrossSections() const {
return DwarfUsesRelocationsAcrossSections;
}
bool useDwarfRegNumForCFI() const {
return DwarfRegNumForCFI;
}
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;
}
};
}
#endif

View File

@@ -0,0 +1,36 @@
//===-- MCAsmInfoCOFF.h - COFF asm properties -------------------*- 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_MCASMINFOCOFF_H
#define LLVM_MC_MCASMINFOCOFF_H
#include "llvm/MC/MCAsmInfo.h"
namespace llvm {
class MCAsmInfoCOFF : public MCAsmInfo {
virtual void anchor();
protected:
explicit MCAsmInfoCOFF();
};
class MCAsmInfoMicrosoft : public MCAsmInfoCOFF {
virtual void anchor();
protected:
explicit MCAsmInfoMicrosoft();
};
class MCAsmInfoGNUCOFF : public MCAsmInfoCOFF {
virtual void anchor();
protected:
explicit MCAsmInfoGNUCOFF();
};
}
#endif // LLVM_MC_MCASMINFOCOFF_H

View File

@@ -0,0 +1,29 @@
//===---- MCAsmInfoDarwin.h - Darwin asm properties -------------*- 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 target asm properties related what form asm statements
// should take in general on Darwin-based targets
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCASMINFODARWIN_H
#define LLVM_MC_MCASMINFODARWIN_H
#include "llvm/MC/MCAsmInfo.h"
namespace llvm {
class MCAsmInfoDarwin : public MCAsmInfo {
virtual void anchor();
public:
explicit MCAsmInfoDarwin();
};
}
#endif // LLVM_MC_MCASMINFODARWIN_H

View File

@@ -0,0 +1,112 @@
//===- MCAsmLayout.h - Assembly Layout Object -------------------*- 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_MCASMLAYOUT_H
#define LLVM_MC_MCASMLAYOUT_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
namespace llvm {
class MCAssembler;
class MCFragment;
class MCSectionData;
class MCSymbolData;
/// Encapsulates the layout of an assembly file at a particular point in time.
///
/// Assembly may require computing multiple layouts for a particular assembly
/// file as part of the relaxation process. This class encapsulates the layout
/// at a single point in time in such a way that it is always possible to
/// efficiently compute the exact address of any symbol in the assembly file,
/// even during the relaxation process.
class MCAsmLayout {
public:
typedef llvm::SmallVectorImpl<MCSectionData*>::const_iterator const_iterator;
typedef llvm::SmallVectorImpl<MCSectionData*>::iterator iterator;
private:
MCAssembler &Assembler;
/// List of sections in layout order.
llvm::SmallVector<MCSectionData*, 16> SectionOrder;
/// 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 valid.
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;
/// \brief Is the layout for this fragment valid?
bool isFragmentValid(const MCFragment *F) const;
/// \brief Compute the amount of padding required before this fragment to
/// obey bundling restrictions.
uint64_t computeBundlePadding(const MCFragment *F,
uint64_t FOffset, uint64_t FSize);
public:
MCAsmLayout(MCAssembler &_Assembler);
/// Get the assembler object this is a layout for.
MCAssembler &getAssembler() const { return Assembler; }
/// \brief Invalidate the fragments starting with F because it has been
/// resized. The fragment's size should have already been updated, but
/// its bundle padding will be recomputed.
void invalidateFragmentsFrom(MCFragment *F);
/// \brief Perform layout for a single fragment, assuming that the previous
/// fragment has already been laid out correctly, and the parent section has
/// been initialized.
void layoutFragment(MCFragment *Fragment);
/// @name Section Access (in layout order)
/// @{
llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() {
return SectionOrder;
}
const llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() const {
return SectionOrder;
}
/// @}
/// @name Fragment Layout Data
/// @{
/// \brief Get the offset of the given fragment inside its containing section.
uint64_t getFragmentOffset(const MCFragment *F) const;
/// @}
/// @name Utility Functions
/// @{
/// \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.
uint64_t getSectionAddressSize(const MCSectionData *SD) const;
/// \brief Get the data size of the given section, as emitted to the object
/// file. This may include additional padding, or be 0 for virtual sections.
uint64_t getSectionFileSize(const MCSectionData *SD) const;
/// \brief Get the offset of the given symbol, as computed in the current
/// layout.
uint64_t getSymbolOffset(const MCSymbolData *SD) const;
/// @}
};
} // end namespace llvm
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -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() const { return Type == TextAtom; }
bool isDataAtom() const { 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

View File

@@ -0,0 +1,43 @@
//===-- llvm/MC/MCCodeEmitter.h - Instruction Encoding ----------*- 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_MCCODEEMITTER_H
#define LLVM_MC_MCCODEEMITTER_H
#include "llvm/Support/Compiler.h"
namespace llvm {
class MCFixup;
class MCInst;
class raw_ostream;
template<typename T> class SmallVectorImpl;
/// MCCodeEmitter - Generic instruction encoding interface.
class MCCodeEmitter {
private:
MCCodeEmitter(const MCCodeEmitter &) LLVM_DELETED_FUNCTION;
void operator=(const MCCodeEmitter &) LLVM_DELETED_FUNCTION;
protected: // Can only create subclasses.
MCCodeEmitter();
public:
virtual ~MCCodeEmitter();
/// Lifetime management
virtual void reset() { }
/// EncodeInstruction - Encode the given \p Inst to bytes on the output
/// stream \p OS.
virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const = 0;
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,48 @@
//===-- 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: static, pic, etc.
///
Reloc::Model RelocationModel;
/// CMModel - Code model.
///
CodeModel::Model CMModel;
/// OptLevel - Optimization level.
///
CodeGenOpt::Level OptLevel;
public:
void InitMCCodeGenInfo(Reloc::Model RM = Reloc::Default,
CodeModel::Model CM = CodeModel::Default,
CodeGenOpt::Level OL = CodeGenOpt::Default);
Reloc::Model getRelocationModel() const { return RelocationModel; }
CodeModel::Model getCodeModel() const { return CMModel; }
CodeGenOpt::Level getOptLevel() const { return OptLevel; }
};
} // namespace llvm
#endif

View File

@@ -0,0 +1,490 @@
//===- MCContext.h - Machine Code Context -----------------------*- 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_MCCONTEXT_H
#define LLVM_MC_MCCONTEXT_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <vector> // FIXME: Shouldn't be needed.
namespace llvm {
class MCAsmInfo;
class MCExpr;
class MCSection;
class MCSymbol;
class MCLabel;
class MCDwarfFile;
class MCDwarfLoc;
class MCObjectFileInfo;
class MCRegisterInfo;
class MCLineSection;
class SMLoc;
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.
///
class MCContext {
MCContext(const MCContext&) LLVM_DELETED_FUNCTION;
MCContext &operator=(const MCContext&) LLVM_DELETED_FUNCTION;
public:
typedef StringMap<MCSymbol*, BumpPtrAllocator&> SymbolTable;
private:
/// The SourceMgr for this object, if any.
const SourceMgr *SrcMgr;
/// 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.
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.
unsigned NextUniqueID;
/// Instances of directional local labels.
DenseMap<unsigned, MCLabel *> Instances;
/// NextInstance() creates the next instance of the directional local label
/// for the LocalLabelVal and adds it to the map if needed.
unsigned NextInstance(int64_t LocalLabelVal);
/// 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 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;
/// The stream that gets written to for the .secure_log_unique directive.
raw_ostream *SecureLog;
/// Boolean toggled when .secure_log_unique / .secure_log_reset is seen to
/// catch errors if .secure_log_unique appears twice without
/// .secure_log_reset appearing between them.
bool SecureLogUsed;
/// The compilation directory to use for DW_AT_comp_dir.
std::string CompilationDir;
/// The main file name if passed in explicitly.
std::string MainFileName;
/// The dwarf file and directory tables from the dwarf .file directive.
/// We now emit a line table for each compile unit. To reduce the prologue
/// size of each line table, the files and directories used by each compile
/// unit are separated.
typedef std::map<unsigned, SmallVector<MCDwarfFile *, 4> > MCDwarfFilesMap;
MCDwarfFilesMap MCDwarfFilesCUMap;
std::map<unsigned, SmallVector<StringRef, 4> > MCDwarfDirsCUMap;
/// The current dwarf line information from the last dwarf .loc directive.
MCDwarfLoc CurrentDwarfLoc;
bool DwarfLocSeen;
/// Generate dwarf debugging info for assembly source files.
bool GenDwarfForAssembly;
/// The current dwarf file number when generate dwarf debugging info for
/// assembly source files.
unsigned GenDwarfFileNumber;
/// The default initial text section that we generate dwarf debugging line
/// info for when generating dwarf assembly source files.
const MCSection *GenDwarfSection;
/// Symbols created for the start and end of this section.
MCSymbol *GenDwarfSectionStartSym, *GenDwarfSectionEndSym;
/// The information gathered from labels that will have dwarf label
/// entries when generating dwarf assembly source files.
std::vector<const MCGenDwarfLabelEntry *> MCGenDwarfLabelEntries;
/// The string to embed in the debug information for the compile unit, if
/// non-empty.
StringRef DwarfDebugFlags;
/// The string to embed in as the dwarf AT_producer for the compile unit, if
/// non-empty.
StringRef DwarfDebugProducer;
/// 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;
/// The Compile Unit ID that we are currently processing.
unsigned DwarfCompileUnitID;
/// The line table start symbol for each Compile Unit.
DenseMap<unsigned, MCSymbol *> MCLineTableSymbols;
void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
/// Do automatic reset in destructor
bool AutoReset;
MCSymbol *CreateSymbol(StringRef Name);
public:
explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI,
const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0,
bool DoAutoReset = true);
~MCContext();
const SourceMgr *getSourceManager() const { return SrcMgr; }
const MCAsmInfo &getAsmInfo() const { return MAI; }
const MCRegisterInfo &getRegisterInfo() const { return MRI; }
const MCObjectFileInfo *getObjectFileInfo() const { return MOFI; }
void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; }
/// @name Module Lifetime Management
/// @{
/// reset - return object to right after construction state to prepare
/// to process a new module
void reset();
/// @}
/// @name Symbol Management
/// @{
/// CreateTempSymbol - Create and return a new assembler temporary symbol
/// with a unique but unspecified name.
MCSymbol *CreateTempSymbol();
/// getUniqueSymbolID() - Return a unique identifier for use in constructing
/// symbol names.
unsigned getUniqueSymbolID() { return NextUniqueID++; }
/// 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
/// symbol for numbered label (used for "1b" or 1f" references).
MCSymbol *GetDirectionalLocalSymbol(int64_t LocalLabelVal, int bORf);
/// GetOrCreateSymbol - Lookup the symbol inside with the specified
/// @p Name. If it exists, return it. If not, create a forward
/// reference and return it.
///
/// @param Name - The symbol name, which must be unique across all symbols.
MCSymbol *GetOrCreateSymbol(StringRef Name);
MCSymbol *GetOrCreateSymbol(const Twine &Name);
/// LookupSymbol - Get the symbol for \p Name, or null.
MCSymbol *LookupSymbol(StringRef Name) const;
MCSymbol *LookupSymbol(const Twine &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 Management
/// @{
/// getMachOSection - Return the MCSection for the specified mach-o section.
/// This requires the operands to be valid.
const MCSectionMachO *getMachOSection(StringRef Segment,
StringRef Section,
unsigned TypeAndAttributes,
unsigned Reserved2,
SectionKind K);
const MCSectionMachO *getMachOSection(StringRef Segment,
StringRef Section,
unsigned TypeAndAttributes,
SectionKind K) {
return getMachOSection(Segment, Section, TypeAndAttributes, 0, K);
}
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);
const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
SectionKind Kind) {
return getCOFFSection (Section, Characteristics, 0, Kind);
}
/// @}
/// @name Dwarf Management
/// @{
/// \brief Get the compilation directory for DW_AT_comp_dir
/// This can be overridden by clients which want to control the reported
/// compilation directory and have it be something other than the current
/// working directory.
const std::string &getCompilationDir() const { return CompilationDir; }
/// \brief Set the compilation directory for DW_AT_comp_dir
/// Override the default (CWD) compilation directory.
void setCompilationDir(StringRef S) { CompilationDir = S.str(); }
/// \brief Get the main file name for use in error messages and debug
/// info. This can be set to ensure we've got the correct file name
/// after preprocessing or for -save-temps.
const std::string &getMainFileName() const { return MainFileName; }
/// \brief Set the main file name and override the default.
void setMainFileName(StringRef S) { MainFileName = S.str(); }
/// GetDwarfFile - creates an entry in the dwarf file and directory tables.
unsigned GetDwarfFile(StringRef Directory, StringRef FileName,
unsigned FileNumber, unsigned CUID);
bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0);
bool hasDwarfFiles() const {
// Traverse MCDwarfFilesCUMap and check whether each entry is empty.
MCDwarfFilesMap::const_iterator MapB, MapE;
for (MapB = MCDwarfFilesCUMap.begin(), MapE = MCDwarfFilesCUMap.end();
MapB != MapE; MapB++)
if (!MapB->second.empty())
return true;
return false;
}
const SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles(unsigned CUID = 0) {
return MCDwarfFilesCUMap[CUID];
}
const SmallVectorImpl<StringRef> &getMCDwarfDirs(unsigned CUID = 0) {
return MCDwarfDirsCUMap[CUID];
}
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);
}
unsigned getDwarfCompileUnitID() {
return DwarfCompileUnitID;
}
void setDwarfCompileUnitID(unsigned CUIndex) {
DwarfCompileUnitID = CUIndex;
}
const DenseMap<unsigned, MCSymbol *> &getMCLineTableSymbols() const {
return MCLineTableSymbols;
}
MCSymbol *getMCLineTableSymbol(unsigned ID) const {
DenseMap<unsigned, MCSymbol *>::const_iterator CIter =
MCLineTableSymbols.find(ID);
if (CIter == MCLineTableSymbols.end())
return NULL;
return CIter->second;
}
void setMCLineTableSymbol(MCSymbol *Sym, unsigned ID) {
MCLineTableSymbols[ID] = Sym;
}
/// 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; }
bool getGenDwarfForAssembly() { return GenDwarfForAssembly; }
void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; }
unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; }
unsigned nextGenDwarfFileNumber() { return ++GenDwarfFileNumber; }
const MCSection *getGenDwarfSection() { return GenDwarfSection; }
void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; }
MCSymbol *getGenDwarfSectionStartSym() { return GenDwarfSectionStartSym; }
void setGenDwarfSectionStartSym(MCSymbol *Sym) {
GenDwarfSectionStartSym = Sym;
}
MCSymbol *getGenDwarfSectionEndSym() { return GenDwarfSectionEndSym; }
void setGenDwarfSectionEndSym(MCSymbol *Sym) {
GenDwarfSectionEndSym = Sym;
}
const std::vector<const MCGenDwarfLabelEntry *>
&getMCGenDwarfLabelEntries() const {
return MCGenDwarfLabelEntries;
}
void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry *E) {
MCGenDwarfLabelEntries.push_back(E);
}
void setDwarfDebugFlags(StringRef S) { DwarfDebugFlags = S; }
StringRef getDwarfDebugFlags() { return DwarfDebugFlags; }
void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; }
StringRef getDwarfDebugProducer() { return DwarfDebugProducer; }
/// @}
char *getSecureLogFile() { return SecureLogFile; }
raw_ostream *getSecureLog() { return SecureLog; }
bool getSecureLogUsed() { return SecureLogUsed; }
void setSecureLog(raw_ostream *Value) {
SecureLog = Value;
}
void setSecureLogUsed(bool Value) {
SecureLogUsed = Value;
}
void *Allocate(unsigned Size, unsigned Align = 8) {
return Allocator.Allocate(Size, Align);
}
void Deallocate(void *Ptr) {
}
// Unrecoverable error has occured. Display the best diagnostic we can
// and bail via exit(1). For now, most MC backend errors are unrecoverable.
// FIXME: We should really do something about that.
LLVM_ATTRIBUTE_NORETURN void FatalError(SMLoc L, const Twine &Msg);
};
} // end namespace llvm
// operator new and delete aren't allowed inside namespaces.
// The throw specifications are mandated by the standard.
/// @brief Placement new for using the MCContext's allocator.
///
/// This placement form of operator new uses the MCContext's allocator for
/// obtaining memory. It is a non-throwing new, which means that it returns
/// null on error. (If that is what the allocator does. The current does, so if
/// this ever changes, this operator will have to be changed, too.)
/// Usage looks like this (assuming there's an MCContext 'Context' in scope):
/// @code
/// // Default alignment (16)
/// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments);
/// // Specific alignment
/// IntegerLiteral *Ex2 = new (Context, 8) IntegerLiteral(arguments);
/// @endcode
/// Please note that you cannot use delete on the pointer; it must be
/// deallocated using an explicit destructor call followed by
/// @c Context.Deallocate(Ptr).
///
/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
/// @param C The MCContext that provides the allocator.
/// @param Alignment The alignment of the allocated memory (if the underlying
/// allocator supports it).
/// @return The allocated memory. Could be NULL.
inline void *operator new(size_t Bytes, llvm::MCContext &C,
size_t Alignment = 16) throw () {
return C.Allocate(Bytes, Alignment);
}
/// @brief Placement delete companion to the new above.
///
/// This operator is just a companion to the new above. There is no way of
/// invoking it directly; see the new operator for more details. This operator
/// is called implicitly by the compiler if a placement new expression using
/// the MCContext throws in the object constructor.
inline void operator delete(void *Ptr, llvm::MCContext &C, size_t)
throw () {
C.Deallocate(Ptr);
}
/// This placement form of operator new[] uses the MCContext's allocator for
/// obtaining memory. It is a non-throwing new[], which means that it returns
/// null on error.
/// Usage looks like this (assuming there's an MCContext 'Context' in scope):
/// @code
/// // Default alignment (16)
/// char *data = new (Context) char[10];
/// // Specific alignment
/// char *data = new (Context, 8) char[10];
/// @endcode
/// Please note that you cannot use delete on the pointer; it must be
/// deallocated using an explicit destructor call followed by
/// @c Context.Deallocate(Ptr).
///
/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
/// @param C The MCContext that provides the allocator.
/// @param Alignment The alignment of the allocated memory (if the underlying
/// allocator supports it).
/// @return The allocated memory. Could be NULL.
inline void *operator new[](size_t Bytes, llvm::MCContext& C,
size_t Alignment = 16) throw () {
return C.Allocate(Bytes, Alignment);
}
/// @brief Placement delete[] companion to the new[] above.
///
/// This operator is just a companion to the new[] above. There is no way of
/// invoking it directly; see the new[] operator for more details. This operator
/// is called implicitly by the compiler if a placement new[] expression using
/// the MCContext throws in the object constructor.
inline void operator delete[](void *Ptr, llvm::MCContext &C) throw () {
C.Deallocate(Ptr);
}
#endif

View File

@@ -0,0 +1,65 @@
//===- MCDirectives.h - Enums for directives on various targets -*- 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 various enums that represent target-specific directives.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCDIRECTIVES_H
#define LLVM_MC_MCDIRECTIVES_H
namespace llvm {
enum MCSymbolAttr {
MCSA_Invalid = 0, ///< Not a valid directive.
// Various directives in alphabetical order.
MCSA_ELF_TypeFunction, ///< .type _foo, STT_FUNC # aka @function
MCSA_ELF_TypeIndFunction, ///< .type _foo, STT_GNU_IFUNC
MCSA_ELF_TypeObject, ///< .type _foo, STT_OBJECT # aka @object
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)
MCSA_Internal, ///< .internal (ELF)
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)
MCSA_Weak, ///< .weak
MCSA_WeakDefinition, ///< .weak_definition (MachO)
MCSA_WeakReference, ///< .weak_reference (MachO)
MCSA_WeakDefAutoPrivate ///< .weak_def_can_be_hidden (MachO)
};
enum MCAssemblerFlag {
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)
};
enum MCDataRegionType {
MCDR_DataRegion, ///< .data_region
MCDR_DataRegionJT8, ///< .data_region jt8
MCDR_DataRegionJT16, ///< .data_region jt16
MCDR_DataRegionJT32, ///< .data_region jt32
MCDR_DataRegionEnd ///< .end_data_region
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,126 @@
//===-- llvm/MC/MCDisassembler.h - Disassembler interface -------*- 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_MCDISASSEMBLER_H
#define LLVM_MC_MCDISASSEMBLER_H
#include "llvm-c/Disassembler.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
class MCInst;
class MCSubtargetInfo;
class MemoryObject;
class raw_ostream;
class MCContext;
/// MCDisassembler - Superclass for all disassemblers. Consumes a memory region
/// 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(const MCSubtargetInfo &STI) : GetOpInfo(0), SymbolLookUp(0),
DisInfo(0), Ctx(0),
STI(STI), CommentStream(0) {}
virtual ~MCDisassembler();
/// getInstruction - Returns the disassembly of a single instruction.
///
/// @param instr - An MCInst to populate with the contents of the
/// instruction.
/// @param size - A value to populate with the size of the instruction, or
/// the number of bytes consumed while attempting to decode
/// an invalid instruction.
/// @param region - The memory object to use as a source for machine code.
/// @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.
/// @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 &region,
uint64_t address,
raw_ostream &vStream,
raw_ostream &cStream) const = 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
#endif

View File

@@ -0,0 +1,425 @@
//===- MCDwarf.h - Machine Code Dwarf 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 the declaration of the MCDwarfFile to support the dwarf
// .file directive and the .loc directive.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCDWARF_H
#define LLVM_MC_MCDWARF_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <vector>
namespace llvm {
class MCContext;
class MCObjectWriter;
class MCSection;
class MCStreamer;
class MCSymbol;
class SourceMgr;
class SMLoc;
/// MCDwarfFile - Instances of this class represent the name of the dwarf
/// .file directive and its associated dwarf file number in the MC file,
/// and MCDwarfFile's are created and unique'd by the MCContext class where
/// the file number for each is its index into the vector of DwarfFiles (note
/// index 0 is not used and not a valid dwarf file number).
class MCDwarfFile {
// Name - the base name of the file without its directory path.
// The StringRef references memory allocated in the MCContext.
StringRef Name;
// DirIndex - the index into the list of directory names for this file name.
unsigned DirIndex;
private: // MCContext creates and uniques these.
friend class MCContext;
MCDwarfFile(StringRef name, unsigned dirIndex)
: Name(name), DirIndex(dirIndex) {}
MCDwarfFile(const MCDwarfFile&) LLVM_DELETED_FUNCTION;
void operator=(const MCDwarfFile&) LLVM_DELETED_FUNCTION;
public:
/// getName - Get the base name of this MCDwarfFile.
StringRef getName() const { return Name; }
/// getDirIndex - Get the dirIndex of this MCDwarfFile.
unsigned getDirIndex() const { return DirIndex; }
/// print - Print the value to the stream \p OS.
void print(raw_ostream &OS) const;
/// dump - Print the value to stderr.
void dump() const;
};
inline raw_ostream &operator<<(raw_ostream &OS, const MCDwarfFile &DwarfFile){
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&) LLVM_DELETED_FUNCTION;
void operator=(const MCLineSection&) LLVM_DELETED_FUNCTION;
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, unsigned CUID) {
MCLineDivisions[CUID].push_back(LineEntry);
}
typedef std::vector<MCLineEntry> MCLineEntryCollection;
typedef MCLineEntryCollection::iterator iterator;
typedef MCLineEntryCollection::const_iterator const_iterator;
typedef std::map<unsigned, MCLineEntryCollection> MCLineDivisionMap;
private:
// A collection of MCLineEntry for each Compile Unit ID.
MCLineDivisionMap MCLineDivisions;
public:
// Returns whether MCLineSection contains entries for a given Compile
// Unit ID.
bool containEntriesForID(unsigned CUID) const {
return MCLineDivisions.count(CUID);
}
// Returns the collection of MCLineEntry for a given Compile Unit ID.
const MCLineEntryCollection &getMCLineEntries(unsigned CUID) const {
MCLineDivisionMap::const_iterator CIter = MCLineDivisions.find(CUID);
assert(CIter != MCLineDivisions.end());
return CIter->second;
}
};
class MCDwarfFileTable {
public:
//
// This emits the Dwarf file and the line tables for all Compile Units.
//
static const MCSymbol *Emit(MCStreamer *MCOS);
//
// This emits the Dwarf file and the line tables for a given Compile Unit.
//
static const MCSymbol *EmitCU(MCStreamer *MCOS, unsigned ID);
};
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 MCGenDwarfInfo {
public:
//
// When generating dwarf for assembly source files this emits the Dwarf
// sections.
//
static void Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol);
};
// When generating dwarf for assembly source files this is the info that is
// needed to be gathered for each symbol that will have a dwarf label.
class MCGenDwarfLabelEntry {
private:
// Name of the symbol without a leading underbar, if any.
StringRef Name;
// The dwarf file number this symbol is in.
unsigned FileNumber;
// The line number this symbol is at.
unsigned LineNumber;
// The low_pc for the dwarf label is taken from this symbol.
MCSymbol *Label;
public:
MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber,
unsigned lineNumber, MCSymbol *label) :
Name(name), FileNumber(fileNumber), LineNumber(lineNumber), Label(label){}
StringRef getName() const { return Name; }
unsigned getFileNumber() const { return FileNumber; }
unsigned getLineNumber() const { return LineNumber; }
MCSymbol *getLabel() const { return Label; }
// This is called when label is created when we are generating dwarf for
// assembly source files.
static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr,
SMLoc &Loc);
};
class MCCFIInstruction {
public:
enum OpType { OpSameValue, OpRememberState, OpRestoreState, OpOffset,
OpDefCfaRegister, OpDefCfaOffset, OpDefCfa, OpRelOffset,
OpAdjustCfaOffset, OpEscape, OpRestore, OpUndefined,
OpRegister };
private:
OpType Operation;
MCSymbol *Label;
unsigned Register;
union {
int Offset;
unsigned Register2;
};
std::vector<char> Values;
MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V) :
Operation(Op), Label(L), Register(R), Offset(O),
Values(V.begin(), V.end()) {
assert(Op != OpRegister);
}
MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2) :
Operation(Op), Label(L), Register(R1), Register2(R2) {
assert(Op == OpRegister);
}
public:
static MCCFIInstruction
createOffset(MCSymbol *L, unsigned Register, int Offset) {
return MCCFIInstruction(OpOffset, L, Register, Offset, "");
}
static MCCFIInstruction
createDefCfaRegister(MCSymbol *L, unsigned Register) {
return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, "");
}
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
}
static MCCFIInstruction
createDefCfa(MCSymbol *L, unsigned Register, int Offset) {
return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
}
static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) {
return MCCFIInstruction(OpUndefined, L, Register, 0, "");
}
static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) {
return MCCFIInstruction(OpRestore, L, Register, 0, "");
}
static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) {
return MCCFIInstruction(OpSameValue, L, Register, 0, "");
}
static MCCFIInstruction createRestoreState(MCSymbol *L) {
return MCCFIInstruction(OpRestoreState, L, 0, 0, "");
}
static MCCFIInstruction createRememberState(MCSymbol *L) {
return MCCFIInstruction(OpRememberState, L, 0, 0, "");
}
static MCCFIInstruction
createRelOffset(MCSymbol *L, unsigned Register, int Offset) {
return MCCFIInstruction(OpRelOffset, L, Register, Offset, "");
}
static MCCFIInstruction
createAdjustCfaOffset(MCSymbol *L, int Adjustment) {
return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");
}
static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) {
return MCCFIInstruction(OpEscape, L, 0, 0, Vals);
}
static MCCFIInstruction
createRegister(MCSymbol *L, unsigned Register1, unsigned Register2) {
return MCCFIInstruction(OpRegister, L, Register1, Register2);
}
OpType getOperation() const { return Operation; }
MCSymbol *getLabel() const { return Label; }
unsigned getRegister() const {
assert(Operation == OpDefCfa || Operation == OpOffset ||
Operation == OpRestore || Operation == OpUndefined ||
Operation == OpSameValue || Operation == OpDefCfaRegister ||
Operation == OpRelOffset || Operation == OpRegister);
return Register;
}
unsigned getRegister2() const {
assert(Operation == OpRegister);
return Register2;
}
int getOffset() const {
assert(Operation == OpDefCfa || Operation == OpOffset ||
Operation == OpRelOffset || Operation == OpDefCfaOffset ||
Operation == OpAdjustCfaOffset);
return Offset;
}
const StringRef getValues() const {
assert(Operation == OpEscape);
return StringRef(&Values[0], Values.size());
}
};
struct MCDwarfFrameInfo {
MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0),
Function(0), Instructions(), PersonalityEncoding(),
LsdaEncoding(0), CompactUnwindEncoding(0),
IsSignalFrame(false) {}
MCSymbol *Begin;
MCSymbol *End;
const MCSymbol *Personality;
const MCSymbol *Lsda;
const MCSymbol *Function;
std::vector<MCCFIInstruction> Instructions;
unsigned PersonalityEncoding;
unsigned LsdaEncoding;
uint32_t CompactUnwindEncoding;
bool IsSignalFrame;
};
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

View File

@@ -0,0 +1,37 @@
//===- lib/MC/MCELF.h - ELF MC --------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains some support functions used by the ELF Streamer and
// ObjectWriter.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCELF_H
#define LLVM_MC_MCELF_H
#include "llvm/MC/MCExpr.h"
namespace llvm {
class MCSymbolData;
class MCELF {
public:
static void SetBinding(MCSymbolData &SD, unsigned Binding);
static unsigned GetBinding(const MCSymbolData &SD);
static void SetType(MCSymbolData &SD, unsigned Type);
static unsigned GetType(const MCSymbolData &SD);
static void SetVisibility(MCSymbolData &SD, unsigned Visibility);
static unsigned GetVisibility(MCSymbolData &SD);
static void setOther(MCSymbolData &SD, unsigned Other);
static unsigned getOther(MCSymbolData &SD);
};
}
#endif

View File

@@ -0,0 +1,154 @@
//===-- 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/ADT/Triple.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ELF.h"
#include <vector>
namespace llvm {
class MCAssembler;
class MCFixup;
class MCFragment;
class MCObjectWriter;
class MCSymbol;
class MCValue;
/// @name Relocation Data
/// @{
struct ELFRelocationEntry {
// Make these big enough for both 32-bit and 64-bit
uint64_t r_offset;
int Index;
unsigned Type;
const MCSymbol *Symbol;
uint64_t r_addend;
const MCFixup *Fixup;
ELFRelocationEntry()
: r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0), Fixup(0) {}
ELFRelocationEntry(uint64_t RelocOffset, int Idx, unsigned RelType,
const MCSymbol *Sym, uint64_t Addend, const MCFixup &Fixup)
: r_offset(RelocOffset), Index(Idx), Type(RelType), Symbol(Sym),
r_addend(Addend), Fixup(&Fixup) {}
// Support lexicographic sorting.
bool operator<(const ELFRelocationEntry &RE) const {
return RE.r_offset < r_offset;
}
};
class MCELFObjectTargetWriter {
const uint8_t OSABI;
const uint16_t EMachine;
const unsigned HasRelocationAddend : 1;
const unsigned Is64Bit : 1;
const unsigned IsN64 : 1;
protected:
MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_,
uint16_t EMachine_, bool HasRelocationAddend,
bool IsN64=false);
public:
static uint8_t getOSABI(Triple::OSType OSType) {
switch (OSType) {
case Triple::FreeBSD:
return ELF::ELFOSABI_FREEBSD;
case Triple::Linux:
return ELF::ELFOSABI_LINUX;
default:
return ELF::ELFOSABI_NONE;
}
}
virtual ~MCELFObjectTargetWriter() {}
virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel, bool IsRelocWithSymbol,
int64_t Addend) const = 0;
virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
const MCValue &Target,
const MCFragment &F,
const MCFixup &Fixup,
bool IsPCRel) const;
virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel) const;
virtual void adjustFixupOffset(const MCFixup &Fixup,
uint64_t &RelocOffset);
virtual void sortRelocs(const MCAssembler &Asm,
std::vector<ELFRelocationEntry> &Relocs);
/// @name Accessors
/// @{
uint8_t getOSABI() const { return OSABI; }
uint16_t getEMachine() const { return EMachine; }
bool hasRelocationAddend() const { return HasRelocationAddend; }
bool is64Bit() const { return Is64Bit; }
bool isN64() const { return IsN64; }
/// @}
// Instead of changing everyone's API we pack the N64 Type fields
// into the existing 32 bit data unsigned.
#define R_TYPE_SHIFT 0
#define R_TYPE_MASK 0xffffff00
#define R_TYPE2_SHIFT 8
#define R_TYPE2_MASK 0xffff00ff
#define R_TYPE3_SHIFT 16
#define R_TYPE3_MASK 0xff00ffff
#define R_SSYM_SHIFT 24
#define R_SSYM_MASK 0x00ffffff
// N64 relocation type accessors
unsigned getRType(uint32_t Type) const {
return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff);
}
unsigned getRType2(uint32_t Type) const {
return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff);
}
unsigned getRType3(uint32_t Type) const {
return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff);
}
unsigned getRSsym(uint32_t Type) const {
return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff);
}
// N64 relocation type setting
unsigned setRType(unsigned Value, unsigned Type) const {
return ((Type & R_TYPE_MASK) | ((Value & 0xff) << R_TYPE_SHIFT));
}
unsigned setRType2(unsigned Value, unsigned Type) const {
return (Type & R_TYPE2_MASK) | ((Value & 0xff) << R_TYPE2_SHIFT);
}
unsigned setRType3(unsigned Value, unsigned Type) const {
return (Type & R_TYPE3_MASK) | ((Value & 0xff) << R_TYPE3_SHIFT);
}
unsigned setRSsym(unsigned Value, unsigned Type) const {
return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT);
}
};
/// \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

View File

@@ -0,0 +1,126 @@
//===- MCELFStreamer.h - MCStreamer ELF Object File Interface ---*- 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_MCELFSTREAMER_H
#define LLVM_MC_MCELFSTREAMER_H
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/DataTypes.h"
#include <vector>
namespace llvm {
class MCAsmBackend;
class MCAssembler;
class MCCodeEmitter;
class MCExpr;
class MCInst;
class MCSymbol;
class MCSymbolData;
class raw_ostream;
class MCELFStreamer : public MCObjectStreamer {
protected:
MCELFStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *Emitter)
: MCObjectStreamer(Kind, Context, TAB, OS, Emitter) {}
public:
MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *Emitter)
: MCObjectStreamer(SK_ELFStreamer, Context, TAB, OS, Emitter) {}
MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *Emitter, MCAssembler *Assembler)
: MCObjectStreamer(SK_ELFStreamer, Context, TAB, OS, Emitter,
Assembler) {}
virtual ~MCELFStreamer();
/// @name MCStreamer Interface
/// @{
virtual void InitSections();
virtual void InitToTextSection();
virtual void ChangeSection(const MCSection *Section,
const MCExpr *Subsection);
virtual void EmitLabel(MCSymbol *Symbol);
virtual void EmitDebugLabel(MCSymbol *Symbol);
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
virtual void EmitThumbFunc(MCSymbol *Func);
virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment);
virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
virtual void EmitCOFFSymbolStorageClass(int StorageClass);
virtual void EmitCOFFSymbolType(int Type);
virtual void EndCOFFSymbolDef();
virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol);
virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment);
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
uint64_t Size = 0, unsigned ByteAlignment = 0);
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment = 0);
virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
unsigned AddrSpace);
virtual void EmitFileDirective(StringRef Filename);
virtual void EmitTCEntry(const MCSymbol &S);
virtual void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned);
virtual void FinishImpl();
/// @}
static bool classof(const MCStreamer *S) {
return S->getKind() == SK_ELFStreamer || S->getKind() == SK_ARMELFStreamer;
}
private:
virtual void EmitInstToFragment(const MCInst &Inst);
virtual void EmitInstToData(const MCInst &Inst);
virtual void EmitBundleAlignMode(unsigned AlignPow2);
virtual void EmitBundleLock(bool AlignToEnd);
virtual void EmitBundleUnlock();
void fixSymbolsInTLSFixups(const MCExpr *expr);
struct LocalCommon {
MCSymbolData *SD;
uint64_t Size;
unsigned ByteAlignment;
};
std::vector<LocalCommon> LocalCommons;
SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
void SetSection(StringRef Section, unsigned Type, unsigned Flags,
SectionKind Kind);
void SetSectionData();
void SetSectionText();
void SetSectionBss();
};
} // end namespace llvm
#endif

View File

@@ -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

View File

@@ -0,0 +1,486 @@
//===- MCExpr.h - Assembly Level Expressions --------------------*- 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_MCEXPR_H
#define LLVM_MC_MCEXPR_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
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.
class MCExpr {
public:
enum ExprKind {
Binary, ///< Binary expressions.
Constant, ///< Constant expressions.
SymbolRef, ///< References to labels and assigned expressions.
Unary, ///< Unary expressions.
Target ///< Target specific expression.
};
private:
ExprKind Kind;
MCExpr(const MCExpr&) LLVM_DELETED_FUNCTION;
void operator=(const MCExpr&) LLVM_DELETED_FUNCTION;
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
/// @{
ExprKind getKind() const { return Kind; }
/// @}
/// @name Utility Methods
/// @{
void print(raw_ostream &OS) const;
void dump() const;
/// @}
/// @name Expression Evaluation
/// @{
/// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value.
///
/// @param Res - The absolute value, if evaluation succeeds.
/// @param Layout - The assembler layout object to use for evaluating symbol
/// values. If not given, then only non-symbolic expressions will be
/// evaluated.
/// @result - True on success.
bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout,
const SectionAddrMap &Addrs) 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;
/// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable
/// value, i.e. an expression of the fixed form (a - b + constant).
///
/// @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) 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;
/// @}
};
inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
E.print(OS);
return OS;
}
//// MCConstantExpr - Represent a constant integer expression.
class MCConstantExpr : public MCExpr {
int64_t Value;
explicit MCConstantExpr(int64_t _Value)
: MCExpr(MCExpr::Constant), Value(_Value) {}
public:
/// @name Construction
/// @{
static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx);
/// @}
/// @name Accessors
/// @{
int64_t getValue() const { return Value; }
/// @}
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Constant;
}
};
/// MCSymbolRefExpr - Represent a reference to a symbol from inside an
/// expression.
///
/// A symbol reference in an expression may be a use of a label, a use of an
/// assembler variable (defined constant), or constitute an implicit definition
/// of the symbol as external.
class MCSymbolRefExpr : public MCExpr {
public:
enum VariantKind {
VK_None,
VK_Invalid,
VK_GOT,
VK_GOTOFF,
VK_GOTPCREL,
VK_GOTTPOFF,
VK_INDNTPOFF,
VK_NTPOFF,
VK_GOTNTPOFF,
VK_PLT,
VK_TLSGD,
VK_TLSLD,
VK_TLSLDM,
VK_TPOFF,
VK_DTPOFF,
VK_TLVP, // Mach-O thread local variable relocation
VK_SECREL,
// FIXME: We'd really like to use the generic Kinds listed above for these.
VK_ARM_NONE,
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_ARM_TARGET1,
VK_ARM_TARGET2,
VK_ARM_PREL31,
VK_PPC_TOC, // TOC base
VK_PPC_TOC_ENTRY, // TOC entry
VK_PPC_DARWIN_HA16, // ha16(symbol)
VK_PPC_DARWIN_LO16, // lo16(symbol)
VK_PPC_GAS_HA16, // symbol@ha
VK_PPC_GAS_LO16, // symbol@l
VK_PPC_TPREL16_HA, // symbol@tprel@ha
VK_PPC_TPREL16_LO, // symbol@tprel@l
VK_PPC_DTPREL16_HA, // symbol@dtprel@ha
VK_PPC_DTPREL16_LO, // symbol@dtprel@l
VK_PPC_TOC16_HA, // symbol@toc@ha
VK_PPC_TOC16_LO, // symbol@toc@l
VK_PPC_GOT_TPREL16_HA, // symbol@got@tprel@ha
VK_PPC_GOT_TPREL16_LO, // symbol@got@tprel@l
VK_PPC_TLS, // symbol@tls
VK_PPC_GOT_TLSGD16_HA, // symbol@got@tlsgd@ha
VK_PPC_GOT_TLSGD16_LO, // symbol@got@tlsgd@l
VK_PPC_TLSGD, // symbol@tlsgd
VK_PPC_GOT_TLSLD16_HA, // symbol@got@tlsld@ha
VK_PPC_GOT_TLSLD16_LO, // symbol@got@tlsld@l
VK_PPC_TLSLD, // symbol@tlsld
VK_Mips_GPREL,
VK_Mips_GOT_CALL,
VK_Mips_GOT16,
VK_Mips_GOT,
VK_Mips_ABS_HI,
VK_Mips_ABS_LO,
VK_Mips_TLSGD,
VK_Mips_TLSLDM,
VK_Mips_DTPREL_HI,
VK_Mips_DTPREL_LO,
VK_Mips_GOTTPREL,
VK_Mips_TPREL_HI,
VK_Mips_TPREL_LO,
VK_Mips_GPOFF_HI,
VK_Mips_GPOFF_LO,
VK_Mips_GOT_DISP,
VK_Mips_GOT_PAGE,
VK_Mips_GOT_OFST,
VK_Mips_HIGHER,
VK_Mips_HIGHEST,
VK_Mips_GOT_HI16,
VK_Mips_GOT_LO16,
VK_Mips_CALL_HI16,
VK_Mips_CALL_LO16,
VK_COFF_IMGREL32 // symbol@imgrel (image-relative)
};
private:
/// The symbol being referenced.
const MCSymbol *Symbol;
/// The symbol reference modifier.
const VariantKind Kind;
explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind)
: MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) {
assert(Symbol);
}
public:
/// @name Construction
/// @{
static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) {
return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx);
}
static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind,
MCContext &Ctx);
static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind,
MCContext &Ctx);
/// @}
/// @name Accessors
/// @{
const MCSymbol &getSymbol() const { return *Symbol; }
VariantKind getKind() const { return Kind; }
/// @}
/// @name Static Utility Functions
/// @{
static StringRef getVariantKindName(VariantKind Kind);
static VariantKind getVariantKindForName(StringRef Name);
/// @}
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::SymbolRef;
}
};
/// MCUnaryExpr - Unary assembler expressions.
class MCUnaryExpr : public MCExpr {
public:
enum Opcode {
LNot, ///< Logical negation.
Minus, ///< Unary minus.
Not, ///< Bitwise negation.
Plus ///< Unary plus.
};
private:
Opcode Op;
const MCExpr *Expr;
MCUnaryExpr(Opcode _Op, const MCExpr *_Expr)
: MCExpr(MCExpr::Unary), Op(_Op), Expr(_Expr) {}
public:
/// @name Construction
/// @{
static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr,
MCContext &Ctx);
static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) {
return Create(LNot, Expr, Ctx);
}
static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) {
return Create(Minus, Expr, Ctx);
}
static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) {
return Create(Not, Expr, Ctx);
}
static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) {
return Create(Plus, Expr, Ctx);
}
/// @}
/// @name Accessors
/// @{
/// getOpcode - Get the kind of this unary expression.
Opcode getOpcode() const { return Op; }
/// getSubExpr - Get the child of this unary expression.
const MCExpr *getSubExpr() const { return Expr; }
/// @}
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Unary;
}
};
/// MCBinaryExpr - Binary assembler expressions.
class MCBinaryExpr : public MCExpr {
public:
enum Opcode {
Add, ///< Addition.
And, ///< Bitwise and.
Div, ///< Signed division.
EQ, ///< Equality comparison.
GT, ///< Signed greater than comparison (result is either 0 or some
///< target-specific non-zero value)
GTE, ///< Signed greater than or equal comparison (result is either 0 or
///< some target-specific non-zero value).
LAnd, ///< Logical and.
LOr, ///< Logical or.
LT, ///< Signed less than comparison (result is either 0 or
///< some target-specific non-zero value).
LTE, ///< Signed less than or equal comparison (result is either 0 or
///< some target-specific non-zero value).
Mod, ///< Signed remainder.
Mul, ///< Multiplication.
NE, ///< Inequality comparison.
Or, ///< Bitwise or.
Shl, ///< Shift left.
Shr, ///< Shift right (arithmetic or logical, depending on target)
Sub, ///< Subtraction.
Xor ///< Bitwise exclusive or.
};
private:
Opcode Op;
const MCExpr *LHS, *RHS;
MCBinaryExpr(Opcode _Op, const MCExpr *_LHS, const MCExpr *_RHS)
: MCExpr(MCExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {}
public:
/// @name Construction
/// @{
static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS,
const MCExpr *RHS, MCContext &Ctx);
static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(Add, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(And, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(Div, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(EQ, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(GT, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(GTE, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(LAnd, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(LOr, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(LT, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(LTE, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(Mod, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(Mul, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(NE, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(Or, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(Shl, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateShr(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(Shr, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(Sub, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
return Create(Xor, LHS, RHS, Ctx);
}
/// @}
/// @name Accessors
/// @{
/// getOpcode - Get the kind of this binary expression.
Opcode getOpcode() const { return Op; }
/// getLHS - Get the left-hand side expression of the binary operator.
const MCExpr *getLHS() const { return LHS; }
/// getRHS - Get the right-hand side expression of the binary operator.
const MCExpr *getRHS() const { return RHS; }
/// @}
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Binary;
}
};
/// MCTargetExpr - This is an extension point for target-specific MCExpr
/// subclasses to implement.
///
/// NOTE: All subclasses are required to have trivial destructors because
/// MCExprs are bump pointer allocated and not destructed.
class MCTargetExpr : public MCExpr {
virtual void anchor();
protected:
MCTargetExpr() : MCExpr(Target) {}
virtual ~MCTargetExpr() {}
public:
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;
virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Target;
}
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,32 @@
//===-- llvm/MC/MCFixedLenDisassembler.h - Decoder driver -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Fixed length disassembler decoder state machine driver.
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCFIXEDLENDISASSEMBLER_H
#define LLVM_MC_MCFIXEDLENDISASSEMBLER_H
namespace llvm {
namespace MCD {
// Disassembler state machine opcodes.
enum DecoderOps {
OPC_ExtractField = 1, // OPC_ExtractField(uint8_t Start, uint8_t Len)
OPC_FilterValue, // OPC_FilterValue(uleb128 Val, uint16_t NumToSkip)
OPC_CheckField, // OPC_CheckField(uint8_t Start, uint8_t Len,
// uleb128 Val, uint16_t NumToSkip)
OPC_CheckPredicate, // OPC_CheckPredicate(uleb128 PIdx, uint16_t NumToSkip)
OPC_Decode, // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
OPC_SoftFail, // OPC_SoftFail(uleb128 PMask, uleb128 NMask)
OPC_Fail // OPC_Fail()
};
} // namespace MCDecode
} // namespace llvm
#endif

View File

@@ -0,0 +1,112 @@
//===-- llvm/MC/MCFixup.h - Instruction Relocation and Patching -*- 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_MCFIXUP_H
#define LLVM_MC_MCFIXUP_H
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SMLoc.h"
#include <cassert>
namespace llvm {
class MCExpr;
/// MCFixupKind - Extensible enumeration to represent the type of a fixup.
enum MCFixupKind {
FK_Data_1 = 0, ///< A one-byte fixup.
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.
FK_GPRel_1, ///< A one-byte gp relative fixup.
FK_GPRel_2, ///< A two-byte gp relative fixup.
FK_GPRel_4, ///< A four-byte gp relative fixup.
FK_GPRel_8, ///< A eight-byte gp relative fixup.
FK_SecRel_1, ///< A one-byte section relative fixup.
FK_SecRel_2, ///< A two-byte section relative fixup.
FK_SecRel_4, ///< A four-byte section relative fixup.
FK_SecRel_8, ///< A eight-byte section relative fixup.
FirstTargetFixupKind = 128,
// Limit range of target fixups, in case we want to pack more efficiently
// later.
MaxTargetFixupKind = (1 << 8)
};
/// MCFixup - Encode information on a single operation to perform on a byte
/// sequence (e.g., an encoded instruction) which requires assemble- or run-
/// time patching.
///
/// Fixups are used any time the target instruction encoder needs to represent
/// some value in an instruction which is not yet concrete. The encoder will
/// encode the instruction assuming the value is 0, and emit a fixup which
/// communicates to the assembler backend how it should rewrite the encoded
/// value.
///
/// During the process of relaxation, the assembler will apply fixups as
/// symbolic values become concrete. When relaxation is complete, any remaining
/// fixups become relocations in the object file (or errors, if the fixup cannot
/// be encoded on the target).
class MCFixup {
/// The value to put into the fixup location. The exact interpretation of the
/// expression is target dependent, usually it will be one of the operands to
/// an instruction or an assembler directive.
const MCExpr *Value;
/// The byte index of start of the relocation inside the encoded instruction.
uint32_t Offset;
/// The target dependent kind of fixup item this is. The kind is used to
/// determine how the operand value should be encoded into the instruction.
unsigned Kind;
/// The source location which gave rise to the fixup, if any.
SMLoc Loc;
public:
static MCFixup Create(uint32_t Offset, const MCExpr *Value,
MCFixupKind Kind, SMLoc Loc = SMLoc()) {
assert(unsigned(Kind) < MaxTargetFixupKind && "Kind out of range!");
MCFixup FI;
FI.Value = Value;
FI.Offset = Offset;
FI.Kind = unsigned(Kind);
FI.Loc = Loc;
return FI;
}
MCFixupKind getKind() const { return MCFixupKind(Kind); }
uint32_t getOffset() const { return Offset; }
void setOffset(uint32_t Value) { Offset = Value; }
const MCExpr *getValue() const { return Value; }
/// 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, bool isPCRel) {
switch (Size) {
default: llvm_unreachable("Invalid generic fixup size!");
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;
}
}
SMLoc getLoc() const { return Loc; }
};
} // End llvm namespace
#endif

View File

@@ -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

View File

@@ -0,0 +1,204 @@
//===-- llvm/MC/MCInst.h - MCInst 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 MCInst and MCOperand classes, which
// is the basic representation used to represent low-level machine code
// instructions.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCINST_H
#define LLVM_MC_MCINST_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/SMLoc.h"
namespace llvm {
class raw_ostream;
class MCAsmInfo;
class MCInstPrinter;
class MCExpr;
class MCInst;
/// MCOperand - Instances of this class represent operands of the MCInst class.
/// This is a simple discriminated union.
class MCOperand {
enum MachineOperandType {
kInvalid, ///< Uninitialized.
kRegister, ///< Register operand.
kImmediate, ///< Immediate operand.
kFPImmediate, ///< Floating-point immediate operand.
kExpr, ///< Relocatable immediate operand.
kInst ///< Sub-instruction operand.
};
unsigned char Kind;
union {
unsigned RegVal;
int64_t ImmVal;
double FPImmVal;
const MCExpr *ExprVal;
const MCInst *InstVal;
};
public:
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; }
bool isInst() const { return Kind == kInst; }
/// getReg - Returns the register number.
unsigned getReg() const {
assert(isReg() && "This is not a register operand!");
return RegVal;
}
/// setReg - Set the register number.
void setReg(unsigned Reg) {
assert(isReg() && "This is not a register operand!");
RegVal = Reg;
}
int64_t getImm() const {
assert(isImm() && "This is not an immediate");
return ImmVal;
}
void setImm(int64_t Val) {
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;
}
void setExpr(const MCExpr *Val) {
assert(isExpr() && "This is not an expression");
ExprVal = Val;
}
const MCInst *getInst() const {
assert(isInst() && "This is not a sub-instruction");
return InstVal;
}
void setInst(const MCInst *Val) {
assert(isInst() && "This is not a sub-instruction");
InstVal = Val;
}
static MCOperand CreateReg(unsigned Reg) {
MCOperand Op;
Op.Kind = kRegister;
Op.RegVal = Reg;
return Op;
}
static MCOperand CreateImm(int64_t Val) {
MCOperand Op;
Op.Kind = kImmediate;
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;
Op.ExprVal = Val;
return Op;
}
static MCOperand CreateInst(const MCInst *Val) {
MCOperand Op;
Op.Kind = kInst;
Op.InstVal = Val;
return Op;
}
void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
void dump() const;
};
template <> struct isPodLike<MCOperand> { static const bool value = true; };
/// MCInst - Instances of this class represent a single low-level machine
/// instruction.
class MCInst {
unsigned Opcode;
SMLoc Loc;
SmallVector<MCOperand, 8> Operands;
public:
MCInst() : Opcode(0) {}
void setOpcode(unsigned Op) { Opcode = Op; }
unsigned getOpcode() const { return Opcode; }
void setLoc(SMLoc loc) { Loc = loc; }
SMLoc getLoc() const { return Loc; }
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 SmallVectorImpl<MCOperand>::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;
/// \brief Dump the MCInst as prettily as possible using the additional MC
/// structures, if given. Operators are separated by the \p Separator
/// string.
void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI = 0,
const MCInstPrinter *Printer = 0,
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
#endif

View File

@@ -0,0 +1,68 @@
//===-- llvm/MC/MCInstBuilder.h - Simplify creation of MCInsts --*- 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 MCInstBuilder class for convenient creation of
// MCInsts.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCINSTBUILDER_H
#define LLVM_MC_MCINSTBUILDER_H
#include "llvm/MC/MCInst.h"
namespace llvm {
class MCInstBuilder {
MCInst Inst;
public:
/// \brief Create a new MCInstBuilder for an MCInst with a specific opcode.
MCInstBuilder(unsigned Opcode) {
Inst.setOpcode(Opcode);
}
/// \brief Add a new register operand.
MCInstBuilder &addReg(unsigned Reg) {
Inst.addOperand(MCOperand::CreateReg(Reg));
return *this;
}
/// \brief Add a new integer immediate operand.
MCInstBuilder &addImm(int64_t Val) {
Inst.addOperand(MCOperand::CreateImm(Val));
return *this;
}
/// \brief Add a new floating point immediate operand.
MCInstBuilder &addFPImm(double Val) {
Inst.addOperand(MCOperand::CreateFPImm(Val));
return *this;
}
/// \brief Add a new MCExpr operand.
MCInstBuilder &addExpr(const MCExpr *Val) {
Inst.addOperand(MCOperand::CreateExpr(Val));
return *this;
}
/// \brief Add a new MCInst operand.
MCInstBuilder &addInst(const MCInst *Val) {
Inst.addOperand(MCOperand::CreateInst(Val));
return *this;
}
operator MCInst&() {
return Inst;
}
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,89 @@
//===-- MCInstPrinter.h - Convert an MCInst to target assembly syntax -----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCINSTPRINTER_H
#define LLVM_MC_MCINSTPRINTER_H
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Format.h"
namespace llvm {
class MCInst;
class raw_ostream;
class MCAsmInfo;
class MCInstrInfo;
class MCRegisterInfo;
class StringRef;
/// MCInstPrinter - This is an instance of a target assembly language printer
/// that converts an MCInst to valid target assembly syntax.
class MCInstPrinter {
protected:
/// CommentStream - a stream that comments can be emitted to if desired.
/// Each comment must end with a newline. This will be null if verbose
/// assembly emission is disable.
raw_ostream *CommentStream;
const MCAsmInfo &MAI;
const MCInstrInfo &MII;
const MCRegisterInfo &MRI;
/// The current set of available features.
unsigned AvailableFeatures;
/// True if we are printing marked up assembly.
bool UseMarkup;
/// True if we are printing immediates as hex.
bool PrintImmHex;
/// Utility function for printing annotations.
void printAnnotation(raw_ostream &OS, StringRef Annot);
public:
MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii,
const MCRegisterInfo &mri)
: CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0),
UseMarkup(0), PrintImmHex(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,
StringRef Annot) = 0;
/// getOpcodeName - Return the name of the specified opcode enum (e.g.
/// "MOV32ri") or empty if we can't resolve it.
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; }
bool getUseMarkup() const { return UseMarkup; }
void setUseMarkup(bool Value) { UseMarkup = Value; }
/// Utility functions to make adding mark ups simpler.
StringRef markup(StringRef s) const;
StringRef markup(StringRef a, StringRef b) const;
bool getPrintImmHex() const { return PrintImmHex; }
void setPrintImmHex(bool Value) { PrintImmHex = Value; }
/// Utility function to print immediates in decimal or hex.
format_object1<int64_t> formatImm(const int64_t Value) const;
};
} // namespace llvm
#endif

View File

@@ -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()).isConditionalBranch();
}
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;
};
}

View File

@@ -0,0 +1,564 @@
//===-- 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/MC/MCInst.h"
#include "llvm/MC/MCRegisterInfo.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.
int16_t RegClass;
/// Flags - These are flags from the MCOI::OperandFlags enum.
uint8_t Flags;
/// OperandType - Information about the type of the operand.
uint8_t OperandType;
/// 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).
uint32_t Constraints;
/// 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,
Select,
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.
unsigned Flags; // Flags identifying machine instr class
uint64_t TSFlags; // Target Specific Flag values
const uint16_t *ImplicitUses; // Registers implicitly read by this instr
const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr
const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands
/// \brief 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;
}
/// \brief Return the opcode number for this descriptor.
unsigned getOpcode() const {
return Opcode;
}
/// \brief 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;
}
/// \brief 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;
}
/// \brief Return flags of this instruction.
unsigned getFlags() const { return Flags; }
/// \brief 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);
}
/// \brief 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);
}
/// \brief 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);
}
/// \brief Return true if the instruction is a return.
bool isReturn() const {
return Flags & (1 << MCID::Return);
}
/// \brief Return true if the instruction is a call.
bool isCall() const {
return Flags & (1 << MCID::Call);
}
/// \brief 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);
}
/// \brief 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);
}
/// \brief 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);
}
/// \brief Return true if this is an indirect branch, such as a
/// branch through a register.
bool isIndirectBranch() const {
return Flags & (1 << MCID::IndirectBranch);
}
/// \brief 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();
}
/// \brief 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();
}
/// \brief Return true if this is a branch or an instruction which directly
/// writes to the program counter. Considered 'may' affect rather than
/// 'does' affect as things like predication are not taken into account.
bool mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const {
if (isBranch() || isCall() || isReturn() || isIndirectBranch())
return true;
unsigned PC = RI.getProgramCounter();
if (PC == 0) return false;
return hasDefOfPhysReg(MI, PC, RI);
}
/// \brief 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);
}
/// \brief Return true if this instruction is a comparison.
bool isCompare() const {
return Flags & (1 << MCID::Compare);
}
/// \brief Return true if this instruction is a move immediate
/// (including conditional moves) instruction.
bool isMoveImmediate() const {
return Flags & (1 << MCID::MoveImm);
}
/// \brief Return true if this instruction is a bitcast instruction.
bool isBitcast() const {
return Flags & (1 << MCID::Bitcast);
}
/// \brief Return true if this is a select instruction.
bool isSelect() const {
return Flags & (1 << MCID::Select);
}
/// \brief 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
//===--------------------------------------------------------------------===//
/// \brief 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);
}
/// \brief 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);
}
/// 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 uint16_t *getImplicitUses() const {
return ImplicitUses;
}
/// \brief 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 uint16_t *getImplicitDefs() const {
return ImplicitDefs;
}
/// \brief Return the number of implicit defs this instruct has.
unsigned getNumImplicitDefs() const {
if (ImplicitDefs == 0) return 0;
unsigned i = 0;
for (; ImplicitDefs[i]; ++i) /*empty*/;
return i;
}
/// \brief Return true if this instruction implicitly
/// uses the specified physical register.
bool hasImplicitUseOfPhysReg(unsigned Reg) const {
if (const uint16_t *ImpUses = ImplicitUses)
for (; *ImpUses; ++ImpUses)
if (*ImpUses == Reg) return true;
return false;
}
/// \brief Return true if this instruction implicitly
/// defines the specified physical register.
bool hasImplicitDefOfPhysReg(unsigned Reg,
const MCRegisterInfo *MRI = 0) const {
if (const uint16_t *ImpDefs = ImplicitDefs)
for (; *ImpDefs; ++ImpDefs)
if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs)))
return true;
return false;
}
/// \brief Return true if this instruction defines the specified physical
/// register, either explicitly or implicitly.
bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg,
const MCRegisterInfo &RI) const {
for (int i = 0, e = NumDefs; i != e; ++i)
if (MI.getOperand(i).isReg() &&
RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg()))
return true;
return hasImplicitDefOfPhysReg(Reg, &RI);
}
/// \brief 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;
}
/// \brief 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;
}
/// \brief 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;
}
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,62 @@
//===-- 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
const unsigned *InstrNameIndices; // Array for name indices in InstrNameData
const char *InstrNameData; // Instruction name string pool
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, const unsigned *NI, const char *ND,
unsigned NO) {
Desc = D;
InstrNameIndices = NI;
InstrNameData = ND;
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];
}
/// getName - Returns the name for the instructions with the given opcode.
const char *getName(unsigned Opcode) const {
assert(Opcode < NumOpcodes && "Invalid opcode!");
return &InstrNameData[InstrNameIndices[Opcode]];
}
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,257 @@
//===-- 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 "llvm/MC/MCSchedule.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 {
int NumMicroOps; ///< # of micro-ops, -1 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 MCSchedModel *SchedModel; ///< Basic machine properties.
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
/// Ctors.
///
InstrItineraryData() : SchedModel(&MCSchedModel::DefaultSchedModel),
Stages(0), OperandCycles(0),
Forwardings(0), Itineraries(0) {}
InstrItineraryData(const MCSchedModel *SM, const InstrStage *S,
const unsigned *OS, const unsigned *F)
: SchedModel(SM), Stages(S), OperandCycles(OS), Forwardings(F),
Itineraries(SchedModel->InstrItineraries) {}
/// 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.
///
/// InstrStages override the itinerary's MinLatency property. In fact, if the
/// stage latencies, which may be zero, are less than MinLatency,
/// getStageLatency returns a value less than MinLatency.
///
/// If no stages exist, MinLatency is used. If MinLatency is invalid (<0),
/// then it defaults to one cycle.
unsigned getStageLatency(unsigned ItinClassIndx) const {
// If the target doesn't provide itinerary information, use a simple
// non-zero default value for all instructions.
if (isEmpty())
return SchedModel->MinLatency < 0 ? 1 : SchedModel->MinLatency;
// 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;
}
/// getNumMicroOps - Return the number of micro-ops that the given class
/// decodes to. Return -1 for classes that require dynamic lookup via
/// TargetInstrInfo.
int getNumMicroOps(unsigned ItinClassIndx) const {
if (isEmpty())
return 1;
return Itineraries[ItinClassIndx].NumMicroOps;
}
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,58 @@
//===- MCLabel.h - Machine Code Directional Local Labels --------*- 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 MCLabel class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCLABEL_H
#define LLVM_MC_MCLABEL_H
#include "llvm/Support/Compiler.h"
namespace llvm {
class MCContext;
class raw_ostream;
/// MCLabel - Instances of this class represent a label name in the MC file,
/// and MCLabel are created and unique'd by the MCContext class. MCLabel
/// should only be constructed for valid instances in the object file.
class MCLabel {
// Instance - the instance number of this Directional Local Label
unsigned Instance;
private: // MCContext creates and uniques these.
friend class MCContext;
MCLabel(unsigned instance)
: Instance(instance) {}
MCLabel(const MCLabel&) LLVM_DELETED_FUNCTION;
void operator=(const MCLabel&) LLVM_DELETED_FUNCTION;
public:
/// getInstance - Get the current instance of this Directional Local Label.
unsigned getInstance() const { return Instance; }
/// incInstance - Increment the current instance of this Directional Local
/// Label.
unsigned incInstance() { return ++Instance; }
/// print - Print the value to the stream \p OS.
void print(raw_ostream &OS) const;
/// dump - Print the value to stderr.
void dump() const;
};
inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) {
Label.print(OS);
return OS;
}
} // end namespace llvm
#endif

View File

@@ -0,0 +1,46 @@
//===- MCMachOSymbolFlags.h - MachO 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 MachO target.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCMACHOSYMBOLFLAGS_H
#define LLVM_MC_MCMACHOSYMBOLFLAGS_H
// These flags are mostly used in MCMachOStreamer.cpp but also needed in
// MachObjectWriter.cpp to test for Weak Definitions of symbols to emit
// the correct relocation information.
namespace llvm {
/// SymbolFlags - We store the value for the 'desc' symbol field in the lowest
/// 16 bits of the implementation defined flags.
enum SymbolFlags { // See <mach-o/nlist.h>.
SF_DescFlagsMask = 0xFFFF,
// Reference type flags.
SF_ReferenceTypeMask = 0x0007,
SF_ReferenceTypeUndefinedNonLazy = 0x0000,
SF_ReferenceTypeUndefinedLazy = 0x0001,
SF_ReferenceTypeDefined = 0x0002,
SF_ReferenceTypePrivateDefined = 0x0003,
SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004,
SF_ReferenceTypePrivateUndefinedLazy = 0x0005,
// Other 'desc' flags.
SF_ThumbFunc = 0x0008,
SF_NoDeadStrip = 0x0020,
SF_WeakReference = 0x0040,
SF_WeakDefinition = 0x0080,
SF_SymbolResolver = 0x0100
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,276 @@
//===-- 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 Lifetime Management
/// @{
virtual void reset() {};
/// @}
/// @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 Lifetime management Methods
/// @{
virtual void reset();
/// @}
/// @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.
///
/// \param NumSections The number of sections in this segment.
/// \param 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);
void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset,
uint32_t DataSize);
void WriteLinkerOptionsLoadCommand(const std::vector<std::string> &Options);
// 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.
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 markAbsoluteVariableSymbols(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

View File

@@ -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

View File

@@ -0,0 +1,360 @@
//===-- 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/Support/CodeGen.h"
namespace llvm {
class MCContext;
class MCSection;
class StringRef;
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;
/// Section flags for eh_frame
unsigned EHSectionType;
unsigned EHSectionFlags;
/// CompactUnwindDwarfEHFrameOnly - Compact unwind encoding indicating that we
/// should emit only an EH frame.
unsigned CompactUnwindDwarfEHFrameOnly;
/// 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 *DwarfPubTypesSection;
const MCSection *DwarfDebugInlineSection;
const MCSection *DwarfStrSection;
const MCSection *DwarfLocSection;
const MCSection *DwarfARangesSection;
const MCSection *DwarfRangesSection;
const MCSection *DwarfMacroInfoSection;
// The pubnames section is no longer generated by default. The generation
// can be enabled by a compiler flag.
const MCSection *DwarfPubNamesSection;
// DWARF5 Experimental Debug Info Sections
/// DwarfAccelNamesSection, DwarfAccelObjCSection,
/// DwarfAccelNamespaceSection, DwarfAccelTypesSection -
/// If we use the DWARF accelerated hash tables then we want to emit these
/// sections.
const MCSection *DwarfAccelNamesSection;
const MCSection *DwarfAccelObjCSection;
const MCSection *DwarfAccelNamespaceSection;
const MCSection *DwarfAccelTypesSection;
/// These are used for the Fission separate debug information files.
const MCSection *DwarfInfoDWOSection;
const MCSection *DwarfAbbrevDWOSection;
const MCSection *DwarfStrDWOSection;
const MCSection *DwarfLineDWOSection;
const MCSection *DwarfLocDWOSection;
const MCSection *DwarfStrOffDWOSection;
const MCSection *DwarfAddrSection;
// 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, MachO and COFF.
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; }
unsigned getCompactUnwindDwarfEHFrameOnly() const {
return CompactUnwindDwarfEHFrameOnly;
}
const MCSection *getTextSection() const { return TextSection; }
const MCSection *getDataSection() const { return DataSection; }
const MCSection *getBSSSection() const { return BSSSection; }
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;
}
// DWARF5 Experimental Debug Info Sections
const MCSection *getDwarfAccelNamesSection() const {
return DwarfAccelNamesSection;
}
const MCSection *getDwarfAccelObjCSection() const {
return DwarfAccelObjCSection;
}
const MCSection *getDwarfAccelNamespaceSection() const {
return DwarfAccelNamespaceSection;
}
const MCSection *getDwarfAccelTypesSection() const {
return DwarfAccelTypesSection;
}
const MCSection *getDwarfInfoDWOSection() const {
return DwarfInfoDWOSection;
}
const MCSection *getDwarfAbbrevDWOSection() const {
return DwarfAbbrevDWOSection;
}
const MCSection *getDwarfStrDWOSection() const {
return DwarfStrDWOSection;
}
const MCSection *getDwarfLineDWOSection() const {
return DwarfLineDWOSection;
}
const MCSection *getDwarfLocDWOSection() const {
return DwarfLocDWOSection;
}
const MCSection *getDwarfStrOffDWOSection() const {
return DwarfStrOffDWOSection;
}
const MCSection *getDwarfAddrSection() const {
return DwarfAddrSection;
}
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

View File

@@ -0,0 +1,126 @@
//===- MCObjectStreamer.h - MCStreamer Object File Interface ----*- 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_MCOBJECTSTREAMER_H
#define LLVM_MC_MCOBJECTSTREAMER_H
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCStreamer.h"
namespace llvm {
class MCAssembler;
class MCCodeEmitter;
class MCSectionData;
class MCExpr;
class MCFragment;
class MCDataFragment;
class MCAsmBackend;
class raw_ostream;
/// \brief Streaming object file generation interface.
///
/// This class provides an implementation of the MCStreamer interface which is
/// suitable for use with the assembler backend. Specific object file formats
/// are expected to subclass this interface to implement directives specific
/// to that file format or custom semantics expected by the object writer
/// implementation.
class MCObjectStreamer : public MCStreamer {
MCAssembler *Assembler;
MCSectionData *CurSectionData;
MCSectionData::iterator CurInsertionPoint;
virtual void EmitInstToData(const MCInst &Inst) = 0;
virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame);
protected:
MCObjectStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB,
raw_ostream &_OS, MCCodeEmitter *_Emitter);
MCObjectStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB,
raw_ostream &_OS, MCCodeEmitter *_Emitter,
MCAssembler *_Assembler);
~MCObjectStreamer();
public:
/// state management
virtual void reset();
protected:
MCSectionData *getCurrentSectionData() const {
return CurSectionData;
}
MCFragment *getCurrentFragment() const;
void insert(MCFragment *F) const {
CurSectionData->getFragmentList().insert(CurInsertionPoint, F);
F->setParent(CurSectionData);
}
/// Get a data fragment to write into, creating a new one if the current
/// fragment is not a data fragment.
MCDataFragment *getOrCreateDataFragment() const;
const MCExpr *AddValueSymbols(const MCExpr *Value);
public:
MCAssembler &getAssembler() { return *Assembler; }
/// @name MCStreamer Interface
/// @{
virtual void EmitLabel(MCSymbol *Symbol);
virtual void EmitDebugLabel(MCSymbol *Symbol);
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
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,
const MCExpr *Subsection);
virtual void EmitInstruction(const MCInst &Inst);
/// \brief Emit an instruction to a special fragment, because this instruction
/// can change its size during relaxation.
virtual void EmitInstToFragment(const MCInst &Inst);
virtual void EmitBundleAlignMode(unsigned AlignPow2);
virtual void EmitBundleLock(bool AlignToEnd);
virtual void EmitBundleUnlock();
virtual void EmitBytes(StringRef Data, unsigned AddrSpace = 0);
virtual void EmitValueToAlignment(unsigned ByteAlignment,
int64_t Value = 0,
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0);
virtual void EmitCodeAlignment(unsigned ByteAlignment,
unsigned MaxBytesToEmit = 0);
virtual bool 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 EmitGPRel32Value(const MCExpr *Value);
virtual void EmitGPRel64Value(const MCExpr *Value);
virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
unsigned AddrSpace = 0);
virtual void FinishImpl();
/// @}
static bool classof(const MCStreamer *S) {
return S->getKind() >= SK_ELFStreamer && S->getKind() <= SK_WinCOFFStreamer;
}
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,199 @@
//===-- llvm/MC/MCObjectWriter.h - Object File Writer Interface -*- 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_MCOBJECTWRITER_H
#define LLVM_MC_MCOBJECTWRITER_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
namespace llvm {
class MCAsmLayout;
class MCAssembler;
class MCFixup;
class MCFragment;
class MCSymbolData;
class MCSymbolRefExpr;
class MCValue;
/// MCObjectWriter - Defines the object file and target independent interfaces
/// used by the assembler backend to write native file format object files.
///
/// The object writer contains a few callbacks used by the assembler to allow
/// the object writer to modify the assembler data structures at appropriate
/// points. Once assembly is complete, the object writer is given the
/// MCAssembler instance, which contains all the symbol and section data which
/// should be emitted as part of WriteObject().
///
/// The object writer also contains a number of helper methods for writing
/// binary data to the output stream.
class MCObjectWriter {
MCObjectWriter(const MCObjectWriter &) LLVM_DELETED_FUNCTION;
void operator=(const MCObjectWriter &) LLVM_DELETED_FUNCTION;
protected:
raw_ostream &OS;
unsigned IsLittleEndian : 1;
protected: // Can only create subclasses.
MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian)
: OS(_OS), IsLittleEndian(_IsLittleEndian) {}
public:
virtual ~MCObjectWriter();
/// lifetime management
virtual void reset() { }
bool isLittleEndian() const { return IsLittleEndian; }
raw_ostream &getStream() { return OS; }
/// @name High-Level API
/// @{
/// \brief Perform any late binding of symbols (for example, to assign symbol
/// indices for use when generating relocations).
///
/// This routine is called by the assembler after layout and relaxation is
/// complete.
virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) = 0;
/// \brief Record a relocation entry.
///
/// This routine is called by the assembler after layout and relaxation, and
/// post layout binding. The implementation is responsible for storing
/// information about the relocation so that it can be emitted during
/// WriteObject().
virtual void RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
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;
/// \brief 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(MCAssembler &Asm,
const MCAsmLayout &Layout) = 0;
/// @}
/// @name Binary Output
/// @{
void Write8(uint8_t Value) {
OS << char(Value);
}
void WriteLE16(uint16_t Value) {
Write8(uint8_t(Value >> 0));
Write8(uint8_t(Value >> 8));
}
void WriteLE32(uint32_t Value) {
WriteLE16(uint16_t(Value >> 0));
WriteLE16(uint16_t(Value >> 16));
}
void WriteLE64(uint64_t Value) {
WriteLE32(uint32_t(Value >> 0));
WriteLE32(uint32_t(Value >> 32));
}
void WriteBE16(uint16_t Value) {
Write8(uint8_t(Value >> 8));
Write8(uint8_t(Value >> 0));
}
void WriteBE32(uint32_t Value) {
WriteBE16(uint16_t(Value >> 16));
WriteBE16(uint16_t(Value >> 0));
}
void WriteBE64(uint64_t Value) {
WriteBE32(uint32_t(Value >> 32));
WriteBE32(uint32_t(Value >> 0));
}
void Write16(uint16_t Value) {
if (IsLittleEndian)
WriteLE16(Value);
else
WriteBE16(Value);
}
void Write32(uint32_t Value) {
if (IsLittleEndian)
WriteLE32(Value);
else
WriteBE32(Value);
}
void Write64(uint64_t Value) {
if (IsLittleEndian)
WriteLE64(Value);
else
WriteBE64(Value);
}
void WriteZeros(unsigned N) {
const char Zeros[16] = { 0 };
for (unsigned i = 0, e = N / 16; i != e; ++i)
OS << StringRef(Zeros, 16);
OS << StringRef(Zeros, N % 16);
}
void WriteBytes(const SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSize = 0) {
WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize);
}
void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
// TODO: this version may need to go away once all fragment contents are
// converted to SmallVector<char, N>
assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) &&
"data size greater than fill size, unexpected large write will occur");
OS << Str;
if (ZeroFillSize)
WriteZeros(ZeroFillSize - Str.size());
}
/// @}
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,40 @@
//===- AsmCond.h - Assembly file conditional assembly ----------*- 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_MCPARSER_ASMCOND_H
#define LLVM_MC_MCPARSER_ASMCOND_H
namespace llvm {
/// AsmCond - Class to support conditional assembly
///
/// The conditional assembly feature (.if, .else, .elseif and .endif) is
/// implemented with AsmCond that tells us what we are in the middle of
/// processing. Ignore can be either true or false. When true we are ignoring
/// the block of code in the middle of a conditional.
class AsmCond {
public:
enum ConditionalAssemblyType {
NoCond, // no conditional is being processed
IfCond, // inside if conditional
ElseIfCond, // inside elseif conditional
ElseCond // inside else conditional
};
ConditionalAssemblyType TheCond;
bool CondMet;
bool Ignore;
AsmCond() : TheCond(NoCond), CondMet(false), Ignore(false) {}
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,70 @@
//===- AsmLexer.h - Lexer for Assembly Files --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class declares the lexer for assembly files.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCPARSER_ASMLEXER_H
#define LLVM_MC_MCPARSER_ASMLEXER_H
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/Support/DataTypes.h"
#include <string>
namespace llvm {
class MemoryBuffer;
class MCAsmInfo;
/// 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&) LLVM_DELETED_FUNCTION;
AsmLexer(const AsmLexer&) LLVM_DELETED_FUNCTION;
protected:
/// LexToken - Read the next token and return its code.
virtual AsmToken LexToken();
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:
int getNextChar();
AsmToken ReturnError(const char *Loc, const std::string &Msg);
AsmToken LexIdentifier();
AsmToken LexSlash();
AsmToken LexLineComment();
AsmToken LexDigit();
AsmToken LexSingleQuote();
AsmToken LexQuote();
AsmToken LexFloatLiteral();
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,177 @@
//===-- llvm/MC/MCAsmLexer.h - Abstract Asm Lexer Interface -----*- 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_MCPARSER_MCASMLEXER_H
#define LLVM_MC_MCPARSER_MCASMLEXER_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/SMLoc.h"
namespace llvm {
/// AsmToken - Target independent representation for an assembler token.
class AsmToken {
public:
enum TokenKind {
// Markers
Eof, Error,
// String values.
Identifier,
String,
// Integer values.
Integer,
// Real values.
Real,
// No-value.
EndOfStatement,
Colon,
Space,
Plus, Minus, Tilde,
Slash, // '/'
BackSlash, // '\'
LParen, RParen, LBrac, RBrac, LCurly, RCurly,
Star, Dot, Comma, Dollar, Equal, EqualEqual,
Pipe, PipePipe, Caret,
Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash,
Less, LessEqual, LessLess, LessGreater,
Greater, GreaterEqual, GreaterGreater, At
};
private:
TokenKind Kind;
/// A reference to the entire token contents; this is always a pointer into
/// a memory buffer owned by the source manager.
StringRef Str;
int64_t IntVal;
public:
AsmToken() {}
AsmToken(TokenKind _Kind, StringRef _Str, int64_t _IntVal = 0)
: Kind(_Kind), Str(_Str), IntVal(_IntVal) {}
TokenKind getKind() const { return Kind; }
bool is(TokenKind K) const { return Kind == K; }
bool isNot(TokenKind K) const { return Kind != K; }
SMLoc getLoc() const;
SMLoc getEndLoc() const;
/// getStringContents - Get the contents of a string token (without quotes).
StringRef getStringContents() const {
assert(Kind == String && "This token isn't a string!");
return Str.slice(1, Str.size() - 1);
}
/// getIdentifier - Get the identifier string for the current token, which
/// should be an identifier or a string. This gets the portion of the string
/// which should be used as the identifier, e.g., it does not include the
/// quotes on strings.
StringRef getIdentifier() const {
if (Kind == Identifier)
return getString();
return getStringContents();
}
/// getString - Get the string for the current token, this includes all
/// characters (for example, the quotes on strings) in the token.
///
/// The returned StringRef points into the source manager's memory buffer, and
/// is safe to store across calls to Lex().
StringRef getString() const { return Str; }
// 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 {
assert(Kind == Integer && "This token isn't an integer!");
return IntVal;
}
};
/// MCAsmLexer - Generic assembler lexer interface, for use by target specific
/// assembly lexers.
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;
MCAsmLexer(const MCAsmLexer &) LLVM_DELETED_FUNCTION;
void operator=(const MCAsmLexer &) LLVM_DELETED_FUNCTION;
protected: // Can only create subclasses.
const char *TokStart;
bool SkipSpace;
MCAsmLexer();
virtual AsmToken LexToken() = 0;
void SetError(const SMLoc &errLoc, const std::string &err) {
ErrLoc = errLoc;
Err = err;
}
public:
virtual ~MCAsmLexer();
/// Lex - Consume the next token from the input stream and return it.
///
/// The lexer will continuosly return the end-of-file token once the end of
/// the main input file has been reached.
const AsmToken &Lex() {
return CurTok = LexToken();
}
virtual StringRef LexUntilEndOfStatement() = 0;
/// getLoc - Get the current source location.
SMLoc getLoc() const;
/// 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 \p K.
bool is(AsmToken::TokenKind K) const { return CurTok.is(K); }
/// isNot - Check if the current token has kind \p K.
bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); }
/// setSkipSpace - Set whether spaces should be ignored by the lexer
void setSkipSpace(bool val) { SkipSpace = val; }
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,199 @@
//===-- llvm/MC/MCAsmParser.h - Abstract Asm Parser Interface ---*- 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_MCPARSER_MCASMPARSER_H
#define LLVM_MC_MCPARSER_MCASMPARSER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCParser/AsmLexer.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
class MCAsmInfo;
class MCAsmLexer;
class MCAsmParserExtension;
class MCContext;
class MCExpr;
class MCInstPrinter;
class MCInstrInfo;
class MCStreamer;
class MCTargetAsmParser;
class SMLoc;
class SMRange;
class SourceMgr;
class Twine;
/// MCAsmParserSemaCallback - Generic Sema callback for assembly parser.
class MCAsmParserSemaCallback {
public:
typedef struct {
bool IsVarDecl;
unsigned Length, Size, Type;
void clear() {
IsVarDecl = false;
Length = 1;
Size = 0;
Type = 0;
}
} InlineAsmIdentifierInfo;
virtual ~MCAsmParserSemaCallback();
virtual void *LookupInlineAsmIdentifier(StringRef &LineBuf,
InlineAsmIdentifierInfo &Info) = 0;
virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
unsigned &Offset) = 0;
};
/// MCAsmParser - Generic assembler parser interface, for use by target specific
/// assembly parsers.
class MCAsmParser {
public:
typedef bool (*DirectiveHandler)(MCAsmParserExtension*, StringRef, SMLoc);
typedef std::pair<MCAsmParserExtension*, DirectiveHandler>
ExtensionDirectiveHandler;
private:
MCAsmParser(const MCAsmParser &) LLVM_DELETED_FUNCTION;
void operator=(const MCAsmParser &) LLVM_DELETED_FUNCTION;
MCTargetAsmParser *TargetParser;
unsigned ShowParsedOperands : 1;
protected: // Can only create subclasses.
MCAsmParser();
public:
virtual ~MCAsmParser();
virtual void addDirectiveHandler(StringRef Directive,
ExtensionDirectiveHandler Handler) = 0;
virtual SourceMgr &getSourceManager() = 0;
virtual MCAsmLexer &getLexer() = 0;
virtual MCContext &getContext() = 0;
/// getStreamer - Return the output streamer for the assembler.
virtual MCStreamer &getStreamer() = 0;
MCTargetAsmParser &getTargetParser() const { return *TargetParser; }
void setTargetParser(MCTargetAsmParser &P);
virtual unsigned getAssemblerDialect() { return 0;}
virtual void setAssemblerDialect(unsigned i) { }
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;
virtual void setParsingInlineAsm(bool V) = 0;
virtual bool isParsingInlineAsm() = 0;
/// parseMSInlineAsm - Parse ms-style inline assembly.
virtual bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
unsigned &NumOutputs, unsigned &NumInputs,
SmallVectorImpl<std::pair<void *, bool> > &OpDecls,
SmallVectorImpl<std::string> &Constraints,
SmallVectorImpl<std::string> &Clobbers,
const MCInstrInfo *MII,
const MCInstPrinter *IP,
MCAsmParserSemaCallback &SI) = 0;
/// Warning - Emit a warning at the location \p L, with the message \p Msg.
///
/// \return The return value is true, if warnings are fatal.
virtual bool Warning(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) = 0;
/// Error - Emit an error at the location \p L, with the message \p Msg.
///
/// \return The return value is always true, as an idiomatic convenience to
/// clients.
virtual bool Error(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) = 0;
/// Lex - Get the next AsmToken in the stream, possibly handling file
/// inclusion first.
virtual const AsmToken &Lex() = 0;
/// getTok - Get the current AsmToken from the stream.
const AsmToken &getTok();
/// \brief Report an error at the current lexer location.
bool TokError(const Twine &Msg,
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>());
/// parseIdentifier - Parse an identifier or string (as a quoted identifier)
/// and set \p Res to the identifier contents.
virtual bool parseIdentifier(StringRef &Res) = 0;
/// \brief Parse up to the end of statement and return the contents from the
/// current token until the end of the statement; the current token on exit
/// will be either the EndOfStatement or EOF.
virtual StringRef parseStringToEndOfStatement() = 0;
/// parseEscapedString - Parse the current token as a string which may include
/// escaped characters and return the string contents.
virtual bool parseEscapedString(std::string &Data) = 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
/// on error.
/// @result - False on success.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
bool parseExpression(const MCExpr *&Res);
/// parsePrimaryExpr - Parse a primary expression.
///
/// @param Res - The value of the expression. The result is undefined
/// on error.
/// @result - False on success.
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) = 0;
/// parseParenExpression - Parse an arbitrary expression, assuming that an
/// initial '(' has already been consumed.
///
/// @param Res - The value of the expression. The result is undefined
/// on error.
/// @result - False on success.
virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
/// parseAbsoluteExpression - Parse an expression which must evaluate to an
/// absolute value.
///
/// @param Res - The value of the absolute expression. The result is undefined
/// on error.
/// @result - False on success.
virtual bool parseAbsoluteExpression(int64_t &Res) = 0;
/// checkForValidSection - Ensure that we have a valid section set in the
/// streamer. Otherwise, report an error and switch to .text.
virtual void checkForValidSection() = 0;
};
/// \brief Create an MCAsmParser instance.
MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &,
MCStreamer &, const MCAsmInfo &);
} // End llvm namespace
#endif

View File

@@ -0,0 +1,80 @@
//===-- llvm/MC/MCAsmParserExtension.h - Asm Parser Hooks -------*- 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_MCPARSER_MCASMPARSEREXTENSION_H
#define LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/Support/SMLoc.h"
namespace llvm {
class Twine;
/// \brief Generic interface for extending the MCAsmParser,
/// which is implemented by target and object file assembly parser
/// implementations.
class MCAsmParserExtension {
MCAsmParserExtension(const MCAsmParserExtension &) LLVM_DELETED_FUNCTION;
void operator=(const MCAsmParserExtension &) LLVM_DELETED_FUNCTION;
MCAsmParser *Parser;
protected:
MCAsmParserExtension();
// Helper template for implementing static dispatch functions.
template<typename T, bool (T::*Handler)(StringRef, SMLoc)>
static bool HandleDirective(MCAsmParserExtension *Target,
StringRef Directive,
SMLoc DirectiveLoc) {
T *Obj = static_cast<T*>(Target);
return (Obj->*Handler)(Directive, DirectiveLoc);
}
bool BracketExpressionsSupported;
public:
virtual ~MCAsmParserExtension();
/// \brief Initialize the extension for parsing using the given \p Parser.
/// The extension should use the AsmParser interfaces to register its
/// parsing routines.
virtual void Initialize(MCAsmParser &Parser);
/// @name MCAsmParser Proxy Interfaces
/// @{
MCContext &getContext() { return getParser().getContext(); }
MCAsmLexer &getLexer() { return getParser().getLexer(); }
MCAsmParser &getParser() { return *Parser; }
SourceMgr &getSourceManager() { return getParser().getSourceManager(); }
MCStreamer &getStreamer() { return getParser().getStreamer(); }
bool Warning(SMLoc L, const Twine &Msg) {
return getParser().Warning(L, Msg);
}
bool Error(SMLoc L, const Twine &Msg) {
return getParser().Error(L, Msg);
}
bool TokError(const Twine &Msg) {
return getParser().TokError(Msg);
}
const AsmToken &Lex() { return getParser().Lex(); }
const AsmToken &getTok() { return getParser().getTok(); }
bool HasBracketExpressions() const { return BracketExpressionsSupported; }
/// @}
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,86 @@
//===-- llvm/MC/MCParsedAsmOperand.h - Asm Parser Operand -------*- 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_MCPARSER_MCPARSEDASMOPERAND_H
#define LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H
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 {
/// MCOperandNum - The corresponding MCInst operand number. Only valid when
/// parsing MS-style inline assembly.
unsigned MCOperandNum;
/// Constraint - The constraint on this operand. Only valid when parsing
/// MS-style inline assembly.
std::string Constraint;
public:
MCParsedAsmOperand() {}
virtual ~MCParsedAsmOperand() {}
void setConstraint(StringRef C) { Constraint = C.str(); }
StringRef getConstraint() { return Constraint; }
void setMCOperandNum (unsigned OpNum) { MCOperandNum = OpNum; }
unsigned getMCOperandNum() { return MCOperandNum; }
virtual StringRef getSymName() { return StringRef(); }
/// isToken - Is this a token operand?
virtual bool isToken() const = 0;
/// isImm - Is this an immediate operand?
virtual bool isImm() const = 0;
/// isReg - Is this a register operand?
virtual bool isReg() const = 0;
virtual unsigned getReg() const = 0;
/// isMem - Is this a memory operand?
virtual bool isMem() const = 0;
/// getStartLoc - Get the location of the first token of this operand.
virtual SMLoc getStartLoc() const = 0;
/// getEndLoc - Get the location of the last token of this operand.
virtual SMLoc getEndLoc() const = 0;
/// needAddressOf - Do we need to emit code to get the address of the
/// variable/label? Only valid when parsing MS-style inline assembly.
virtual bool needAddressOf() const { return false; }
/// isOffsetOf - Do we need to emit code to get the offset of the variable,
/// rather then the value of the variable? Only valid when parsing MS-style
/// inline assembly.
virtual bool isOffsetOf() const { return false; }
/// getOffsetOfLoc - Get the location of the offset operator.
virtual SMLoc getOffsetOfLoc() const { return SMLoc(); }
/// 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

View File

@@ -0,0 +1,542 @@
//=== 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 "llvm/Support/ErrorHandling.h"
#include <cassert>
namespace llvm {
/// An unsigned integer type large enough to represent all physical registers,
/// but not necessarily virtual registers.
typedef uint16_t MCPhysReg;
/// MCRegisterClass - Base class of TargetRegisterClass.
class MCRegisterClass {
public:
typedef const MCPhysReg* iterator;
typedef const MCPhysReg* const_iterator;
const char *Name;
const iterator RegsBegin;
const uint8_t *const RegSet;
const uint16_t RegsSize;
const uint16_t RegSetSize;
const uint16_t ID;
const uint16_t RegSize, Alignment; // Size & Alignment of register in bytes
const int8_t CopyCost;
const bool Allocatable;
/// 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 RegsBegin + RegsSize; }
/// getNumRegs - Return the number of registers in this class.
///
unsigned getNumRegs() const { return RegsSize; }
/// 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 {
uint32_t Name; // Printable name for the reg (for debugging)
uint32_t Overlaps; // Overlapping registers, described above
uint32_t SubRegs; // Sub-register set, described above
uint32_t SuperRegs; // Super-register set, described above
// Offset into MCRI::SubRegIndices of a list of sub-register indices for each
// sub-register in SubRegs.
uint32_t SubRegIndices;
// RegUnits - Points to the list of register units. The low 4 bits holds the
// Scale, the high bits hold an offset into DiffLists. See MCRegUnitIterator.
uint32_t RegUnits;
};
/// 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;
/// DwarfLLVMRegPair - Emitted by tablegen so Dwarf<->LLVM reg mappings can be
/// performed with a binary search.
struct DwarfLLVMRegPair {
unsigned FromReg;
unsigned ToReg;
bool operator<(DwarfLLVMRegPair RHS) const { return FromReg < RHS.FromReg; }
};
private:
const MCRegisterDesc *Desc; // Pointer to the descriptor array
unsigned NumRegs; // Number of entries in the array
unsigned RAReg; // Return address register
unsigned PCReg; // Program counter register
const MCRegisterClass *Classes; // Pointer to the regclass array
unsigned NumClasses; // Number of entries in the array
unsigned NumRegUnits; // Number of regunits.
const uint16_t (*RegUnitRoots)[2]; // Pointer to regunit root table.
const MCPhysReg *DiffLists; // Pointer to the difflists array
const char *RegStrings; // Pointer to the string table.
const uint16_t *SubRegIndices; // Pointer to the subreg lookup
// array.
unsigned NumSubRegIndices; // Number of subreg indices.
const uint16_t *RegEncodingTable; // Pointer to array of register
// encodings.
unsigned L2DwarfRegsSize;
unsigned EHL2DwarfRegsSize;
unsigned Dwarf2LRegsSize;
unsigned EHDwarf2LRegsSize;
const DwarfLLVMRegPair *L2DwarfRegs; // LLVM to Dwarf regs mapping
const DwarfLLVMRegPair *EHL2DwarfRegs; // LLVM to Dwarf regs mapping EH
const DwarfLLVMRegPair *Dwarf2LRegs; // Dwarf to LLVM regs mapping
const DwarfLLVMRegPair *EHDwarf2LRegs; // Dwarf to LLVM regs mapping EH
DenseMap<unsigned, int> L2SEHRegs; // LLVM to SEH regs mapping
public:
/// DiffListIterator - Base iterator class that can traverse the
/// differentially encoded register and regunit lists in DiffLists.
/// Don't use this class directly, use one of the specialized sub-classes
/// defined below.
class DiffListIterator {
uint16_t Val;
const MCPhysReg *List;
protected:
/// Create an invalid iterator. Call init() to point to something useful.
DiffListIterator() : Val(0), List(0) {}
/// init - Point the iterator to InitVal, decoding subsequent values from
/// DiffList. The iterator will initially point to InitVal, sub-classes are
/// responsible for skipping the seed value if it is not part of the list.
void init(MCPhysReg InitVal, const MCPhysReg *DiffList) {
Val = InitVal;
List = DiffList;
}
/// advance - Move to the next list position, return the applied
/// differential. This function does not detect the end of the list, that
/// is the caller's responsibility (by checking for a 0 return value).
unsigned advance() {
assert(isValid() && "Cannot move off the end of the list.");
MCPhysReg D = *List++;
Val += D;
return D;
}
public:
/// isValid - returns true if this iterator is not yet at the end.
bool isValid() const { return List; }
/// Dereference the iterator to get the value at the current position.
unsigned operator*() const { return Val; }
/// Pre-increment to move to the next position.
void operator++() {
// The end of the list is encoded as a 0 differential.
if (!advance())
List = 0;
}
};
// These iterators are allowed to sub-class DiffListIterator and access
// internal list pointers.
friend class MCSubRegIterator;
friend class MCSuperRegIterator;
friend class MCRegAliasIterator;
friend class MCRegUnitIterator;
friend class MCRegUnitRootIterator;
/// \brief Initialize MCRegisterInfo, called by TableGen
/// auto-generated routines. *DO NOT USE*.
void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA,
unsigned PC,
const MCRegisterClass *C, unsigned NC,
const uint16_t (*RURoots)[2],
unsigned NRU,
const MCPhysReg *DL,
const char *Strings,
const uint16_t *SubIndices,
unsigned NumIndices,
const uint16_t *RET) {
Desc = D;
NumRegs = NR;
RAReg = RA;
PCReg = PC;
Classes = C;
DiffLists = DL;
RegStrings = Strings;
NumClasses = NC;
RegUnitRoots = RURoots;
NumRegUnits = NRU;
SubRegIndices = SubIndices;
NumSubRegIndices = NumIndices;
RegEncodingTable = RET;
}
/// \brief Used to initialize LLVM register to Dwarf
/// register number mapping. Called by TableGen auto-generated routines.
/// *DO NOT USE*.
void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size,
bool isEH) {
if (isEH) {
EHL2DwarfRegs = Map;
EHL2DwarfRegsSize = Size;
} else {
L2DwarfRegs = Map;
L2DwarfRegsSize = Size;
}
}
/// \brief Used to initialize Dwarf register to LLVM
/// register number mapping. Called by TableGen auto-generated routines.
/// *DO NOT USE*.
void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size,
bool isEH) {
if (isEH) {
EHDwarf2LRegs = Map;
EHDwarf2LRegsSize = Size;
} else {
Dwarf2LRegs = Map;
Dwarf2LRegsSize = Size;
}
}
/// 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;
}
/// \brief This method should return the register where the return
/// address can be found.
unsigned getRARegister() const {
return RAReg;
}
/// Return the register which is the program counter.
unsigned getProgramCounter() const {
return PCReg;
}
const MCRegisterDesc &operator[](unsigned RegNo) const {
assert(RegNo < NumRegs &&
"Attempting to access record for invalid register number!");
return Desc[RegNo];
}
/// \brief Provide a get method, equivalent to [], but more useful with a
/// pointer to this object.
const MCRegisterDesc &get(unsigned RegNo) const {
return operator[](RegNo);
}
/// \brief Returns the physical register number of sub-register "Index"
/// for physical register RegNo. Return zero if the sub-register does not
/// exist.
unsigned getSubReg(unsigned Reg, unsigned Idx) const;
/// \brief Return a super-register of the specified register
/// Reg so its sub-register of index SubIdx is Reg.
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx,
const MCRegisterClass *RC) const;
/// \brief For a given register pair, return the sub-register index
/// if the second register is a sub-register of the first. Return zero
/// otherwise.
unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const;
/// \brief Return the human-readable symbolic target-specific name for the
/// specified physical register.
const char *getName(unsigned RegNo) const {
return RegStrings + get(RegNo).Name;
}
/// \brief Return the number of registers this target has (useful for
/// sizing arrays holding per register information)
unsigned getNumRegs() const {
return NumRegs;
}
/// \brief Return the number of sub-register indices
/// understood by the target. Index 0 is reserved for the no-op sub-register,
/// while 1 to getNumSubRegIndices() - 1 represent real sub-registers.
unsigned getNumSubRegIndices() const {
return NumSubRegIndices;
}
/// \brief Return the number of (native) register units in the
/// target. Register units are numbered from 0 to getNumRegUnits() - 1. They
/// can be accessed through MCRegUnitIterator defined below.
unsigned getNumRegUnits() const {
return NumRegUnits;
}
/// \brief 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;
/// \brief Map a dwarf register back to a target register.
int getLLVMRegNum(unsigned RegNum, bool isEH) const;
/// \brief 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;
regclass_iterator regclass_begin() const { return Classes; }
regclass_iterator regclass_end() const { return Classes+NumClasses; }
unsigned getNumRegClasses() const {
return (unsigned)(regclass_end()-regclass_begin());
}
/// \brief 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];
}
/// \brief Returns the encoding for RegNo
uint16_t getEncodingValue(unsigned RegNo) const {
assert(RegNo < NumRegs &&
"Attempting to get encoding for invalid register number!");
return RegEncodingTable[RegNo];
}
/// \brief Returns true if RegB is a sub-register of RegA.
bool isSubRegister(unsigned RegA, unsigned RegB) const {
return isSuperRegister(RegB, RegA);
}
/// \brief Returns true if RegB is a super-register of RegA.
bool isSuperRegister(unsigned RegA, unsigned RegB) const;
/// \brief Returns true if RegB is a sub-register of RegA or if RegB == RegA.
bool isSubRegisterEq(unsigned RegA, unsigned RegB) const {
return isSuperRegisterEq(RegB, RegA);
}
/// \brief Returns true if RegB is a super-register of RegA or if
/// RegB == RegA.
bool isSuperRegisterEq(unsigned RegA, unsigned RegB) const {
return RegA == RegB || isSuperRegister(RegA, RegB);
}
};
//===----------------------------------------------------------------------===//
// Register List Iterators
//===----------------------------------------------------------------------===//
// MCRegisterInfo provides lists of super-registers, sub-registers, and
// aliasing registers. Use these iterator classes to traverse the lists.
/// MCSubRegIterator enumerates all sub-registers of Reg.
class MCSubRegIterator : public MCRegisterInfo::DiffListIterator {
public:
MCSubRegIterator(unsigned Reg, const MCRegisterInfo *MCRI) {
init(Reg, MCRI->DiffLists + MCRI->get(Reg).SubRegs);
++*this;
}
};
/// MCSuperRegIterator enumerates all super-registers of Reg.
class MCSuperRegIterator : public MCRegisterInfo::DiffListIterator {
public:
MCSuperRegIterator(unsigned Reg, const MCRegisterInfo *MCRI) {
init(Reg, MCRI->DiffLists + MCRI->get(Reg).SuperRegs);
++*this;
}
};
/// MCRegAliasIterator enumerates all registers aliasing Reg.
/// If IncludeSelf is set, Reg itself is included in the list.
class MCRegAliasIterator : public MCRegisterInfo::DiffListIterator {
public:
MCRegAliasIterator(unsigned Reg, const MCRegisterInfo *MCRI,
bool IncludeSelf) {
init(Reg, MCRI->DiffLists + MCRI->get(Reg).Overlaps);
// Initially, the iterator points to Reg itself.
if (!IncludeSelf)
++*this;
}
};
// Definition for isSuperRegister. Put it down here since it needs the
// iterator defined above in addition to the MCRegisterInfo class itself.
inline bool MCRegisterInfo::isSuperRegister(unsigned RegA, unsigned RegB) const{
for (MCSuperRegIterator I(RegA, this); I.isValid(); ++I)
if (*I == RegB)
return true;
return false;
}
//===----------------------------------------------------------------------===//
// Register Units
//===----------------------------------------------------------------------===//
// Register units are used to compute register aliasing. Every register has at
// least one register unit, but it can have more. Two registers overlap if and
// only if they have a common register unit.
//
// A target with a complicated sub-register structure will typically have many
// fewer register units than actual registers. MCRI::getNumRegUnits() returns
// the number of register units in the target.
// MCRegUnitIterator enumerates a list of register units for Reg. The list is
// in ascending numerical order.
class MCRegUnitIterator : public MCRegisterInfo::DiffListIterator {
public:
/// MCRegUnitIterator - Create an iterator that traverses the register units
/// in Reg.
MCRegUnitIterator(unsigned Reg, const MCRegisterInfo *MCRI) {
assert(Reg && "Null register has no regunits");
// Decode the RegUnits MCRegisterDesc field.
unsigned RU = MCRI->get(Reg).RegUnits;
unsigned Scale = RU & 15;
unsigned Offset = RU >> 4;
// Initialize the iterator to Reg * Scale, and the List pointer to
// DiffLists + Offset.
init(Reg * Scale, MCRI->DiffLists + Offset);
// That may not be a valid unit, we need to advance by one to get the real
// unit number. The first differential can be 0 which would normally
// terminate the list, but since we know every register has at least one
// unit, we can allow a 0 differential here.
advance();
}
};
// Each register unit has one or two root registers. The complete set of
// registers containing a register unit is the union of the roots and their
// super-registers. All registers aliasing Unit can be visited like this:
//
// for (MCRegUnitRootIterator RI(Unit, MCRI); RI.isValid(); ++RI) {
// unsigned Root = *RI;
// visit(Root);
// for (MCSuperRegIterator SI(Root, MCRI); SI.isValid(); ++SI)
// visit(*SI);
// }
/// MCRegUnitRootIterator enumerates the root registers of a register unit.
class MCRegUnitRootIterator {
uint16_t Reg0;
uint16_t Reg1;
public:
MCRegUnitRootIterator(unsigned RegUnit, const MCRegisterInfo *MCRI) {
assert(RegUnit < MCRI->getNumRegUnits() && "Invalid register unit");
Reg0 = MCRI->RegUnitRoots[RegUnit][0];
Reg1 = MCRI->RegUnitRoots[RegUnit][1];
}
/// \brief Dereference to get the current root register.
unsigned operator*() const {
return Reg0;
}
/// \brief Check if the iterator is at the end of the list.
bool isValid() const {
return Reg0;
}
/// \brief Preincrement to move to the next root register.
void operator++() {
assert(isValid() && "Cannot move off the end of the list.");
Reg0 = Reg1;
Reg1 = 0;
}
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,254 @@
//===-- llvm/MC/MCSchedule.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 defines the classes used to describe a subtarget's machine model
// for scheduling and other instruction cost heuristics.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSCHEDULE_H
#define LLVM_MC_MCSCHEDULE_H
#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
struct InstrItinerary;
/// Define a kind of processor resource that will be modeled by the scheduler.
struct MCProcResourceDesc {
#ifndef NDEBUG
const char *Name;
#endif
unsigned NumUnits; // Number of resource of this kind
unsigned SuperIdx; // Index of the resources kind that contains this kind.
// Buffered resources may be consumed at some indeterminate cycle after
// dispatch (e.g. for instructions that may issue out-of-order). Unbuffered
// resources always consume their resource some fixed number of cycles after
// dispatch (e.g. for instruction interlocking that may stall the pipeline).
bool IsBuffered;
bool operator==(const MCProcResourceDesc &Other) const {
return NumUnits == Other.NumUnits && SuperIdx == Other.SuperIdx
&& IsBuffered == Other.IsBuffered;
}
};
/// Identify one of the processor resource kinds consumed by a particular
/// scheduling class for the specified number of cycles.
struct MCWriteProcResEntry {
unsigned ProcResourceIdx;
unsigned Cycles;
bool operator==(const MCWriteProcResEntry &Other) const {
return ProcResourceIdx == Other.ProcResourceIdx && Cycles == Other.Cycles;
}
};
/// Specify the latency in cpu cycles for a particular scheduling class and def
/// index. -1 indicates an invalid latency. Heuristics would typically consider
/// an instruction with invalid latency to have infinite latency. Also identify
/// the WriteResources of this def. When the operand expands to a sequence of
/// writes, this ID is the last write in the sequence.
struct MCWriteLatencyEntry {
int Cycles;
unsigned WriteResourceID;
bool operator==(const MCWriteLatencyEntry &Other) const {
return Cycles == Other.Cycles && WriteResourceID == Other.WriteResourceID;
}
};
/// Specify the number of cycles allowed after instruction issue before a
/// particular use operand reads its registers. This effectively reduces the
/// write's latency. Here we allow negative cycles for corner cases where
/// latency increases. This rule only applies when the entry's WriteResource
/// matches the write's WriteResource.
///
/// MCReadAdvanceEntries are sorted first by operand index (UseIdx), then by
/// WriteResourceIdx.
struct MCReadAdvanceEntry {
unsigned UseIdx;
unsigned WriteResourceID;
int Cycles;
bool operator==(const MCReadAdvanceEntry &Other) const {
return UseIdx == Other.UseIdx && WriteResourceID == Other.WriteResourceID
&& Cycles == Other.Cycles;
}
};
/// Summarize the scheduling resources required for an instruction of a
/// particular scheduling class.
///
/// Defined as an aggregate struct for creating tables with initializer lists.
struct MCSchedClassDesc {
static const unsigned short InvalidNumMicroOps = UINT16_MAX;
static const unsigned short VariantNumMicroOps = UINT16_MAX - 1;
#ifndef NDEBUG
const char* Name;
#endif
unsigned short NumMicroOps;
bool BeginGroup;
bool EndGroup;
unsigned WriteProcResIdx; // First index into WriteProcResTable.
unsigned NumWriteProcResEntries;
unsigned WriteLatencyIdx; // First index into WriteLatencyTable.
unsigned NumWriteLatencyEntries;
unsigned ReadAdvanceIdx; // First index into ReadAdvanceTable.
unsigned NumReadAdvanceEntries;
bool isValid() const {
return NumMicroOps != InvalidNumMicroOps;
}
bool isVariant() const {
return NumMicroOps == VariantNumMicroOps;
}
};
/// Machine model for scheduling, bundling, and heuristics.
///
/// The machine model directly provides basic information about the
/// microarchitecture to the scheduler in the form of properties. It also
/// optionally refers to scheduler resource tables and itinerary
/// tables. Scheduler resource tables model the latency and cost for each
/// instruction type. Itinerary tables are an independant mechanism that
/// provides a detailed reservation table describing each cycle of instruction
/// execution. Subtargets may define any or all of the above categories of data
/// depending on the type of CPU and selected scheduler.
class MCSchedModel {
public:
static MCSchedModel DefaultSchedModel; // For unknown processors.
// IssueWidth is the maximum number of instructions that may be scheduled in
// the same per-cycle group.
unsigned IssueWidth;
static const unsigned DefaultIssueWidth = 1;
// MinLatency is the minimum latency between a register write
// followed by a data dependent read. This determines which
// instructions may be scheduled in the same per-cycle group. This
// is distinct from *expected* latency, which determines the likely
// critical path but does not guarantee a pipeline
// hazard. MinLatency can always be overridden by the number of
// InstrStage cycles.
//
// (-1) Standard in-order processor.
// Use InstrItinerary OperandCycles as MinLatency.
// If no OperandCycles exist, then use the cycle of the last InstrStage.
//
// (0) Out-of-order processor, or in-order with bundled dependencies.
// RAW dependencies may be dispatched in the same cycle.
// Optional InstrItinerary OperandCycles provides expected latency.
//
// (>0) In-order processor with variable latencies.
// Use the greater of this value or the cycle of the last InstrStage.
// Optional InstrItinerary OperandCycles provides expected latency.
// TODO: can't yet specify both min and expected latency per operand.
int MinLatency;
static const int DefaultMinLatency = -1;
// LoadLatency is the expected latency of load instructions.
//
// If MinLatency >= 0, this may be overriden for individual load opcodes by
// InstrItinerary OperandCycles.
unsigned LoadLatency;
static const unsigned DefaultLoadLatency = 4;
// HighLatency is the expected latency of "very high latency" operations.
// See TargetInstrInfo::isHighLatencyDef().
// By default, this is set to an arbitrarily high number of cycles
// likely to have some impact on scheduling heuristics.
// If MinLatency >= 0, this may be overriden by InstrItinData OperandCycles.
unsigned HighLatency;
static const unsigned DefaultHighLatency = 10;
// ILPWindow is the number of cycles that the scheduler effectively ignores
// before attempting to hide latency. This should be zero for in-order cpus to
// always hide expected latency. For out-of-order cpus, it may be tweaked as
// desired to roughly approximate instruction buffers. The actual threshold is
// not very important for an OOO processor, as long as it isn't too high. A
// nonzero value helps avoid rescheduling to hide latency when its is fairly
// obviously useless and makes register pressure heuristics more effective.
unsigned ILPWindow;
static const unsigned DefaultILPWindow = 0;
// MispredictPenalty is the typical number of extra cycles the processor
// takes to recover from a branch misprediction.
unsigned MispredictPenalty;
static const unsigned DefaultMispredictPenalty = 10;
private:
unsigned ProcID;
const MCProcResourceDesc *ProcResourceTable;
const MCSchedClassDesc *SchedClassTable;
unsigned NumProcResourceKinds;
unsigned NumSchedClasses;
// Instruction itinerary tables used by InstrItineraryData.
friend class InstrItineraryData;
const InstrItinerary *InstrItineraries;
public:
// Default's must be specified as static const literals so that tablegenerated
// target code can use it in static initializers. The defaults need to be
// initialized in this default ctor because some clients directly instantiate
// MCSchedModel instead of using a generated itinerary.
MCSchedModel(): IssueWidth(DefaultIssueWidth),
MinLatency(DefaultMinLatency),
LoadLatency(DefaultLoadLatency),
HighLatency(DefaultHighLatency),
ILPWindow(DefaultILPWindow),
MispredictPenalty(DefaultMispredictPenalty),
ProcID(0), ProcResourceTable(0), SchedClassTable(0),
NumProcResourceKinds(0), NumSchedClasses(0),
InstrItineraries(0) {
(void)NumProcResourceKinds;
(void)NumSchedClasses;
}
// Table-gen driven ctor.
MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned ilp,
unsigned mp, unsigned pi, const MCProcResourceDesc *pr,
const MCSchedClassDesc *sc, unsigned npr, unsigned nsc,
const InstrItinerary *ii):
IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl),
ILPWindow(ilp), MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr),
SchedClassTable(sc), NumProcResourceKinds(npr), NumSchedClasses(nsc),
InstrItineraries(ii) {}
unsigned getProcessorID() const { return ProcID; }
/// Does this machine model include instruction-level scheduling.
bool hasInstrSchedModel() const { return SchedClassTable; }
unsigned getNumProcResourceKinds() const {
return NumProcResourceKinds;
}
const MCProcResourceDesc *getProcResource(unsigned ProcResourceIdx) const {
assert(hasInstrSchedModel() && "No scheduling machine model");
assert(ProcResourceIdx < NumProcResourceKinds && "bad proc resource idx");
return &ProcResourceTable[ProcResourceIdx];
}
const MCSchedClassDesc *getSchedClassDesc(unsigned SchedClassIdx) const {
assert(hasInstrSchedModel() && "No scheduling machine model");
assert(SchedClassIdx < NumSchedClasses && "bad scheduling class idx");
return &SchedClassTable[SchedClassIdx];
}
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,79 @@
//===- MCSection.h - Machine Code Sections ----------------------*- 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 MCSection class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSECTION_H
#define LLVM_MC_MCSECTION_H
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
class MCAsmInfo;
class MCExpr;
class raw_ostream;
/// MCSection - Instances of this class represent a uniqued identifier for a
/// section in the current translation unit. The MCContext class uniques and
/// creates these.
class MCSection {
public:
enum SectionVariant {
SV_COFF = 0,
SV_ELF,
SV_MachO
};
private:
MCSection(const MCSection&) LLVM_DELETED_FUNCTION;
void operator=(const MCSection&) LLVM_DELETED_FUNCTION;
protected:
MCSection(SectionVariant V, SectionKind K) : Variant(V), Kind(K) {}
SectionVariant Variant;
SectionKind Kind;
public:
virtual ~MCSection();
SectionKind getKind() const { return Kind; }
SectionVariant getVariant() const { return Variant; }
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS,
const MCExpr *Subsection) const = 0;
// Convenience routines to get label names for the beginning/end of a
// section.
virtual std::string getLabelBeginName() const = 0;
virtual std::string getLabelEndName() const = 0;
/// isBaseAddressKnownZero - Return true if we know that this section will
/// get a base address of zero. In cases where we know that this is true we
/// can emit section offsets as direct references to avoid a subtraction
/// from the base of the section, saving a relocation.
virtual bool isBaseAddressKnownZero() const {
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;
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,75 @@
//===- MCSectionCOFF.h - COFF Machine Code Sections -------------*- 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 MCSectionCOFF class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSECTIONCOFF_H
#define LLVM_MC_MCSECTIONCOFF_H
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSection.h"
#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;
/// Selection - This is the Selection field for the section symbol, if
/// it is a COMDAT section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
int Selection;
private:
friend class MCContext;
MCSectionCOFF(StringRef Section, unsigned Characteristics,
int Selection, SectionKind K)
: MCSection(SV_COFF, K), SectionName(Section),
Characteristics(Characteristics), Selection (Selection) {
assert ((Characteristics & 0x00F00000) == 0 &&
"alignment must not be set upon section creation");
}
~MCSectionCOFF();
public:
/// ShouldOmitSectionDirective - Decides whether a '.section' directive
/// should be printed before the section name
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
StringRef getSectionName() const { return SectionName; }
virtual std::string getLabelBeginName() const {
return SectionName.str() + "_begin";
}
virtual std::string getLabelEndName() const {
return SectionName.str() + "_end";
}
unsigned getCharacteristics() const { return Characteristics; }
int getSelection () const { return Selection; }
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS,
const MCExpr *Subsection) const;
virtual bool UseCodeAlign() const;
virtual bool isVirtualSection() const;
static bool classof(const MCSection *S) {
return S->getVariant() == SV_COFF;
}
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,95 @@
//===- MCSectionELF.h - ELF Machine Code Sections ---------------*- 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 MCSectionELF class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSECTIONELF_H
#define LLVM_MC_MCSECTIONELF_H
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSection.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/raw_ostream.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;
/// 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, unsigned entrySize, const MCSymbol *group)
: MCSection(SV_ELF, K), SectionName(Section), Type(type), Flags(flags),
EntrySize(entrySize), Group(group) {}
~MCSectionELF();
public:
/// ShouldOmitSectionDirective - Decides whether a '.section' directive
/// should be printed before the section name
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
StringRef getSectionName() const { return SectionName; }
virtual std::string getLabelBeginName() const {
return SectionName.str() + "_begin"; }
virtual std::string getLabelEndName() const {
return SectionName.str() + "_end";
}
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 MCExpr *Subsection) 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() & ELF::SHF_ALLOC) == 0;
}
static bool classof(const MCSection *S) {
return S->getVariant() == SV_ELF;
}
// Return the entry size for sections with fixed-width data.
static unsigned DetermineEntrySize(SectionKind Kind);
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,190 @@
//===- MCSectionMachO.h - MachO Machine Code Sections -----------*- 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 MCSectionMachO class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSECTIONMACHO_H
#define LLVM_MC_MCSECTIONMACHO_H
#include "llvm/ADT/StringRef.h"
#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);
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.
S_ZEROFILL = 0x01U,
/// S_CSTRING_LITERALS - Section with literal C strings.
S_CSTRING_LITERALS = 0x02U,
/// S_4BYTE_LITERALS - Section with 4 byte literals.
S_4BYTE_LITERALS = 0x03U,
/// S_8BYTE_LITERALS - Section with 8 byte literals.
S_8BYTE_LITERALS = 0x04U,
/// S_LITERAL_POINTERS - Section with pointers to literals.
S_LITERAL_POINTERS = 0x05U,
/// S_NON_LAZY_SYMBOL_POINTERS - Section with non-lazy symbol pointers.
S_NON_LAZY_SYMBOL_POINTERS = 0x06U,
/// S_LAZY_SYMBOL_POINTERS - Section with lazy symbol pointers.
S_LAZY_SYMBOL_POINTERS = 0x07U,
/// S_SYMBOL_STUBS - Section with symbol stubs, byte size of stub in
/// the Reserved2 field.
S_SYMBOL_STUBS = 0x08U,
/// S_MOD_INIT_FUNC_POINTERS - Section with only function pointers for
/// initialization.
S_MOD_INIT_FUNC_POINTERS = 0x09U,
/// 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.
S_COALESCED = 0x0BU,
/// S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4
/// gigabytes).
S_GB_ZEROFILL = 0x0CU,
/// S_INTERPOSING - Section with only pairs of function pointers for
/// interposing.
S_INTERPOSING = 0x0DU,
/// S_16BYTE_LITERALS - Section with only 16 byte literals.
S_16BYTE_LITERALS = 0x0EU,
/// S_DTRACE_DOF - Section contains DTrace Object Format.
S_DTRACE_DOF = 0x0FU,
/// S_LAZY_DYLIB_SYMBOL_POINTERS - Section with lazy symbol pointers to
/// lazy loaded dylibs.
S_LAZY_DYLIB_SYMBOL_POINTERS = 0x10U,
/// S_THREAD_LOCAL_REGULAR - Section with ....
S_THREAD_LOCAL_REGULAR = 0x11U,
/// S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section.
S_THREAD_LOCAL_ZEROFILL = 0x12U,
/// S_THREAD_LOCAL_VARIABLES - Section with thread local variable structure
/// data.
S_THREAD_LOCAL_VARIABLES = 0x13U,
/// S_THREAD_LOCAL_VARIABLE_POINTERS - Section with ....
S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14U,
/// S_THREAD_LOCAL_INIT_FUNCTION_POINTERS - Section with thread local
/// variable initialization pointers to functions.
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,
/// S_ATTR_NO_TOC - Section contains coalesced symbols that are not to be
/// in a ranlib table of contents.
S_ATTR_NO_TOC = 1U << 30,
/// S_ATTR_STRIP_STATIC_SYMS - Ok to strip static symbols in this section
/// in files with the MY_DYLDLINK flag.
S_ATTR_STRIP_STATIC_SYMS = 1U << 29,
/// S_ATTR_NO_DEAD_STRIP - No dead stripping.
S_ATTR_NO_DEAD_STRIP = 1U << 28,
/// S_ATTR_LIVE_SUPPORT - Blocks are live if they reference live blocks.
S_ATTR_LIVE_SUPPORT = 1U << 27,
/// S_ATTR_SELF_MODIFYING_CODE - Used with i386 code stubs written on by
/// dyld.
S_ATTR_SELF_MODIFYING_CODE = 1U << 26,
/// S_ATTR_DEBUG - A debug section.
S_ATTR_DEBUG = 1U << 25,
/// S_ATTR_SOME_INSTRUCTIONS - Section contains some machine instructions.
S_ATTR_SOME_INSTRUCTIONS = 1U << 10,
/// S_ATTR_EXT_RELOC - Section has external relocation entries.
S_ATTR_EXT_RELOC = 1U << 9,
/// S_ATTR_LOC_RELOC - Section has local relocation entries.
S_ATTR_LOC_RELOC = 1U << 8
};
StringRef getSegmentName() const {
// SegmentName is not necessarily null terminated!
if (SegmentName[15])
return StringRef(SegmentName, 16);
return StringRef(SegmentName);
}
StringRef getSectionName() const {
// SectionName is not necessarily null terminated!
if (SectionName[15])
return StringRef(SectionName, 16);
return StringRef(SectionName);
}
virtual std::string getLabelBeginName() const {
return StringRef(getSegmentName().str() + getSectionName().str() + "_begin");
}
virtual std::string getLabelEndName() const {
return StringRef(getSegmentName().str() + getSectionName().str() + "_end");
}
unsigned getTypeAndAttributes() const { return TypeAndAttributes; }
unsigned getStubSize() const { return Reserved2; }
unsigned getType() const { return TypeAndAttributes & SECTION_TYPE; }
bool hasAttribute(unsigned Value) const {
return (TypeAndAttributes & Value) != 0;
}
/// ParseSectionSpecifier - Parse the section specifier indicated by "Spec".
/// This is a string that can appear after a .section directive in a mach-o
/// 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 MCExpr *Subsection) const;
virtual bool UseCodeAlign() const;
virtual bool isVirtualSection() const;
static bool classof(const MCSection *S) {
return S->getVariant() == SV_MachO;
}
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,707 @@
//===- MCStreamer.h - High-level Streaming Machine Code Output --*- 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 MCStreamer class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSTREAMER_H
#define LLVM_MC_MCSTREAMER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCWin64EH.h"
#include "llvm/Support/DataTypes.h"
#include <string>
namespace llvm {
class MCAsmBackend;
class MCCodeEmitter;
class MCContext;
class MCExpr;
class MCInst;
class MCInstPrinter;
class MCSection;
class MCSymbol;
class StringRef;
class Twine;
class raw_ostream;
class formatted_raw_ostream;
typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair;
/// MCStreamer - Streaming machine code generation interface. This interface
/// is intended to provide a programatic interface that is very similar to the
/// level that an assembler .s file provides. It has callbacks to emit bytes,
/// handle directives, etc. The implementation of this interface retains
/// state to know what the current section is etc.
///
/// There are multiple implementations of this interface: one for writing out
/// a .s file, and implementations that write out .o files of various formats.
///
class MCStreamer {
public:
enum StreamerKind {
SK_AsmStreamer,
SK_NullStreamer,
SK_RecordStreamer,
// MCObjectStreamer subclasses.
SK_ELFStreamer,
SK_ARMELFStreamer,
SK_MachOStreamer,
SK_PureStreamer,
SK_MipsELFStreamer,
SK_WinCOFFStreamer
};
private:
const StreamerKind Kind;
MCContext &Context;
MCStreamer(const MCStreamer&) LLVM_DELETED_FUNCTION;
MCStreamer &operator=(const MCStreamer&) LLVM_DELETED_FUNCTION;
bool EmitEHFrame;
bool EmitDebugFrame;
std::vector<MCDwarfFrameInfo> FrameInfos;
MCDwarfFrameInfo *getCurrentFrameInfo();
MCSymbol *EmitCFICommon();
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<MCSectionSubPair, MCSectionSubPair>, 4> SectionStack;
bool AutoInitSections;
protected:
MCStreamer(StreamerKind Kind, MCContext &Ctx);
const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A,
const MCSymbol *B);
const MCExpr *ForceExpAbs(const MCExpr* Expr);
void RecordProcStart(MCDwarfFrameInfo &Frame);
virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
void RecordProcEnd(MCDwarfFrameInfo &Frame);
virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame);
void EmitFrames(bool usingCFI);
MCWin64EHUnwindInfo *getCurrentW64UnwindInfo(){return CurrentW64UnwindInfo;}
void EmitW64Tables();
public:
virtual ~MCStreamer();
StreamerKind getKind() const { return Kind; }
/// State management
///
virtual void reset();
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; }
/// AddComment - Add a comment that can be emitted to the generated .s
/// file if applicable as a QoI issue to make the output of the compiler
/// more readable. This only affects the MCAsmStreamer, and only when
/// verbose assembly output is enabled.
///
/// 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.
MCSectionSubPair getCurrentSection() const {
if (!SectionStack.empty())
return SectionStack.back().first;
return MCSectionSubPair();
}
/// getPreviousSection - Return the previous section that the streamer is
/// emitting code to.
MCSectionSubPair getPreviousSection() const {
if (!SectionStack.empty())
return SectionStack.back().second;
return MCSectionSubPair();
}
/// 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 *, const MCExpr *) = 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;
MCSectionSubPair oldSection = SectionStack.pop_back_val().first;
MCSectionSubPair curSection = SectionStack.back().first;
if (oldSection != curSection)
ChangeSection(curSection.first, curSection.second);
return true;
}
bool SubSection(const MCExpr *Subsection) {
if (SectionStack.empty())
return false;
SwitchSection(SectionStack.back().first.first, Subsection);
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.
void SwitchSection(const MCSection *Section, const MCExpr *Subsection = 0) {
assert(Section && "Cannot switch to a null section!");
MCSectionSubPair curSection = SectionStack.back().first;
SectionStack.back().second = curSection;
if (MCSectionSubPair(Section, Subsection) != curSection) {
SectionStack.back().first = MCSectionSubPair(Section, Subsection);
ChangeSection(Section, Subsection);
}
}
/// 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,
const MCExpr *Subsection = 0) {
assert(Section && "Cannot switch to a null section!");
MCSectionSubPair curSection = SectionStack.back().first;
SectionStack.back().second = curSection;
if (MCSectionSubPair(Section, Subsection) != curSection)
SectionStack.back().first = MCSectionSubPair(Section, Subsection);
}
/// Initialize the streamer.
void InitStreamer() {
if (AutoInitSections)
InitSections();
}
/// Tell this MCStreamer to call InitSections upon initialization.
void setAutoInitSections(bool AutoInitSections) {
this->AutoInitSections = AutoInitSections;
}
/// InitSections - Create the default sections and set the initial one.
virtual void InitSections() = 0;
/// InitToTextSection - Create a text section and switch the streamer to it.
virtual void InitToTextSection() = 0;
/// EmitLabel - Emit a label for @p Symbol into the current section.
///
/// This corresponds to an assembler statement such as:
/// foo:
///
/// @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);
virtual void EmitDebugLabel(MCSymbol *Symbol);
virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
MCSymbol *EHSymbol);
/// EmitAssemblerFlag - Note in the output the specified @p Flag.
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0;
/// EmitLinkerOptions - Emit the given list @p Options of strings as linker
/// options into the output.
virtual void EmitLinkerOptions(ArrayRef<std::string> Kind) {}
/// EmitDataRegion - Note in the output the specified region @p Kind.
virtual void EmitDataRegion(MCDataRegionType Kind) {}
/// EmitThumbFunc - Note in the output that the specified @p Func is
/// a Thumb mode function (ARM target only).
virtual void EmitThumbFunc(MCSymbol *Func) = 0;
/// getOrCreateSymbolData - Get symbol data for given symbol.
virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol);
/// EmitAssignment - Emit an assignment of @p Value to @p Symbol.
///
/// This corresponds to an assembler statement such as:
/// symbol = value
///
/// The assignment generates no code, but has the side effect of binding the
/// value in the current context. For the assembly streamer, this prints the
/// binding into the .s file.
///
/// @param Symbol - The symbol being assigned to.
/// @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;
/// EmitSymbolDesc - Set the @p DescValue for the @p Symbol.
///
/// @param Symbol - The symbol to have its n_desc field set.
/// @param DescValue - The value to set into the n_desc field.
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) = 0;
/// BeginCOFFSymbolDef - Start emitting COFF symbol definition
///
/// @param Symbol - The symbol to have its External & Type fields set.
virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) = 0;
/// EmitCOFFSymbolStorageClass - Emit the storage class of the symbol.
///
/// @param StorageClass - The storage class the symbol should have.
virtual void EmitCOFFSymbolStorageClass(int StorageClass) = 0;
/// EmitCOFFSymbolType - Emit the type of the symbol.
///
/// @param Type - A COFF type identifier (see COFF::SymbolType in X86COFF.h)
virtual void EmitCOFFSymbolType(int Type) = 0;
/// EndCOFFSymbolDef - Marks the end of the symbol definition.
virtual void EndCOFFSymbolDef() = 0;
/// EmitCOFFSecRel32 - Emits a COFF section relative relocation.
///
/// @param Symbol - Symbol the section relative realocation should point to.
virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
/// EmitELFSize - Emit an ELF .size directive.
///
/// This corresponds to an assembler statement such as:
/// .size symbol, expression
///
virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) = 0;
/// EmitCommonSymbol - Emit a common symbol.
///
/// @param Symbol - The common symbol to emit.
/// @param Size - The size of the common symbol.
/// @param ByteAlignment - The alignment of the symbol if
/// non-zero. This must be a power of 2.
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) = 0;
/// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
///
/// @param Symbol - The common symbol to emit.
/// @param Size - The size of the common symbol.
/// @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
/// @param Symbol - The zerofill symbol to emit, if non-NULL.
/// @param Size - The size of the zerofill symbol.
/// @param ByteAlignment - The alignment of the zerofill symbol if
/// non-zero. This must be a power of 2 on some targets.
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
uint64_t Size = 0,unsigned ByteAlignment = 0) = 0;
/// EmitTBSSSymbol - Emit a thread local bss (.tbss) symbol.
///
/// @param Section - The thread local common section.
/// @param Symbol - The thread local common symbol to emit.
/// @param Size - The size of the symbol.
/// @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;
/// @}
/// @name Generating Data
/// @{
/// EmitBytes - Emit the bytes in \p Data into the output.
///
/// This is used to implement assembler directives such as .byte, .ascii,
/// etc.
virtual void EmitBytes(StringRef Data, unsigned AddrSpace = 0) = 0;
/// EmitValue - Emit the expression @p Value into the output as a native
/// integer of the given @p Size bytes.
///
/// This is used to implement assembler directives such as .word, .quad,
/// etc.
///
/// @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 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 Padding = 0,
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.
void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
unsigned AddrSpace = 0);
/// EmitGPRel64Value - Emit the expression @p Value into the output as a
/// gprel64 (64-bit GP relative) value.
///
/// This is used to implement assembler directives such as .gpdword on
/// targets that support them.
virtual void EmitGPRel64Value(const MCExpr *Value);
/// 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);
/// 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 = 0);
/// EmitZeros - Emit NumBytes worth of zeros. This is a convenience
/// function that just wraps EmitFill.
void EmitZeros(uint64_t NumBytes, unsigned AddrSpace = 0) {
EmitFill(NumBytes, 0, AddrSpace);
}
/// EmitValueToAlignment - Emit some number of copies of @p Value until
/// the byte alignment @p ByteAlignment is reached.
///
/// If the number of bytes need to emit for the alignment is not a multiple
/// of @p ValueSize, then the contents of the emitted fill bytes is
/// undefined.
///
/// This used to implement the .align assembler directive.
///
/// @param ByteAlignment - The alignment to reach. This must be a power of
/// two on some targets.
/// @param Value - The value to use when filling bytes.
/// @param ValueSize - The size of the integer (in bytes) to emit for
/// @p Value. This must match a native machine width.
/// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
/// the alignment cannot be reached in this many bytes, no bytes are
/// emitted.
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0) = 0;
/// EmitCodeAlignment - Emit nops until the byte alignment @p ByteAlignment
/// is reached.
///
/// This used to align code where the alignment bytes may be executed. This
/// can emit different bytes for different sizes to optimize execution.
///
/// @param ByteAlignment - The alignment to reach. This must be a power of
/// two on some targets.
/// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
/// the alignment cannot be reached in this many bytes, no bytes are
/// emitted.
virtual void EmitCodeAlignment(unsigned ByteAlignment,
unsigned MaxBytesToEmit = 0) = 0;
/// EmitValueToOffset - Emit some number of copies of @p Value until the
/// byte offset @p Offset is reached.
///
/// This is used to implement assembler directives such as .org.
///
/// @param Offset - The offset to reach. This may be an expression, but the
/// expression must be associated with the current section.
/// @param Value - The value to use when filling bytes.
/// @return false on success, true if the offset was invalid.
virtual bool 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 bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename, unsigned CUID = 0);
/// 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);
void EmitCFIStartProc();
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 EmitCFIRestore(int64_t Register);
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
virtual void EmitCFIEscape(StringRef Values);
virtual void EmitCFISignalFrame();
virtual void EmitCFIUndefined(int64_t Register);
virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
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.
virtual void EmitInstruction(const MCInst &Inst) = 0;
/// \brief Set the bundle alignment mode from now on in the section.
/// The argument is the power of 2 to which the alignment is set. The
/// value 0 means turn the bundle alignment off.
virtual void EmitBundleAlignMode(unsigned AlignPow2) = 0;
/// \brief The following instructions are a bundle-locked group.
///
/// \param AlignToEnd - If true, the bundle-locked group will be aligned to
/// the end of a bundle.
virtual void EmitBundleLock(bool AlignToEnd) = 0;
/// \brief Ends a bundle-locked group.
virtual void EmitBundleUnlock() = 0;
/// EmitRawText - If this file is backed by a assembly streamer, this dumps
/// the specified string in the output .s file. This capability is
/// 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);
/// PPC-related methods.
/// FIXME: Eventually replace it with some "target MC streamer" and move
/// these methods there.
virtual void EmitTCEntry(const MCSymbol &S);
/// FinishImpl - Streamer specific finalization.
virtual void FinishImpl() = 0;
/// Finish - Finish emission of machine code.
void Finish();
};
/// createNullStreamer - Create a dummy machine code streamer, which does
/// nothing. This is useful for timing the assembler front end.
MCStreamer *createNullStreamer(MCContext &Ctx);
/// createAsmStreamer - Create a machine code streamer which will print out
/// assembly for the native target, suitable for compiling with a native
/// assembler.
///
/// \param InstPrint - If given, the instruction printer to use. If not given
/// the MCInst representation will be printed. This method takes ownership of
/// InstPrint.
///
/// \param CE - If given, a code emitter to use to show the instruction
/// encoding inline with the assembly. This method takes ownership of \p 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 \p TAB.
///
/// \param ShowInst - Whether to show the MCInst representation inline with
/// the assembly.
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
bool isVerboseAsm,
bool useLoc,
bool useCFI,
bool useDwarfDirectory,
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 \p TAB and \p CE.
MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *CE,
bool RelaxAll = false);
/// createWinCOFFStreamer - Create a machine code streamer which will
/// generate Microsoft COFF format object files.
///
/// Takes ownership of \p TAB and \p CE.
MCStreamer *createWinCOFFStreamer(MCContext &Ctx,
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);
/// createPureStreamer - Create a machine code streamer which will generate
/// "pure" MC object files, for use with MC-JIT and testing tools.
///
/// Takes ownership of \p TAB and \p CE.
MCStreamer *createPureStreamer(MCContext &Ctx, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *CE);
} // end namespace llvm
#endif

View File

@@ -0,0 +1,139 @@
//==-- 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/MCInstrItineraries.h"
#include "llvm/MC/SubtargetFeature.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
// Scheduler machine model
const SubtargetInfoKV *ProcSchedModels;
const MCWriteProcResEntry *WriteProcResTable;
const MCWriteLatencyEntry *WriteLatencyTable;
const MCReadAdvanceEntry *ReadAdvanceTable;
const MCSchedModel *CPUSchedModel;
const InstrStage *Stages; // Instruction itinerary stages
const unsigned *OperandCycles; // Itinerary operand cycles
const unsigned *ForwardingPaths; // Forwarding paths
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 *ProcSched,
const MCWriteProcResEntry *WPR,
const MCWriteLatencyEntry *WL,
const MCReadAdvanceEntry *RA,
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;
}
/// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with
/// feature string). Recompute feature bits and scheduling model.
void InitMCProcessorInfo(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);
/// getSchedModelForCPU - Get the machine model of a CPU.
///
const MCSchedModel *getSchedModelForCPU(StringRef CPU) const;
/// getSchedModel - Get the machine model for this subtarget's CPU.
///
const MCSchedModel *getSchedModel() const { return CPUSchedModel; }
/// Return an iterator at the first process resource consumed by the given
/// scheduling class.
const MCWriteProcResEntry *getWriteProcResBegin(
const MCSchedClassDesc *SC) const {
return &WriteProcResTable[SC->WriteProcResIdx];
}
const MCWriteProcResEntry *getWriteProcResEnd(
const MCSchedClassDesc *SC) const {
return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
}
const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
unsigned DefIdx) const {
assert(DefIdx < SC->NumWriteLatencyEntries &&
"MachineModel does not specify a WriteResource for DefIdx");
return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
}
int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
unsigned WriteResID) const {
// TODO: The number of read advance entries in a class can be significant
// (~50). Consider compressing the WriteID into a dense ID of those that are
// used by ReadAdvance and representing them as a bitset.
for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
*E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
if (I->UseIdx < UseIdx)
continue;
if (I->UseIdx > UseIdx)
break;
// Find the first WriteResIdx match, which has the highest cycle count.
if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
return I->Cycles;
}
}
return 0;
}
/// getInstrItineraryForCPU - Get scheduling itinerary of a CPU.
///
InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
/// Initialize an InstrItineraryData instance.
void initInstrItins(InstrItineraryData &InstrItins) const;
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,165 @@
//===- MCSymbol.h - Machine Code Symbols ------------------------*- 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 MCSymbol class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSYMBOL_H
#define LLVM_MC_MCSYMBOL_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
class MCExpr;
class MCSection;
class MCContext;
class raw_ostream;
/// MCSymbol - Instances of this class represent a symbol name in the MC file,
/// and MCSymbols are created and unique'd by the MCContext class. MCSymbols
/// should only be constructed with valid names for the object file.
///
/// If the symbol is defined/emitted into the current translation unit, the
/// Section member is set to indicate what section it lives in. Otherwise, if
/// it is a reference to an external entity, it has a null section.
class MCSymbol {
// Special sentinal value for the absolute pseudo section.
//
// FIXME: Use a PointerInt wrapper for this?
static const MCSection *AbsolutePseudoSection;
/// Name - The name of the symbol. The referred-to string data is actually
/// held by the StringMap that lives in MCContext.
StringRef Name;
/// Section - The section the symbol is defined in. This is null for
/// undefined symbols, and the special AbsolutePseudoSection value for
/// absolute symbols.
const MCSection *Section;
/// Value - If non-null, the value for a variable symbol.
const MCExpr *Value;
/// IsTemporary - True if this is an assembler temporary label, which
/// typically does not survive in the .o file's symbol table. Usually
/// "Lfoo" or ".foo".
unsigned IsTemporary : 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), IsUsed(false) {}
MCSymbol(const MCSymbol&) LLVM_DELETED_FUNCTION;
void operator=(const MCSymbol&) LLVM_DELETED_FUNCTION;
public:
/// getName - Get the symbol name.
StringRef getName() const { return Name; }
/// @name Accessors
/// @{
/// isTemporary - Check if this is an assembler temporary symbol.
bool isTemporary() const { return IsTemporary; }
/// isUsed - Check if this is used.
bool isUsed() const { return IsUsed; }
void setUsed(bool Value) const { IsUsed = Value; }
/// @}
/// @name Associated Sections
/// @{
/// isDefined - Check if this symbol is defined (i.e., it has an address).
///
/// Defined symbols are either absolute or in some section.
bool isDefined() const {
return Section != 0;
}
/// isInSection - Check if this symbol is defined in some section (i.e., it
/// is defined but not absolute).
bool isInSection() const {
return isDefined() && !isAbsolute();
}
/// isUndefined - Check if this symbol undefined (i.e., implicitly defined).
bool isUndefined() const {
return !isDefined();
}
/// isAbsolute - Check if this is an absolute symbol.
bool isAbsolute() const {
return Section == AbsolutePseudoSection;
}
/// getSection - Get the section associated with a defined, non-absolute
/// symbol.
const MCSection &getSection() const {
assert(isInSection() && "Invalid accessor!");
return *Section;
}
/// setSection - Mark the symbol as defined in the section \p S.
void setSection(const MCSection &S) { Section = &S; }
/// setUndefined - Mark the symbol as undefined.
void setUndefined() {
Section = 0;
}
/// setAbsolute - Mark the symbol as absolute.
void setAbsolute() { Section = AbsolutePseudoSection; }
/// @}
/// @name Variable Symbols
/// @{
/// isVariable - Check if this is a variable symbol.
bool isVariable() const {
return Value != 0;
}
/// getVariableValue() - 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);
/// @}
/// print - Print the value to the stream \p OS.
void print(raw_ostream &OS) const;
/// dump - Print the value to stderr.
void dump() const;
};
inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) {
Sym.print(OS);
return OS;
}
} // end namespace llvm
#endif

View File

@@ -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 &) LLVM_DELETED_FUNCTION;
void operator=(const MCTargetAsmLexer &) LLVM_DELETED_FUNCTION;
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 \p 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 \p K.
bool is(AsmToken::TokenKind K) const { return CurTok.is(K); }
/// isNot - Check if the current token has kind \p K.
bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); }
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,181 @@
//===-- 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;
enum AsmRewriteKind {
AOK_Delete = 0, // Rewrite should be ignored.
AOK_Align, // Rewrite align as .align.
AOK_DotOperator, // Rewrite a dot operator expression as an immediate.
// E.g., [eax].foo.bar -> [eax].8
AOK_Emit, // Rewrite _emit as .byte.
AOK_Imm, // Rewrite as $$N.
AOK_ImmPrefix, // Add $$ before a parsed Imm.
AOK_Input, // Rewrite in terms of $N.
AOK_Output, // Rewrite in terms of $N.
AOK_SizeDirective, // Add a sizing directive (e.g., dword ptr).
AOK_Skip // Skip emission (e.g., offset/type operators).
};
const char AsmRewritePrecedence [] = {
0, // AOK_Delete
1, // AOK_Align
1, // AOK_DotOperator
1, // AOK_Emit
3, // AOK_Imm
3, // AOK_ImmPrefix
2, // AOK_Input
2, // AOK_Output
4, // AOK_SizeDirective
1 // AOK_Skip
};
struct AsmRewrite {
AsmRewriteKind Kind;
SMLoc Loc;
unsigned Len;
unsigned Val;
public:
AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len = 0, unsigned val = 0)
: Kind(kind), Loc(loc), Len(len), Val(val) {}
};
struct ParseInstructionInfo {
SmallVectorImpl<AsmRewrite> *AsmRewrites;
ParseInstructionInfo() : AsmRewrites(0) {}
ParseInstructionInfo(SmallVectorImpl<AsmRewrite> *rewrites)
: AsmRewrites(rewrites) {}
~ParseInstructionInfo() {}
};
/// MCTargetAsmParser - Generic interface to target specific assembly parsers.
class MCTargetAsmParser : public MCAsmParserExtension {
public:
enum MatchResultTy {
Match_InvalidOperand,
Match_MissingFeature,
Match_MnemonicFail,
Match_Success,
FIRST_TARGET_MATCH_RESULT_TY
};
private:
MCTargetAsmParser(const MCTargetAsmParser &) LLVM_DELETED_FUNCTION;
void operator=(const MCTargetAsmParser &) LLVM_DELETED_FUNCTION;
protected: // Can only create subclasses.
MCTargetAsmParser();
/// AvailableFeatures - The current set of available features.
unsigned AvailableFeatures;
/// ParsingInlineAsm - Are we parsing ms-style inline assembly?
bool ParsingInlineAsm;
/// SemaCallback - The Sema callback implementation. Must be set when parsing
/// ms-style inline assembly.
MCAsmParserSemaCallback *SemaCallback;
public:
virtual ~MCTargetAsmParser();
unsigned getAvailableFeatures() const { return AvailableFeatures; }
void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
bool isParsingInlineAsm () { return ParsingInlineAsm; }
void setParsingInlineAsm (bool Value) { ParsingInlineAsm = Value; }
void setSemaCallback(MCAsmParserSemaCallback *Callback) {
SemaCallback = Callback;
}
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(ParseInstructionInfo &Info, 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;
/// mnemonicIsValid - This returns true if this is a valid mnemonic and false
/// otherwise.
virtual bool mnemonicIsValid(StringRef Mnemonic) = 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, unsigned &Opcode,
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCStreamer &Out, unsigned &ErrorInfo,
bool MatchingInlineAsm) = 0;
/// Allow a target to add special case operand matching for things that
/// tblgen doesn't/can't handle effectively. For example, literal
/// immediates on ARM. TableGen expects a token operand, but the parser
/// will recognize them as immediates.
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op,
unsigned Kind) {
return Match_InvalidOperand;
}
/// checkTargetMatchPredicate - Validate the instruction match against
/// any complex target predicates not expressible via match classes.
virtual unsigned checkTargetMatchPredicate(MCInst &Inst) {
return Match_Success;
}
virtual void convertToMapAndConstraints(unsigned Kind,
const SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,77 @@
//===-- llvm/MC/MCValue.h - MCValue 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 MCValue class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCVALUE_H
#define LLVM_MC_MCVALUE_H
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
class MCAsmInfo;
class MCSymbol;
class MCSymbolRefExpr;
class raw_ostream;
/// MCValue - This represents an "assembler immediate". In its most general
/// form, this can hold "SymbolA - SymbolB + imm64". Not all targets supports
/// relocations of this general form, but we need to represent this anyway.
///
/// In the general form, SymbolB can only be defined if SymbolA is, and both
/// must be in the same (non-external) section. The latter constraint is not
/// enforced, since a symbol's section may not be known at construction.
///
/// Note that this class must remain a simple POD value class, because we need
/// it to live in unions etc.
class MCValue {
const MCSymbolRefExpr *SymA, *SymB;
int64_t Cst;
public:
int64_t getConstant() const { return Cst; }
const MCSymbolRefExpr *getSymA() const { return SymA; }
const MCSymbolRefExpr *getSymB() const { return SymB; }
/// isAbsolute - Is this an absolute (as opposed to relocatable) value.
bool isAbsolute() const { return !SymA && !SymB; }
/// print - Print the value to the stream \p OS.
void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
/// dump - Print the value to stderr.
void dump() const;
static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=0,
int64_t Val = 0) {
MCValue R;
assert((!SymB || SymA) && "Invalid relocatable MCValue!");
R.Cst = Val;
R.SymA = SymA;
R.SymB = SymB;
return R;
}
static MCValue get(int64_t Val) {
MCValue R;
R.Cst = Val;
R.SymA = 0;
R.SymB = 0;
return R;
}
};
} // end namespace llvm
#endif

View File

@@ -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

View File

@@ -0,0 +1,43 @@
//===-- llvm/MC/MCWinCOFFObjectWriter.h - Win COFF 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_MCWINCOFFOBJECTWRITER_H
#define LLVM_MC_MCWINCOFFOBJECTWRITER_H
namespace llvm {
class MCFixup;
class MCObjectWriter;
class MCValue;
class raw_ostream;
class MCWinCOFFObjectTargetWriter {
const unsigned Machine;
protected:
MCWinCOFFObjectTargetWriter(unsigned Machine_);
public:
virtual ~MCWinCOFFObjectTargetWriter() {}
unsigned getMachine() const { return Machine; }
virtual unsigned getRelocType(const MCValue &Target,
const MCFixup &Fixup,
bool IsCrossSection) const = 0;
};
/// \brief Construct a new Win COFF writer instance.
///
/// \param MOTW - The target specific WinCOFF writer subclass.
/// \param OS - The stream to write to.
/// \returns The constructed object writer.
MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
raw_ostream &OS);
} // End llvm namespace
#endif

View File

@@ -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

View File

@@ -0,0 +1,240 @@
//===-- llvm/Target/TargetLoweringObjectFile.h - Object 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 implements classes used to handle lowerings specific to common
// object file formats.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_SECTIONKIND_H
#define LLVM_MC_SECTIONKIND_H
namespace llvm {
/// SectionKind - This is a simple POD value that classifies the properties of
/// a section. A section is classified into the deepest possible
/// classification, and then the target maps them onto their sections based on
/// what capabilities they have.
///
/// The comments below describe these as if they were an inheritance hierarchy
/// in order to explain the predicates below.
///
class SectionKind {
enum Kind {
/// Metadata - Debug info sections or other metadata.
Metadata,
/// Text - Text section, used for functions and other executable code.
Text,
/// ReadOnly - Data that is never written to at program runtime by the
/// program or the dynamic linker. Things in the top-level readonly
/// SectionKind are not mergeable.
ReadOnly,
/// MergableCString - Any null-terminated string which allows merging.
/// These values are known to end in a nul value of the specified size,
/// not otherwise contain a nul value, and be mergable. This allows the
/// linker to unique the strings if it so desires.
/// Mergeable1ByteCString - 1 byte mergable, null terminated, string.
Mergeable1ByteCString,
/// Mergeable2ByteCString - 2 byte mergable, null terminated, string.
Mergeable2ByteCString,
/// Mergeable4ByteCString - 4 byte mergable, null terminated, string.
Mergeable4ByteCString,
/// MergeableConst - These are sections for merging fixed-length
/// constants together. For example, this can be used to unique
/// constant pool entries etc.
MergeableConst,
/// MergeableConst4 - This is a section used by 4-byte constants,
/// for example, floats.
MergeableConst4,
/// MergeableConst8 - This is a section used by 8-byte constants,
/// for example, doubles.
MergeableConst8,
/// MergeableConst16 - This is a section used by 16-byte constants,
/// for example, vectors.
MergeableConst16,
/// Writeable - This is the base of all segments that need to be written
/// to during program runtime.
/// ThreadLocal - This is the base of all TLS segments. All TLS
/// objects must be writeable, otherwise there is no reason for them to
/// be thread local!
/// ThreadBSS - Zero-initialized TLS data objects.
ThreadBSS,
/// ThreadData - Initialized TLS data objects.
ThreadData,
/// GlobalWriteableData - Writeable data that is global (not thread
/// local).
/// BSS - Zero initialized writeable data.
BSS,
/// BSSLocal - This is BSS (zero initialized and writable) data
/// which has local linkage.
BSSLocal,
/// BSSExtern - This is BSS data with normal external linkage.
BSSExtern,
/// Common - Data with common linkage. These represent tentative
/// definitions, which always have a zero initializer and are never
/// marked 'constant'.
Common,
/// DataRel - This is the most general form of data that is written
/// to by the program, it can have random relocations to arbitrary
/// globals.
DataRel,
/// DataRelLocal - This is writeable data that has a non-zero
/// initializer and has relocations in it, but all of the
/// relocations are known to be within the final linked image
/// the global is linked into.
DataRelLocal,
/// DataNoRel - This is writeable data that has a non-zero
/// initializer, but whose initializer is known to have no
/// relocations.
DataNoRel,
/// ReadOnlyWithRel - These are global variables that are never
/// written to by the program, but that have relocations, so they
/// must be stuck in a writeable section so that the dynamic linker
/// can write to them. If it chooses to, the dynamic linker can
/// mark the pages these globals end up on as read-only after it is
/// done with its relocation phase.
ReadOnlyWithRel,
/// ReadOnlyWithRelLocal - This is data that is readonly by the
/// program, but must be writeable so that the dynamic linker
/// can perform relocations in it. This is used when we know
/// that all the relocations are to globals in this final
/// linked image.
ReadOnlyWithRelLocal
} K : 8;
public:
bool isMetadata() const { return K == Metadata; }
bool isText() const { return K == Text; }
bool isReadOnly() const {
return K == ReadOnly || isMergeableCString() ||
isMergeableConst();
}
bool isMergeableCString() const {
return K == Mergeable1ByteCString || K == Mergeable2ByteCString ||
K == Mergeable4ByteCString;
}
bool isMergeable1ByteCString() const { return K == Mergeable1ByteCString; }
bool isMergeable2ByteCString() const { return K == Mergeable2ByteCString; }
bool isMergeable4ByteCString() const { return K == Mergeable4ByteCString; }
bool isMergeableConst() const {
return K == MergeableConst || K == MergeableConst4 ||
K == MergeableConst8 || K == MergeableConst16;
}
bool isMergeableConst4() const { return K == MergeableConst4; }
bool isMergeableConst8() const { return K == MergeableConst8; }
bool isMergeableConst16() const { return K == MergeableConst16; }
bool isWriteable() const {
return isThreadLocal() || isGlobalWriteableData();
}
bool isThreadLocal() const {
return K == ThreadData || K == ThreadBSS;
}
bool isThreadBSS() const { return K == ThreadBSS; }
bool isThreadData() const { return K == ThreadData; }
bool isGlobalWriteableData() const {
return isBSS() || isCommon() || isDataRel() || isReadOnlyWithRel();
}
bool isBSS() const { return K == BSS || K == BSSLocal || K == BSSExtern; }
bool isBSSLocal() const { return K == BSSLocal; }
bool isBSSExtern() const { return K == BSSExtern; }
bool isCommon() const { return K == Common; }
bool isDataRel() const {
return K == DataRel || K == DataRelLocal || K == DataNoRel;
}
bool isDataRelLocal() const {
return K == DataRelLocal || K == DataNoRel;
}
bool isDataNoRel() const { return K == DataNoRel; }
bool isReadOnlyWithRel() const {
return K == ReadOnlyWithRel || K == ReadOnlyWithRelLocal;
}
bool isReadOnlyWithRelLocal() const {
return K == ReadOnlyWithRelLocal;
}
private:
static SectionKind get(Kind K) {
SectionKind Res;
Res.K = K;
return Res;
}
public:
static SectionKind getMetadata() { return get(Metadata); }
static SectionKind getText() { return get(Text); }
static SectionKind getReadOnly() { return get(ReadOnly); }
static SectionKind getMergeable1ByteCString() {
return get(Mergeable1ByteCString);
}
static SectionKind getMergeable2ByteCString() {
return get(Mergeable2ByteCString);
}
static SectionKind getMergeable4ByteCString() {
return get(Mergeable4ByteCString);
}
static SectionKind getMergeableConst() { return get(MergeableConst); }
static SectionKind getMergeableConst4() { return get(MergeableConst4); }
static SectionKind getMergeableConst8() { return get(MergeableConst8); }
static SectionKind getMergeableConst16() { return get(MergeableConst16); }
static SectionKind getThreadBSS() { return get(ThreadBSS); }
static SectionKind getThreadData() { return get(ThreadData); }
static SectionKind getBSS() { return get(BSS); }
static SectionKind getBSSLocal() { return get(BSSLocal); }
static SectionKind getBSSExtern() { return get(BSSExtern); }
static SectionKind getCommon() { return get(Common); }
static SectionKind getDataRel() { return get(DataRel); }
static SectionKind getDataRelLocal() { return get(DataRelLocal); }
static SectionKind getDataNoRel() { return get(DataNoRel); }
static SectionKind getReadOnlyWithRel() { return get(ReadOnlyWithRel); }
static SectionKind getReadOnlyWithRelLocal(){
return get(ReadOnlyWithRelLocal);
}
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,109 @@
//===-- 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 "llvm/ADT/Triple.h"
#include "llvm/Support/DataTypes.h"
#include <vector>
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
const 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
/// "+attr1,+attr2,-attr3,...,+attrN"
/// A comma separates each feature from the next (all lowercase.)
/// 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);
/// 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