summaryrefslogtreecommitdiff
path: root/include/llvm/MC
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2014-11-24 09:08:18 +0000
committerDimitry Andric <dim@FreeBSD.org>2014-11-24 09:08:18 +0000
commit5ca98fd98791947eba83a1ed3f2c8191ef7afa6c (patch)
treef5944309621cee4fe0976be6f9ac619b7ebfc4c2 /include/llvm/MC
parent68bcb7db193e4bc81430063148253d30a791023e (diff)
Notes
Diffstat (limited to 'include/llvm/MC')
-rw-r--r--include/llvm/MC/ConstantPools.h92
-rw-r--r--include/llvm/MC/MCAnalysis/MCAtom.h (renamed from include/llvm/MC/MCAtom.h)14
-rw-r--r--include/llvm/MC/MCAnalysis/MCFunction.h (renamed from include/llvm/MC/MCFunction.h)18
-rw-r--r--include/llvm/MC/MCAnalysis/MCModule.h (renamed from include/llvm/MC/MCModule.h)11
-rw-r--r--include/llvm/MC/MCAnalysis/MCModuleYAML.h (renamed from include/llvm/MC/MCModuleYAML.h)9
-rw-r--r--include/llvm/MC/MCAsmBackend.h21
-rw-r--r--include/llvm/MC/MCAsmInfo.h996
-rw-r--r--include/llvm/MC/MCAsmInfoCOFF.h4
-rw-r--r--include/llvm/MC/MCAsmLayout.h8
-rw-r--r--include/llvm/MC/MCAssembler.h186
-rw-r--r--include/llvm/MC/MCCodeEmitter.h4
-rw-r--r--include/llvm/MC/MCContext.h167
-rw-r--r--include/llvm/MC/MCDirectives.h5
-rw-r--r--include/llvm/MC/MCDisassembler.h42
-rw-r--r--include/llvm/MC/MCDwarf.h162
-rw-r--r--include/llvm/MC/MCELF.h4
-rw-r--r--include/llvm/MC/MCELFObjectWriter.h48
-rw-r--r--include/llvm/MC/MCELFStreamer.h95
-rw-r--r--include/llvm/MC/MCELFSymbolFlags.h14
-rw-r--r--include/llvm/MC/MCExpr.h52
-rw-r--r--include/llvm/MC/MCExternalSymbolizer.h20
-rw-r--r--include/llvm/MC/MCFixup.h1
-rw-r--r--include/llvm/MC/MCInst.h8
-rw-r--r--include/llvm/MC/MCInstPrinter.h5
-rw-r--r--include/llvm/MC/MCInstrAnalysis.h7
-rw-r--r--include/llvm/MC/MCInstrDesc.h6
-rw-r--r--include/llvm/MC/MCInstrItineraries.h6
-rw-r--r--include/llvm/MC/MCLinkerOptimizationHint.h205
-rw-r--r--include/llvm/MC/MCMachObjectWriter.h31
-rw-r--r--include/llvm/MC/MCObjectDisassembler.h17
-rw-r--r--include/llvm/MC/MCObjectFileInfo.h48
-rw-r--r--include/llvm/MC/MCObjectStreamer.h110
-rw-r--r--include/llvm/MC/MCObjectSymbolizer.h12
-rw-r--r--include/llvm/MC/MCObjectWriter.h1
-rw-r--r--include/llvm/MC/MCParser/AsmLexer.h10
-rw-r--r--include/llvm/MC/MCParser/MCAsmLexer.h21
-rw-r--r--include/llvm/MC/MCParser/MCAsmParser.h36
-rw-r--r--include/llvm/MC/MCParser/MCParsedAsmOperand.h2
-rw-r--r--include/llvm/MC/MCRegisterInfo.h8
-rw-r--r--include/llvm/MC/MCSchedule.h50
-rw-r--r--include/llvm/MC/MCSectionCOFF.h32
-rw-r--r--include/llvm/MC/MCSectionELF.h28
-rw-r--r--include/llvm/MC/MCSectionMachO.h112
-rw-r--r--include/llvm/MC/MCStreamer.h356
-rw-r--r--include/llvm/MC/MCSubtargetInfo.h13
-rw-r--r--include/llvm/MC/MCSymbol.h10
-rw-r--r--include/llvm/MC/MCSymbolizer.h10
-rw-r--r--include/llvm/MC/MCTargetAsmParser.h41
-rw-r--r--include/llvm/MC/MCTargetOptions.h56
-rw-r--r--include/llvm/MC/MCTargetOptionsCommandFlags.h53
-rw-r--r--include/llvm/MC/MCValue.h31
-rw-r--r--include/llvm/MC/MCWin64EH.h84
-rw-r--r--include/llvm/MC/MCWinCOFFObjectWriter.h1
-rw-r--r--include/llvm/MC/MCWinCOFFStreamer.h74
-rw-r--r--include/llvm/MC/MCWinEH.h29
-rw-r--r--include/llvm/MC/MachineLocation.h7
-rw-r--r--include/llvm/MC/StringTableBuilder.h59
-rw-r--r--include/llvm/MC/SubtargetFeature.h13
-rw-r--r--include/llvm/MC/YAML.h94
59 files changed, 2200 insertions, 1459 deletions
diff --git a/include/llvm/MC/ConstantPools.h b/include/llvm/MC/ConstantPools.h
new file mode 100644
index 000000000000..2e76074db774
--- /dev/null
+++ b/include/llvm/MC/ConstantPools.h
@@ -0,0 +1,92 @@
+//===- ConstantPool.h - Keep track of assembler-generated ------*- 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 ConstantPool and AssemblerConstantPools classes.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_MC_CONSTANTPOOL_H
+#define LLVM_MC_CONSTANTPOOL_H
+
+#include "llvm/ADT/SmallVector.h"
+namespace llvm {
+class MCContext;
+class MCExpr;
+class MCSection;
+class MCStreamer;
+class MCSymbol;
+
+struct ConstantPoolEntry {
+ ConstantPoolEntry(MCSymbol *L, const MCExpr *Val, unsigned Sz)
+ : Label(L), Value(Val), Size(Sz) {}
+ MCSymbol *Label;
+ const MCExpr *Value;
+ unsigned Size;
+};
+
+// A class to keep track of assembler-generated constant pools that are use to
+// implement the ldr-pseudo.
+class ConstantPool {
+ typedef SmallVector<ConstantPoolEntry, 4> EntryVecTy;
+ EntryVecTy Entries;
+
+public:
+ // Initialize a new empty constant pool
+ ConstantPool() {}
+
+ // Add a new entry to the constant pool in the next slot.
+ // \param Value is the new entry to put in the constant pool.
+ // \param Size is the size in bytes of the entry
+ //
+ // \returns a MCExpr that references the newly inserted value
+ const MCExpr *addEntry(const MCExpr *Value, MCContext &Context,
+ unsigned Size);
+
+ // Emit the contents of the constant pool using the provided streamer.
+ void emitEntries(MCStreamer &Streamer);
+
+ // Return true if the constant pool is empty
+ bool empty();
+};
+
+class AssemblerConstantPools {
+ // Map type used to keep track of per-Section constant pools used by the
+ // ldr-pseudo opcode. The map associates a section to its constant pool. The
+ // constant pool is a vector of (label, value) pairs. When the ldr
+ // pseudo is parsed we insert a new (label, value) pair into the constant pool
+ // for the current section and add MCSymbolRefExpr to the new label as
+ // an opcode to the ldr. After we have parsed all the user input we
+ // output the (label, value) pairs in each constant pool at the end of the
+ // section.
+ //
+ // We use the MapVector for the map type to ensure stable iteration of
+ // the sections at the end of the parse. We need to iterate over the
+ // sections in a stable order to ensure that we have print the
+ // constant pools in a deterministic order when printing an assembly
+ // file.
+ typedef MapVector<const MCSection *, ConstantPool> ConstantPoolMapTy;
+ ConstantPoolMapTy ConstantPools;
+
+public:
+ AssemblerConstantPools() {}
+ ~AssemblerConstantPools() {}
+
+ void emitAll(MCStreamer &Streamer);
+ void emitForCurrentSection(MCStreamer &Streamer);
+ const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Expr,
+ unsigned Size);
+
+private:
+ ConstantPool *getConstantPool(const MCSection *Section);
+ ConstantPool &getOrCreateConstantPool(const MCSection *Section);
+};
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCAtom.h b/include/llvm/MC/MCAnalysis/MCAtom.h
index eab32d691fa8..33f3431a59a9 100644
--- a/include/llvm/MC/MCAtom.h
+++ b/include/llvm/MC/MCAnalysis/MCAtom.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCAtom.h ----------------------------------------*- C++ -*-===//
+//===-- MCAtom.h ------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCATOM_H
-#define LLVM_MC_MCATOM_H
+#ifndef LLVM_MC_MCANALYSIS_MCATOM_H
+#define LLVM_MC_MCANALYSIS_MCATOM_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/MC/MCInst.h"
@@ -145,8 +145,8 @@ public:
/// \name Atom type specific split/truncate logic.
/// @{
- MCTextAtom *split(uint64_t SplitPt) LLVM_OVERRIDE;
- void truncate(uint64_t TruncPt) LLVM_OVERRIDE;
+ MCTextAtom *split(uint64_t SplitPt) override;
+ void truncate(uint64_t TruncPt) override;
/// @}
// Class hierarchy.
@@ -179,8 +179,8 @@ public:
/// \name Atom type specific split/truncate logic.
/// @{
- MCDataAtom *split(uint64_t SplitPt) LLVM_OVERRIDE;
- void truncate(uint64_t TruncPt) LLVM_OVERRIDE;
+ MCDataAtom *split(uint64_t SplitPt) override;
+ void truncate(uint64_t TruncPt) override;
/// @}
// Class hierarchy.
diff --git a/include/llvm/MC/MCFunction.h b/include/llvm/MC/MCAnalysis/MCFunction.h
index 22c9192ac4b5..44fa4503b8e0 100644
--- a/include/llvm/MC/MCFunction.h
+++ b/include/llvm/MC/MCAnalysis/MCFunction.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCFunction.h ------------------------------------*- C++ -*-===//
+//===-- MCFunction.h --------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,11 +12,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCFUNCTION_H
-#define LLVM_MC_MCFUNCTION_H
+#ifndef LLVM_MC_MCANALYSIS_MCFUNCTION_H
+#define LLVM_MC_MCANALYSIS_MCFUNCTION_H
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCInst.h"
+#include <memory>
#include <string>
#include <vector>
@@ -88,13 +89,12 @@ class MCFunction {
std::string Name;
MCModule *ParentModule;
- typedef std::vector<MCBasicBlock*> BasicBlockListTy;
+ typedef std::vector<std::unique_ptr<MCBasicBlock>> BasicBlockListTy;
BasicBlockListTy Blocks;
// MCModule owns the function.
friend class MCModule;
MCFunction(StringRef Name, MCModule *Parent);
- ~MCFunction();
public:
/// \brief Create an MCBasicBlock backed by Insts and add it to this function.
@@ -126,10 +126,10 @@ public:
const_iterator end() const { return Blocks.end(); }
iterator end() { return Blocks.end(); }
- const MCBasicBlock* front() const { return Blocks.front(); }
- MCBasicBlock* front() { return Blocks.front(); }
- const MCBasicBlock* back() const { return Blocks.back(); }
- MCBasicBlock* back() { return Blocks.back(); }
+ const MCBasicBlock* front() const { return Blocks.front().get(); }
+ MCBasicBlock* front() { return Blocks.front().get(); }
+ const MCBasicBlock* back() const { return Blocks.back().get(); }
+ MCBasicBlock* back() { return Blocks.back().get(); }
/// \brief Find the basic block, if any, that starts at \p StartAddr.
const MCBasicBlock *find(uint64_t StartAddr) const;
diff --git a/include/llvm/MC/MCModule.h b/include/llvm/MC/MCAnalysis/MCModule.h
index 63635c7478ce..cf7e2c0a645e 100644
--- a/include/llvm/MC/MCModule.h
+++ b/include/llvm/MC/MCAnalysis/MCModule.h
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCModule.h - MCModule class ---------------------*- C++ -*-===//
+//===-- MCModule.h - MCModule class -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,12 +12,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCMODULE_H
-#define LLVM_MC_MCMODULE_H
+#ifndef LLVM_MC_MCANALYSIS_MCMODULE_H
+#define LLVM_MC_MCANALYSIS_MCMODULE_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
+#include <memory>
#include <vector>
namespace llvm {
@@ -73,7 +74,7 @@ class MCModule {
/// \name Function tracking
/// @{
- typedef std::vector<MCFunction*> FunctionListTy;
+ typedef std::vector<std::unique_ptr<MCFunction>> FunctionListTy;
FunctionListTy Functions;
/// @}
@@ -87,7 +88,7 @@ class MCModule {
friend class MCObjectDisassembler;
public:
- MCModule() : Entrypoint(0) { }
+ MCModule();
~MCModule();
/// \name Create a new MCAtom covering the specified offset range.
diff --git a/include/llvm/MC/MCModuleYAML.h b/include/llvm/MC/MCAnalysis/MCModuleYAML.h
index 281e3d8dc912..48562777677b 100644
--- a/include/llvm/MC/MCModuleYAML.h
+++ b/include/llvm/MC/MCAnalysis/MCModuleYAML.h
@@ -13,12 +13,11 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCMODULEYAML_H
-#define LLVM_MC_MCMODULEYAML_H
+#ifndef LLVM_MC_MCANALYSIS_MCMODULEYAML_H
+#define LLVM_MC_MCANALYSIS_MCMODULEYAML_H
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/MC/MCModule.h"
+#include "llvm/MC/MCAnalysis/MCModule.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
@@ -33,7 +32,7 @@ StringRef mcmodule2yaml(raw_ostream &OS, const MCModule &MCM,
/// \brief Creates a new module and returns it in \p MCM.
/// \returns The empty string on success, an error message on failure.
-StringRef yaml2mcmodule(OwningPtr<MCModule> &MCM, StringRef YamlContent,
+StringRef yaml2mcmodule(std::unique_ptr<MCModule> &MCM, StringRef YamlContent,
const MCInstrInfo &MII, const MCRegisterInfo &MRI);
} // end namespace llvm
diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h
index f946f41981c8..82b65fdaf5c8 100644
--- a/include/llvm/MC/MCAsmBackend.h
+++ b/include/llvm/MC/MCAsmBackend.h
@@ -38,7 +38,6 @@ class MCAsmBackend {
protected: // Can only create subclasses.
MCAsmBackend();
- unsigned HasReliableSymbolDifference : 1;
unsigned HasDataInCodeSupport : 1;
public:
@@ -58,20 +57,6 @@ public:
"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; }
@@ -105,16 +90,14 @@ public:
virtual void processFixupValue(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFixup &Fixup, const MCFragment *DF,
- MCValue &Target, uint64_t &Value,
+ const 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;
+ uint64_t Value, bool IsPCRel) const = 0;
/// @}
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 9845623d4716..06e473d6b625 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -23,536 +23,496 @@
#include <vector>
namespace llvm {
- class MCExpr;
- class MCSection;
- class MCStreamer;
- class MCSymbol;
- class MCContext;
-
- namespace ExceptionHandling {
- enum ExceptionsType { None, DwarfCFI, SjLj, ARM, Win64 };
- }
+class MCExpr;
+class MCSection;
+class MCStreamer;
+class MCSymbol;
+class MCContext;
+
+namespace WinEH {
+enum class EncodingType {
+ ET_Invalid, /// Invalid
+ ET_Alpha, /// Windows Alpha
+ ET_Alpha64, /// Windows AXP64
+ ET_ARM, /// Windows NT (Windows on ARM)
+ ET_CE, /// Windows CE ARM, PowerPC, SH3, SH4
+ ET_Itanium, /// Windows x64, Windows Itanium (IA-64)
+ ET_MIPS = ET_Alpha,
+};
+}
+
+enum class ExceptionHandling {
+ None, /// No exception support
+ DwarfCFI, /// DWARF-like instruction based exceptions
+ SjLj, /// setjmp/longjmp based exceptions
+ ARM, /// ARM EHABI
+ WinEH, /// Windows Exception Handling
+};
+
+namespace LCOMM {
+enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment };
+}
+
+/// 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.
+ //
+
+ /// Pointer size in bytes. Default is 4.
+ unsigned PointerSize;
+
+ /// Size of the stack slot reserved for callee-saved registers, in bytes.
+ /// Default is same as pointer size.
+ unsigned CalleeSaveStackSlotSize;
+
+ /// True if target is little endian. Default is true.
+ bool IsLittleEndian;
+
+ /// True if target stack grow up. Default is false.
+ bool StackGrowsUp;
+
+ /// True if this target has the MachO .subsections_via_symbols directive.
+ /// Default is false.
+ bool HasSubsectionsViaSymbols;
+
+ /// True if this is a MachO target that supports the macho-specific .zerofill
+ /// directive for emitting BSS Symbols. Default is false.
+ bool HasMachoZeroFillDirective;
+
+ /// True if this is a MachO target that supports the macho-specific .tbss
+ /// directive for emitting thread local BSS Symbols. Default is false.
+ bool HasMachoTBSSDirective;
+
+ /// 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. Default
+ /// is false.
+ bool HasStaticCtorDtorReferenceInStaticMode;
+
+ /// 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. Default to false.
+ bool LinkerRequiresNonEmptyDwarfLines;
+
+ /// This is the maximum possible length of an instruction, which is needed to
+ /// compute the size of an inline asm. Defaults to 4.
+ unsigned MaxInstLength;
+
+ /// Every possible instruction length is a multiple of this value. Factored
+ /// out in .debug_frame and .debug_line. Defaults to 1.
+ unsigned MinInstAlignment;
+
+ /// The '$' token, when not referencing an identifier or constant, refers to
+ /// the current PC. Defaults to false.
+ bool DollarIsPC;
+
+ /// This string, if specified, is used to separate instructions from each
+ /// other when on the same line. Defaults to ';'
+ const char *SeparatorString;
+
+ /// This indicates the comment character used by the assembler. Defaults to
+ /// "#"
+ const char *CommentString;
+
+ /// This is appended to emitted labels. Defaults to ":"
+ const char *LabelSuffix;
+
+ // Print the EH begin symbol with an assignment. Defaults to false.
+ bool UseAssignmentForEHBegin;
+
+ /// 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. Defaults to "L"
+ const char *PrivateGlobalPrefix;
+
+ /// 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. The default of "" meast that for this system
+ /// a plain private symbol should be used. Defaults to "".
+ const char *LinkerPrivateGlobalPrefix;
+
+ /// If these are nonempty, they contain a directive to emit before and after
+ /// an inline assembly statement. Defaults to "#APP\n", "#NO_APP\n"
+ const char *InlineAsmStart;
+ const char *InlineAsmEnd;
+
+ /// These are assembly directives that tells the assembler to interpret the
+ /// following instructions differently. Defaults to ".code16", ".code32",
+ /// ".code64".
+ const char *Code16Directive;
+ const char *Code32Directive;
+ const char *Code64Directive;
+
+ /// Which dialect of an assembler variant to use. Defaults to 0
+ unsigned AssemblerDialect;
+
+ /// This is true if the assembler allows @ characters in symbol names.
+ /// Defaults to false.
+ bool AllowAtInName;
+
+ /// 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 -------------------------------------===//
+
+ /// 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. Defaults to "\t.zero\t"
+ const char *ZeroDirective;
+
+ /// This directive allows emission of an ascii string with the standard C
+ /// escape characters embedded into it. Defaults to "\t.ascii\t"
+ const char *AsciiDirective;
+
+ /// 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. Defaults to "\t.asciz\t"
+ const char *AscizDirective;
+
+ /// 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. Defaults to "\t.byte\t",
+ /// "\t.short\t", "\t.long\t", "\t.quad\t"
+ const char *Data8bitsDirective;
+ const char *Data16bitsDirective;
+ const char *Data32bitsDirective;
+ const char *Data64bitsDirective;
+
+ /// 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. Defaults
+ /// to NULL.
+ const char *GPRel64Directive;
+
+ /// 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. Defaults to NULL.
+ const char *GPRel32Directive;
+
+ /// 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. Defaults to false.
+ bool SunStyleELFSectionSwitchSyntax;
+
+ /// 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. Defaults to false.
+ bool UsesELFSectionDirectiveForBSS;
+
+ bool NeedsDwarfSectionOffsetDirective;
+
+ //===--- Alignment Information ----------------------------------------===//
+
+ /// 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. Defaults
+ /// to true.
+ bool AlignmentIsInBytes;
+
+ /// If non-zero, this is used to fill the executable space created as the
+ /// result of a alignment directive. Defaults to 0
+ unsigned TextAlignFillValue;
+
+ //===--- Global Variable Emission Directives --------------------------===//
+
+ /// This is the directive used to declare a global entity. Defaults to NULL.
+ const char *GlobalDirective;
+
+ /// True if the assembler supports the .set directive. Defaults to true.
+ bool HasSetDirective;
+
+ /// False if the assembler requires that we use
+ /// \code
+ /// Lc = a - b
+ /// .long Lc
+ /// \endcode
+ //
+ /// instead of
+ //
+ /// \code
+ /// .long a - b
+ /// \endcode
+ ///
+ /// Defaults to true.
+ bool HasAggressiveSymbolFolding;
+
+ /// True is .comm's and .lcomms optional alignment is to be specified in bytes
+ /// instead of log2(n). Defaults to true.
+ bool COMMDirectiveAlignmentIsInBytes;
+
+ /// Describes if the .lcomm directive for the target supports an alignment
+ /// argument and how it is interpreted. Defaults to NoAlignment.
+ LCOMM::LCOMMType LCOMMDirectiveAlignmentType;
+
+ /// True if the target has .type and .size directives, this is true for most
+ /// ELF targets. Defaults to true.
+ bool HasDotTypeDotSizeDirective;
+
+ /// True if the target has a single parameter .file directive, this is true
+ /// for ELF targets. Defaults to true.
+ bool HasSingleParameterDotFile;
+
+ /// True if the target has a .ident directive, this is true for ELF targets.
+ /// Defaults to false.
+ bool HasIdentDirective;
+
+ /// True if this target supports the MachO .no_dead_strip directive. Defaults
+ /// to false.
+ bool HasNoDeadStrip;
+
+ /// This directive, if non-null, is used to declare a global as being a weak
+ /// undefined symbol. Defaults to NULL.
+ const char *WeakRefDirective;
+
+ /// True if we have a directive to declare a global as being a weak defined
+ /// symbol. Defaults to false.
+ bool HasWeakDefDirective;
+
+ /// True if we have a directive to declare a global as being a weak defined
+ /// symbol that can be hidden (unexported). Defaults to false.
+ bool HasWeakDefCanBeHiddenDirective;
+
+ /// True if we have a .linkonce directive. This is used on cygwin/mingw.
+ /// Defaults to false.
+ bool HasLinkOnceDirective;
+
+ /// This attribute, if not MCSA_Invalid, is used to declare a symbol as having
+ /// hidden visibility. Defaults to MCSA_Hidden.
+ MCSymbolAttr HiddenVisibilityAttr;
+
+ /// This attribute, if not MCSA_Invalid, is used to declare an undefined
+ /// symbol as having hidden visibility. Defaults to MCSA_Hidden.
+ MCSymbolAttr HiddenDeclarationVisibilityAttr;
+
+ /// This attribute, if not MCSA_Invalid, is used to declare a symbol as having
+ /// protected visibility. Defaults to MCSA_Protected
+ MCSymbolAttr ProtectedVisibilityAttr;
+
+ //===--- Dwarf Emission Directives -----------------------------------===//
+
+ /// True if target asm supports leb128 directives. Defaults to false.
+ bool HasLEB128;
+
+ /// True if target supports emission of debugging information. Defaults to
+ /// false.
+ bool SupportsDebugInformation;
+
+ /// Exception handling format for the target. Defaults to None.
+ ExceptionHandling ExceptionsType;
+
+ /// Windows exception handling data (.pdata) encoding. Defaults to Invalid.
+ WinEH::EncodingType WinEHEncodingType;
- namespace LCOMM {
- enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment };
+ /// True if Dwarf2 output generally uses relocations for references to other
+ /// .debug_* sections.
+ bool DwarfUsesRelocationsAcrossSections;
+
+ /// True if DWARF FDE symbol reference relocations should be replaced by an
+ /// absolute difference.
+ bool DwarfFDESymbolsUseAbsDiff;
+
+ /// True if dwarf register numbers are printed instead of symbolic register
+ /// names in .cfi_* directives. Defaults to false.
+ bool DwarfRegNumForCFI;
+
+ /// True if target uses parens to indicate the symbol variant instead of @.
+ /// For example, foo(plt) instead of foo@plt. Defaults to false.
+ bool UseParensForSymbolVariant;
+
+ //===--- Prologue State ----------------------------------------------===//
+
+ std::vector<MCCFIInstruction> InitialFrameState;
+
+ //===--- Integrated Assembler State ----------------------------------===//
+
+ /// Should we use the integrated assembler?
+ /// The integrated assembler should be enabled by default (by the
+ /// constructors) when failing to parse a valid piece of assembly (inline
+ /// or otherwise) is considered a bug. It may then be overridden after
+ /// construction (see LLVMTargetMachine::initAsmInfo()).
+ bool UseIntegratedAssembler;
+
+ /// Compress DWARF debug sections. Defaults to false.
+ bool CompressDebugSections;
+
+public:
+ explicit MCAsmInfo();
+ virtual ~MCAsmInfo();
+
+ /// Get the pointer size in bytes.
+ unsigned getPointerSize() const { return PointerSize; }
+
+ /// Get the callee-saved register stack slot
+ /// size in bytes.
+ unsigned getCalleeSaveStackSlotSize() const {
+ return CalleeSaveStackSlotSize;
}
- /// 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.
-
- /// MinInstAlignment - Every possible instruction length is a multiple of
- /// this value. Factored out in .debug_frame and .debug_line.
- unsigned MinInstAlignment; // Defaults to 1.
-
- /// DollarIsPC - The '$' token, when not referencing an identifier or
- /// constant, refers to the current PC.
- bool DollarIsPC; // Defaults to false.
-
- /// 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
-
- /// \brief This is true if the assembler allows @ characters in symbol
- /// names. Defaults to false.
- bool AllowAtInName;
-
- /// 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.
-
- /// 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.
-
- bool NeedsDwarfSectionOffsetDirective;
-
- //===--- 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
+ /// True if the target is little endian.
+ bool isLittleEndian() const { return IsLittleEndian; }
- /// 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
+ /// True if target stack grow up.
+ bool isStackGrowthDirectionUp() const { return StackGrowsUp; }
- //===--- Global Variable Emission Directives --------------------------===//
+ bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
- /// GlobalDirective - This is the directive used to declare a global entity.
- ///
- const char *GlobalDirective; // Defaults to NULL.
+ // Data directive accessors.
- /// HasSetDirective - True if the assembler supports the .set directive.
- bool HasSetDirective; // Defaults to true.
+ const char *getData8bitsDirective() const { return Data8bitsDirective; }
+ const char *getData16bitsDirective() const { return Data16bitsDirective; }
+ const char *getData32bitsDirective() const { return Data32bitsDirective; }
+ const char *getData64bitsDirective() const { return Data64bitsDirective; }
+ const char *getGPRel64Directive() const { return GPRel64Directive; }
+ const char *getGPRel32Directive() const { return GPRel32Directive; }
+
+ /// 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 nullptr;
+ }
- /// HasAggressiveSymbolFolding - False if the assembler requires that we use
- /// Lc = a - b
- /// .long Lc
- /// instead of
- /// .long a - b
- bool HasAggressiveSymbolFolding; // Defaults to true.
+ virtual const MCExpr *getExprForPersonalitySymbol(const MCSymbol *Sym,
+ unsigned Encoding,
+ MCStreamer &Streamer) const;
- /// COMMDirectiveAlignmentIsInBytes - True is .comm's and .lcomms optional
- /// alignment is to be specified in bytes instead of log2(n).
- bool COMMDirectiveAlignmentIsInBytes; // Defaults to true;
+ virtual const MCExpr *getExprForFDESymbol(const MCSymbol *Sym,
+ unsigned Encoding,
+ MCStreamer &Streamer) const;
- /// 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.
+ bool usesSunStyleELFSectionSwitchSyntax() const {
+ return SunStyleELFSectionSwitchSyntax;
+ }
+
+ bool usesELFSectionDirectiveForBSS() const {
+ return UsesELFSectionDirectiveForBSS;
+ }
- /// HasSingleParameterDotFile - True if the target has a single parameter
- /// .file directive, this is true for ELF targets.
- bool HasSingleParameterDotFile; // Defaults to true.
-
- /// hasIdentDirective - True if the target has a .ident directive, this is
- /// true for ELF targets.
- bool HasIdentDirective; // Defaults to false.
-
- /// HasNoDeadStrip - True if this target supports the MachO .no_dead_strip
- /// directive.
- bool HasNoDeadStrip; // 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.
-
- /// True if we have a directive to declare a global as being a weak
- /// defined symbol.
- bool HasWeakDefDirective; // Defaults to false.
-
- /// True if we have a directive to declare a global as being a weak
- /// defined symbol that can be hidden (unexported).
- bool HasWeakDefCanBeHiddenDirective; // Defaults to false.
-
- /// True if we have a .linkonce directive. This is used on cygwin/mingw.
- bool HasLinkOnceDirective; // Defaults to false.
-
- /// 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
-
- /// DwarfUsesRelocationsAcrossSections - True if Dwarf2 output generally
- /// uses relocations for references to other .debug_* sections.
- bool DwarfUsesRelocationsAcrossSections;
-
- /// DwarfFDESymbolsUseAbsDiff - true if DWARF FDE symbol reference
- /// relocations should be replaced by an absolute difference.
- bool DwarfFDESymbolsUseAbsDiff;
-
- /// 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<MCCFIInstruction> InitialFrameState;
-
- public:
- explicit MCAsmInfo();
- virtual ~MCAsmInfo();
-
- // FIXME: move these methods to DwarfPrinter when the JIT stops using them.
- static unsigned getSLEB128Size(int64_t Value);
- static unsigned getULEB128Size(uint64_t 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() const {
- return Data8bitsDirective;
- }
- const char *getData16bitsDirective() const {
- return Data16bitsDirective;
- }
- const char *getData32bitsDirective() const {
- return Data32bitsDirective;
- }
- const char *getData64bitsDirective() const {
- return Data64bitsDirective;
- }
- 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;
- }
-
- bool needsDwarfSectionOffsetDirective() const {
- return NeedsDwarfSectionOffsetDirective;
- }
-
- // 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;
- }
- unsigned getMinInstAlignment() const {
- return MinInstAlignment;
- }
- bool getDollarIsPC() const {
- return DollarIsPC;
- }
- 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 {
+ bool needsDwarfSectionOffsetDirective() const {
+ return NeedsDwarfSectionOffsetDirective;
+ }
+
+ // 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; }
+ unsigned getMinInstAlignment() const { return MinInstAlignment; }
+ bool getDollarIsPC() const { return DollarIsPC; }
+ const char *getSeparatorString() const { return SeparatorString; }
+
+ /// This indicates the column (zero-based) at which asm comments should be
+ /// printed.
+ unsigned getCommentColumn() const { return 40; }
+
+ const char *getCommentString() const { return CommentString; }
+ const char *getLabelSuffix() const { return LabelSuffix; }
+
+ bool useAssignmentForEHBegin() const { return UseAssignmentForEHBegin; }
+ const char *getPrivateGlobalPrefix() const { return PrivateGlobalPrefix; }
+ bool hasLinkerPrivateGlobalPrefix() const {
+ return LinkerPrivateGlobalPrefix[0] != '\0';
+ }
+ const char *getLinkerPrivateGlobalPrefix() const {
+ if (hasLinkerPrivateGlobalPrefix())
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 doesAllowAtInName() const {
- return AllowAtInName;
- }
- 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;
- }
- 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 hasIdentDirective() const { return HasIdentDirective; }
- bool hasNoDeadStrip() const { return HasNoDeadStrip; }
- const char *getWeakRefDirective() const { return WeakRefDirective; }
- bool hasWeakDefDirective() const { return HasWeakDefDirective; }
- bool hasWeakDefCanBeHiddenDirective() const {
- return HasWeakDefCanBeHiddenDirective;
- }
- bool hasLinkOnceDirective() const { return HasLinkOnceDirective; }
-
- 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 doesDwarfUseRelocationsAcrossSections() const {
- return DwarfUsesRelocationsAcrossSections;
- }
- bool doDwarfFDESymbolsUseAbsDiff() const {
- return DwarfFDESymbolsUseAbsDiff;
- }
- bool useDwarfRegNumForCFI() const {
- return DwarfRegNumForCFI;
- }
-
- void addInitialFrameState(const MCCFIInstruction &Inst) {
- InitialFrameState.push_back(Inst);
- }
-
- const std::vector<MCCFIInstruction> &getInitialFrameState() const {
- return InitialFrameState;
- }
- };
+ return getPrivateGlobalPrefix();
+ }
+ 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 doesAllowAtInName() const { return AllowAtInName; }
+ bool doesSupportDataRegionDirectives() const {
+ return UseDataRegionDirectives;
+ }
+ const char *getZeroDirective() const { return ZeroDirective; }
+ const char *getAsciiDirective() const { return AsciiDirective; }
+ const char *getAscizDirective() const { return AscizDirective; }
+ bool getAlignmentIsInBytes() const { return AlignmentIsInBytes; }
+ unsigned getTextAlignFillValue() const { return TextAlignFillValue; }
+ const char *getGlobalDirective() const { return GlobalDirective; }
+ 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 hasIdentDirective() const { return HasIdentDirective; }
+ bool hasNoDeadStrip() const { return HasNoDeadStrip; }
+ const char *getWeakRefDirective() const { return WeakRefDirective; }
+ bool hasWeakDefDirective() const { return HasWeakDefDirective; }
+ bool hasWeakDefCanBeHiddenDirective() const {
+ return HasWeakDefCanBeHiddenDirective;
+ }
+ bool hasLinkOnceDirective() const { return HasLinkOnceDirective; }
+
+ 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 getExceptionHandlingType() const { return ExceptionsType; }
+ WinEH::EncodingType getWinEHEncodingType() const { return WinEHEncodingType; }
+ bool isExceptionHandlingDwarf() const {
+ return (ExceptionsType == ExceptionHandling::DwarfCFI ||
+ ExceptionsType == ExceptionHandling::ARM ||
+ // Windows handler data still uses DWARF LSDA encoding.
+ ExceptionsType == ExceptionHandling::WinEH);
+ }
+ bool doesDwarfUseRelocationsAcrossSections() const {
+ return DwarfUsesRelocationsAcrossSections;
+ }
+ bool doDwarfFDESymbolsUseAbsDiff() const { return DwarfFDESymbolsUseAbsDiff; }
+ bool useDwarfRegNumForCFI() const { return DwarfRegNumForCFI; }
+ bool useParensForSymbolVariant() const { return UseParensForSymbolVariant; }
+
+ void addInitialFrameState(const MCCFIInstruction &Inst) {
+ InitialFrameState.push_back(Inst);
+ }
+
+ const std::vector<MCCFIInstruction> &getInitialFrameState() const {
+ return InitialFrameState;
+ }
+
+ /// Return true if assembly (inline or otherwise) should be parsed.
+ bool useIntegratedAssembler() const { return UseIntegratedAssembler; }
+
+ /// Set whether assembly (inline or otherwise) should be parsed.
+ virtual void setUseIntegratedAssembler(bool Value) {
+ UseIntegratedAssembler = Value;
+ }
+
+ bool compressDebugSections() const { return CompressDebugSections; }
+
+ void setCompressDebugSections(bool CompressDebugSections) {
+ this->CompressDebugSections = CompressDebugSections;
+ }
+};
}
#endif
diff --git a/include/llvm/MC/MCAsmInfoCOFF.h b/include/llvm/MC/MCAsmInfoCOFF.h
index 7286151760c0..56444f3c7cf5 100644
--- a/include/llvm/MC/MCAsmInfoCOFF.h
+++ b/include/llvm/MC/MCAsmInfoCOFF.h
@@ -20,13 +20,13 @@ namespace llvm {
};
class MCAsmInfoMicrosoft : public MCAsmInfoCOFF {
- virtual void anchor();
+ void anchor() override;
protected:
explicit MCAsmInfoMicrosoft();
};
class MCAsmInfoGNUCOFF : public MCAsmInfoCOFF {
- virtual void anchor();
+ void anchor() override;
protected:
explicit MCAsmInfoGNUCOFF();
};
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
index 3058b7b48742..f048e34671db 100644
--- a/include/llvm/MC/MCAsmLayout.h
+++ b/include/llvm/MC/MCAsmLayout.h
@@ -17,6 +17,7 @@ namespace llvm {
class MCAssembler;
class MCFragment;
class MCSectionData;
+class MCSymbol;
class MCSymbolData;
/// Encapsulates the layout of an assembly file at a particular point in time.
@@ -102,8 +103,15 @@ public:
/// \brief Get the offset of the given symbol, as computed in the current
/// layout.
+ /// \result True on success.
+ bool getSymbolOffset(const MCSymbolData *SD, uint64_t &Val) const;
+
+ /// \brief Variant that reports a fatal error if the offset is not computable.
uint64_t getSymbolOffset(const MCSymbolData *SD) const;
+ /// \brief If this symbol is equivalent to A + Constant, return A.
+ const MCSymbol *getBaseSymbol(const MCSymbol &Symbol) const;
+
/// @}
};
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 8735a55ce044..1cb34c2fe33b 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -15,8 +15,11 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCLinkerOptimizationHint.h"
+#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include <algorithm>
@@ -33,6 +36,7 @@ class MCFragment;
class MCObjectWriter;
class MCSection;
class MCSectionData;
+class MCSubtargetInfo;
class MCSymbol;
class MCSymbolData;
class MCValue;
@@ -64,8 +68,7 @@ private:
MCSectionData *Parent;
/// Atom - The atom this fragment is in, as represented by it's defining
- /// symbol. Atom's are only used by backends which set
- /// \see MCAsmBackend::hasReliableSymbolDifference().
+ /// symbol.
MCSymbolData *Atom;
/// @name Assembler Backend Data
@@ -83,7 +86,7 @@ private:
/// @}
protected:
- MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
+ MCFragment(FragmentType _Kind, MCSectionData *_Parent = nullptr);
public:
// Only for sentinel.
@@ -134,7 +137,7 @@ class MCEncodedFragment : public MCFragment {
uint8_t BundlePadding;
public:
- MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0)
+ MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = nullptr)
: MCFragment(FType, SD), BundlePadding(0)
{
}
@@ -143,11 +146,11 @@ public:
virtual SmallVectorImpl<char> &getContents() = 0;
virtual const SmallVectorImpl<char> &getContents() const = 0;
- virtual uint8_t getBundlePadding() const {
+ uint8_t getBundlePadding() const override {
return BundlePadding;
}
- virtual void setBundlePadding(uint8_t N) {
+ void setBundlePadding(uint8_t N) override {
BundlePadding = N;
}
@@ -168,11 +171,11 @@ public:
/// data and also have fixups registered.
///
class MCEncodedFragmentWithFixups : public MCEncodedFragment {
- virtual void anchor();
+ void anchor() override;
public:
MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
- MCSectionData *SD = 0)
+ MCSectionData *SD = nullptr)
: MCEncodedFragment(FType, SD)
{
}
@@ -199,7 +202,7 @@ public:
/// Fragment for data and encoded instructions.
///
class MCDataFragment : public MCEncodedFragmentWithFixups {
- virtual void anchor();
+ void anchor() override;
/// \brief Does this fragment contain encoded instructions anywhere in it?
bool HasInstructions;
@@ -212,34 +215,36 @@ class MCDataFragment : public MCEncodedFragmentWithFixups {
/// Fixups - The list of fixups in this fragment.
SmallVector<MCFixup, 4> Fixups;
public:
- MCDataFragment(MCSectionData *SD = 0)
+ MCDataFragment(MCSectionData *SD = nullptr)
: MCEncodedFragmentWithFixups(FT_Data, SD),
HasInstructions(false), AlignToBundleEnd(false)
{
}
- virtual SmallVectorImpl<char> &getContents() { return Contents; }
- virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+ SmallVectorImpl<char> &getContents() override { return Contents; }
+ const SmallVectorImpl<char> &getContents() const override {
+ return Contents;
+ }
- SmallVectorImpl<MCFixup> &getFixups() {
+ SmallVectorImpl<MCFixup> &getFixups() override {
return Fixups;
}
- const SmallVectorImpl<MCFixup> &getFixups() const {
+ const SmallVectorImpl<MCFixup> &getFixups() const override {
return Fixups;
}
- virtual bool hasInstructions() const { return HasInstructions; }
+ bool hasInstructions() const override { return HasInstructions; }
virtual void setHasInstructions(bool V) { HasInstructions = V; }
- virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
- virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
+ bool alignToBundleEnd() const override { return AlignToBundleEnd; }
+ void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; }
- fixup_iterator fixup_begin() { return Fixups.begin(); }
- const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
+ fixup_iterator fixup_begin() override { return Fixups.begin(); }
+ const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
- fixup_iterator fixup_end() {return Fixups.end();}
- const_fixup_iterator fixup_end() const {return Fixups.end();}
+ fixup_iterator fixup_end() override {return Fixups.end();}
+ const_fixup_iterator fixup_end() const override {return Fixups.end();}
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Data;
@@ -252,27 +257,27 @@ public:
/// consumption.
///
class MCCompactEncodedInstFragment : public MCEncodedFragment {
- virtual void anchor();
+ void anchor() override;
/// \brief Should this fragment be aligned to the end of a bundle?
bool AlignToBundleEnd;
SmallVector<char, 4> Contents;
public:
- MCCompactEncodedInstFragment(MCSectionData *SD = 0)
+ MCCompactEncodedInstFragment(MCSectionData *SD = nullptr)
: MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false)
{
}
- virtual bool hasInstructions() const {
+ bool hasInstructions() const override {
return true;
}
- virtual SmallVectorImpl<char> &getContents() { return Contents; }
- virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+ SmallVectorImpl<char> &getContents() override { return Contents; }
+ const SmallVectorImpl<char> &getContents() const override { return Contents; }
- virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
- virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
+ bool alignToBundleEnd() const override { return AlignToBundleEnd; }
+ void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; }
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_CompactEncodedInst;
@@ -283,11 +288,16 @@ public:
/// relaxed during the assembler layout and relaxation stage.
///
class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
- virtual void anchor();
+ void anchor() override;
/// Inst - The instruction this is a fragment for.
MCInst Inst;
+ /// STI - The MCSubtargetInfo in effect when the instruction was encoded.
+ /// Keep a copy instead of a reference to make sure that updates to STI
+ /// in the assembler are not seen here.
+ const MCSubtargetInfo STI;
+
/// Contents - Binary data for the currently encoded instruction.
SmallVector<char, 8> Contents;
@@ -295,31 +305,35 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
SmallVector<MCFixup, 1> Fixups;
public:
- MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0)
- : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) {
+ MCRelaxableFragment(const MCInst &_Inst,
+ const MCSubtargetInfo &_STI,
+ MCSectionData *SD = nullptr)
+ : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst), STI(_STI) {
}
- virtual SmallVectorImpl<char> &getContents() { return Contents; }
- virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+ SmallVectorImpl<char> &getContents() override { return Contents; }
+ const SmallVectorImpl<char> &getContents() const override { return Contents; }
const MCInst &getInst() const { return Inst; }
void setInst(const MCInst& Value) { Inst = Value; }
- SmallVectorImpl<MCFixup> &getFixups() {
+ const MCSubtargetInfo &getSubtargetInfo() { return STI; }
+
+ SmallVectorImpl<MCFixup> &getFixups() override {
return Fixups;
}
- const SmallVectorImpl<MCFixup> &getFixups() const {
+ const SmallVectorImpl<MCFixup> &getFixups() const override {
return Fixups;
}
- virtual bool hasInstructions() const { return true; }
+ bool hasInstructions() const override { return true; }
- fixup_iterator fixup_begin() { return Fixups.begin(); }
- const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
+ fixup_iterator fixup_begin() override { return Fixups.begin(); }
+ const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
- fixup_iterator fixup_end() {return Fixups.end();}
- const_fixup_iterator fixup_end() const {return Fixups.end();}
+ fixup_iterator fixup_end() override {return Fixups.end();}
+ const_fixup_iterator fixup_end() const override {return Fixups.end();}
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Relaxable;
@@ -349,7 +363,7 @@ class MCAlignFragment : public MCFragment {
public:
MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
- unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
+ unsigned _MaxBytesToEmit, MCSectionData *SD = nullptr)
: MCFragment(FT_Align, SD), Alignment(_Alignment),
Value(_Value),ValueSize(_ValueSize),
MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
@@ -390,7 +404,7 @@ class MCFillFragment : public MCFragment {
public:
MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
- MCSectionData *SD = 0)
+ MCSectionData *SD = nullptr)
: MCFragment(FT_Fill, SD),
Value(_Value), ValueSize(_ValueSize), Size(_Size) {
assert((!ValueSize || (Size % ValueSize) == 0) &&
@@ -423,7 +437,8 @@ class MCOrgFragment : public MCFragment {
int8_t Value;
public:
- MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
+ MCOrgFragment(const MCExpr &_Offset, int8_t _Value,
+ MCSectionData *SD = nullptr)
: MCFragment(FT_Org, SD),
Offset(&_Offset), Value(_Value) {}
@@ -452,7 +467,8 @@ class MCLEBFragment : public MCFragment {
SmallString<8> Contents;
public:
- MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD = 0)
+ MCLEBFragment(const MCExpr &Value_, bool IsSigned_,
+ MCSectionData *SD = nullptr)
: MCFragment(FT_LEB, SD),
Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
@@ -488,7 +504,7 @@ class MCDwarfLineAddrFragment : public MCFragment {
public:
MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
- MCSectionData *SD = 0)
+ MCSectionData *SD = nullptr)
: MCFragment(FT_Dwarf, SD),
LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
@@ -519,7 +535,8 @@ class MCDwarfCallFrameFragment : public MCFragment {
SmallString<8> Contents;
public:
- MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD = 0)
+ MCDwarfCallFrameFragment(const MCExpr &_AddrDelta,
+ MCSectionData *SD = nullptr)
: MCFragment(FT_DwarfFrame, SD),
AddrDelta(&_AddrDelta) { Contents.push_back(0); }
@@ -600,7 +617,7 @@ private:
public:
// Only for use as sentinel.
MCSectionData();
- MCSectionData(const MCSection &Section, MCAssembler *A = 0);
+ MCSectionData(const MCSection &Section, MCAssembler *A = nullptr);
const MCSection &getSection() const { return *Section; }
@@ -710,7 +727,7 @@ public:
// Only for use as sentinel.
MCSymbolData();
MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
- MCAssembler *A = 0);
+ MCAssembler *A = nullptr);
/// @name Accessors
/// @{
@@ -785,7 +802,7 @@ public:
/// @}
- void dump();
+ void dump() const;
};
// FIXME: This really doesn't belong here. See comments below.
@@ -817,6 +834,9 @@ public:
typedef SymbolDataListType::const_iterator const_symbol_iterator;
typedef SymbolDataListType::iterator symbol_iterator;
+ typedef iterator_range<symbol_iterator> symbol_range;
+ typedef iterator_range<const_symbol_iterator> const_symbol_range;
+
typedef std::vector<std::string> FileNameVectorType;
typedef FileNameVectorType::const_iterator const_file_name_iterator;
@@ -828,6 +848,15 @@ public:
const_data_region_iterator;
typedef std::vector<DataRegionData>::iterator data_region_iterator;
+ /// MachO specific deployment target version info.
+ // A Major version of 0 indicates that no version information was supplied
+ // and so the corresponding load command should not be emitted.
+ typedef struct {
+ MCVersionMinType Kind;
+ unsigned Major;
+ unsigned Minor;
+ unsigned Update;
+ } VersionMinInfoType;
private:
MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION;
void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION;
@@ -873,7 +902,7 @@ private:
// here. Maybe when the relocation stuff moves to target specific,
// this can go with it? The streamer would need some target specific
// refactoring too.
- SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
+ mutable SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
/// \brief The bundle alignment size currently set in the assembler.
///
@@ -890,6 +919,12 @@ private:
// Access to the flags is necessary in cases where assembler directives affect
// which flags to be set.
unsigned ELFHeaderEFlags;
+
+ /// Used to communicate Linker Optimization Hint information between
+ /// the Streamer and the .o writer
+ MCLOHContainer LOHContainer;
+
+ VersionMinInfoType VersionMinInfo;
private:
/// Evaluate a fixup to a relocatable expression and the value which should be
/// placed into the fixup.
@@ -936,8 +971,8 @@ private:
/// finishLayout - Finalize a layout, including fragment lowering.
void finishLayout(MCAsmLayout &Layout);
- uint64_t handleFixup(const MCAsmLayout &Layout,
- MCFragment &F, const MCFixup &Fixup);
+ std::pair<uint64_t, bool> handleFixup(const MCAsmLayout &Layout,
+ MCFragment &F, const MCFixup &Fixup);
public:
/// Compute the effective fragment size assuming it is laid out at the given
@@ -960,9 +995,7 @@ public:
const MCAsmLayout &Layout) const;
/// Check whether a given symbol has been flagged with .thumb_func.
- bool isThumbFunc(const MCSymbol *Func) const {
- return ThumbFuncs.count(Func);
- }
+ bool isThumbFunc(const MCSymbol *Func) const;
/// Flag a function symbol as the target of a .thumb_func directive.
void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
@@ -971,6 +1004,16 @@ public:
unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;}
void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;}
+ /// MachO deployment target version information.
+ const VersionMinInfoType &getVersionMinInfo() const { return VersionMinInfo; }
+ void setVersionMinInfo(MCVersionMinType Kind, unsigned Major, unsigned Minor,
+ unsigned Update) {
+ VersionMinInfo.Kind = Kind;
+ VersionMinInfo.Major = Major;
+ VersionMinInfo.Minor = Minor;
+ VersionMinInfo.Update = Update;
+ }
+
public:
/// Construct a new assembler instance.
///
@@ -1057,6 +1100,9 @@ public:
symbol_iterator symbol_end() { return Symbols.end(); }
const_symbol_iterator symbol_end() const { return Symbols.end(); }
+ symbol_range symbols() { return make_range(symbol_begin(), symbol_end()); }
+ const_symbol_range symbols() const { return make_range(symbol_begin(), symbol_end()); }
+
size_t symbol_size() const { return Symbols.size(); }
/// @}
@@ -1122,6 +1168,19 @@ public:
size_t data_region_size() const { return DataRegions.size(); }
/// @}
+ /// @name Data Region List Access
+ /// @{
+
+ // FIXME: This is a total hack, this should not be here. Once things are
+ // factored so that the streamer has direct access to the .o writer, it can
+ // disappear.
+ MCLOHContainer & getLOHContainer() {
+ return LOHContainer;
+ }
+ const MCLOHContainer & getLOHContainer() const {
+ return const_cast<MCAssembler *>(this)->getLOHContainer();
+ }
+ /// @}
/// @name Backend Data Access
/// @{
@@ -1132,7 +1191,7 @@ public:
}
MCSectionData &getOrCreateSectionData(const MCSection &Section,
- bool *Created = 0) {
+ bool *Created = nullptr) {
MCSectionData *&Entry = SectionMap[&Section];
if (Created) *Created = !Entry;
@@ -1142,19 +1201,28 @@ public:
return *Entry;
}
- MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
+ bool hasSymbolData(const MCSymbol &Symbol) const {
+ return SymbolMap.lookup(&Symbol) != nullptr;
+ }
+
+ MCSymbolData &getSymbolData(const MCSymbol &Symbol) {
+ return const_cast<MCSymbolData &>(
+ static_cast<const MCAssembler &>(*this).getSymbolData(Symbol));
+ }
+
+ const MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
assert(Entry && "Missing symbol data!");
return *Entry;
}
MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
- bool *Created = 0) {
+ bool *Created = nullptr) {
MCSymbolData *&Entry = SymbolMap[&Symbol];
if (Created) *Created = !Entry;
if (!Entry)
- Entry = new MCSymbolData(Symbol, 0, 0, this);
+ Entry = new MCSymbolData(Symbol, nullptr, 0, this);
return *Entry;
}
diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h
index 9bfa08eb5d01..d3b56177d50a 100644
--- a/include/llvm/MC/MCCodeEmitter.h
+++ b/include/llvm/MC/MCCodeEmitter.h
@@ -15,6 +15,7 @@
namespace llvm {
class MCFixup;
class MCInst;
+class MCSubtargetInfo;
class raw_ostream;
template<typename T> class SmallVectorImpl;
@@ -35,7 +36,8 @@ public:
/// 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;
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const = 0;
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index c8b66261bfea..eb0340f7421a 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -11,15 +11,18 @@
#define LLVM_MC_MCCONTEXT_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCStreamer.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 <tuple>
#include <vector> // FIXME: Shouldn't be needed.
namespace llvm {
@@ -28,7 +31,7 @@ namespace llvm {
class MCSection;
class MCSymbol;
class MCLabel;
- class MCDwarfFile;
+ struct MCDwarfFile;
class MCDwarfLoc;
class MCObjectFileInfo;
class MCRegisterInfo;
@@ -70,6 +73,14 @@ namespace llvm {
/// Symbols - Bindings of names to symbols.
SymbolTable Symbols;
+ /// A maping from a local label number and an instance count to a symbol.
+ /// For example, in the assembly
+ /// 1:
+ /// 2:
+ /// 1:
+ /// We have three labels represented by the pairs (1, 0), (2, 0) and (1, 1)
+ DenseMap<std::pair<unsigned, unsigned>, MCSymbol*> LocalSymbols;
+
/// UsedNames - Keeps tracks of names that were used both for used declared
/// and artificial symbols.
StringMap<bool, BumpPtrAllocator&> UsedNames;
@@ -82,10 +93,10 @@ namespace llvm {
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);
+ unsigned NextInstance(unsigned 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);
+ unsigned GetInstance(unsigned 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
@@ -108,9 +119,7 @@ namespace llvm {
/// 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;
+ std::map<unsigned, MCDwarfLineTable> MCDwarfLineTablesCUMap;
/// The current dwarf line information from the last dwarf .loc directive.
MCDwarfLoc CurrentDwarfLoc;
@@ -123,15 +132,14 @@ namespace llvm {
/// 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;
+ /// Symbols created for the start and end of each section, used for
+ /// generating the .debug_ranges and .debug_aranges sections.
+ MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> >
+ SectionStartEndSyms;
/// The information gathered from labels that will have dwarf label
/// entries when generating dwarf assembly source files.
- std::vector<const MCGenDwarfLabelEntry *> MCGenDwarfLabelEntries;
+ std::vector<MCGenDwarfLabelEntry> MCGenDwarfLabelEntries;
/// The string to embed in the debug information for the compile unit, if
/// non-empty.
@@ -141,33 +149,36 @@ namespace llvm {
/// non-empty.
StringRef DwarfDebugProducer;
+ /// The maximum version of dwarf that we should emit.
+ uint16_t DwarfVersion;
+
/// 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;
+ typedef std::pair<std::string, std::string> SectionGroupPair;
+ typedef std::tuple<std::string, std::string, int> SectionGroupTriple;
+
+ StringMap<const MCSectionMachO*> MachOUniquingMap;
+ std::map<SectionGroupPair, const MCSectionELF *> ELFUniquingMap;
+ std::map<SectionGroupTriple, const MCSectionCOFF *> COFFUniquingMap;
/// Do automatic reset in destructor
bool AutoReset;
MCSymbol *CreateSymbol(StringRef Name);
+ MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
+ unsigned Instance);
+
public:
explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI,
- const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0,
- bool DoAutoReset = true);
+ const MCObjectFileInfo *MOFI,
+ const SourceMgr *Mgr = nullptr, bool DoAutoReset = true);
~MCContext();
const SourceMgr *getSourceManager() const { return SrcMgr; }
@@ -192,6 +203,10 @@ namespace llvm {
/// @name Symbol Management
/// @{
+ /// CreateLinkerPrivateTempSymbol - Create and return a new linker temporary
+ /// symbol with a unique but unspecified name.
+ MCSymbol *CreateLinkerPrivateTempSymbol();
+
/// CreateTempSymbol - Create and return a new assembler temporary symbol
/// with a unique but unspecified name.
MCSymbol *CreateTempSymbol();
@@ -200,13 +215,13 @@ namespace llvm {
/// 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);
+ /// Create the definition of a directional local symbol for numbered label
+ /// (used for "1:" definitions).
+ MCSymbol *CreateDirectionalLocalSymbol(unsigned 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);
+ /// Create and return a directional local symbol for numbered label (used
+ /// for "1b" or 1f" references).
+ MCSymbol *GetDirectionalLocalSymbol(unsigned LocalLabelVal, bool Before);
/// GetOrCreateSymbol - Lookup the symbol inside with the specified
/// @p Name. If it exists, return it. If not, create a forward
@@ -254,14 +269,14 @@ namespace llvm {
unsigned Flags, SectionKind Kind,
unsigned EntrySize, StringRef Group);
+ void renameELFSection(const MCSectionELF *Section, StringRef Name);
+
const MCSectionELF *CreateELFGroupSection();
const MCSectionCOFF *getCOFFSection(StringRef Section,
unsigned Characteristics,
SectionKind Kind,
- StringRef COMDATSymName,
- int Selection,
- const MCSectionCOFF *Assoc = 0);
+ StringRef COMDATSymName, int Selection);
const MCSectionCOFF *getCOFFSection(StringRef Section,
unsigned Characteristics,
@@ -278,6 +293,7 @@ namespace llvm {
/// 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.
+ /// Returns an empty string if the current directory cannot be determined.
StringRef getCompilationDir() const { return CompilationDir; }
/// \brief Set the compilation directory for DW_AT_comp_dir
@@ -290,7 +306,7 @@ namespace llvm {
const std::string &getMainFileName() const { return MainFileName; }
/// \brief Set the main file name and override the default.
- void setMainFileName(StringRef S) { MainFileName = S.str(); }
+ void setMainFileName(StringRef S) { MainFileName = S; }
/// GetDwarfFile - creates an entry in the dwarf file and directory tables.
unsigned GetDwarfFile(StringRef Directory, StringRef FileName,
@@ -298,33 +314,32 @@ namespace llvm {
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 std::map<unsigned, MCDwarfLineTable> &getMCDwarfLineTables() const {
+ return MCDwarfLineTablesCUMap;
}
- const SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles(unsigned CUID = 0) {
- return MCDwarfFilesCUMap[CUID];
+ MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) {
+ return MCDwarfLineTablesCUMap[CUID];
}
- const SmallVectorImpl<StringRef> &getMCDwarfDirs(unsigned CUID = 0) {
- return MCDwarfDirsCUMap[CUID];
+
+ const MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) const {
+ auto I = MCDwarfLineTablesCUMap.find(CUID);
+ assert(I != MCDwarfLineTablesCUMap.end());
+ return I->second;
}
- const DenseMap<const MCSection *, MCLineSection *>
- &getMCLineSections() const {
- return MCLineSections;
+ const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles(unsigned CUID = 0) {
+ return getMCDwarfLineTable(CUID).getMCDwarfFiles();
}
- const std::vector<const MCSection *> &getMCLineSectionOrder() const {
- return MCLineSectionOrder;
+ const SmallVectorImpl<std::string> &getMCDwarfDirs(unsigned CUID = 0) {
+ return getMCDwarfLineTable(CUID).getMCDwarfDirs();
}
- void addMCLineSection(const MCSection *Sec, MCLineSection *Line) {
- MCLineSections[Sec] = Line;
- MCLineSectionOrder.push_back(Sec);
+
+ bool hasMCLineSections() const {
+ for (const auto &Table : MCDwarfLineTablesCUMap)
+ if (!Table.second.getMCDwarfFiles().empty() || Table.second.getLabel())
+ return true;
+ return false;
}
unsigned getDwarfCompileUnitID() {
return DwarfCompileUnitID;
@@ -332,18 +347,8 @@ namespace llvm {
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;
+ void setMCLineTableCompilationDir(unsigned CUID, StringRef CompilationDir) {
+ getMCDwarfLineTable(CUID).setCompilationDir(CompilationDir);
}
/// setCurrentDwarfLoc - saves the information from the currently parsed
@@ -369,22 +374,25 @@ namespace llvm {
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;
+ void setGenDwarfFileNumber(unsigned FileNumber) {
+ GenDwarfFileNumber = FileNumber;
+ }
+ MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> > &
+ getGenDwarfSectionSyms() {
+ return SectionStartEndSyms;
}
- MCSymbol *getGenDwarfSectionEndSym() { return GenDwarfSectionEndSym; }
- void setGenDwarfSectionEndSym(MCSymbol *Sym) {
- GenDwarfSectionEndSym = Sym;
+ std::pair<MapVector<const MCSection *,
+ std::pair<MCSymbol *, MCSymbol *> >::iterator,
+ bool>
+ addGenDwarfSection(const MCSection *Sec) {
+ return SectionStartEndSyms.insert(
+ std::make_pair(Sec, std::make_pair(nullptr, nullptr)));
}
- const std::vector<const MCGenDwarfLabelEntry *>
- &getMCGenDwarfLabelEntries() const {
+ void finalizeDwarfSections(MCStreamer &MCOS);
+ const std::vector<MCGenDwarfLabelEntry> &getMCGenDwarfLabelEntries() const {
return MCGenDwarfLabelEntries;
}
- void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry *E) {
+ void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry &E) {
MCGenDwarfLabelEntries.push_back(E);
}
@@ -394,6 +402,9 @@ namespace llvm {
void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; }
StringRef getDwarfDebugProducer() { return DwarfDebugProducer; }
+ void setDwarfVersion(uint16_t v) { DwarfVersion = v; }
+ uint16_t getDwarfVersion() const { return DwarfVersion; }
+
/// @}
char *getSecureLogFile() { return SecureLogFile; }
@@ -415,7 +426,7 @@ namespace llvm {
// Unrecoverable error has occurred. 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);
+ LLVM_ATTRIBUTE_NORETURN void FatalError(SMLoc L, const Twine &Msg) const;
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h
index 0461766c2fd3..f9d66e0b15d7 100644
--- a/include/llvm/MC/MCDirectives.h
+++ b/include/llvm/MC/MCDirectives.h
@@ -60,6 +60,11 @@ enum MCDataRegionType {
MCDR_DataRegionEnd ///< .end_data_region
};
+enum MCVersionMinType {
+ MCVM_IOSVersionMin, ///< .ios_version_min
+ MCVM_OSXVersionMin ///< .macosx_version_min
+};
+
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h
index 83f26ef3edb9..9d441bbd88fb 100644
--- a/include/llvm/MC/MCDisassembler.h
+++ b/include/llvm/MC/MCDisassembler.h
@@ -10,9 +10,8 @@
#define LLVM_MC_MCDISASSEMBLER_H
#include "llvm-c/Disassembler.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/MC/MCSymbolizer.h"
#include "llvm/MC/MCRelocationInfo.h"
+#include "llvm/MC/MCSymbolizer.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -56,10 +55,8 @@ public:
};
/// Constructor - Performs initial setup for the disassembler.
- MCDisassembler(const MCSubtargetInfo &STI) : GetOpInfo(0), SymbolLookUp(0),
- DisInfo(0), Ctx(0),
- STI(STI), Symbolizer(0),
- CommentStream(0) {}
+ MCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
+ : Ctx(Ctx), STI(STI), Symbolizer(), CommentStream(nullptr) {}
virtual ~MCDisassembler();
@@ -86,23 +83,12 @@ public:
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;
+ MCContext &Ctx;
protected:
// Subtarget information, for instruction decoding predicates if required.
const MCSubtargetInfo &STI;
- OwningPtr<MCSymbolizer> Symbolizer;
+ std::unique_ptr<MCSymbolizer> Symbolizer;
public:
// Helpers around MCSymbolizer
@@ -115,21 +101,9 @@ public:
/// Set \p Symzer as the current symbolizer.
/// This takes ownership of \p Symzer, and deletes the previously set one.
- void setSymbolizer(OwningPtr<MCSymbolizer> &Symzer);
-
- /// Sets up an external symbolizer that uses the C API callbacks.
- void setupForSymbolicDisassembly(LLVMOpInfoCallback GetOpInfo,
- LLVMSymbolLookupCallback SymbolLookUp,
- void *DisInfo,
- MCContext *Ctx,
- OwningPtr<MCRelocationInfo> &RelInfo);
-
- LLVMOpInfoCallback getLLVMOpInfoCallback() const { return GetOpInfo; }
- LLVMSymbolLookupCallback getLLVMSymbolLookupCallback() const {
- return SymbolLookUp;
- }
- void *getDisInfoBlock() const { return DisInfo; }
- MCContext *getMCContext() const { return Ctx; }
+ void setSymbolizer(std::unique_ptr<MCSymbolizer> Symzer);
+
+ MCContext& getContext() const { return Ctx; }
const MCSubtargetInfo& getSubtargetInfo() const { return STI; }
diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h
index 65b920bf232e..6cd9a9a21e21 100644
--- a/include/llvm/MC/MCDwarf.h
+++ b/include/llvm/MC/MCDwarf.h
@@ -15,16 +15,22 @@
#ifndef LLVM_MC_MCDWARF_H
#define LLVM_MC_MCDWARF_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <vector>
+#include <string>
+#include <utility>
namespace llvm {
class MCAsmBackend;
class MCContext;
+class MCObjectStreamer;
class MCSection;
class MCStreamer;
class MCSymbol;
@@ -36,41 +42,15 @@ class SMLoc;
/// 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 {
+struct MCDwarfFile {
// Name - the base name of the file without its directory path.
// The StringRef references memory allocated in the MCContext.
- StringRef Name;
+ std::string 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 {
@@ -168,62 +148,111 @@ public:
// 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);
+ static void Make(MCObjectStreamer *MCOS, const MCSection *Section);
};
/// MCLineSection - Instances of this class represent the line information
-/// for a section where machine instructions have been assembled after seeing
+/// for a compile unit 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);
+ void addLineEntry(const MCLineEntry &LineEntry, const MCSection *Sec) {
+ MCLineDivisions[Sec].push_back(LineEntry);
}
typedef std::vector<MCLineEntry> MCLineEntryCollection;
typedef MCLineEntryCollection::iterator iterator;
typedef MCLineEntryCollection::const_iterator const_iterator;
- typedef std::map<unsigned, MCLineEntryCollection> MCLineDivisionMap;
+ typedef MapVector<const MCSection *, MCLineEntryCollection> MCLineDivisionMap;
private:
- // A collection of MCLineEntry for each Compile Unit ID.
+ // A collection of MCLineEntry for each section.
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;
+ const MCLineDivisionMap &getMCLineEntries() const {
+ return MCLineDivisions;
}
};
-class MCDwarfFileTable {
+struct MCDwarfLineTableHeader {
+ MCSymbol *Label;
+ SmallVector<std::string, 3> MCDwarfDirs;
+ SmallVector<MCDwarfFile, 3> MCDwarfFiles;
+ StringMap<unsigned> SourceIdMap;
+ StringRef CompilationDir;
+
+ MCDwarfLineTableHeader() : Label(nullptr) {}
+ unsigned getFile(StringRef &Directory, StringRef &FileName,
+ unsigned FileNumber = 0);
+ std::pair<MCSymbol *, MCSymbol *> Emit(MCStreamer *MCOS) const;
+ std::pair<MCSymbol *, MCSymbol *>
+ Emit(MCStreamer *MCOS, ArrayRef<char> SpecialOpcodeLengths) const;
+};
+
+class MCDwarfDwoLineTable {
+ MCDwarfLineTableHeader Header;
+public:
+ void setCompilationDir(StringRef CompilationDir) {
+ Header.CompilationDir = CompilationDir;
+ }
+ unsigned getFile(StringRef Directory, StringRef FileName) {
+ return Header.getFile(Directory, FileName);
+ }
+ void Emit(MCStreamer &MCOS) const;
+};
+
+class MCDwarfLineTable {
+ MCDwarfLineTableHeader Header;
+ MCLineSection MCLineSections;
+
public:
- //
// This emits the Dwarf file and the line tables for all Compile Units.
- //
- static const MCSymbol *Emit(MCStreamer *MCOS);
- //
+ static void Emit(MCObjectStreamer *MCOS);
+
// This emits the Dwarf file and the line tables for a given Compile Unit.
- //
- static const MCSymbol *EmitCU(MCStreamer *MCOS, unsigned ID);
+ void EmitCU(MCObjectStreamer *MCOS) const;
+
+ unsigned getFile(StringRef &Directory, StringRef &FileName,
+ unsigned FileNumber = 0);
+
+ MCSymbol *getLabel() const {
+ return Header.Label;
+ }
+
+ void setLabel(MCSymbol *Label) {
+ Header.Label = Label;
+ }
+
+ void setCompilationDir(StringRef CompilationDir) {
+ Header.CompilationDir = CompilationDir;
+ }
+
+ const SmallVectorImpl<std::string> &getMCDwarfDirs() const {
+ return Header.MCDwarfDirs;
+ }
+
+ SmallVectorImpl<std::string> &getMCDwarfDirs() {
+ return Header.MCDwarfDirs;
+ }
+
+ const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() const {
+ return Header.MCDwarfFiles;
+ }
+
+ SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() {
+ return Header.MCDwarfFiles;
+ }
+
+ const MCLineSection &getMCLineSections() const {
+ return MCLineSections;
+ }
+ MCLineSection &getMCLineSections() {
+ return MCLineSections;
+ }
};
class MCDwarfLineAddr {
@@ -242,7 +271,7 @@ public:
// When generating dwarf for assembly source files this emits the Dwarf
// sections.
//
- static void Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol);
+ static void Emit(MCStreamer *MCOS);
};
// When generating dwarf for assembly source files this is the info that is
@@ -436,19 +465,19 @@ public:
struct MCDwarfFrameInfo {
MCDwarfFrameInfo()
- : Begin(0), End(0), Personality(0), Lsda(0), Function(0), Instructions(),
- PersonalityEncoding(), LsdaEncoding(0), CompactUnwindEncoding(0),
- IsSignalFrame(false) {}
+ : Begin(nullptr), End(nullptr), Personality(nullptr), Lsda(nullptr),
+ Instructions(), PersonalityEncoding(), LsdaEncoding(0),
+ CompactUnwindEncoding(0), IsSignalFrame(false), IsSimple(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;
+ bool IsSimple;
};
class MCDwarfFrameEmitter {
@@ -456,9 +485,8 @@ public:
//
// This emits the frame info section.
//
- static void Emit(MCStreamer &streamer, MCAsmBackend *MAB,
- bool usingCFI, bool isEH);
- static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta);
+ static void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH);
+ static void EmitAdvanceLoc(MCObjectStreamer &Streamer, uint64_t AddrDelta);
static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta,
raw_ostream &OS);
};
diff --git a/include/llvm/MC/MCELF.h b/include/llvm/MC/MCELF.h
index 7e59911a89c3..294a51bf7c76 100644
--- a/include/llvm/MC/MCELF.h
+++ b/include/llvm/MC/MCELF.h
@@ -27,9 +27,9 @@ class MCELF {
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 unsigned GetVisibility(const MCSymbolData &SD);
static void setOther(MCSymbolData &SD, unsigned Other);
- static unsigned getOther(MCSymbolData &SD);
+ static unsigned getOther(const MCSymbolData &SD);
};
}
diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h
index 92ad1b1a46fe..421e7a0b2c19 100644
--- a/include/llvm/MC/MCELFObjectWriter.h
+++ b/include/llvm/MC/MCELFObjectWriter.h
@@ -20,30 +20,11 @@ class MCAssembler;
class MCFixup;
class MCFragment;
class MCObjectWriter;
+class MCSectionData;
class MCSymbol;
+class MCSymbolData;
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) {}
-};
-
class MCELFObjectTargetWriter {
const uint8_t OSABI;
const uint16_t EMachine;
@@ -72,19 +53,10 @@ public:
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 sortRelocs(const MCAssembler &Asm,
- std::vector<ELFRelocationEntry> &Relocs);
+ bool IsPCRel) const = 0;
+
+ virtual bool needsRelocateWithSymbol(const MCSymbolData &SD,
+ unsigned Type) const;
/// @name Accessors
/// @{
@@ -107,16 +79,16 @@ public:
#define R_SSYM_MASK 0x00ffffff
// N64 relocation type accessors
- unsigned getRType(uint32_t Type) const {
+ uint8_t getRType(uint32_t Type) const {
return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff);
}
- unsigned getRType2(uint32_t Type) const {
+ uint8_t getRType2(uint32_t Type) const {
return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff);
}
- unsigned getRType3(uint32_t Type) const {
+ uint8_t getRType3(uint32_t Type) const {
return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff);
}
- unsigned getRSsym(uint32_t Type) const {
+ uint8_t getRSsym(uint32_t Type) const {
return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff);
}
diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h
index 4e24dcfacd50..66729fe0147e 100644
--- a/include/llvm/MC/MCELFStreamer.h
+++ b/include/llvm/MC/MCELFStreamer.h
@@ -29,70 +29,66 @@ class raw_ostream;
class MCELFStreamer : public MCObjectStreamer {
public:
- MCELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
- MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, TargetStreamer, TAB, OS, Emitter),
- SeenIdent(false) {}
+ MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter)
+ : MCObjectStreamer(Context, TAB, OS, Emitter),
+ SeenIdent(false) {}
- MCELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
- MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter,
- MCAssembler *Assembler)
- : MCObjectStreamer(Context, TargetStreamer, TAB, OS, Emitter, Assembler),
- SeenIdent(false) {}
+ MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter, MCAssembler *Assembler)
+ : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler),
+ SeenIdent(false) {}
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 bool 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();
+ void InitSections() override;
+ void ChangeSection(const MCSection *Section,
+ const MCExpr *Subsection) override;
+ void EmitLabel(MCSymbol *Symbol) override;
+ void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
+ void EmitThumbFunc(MCSymbol *Func) override;
+ void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
+ bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+ void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
+ void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+ void BeginCOFFSymbolDef(const MCSymbol *Symbol) override;
+ void EmitCOFFSymbolStorageClass(int StorageClass) override;
+ void EmitCOFFSymbolType(int Type) override;
+ void EndCOFFSymbolDef() override;
- virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol);
+ void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
- virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
+ void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
- virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment);
+ void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr,
+ uint64_t Size = 0, unsigned ByteAlignment = 0) override;
+ void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
+ uint64_t Size, unsigned ByteAlignment = 0) override;
+ void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ const SMLoc &Loc = SMLoc()) override;
- 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);
+ void EmitFileDirective(StringRef Filename) override;
- virtual void EmitFileDirective(StringRef Filename);
+ void EmitIdent(StringRef IdentString) override;
- virtual void EmitIdent(StringRef IdentString);
+ void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned) override;
- virtual void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned);
+ void Flush() override;
- virtual void Flush();
+ void FinishImpl() override;
- virtual void FinishImpl();
+ void EmitBundleAlignMode(unsigned AlignPow2) override;
+ void EmitBundleLock(bool AlignToEnd) override;
+ void EmitBundleUnlock() override;
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 EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override;
+ void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
void fixSymbolsInTLSFixups(const MCExpr *expr);
@@ -107,13 +103,6 @@ private:
std::vector<LocalCommon> LocalCommons;
SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
-
-
- void SetSection(StringRef Section, unsigned Type, unsigned Flags,
- SectionKind Kind);
- void SetSectionData();
- void SetSectionText();
- void SetSectionBss();
};
MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
diff --git a/include/llvm/MC/MCELFSymbolFlags.h b/include/llvm/MC/MCELFSymbolFlags.h
index d0e1dace99d1..297c44269a8f 100644
--- a/include/llvm/MC/MCELFSymbolFlags.h
+++ b/include/llvm/MC/MCELFSymbolFlags.h
@@ -21,10 +21,10 @@
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.
+ 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_STO_Shift = 10 // Shift value for STO_* flags.
};
enum ELFSymbolFlags {
@@ -41,16 +41,14 @@ namespace llvm {
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_GnuIFunc = (ELF::STT_GNU_IFUNC << 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)
+ ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift)
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index 5d559744da97..e96ecb4be175 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -15,11 +15,13 @@
#include "llvm/Support/DataTypes.h"
namespace llvm {
+class MCAsmInfo;
class MCAsmLayout;
class MCAssembler;
class MCContext;
class MCSection;
class MCSectionData;
+class MCStreamer;
class MCSymbol;
class MCValue;
class raw_ostream;
@@ -52,8 +54,9 @@ protected:
bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
- const SectionAddrMap *Addrs,
- bool InSet) const;
+ const SectionAddrMap *Addrs, bool InSet,
+ bool ForceVarExpansion) const;
+
public:
/// @name Accessors
/// @{
@@ -90,7 +93,15 @@ public:
/// @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;
+ bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout) const;
+
+ /// \brief Try to evaluate the expression to the form (a - b + constant) where
+ /// neither a nor b are variables.
+ ///
+ /// This is a more aggressive variant of EvaluateAsRelocatable. The intended
+ /// use is for when relocations are not available, like the symbol value in
+ /// the symbol table.
+ bool EvaluateAsValue(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
@@ -157,19 +168,24 @@ public:
VK_TLSLDM,
VK_TPOFF,
VK_DTPOFF,
- VK_TLVP, // Mach-O thread local variable relocation
+ VK_TLVP, // Mach-O thread local variable relocations
+ VK_TLVPPAGE,
+ VK_TLVPPAGEOFF,
+ VK_PAGE,
+ VK_PAGEOFF,
+ VK_GOTPAGE,
+ VK_GOTPAGEOFF,
VK_SECREL,
- // FIXME: We'd really like to use the generic Kinds listed above for these.
+ VK_WEAKREF, // The link between the symbols in .weakref foo, bar
+
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_ARM_TLSLDO, // symbol(tlsldo)
+ VK_ARM_TLSCALL, // symbol(tlscall)
+ VK_ARM_TLSDESC, // symbol(tlsdesc)
+ VK_ARM_TLSDESCSEQ,
VK_PPC_LO, // symbol@l
VK_PPC_HI, // symbol@h
@@ -247,6 +263,8 @@ public:
VK_Mips_GOT_LO16,
VK_Mips_CALL_HI16,
VK_Mips_CALL_LO16,
+ VK_Mips_PCREL_HI16,
+ VK_Mips_PCREL_LO16,
VK_COFF_IMGREL32 // symbol@imgrel (image-relative)
};
@@ -258,9 +276,14 @@ private:
/// The symbol reference modifier.
const VariantKind Kind;
- explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind)
- : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) {
+ /// MCAsmInfo that is used to print symbol variants correctly.
+ const MCAsmInfo *MAI;
+
+ explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind,
+ const MCAsmInfo *_MAI)
+ : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind), MAI(_MAI) {
assert(Symbol);
+ assert(MAI);
}
public:
@@ -281,6 +304,7 @@ public:
/// @{
const MCSymbol &getSymbol() const { return *Symbol; }
+ const MCAsmInfo &getMCAsmInfo() const { return *MAI; }
VariantKind getKind() const { return Kind; }
@@ -501,7 +525,7 @@ 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 void visitUsedExpr(MCStreamer& Streamer) const = 0;
virtual const MCSection *FindAssociatedSection() const = 0;
virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
diff --git a/include/llvm/MC/MCExternalSymbolizer.h b/include/llvm/MC/MCExternalSymbolizer.h
index c942adca3b4d..2c7d23707c95 100644
--- a/include/llvm/MC/MCExternalSymbolizer.h
+++ b/include/llvm/MC/MCExternalSymbolizer.h
@@ -18,6 +18,7 @@
#include "llvm-c/Disassembler.h"
#include "llvm/MC/MCSymbolizer.h"
+#include <memory>
namespace llvm {
@@ -25,7 +26,7 @@ namespace llvm {
///
/// See llvm-c/Disassembler.h.
class MCExternalSymbolizer : public MCSymbolizer {
-
+protected:
/// \name Hooks for symbolic disassembly via the public 'C' interface.
/// @{
/// The function to get the symbolic information for operands.
@@ -38,19 +39,18 @@ class MCExternalSymbolizer : public MCSymbolizer {
public:
MCExternalSymbolizer(MCContext &Ctx,
- OwningPtr<MCRelocationInfo> &RelInfo,
+ std::unique_ptr<MCRelocationInfo> RelInfo,
LLVMOpInfoCallback getOpInfo,
- LLVMSymbolLookupCallback symbolLookUp,
- void *disInfo)
- : MCSymbolizer(Ctx, RelInfo),
- GetOpInfo(getOpInfo), SymbolLookUp(symbolLookUp), DisInfo(disInfo) {}
+ LLVMSymbolLookupCallback symbolLookUp, void *disInfo)
+ : MCSymbolizer(Ctx, std::move(RelInfo)), GetOpInfo(getOpInfo),
+ SymbolLookUp(symbolLookUp), DisInfo(disInfo) {}
bool tryAddingSymbolicOperand(MCInst &MI, raw_ostream &CommentStream,
- int64_t Value,
- uint64_t Address, bool IsBranch,
- uint64_t Offset, uint64_t InstSize);
+ int64_t Value, uint64_t Address, bool IsBranch,
+ uint64_t Offset, uint64_t InstSize) override;
void tryAddingPcLoadReferenceComment(raw_ostream &CommentStream,
- int64_t Value, uint64_t Address);
+ int64_t Value,
+ uint64_t Address) override;
};
}
diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h
index 16e9eb730b4e..98a1419a1934 100644
--- a/include/llvm/MC/MCFixup.h
+++ b/include/llvm/MC/MCFixup.h
@@ -10,6 +10,7 @@
#ifndef LLVM_MC_MCFIXUP_H
#define LLVM_MC_MCFIXUP_H
+#include "llvm/MC/MCExpr.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SMLoc.h"
diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h
index 4766815da556..6918280a4219 100644
--- a/include/llvm/MC/MCInst.h
+++ b/include/llvm/MC/MCInst.h
@@ -184,18 +184,18 @@ public:
/// \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,
+ void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI = nullptr,
+ const MCInstPrinter *Printer = nullptr,
StringRef Separator = " ") const;
};
inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
- MO.print(OS, 0);
+ MO.print(OS, nullptr);
return OS;
}
inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
- MI.print(OS, 0);
+ MI.print(OS, nullptr);
return OS;
}
diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h
index b4258bef04ce..7f55b29f8ee0 100644
--- a/include/llvm/MC/MCInstPrinter.h
+++ b/include/llvm/MC/MCInstPrinter.h
@@ -57,8 +57,9 @@ protected:
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), PrintHexStyle(HexStyle::C) {}
+ : CommentStream(nullptr), MAI(mai), MII(mii), MRI(mri),
+ AvailableFeatures(0), UseMarkup(0), PrintImmHex(0),
+ PrintHexStyle(HexStyle::C) {}
virtual ~MCInstPrinter();
diff --git a/include/llvm/MC/MCInstrAnalysis.h b/include/llvm/MC/MCInstrAnalysis.h
index 17bfd1582ae5..e921f768ac45 100644
--- a/include/llvm/MC/MCInstrAnalysis.h
+++ b/include/llvm/MC/MCInstrAnalysis.h
@@ -12,6 +12,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_MC_MCINSTRANALYSIS_H
+#define LLVM_MC_MCINSTRANALYSIS_H
+
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
@@ -63,4 +66,6 @@ public:
uint64_t &Target) const;
};
-}
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h
index 214b593f4ad6..5896de7f76df 100644
--- a/include/llvm/MC/MCInstrDesc.h
+++ b/include/llvm/MC/MCInstrDesc.h
@@ -504,7 +504,7 @@ public:
/// \brief Return the number of implicit uses this instruction has.
unsigned getNumImplicitUses() const {
- if (ImplicitUses == 0) return 0;
+ if (!ImplicitUses) return 0;
unsigned i = 0;
for (; ImplicitUses[i]; ++i) /*empty*/;
return i;
@@ -526,7 +526,7 @@ public:
/// \brief Return the number of implicit defs this instruct has.
unsigned getNumImplicitDefs() const {
- if (ImplicitDefs == 0) return 0;
+ if (!ImplicitDefs) return 0;
unsigned i = 0;
for (; ImplicitDefs[i]; ++i) /*empty*/;
return i;
@@ -544,7 +544,7 @@ public:
/// \brief Return true if this instruction implicitly
/// defines the specified physical register.
bool hasImplicitDefOfPhysReg(unsigned Reg,
- const MCRegisterInfo *MRI = 0) const {
+ const MCRegisterInfo *MRI = nullptr) const {
if (const uint16_t *ImpDefs = ImplicitDefs)
for (; *ImpDefs; ++ImpDefs)
if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs)))
diff --git a/include/llvm/MC/MCInstrItineraries.h b/include/llvm/MC/MCInstrItineraries.h
index c4f9e1c32ab1..5104345e1abb 100644
--- a/include/llvm/MC/MCInstrItineraries.h
+++ b/include/llvm/MC/MCInstrItineraries.h
@@ -119,8 +119,8 @@ public:
/// Ctors.
///
InstrItineraryData() : SchedModel(&MCSchedModel::DefaultSchedModel),
- Stages(0), OperandCycles(0),
- Forwardings(0), Itineraries(0) {}
+ Stages(nullptr), OperandCycles(nullptr),
+ Forwardings(nullptr), Itineraries(nullptr) {}
InstrItineraryData(const MCSchedModel *SM, const InstrStage *S,
const unsigned *OS, const unsigned *F)
@@ -129,7 +129,7 @@ public:
/// isEmpty - Returns true if there are no itineraries.
///
- bool isEmpty() const { return Itineraries == 0; }
+ bool isEmpty() const { return Itineraries == nullptr; }
/// isEndMarker - Returns true if the index is for the end marker
/// itinerary.
diff --git a/include/llvm/MC/MCLinkerOptimizationHint.h b/include/llvm/MC/MCLinkerOptimizationHint.h
new file mode 100644
index 000000000000..50fd527ffe2a
--- /dev/null
+++ b/include/llvm/MC/MCLinkerOptimizationHint.h
@@ -0,0 +1,205 @@
+//===- MCLinkerOptimizationHint.h - LOH interface ---------------*- 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 some helpers classes to handle Linker Optimization Hint
+// (LOH).
+//
+// FIXME: LOH interface supports only MachO format at the moment.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
+#define LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCMachObjectWriter.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+// Forward declarations.
+class MCAsmLayout;
+class MCSymbol;
+
+/// Linker Optimization Hint Type.
+enum MCLOHType {
+ MCLOH_AdrpAdrp = 0x1u, ///< Adrp xY, _v1@PAGE -> Adrp xY, _v2@PAGE.
+ MCLOH_AdrpLdr = 0x2u, ///< Adrp _v@PAGE -> Ldr _v@PAGEOFF.
+ MCLOH_AdrpAddLdr = 0x3u, ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Ldr.
+ MCLOH_AdrpLdrGotLdr = 0x4u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Ldr.
+ MCLOH_AdrpAddStr = 0x5u, ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Str.
+ MCLOH_AdrpLdrGotStr = 0x6u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Str.
+ MCLOH_AdrpAdd = 0x7u, ///< Adrp _v@PAGE -> Add _v@PAGEOFF.
+ MCLOH_AdrpLdrGot = 0x8u ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF.
+};
+
+static inline StringRef MCLOHDirectiveName() {
+ return StringRef(".loh");
+}
+
+static inline bool isValidMCLOHType(MCLOHType Kind) {
+ return Kind >= MCLOH_AdrpAdrp && Kind <= MCLOH_AdrpLdrGot;
+}
+
+static inline int MCLOHNameToId(StringRef Name) {
+#define MCLOHCaseNameToId(Name) .Case(#Name, MCLOH_ ## Name)
+ return StringSwitch<int>(Name)
+ MCLOHCaseNameToId(AdrpAdrp)
+ MCLOHCaseNameToId(AdrpLdr)
+ MCLOHCaseNameToId(AdrpAddLdr)
+ MCLOHCaseNameToId(AdrpLdrGotLdr)
+ MCLOHCaseNameToId(AdrpAddStr)
+ MCLOHCaseNameToId(AdrpLdrGotStr)
+ MCLOHCaseNameToId(AdrpAdd)
+ MCLOHCaseNameToId(AdrpLdrGot)
+ .Default(-1);
+}
+
+static inline StringRef MCLOHIdToName(MCLOHType Kind) {
+#define MCLOHCaseIdToName(Name) case MCLOH_ ## Name: return StringRef(#Name);
+ switch (Kind) {
+ MCLOHCaseIdToName(AdrpAdrp);
+ MCLOHCaseIdToName(AdrpLdr);
+ MCLOHCaseIdToName(AdrpAddLdr);
+ MCLOHCaseIdToName(AdrpLdrGotLdr);
+ MCLOHCaseIdToName(AdrpAddStr);
+ MCLOHCaseIdToName(AdrpLdrGotStr);
+ MCLOHCaseIdToName(AdrpAdd);
+ MCLOHCaseIdToName(AdrpLdrGot);
+ }
+ return StringRef();
+}
+
+static inline int MCLOHIdToNbArgs(MCLOHType Kind) {
+ switch (Kind) {
+ // LOH with two arguments
+ case MCLOH_AdrpAdrp:
+ case MCLOH_AdrpLdr:
+ case MCLOH_AdrpAdd:
+ case MCLOH_AdrpLdrGot:
+ return 2;
+ // LOH with three arguments
+ case MCLOH_AdrpAddLdr:
+ case MCLOH_AdrpLdrGotLdr:
+ case MCLOH_AdrpAddStr:
+ case MCLOH_AdrpLdrGotStr:
+ return 3;
+ }
+ return -1;
+}
+
+/// Store Linker Optimization Hint information (LOH).
+class MCLOHDirective {
+ MCLOHType Kind;
+
+ /// Arguments of this directive. Order matters.
+ SmallVector<MCSymbol *, 3> Args;
+
+ /// Emit this directive in @p OutStream using the information available
+ /// in the given @p ObjWriter and @p Layout to get the address of the
+ /// arguments within the object file.
+ void Emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter,
+ const MCAsmLayout &Layout) const;
+
+public:
+ typedef SmallVectorImpl<MCSymbol *> LOHArgs;
+
+ MCLOHDirective(MCLOHType Kind, const LOHArgs &Args)
+ : Kind(Kind), Args(Args.begin(), Args.end()) {
+ assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!");
+ }
+
+ MCLOHType getKind() const { return Kind; }
+
+ const LOHArgs &getArgs() const { return Args; }
+
+ /// Emit this directive as:
+ /// <kind, numArgs, addr1, ..., addrN>
+ void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {
+ raw_ostream &OutStream = ObjWriter.getStream();
+ Emit_impl(OutStream, ObjWriter, Layout);
+ }
+
+ /// Get the size in bytes of this directive if emitted in @p ObjWriter with
+ /// the given @p Layout.
+ uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
+ const MCAsmLayout &Layout) const {
+ class raw_counting_ostream : public raw_ostream {
+ uint64_t Count;
+
+ void write_impl(const char *, size_t size) override { Count += size; }
+
+ uint64_t current_pos() const override { return Count; }
+
+ public:
+ raw_counting_ostream() : Count(0) {}
+ ~raw_counting_ostream() { flush(); }
+ };
+
+ raw_counting_ostream OutStream;
+ Emit_impl(OutStream, ObjWriter, Layout);
+ return OutStream.tell();
+ }
+};
+
+class MCLOHContainer {
+ /// Keep track of the emit size of all the LOHs.
+ mutable uint64_t EmitSize;
+
+ /// Keep track of all LOH directives.
+ SmallVector<MCLOHDirective, 32> Directives;
+
+public:
+ typedef SmallVectorImpl<MCLOHDirective> LOHDirectives;
+
+ MCLOHContainer() : EmitSize(0) {};
+
+ /// Const accessor to the directives.
+ const LOHDirectives &getDirectives() const {
+ return Directives;
+ }
+
+ /// Add the directive of the given kind @p Kind with the given arguments
+ /// @p Args to the container.
+ void addDirective(MCLOHType Kind, const MCLOHDirective::LOHArgs &Args) {
+ Directives.push_back(MCLOHDirective(Kind, Args));
+ }
+
+ /// Get the size of the directives if emitted.
+ uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
+ const MCAsmLayout &Layout) const {
+ if (!EmitSize) {
+ for (const MCLOHDirective &D : Directives)
+ EmitSize += D.getEmitSize(ObjWriter, Layout);
+ }
+ return EmitSize;
+ }
+
+ /// Emit all Linker Optimization Hint in one big table.
+ /// Each line of the table is emitted by LOHDirective::Emit.
+ void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {
+ for (const MCLOHDirective &D : Directives)
+ D.Emit(ObjWriter, Layout);
+ }
+
+ void reset() {
+ Directives.clear();
+ EmitSize = 0;
+ }
+};
+
+// Add types for specialized template using MCSymbol.
+typedef MCLOHDirective::LOHArgs MCLOHArgs;
+typedef MCLOHContainer::LOHDirectives MCLOHDirectives;
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h
index 3ba6e651007c..12a7f0ee7bb5 100644
--- a/include/llvm/MC/MCMachObjectWriter.h
+++ b/include/llvm/MC/MCMachObjectWriter.h
@@ -11,7 +11,6 @@
#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"
@@ -92,7 +91,7 @@ class MachObjectWriter : public MCObjectWriter {
};
/// The target specific Mach-O writer instance.
- llvm::OwningPtr<MCMachObjectTargetWriter> TargetObjectWriter;
+ std::unique_ptr<MCMachObjectTargetWriter> TargetObjectWriter;
/// @name Relocation Data
/// @{
@@ -112,6 +111,8 @@ class MachObjectWriter : public MCObjectWriter {
/// @}
+ MachSymbolData *findSymbolData(const MCSymbol &Sym);
+
public:
MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS,
bool _IsLittleEndian)
@@ -121,7 +122,7 @@ public:
/// @name Lifetime management Methods
/// @{
- virtual void reset();
+ void reset() override;
/// @}
@@ -154,9 +155,9 @@ public:
/// @{
bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
- bool isARM() const {
- uint32_t CPUType = TargetObjectWriter->getCPUType() & ~MachO::CPU_ARCH_MASK;
- return CPUType == MachO::CPU_TYPE_ARM;
+ bool isX86_64() const {
+ uint32_t CPUType = TargetObjectWriter->getCPUType();
+ return CPUType == MachO::CPU_TYPE_X86_64;
}
/// @}
@@ -231,7 +232,8 @@ public:
void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
- MCValue Target, uint64_t &FixedValue);
+ MCValue Target, bool &IsPCRel,
+ uint64_t &FixedValue) override;
void BindIndirectSymbols(MCAssembler &Asm);
@@ -248,15 +250,16 @@ public:
void markAbsoluteVariableSymbols(MCAssembler &Asm,
const MCAsmLayout &Layout);
- void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout);
+ void ExecutePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) override;
- virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
- const MCSymbolData &DataA,
- const MCFragment &FB,
- bool InSet,
- bool IsPCRel) const;
+ bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const override;
- void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
+ void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
};
diff --git a/include/llvm/MC/MCObjectDisassembler.h b/include/llvm/MC/MCObjectDisassembler.h
index 0d87d33bab98..5b935db59585 100644
--- a/include/llvm/MC/MCObjectDisassembler.h
+++ b/include/llvm/MC/MCObjectDisassembler.h
@@ -16,7 +16,6 @@
#define LLVM_MC_MCOBJECTDISASSEMBLER_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MemoryObject.h"
@@ -67,8 +66,8 @@ public:
/// \brief Set the region on which to fallback if disassembly was requested
/// somewhere not accessible in the object file.
/// This is used for dynamic disassembly (see RawMemoryObject).
- void setFallbackRegion(OwningPtr<MemoryObject> &Region) {
- FallbackRegion.reset(Region.take());
+ void setFallbackRegion(std::unique_ptr<MemoryObject> &Region) {
+ FallbackRegion.reset(Region.release());
}
/// \brief Set the symbolizer to use to get information on external functions.
@@ -113,7 +112,7 @@ protected:
MCObjectSymbolizer *MOS;
/// \brief The fallback memory region, outside the object file.
- OwningPtr<MemoryObject> FallbackRegion;
+ std::unique_ptr<MemoryObject> FallbackRegion;
/// \brief Return a memory region suitable for reading starting at \p Addr.
/// In most cases, this returns a StringRefMemoryObject backed by the
@@ -162,12 +161,12 @@ public:
uint64_t HeaderLoadAddress);
protected:
- uint64_t getEffectiveLoadAddr(uint64_t Addr) LLVM_OVERRIDE;
- uint64_t getOriginalLoadAddr(uint64_t EffectiveAddr) LLVM_OVERRIDE;
- uint64_t getEntrypoint() LLVM_OVERRIDE;
+ uint64_t getEffectiveLoadAddr(uint64_t Addr) override;
+ uint64_t getOriginalLoadAddr(uint64_t EffectiveAddr) override;
+ uint64_t getEntrypoint() override;
- ArrayRef<uint64_t> getStaticInitFunctions() LLVM_OVERRIDE;
- ArrayRef<uint64_t> getStaticExitFunctions() LLVM_OVERRIDE;
+ ArrayRef<uint64_t> getStaticInitFunctions() override;
+ ArrayRef<uint64_t> getStaticExitFunctions() override;
};
}
diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h
index c48dcb021620..4d1715eccf5a 100644
--- a/include/llvm/MC/MCObjectFileInfo.h
+++ b/include/llvm/MC/MCObjectFileInfo.h
@@ -14,13 +14,13 @@
#ifndef LLVM_MC_MCBJECTFILEINFO_H
#define LLVM_MC_MCBJECTFILEINFO_H
+#include "llvm/ADT/Triple.h"
#include "llvm/Support/CodeGen.h"
namespace llvm {
class MCContext;
class MCSection;
class StringRef;
- class Triple;
class MCObjectFileInfo {
protected:
@@ -33,17 +33,15 @@ protected:
/// 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;
+ /// SupportsCompactUnwindWithoutEHFrame - True if the target object file
+ /// supports emitting a compact unwind section without an associated EH frame
+ /// section.
+ bool SupportsCompactUnwindWithoutEHFrame;
- /// PersonalityEncoding, LSDAEncoding, FDEEncoding, TTypeEncoding - Some
- /// encoding values for EH.
+ /// PersonalityEncoding, LSDAEncoding, TTypeEncoding - Some encoding values
+ /// for EH.
unsigned PersonalityEncoding;
unsigned LSDAEncoding;
- unsigned FDEEncoding;
unsigned FDECFIEncoding;
unsigned TTypeEncoding;
@@ -129,6 +127,8 @@ protected:
const MCSection *DwarfGnuPubNamesSection;
const MCSection *DwarfGnuPubTypesSection;
+ const MCSection *COFFDebugSymbolsSection;
+
// Extra TLS Variable Data section. If the target needs to put additional
// information for a TLS variable, it'll go here.
const MCSection *TLSExtraDataSection;
@@ -195,21 +195,19 @@ public:
void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM,
MCContext &ctx);
- bool isFunctionEHFrameSymbolPrivate() const {
- return IsFunctionEHFrameSymbolPrivate;
- }
bool getSupportsWeakOmittedEHFrame() const {
return SupportsWeakOmittedEHFrame;
}
+ bool getSupportsCompactUnwindWithoutEHFrame() const {
+ return SupportsCompactUnwindWithoutEHFrame;
+ }
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 getFDEEncoding() const { return FDECFIEncoding; }
unsigned getTTypeEncoding() const { return TTypeEncoding; }
unsigned getCompactUnwindDwarfEHFrameOnly() const {
@@ -262,6 +260,8 @@ public:
const MCSection *getDwarfInfoDWOSection() const {
return DwarfInfoDWOSection;
}
+ const MCSection *getDwarfTypesSection(uint64_t Hash) const;
+ const MCSection *getDwarfTypesDWOSection(uint64_t Hash) const;
const MCSection *getDwarfAbbrevDWOSection() const {
return DwarfAbbrevDWOSection;
}
@@ -281,6 +281,10 @@ public:
return DwarfAddrSection;
}
+ const MCSection *getCOFFDebugSymbolsSection() const {
+ return COFFDebugSymbolsSection;
+ }
+
const MCSection *getTLSExtraDataSection() const {
return TLSExtraDataSection;
}
@@ -353,12 +357,21 @@ public:
return EHFrameSection;
}
-private:
enum Environment { IsMachO, IsELF, IsCOFF };
+ Environment getObjectFileType() const {
+ return Env;
+ }
+
+ Reloc::Model getRelocM() const {
+ return RelocM;
+ }
+
+private:
Environment Env;
Reloc::Model RelocM;
CodeModel::Model CMModel;
MCContext *Ctx;
+ Triple TT;
void InitMachOMCObjectFileInfo(Triple T);
void InitELFMCObjectFileInfo(Triple T);
@@ -367,6 +380,9 @@ private:
/// InitEHFrameSection - Initialize EHFrameSection on demand.
///
void InitEHFrameSection();
+
+public:
+ const Triple &getTargetTriple() const { return TT; }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index 56675443015e..8d37c85b0585 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -17,6 +17,7 @@ namespace llvm {
class MCAssembler;
class MCCodeEmitter;
class MCSectionData;
+class MCSubtargetInfo;
class MCExpr;
class MCFragment;
class MCDataFragment;
@@ -34,23 +35,32 @@ class MCObjectStreamer : public MCStreamer {
MCAssembler *Assembler;
MCSectionData *CurSectionData;
MCSectionData::iterator CurInsertionPoint;
+ bool EmitEHFrame;
+ bool EmitDebugFrame;
- virtual void EmitInstToData(const MCInst &Inst) = 0;
- virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
- virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame);
+ virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0;
+ void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
+ void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
protected:
- MCObjectStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
- MCAsmBackend &TAB, raw_ostream &_OS,
+ MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS,
MCCodeEmitter *_Emitter);
- MCObjectStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
- MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter,
- MCAssembler *_Assembler);
+ MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS,
+ MCCodeEmitter *_Emitter, MCAssembler *_Assembler);
~MCObjectStreamer();
public:
/// state management
- virtual void reset();
+ void reset() override;
+
+ /// Object streamers require the integrated assembler.
+ bool isIntegratedAssemblerRequired() const override { return true; }
+
+ MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) {
+ return getAssembler().getOrCreateSymbolData(*Symbol);
+ }
+ void EmitFrames(MCAsmBackend *MAB);
+ void EmitCFISections(bool EH, bool Debug) override;
protected:
MCSectionData *getCurrentSectionData() const {
@@ -68,55 +78,57 @@ protected:
/// fragment is not a data fragment.
MCDataFragment *getOrCreateDataFragment() const;
- const MCExpr *AddValueSymbols(const MCExpr *Value);
-
public:
+ void visitUsedSymbol(const MCSymbol &Sym) override;
+
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);
- 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);
+ void EmitLabel(MCSymbol *Symbol) override;
+ void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
+ void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ const SMLoc &Loc = SMLoc()) override;
+ void EmitULEB128Value(const MCExpr *Value) override;
+ void EmitSLEB128Value(const MCExpr *Value) override;
+ void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
+ void ChangeSection(const MCSection *Section,
+ const MCExpr *Subsection) override;
+ void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo& STI) override;
/// \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);
- 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 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);
- 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);
- virtual void EmitZeros(uint64_t NumBytes);
- virtual void FinishImpl();
+ virtual void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &);
+
+ void EmitBundleAlignMode(unsigned AlignPow2) override;
+ void EmitBundleLock(bool AlignToEnd) override;
+ void EmitBundleUnlock() override;
+ void EmitBytes(StringRef Data) override;
+ void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
+ unsigned ValueSize = 1,
+ unsigned MaxBytesToEmit = 0) override;
+ void EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit = 0) override;
+ bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value) override;
+ void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
+ unsigned Column, unsigned Flags,
+ unsigned Isa, unsigned Discriminator,
+ StringRef FileName) override;
+ void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
+ const MCSymbol *Label,
+ unsigned PointerSize);
+ void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
+ const MCSymbol *Label);
+ void EmitGPRel32Value(const MCExpr *Value) override;
+ void EmitGPRel64Value(const MCExpr *Value) override;
+ void EmitFill(uint64_t NumBytes, uint8_t FillValue) override;
+ void EmitZeros(uint64_t NumBytes) override;
+ void FinishImpl() override;
+
+ virtual bool mayHaveInstructions() const {
+ return getCurrentSectionData()->hasInstructions();
+ }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCObjectSymbolizer.h b/include/llvm/MC/MCObjectSymbolizer.h
index 64b932ebe4f9..f75b7f58a141 100644
--- a/include/llvm/MC/MCObjectSymbolizer.h
+++ b/include/llvm/MC/MCObjectSymbolizer.h
@@ -41,7 +41,7 @@ protected:
const object::RelocationRef *findRelocationAt(uint64_t Addr);
const object::SectionRef *findSectionContaining(uint64_t Addr);
- MCObjectSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo,
+ MCObjectSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> RelInfo,
const object::ObjectFile *Obj);
public:
@@ -50,10 +50,11 @@ public:
bool tryAddingSymbolicOperand(MCInst &MI, raw_ostream &cStream,
int64_t Value, uint64_t Address,
bool IsBranch, uint64_t Offset,
- uint64_t InstSize);
+ uint64_t InstSize) override;
void tryAddingPcLoadReferenceComment(raw_ostream &cStream,
- int64_t Value, uint64_t Address);
+ int64_t Value,
+ uint64_t Address) override;
/// @}
/// \brief Look for an external function symbol at \p Addr.
@@ -63,8 +64,9 @@ public:
/// \brief Create an object symbolizer for \p Obj.
static MCObjectSymbolizer *
- createObjectSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo,
- const object::ObjectFile *Obj);
+ createObjectSymbolizer(MCContext &Ctx,
+ std::unique_ptr<MCRelocationInfo> RelInfo,
+ const object::ObjectFile *Obj);
private:
typedef DenseMap<uint64_t, object::RelocationRef> AddrToRelocMap;
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
index 4939a3f1fb07..55c828c6c179 100644
--- a/include/llvm/MC/MCObjectWriter.h
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -80,6 +80,7 @@ public:
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
+ bool &IsPCRel,
uint64_t &FixedValue) = 0;
/// \brief Check whether the difference (A - B) between two symbol
diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h
index 1b3ab577519b..0b550ba627e9 100644
--- a/include/llvm/MC/MCParser/AsmLexer.h
+++ b/include/llvm/MC/MCParser/AsmLexer.h
@@ -28,7 +28,7 @@ class AsmLexer : public MCAsmLexer {
const MCAsmInfo &MAI;
const char *CurPtr;
- const MemoryBuffer *CurBuf;
+ StringRef CurBuf;
bool isAtStartOfLine;
void operator=(const AsmLexer&) LLVM_DELETED_FUNCTION;
@@ -36,17 +36,19 @@ class AsmLexer : public MCAsmLexer {
protected:
/// LexToken - Read the next token and return its code.
- virtual AsmToken LexToken();
+ AsmToken LexToken() override;
public:
AsmLexer(const MCAsmInfo &MAI);
~AsmLexer();
- void setBuffer(const MemoryBuffer *buf, const char *ptr = NULL);
+ void setBuffer(StringRef Buf, const char *ptr = nullptr);
- virtual StringRef LexUntilEndOfStatement();
+ StringRef LexUntilEndOfStatement() override;
StringRef LexUntilEndOfLine();
+ const AsmToken peekTok(bool ShouldSkipSpace = true) override;
+
bool isAtStartOfComment(char Char);
bool isAtStatementSeparator(const char *Ptr);
diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h
index 53b380f12f71..e3d4181e086f 100644
--- a/include/llvm/MC/MCParser/MCAsmLexer.h
+++ b/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -10,6 +10,7 @@
#ifndef LLVM_MC_MCPARSER_MCASMLEXER_H
#define LLVM_MC_MCPARSER_MCASMLEXER_H
+#include "llvm/ADT/APInt.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
@@ -30,6 +31,7 @@ public:
// Integer values.
Integer,
+ BigNum, // larger than 64 bits
// Real values.
Real,
@@ -57,12 +59,14 @@ private:
/// a memory buffer owned by the source manager.
StringRef Str;
- int64_t IntVal;
+ APInt IntVal;
public:
AsmToken() {}
- AsmToken(TokenKind _Kind, StringRef _Str, int64_t _IntVal = 0)
+ AsmToken(TokenKind _Kind, StringRef _Str, APInt _IntVal)
: Kind(_Kind), Str(_Str), IntVal(_IntVal) {}
+ AsmToken(TokenKind _Kind, StringRef _Str, int64_t _IntVal = 0)
+ : Kind(_Kind), Str(_Str), IntVal(64, _IntVal, true) {}
TokenKind getKind() const { return Kind; }
bool is(TokenKind K) const { return Kind == K; }
@@ -99,6 +103,12 @@ public:
// 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.getZExtValue();
+ }
+
+ APInt getAPIntVal() const {
+ assert((Kind == Integer || Kind == BigNum) &&
+ "This token isn't an integer!");
return IntVal;
}
};
@@ -118,6 +128,7 @@ class MCAsmLexer {
protected: // Can only create subclasses.
const char *TokStart;
bool SkipSpace;
+ bool AllowAtInIdentifier;
MCAsmLexer();
@@ -149,6 +160,9 @@ public:
return CurTok;
}
+ /// peekTok - Look ahead at the next token to be lexed.
+ virtual const AsmToken peekTok(bool ShouldSkipSpace = true) = 0;
+
/// getErrLoc - Get the current error location
const SMLoc &getErrLoc() {
return ErrLoc;
@@ -170,6 +184,9 @@ public:
/// setSkipSpace - Set whether spaces should be ignored by the lexer
void setSkipSpace(bool val) { SkipSpace = val; }
+
+ bool getAllowAtInIdentifier() { return AllowAtInIdentifier; }
+ void setAllowAtInIdentifier(bool v) { AllowAtInIdentifier = v; }
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h
index 1d1553429994..9836795450ff 100644
--- a/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/include/llvm/MC/MCParser/MCAsmParser.h
@@ -30,23 +30,24 @@ class SMRange;
class SourceMgr;
class Twine;
+class InlineAsmIdentifierInfo {
+public:
+ void *OpDecl;
+ bool IsVarDecl;
+ unsigned Length, Size, Type;
+
+ void clear() {
+ OpDecl = nullptr;
+ IsVarDecl = false;
+ Length = 1;
+ Size = 0;
+ Type = 0;
+ }
+};
+
/// MCAsmParserSemaCallback - Generic Sema callback for assembly parser.
class MCAsmParserSemaCallback {
public:
- typedef struct {
- void *OpDecl;
- bool IsVarDecl;
- unsigned Length, Size, Type;
-
- void clear() {
- OpDecl = 0;
- IsVarDecl = false;
- Length = 1;
- Size = 0;
- Type = 0;
- }
- } InlineAsmIdentifierInfo;
-
virtual ~MCAsmParserSemaCallback();
virtual void *LookupInlineAsmIdentifier(StringRef &LineBuf,
InlineAsmIdentifierInfo &Info,
@@ -56,9 +57,6 @@ public:
unsigned &Offset) = 0;
};
-typedef MCAsmParserSemaCallback::InlineAsmIdentifierInfo
- InlineAsmIdentifierInfo;
-
/// MCAsmParser - Generic assembler parser interface, for use by target specific
/// assembly parsers.
class MCAsmParser {
@@ -118,6 +116,10 @@ public:
const MCInstPrinter *IP,
MCAsmParserSemaCallback &SI) = 0;
+ /// Note - Emit a note at the location \p L, with the message \p Msg.
+ virtual void Note(SMLoc L, const Twine &Msg,
+ ArrayRef<SMRange> Ranges = None) = 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.
diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
index 818fbbd6c6c8..e8740aa10aa2 100644
--- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h
+++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
@@ -38,7 +38,7 @@ public:
unsigned getMCOperandNum() { return MCOperandNum; }
virtual StringRef getSymName() { return StringRef(); }
- virtual void *getOpDecl() { return 0; }
+ virtual void *getOpDecl() { return nullptr; }
/// isToken - Is this a token operand?
virtual bool isToken() const = 0;
diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h
index 3fa89c109c1c..766f63182925 100644
--- a/include/llvm/MC/MCRegisterInfo.h
+++ b/include/llvm/MC/MCRegisterInfo.h
@@ -159,7 +159,7 @@ private:
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 (*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
@@ -191,7 +191,7 @@ public:
protected:
/// Create an invalid iterator. Call init() to point to something useful.
- DiffListIterator() : Val(0), List(0) {}
+ DiffListIterator() : Val(0), List(nullptr) {}
/// init - Point the iterator to InitVal, decoding subsequent values from
/// DiffList. The iterator will initially point to InitVal, sub-classes are
@@ -223,7 +223,7 @@ public:
void operator++() {
// The end of the list is encoded as a 0 differential.
if (!advance())
- List = 0;
+ List = nullptr;
}
};
@@ -239,7 +239,7 @@ public:
void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA,
unsigned PC,
const MCRegisterClass *C, unsigned NC,
- const uint16_t (*RURoots)[2],
+ const MCPhysReg (*RURoots)[2],
unsigned NRU,
const MCPhysReg *DL,
const char *Strings,
diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h
index 6881e1d05ac3..43b8672265c6 100644
--- a/include/llvm/MC/MCSchedule.h
+++ b/include/llvm/MC/MCSchedule.h
@@ -32,11 +32,16 @@ struct MCProcResourceDesc {
// Number of resources that may be buffered.
//
- // Buffered resources (BufferSize > 0 || BufferSize == -1) may be consumed at
- // some indeterminate cycle after dispatch (e.g. for instructions that may
- // issue out-of-order). Unbuffered resources (BufferSize == 0) always consume
- // their resource some fixed number of cycles after dispatch (e.g. for
- // instruction interlocking that may stall the pipeline).
+ // Buffered resources (BufferSize != 0) may be consumed at some indeterminate
+ // cycle after dispatch. This should be used for out-of-order cpus when
+ // instructions that use this resource can be buffered in a reservaton
+ // station.
+ //
+ // Unbuffered resources (BufferSize == 0) always consume their resource some
+ // fixed number of cycles after dispatch. If a resource is unbuffered, then
+ // the scheduler will avoid scheduling instructions with conflicting resources
+ // in the same cycle. This is for in-order cpus, or the in-order portion of
+ // an out-of-order cpus.
int BufferSize;
bool operator==(const MCProcResourceDesc &Other) const {
@@ -149,11 +154,19 @@ public:
// but we balance those stalls against other heuristics.
//
// "> 1" means the processor is out-of-order. This is a machine independent
- // estimate of highly machine specific characteristics such are the register
+ // estimate of highly machine specific characteristics such as the register
// renaming pool and reorder buffer.
unsigned MicroOpBufferSize;
static const unsigned DefaultMicroOpBufferSize = 0;
+ // LoopMicroOpBufferSize is the number of micro-ops that the processor may
+ // buffer for optimized loop execution. More generally, this represents the
+ // optimal number of micro-ops in a loop body. A loop may be partially
+ // unrolled to bring the count of micro-ops in the loop body closer to this
+ // number.
+ unsigned LoopMicroOpBufferSize;
+ static const unsigned DefaultLoopMicroOpBufferSize = 0;
+
// LoadLatency is the expected latency of load instructions.
//
// If MinLatency >= 0, this may be overriden for individual load opcodes by
@@ -173,6 +186,8 @@ public:
// takes to recover from a branch misprediction.
unsigned MispredictPenalty;
static const unsigned DefaultMispredictPenalty = 10;
+
+ bool PostRAScheduler; // default value is false
bool CompleteModel;
@@ -193,24 +208,27 @@ public:
// MCSchedModel instead of using a generated itinerary.
MCSchedModel(): IssueWidth(DefaultIssueWidth),
MicroOpBufferSize(DefaultMicroOpBufferSize),
+ LoopMicroOpBufferSize(DefaultLoopMicroOpBufferSize),
LoadLatency(DefaultLoadLatency),
HighLatency(DefaultHighLatency),
MispredictPenalty(DefaultMispredictPenalty),
- CompleteModel(true),
- ProcID(0), ProcResourceTable(0), SchedClassTable(0),
- NumProcResourceKinds(0), NumSchedClasses(0),
- InstrItineraries(0) {
+ PostRAScheduler(false), CompleteModel(true),
+ ProcID(0), ProcResourceTable(nullptr),
+ SchedClassTable(nullptr), NumProcResourceKinds(0),
+ NumSchedClasses(0), InstrItineraries(nullptr) {
(void)NumProcResourceKinds;
(void)NumSchedClasses;
}
// Table-gen driven ctor.
- MCSchedModel(unsigned iw, int mbs, unsigned ll, unsigned hl,
- unsigned mp, bool cm, unsigned pi, const MCProcResourceDesc *pr,
- const MCSchedClassDesc *sc, unsigned npr, unsigned nsc,
- const InstrItinerary *ii):
- IssueWidth(iw), MicroOpBufferSize(mbs), LoadLatency(ll), HighLatency(hl),
- MispredictPenalty(mp), CompleteModel(cm), ProcID(pi),
+ MCSchedModel(unsigned iw, int mbs, int lmbs, unsigned ll, unsigned hl,
+ unsigned mp, bool postRASched, bool cm, unsigned pi,
+ const MCProcResourceDesc *pr, const MCSchedClassDesc *sc,
+ unsigned npr, unsigned nsc, const InstrItinerary *ii):
+ IssueWidth(iw), MicroOpBufferSize(mbs), LoopMicroOpBufferSize(lmbs),
+ LoadLatency(ll), HighLatency(hl),
+ MispredictPenalty(mp), PostRAScheduler(postRASched),
+ CompleteModel(cm), ProcID(pi),
ProcResourceTable(pr), SchedClassTable(sc), NumProcResourceKinds(npr),
NumSchedClasses(nsc), InstrItineraries(ii) {}
diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
index 45c84ae71eeb..0bbf3696686e 100644
--- a/include/llvm/MC/MCSectionCOFF.h
+++ b/include/llvm/MC/MCSectionCOFF.h
@@ -36,30 +36,21 @@ class MCSymbol;
/// The COMDAT symbol of this section. Only valid if this is a COMDAT
/// section. Two COMDAT sections are merged if they have the same
/// COMDAT symbol.
- const MCSymbol *COMDATSymbol;
+ MCSymbol *COMDATSymbol;
/// Selection - This is the Selection field for the section symbol, if
/// it is a COMDAT section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
mutable int Selection;
- /// Assoc - This is name of the associated section, if it is a COMDAT
- /// section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0 with an
- /// associative Selection (IMAGE_COMDAT_SELECT_ASSOCIATIVE).
- mutable const MCSectionCOFF *Assoc;
-
private:
friend class MCContext;
MCSectionCOFF(StringRef Section, unsigned Characteristics,
- const MCSymbol *COMDATSymbol, int Selection,
- const MCSectionCOFF *Assoc, SectionKind K)
+ MCSymbol *COMDATSymbol, int Selection, SectionKind K)
: MCSection(SV_COFF, K), SectionName(Section),
Characteristics(Characteristics), COMDATSymbol(COMDATSymbol),
- Selection(Selection), Assoc(Assoc) {
+ Selection(Selection) {
assert ((Characteristics & 0x00F00000) == 0 &&
"alignment must not be set upon section creation");
- assert ((Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) ==
- (Assoc != 0) &&
- "associative COMDAT section must have an associated section");
}
~MCSectionCOFF();
@@ -69,23 +60,22 @@ class MCSymbol;
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
StringRef getSectionName() const { return SectionName; }
- virtual std::string getLabelBeginName() const {
+ std::string getLabelBeginName() const override {
return SectionName.str() + "_begin";
}
- virtual std::string getLabelEndName() const {
+ std::string getLabelEndName() const override {
return SectionName.str() + "_end";
}
unsigned getCharacteristics() const { return Characteristics; }
+ MCSymbol *getCOMDATSymbol() const { return COMDATSymbol; }
int getSelection() const { return Selection; }
- const MCSectionCOFF *getAssocSection() const { return Assoc; }
- void setSelection(int Selection, const MCSectionCOFF *Assoc = 0) const;
+ void setSelection(int Selection) const;
- virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
- raw_ostream &OS,
- const MCExpr *Subsection) const;
- virtual bool UseCodeAlign() const;
- virtual bool isVirtualSection() const;
+ void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+ const MCExpr *Subsection) const override;
+ bool UseCodeAlign() const override;
+ bool isVirtualSection() const override;
static bool classof(const MCSection *S) {
return S->getVariant() == SV_COFF;
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
index 59799158ad3c..5ec23f1afad2 100644
--- a/include/llvm/MC/MCSectionELF.h
+++ b/include/llvm/MC/MCSectionELF.h
@@ -14,8 +14,9 @@
#ifndef LLVM_MC_MCSECTIONELF_H
#define LLVM_MC_MCSECTIONELF_H
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/raw_ostream.h"
@@ -52,6 +53,9 @@ private:
: MCSection(SV_ELF, K), SectionName(Section), Type(type), Flags(flags),
EntrySize(entrySize), Group(group) {}
~MCSectionELF();
+
+ void setSectionName(StringRef Name) { SectionName = Name; }
+
public:
/// ShouldOmitSectionDirective - Decides whether a '.section' directive
@@ -59,9 +63,14 @@ public:
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 {
+ std::string getLabelBeginName() const override {
+ if (Group)
+ return (SectionName.str() + '_' + Group->getName() + "_begin").str();
+ return SectionName.str() + "_begin";
+ }
+ std::string getLabelEndName() const override {
+ if (Group)
+ return (SectionName.str() + '_' + Group->getName() + "_end").str();
return SectionName.str() + "_end";
}
unsigned getType() const { return Type; }
@@ -69,15 +78,14 @@ public:
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;
+ void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+ const MCExpr *Subsection) const override;
+ bool UseCodeAlign() const override;
+ bool isVirtualSection() const override;
/// isBaseAddressKnownZero - We know that non-allocatable sections (like
/// debug info) have a base of zero.
- virtual bool isBaseAddressKnownZero() const {
+ bool isBaseAddressKnownZero() const override {
return (getFlags() & ELF::SHF_ALLOC) == 0;
}
diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h
index d7e88ea56124..a5a2089a2974 100644
--- a/include/llvm/MC/MCSectionMachO.h
+++ b/include/llvm/MC/MCSectionMachO.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSection.h"
+#include "llvm/Support/MachO.h"
namespace llvm {
@@ -39,99 +40,6 @@ class MCSectionMachO : public MCSection {
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 LLVM_ENUM_INT_TYPE(uint32_t) {
- // 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])
@@ -145,18 +53,21 @@ public:
return StringRef(SectionName);
}
- virtual std::string getLabelBeginName() const {
+ std::string getLabelBeginName() const override {
return StringRef(getSegmentName().str() + getSectionName().str() + "_begin");
}
- virtual std::string getLabelEndName() const {
+ std::string getLabelEndName() const override {
return StringRef(getSegmentName().str() + getSectionName().str() + "_end");
}
unsigned getTypeAndAttributes() const { return TypeAndAttributes; }
unsigned getStubSize() const { return Reserved2; }
- unsigned getType() const { return TypeAndAttributes & SECTION_TYPE; }
+ MachO::SectionType getType() const {
+ return static_cast<MachO::SectionType>(TypeAndAttributes &
+ MachO::SECTION_TYPE);
+ }
bool hasAttribute(unsigned Value) const {
return (TypeAndAttributes & Value) != 0;
}
@@ -174,11 +85,10 @@ public:
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;
+ void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+ const MCExpr *Subsection) const override;
+ bool UseCodeAlign() const override;
+ bool isVirtualSection() const override;
static bool classof(const MCSection *S) {
return S->getVariant() == SV_MachO;
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 0b1fe6ec0129..63a43d08c3f2 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -19,6 +19,7 @@
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCLinkerOptimizationHint.h"
#include "llvm/MC/MCWin64EH.h"
#include "llvm/Support/DataTypes.h"
#include <string>
@@ -33,10 +34,13 @@ class MCInstPrinter;
class MCSection;
class MCStreamer;
class MCSymbol;
+class MCSymbolRefExpr;
+class MCSubtargetInfo;
class StringRef;
class Twine;
class raw_ostream;
class formatted_raw_ostream;
+class AssemblerConstantPools;
typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair;
@@ -66,34 +70,93 @@ typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair;
/// be treated differently. Callers should always talk to a FooTargetStreamer.
class MCTargetStreamer {
protected:
- MCStreamer *Streamer;
+ MCStreamer &Streamer;
public:
+ MCTargetStreamer(MCStreamer &S);
virtual ~MCTargetStreamer();
- void setStreamer(MCStreamer *S) { Streamer = S; }
+
+ const MCStreamer &getStreamer() { return Streamer; }
+
+ // Allow a target to add behavior to the EmitLabel of MCStreamer.
+ virtual void emitLabel(MCSymbol *Symbol);
+ // Allow a target to add behavior to the emitAssignment of MCStreamer.
+ virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value);
+
+ virtual void finish();
+};
+
+class AArch64TargetStreamer : public MCTargetStreamer {
+public:
+ AArch64TargetStreamer(MCStreamer &S);
+ ~AArch64TargetStreamer();
+
+
+ void finish() override;
+
+ /// Callback used to implement the ldr= pseudo.
+ /// Add a new entry to the constant pool for the current section and return an
+ /// MCExpr that can be used to refer to the constant pool location.
+ const MCExpr *addConstantPoolEntry(const MCExpr *, unsigned Size);
+
+ /// Callback used to implemnt the .ltorg directive.
+ /// Emit contents of constant pool for the current section.
+ void emitCurrentConstantPool();
+
+private:
+ std::unique_ptr<AssemblerConstantPools> ConstantPools;
};
// FIXME: declared here because it is used from
// lib/CodeGen/AsmPrinter/ARMException.cpp.
class ARMTargetStreamer : public MCTargetStreamer {
- virtual void anchor();
public:
- virtual void emitFnStart() = 0;
- virtual void emitFnEnd() = 0;
- virtual void emitCantUnwind() = 0;
- virtual void emitPersonality(const MCSymbol *Personality) = 0;
- virtual void emitHandlerData() = 0;
+ ARMTargetStreamer(MCStreamer &S);
+ ~ARMTargetStreamer();
+
+ virtual void emitFnStart();
+ virtual void emitFnEnd();
+ virtual void emitCantUnwind();
+ virtual void emitPersonality(const MCSymbol *Personality);
+ virtual void emitPersonalityIndex(unsigned Index);
+ virtual void emitHandlerData();
virtual void emitSetFP(unsigned FpReg, unsigned SpReg,
- int64_t Offset = 0) = 0;
- virtual void emitPad(int64_t Offset) = 0;
+ int64_t Offset = 0);
+ virtual void emitMovSP(unsigned Reg, int64_t Offset = 0);
+ virtual void emitPad(int64_t Offset);
virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
- bool isVector) = 0;
-
- virtual void switchVendor(StringRef Vendor) = 0;
- virtual void emitAttribute(unsigned Attribute, unsigned Value) = 0;
- virtual void emitTextAttribute(unsigned Attribute, StringRef String) = 0;
- virtual void emitFPU(unsigned FPU) = 0;
- virtual void finishAttributeSection() = 0;
+ bool isVector);
+ virtual void emitUnwindRaw(int64_t StackOffset,
+ const SmallVectorImpl<uint8_t> &Opcodes);
+
+ virtual void switchVendor(StringRef Vendor);
+ virtual void emitAttribute(unsigned Attribute, unsigned Value);
+ virtual void emitTextAttribute(unsigned Attribute, StringRef String);
+ virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
+ StringRef StringValue = "");
+ virtual void emitFPU(unsigned FPU);
+ virtual void emitArch(unsigned Arch);
+ virtual void emitObjectArch(unsigned Arch);
+ virtual void finishAttributeSection();
+ virtual void emitInst(uint32_t Inst, char Suffix = '\0');
+
+ virtual void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE);
+
+ virtual void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value);
+
+ void finish() override;
+
+ /// Callback used to implement the ldr= pseudo.
+ /// Add a new entry to the constant pool for the current section and return an
+ /// MCExpr that can be used to refer to the constant pool location.
+ const MCExpr *addConstantPoolEntry(const MCExpr *);
+
+ /// Callback used to implemnt the .ltorg directive.
+ /// Emit contents of constant pool for the current section.
+ void emitCurrentConstantPool();
+
+private:
+ std::unique_ptr<AssemblerConstantPools> ConstantPools;
};
/// MCStreamer - Streaming machine code generation interface. This interface
@@ -107,25 +170,20 @@ public:
///
class MCStreamer {
MCContext &Context;
- OwningPtr<MCTargetStreamer> TargetStreamer;
+ std::unique_ptr<MCTargetStreamer> TargetStreamer;
MCStreamer(const MCStreamer &) LLVM_DELETED_FUNCTION;
MCStreamer &operator=(const MCStreamer &) LLVM_DELETED_FUNCTION;
- bool EmitEHFrame;
- bool EmitDebugFrame;
+ std::vector<MCDwarfFrameInfo> DwarfFrameInfos;
+ MCDwarfFrameInfo *getCurrentDwarfFrameInfo();
+ void EnsureValidDwarfFrame();
- std::vector<MCDwarfFrameInfo> FrameInfos;
- MCDwarfFrameInfo *getCurrentFrameInfo();
MCSymbol *EmitCFICommon();
- void EnsureValidFrame();
-
- std::vector<MCWin64EHUnwindInfo *> W64UnwindInfos;
- MCWin64EHUnwindInfo *CurrentW64UnwindInfo;
- void setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame);
- void EnsureValidW64UnwindInfo();
- MCSymbol *LastSymbol;
+ std::vector<MCWinFrameInfo *> WinFrameInfos;
+ MCWinFrameInfo *CurrentWinFrameInfo;
+ void EnsureValidWinFrameInfo();
// SymbolOrdering - Tracks an index to represent the order
// a symbol was emitted in. Zero means we did not emit that symbol.
@@ -135,53 +193,53 @@ class MCStreamer {
/// values saved by PushSection.
SmallVector<std::pair<MCSectionSubPair, MCSectionSubPair>, 4> SectionStack;
- bool AutoInitSections;
-
protected:
- MCStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer);
+ MCStreamer(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(MCAsmBackend *MAB, bool usingCFI);
- MCWin64EHUnwindInfo *getCurrentW64UnwindInfo() {
- return CurrentW64UnwindInfo;
+ MCWinFrameInfo *getCurrentWinFrameInfo() {
+ return CurrentWinFrameInfo;
}
- void EmitW64Tables();
+
+ void EmitWindowsUnwindTables();
virtual void EmitRawTextImpl(StringRef String);
public:
virtual ~MCStreamer();
+ void visitUsedExpr(const MCExpr &Expr);
+ virtual void visitUsedSymbol(const MCSymbol &Sym);
+
+ void setTargetStreamer(MCTargetStreamer *TS) {
+ TargetStreamer.reset(TS);
+ }
+
/// State management
///
virtual void reset();
MCContext &getContext() const { return Context; }
- MCTargetStreamer &getTargetStreamer() {
- assert(TargetStreamer);
- return *TargetStreamer;
+ MCTargetStreamer *getTargetStreamer() {
+ return TargetStreamer.get();
}
- unsigned getNumFrameInfos() { return FrameInfos.size(); }
-
- const MCDwarfFrameInfo &getFrameInfo(unsigned i) { return FrameInfos[i]; }
-
- ArrayRef<MCDwarfFrameInfo> getFrameInfos() const { return FrameInfos; }
-
- unsigned getNumW64UnwindInfos() { return W64UnwindInfos.size(); }
+ unsigned getNumFrameInfos() { return DwarfFrameInfos.size(); }
+ ArrayRef<MCDwarfFrameInfo> getDwarfFrameInfos() const {
+ return DwarfFrameInfos;
+ }
- MCWin64EHUnwindInfo &getW64UnwindInfo(unsigned i) {
- return *W64UnwindInfos[i];
+ unsigned getNumWinFrameInfos() { return WinFrameInfos.size(); }
+ ArrayRef<MCWinFrameInfo *> getWinFrameInfos() const {
+ return WinFrameInfos;
}
void generateCompactUnwindEncodings(MCAsmBackend *MAB);
@@ -197,6 +255,10 @@ public:
/// unformatted text to the .s file with EmitRawText.
virtual bool hasRawTextSupport() const { return false; }
+ /// Is the integrated assembler required for this streamer to function
+ /// correctly?
+ virtual bool isIntegratedAssemblerRequired() 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
@@ -211,6 +273,12 @@ public:
/// use this method.
virtual raw_ostream &GetCommentOS();
+ /// Print T and prefix it with the comment string (normally #) and optionally
+ /// a tab. This prints the comment immediately, not at the end of the
+ /// current line. It is basically a safe version of EmitRawText: since it
+ /// only prints comments, the object streamer ignores it instead of asserting.
+ virtual void emitRawComment(const Twine &T, bool TabPrefix = true);
+
/// AddBlankLine - Emit a blank line to a .s file to pretty it up.
virtual void AddBlankLine() {}
@@ -245,7 +313,7 @@ public:
///
/// This is called by PopSection and SwitchSection, if the current
/// section changes.
- virtual void ChangeSection(const MCSection *, const MCExpr *) = 0;
+ virtual void ChangeSection(const MCSection *, const MCExpr *);
/// pushSection - Save the current and previous section on the
/// section stack.
@@ -281,7 +349,8 @@ public:
/// @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) {
+ void SwitchSection(const MCSection *Section,
+ const MCExpr *Subsection = nullptr) {
assert(Section && "Cannot switch to a null section!");
MCSectionSubPair curSection = SectionStack.back().first;
SectionStack.back().second = curSection;
@@ -295,7 +364,7 @@ public:
/// 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) {
+ const MCExpr *Subsection = nullptr) {
assert(Section && "Cannot switch to a null section!");
MCSectionSubPair curSection = SectionStack.back().first;
SectionStack.back().second = curSection;
@@ -303,22 +372,8 @@ public:
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;
+ /// Create the default sections and set the initial one.
+ virtual void InitSections();
/// AssignSection - Sets the symbol's section.
///
@@ -334,14 +389,14 @@ public:
/// @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.
+ // FIXME: These emission are non-const because we mutate the symbol to
+ // add the section we're emitting it to later.
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;
+ virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
/// EmitLinkerOptions - Emit the given list @p Options of strings as linker
/// options into the output.
@@ -350,12 +405,13 @@ public:
/// EmitDataRegion - Note in the output the specified region @p Kind.
virtual void EmitDataRegion(MCDataRegionType Kind) {}
+ /// EmitVersionMin - Specify the MachO minimum deployment target version.
+ virtual void EmitVersionMin(MCVersionMinType, unsigned Major, unsigned Minor,
+ unsigned Update) {}
+
/// 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);
+ virtual void EmitThumbFunc(MCSymbol *Func);
/// EmitAssignment - Emit an assignment of @p Value to @p Symbol.
///
@@ -368,7 +424,7 @@ public:
///
/// @param Symbol - The symbol being assigned to.
/// @param Value - The value for the symbol.
- virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) = 0;
+ virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
/// EmitWeakReference - Emit an weak reference from @p Alias to @p Symbol.
///
@@ -377,7 +433,7 @@ public:
///
/// @param Alias - The alias that is being created.
/// @param Symbol - The symbol being aliased.
- virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) = 0;
+ virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
/// EmitSymbolAttribute - Add the given @p Attribute to @p Symbol.
virtual bool EmitSymbolAttribute(MCSymbol *Symbol,
@@ -387,29 +443,34 @@ public:
///
/// @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;
+ virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
/// BeginCOFFSymbolDef - Start emitting COFF symbol definition
///
/// @param Symbol - The symbol to have its External & Type fields set.
- virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) = 0;
+ virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
/// EmitCOFFSymbolStorageClass - Emit the storage class of the symbol.
///
/// @param StorageClass - The storage class the symbol should have.
- virtual void EmitCOFFSymbolStorageClass(int StorageClass) = 0;
+ virtual void EmitCOFFSymbolStorageClass(int StorageClass);
/// 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;
+ virtual void EmitCOFFSymbolType(int Type);
/// EndCOFFSymbolDef - Marks the end of the symbol definition.
- virtual void EndCOFFSymbolDef() = 0;
+ virtual void EndCOFFSymbolDef();
+
+ /// EmitCOFFSectionIndex - Emits a COFF section index.
+ ///
+ /// @param Symbol - Symbol the section number relocation should point to.
+ virtual void EmitCOFFSectionIndex(MCSymbol const *Symbol);
/// EmitCOFFSecRel32 - Emits a COFF section relative relocation.
///
- /// @param Symbol - Symbol the section relative realocation should point to.
+ /// @param Symbol - Symbol the section relative relocation should point to.
virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
/// EmitELFSize - Emit an ELF .size directive.
@@ -417,7 +478,11 @@ public:
/// This corresponds to an assembler statement such as:
/// .size symbol, expression
///
- virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) = 0;
+ virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
+
+ /// \brief Emit a Linker Optimization Hint (LOH) directive.
+ /// \param Args - Arguments of the LOH.
+ virtual void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {}
/// EmitCommonSymbol - Emit a common symbol.
///
@@ -434,7 +499,7 @@ public:
/// @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;
+ unsigned ByteAlignment);
/// EmitZerofill - Emit the zerofill section and an optional symbol.
///
@@ -443,8 +508,9 @@ public:
/// @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;
+ virtual void EmitZerofill(const MCSection *Section,
+ MCSymbol *Symbol = nullptr, uint64_t Size = 0,
+ unsigned ByteAlignment = 0) = 0;
/// EmitTBSSSymbol - Emit a thread local bss (.tbss) symbol.
///
@@ -454,7 +520,7 @@ public:
/// @param ByteAlignment - The alignment of the thread local common symbol
/// if non-zero. This must be a power of 2 on some targets.
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size, unsigned ByteAlignment = 0) = 0;
+ uint64_t Size, unsigned ByteAlignment = 0);
/// @}
/// @name Generating Data
@@ -464,7 +530,7 @@ public:
///
/// This is used to implement assembler directives such as .byte, .ascii,
/// etc.
- virtual void EmitBytes(StringRef Data) = 0;
+ virtual void EmitBytes(StringRef Data);
/// EmitValue - Emit the expression @p Value into the output as a native
/// integer of the given @p Size bytes.
@@ -475,9 +541,12 @@ public:
/// @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) = 0;
+ /// @param Loc - The location of the expression for error reporting.
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ const SMLoc &Loc = SMLoc());
- void EmitValue(const MCExpr *Value, unsigned Size);
+ void EmitValue(const MCExpr *Value, unsigned Size,
+ const SMLoc &Loc = SMLoc());
/// EmitIntValue - Special case of EmitValue that avoids the client having
/// to pass in a MCExpr for constant integers.
@@ -489,9 +558,9 @@ public:
/// .long foo
void EmitAbsValue(const MCExpr *Value, unsigned Size);
- virtual void EmitULEB128Value(const MCExpr *Value) = 0;
+ virtual void EmitULEB128Value(const MCExpr *Value);
- virtual void EmitSLEB128Value(const MCExpr *Value) = 0;
+ virtual void EmitSLEB128Value(const MCExpr *Value);
/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
@@ -503,7 +572,8 @@ public:
/// EmitSymbolValue - Special case of EmitValue that avoids the client
/// having to pass in a MCExpr for MCSymbols.
- void EmitSymbolValue(const MCSymbol *Sym, unsigned Size);
+ void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
+ bool IsSectionRelative = false);
/// EmitGPRel64Value - Emit the expression @p Value into the output as a
/// gprel64 (64-bit GP relative) value.
@@ -546,7 +616,7 @@ public:
/// emitted.
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
- unsigned MaxBytesToEmit = 0) = 0;
+ unsigned MaxBytesToEmit = 0);
/// EmitCodeAlignment - Emit nops until the byte alignment @p ByteAlignment
/// is reached.
@@ -560,7 +630,7 @@ public:
/// the alignment cannot be reached in this many bytes, no bytes are
/// emitted.
virtual void EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit = 0) = 0;
+ unsigned MaxBytesToEmit = 0);
/// EmitValueToOffset - Emit some number of copies of @p Value until the
/// byte offset @p Offset is reached.
@@ -572,13 +642,13 @@ public:
/// @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;
+ unsigned char Value = 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;
+ virtual void EmitFileDirective(StringRef Filename);
/// Emit the "identifiers" directive. This implements the
/// '.ident "version foo"' assembler directive.
@@ -587,8 +657,9 @@ public:
/// 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);
+ virtual unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
+ StringRef Filename,
+ unsigned CUID = 0);
/// EmitDwarfLocDirective - This implements the DWARF2
// '.loc fileno lineno ...' assembler directive.
@@ -597,20 +668,14 @@ public:
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) {}
+ virtual MCSymbol *getDwarfLineTableSymbol(unsigned CUID);
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 EmitCFIStartProc(bool IsSimple);
void EmitCFIEndProc();
virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
virtual void EmitCFIDefCfaOffset(int64_t Offset);
@@ -630,38 +695,38 @@ public:
virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
virtual void EmitCFIWindowSave();
- 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();
+ virtual void EmitWinCFIStartProc(const MCSymbol *Symbol);
+ virtual void EmitWinCFIEndProc();
+ virtual void EmitWinCFIStartChained();
+ virtual void EmitWinCFIEndChained();
+ virtual void EmitWinCFIPushReg(unsigned Register);
+ virtual void EmitWinCFISetFrame(unsigned Register, unsigned Offset);
+ virtual void EmitWinCFIAllocStack(unsigned Size);
+ virtual void EmitWinCFISaveReg(unsigned Register, unsigned Offset);
+ virtual void EmitWinCFISaveXMM(unsigned Register, unsigned Offset);
+ virtual void EmitWinCFIPushFrame(bool Code);
+ virtual void EmitWinCFIEndProlog();
+
+ virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except);
+ virtual void EmitWinEHHandlerData();
/// EmitInstruction - Emit the given @p Instruction into the current
/// section.
- virtual void EmitInstruction(const MCInst &Inst) = 0;
+ virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI);
/// \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;
+ virtual void EmitBundleAlignMode(unsigned AlignPow2);
/// \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;
+ virtual void EmitBundleLock(bool AlignToEnd);
/// \brief Ends a bundle-locked group.
- virtual void EmitBundleUnlock() = 0;
+ virtual void EmitBundleUnlock();
/// EmitRawText - If this file is backed by a assembly streamer, this dumps
/// the specified string in the output .s file. This capability is
@@ -672,9 +737,11 @@ public:
virtual void Flush() {}
/// FinishImpl - Streamer specific finalization.
- virtual void FinishImpl() = 0;
+ virtual void FinishImpl();
/// Finish - Finish emission of machine code.
void Finish();
+
+ virtual bool mayHaveInstructions() const { return true; }
};
/// createNullStreamer - Create a dummy machine code streamer, which does
@@ -698,12 +765,10 @@ MCStreamer *createNullStreamer(MCContext &Ctx);
///
/// \param ShowInst - Whether to show the MCInst representation inline with
/// the assembly.
-MCStreamer *createAsmStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer,
- formatted_raw_ostream &OS, bool isVerboseAsm,
- bool useLoc, bool useCFI, bool useDwarfDirectory,
- MCInstPrinter *InstPrint = 0,
- MCCodeEmitter *CE = 0, MCAsmBackend *TAB = 0,
- bool ShowInst = false);
+MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+ bool isVerboseAsm, bool useDwarfDirectory,
+ MCInstPrinter *InstPrint, MCCodeEmitter *CE,
+ MCAsmBackend *TAB, bool ShowInst);
/// createMachOStreamer - Create a machine code streamer which will generate
/// Mach-O format object files.
@@ -711,30 +776,15 @@ MCStreamer *createAsmStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer,
/// 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);
+ bool RelaxAll = false,
+ bool LabelSections = false);
/// createELFStreamer - Create a machine code streamer which will generate
/// ELF format object files.
-MCStreamer *createELFStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer,
- MCAsmBackend &TAB, raw_ostream &OS,
- MCCodeEmitter *CE, bool RelaxAll,
+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
diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h
index 01e8236482f7..088c5e7470d6 100644
--- a/include/llvm/MC/MCSubtargetInfo.h
+++ b/include/llvm/MC/MCSubtargetInfo.h
@@ -28,8 +28,8 @@ class StringRef;
///
class MCSubtargetInfo {
std::string TargetTriple; // Target triple
- const SubtargetFeatureKV *ProcFeatures; // Processor feature list
- const SubtargetFeatureKV *ProcDesc; // Processor descriptions
+ ArrayRef<SubtargetFeatureKV> ProcFeatures; // Processor feature list
+ ArrayRef<SubtargetFeatureKV> ProcDesc; // Processor descriptions
// Scheduler machine model
const SubtargetInfoKV *ProcSchedModels;
@@ -41,21 +41,18 @@ class MCSubtargetInfo {
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,
+ ArrayRef<SubtargetFeatureKV> PF,
+ ArrayRef<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);
+ const unsigned *OC, const unsigned *FP);
/// getTargetTriple - Return the target triple string.
StringRef getTargetTriple() const {
diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h
index fe927555c49b..0b3c3ceb210f 100644
--- a/include/llvm/MC/MCSymbol.h
+++ b/include/llvm/MC/MCSymbol.h
@@ -60,7 +60,7 @@ namespace llvm {
friend class MCExpr;
friend class MCContext;
MCSymbol(StringRef name, bool isTemporary)
- : Name(name), Section(0), Value(0),
+ : Name(name), Section(nullptr), Value(nullptr),
IsTemporary(isTemporary), IsUsed(false) {}
MCSymbol(const MCSymbol&) LLVM_DELETED_FUNCTION;
@@ -87,7 +87,7 @@ namespace llvm {
///
/// Defined symbols are either absolute or in some section.
bool isDefined() const {
- return Section != 0;
+ return Section != nullptr;
}
/// isInSection - Check if this symbol is defined in some section (i.e., it
@@ -118,7 +118,7 @@ namespace llvm {
/// setUndefined - Mark the symbol as undefined.
void setUndefined() {
- Section = 0;
+ Section = nullptr;
}
/// setAbsolute - Mark the symbol as absolute.
@@ -130,7 +130,7 @@ namespace llvm {
/// isVariable - Check if this is a variable symbol.
bool isVariable() const {
- return Value != 0;
+ return Value != nullptr;
}
/// getVariableValue() - Get the value for variable symbols.
@@ -141,7 +141,7 @@ namespace llvm {
}
// AliasedSymbol() - If this is an alias (a = b), return the symbol
- // we ultimately point to. For a non alias, this just returns the symbol
+ // we ultimately point to. For a non-alias, this just returns the symbol
// itself.
const MCSymbol &AliasedSymbol() const;
diff --git a/include/llvm/MC/MCSymbolizer.h b/include/llvm/MC/MCSymbolizer.h
index e42a2146dc53..cbbb591f1b80 100644
--- a/include/llvm/MC/MCSymbolizer.h
+++ b/include/llvm/MC/MCSymbolizer.h
@@ -16,10 +16,11 @@
#ifndef LLVM_MC_MCSYMBOLIZER_H
#define LLVM_MC_MCSYMBOLIZER_H
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/MC/MCRelocationInfo.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <memory>
namespace llvm {
@@ -42,11 +43,14 @@ class MCSymbolizer {
protected:
MCContext &Ctx;
- OwningPtr<MCRelocationInfo> RelInfo;
+ std::unique_ptr<MCRelocationInfo> RelInfo;
public:
/// \brief Construct an MCSymbolizer, taking ownership of \p RelInfo.
- MCSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo);
+ MCSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> RelInfo)
+ : Ctx(Ctx), RelInfo(std::move(RelInfo)) {
+ }
+
virtual ~MCSymbolizer();
/// \brief Try to add a symbolic operand instead of \p Value to the MCInst.
diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h
index d132a732c416..9a5881b14b44 100644
--- a/include/llvm/MC/MCTargetAsmParser.h
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -10,18 +10,23 @@
#ifndef LLVM_MC_TARGETPARSER_H
#define LLVM_MC_TARGETPARSER_H
-#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCParser/MCAsmParserExtension.h"
+#include "llvm/MC/MCTargetOptions.h"
+
+#include <memory>
namespace llvm {
-class MCStreamer;
-class StringRef;
-class SMLoc;
class AsmToken;
-class MCParsedAsmOperand;
class MCInst;
+class MCParsedAsmOperand;
+class MCStreamer;
+class SMLoc;
+class StringRef;
template <typename T> class SmallVectorImpl;
+typedef SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>> OperandVector;
+
enum AsmRewriteKind {
AOK_Delete = 0, // Rewrite should be ignored.
AOK_Align, // Rewrite align as .align.
@@ -63,7 +68,7 @@ struct ParseInstructionInfo {
SmallVectorImpl<AsmRewrite> *AsmRewrites;
- ParseInstructionInfo() : AsmRewrites(0) {}
+ ParseInstructionInfo() : AsmRewrites(nullptr) {}
ParseInstructionInfo(SmallVectorImpl<AsmRewrite> *rewrites)
: AsmRewrites(rewrites) {}
@@ -97,6 +102,9 @@ protected: // Can only create subclasses.
/// ms-style inline assembly.
MCAsmParserSemaCallback *SemaCallback;
+ /// Set of options which affects instrumentation of inline assembly.
+ MCTargetOptions MCOptions;
+
public:
virtual ~MCTargetAsmParser();
@@ -127,8 +135,7 @@ public:
/// ownership of them to the caller.
/// \return True on failure.
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
- SMLoc NameLoc,
- SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
+ SMLoc NameLoc, OperandVector &Operands) = 0;
/// ParseDirective - Parse a target specific assembler directive
///
@@ -152,17 +159,19 @@ public:
///
/// 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;
+ virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
+ OperandVector &Operands, MCStreamer &Out,
+ unsigned &ErrorInfo,
+ bool MatchingInlineAsm) = 0;
+
+ /// Allows targets to let registers opt out of clobber lists.
+ virtual bool OmitRegisterFromClobberLists(unsigned RegNo) { return false; }
/// 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,
+ virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
unsigned Kind) {
return Match_InvalidOperand;
}
@@ -174,12 +183,12 @@ public:
}
virtual void convertToMapAndConstraints(unsigned Kind,
- const SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
+ const OperandVector &Operands) = 0;
virtual const MCExpr *applyModifierToExpr(const MCExpr *E,
MCSymbolRefExpr::VariantKind,
MCContext &Ctx) {
- return 0;
+ return nullptr;
}
virtual void onLabelParsed(MCSymbol *Symbol) { };
diff --git a/include/llvm/MC/MCTargetOptions.h b/include/llvm/MC/MCTargetOptions.h
new file mode 100644
index 000000000000..eb4348ed3ec2
--- /dev/null
+++ b/include/llvm/MC/MCTargetOptions.h
@@ -0,0 +1,56 @@
+//===- MCTargetOptions.h - MC Target Options -------------------*- 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_MCTARGETOPTIONS_H
+#define LLVM_MC_MCTARGETOPTIONS_H
+
+namespace llvm {
+
+class MCTargetOptions {
+public:
+ enum AsmInstrumentation {
+ AsmInstrumentationNone,
+ AsmInstrumentationAddress
+ };
+
+ /// Enables AddressSanitizer instrumentation at machine level.
+ bool SanitizeAddress : 1;
+
+ bool MCRelaxAll : 1;
+ bool MCNoExecStack : 1;
+ bool MCSaveTempLabels : 1;
+ bool MCUseDwarfDirectory : 1;
+ bool ShowMCEncoding : 1;
+ bool ShowMCInst : 1;
+ bool AsmVerbose : 1;
+ int DwarfVersion;
+ MCTargetOptions();
+};
+
+inline bool operator==(const MCTargetOptions &LHS, const MCTargetOptions &RHS) {
+#define ARE_EQUAL(X) LHS.X == RHS.X
+ return (ARE_EQUAL(SanitizeAddress) &&
+ ARE_EQUAL(MCRelaxAll) &&
+ ARE_EQUAL(MCNoExecStack) &&
+ ARE_EQUAL(MCSaveTempLabels) &&
+ ARE_EQUAL(MCUseDwarfDirectory) &&
+ ARE_EQUAL(ShowMCEncoding) &&
+ ARE_EQUAL(ShowMCInst) &&
+ ARE_EQUAL(AsmVerbose) &&
+ ARE_EQUAL(DwarfVersion));
+#undef ARE_EQUAL
+}
+
+inline bool operator!=(const MCTargetOptions &LHS, const MCTargetOptions &RHS) {
+ return !(LHS == RHS);
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCTargetOptionsCommandFlags.h b/include/llvm/MC/MCTargetOptionsCommandFlags.h
new file mode 100644
index 000000000000..6d4eb0ef5911
--- /dev/null
+++ b/include/llvm/MC/MCTargetOptionsCommandFlags.h
@@ -0,0 +1,53 @@
+//===-- MCTargetOptionsCommandFlags.h --------------------------*- 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 machine code-specific flags that are shared between
+// different command line tools.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCTARGETOPTIONSCOMMANDFLAGS_H
+#define LLVM_MC_MCTARGETOPTIONSCOMMANDFLAGS_H
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/MC/MCTargetOptions.h"
+using namespace llvm;
+
+cl::opt<MCTargetOptions::AsmInstrumentation> AsmInstrumentation(
+ "asm-instrumentation", cl::desc("Instrumentation of inline assembly and "
+ "assembly source files"),
+ cl::init(MCTargetOptions::AsmInstrumentationNone),
+ cl::values(clEnumValN(MCTargetOptions::AsmInstrumentationNone, "none",
+ "no instrumentation at all"),
+ clEnumValN(MCTargetOptions::AsmInstrumentationAddress, "address",
+ "instrument instructions with memory arguments"),
+ clEnumValEnd));
+
+cl::opt<bool> RelaxAll("mc-relax-all",
+ cl::desc("When used with filetype=obj, "
+ "relax all fixups in the emitted object file"));
+
+cl::opt<int> DwarfVersion("dwarf-version", cl::desc("Dwarf version"),
+ cl::init(0));
+
+cl::opt<bool> ShowMCInst("asm-show-inst",
+ cl::desc("Emit internal instruction representation to "
+ "assembly file"));
+
+static inline MCTargetOptions InitMCTargetOptionsFromFlags() {
+ MCTargetOptions Options;
+ Options.SanitizeAddress =
+ (AsmInstrumentation == MCTargetOptions::AsmInstrumentationAddress);
+ Options.MCRelaxAll = RelaxAll;
+ Options.DwarfVersion = DwarfVersion;
+ Options.ShowMCInst = ShowMCInst;
+ return Options;
+}
+
+#endif
diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h
index a4e730111484..dd86979690cf 100644
--- a/include/llvm/MC/MCValue.h
+++ b/include/llvm/MC/MCValue.h
@@ -14,19 +14,25 @@
#ifndef LLVM_MC_MCVALUE_H
#define LLVM_MC_MCVALUE_H
+#include "llvm/MC/MCExpr.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.
+/// MCValue - This represents an "assembler immediate". In its most
+/// general form, this can hold ":Kind:(SymbolA - SymbolB + imm64)".
+/// Not all targets supports relocations of this general form, but we
+/// need to represent this anyway.
+///
+/// In general both SymbolA and SymbolB will also have a modifier
+/// analogous to the top-level Kind. Current targets are not expected
+/// to make use of both though. The choice comes down to whether
+/// relocation modifiers apply to the closest symbol or the whole
+/// expression.
///
/// 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
@@ -37,11 +43,13 @@ class raw_ostream;
class MCValue {
const MCSymbolRefExpr *SymA, *SymB;
int64_t Cst;
+ uint32_t RefKind;
public:
int64_t getConstant() const { return Cst; }
const MCSymbolRefExpr *getSymA() const { return SymA; }
const MCSymbolRefExpr *getSymB() const { return SymB; }
+ uint32_t getRefKind() const { return RefKind; }
/// isAbsolute - Is this an absolute (as opposed to relocatable) value.
bool isAbsolute() const { return !SymA && !SymB; }
@@ -52,21 +60,26 @@ public:
/// dump - Print the value to stderr.
void dump() const;
- static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=0,
- int64_t Val = 0) {
+ MCSymbolRefExpr::VariantKind getAccessVariant() const;
+
+ static MCValue get(const MCSymbolRefExpr *SymA,
+ const MCSymbolRefExpr *SymB = nullptr,
+ int64_t Val = 0, uint32_t RefKind = 0) {
MCValue R;
assert((!SymB || SymA) && "Invalid relocatable MCValue!");
R.Cst = Val;
R.SymA = SymA;
R.SymB = SymB;
+ R.RefKind = RefKind;
return R;
}
static MCValue get(int64_t Val) {
MCValue R;
R.Cst = Val;
- R.SymA = 0;
- R.SymB = 0;
+ R.SymA = nullptr;
+ R.SymB = nullptr;
+ R.RefKind = 0;
return R;
}
diff --git a/include/llvm/MC/MCWin64EH.h b/include/llvm/MC/MCWin64EH.h
index eb4665a2e994..3df0d0ab8c46 100644
--- a/include/llvm/MC/MCWin64EH.h
+++ b/include/llvm/MC/MCWin64EH.h
@@ -15,8 +15,8 @@
#ifndef LLVM_MC_MCWIN64EH_H
#define LLVM_MC_MCWIN64EH_H
+#include "llvm/MC/MCWinEH.h"
#include "llvm/Support/Win64EH.h"
-#include <cassert>
#include <vector>
namespace llvm {
@@ -24,48 +24,42 @@ namespace llvm {
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; }
- };
+namespace Win64EH {
+struct Instruction {
+ static WinEH::Instruction PushNonVol(MCSymbol *L, unsigned Reg) {
+ return WinEH::Instruction(Win64EH::UOP_PushNonVol, L, Reg, -1);
+ }
+ static WinEH::Instruction Alloc(MCSymbol *L, unsigned Size) {
+ return WinEH::Instruction(Size > 128 ? UOP_AllocLarge : UOP_AllocSmall, L,
+ -1, Size);
+ }
+ static WinEH::Instruction PushMachFrame(MCSymbol *L, bool Code) {
+ return WinEH::Instruction(UOP_PushMachFrame, L, -1, Code ? 1 : 0);
+ }
+ static WinEH::Instruction SaveNonVol(MCSymbol *L, unsigned Reg,
+ unsigned Offset) {
+ return WinEH::Instruction(Offset > 512 * 1024 - 8 ? UOP_SaveNonVolBig
+ : UOP_SaveNonVol,
+ L, Reg, Offset);
+ }
+ static WinEH::Instruction SaveXMM(MCSymbol *L, unsigned Reg,
+ unsigned Offset) {
+ return WinEH::Instruction(Offset > 512 * 1024 - 8 ? UOP_SaveXMM128Big
+ : UOP_SaveXMM128,
+ L, Reg, Offset);
+ }
+ static WinEH::Instruction SetFPReg(MCSymbol *L, unsigned Reg, unsigned Off) {
+ return WinEH::Instruction(UOP_SetFPReg, L, Reg, Off);
+ }
+};
+}
- struct MCWin64EHUnwindInfo {
- MCWin64EHUnwindInfo() : Begin(0), End(0), ExceptionHandler(0),
- Function(0), PrologEnd(0), Symbol(0),
- HandlesUnwind(false), HandlesExceptions(false),
- LastFrameInst(-1), ChainedParent(0),
- Instructions() {}
+ struct MCWinFrameInfo {
+ MCWinFrameInfo()
+ : Begin(nullptr), End(nullptr),ExceptionHandler(nullptr),
+ Function(nullptr), PrologEnd(nullptr), Symbol(nullptr),
+ HandlesUnwind(false), HandlesExceptions(false), LastFrameInst(-1),
+ ChainedParent(nullptr), Instructions() {}
MCSymbol *Begin;
MCSymbol *End;
const MCSymbol *ExceptionHandler;
@@ -75,8 +69,8 @@ namespace llvm {
bool HandlesUnwind;
bool HandlesExceptions;
int LastFrameInst;
- MCWin64EHUnwindInfo *ChainedParent;
- std::vector<MCWin64EHInstruction> Instructions;
+ MCWinFrameInfo *ChainedParent;
+ std::vector<WinEH::Instruction> Instructions;
};
class MCWin64EHUnwindEmitter {
@@ -86,7 +80,7 @@ namespace llvm {
// This emits the unwind info sections (.pdata and .xdata in PE/COFF).
//
static void Emit(MCStreamer &streamer);
- static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info);
+ static void EmitUnwindInfo(MCStreamer &streamer, MCWinFrameInfo *info);
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h
index 213481c9090c..dad7bb597039 100644
--- a/include/llvm/MC/MCWinCOFFObjectWriter.h
+++ b/include/llvm/MC/MCWinCOFFObjectWriter.h
@@ -30,6 +30,7 @@ namespace llvm {
virtual unsigned getRelocType(const MCValue &Target,
const MCFixup &Fixup,
bool IsCrossSection) const = 0;
+ virtual bool recordRelocation(const MCFixup &) const { return true; }
};
/// \brief Construct a new Win COFF writer instance.
diff --git a/include/llvm/MC/MCWinCOFFStreamer.h b/include/llvm/MC/MCWinCOFFStreamer.h
new file mode 100644
index 000000000000..7d2d0e4f5560
--- /dev/null
+++ b/include/llvm/MC/MCWinCOFFStreamer.h
@@ -0,0 +1,74 @@
+//===- MCWinCOFFStreamer.h - COFF 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_MCWINCOFFSTREAMER_H
+#define LLVM_MC_MCWINCOFFSTREAMER_H
+
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCObjectStreamer.h"
+
+namespace llvm {
+class MCAsmBackend;
+class MCContext;
+class MCCodeEmitter;
+class MCExpr;
+class MCInst;
+class MCSection;
+class MCSubtargetInfo;
+class MCSymbol;
+class StringRef;
+class raw_ostream;
+
+class MCWinCOFFStreamer : public MCObjectStreamer {
+public:
+ MCWinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB, MCCodeEmitter &CE,
+ raw_ostream &OS);
+
+ /// \name MCStreamer interface
+ /// \{
+
+ void InitSections() override;
+ void EmitLabel(MCSymbol *Symbol) override;
+ void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
+ void EmitThumbFunc(MCSymbol *Func) override;
+ bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+ void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
+ void BeginCOFFSymbolDef(MCSymbol const *Symbol) override;
+ void EmitCOFFSymbolStorageClass(int StorageClass) override;
+ void EmitCOFFSymbolType(int Type) override;
+ void EndCOFFSymbolDef() override;
+ void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
+ void EmitCOFFSecRel32(MCSymbol const *Symbol) override;
+ void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
+ void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+ void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+ void EmitZerofill(const MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+ void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+ void EmitFileDirective(StringRef Filename) override;
+ void EmitIdent(StringRef IdentString) override;
+ void EmitWinEHHandlerData() override;
+ void FinishImpl() override;
+
+ /// \}
+
+protected:
+ const MCSymbol *CurSymbol;
+ void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
+
+private:
+ LLVM_ATTRIBUTE_NORETURN void FatalError(const Twine &Msg) const;
+};
+}
+
+#endif
+
diff --git a/include/llvm/MC/MCWinEH.h b/include/llvm/MC/MCWinEH.h
new file mode 100644
index 000000000000..1cd1b0f1b8ca
--- /dev/null
+++ b/include/llvm/MC/MCWinEH.h
@@ -0,0 +1,29 @@
+//===- MCWinEH.h - Windows Unwinding Support --------------------*- 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_MCWINEH_H
+#define LLVM_MC_MCWINEH_H
+
+namespace llvm {
+class MCSymbol;
+
+namespace WinEH {
+struct Instruction {
+ const MCSymbol *Label;
+ const unsigned Offset;
+ const unsigned Register;
+ const unsigned Operation;
+
+ Instruction(unsigned Op, MCSymbol *L, unsigned Reg, unsigned Off)
+ : Label(L), Offset(Off), Register(Reg), Operation(Op) {}
+};
+}
+}
+
+#endif
diff --git a/include/llvm/MC/MachineLocation.h b/include/llvm/MC/MachineLocation.h
index b3fbee77021d..2a18615eff62 100644
--- a/include/llvm/MC/MachineLocation.h
+++ b/include/llvm/MC/MachineLocation.h
@@ -28,7 +28,7 @@ private:
unsigned Register; // gcc/gdb register number.
int Offset; // Displacement if not register.
public:
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// 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
@@ -73,6 +73,11 @@ public:
void dump();
#endif
};
+
+inline bool operator!=(const MachineLocation &LHS, const MachineLocation &RHS) {
+ return !(LHS == RHS);
+}
+
} // End llvm namespace
#endif
diff --git a/include/llvm/MC/StringTableBuilder.h b/include/llvm/MC/StringTableBuilder.h
new file mode 100644
index 000000000000..065e9e06e2c9
--- /dev/null
+++ b/include/llvm/MC/StringTableBuilder.h
@@ -0,0 +1,59 @@
+//===-- StringTableBuilder.h - String table building utility ------*- 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_STRINGTABLE_BUILDER_H
+#define LLVM_MC_STRINGTABLE_BUILDER_H
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+#include <cassert>
+
+namespace llvm {
+
+/// \brief Utility for building string tables with deduplicated suffixes.
+class StringTableBuilder {
+ SmallString<256> StringTable;
+ StringMap<size_t> StringIndexMap;
+
+public:
+ /// \brief Add a string to the builder. Returns a StringRef to the internal
+ /// copy of s. Can only be used before the table is finalized.
+ StringRef add(StringRef s) {
+ assert(!isFinalized());
+ return StringIndexMap.GetOrCreateValue(s, 0).getKey();
+ }
+
+ /// \brief Analyze the strings and build the final table. No more strings can
+ /// be added after this point.
+ void finalize();
+
+ /// \brief Retrieve the string table data. Can only be used after the table
+ /// is finalized.
+ StringRef data() {
+ assert(isFinalized());
+ return StringTable;
+ }
+
+ /// \brief Get the offest of a string in the string table. Can only be used
+ /// after the table is finalized.
+ size_t getOffset(StringRef s) {
+ assert(isFinalized());
+ assert(StringIndexMap.count(s) && "String is not in table!");
+ return StringIndexMap[s];
+ }
+
+private:
+ bool isFinalized() {
+ return !StringTable.empty();
+ }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h
index d0735ccd9fa3..c5d62a6cbae8 100644
--- a/include/llvm/MC/SubtargetFeature.h
+++ b/include/llvm/MC/SubtargetFeature.h
@@ -18,9 +18,9 @@
#ifndef LLVM_MC_SUBTARGETFEATURE_H
#define LLVM_MC_SUBTARGETFEATURE_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/DataTypes.h"
-#include <vector>
namespace llvm {
class raw_ostream;
@@ -78,20 +78,17 @@ public:
std::string getString() const;
/// Adding Features.
- void AddFeature(const StringRef String, bool IsEnabled = true);
+ void AddFeature(const StringRef String);
/// 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);
+ ArrayRef<SubtargetFeatureKV> FeatureTable);
/// Get feature bits of a CPU.
uint64_t getFeatureBits(const StringRef CPU,
- const SubtargetFeatureKV *CPUTable,
- size_t CPUTableSize,
- const SubtargetFeatureKV *FeatureTable,
- size_t FeatureTableSize);
+ ArrayRef<SubtargetFeatureKV> CPUTable,
+ ArrayRef<SubtargetFeatureKV> FeatureTable);
/// Print feature string.
void print(raw_ostream &OS) const;
diff --git a/include/llvm/MC/YAML.h b/include/llvm/MC/YAML.h
new file mode 100644
index 000000000000..383cdc6785fa
--- /dev/null
+++ b/include/llvm/MC/YAML.h
@@ -0,0 +1,94 @@
+#ifndef LLVM_MC_YAML_H
+#define LLVM_MC_YAML_H
+
+#include "llvm/Support/YAMLTraits.h"
+
+namespace llvm {
+namespace yaml {
+/// \brief Specialized YAMLIO scalar type for representing a binary blob.
+///
+/// A typical use case would be to represent the content of a section in a
+/// binary file.
+/// This class has custom YAMLIO traits for convenient reading and writing.
+/// It renders as a string of hex digits in a YAML file.
+/// For example, it might render as `DEADBEEFCAFEBABE` (YAML does not
+/// require the quotation marks, so for simplicity when outputting they are
+/// omitted).
+/// When reading, any string whose content is an even number of hex digits
+/// will be accepted.
+/// For example, all of the following are acceptable:
+/// `DEADBEEF`, `"DeADbEeF"`, `"\x44EADBEEF"` (Note: '\x44' == 'D')
+///
+/// A significant advantage of using this class is that it never allocates
+/// temporary strings or buffers for any of its functionality.
+///
+/// Example:
+///
+/// The YAML mapping:
+/// \code
+/// Foo: DEADBEEFCAFEBABE
+/// \endcode
+///
+/// Could be modeled in YAMLIO by the struct:
+/// \code
+/// struct FooHolder {
+/// BinaryRef Foo;
+/// };
+/// namespace llvm {
+/// namespace yaml {
+/// template <>
+/// struct MappingTraits<FooHolder> {
+/// static void mapping(IO &IO, FooHolder &FH) {
+/// IO.mapRequired("Foo", FH.Foo);
+/// }
+/// };
+/// } // end namespace yaml
+/// } // end namespace llvm
+/// \endcode
+class BinaryRef {
+ friend bool operator==(const BinaryRef &LHS, const BinaryRef &RHS);
+ /// \brief Either raw binary data, or a string of hex bytes (must always
+ /// be an even number of characters).
+ ArrayRef<uint8_t> Data;
+ /// \brief Discriminator between the two states of the `Data` member.
+ bool DataIsHexString;
+
+public:
+ BinaryRef(ArrayRef<uint8_t> Data) : Data(Data), DataIsHexString(false) {}
+ BinaryRef(StringRef Data)
+ : Data(reinterpret_cast<const uint8_t *>(Data.data()), Data.size()),
+ DataIsHexString(true) {}
+ BinaryRef() : DataIsHexString(true) {}
+ /// \brief The number of bytes that are represented by this BinaryRef.
+ /// This is the number of bytes that writeAsBinary() will write.
+ ArrayRef<uint8_t>::size_type binary_size() const {
+ if (DataIsHexString)
+ return Data.size() / 2;
+ return Data.size();
+ }
+ /// \brief Write the contents (regardless of whether it is binary or a
+ /// hex string) as binary to the given raw_ostream.
+ void writeAsBinary(raw_ostream &OS) const;
+ /// \brief Write the contents (regardless of whether it is binary or a
+ /// hex string) as hex to the given raw_ostream.
+ ///
+ /// For example, a possible output could be `DEADBEEFCAFEBABE`.
+ void writeAsHex(raw_ostream &OS) const;
+};
+
+inline bool operator==(const BinaryRef &LHS, const BinaryRef &RHS) {
+ // Special case for default constructed BinaryRef.
+ if (LHS.Data.empty() && RHS.Data.empty())
+ return true;
+
+ return LHS.DataIsHexString == RHS.DataIsHexString && LHS.Data == RHS.Data;
+}
+
+template <> struct ScalarTraits<BinaryRef> {
+ static void output(const BinaryRef &, void *, llvm::raw_ostream &);
+ static StringRef input(StringRef, void *, BinaryRef &);
+ static bool mustQuote(StringRef S) { return needsQuotes(S); }
+};
+}
+}
+#endif