summaryrefslogtreecommitdiff
path: root/include/llvm/MC
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-05-27 18:44:32 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-05-27 18:44:32 +0000
commit5a5ac124e1efaf208671f01c46edb15f29ed2a0b (patch)
treea6140557876943cdd800ee997c9317283394b22c /include/llvm/MC
parentf03b5bed27d0d2eafd68562ce14f8b5e3f1f0801 (diff)
Notes
Diffstat (limited to 'include/llvm/MC')
-rw-r--r--include/llvm/MC/ConstantPools.h9
-rw-r--r--include/llvm/MC/MCAsmBackend.h71
-rw-r--r--include/llvm/MC/MCAsmInfo.h49
-rw-r--r--include/llvm/MC/MCAsmInfoELF.h3
-rw-r--r--include/llvm/MC/MCAsmLayout.h40
-rw-r--r--include/llvm/MC/MCAssembler.h631
-rw-r--r--include/llvm/MC/MCCodeEmitter.h9
-rw-r--r--include/llvm/MC/MCCodeGenInfo.h40
-rw-r--r--include/llvm/MC/MCContext.h348
-rw-r--r--include/llvm/MC/MCDisassembler.h13
-rw-r--r--include/llvm/MC/MCDwarf.h55
-rw-r--r--include/llvm/MC/MCELF.h2
-rw-r--r--include/llvm/MC/MCELFObjectWriter.h24
-rw-r--r--include/llvm/MC/MCELFStreamer.h41
-rw-r--r--include/llvm/MC/MCExpr.h142
-rw-r--r--include/llvm/MC/MCFixup.h10
-rw-r--r--include/llvm/MC/MCFixupKindInfo.h2
-rw-r--r--include/llvm/MC/MCInst.h31
-rw-r--r--include/llvm/MC/MCInstBuilder.h16
-rw-r--r--include/llvm/MC/MCInstPrinter.h42
-rw-r--r--include/llvm/MC/MCInstrAnalysis.h4
-rw-r--r--include/llvm/MC/MCInstrDesc.h521
-rw-r--r--include/llvm/MC/MCInstrInfo.h13
-rw-r--r--include/llvm/MC/MCInstrItineraries.h45
-rw-r--r--include/llvm/MC/MCLabel.h19
-rw-r--r--include/llvm/MC/MCLinkerOptimizationHint.h14
-rw-r--r--include/llvm/MC/MCMachObjectWriter.h82
-rw-r--r--include/llvm/MC/MCObjectFileInfo.h290
-rw-r--r--include/llvm/MC/MCObjectStreamer.h51
-rw-r--r--include/llvm/MC/MCObjectWriter.h66
-rw-r--r--include/llvm/MC/MCParser/AsmLexer.h6
-rw-r--r--include/llvm/MC/MCParser/MCAsmLexer.h12
-rw-r--r--include/llvm/MC/MCParser/MCAsmParser.h74
-rw-r--r--include/llvm/MC/MCParser/MCAsmParserExtension.h6
-rw-r--r--include/llvm/MC/MCParser/MCParsedAsmOperand.h5
-rw-r--r--include/llvm/MC/MCRelocationInfo.h4
-rw-r--r--include/llvm/MC/MCSection.h203
-rw-r--r--include/llvm/MC/MCSectionCOFF.h13
-rw-r--r--include/llvm/MC/MCSectionELF.h40
-rw-r--r--include/llvm/MC/MCSectionMachO.h12
-rw-r--r--include/llvm/MC/MCStreamer.h382
-rw-r--r--include/llvm/MC/MCSubtargetInfo.h22
-rw-r--r--include/llvm/MC/MCSymbol.h404
-rw-r--r--include/llvm/MC/MCSymbolizer.h20
-rw-r--r--include/llvm/MC/MCTargetAsmParser.h8
-rw-r--r--include/llvm/MC/MCValue.h17
-rw-r--r--include/llvm/MC/MCWinCOFFObjectWriter.h18
-rw-r--r--include/llvm/MC/MCWinCOFFStreamer.h7
-rw-r--r--include/llvm/MC/MCWinEH.h8
-rw-r--r--include/llvm/MC/SectionKind.h6
-rw-r--r--include/llvm/MC/SubtargetFeature.h28
51 files changed, 1908 insertions, 2070 deletions
diff --git a/include/llvm/MC/ConstantPools.h b/include/llvm/MC/ConstantPools.h
index 1fc0332f63c29..9aa4663ba0fc9 100644
--- a/include/llvm/MC/ConstantPools.h
+++ b/include/llvm/MC/ConstantPools.h
@@ -73,21 +73,18 @@ class AssemblerConstantPools {
// 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;
+ typedef MapVector<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);
+ ConstantPool *getConstantPool(MCSection *Section);
+ ConstantPool &getOrCreateConstantPool(MCSection *Section);
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h
index a6d41392724e0..c0a95d48e370e 100644
--- a/include/llvm/MC/MCAsmBackend.h
+++ b/include/llvm/MC/MCAsmBackend.h
@@ -30,10 +30,10 @@ class MCSection;
class MCValue;
class raw_ostream;
-/// MCAsmBackend - Generic interface to target specific assembler backends.
+/// Generic interface to target specific assembler backends.
class MCAsmBackend {
- MCAsmBackend(const MCAsmBackend &) LLVM_DELETED_FUNCTION;
- void operator=(const MCAsmBackend &) LLVM_DELETED_FUNCTION;
+ MCAsmBackend(const MCAsmBackend &) = delete;
+ void operator=(const MCAsmBackend &) = delete;
protected: // Can only create subclasses.
MCAsmBackend();
@@ -46,70 +46,62 @@ public:
/// lifetime management
virtual void reset() {}
- /// createObjectWriter - Create a new MCObjectWriter instance for use by the
- /// assembler backend to emit the final object file.
- virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0;
+ /// Create a new MCObjectWriter instance for use by the assembler backend to
+ /// emit the final object file.
+ virtual MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const = 0;
- /// createELFObjectTargetWriter - Create a new ELFObjectTargetWriter to enable
- /// non-standard ELFObjectWriters.
+ /// Create a new ELFObjectTargetWriter to enable non-standard
+ /// ELFObjectWriters.
virtual MCELFObjectTargetWriter *createELFObjectTargetWriter() const {
llvm_unreachable("createELFObjectTargetWriter is not supported by asm "
"backend");
}
- /// hasDataInCodeSupport - Check whether this target implements data-in-code
- /// markers. If not, data region directives will be ignored.
+ /// Check whether this target implements data-in-code markers. If not, data
+ /// region directives will be ignored.
bool hasDataInCodeSupport() const { return HasDataInCodeSupport; }
- /// doesSectionRequireSymbols - Check whether the given section requires that
- /// all symbols (even temporaries) have symbol table entries.
- virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
- return false;
- }
-
- /// @name Target Fixup Interfaces
+ /// \name Target Fixup Interfaces
/// @{
- /// getNumFixupKinds - Get the number of target specific fixup kinds.
+ /// Get the number of target specific fixup kinds.
virtual unsigned getNumFixupKinds() const = 0;
- /// getFixupKindInfo - Get information on a fixup kind.
+ /// Get information on a fixup kind.
virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const;
- /// processFixupValue - Target hook to adjust the literal value of a fixup
- /// if necessary. IsResolved signals whether the caller believes a relocation
- /// is needed; the target can modify the value. The default does nothing.
+ /// Target hook to adjust the literal value of a fixup if necessary.
+ /// IsResolved signals whether the caller believes a relocation is needed; the
+ /// target can modify the value. The default does nothing.
virtual void processFixupValue(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFixup &Fixup, const MCFragment *DF,
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.
+ /// 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, bool IsPCRel) const = 0;
/// @}
- /// @name Target Relaxation Interfaces
+ /// \name Target Relaxation Interfaces
/// @{
- /// mayNeedRelaxation - Check whether the given instruction may need
- /// relaxation.
+ /// Check whether the given instruction may need relaxation.
///
/// \param Inst - The instruction to test.
virtual bool mayNeedRelaxation(const MCInst &Inst) const = 0;
- /// fixupNeedsRelaxation - Target specific predicate for whether a given
- /// fixup requires the associated instruction to be relaxed.
+ /// Target specific predicate for whether a given fixup requires the
+ /// associated instruction to be relaxed.
virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const = 0;
- /// RelaxInstruction - Relax the instruction in the given fragment to the next
- /// wider instruction.
+ /// Relax the instruction in the given fragment to the next wider instruction.
///
/// \param Inst The instruction to relax, which may be the same as the
/// output.
@@ -118,22 +110,19 @@ public:
/// @}
- /// getMinimumNopSize - Returns the minimum size of a nop in bytes on this
- /// target. The assembler will use this to emit excess padding in situations
- /// where the padding required for simple alignment would be less than the
- /// minimum nop size.
+ /// Returns the minimum size of a nop in bytes on this target. The assembler
+ /// will use this to emit excess padding in situations where the padding
+ /// required for simple alignment would be less than the minimum nop size.
///
virtual unsigned getMinimumNopSize() const { return 1; }
- /// writeNopData - Write an (optimal) nop sequence of Count bytes to the given
- /// output. If the target cannot generate such a sequence, it should return an
- /// error.
+ /// Write an (optimal) nop sequence of Count bytes to the given output. If the
+ /// target cannot generate such a sequence, it should return an error.
///
/// \return - True on success.
virtual bool writeNopData(uint64_t Count, MCObjectWriter *OW) const = 0;
- /// handleAssemblerFlag - Handle any target-specific assembler flags.
- /// By default, do nothing.
+ /// Handle any target-specific assembler flags. By default, do nothing.
virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {}
/// \brief Generate the compact unwind encoding for the CFI instructions.
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index a750a0fd5cefd..0335f3188fc35 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -18,7 +18,6 @@
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCDwarf.h"
-#include "llvm/MC/MachineLocation.h"
#include <cassert>
#include <vector>
@@ -37,17 +36,17 @@ enum class EncodingType {
ARM, /// Windows NT (Windows on ARM)
CE, /// Windows CE ARM, PowerPC, SH3, SH4
Itanium, /// Windows x64, Windows Itanium (IA-64)
+ X86, /// Windows x86, uses no CFI, just EH tables
MIPS = Alpha,
};
}
enum class ExceptionHandling {
- None, /// No exception support
- DwarfCFI, /// DWARF-like instruction based exceptions
- SjLj, /// setjmp/longjmp based exceptions
- ARM, /// ARM EHABI
- ItaniumWinEH, /// Itanium EH built on Windows unwind info (.pdata and .xdata)
- MSVC, /// MSVC compatible exception handling
+ None, /// No exception support
+ DwarfCFI, /// DWARF-like instruction based exceptions
+ SjLj, /// setjmp/longjmp based exceptions
+ ARM, /// ARM EHABI
+ WinEH, /// Windows Exception Handling
};
namespace LCOMM {
@@ -119,6 +118,9 @@ protected:
// Print the EH begin symbol with an assignment. Defaults to false.
bool UseAssignmentForEHBegin;
+ // Do we need to create a local symbol for .size?
+ bool NeedsLocalForSize;
+
/// 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"
@@ -226,7 +228,7 @@ protected:
/// True if the expression
/// .long f - g
- /// uses an relocation but it can be supressed by writting
+ /// uses a relocation but it can be suppressed by writing
/// a = f - g
/// .long a
bool SetDirectiveSuppressesReloc;
@@ -254,6 +256,10 @@ protected:
/// argument and how it is interpreted. Defaults to NoAlignment.
LCOMM::LCOMMType LCOMMDirectiveAlignmentType;
+ // True if the target allows .align directives on functions. This is true for
+ // most targets, so defaults to true.
+ bool HasFunctionAlignment;
+
/// True if the target has .type and .size directives, this is true for most
/// ELF targets. Defaults to true.
bool HasDotTypeDotSizeDirective;
@@ -333,7 +339,7 @@ protected:
std::vector<MCCFIInstruction> InitialFrameState;
- //===--- Integrated Assembler State ----------------------------------===//
+ //===--- Integrated Assembler Information ----------------------------===//
/// Should we use the integrated assembler?
/// The integrated assembler should be enabled by default (by the
@@ -345,6 +351,10 @@ protected:
/// Compress DWARF debug sections. Defaults to false.
bool CompressDebugSections;
+ /// True if the integrated assembler should interpret 'a >> b' constant
+ /// expressions as logical rather than arithmetic.
+ bool UseLogicalShr;
+
public:
explicit MCAsmInfo();
virtual ~MCAsmInfo();
@@ -378,7 +388,7 @@ public:
/// 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 {
+ virtual MCSection *getNonexecutableStackSection(MCContext &Ctx) const {
return nullptr;
}
@@ -428,6 +438,7 @@ public:
const char *getLabelSuffix() const { return LabelSuffix; }
bool useAssignmentForEHBegin() const { return UseAssignmentForEHBegin; }
+ bool needsLocalForSize() const { return NeedsLocalForSize; }
const char *getPrivateGlobalPrefix() const { return PrivateGlobalPrefix; }
const char *getPrivateLabelPrefix() const { return PrivateLabelPrefix; }
bool hasLinkerPrivateGlobalPrefix() const {
@@ -464,6 +475,7 @@ public:
LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const {
return LCOMMDirectiveAlignmentType;
}
+ bool hasFunctionAlignment() const { return HasFunctionAlignment; }
bool hasDotTypeDotSizeDirective() const { return HasDotTypeDotSizeDirective; }
bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; }
bool hasIdentDirective() const { return HasIdentDirective; }
@@ -490,18 +502,17 @@ public:
ExceptionHandling getExceptionHandlingType() const { return ExceptionsType; }
WinEH::EncodingType getWinEHEncodingType() const { return WinEHEncodingType; }
- /// Return true if the exception handling type uses the language-specific data
- /// area (LSDA) format specified by the Itanium C++ ABI.
- bool usesItaniumLSDAForExceptions() const {
+ /// Returns true if the exception handling method for the platform uses call
+ /// frame information to unwind.
+ bool usesCFIForEH() const {
return (ExceptionsType == ExceptionHandling::DwarfCFI ||
- ExceptionsType == ExceptionHandling::ARM ||
- // This Windows EH type uses the Itanium LSDA encoding.
- ExceptionsType == ExceptionHandling::ItaniumWinEH);
+ ExceptionsType == ExceptionHandling::ARM || usesWindowsCFI());
}
bool usesWindowsCFI() const {
- return ExceptionsType == ExceptionHandling::ItaniumWinEH ||
- ExceptionsType == ExceptionHandling::MSVC;
+ return ExceptionsType == ExceptionHandling::WinEH &&
+ (WinEHEncodingType != WinEH::EncodingType::Invalid &&
+ WinEHEncodingType != WinEH::EncodingType::X86);
}
bool doesDwarfUseRelocationsAcrossSections() const {
@@ -532,6 +543,8 @@ public:
void setCompressDebugSections(bool CompressDebugSections) {
this->CompressDebugSections = CompressDebugSections;
}
+
+ bool shouldUseLogicalShr() const { return UseLogicalShr; }
};
}
diff --git a/include/llvm/MC/MCAsmInfoELF.h b/include/llvm/MC/MCAsmInfoELF.h
index 7bd246056eca0..7125f5c7ad7a7 100644
--- a/include/llvm/MC/MCAsmInfoELF.h
+++ b/include/llvm/MC/MCAsmInfoELF.h
@@ -15,8 +15,7 @@
namespace llvm {
class MCAsmInfoELF : public MCAsmInfo {
virtual void anchor();
- const MCSection *
- getNonexecutableStackSection(MCContext &Ctx) const override final;
+ MCSection *getNonexecutableStackSection(MCContext &Ctx) const final;
protected:
MCAsmInfoELF();
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
index f048e34671db4..fb28420e0fa3a 100644
--- a/include/llvm/MC/MCAsmLayout.h
+++ b/include/llvm/MC/MCAsmLayout.h
@@ -16,7 +16,7 @@
namespace llvm {
class MCAssembler;
class MCFragment;
-class MCSectionData;
+class MCSection;
class MCSymbol;
class MCSymbolData;
@@ -28,20 +28,15 @@ class MCSymbolData;
/// efficiently compute the exact address of any symbol in the assembly file,
/// even during the relaxation process.
class MCAsmLayout {
-public:
- typedef llvm::SmallVectorImpl<MCSectionData*>::const_iterator const_iterator;
- typedef llvm::SmallVectorImpl<MCSectionData*>::iterator iterator;
-
-private:
MCAssembler &Assembler;
/// List of sections in layout order.
- llvm::SmallVector<MCSectionData*, 16> SectionOrder;
+ llvm::SmallVector<MCSection *, 16> SectionOrder;
/// The last fragment which was laid out, or 0 if nothing has been laid
/// out. Fragments are always laid out in order, so all fragments with a
/// lower ordinal will be valid.
- mutable DenseMap<const MCSectionData*, MCFragment*> LastValidFragment;
+ mutable DenseMap<const MCSection *, MCFragment *> LastValidFragment;
/// \brief Make sure that the layout for the given fragment is valid, lazily
/// computing it if necessary.
@@ -50,13 +45,8 @@ private:
/// \brief Is the layout for this fragment valid?
bool isFragmentValid(const MCFragment *F) const;
- /// \brief Compute the amount of padding required before this fragment to
- /// obey bundling restrictions.
- uint64_t computeBundlePadding(const MCFragment *F,
- uint64_t FOffset, uint64_t FSize);
-
public:
- MCAsmLayout(MCAssembler &_Assembler);
+ MCAsmLayout(MCAssembler &Assembler);
/// Get the assembler object this is a layout for.
MCAssembler &getAssembler() const { return Assembler; }
@@ -71,43 +61,41 @@ public:
/// been initialized.
void layoutFragment(MCFragment *Fragment);
- /// @name Section Access (in layout order)
+ /// \name Section Access (in layout order)
/// @{
- llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() {
- return SectionOrder;
- }
- const llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() const {
+ llvm::SmallVectorImpl<MCSection *> &getSectionOrder() { return SectionOrder; }
+ const llvm::SmallVectorImpl<MCSection *> &getSectionOrder() const {
return SectionOrder;
}
/// @}
- /// @name Fragment Layout Data
+ /// \name Fragment Layout Data
/// @{
/// \brief Get the offset of the given fragment inside its containing section.
uint64_t getFragmentOffset(const MCFragment *F) const;
/// @}
- /// @name Utility Functions
+ /// \name Utility Functions
/// @{
/// \brief Get the address space size of the given section, as it effects
/// layout. This may differ from the size reported by \see getSectionSize() by
/// not including section tail padding.
- uint64_t getSectionAddressSize(const MCSectionData *SD) const;
+ uint64_t getSectionAddressSize(const MCSection *Sec) const;
/// \brief Get the data size of the given section, as emitted to the object
/// file. This may include additional padding, or be 0 for virtual sections.
- uint64_t getSectionFileSize(const MCSectionData *SD) const;
+ uint64_t getSectionFileSize(const MCSection *Sec) const;
/// \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;
+ /// \return True on success.
+ bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const;
/// \brief Variant that reports a fatal error if the offset is not computable.
- uint64_t getSymbolOffset(const MCSymbolData *SD) const;
+ uint64_t getSymbolOffset(const MCSymbol &S) 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 681a317287992..593504ce06079 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -11,16 +11,20 @@
#define LLVM_MC_MCASSEMBLER_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/ADT/iterator.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCLinkerOptimizationHint.h"
+#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include <algorithm>
@@ -36,18 +40,15 @@ class MCExpr;
class MCFragment;
class MCObjectWriter;
class MCSection;
-class MCSectionData;
class MCSubtargetInfo;
-class MCSymbol;
-class MCSymbolData;
class MCValue;
class MCAsmBackend;
class MCFragment : public ilist_node<MCFragment> {
friend class MCAsmLayout;
- MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION;
- void operator=(const MCFragment&) LLVM_DELETED_FUNCTION;
+ MCFragment(const MCFragment &) = delete;
+ void operator=(const MCFragment &) = delete;
public:
enum FragmentType {
@@ -65,14 +66,14 @@ public:
private:
FragmentType Kind;
- /// Parent - The data for the section this fragment is in.
- MCSectionData *Parent;
+ /// The data for the section this fragment is in.
+ MCSection *Parent;
/// Atom - The atom this fragment is in, as represented by it's defining
/// symbol.
- MCSymbolData *Atom;
+ const MCSymbol *Atom;
- /// @name Assembler Backend Data
+ /// \name Assembler Backend Data
/// @{
//
// FIXME: This could all be kept private to the assembler implementation.
@@ -87,7 +88,7 @@ private:
/// @}
protected:
- MCFragment(FragmentType _Kind, MCSectionData *_Parent = nullptr);
+ MCFragment(FragmentType Kind, MCSection *Parent = nullptr);
public:
// Only for sentinel.
@@ -96,11 +97,11 @@ public:
FragmentType getKind() const { return Kind; }
- MCSectionData *getParent() const { return Parent; }
- void setParent(MCSectionData *Value) { Parent = Value; }
+ MCSection *getParent() const { return Parent; }
+ void setParent(MCSection *Value) { Parent = Value; }
- MCSymbolData *getAtom() const { return Atom; }
- void setAtom(MCSymbolData *Value) { Atom = Value; }
+ const MCSymbol *getAtom() const { return Atom; }
+ void setAtom(const MCSymbol *Value) { Atom = Value; }
unsigned getLayoutOrder() const { return LayoutOrder; }
void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
@@ -111,21 +112,18 @@ public:
/// \brief Should this fragment be placed at the end of an aligned bundle?
virtual bool alignToBundleEnd() const { return false; }
- virtual void setAlignToBundleEnd(bool V) { }
+ virtual void setAlignToBundleEnd(bool V) {}
/// \brief Get the padding size that must be inserted before this fragment.
/// Used for bundling. By default, no padding is inserted.
/// Note that padding size is restricted to 8 bits. This is an optimization
/// to reduce the amount of space used for each fragment. In practice, larger
/// padding should never be required.
- virtual uint8_t getBundlePadding() const {
- return 0;
- }
+ virtual uint8_t getBundlePadding() const { return 0; }
/// \brief Set the padding size for this fragment. By default it's a no-op,
/// and only some fragments have a meaningful implementation.
- virtual void setBundlePadding(uint8_t N) {
- }
+ virtual void setBundlePadding(uint8_t N) {}
void dump();
};
@@ -137,33 +135,28 @@ class MCEncodedFragment : public MCFragment {
virtual void anchor();
uint8_t BundlePadding;
+
public:
- MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = nullptr)
- : MCFragment(FType, SD), BundlePadding(0)
- {
- }
- virtual ~MCEncodedFragment();
+ MCEncodedFragment(MCFragment::FragmentType FType, MCSection *Sec = nullptr)
+ : MCFragment(FType, Sec), BundlePadding(0) {}
+ ~MCEncodedFragment() override;
virtual SmallVectorImpl<char> &getContents() = 0;
virtual const SmallVectorImpl<char> &getContents() const = 0;
- uint8_t getBundlePadding() const override {
- return BundlePadding;
- }
+ uint8_t getBundlePadding() const override { return BundlePadding; }
- void setBundlePadding(uint8_t N) override {
- BundlePadding = N;
- }
+ void setBundlePadding(uint8_t N) override { BundlePadding = N; }
static bool classof(const MCFragment *F) {
MCFragment::FragmentType Kind = F->getKind();
switch (Kind) {
- default:
- return false;
- case MCFragment::FT_Relaxable:
- case MCFragment::FT_CompactEncodedInst:
- case MCFragment::FT_Data:
- return true;
+ default:
+ return false;
+ case MCFragment::FT_Relaxable:
+ case MCFragment::FT_CompactEncodedInst:
+ case MCFragment::FT_Data:
+ return true;
}
}
};
@@ -176,12 +169,10 @@ class MCEncodedFragmentWithFixups : public MCEncodedFragment {
public:
MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
- MCSectionData *SD = nullptr)
- : MCEncodedFragment(FType, SD)
- {
- }
+ MCSection *Sec = nullptr)
+ : MCEncodedFragment(FType, Sec) {}
- virtual ~MCEncodedFragmentWithFixups();
+ ~MCEncodedFragmentWithFixups() override;
typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
@@ -190,7 +181,7 @@ public:
virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
virtual fixup_iterator fixup_begin() = 0;
- virtual const_fixup_iterator fixup_begin() const = 0;
+ virtual const_fixup_iterator fixup_begin() const = 0;
virtual fixup_iterator fixup_end() = 0;
virtual const_fixup_iterator fixup_end() const = 0;
@@ -215,25 +206,18 @@ class MCDataFragment : public MCEncodedFragmentWithFixups {
/// Fixups - The list of fixups in this fragment.
SmallVector<MCFixup, 4> Fixups;
+
public:
- MCDataFragment(MCSectionData *SD = nullptr)
- : MCEncodedFragmentWithFixups(FT_Data, SD),
- HasInstructions(false), AlignToBundleEnd(false)
- {
- }
+ MCDataFragment(MCSection *Sec = nullptr)
+ : MCEncodedFragmentWithFixups(FT_Data, Sec), HasInstructions(false),
+ AlignToBundleEnd(false) {}
SmallVectorImpl<char> &getContents() override { return Contents; }
- const SmallVectorImpl<char> &getContents() const override {
- return Contents;
- }
+ const SmallVectorImpl<char> &getContents() const override { return Contents; }
- SmallVectorImpl<MCFixup> &getFixups() override {
- return Fixups;
- }
+ SmallVectorImpl<MCFixup> &getFixups() override { return Fixups; }
- const SmallVectorImpl<MCFixup> &getFixups() const override {
- return Fixups;
- }
+ const SmallVectorImpl<MCFixup> &getFixups() const override { return Fixups; }
bool hasInstructions() const override { return HasInstructions; }
virtual void setHasInstructions(bool V) { HasInstructions = V; }
@@ -244,8 +228,8 @@ public:
fixup_iterator fixup_begin() override { return Fixups.begin(); }
const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
- fixup_iterator fixup_end() override {return Fixups.end();}
- const_fixup_iterator fixup_end() const override {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;
@@ -264,15 +248,13 @@ class MCCompactEncodedInstFragment : public MCEncodedFragment {
bool AlignToBundleEnd;
SmallVector<char, 4> Contents;
+
public:
- MCCompactEncodedInstFragment(MCSectionData *SD = nullptr)
- : MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false)
- {
+ MCCompactEncodedInstFragment(MCSection *Sec = nullptr)
+ : MCEncodedFragment(FT_CompactEncodedInst, Sec), AlignToBundleEnd(false) {
}
- bool hasInstructions() const override {
- return true;
- }
+ bool hasInstructions() const override { return true; }
SmallVectorImpl<char> &getContents() override { return Contents; }
const SmallVectorImpl<char> &getContents() const override { return Contents; }
@@ -306,35 +288,29 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
SmallVector<MCFixup, 1> Fixups;
public:
- MCRelaxableFragment(const MCInst &_Inst,
- const MCSubtargetInfo &_STI,
- MCSectionData *SD = nullptr)
- : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst), STI(_STI) {
- }
+ MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI,
+ MCSection *Sec = nullptr)
+ : MCEncodedFragmentWithFixups(FT_Relaxable, Sec), Inst(Inst), STI(STI) {}
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; }
+ void setInst(const MCInst &Value) { Inst = Value; }
const MCSubtargetInfo &getSubtargetInfo() { return STI; }
- SmallVectorImpl<MCFixup> &getFixups() override {
- return Fixups;
- }
+ SmallVectorImpl<MCFixup> &getFixups() override { return Fixups; }
- const SmallVectorImpl<MCFixup> &getFixups() const override {
- return Fixups;
- }
+ const SmallVectorImpl<MCFixup> &getFixups() const override { return Fixups; }
bool hasInstructions() const override { return true; }
fixup_iterator fixup_begin() override { return Fixups.begin(); }
const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
- fixup_iterator fixup_end() override {return Fixups.end();}
- const_fixup_iterator fixup_end() const override {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;
@@ -363,13 +339,12 @@ class MCAlignFragment : public MCFragment {
bool EmitNops : 1;
public:
- MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
- unsigned _MaxBytesToEmit, MCSectionData *SD = nullptr)
- : MCFragment(FT_Align, SD), Alignment(_Alignment),
- Value(_Value),ValueSize(_ValueSize),
- MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
+ MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize,
+ unsigned MaxBytesToEmit, MCSection *Sec = nullptr)
+ : MCFragment(FT_Align, Sec), Alignment(Alignment), Value(Value),
+ ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit), EmitNops(false) {}
- /// @name Accessors
+ /// \name Accessors
/// @{
unsigned getAlignment() const { return Alignment; }
@@ -404,15 +379,15 @@ class MCFillFragment : public MCFragment {
uint64_t Size;
public:
- MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
- MCSectionData *SD = nullptr)
- : MCFragment(FT_Fill, SD),
- Value(_Value), ValueSize(_ValueSize), Size(_Size) {
+ MCFillFragment(int64_t Value, unsigned ValueSize, uint64_t Size,
+ MCSection *Sec = nullptr)
+ : MCFragment(FT_Fill, Sec), Value(Value), ValueSize(ValueSize),
+ Size(Size) {
assert((!ValueSize || (Size % ValueSize) == 0) &&
"Fill size must be a multiple of the value size!");
}
- /// @name Accessors
+ /// \name Accessors
/// @{
int64_t getValue() const { return Value; }
@@ -438,12 +413,10 @@ class MCOrgFragment : public MCFragment {
int8_t Value;
public:
- MCOrgFragment(const MCExpr &_Offset, int8_t _Value,
- MCSectionData *SD = nullptr)
- : MCFragment(FT_Org, SD),
- Offset(&_Offset), Value(_Value) {}
+ MCOrgFragment(const MCExpr &Offset, int8_t Value, MCSection *Sec = nullptr)
+ : MCFragment(FT_Org, Sec), Offset(&Offset), Value(Value) {}
- /// @name Accessors
+ /// \name Accessors
/// @{
const MCExpr &getOffset() const { return *Offset; }
@@ -467,13 +440,14 @@ class MCLEBFragment : public MCFragment {
bool IsSigned;
SmallString<8> Contents;
+
public:
- MCLEBFragment(const MCExpr &Value_, bool IsSigned_,
- MCSectionData *SD = nullptr)
- : MCFragment(FT_LEB, SD),
- Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
+ MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
+ : MCFragment(FT_LEB, Sec), Value(&Value_), IsSigned(IsSigned_) {
+ Contents.push_back(0);
+ }
- /// @name Accessors
+ /// \name Accessors
/// @{
const MCExpr &getValue() const { return *Value; }
@@ -504,12 +478,13 @@ class MCDwarfLineAddrFragment : public MCFragment {
SmallString<8> Contents;
public:
- MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
- MCSectionData *SD = nullptr)
- : MCFragment(FT_Dwarf, SD),
- LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
+ MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta,
+ MCSection *Sec = nullptr)
+ : MCFragment(FT_Dwarf, Sec), LineDelta(LineDelta), AddrDelta(&AddrDelta) {
+ Contents.push_back(0);
+ }
- /// @name Accessors
+ /// \name Accessors
/// @{
int64_t getLineDelta() const { return LineDelta; }
@@ -536,12 +511,12 @@ class MCDwarfCallFrameFragment : public MCFragment {
SmallString<8> Contents;
public:
- MCDwarfCallFrameFragment(const MCExpr &_AddrDelta,
- MCSectionData *SD = nullptr)
- : MCFragment(FT_DwarfFrame, SD),
- AddrDelta(&_AddrDelta) { Contents.push_back(0); }
+ MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
+ : MCFragment(FT_DwarfFrame, Sec), AddrDelta(&AddrDelta) {
+ Contents.push_back(0);
+ }
- /// @name Accessors
+ /// \name Accessors
/// @{
const MCExpr &getAddrDelta() const { return *AddrDelta; }
@@ -556,265 +531,10 @@ public:
}
};
-// FIXME: Should this be a separate class, or just merged into MCSection? Since
-// we anticipate the fast path being through an MCAssembler, the only reason to
-// keep it out is for API abstraction.
-class MCSectionData : public ilist_node<MCSectionData> {
- friend class MCAsmLayout;
-
- MCSectionData(const MCSectionData&) LLVM_DELETED_FUNCTION;
- void operator=(const MCSectionData&) LLVM_DELETED_FUNCTION;
-
-public:
- typedef iplist<MCFragment> FragmentListType;
-
- typedef FragmentListType::const_iterator const_iterator;
- typedef FragmentListType::iterator iterator;
-
- typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
- typedef FragmentListType::reverse_iterator reverse_iterator;
-
- /// \brief Express the state of bundle locked groups while emitting code.
- enum BundleLockStateType {
- NotBundleLocked,
- BundleLocked,
- BundleLockedAlignToEnd
- };
-private:
- FragmentListType Fragments;
- const MCSection *Section;
-
- /// Ordinal - The section index in the assemblers section list.
- unsigned Ordinal;
-
- /// LayoutOrder - The index of this section in the layout order.
- unsigned LayoutOrder;
-
- /// Alignment - The maximum alignment seen in this section.
- unsigned Alignment;
-
- /// \brief Keeping track of bundle-locked state.
- BundleLockStateType BundleLockState;
-
- /// \brief Current nesting depth of bundle_lock directives.
- unsigned BundleLockNestingDepth;
-
- /// \brief We've seen a bundle_lock directive but not its first instruction
- /// yet.
- bool BundleGroupBeforeFirstInst;
-
- /// @name Assembler Backend Data
- /// @{
- //
- // FIXME: This could all be kept private to the assembler implementation.
-
- /// HasInstructions - Whether this section has had instructions emitted into
- /// it.
- unsigned HasInstructions : 1;
-
- /// Mapping from subsection number to insertion point for subsection numbers
- /// below that number.
- SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap;
-
- /// @}
-
-public:
- // Only for use as sentinel.
- MCSectionData();
- MCSectionData(const MCSection &Section, MCAssembler *A = nullptr);
-
- const MCSection &getSection() const { return *Section; }
-
- unsigned getAlignment() const { return Alignment; }
- void setAlignment(unsigned Value) { Alignment = Value; }
-
- bool hasInstructions() const { return HasInstructions; }
- void setHasInstructions(bool Value) { HasInstructions = Value; }
-
- unsigned getOrdinal() const { return Ordinal; }
- void setOrdinal(unsigned Value) { Ordinal = Value; }
-
- unsigned getLayoutOrder() const { return LayoutOrder; }
- void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
-
- /// @name Fragment Access
- /// @{
-
- const FragmentListType &getFragmentList() const { return Fragments; }
- FragmentListType &getFragmentList() { return Fragments; }
-
- iterator begin() { return Fragments.begin(); }
- const_iterator begin() const { return Fragments.begin(); }
-
- iterator end() { return Fragments.end(); }
- const_iterator end() const { return Fragments.end(); }
-
- reverse_iterator rbegin() { return Fragments.rbegin(); }
- const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
-
- reverse_iterator rend() { return Fragments.rend(); }
- const_reverse_iterator rend() const { return Fragments.rend(); }
-
- size_t size() const { return Fragments.size(); }
-
- bool empty() const { return Fragments.empty(); }
-
- iterator getSubsectionInsertionPoint(unsigned Subsection);
-
- bool isBundleLocked() const {
- return BundleLockState != NotBundleLocked;
- }
-
- BundleLockStateType getBundleLockState() const {
- return BundleLockState;
- }
-
- void setBundleLockState(BundleLockStateType NewState);
-
- bool isBundleGroupBeforeFirstInst() const {
- return BundleGroupBeforeFirstInst;
- }
-
- void setBundleGroupBeforeFirstInst(bool IsFirst) {
- BundleGroupBeforeFirstInst = IsFirst;
- }
-
- void dump();
-
- /// @}
-};
-
-// FIXME: Same concerns as with SectionData.
-class MCSymbolData : public ilist_node<MCSymbolData> {
- const MCSymbol *Symbol;
-
- /// Fragment - The fragment this symbol's value is relative to, if any. Also
- /// stores if this symbol is visible outside this translation unit (bit 0) or
- /// if it is private extern (bit 1).
- PointerIntPair<MCFragment *, 2> Fragment;
-
- union {
- /// Offset - The offset to apply to the fragment address to form this
- /// symbol's value.
- uint64_t Offset;
-
- /// CommonSize - The size of the symbol, if it is 'common'.
- uint64_t CommonSize;
- };
-
- /// SymbolSize - An expression describing how to calculate the size of
- /// a symbol. If a symbol has no size this field will be NULL.
- const MCExpr *SymbolSize;
-
- /// CommonAlign - The alignment of the symbol, if it is 'common', or -1.
- //
- // FIXME: Pack this in with other fields?
- unsigned CommonAlign;
-
- /// Flags - The Flags field is used by object file implementations to store
- /// additional per symbol information which is not easily classified.
- uint32_t Flags;
-
- /// Index - Index field, for use by the object file implementation.
- uint64_t Index;
-
-public:
- // Only for use as sentinel.
- MCSymbolData();
- MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
- MCAssembler *A = nullptr);
-
- /// @name Accessors
- /// @{
-
- const MCSymbol &getSymbol() const { return *Symbol; }
-
- MCFragment *getFragment() const { return Fragment.getPointer(); }
- void setFragment(MCFragment *Value) { Fragment.setPointer(Value); }
-
- uint64_t getOffset() const {
- assert(!isCommon());
- return Offset;
- }
- void setOffset(uint64_t Value) {
- assert(!isCommon());
- Offset = Value;
- }
-
- /// @}
- /// @name Symbol Attributes
- /// @{
-
- bool isExternal() const { return Fragment.getInt() & 1; }
- void setExternal(bool Value) {
- Fragment.setInt((Fragment.getInt() & ~1) | unsigned(Value));
- }
-
- bool isPrivateExtern() const { return Fragment.getInt() & 2; }
- void setPrivateExtern(bool Value) {
- Fragment.setInt((Fragment.getInt() & ~2) | (unsigned(Value) << 1));
- }
-
- /// isCommon - Is this a 'common' symbol.
- bool isCommon() const { return CommonAlign != -1U; }
-
- /// setCommon - Mark this symbol as being 'common'.
- ///
- /// \param Size - The size of the symbol.
- /// \param Align - The alignment of the symbol.
- void setCommon(uint64_t Size, unsigned Align) {
- assert(getOffset() == 0);
- CommonSize = Size;
- CommonAlign = Align;
- }
-
- /// getCommonSize - Return the size of a 'common' symbol.
- uint64_t getCommonSize() const {
- assert(isCommon() && "Not a 'common' symbol!");
- return CommonSize;
- }
-
- void setSize(const MCExpr *SS) {
- SymbolSize = SS;
- }
-
- const MCExpr *getSize() const {
- return SymbolSize;
- }
-
-
- /// getCommonAlignment - Return the alignment of a 'common' symbol.
- unsigned getCommonAlignment() const {
- assert(isCommon() && "Not a 'common' symbol!");
- return CommonAlign;
- }
-
- /// getFlags - Get the (implementation defined) symbol flags.
- uint32_t getFlags() const { return Flags; }
-
- /// setFlags - Set the (implementation defined) symbol flags.
- void setFlags(uint32_t Value) { Flags = Value; }
-
- /// modifyFlags - Modify the flags via a mask
- void modifyFlags(uint32_t Value, uint32_t Mask) {
- Flags = (Flags & ~Mask) | Value;
- }
-
- /// getIndex - Get the (implementation defined) index.
- uint64_t getIndex() const { return Index; }
-
- /// setIndex - Set the (implementation defined) index.
- void setIndex(uint64_t Value) { Index = Value; }
-
- /// @}
-
- void dump() const;
-};
-
// FIXME: This really doesn't belong here. See comments below.
struct IndirectSymbolData {
MCSymbol *Symbol;
- MCSectionData *SectionData;
+ MCSection *Section;
};
// FIXME: Ditto this. Purely so the Streamer and the ObjectWriter can talk
@@ -831,14 +551,15 @@ class MCAssembler {
friend class MCAsmLayout;
public:
- typedef iplist<MCSectionData> SectionDataListType;
- typedef iplist<MCSymbolData> SymbolDataListType;
+ typedef SetVector<MCSection *> SectionListType;
+ typedef std::vector<const MCSymbol *> SymbolDataListType;
- typedef SectionDataListType::const_iterator const_iterator;
- typedef SectionDataListType::iterator iterator;
+ typedef pointee_iterator<SectionListType::const_iterator> const_iterator;
+ typedef pointee_iterator<SectionListType::iterator> iterator;
- typedef SymbolDataListType::const_iterator const_symbol_iterator;
- typedef SymbolDataListType::iterator symbol_iterator;
+ typedef pointee_iterator<SymbolDataListType::const_iterator>
+ const_symbol_iterator;
+ typedef pointee_iterator<SymbolDataListType::iterator> symbol_iterator;
typedef iterator_range<symbol_iterator> symbol_range;
typedef iterator_range<const_symbol_iterator> const_symbol_range;
@@ -847,11 +568,11 @@ public:
typedef FileNameVectorType::const_iterator const_file_name_iterator;
typedef std::vector<IndirectSymbolData>::const_iterator
- const_indirect_symbol_iterator;
+ const_indirect_symbol_iterator;
typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
typedef std::vector<DataRegionData>::const_iterator
- const_data_region_iterator;
+ const_data_region_iterator;
typedef std::vector<DataRegionData>::iterator data_region_iterator;
/// MachO specific deployment target version info.
@@ -863,9 +584,10 @@ public:
unsigned Minor;
unsigned Update;
} VersionMinInfoType;
+
private:
- MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION;
- void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION;
+ MCAssembler(const MCAssembler &) = delete;
+ void operator=(const MCAssembler &) = delete;
MCContext &Context;
@@ -877,26 +599,18 @@ private:
raw_ostream &OS;
- iplist<MCSectionData> Sections;
+ SectionListType Sections;
- iplist<MCSymbolData> Symbols;
+ SymbolDataListType Symbols;
- /// The map of sections to their associated assembler backend data.
- //
- // FIXME: Avoid this indirection?
- DenseMap<const MCSection*, MCSectionData*> SectionMap;
-
- /// The map of symbols to their associated assembler backend data.
- //
- // FIXME: Avoid this indirection?
- DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
+ DenseSet<const MCSymbol *> LocalsUsedInReloc;
std::vector<IndirectSymbolData> IndirectSymbols;
std::vector<DataRegionData> DataRegions;
/// The list of linker options to propagate into the object file.
- std::vector<std::vector<std::string> > LinkerOptions;
+ std::vector<std::vector<std::string>> LinkerOptions;
/// List of declared file names
FileNameVectorType FileNames;
@@ -908,7 +622,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.
- mutable SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
+ mutable SmallPtrSet<const MCSymbol *, 64> ThumbFuncs;
/// \brief The bundle alignment size currently set in the assembler.
///
@@ -930,6 +644,7 @@ private:
MCLOHContainer LOHContainer;
VersionMinInfoType VersionMinInfo;
+
private:
/// Evaluate a fixup to a relocatable expression and the value which should be
/// placed into the fixup.
@@ -944,9 +659,9 @@ private:
/// \return Whether the fixup value was fully resolved. This is true if the
/// \p Value result is fixed, otherwise the value may change due to
/// relocation.
- bool evaluateFixup(const MCAsmLayout &Layout,
- const MCFixup &Fixup, const MCFragment *DF,
- MCValue &Target, uint64_t &Value) const;
+ bool evaluateFixup(const MCAsmLayout &Layout, const MCFixup &Fixup,
+ const MCFragment *DF, MCValue &Target,
+ uint64_t &Value) const;
/// Check whether a fixup can be satisfied, or whether it needs to be relaxed
/// (increased in size, in order to hold its value correctly).
@@ -963,7 +678,7 @@ private:
/// \brief Perform one layout iteration of the given section and return true
/// if any offsets were adjusted.
- bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD);
+ bool layoutSectionOnce(MCAsmLayout &Layout, MCSection &Sec);
bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF);
@@ -980,6 +695,9 @@ private:
MCFragment &F, const MCFixup &Fixup);
public:
+ void addLocalUsedInReloc(const MCSymbol &Sym);
+ bool isLocalUsedInReloc(const MCSymbol &Sym) const;
+
/// Compute the effective fragment size assuming it is laid out at the given
/// \p SectionAddress and \p FragmentOffset.
uint64_t computeFragmentSize(const MCAsmLayout &Layout,
@@ -987,7 +705,7 @@ public:
/// Find the symbol which defines the atom containing the given symbol, or
/// null if there is no such symbol.
- const MCSymbolData *getAtom(const MCSymbolData *Symbol) const;
+ const MCSymbol *getAtom(const MCSymbol &S) const;
/// Check whether a particular symbol is visible to the linker and is required
/// in the symbol table, or whether it can be discarded by the assembler. This
@@ -996,7 +714,7 @@ public:
bool isSymbolLinkerVisible(const MCSymbol &SD) const;
/// Emit the section contents using the given object writer.
- void writeSectionData(const MCSectionData *Section,
+ void writeSectionData(const MCSection *Section,
const MCAsmLayout &Layout) const;
/// Check whether a given symbol has been flagged with .thumb_func.
@@ -1006,8 +724,8 @@ public:
void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
/// ELF e_header flags
- unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;}
- void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;}
+ unsigned getELFHeaderEFlags() const { return ELFHeaderEFlags; }
+ void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags; }
/// MachO deployment target version information.
const VersionMinInfoType &getVersionMinInfo() const { return VersionMinInfo; }
@@ -1051,36 +769,25 @@ public:
void Finish();
// FIXME: This does not belong here.
- bool getSubsectionsViaSymbols() const {
- return SubsectionsViaSymbols;
- }
- void setSubsectionsViaSymbols(bool Value) {
- SubsectionsViaSymbols = Value;
- }
+ bool getSubsectionsViaSymbols() const { return SubsectionsViaSymbols; }
+ void setSubsectionsViaSymbols(bool Value) { SubsectionsViaSymbols = Value; }
bool getRelaxAll() const { return RelaxAll; }
void setRelaxAll(bool Value) { RelaxAll = Value; }
- bool isBundlingEnabled() const {
- return BundleAlignSize != 0;
- }
+ bool isBundlingEnabled() const { return BundleAlignSize != 0; }
- unsigned getBundleAlignSize() const {
- return BundleAlignSize;
- }
+ unsigned getBundleAlignSize() const { return BundleAlignSize; }
void setBundleAlignSize(unsigned Size) {
- assert((Size == 0 || !(Size & (Size - 1))) &&
+ assert((Size == 0 || !(Size & (Size - 1))) &&
"Expect a power-of-two bundle align size");
BundleAlignSize = Size;
}
- /// @name Section List Access
+ /// \name Section List Access
/// @{
- const SectionDataListType &getSectionList() const { return Sections; }
- SectionDataListType &getSectionList() { return Sections; }
-
iterator begin() { return Sections.begin(); }
const_iterator begin() const { return Sections.begin(); }
@@ -1090,12 +797,8 @@ public:
size_t size() const { return Sections.size(); }
/// @}
- /// @name Symbol List Access
+ /// \name Symbol List Access
/// @{
-
- const SymbolDataListType &getSymbolList() const { return Symbols; }
- SymbolDataListType &getSymbolList() { return Symbols; }
-
symbol_iterator symbol_begin() { return Symbols.begin(); }
const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
@@ -1103,12 +806,14 @@ public:
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()); }
+ const_symbol_range symbols() const {
+ return make_range(symbol_begin(), symbol_end());
+ }
size_t symbol_size() const { return Symbols.size(); }
/// @}
- /// @name Indirect Symbol List Access
+ /// \name Indirect Symbol List Access
/// @{
// FIXME: This is a total hack, this should not be here. Once things are
@@ -1135,34 +840,28 @@ public:
size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
/// @}
- /// @name Linker Option List Access
+ /// \name Linker Option List Access
/// @{
- std::vector<std::vector<std::string> > &getLinkerOptions() {
+ std::vector<std::vector<std::string>> &getLinkerOptions() {
return LinkerOptions;
}
/// @}
- /// @name Data Region List Access
+ /// \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.
- std::vector<DataRegionData> &getDataRegions() {
- return DataRegions;
- }
+ std::vector<DataRegionData> &getDataRegions() { return DataRegions; }
- data_region_iterator data_region_begin() {
- return DataRegions.begin();
- }
+ data_region_iterator data_region_begin() { return DataRegions.begin(); }
const_data_region_iterator data_region_begin() const {
return DataRegions.begin();
}
- data_region_iterator data_region_end() {
- return DataRegions.end();
- }
+ data_region_iterator data_region_end() { return DataRegions.end(); }
const_data_region_iterator data_region_end() const {
return DataRegions.end();
}
@@ -1170,42 +869,23 @@ public:
size_t data_region_size() const { return DataRegions.size(); }
/// @}
- /// @name Data Region List Access
+ /// \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 {
+ MCLOHContainer &getLOHContainer() { return LOHContainer; }
+ const MCLOHContainer &getLOHContainer() const {
return const_cast<MCAssembler *>(this)->getLOHContainer();
}
/// @}
- /// @name Backend Data Access
+ /// \name Backend Data Access
/// @{
- MCSectionData &getSectionData(const MCSection &Section) const {
- MCSectionData *Entry = SectionMap.lookup(&Section);
- assert(Entry && "Missing section data!");
- return *Entry;
- }
-
- MCSectionData &getOrCreateSectionData(const MCSection &Section,
- bool *Created = nullptr) {
- MCSectionData *&Entry = SectionMap[&Section];
+ bool registerSection(MCSection &Section) { return Sections.insert(&Section); }
- if (Created) *Created = !Entry;
- if (!Entry)
- Entry = new MCSectionData(Section, this);
-
- return *Entry;
- }
-
- bool hasSymbolData(const MCSymbol &Symbol) const {
- return SymbolMap.lookup(&Symbol) != nullptr;
- }
+ bool hasSymbolData(const MCSymbol &Symbol) const { return Symbol.hasData(); }
MCSymbolData &getSymbolData(const MCSymbol &Symbol) {
return const_cast<MCSymbolData &>(
@@ -1213,29 +893,25 @@ public:
}
const MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
- MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
- assert(Entry && "Missing symbol data!");
- return *Entry;
+ return Symbol.getData();
}
MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
bool *Created = nullptr) {
- MCSymbolData *&Entry = SymbolMap[&Symbol];
-
- if (Created) *Created = !Entry;
- if (!Entry)
- Entry = new MCSymbolData(Symbol, nullptr, 0, this);
-
- return *Entry;
+ if (Created)
+ *Created = !hasSymbolData(Symbol);
+ if (!hasSymbolData(Symbol)) {
+ Symbol.initializeData();
+ Symbols.push_back(&Symbol);
+ }
+ return Symbol.getData();
}
const_file_name_iterator file_names_begin() const {
return FileNames.begin();
}
- const_file_name_iterator file_names_end() const {
- return FileNames.end();
- }
+ const_file_name_iterator file_names_end() const { return FileNames.end(); }
void addFileName(StringRef FileName) {
if (std::find(file_names_begin(), file_names_end(), FileName) ==
@@ -1243,11 +919,22 @@ public:
FileNames.push_back(FileName);
}
+ /// \brief Write the necessary bundle padding to the given object writer.
+ /// Expects a fragment \p F containing instructions and its size \p FSize.
+ void writeFragmentPadding(const MCFragment &F, uint64_t FSize,
+ MCObjectWriter *OW) const;
+
/// @}
void dump();
};
+/// \brief Compute the amount of padding required before the fragment \p F to
+/// obey bundling restrictions, where \p FOffset is the fragment's offset in
+/// its section and \p FSize is the fragment's size.
+uint64_t computeBundlePadding(const MCAssembler &Assembler, const MCFragment *F,
+ uint64_t FOffset, uint64_t FSize);
+
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h
index d3b56177d50a7..b6c19150c12a5 100644
--- a/include/llvm/MC/MCCodeEmitter.h
+++ b/include/llvm/MC/MCCodeEmitter.h
@@ -22,8 +22,9 @@ template<typename T> class SmallVectorImpl;
/// MCCodeEmitter - Generic instruction encoding interface.
class MCCodeEmitter {
private:
- MCCodeEmitter(const MCCodeEmitter &) LLVM_DELETED_FUNCTION;
- void operator=(const MCCodeEmitter &) LLVM_DELETED_FUNCTION;
+ MCCodeEmitter(const MCCodeEmitter &) = delete;
+ void operator=(const MCCodeEmitter &) = delete;
+
protected: // Can only create subclasses.
MCCodeEmitter();
@@ -31,11 +32,11 @@ public:
virtual ~MCCodeEmitter();
/// Lifetime management
- virtual void reset() { }
+ virtual void reset() {}
/// EncodeInstruction - Encode the given \p Inst to bytes on the output
/// stream \p OS.
- virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS,
+ virtual void encodeInstruction(const MCInst &Inst, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const = 0;
};
diff --git a/include/llvm/MC/MCCodeGenInfo.h b/include/llvm/MC/MCCodeGenInfo.h
index 84ce934d822ee..0a4744f1d0f7d 100644
--- a/include/llvm/MC/MCCodeGenInfo.h
+++ b/include/llvm/MC/MCCodeGenInfo.h
@@ -19,33 +19,33 @@
namespace llvm {
- class MCCodeGenInfo {
- /// RelocationModel - Relocation model: static, pic, etc.
- ///
- Reloc::Model RelocationModel;
+class MCCodeGenInfo {
+ /// RelocationModel - Relocation model: static, pic, etc.
+ ///
+ Reloc::Model RelocationModel;
- /// CMModel - Code model.
- ///
- CodeModel::Model CMModel;
+ /// CMModel - Code model.
+ ///
+ CodeModel::Model CMModel;
- /// OptLevel - Optimization level.
- ///
- CodeGenOpt::Level OptLevel;
+ /// OptLevel - Optimization level.
+ ///
+ CodeGenOpt::Level OptLevel;
- public:
- void InitMCCodeGenInfo(Reloc::Model RM = Reloc::Default,
- CodeModel::Model CM = CodeModel::Default,
- CodeGenOpt::Level OL = CodeGenOpt::Default);
+public:
+ void initMCCodeGenInfo(Reloc::Model RM = Reloc::Default,
+ CodeModel::Model CM = CodeModel::Default,
+ CodeGenOpt::Level OL = CodeGenOpt::Default);
- Reloc::Model getRelocationModel() const { return RelocationModel; }
+ Reloc::Model getRelocationModel() const { return RelocationModel; }
- CodeModel::Model getCodeModel() const { return CMModel; }
+ CodeModel::Model getCodeModel() const { return CMModel; }
- CodeGenOpt::Level getOptLevel() const { return OptLevel; }
+ CodeGenOpt::Level getOptLevel() const { return OptLevel; }
- // Allow overriding OptLevel on a per-function basis.
- void setOptLevel(CodeGenOpt::Level Level) { OptLevel = Level; }
- };
+ // Allow overriding OptLevel on a per-function basis.
+ void setOptLevel(CodeGenOpt::Level Level) { OptLevel = Level; }
+};
} // namespace llvm
#endif
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index e3163a7946a79..5b57b9d448e81 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -15,8 +15,8 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/Twine.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"
@@ -37,20 +37,20 @@ namespace llvm {
class MCRegisterInfo;
class MCLineSection;
class SMLoc;
- class StringRef;
- class Twine;
class MCSectionMachO;
class MCSectionELF;
class MCSectionCOFF;
- /// MCContext - Context object for machine code objects. This class owns all
- /// of the sections that it creates.
+ /// Context object for machine code objects. This class owns all of the
+ /// sections that it creates.
///
class MCContext {
- MCContext(const MCContext&) LLVM_DELETED_FUNCTION;
- MCContext &operator=(const MCContext&) LLVM_DELETED_FUNCTION;
+ MCContext(const MCContext &) = delete;
+ MCContext &operator=(const MCContext &) = delete;
+
public:
- typedef StringMap<MCSymbol*, BumpPtrAllocator&> SymbolTable;
+ typedef StringMap<MCSymbol *, BumpPtrAllocator &> SymbolTable;
+
private:
/// The SourceMgr for this object, if any.
const SourceMgr *SrcMgr;
@@ -64,34 +64,34 @@ namespace llvm {
/// The MCObjectFileInfo for this target.
const MCObjectFileInfo *MOFI;
- /// Allocator - Allocator object used for creating machine code objects.
+ /// Allocator object used for creating machine code objects.
///
/// We use a bump pointer allocator to avoid the need to track all allocated
/// objects.
BumpPtrAllocator Allocator;
- /// Symbols - Bindings of names to symbols.
+ /// Bindings of names to symbols.
SymbolTable Symbols;
/// ELF sections can have a corresponding symbol. This maps one to the
/// other.
- DenseMap<const MCSectionELF*, MCSymbol*> SectionSymbols;
+ DenseMap<const MCSectionELF *, MCSymbol *> SectionSymbols;
- /// A maping from a local label number and an instance count to a symbol.
+ /// A mapping 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;
+ 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;
+ /// Keeps tracks of names that were used both for used declared and
+ /// artificial symbols.
+ StringMap<bool, BumpPtrAllocator &> UsedNames;
- /// NextUniqueID - The next ID to dole out to an unnamed assembler temporary
- /// symbol.
- unsigned NextUniqueID;
+ /// The next ID to dole out to an unnamed assembler temporary symbol with
+ /// a given prefix.
+ StringMap<unsigned> NextID;
/// Instances of directional local labels.
DenseMap<unsigned, MCLabel *> Instances;
@@ -136,10 +136,8 @@ namespace llvm {
/// assembly source files.
unsigned GenDwarfFileNumber;
- /// 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;
+ /// Sections for generating the .debug_ranges and .debug_aranges sections.
+ SetVector<MCSection *> SectionsForRanges;
/// The information gathered from labels that will have dwarf label
/// entries when generating dwarf assembly source files.
@@ -160,21 +158,54 @@ namespace llvm {
/// differences between temporary and non-temporary labels (primarily on
/// Darwin).
bool AllowTemporaryLabels;
+ bool UseNamesOnTempLabels = true;
/// The Compile Unit ID that we are currently processing.
unsigned DwarfCompileUnitID;
- 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;
+ struct ELFSectionKey {
+ std::string SectionName;
+ StringRef GroupName;
+ unsigned UniqueID;
+ ELFSectionKey(StringRef SectionName, StringRef GroupName,
+ unsigned UniqueID)
+ : SectionName(SectionName), GroupName(GroupName), UniqueID(UniqueID) {
+ }
+ bool operator<(const ELFSectionKey &Other) const {
+ if (SectionName != Other.SectionName)
+ return SectionName < Other.SectionName;
+ if (GroupName != Other.GroupName)
+ return GroupName < Other.GroupName;
+ return UniqueID < Other.UniqueID;
+ }
+ };
+
+ struct COFFSectionKey {
+ std::string SectionName;
+ StringRef GroupName;
+ int SelectionKey;
+ COFFSectionKey(StringRef SectionName, StringRef GroupName,
+ int SelectionKey)
+ : SectionName(SectionName), GroupName(GroupName),
+ SelectionKey(SelectionKey) {}
+ bool operator<(const COFFSectionKey &Other) const {
+ if (SectionName != Other.SectionName)
+ return SectionName < Other.SectionName;
+ if (GroupName != Other.GroupName)
+ return GroupName < Other.GroupName;
+ return SelectionKey < Other.SelectionKey;
+ }
+ };
+
+ StringMap<MCSectionMachO *> MachOUniquingMap;
+ std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap;
+ std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
+ StringMap<bool> ELFRelSecNames;
/// Do automatic reset in destructor
bool AutoReset;
- MCSymbol *CreateSymbol(StringRef Name);
+ MCSymbol *CreateSymbol(StringRef Name, bool AlwaysAddSuffix);
MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
unsigned Instance);
@@ -194,8 +225,9 @@ namespace llvm {
const MCObjectFileInfo *getObjectFileInfo() const { return MOFI; }
void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; }
+ void setUseNamesOnTempLabels(bool Value) { UseNamesOnTempLabels = Value; }
- /// @name Module Lifetime Management
+ /// \name Module Lifetime Management
/// @{
/// reset - return object to right after construction state to prepare
@@ -204,104 +236,144 @@ namespace llvm {
/// @}
- /// @name Symbol Management
+ /// \name Symbol Management
/// @{
- /// CreateLinkerPrivateTempSymbol - Create and return a new linker temporary
- /// symbol with a unique but unspecified name.
- MCSymbol *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();
+ /// Create and return a new assembler temporary symbol with a unique but
+ /// unspecified name.
+ MCSymbol *createTempSymbol();
- /// getUniqueSymbolID() - Return a unique identifier for use in constructing
- /// symbol names.
- unsigned getUniqueSymbolID() { return NextUniqueID++; }
+ MCSymbol *createTempSymbol(const Twine &Name, bool AlwaysAddSuffix);
/// Create the definition of a directional local symbol for numbered label
/// (used for "1:" definitions).
- MCSymbol *CreateDirectionalLocalSymbol(unsigned LocalLabelVal);
+ MCSymbol *createDirectionalLocalSymbol(unsigned LocalLabelVal);
/// Create and return a directional local symbol for numbered label (used
/// for "1b" or 1f" references).
- MCSymbol *GetDirectionalLocalSymbol(unsigned LocalLabelVal, bool Before);
+ 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
- /// reference and return it.
+ /// Lookup the symbol inside with the specified \p Name. If it exists,
+ /// return it. If not, create a forward reference and return it.
///
- /// @param Name - The symbol name, which must be unique across all symbols.
- MCSymbol *GetOrCreateSymbol(StringRef Name);
- MCSymbol *GetOrCreateSymbol(const Twine &Name);
+ /// \param Name - The symbol name, which must be unique across all symbols.
+ MCSymbol *getOrCreateSymbol(const Twine &Name);
MCSymbol *getOrCreateSectionSymbol(const MCSectionELF &Section);
- MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName);
+ /// Gets a symbol that will be defined to the final stack offset of a local
+ /// variable after codegen.
+ ///
+ /// \param Idx - The index of a local variable passed to @llvm.frameescape.
+ MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName, unsigned Idx);
+
+ MCSymbol *getOrCreateParentFrameOffsetSymbol(StringRef FuncName);
+
+ MCSymbol *getOrCreateLSDASymbol(StringRef FuncName);
- /// LookupSymbol - Get the symbol for \p Name, or null.
- MCSymbol *LookupSymbol(StringRef Name) const;
- MCSymbol *LookupSymbol(const Twine &Name) const;
+ /// Get the symbol for \p Name, or null.
+ MCSymbol *lookupSymbol(const Twine &Name) const;
/// getSymbols - Get a reference for the symbol table for clients that
/// want to, for example, iterate over all symbols. 'const' because we
/// still want any modifications to the table itself to use the MCContext
/// APIs.
- const SymbolTable &getSymbols() const {
- return Symbols;
- }
+ const SymbolTable &getSymbols() const { return Symbols; }
/// @}
- /// @name Section Management
+ /// \name Section Management
/// @{
- /// getMachOSection - Return the MCSection for the specified mach-o section.
- /// This requires the operands to be valid.
- const MCSectionMachO *getMachOSection(StringRef Segment,
- StringRef Section,
- unsigned TypeAndAttributes,
- unsigned Reserved2,
- SectionKind K);
- const MCSectionMachO *getMachOSection(StringRef Segment,
- StringRef Section,
- unsigned TypeAndAttributes,
- SectionKind K) {
- return getMachOSection(Segment, Section, TypeAndAttributes, 0, K);
+ /// Return the MCSection for the specified mach-o section. This requires
+ /// the operands to be valid.
+ MCSectionMachO *getMachOSection(StringRef Segment, StringRef Section,
+ unsigned TypeAndAttributes,
+ unsigned Reserved2, SectionKind K,
+ const char *BeginSymName = nullptr);
+
+ MCSectionMachO *getMachOSection(StringRef Segment, StringRef Section,
+ unsigned TypeAndAttributes, SectionKind K,
+ const char *BeginSymName = nullptr) {
+ return getMachOSection(Segment, Section, TypeAndAttributes, 0, K,
+ BeginSymName);
}
- const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
- unsigned Flags, SectionKind Kind);
+ MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags) {
+ return getELFSection(Section, Type, Flags, nullptr);
+ }
- const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
- unsigned Flags, SectionKind Kind,
- unsigned EntrySize, StringRef Group);
+ MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, const char *BeginSymName) {
+ return getELFSection(Section, Type, Flags, 0, "", BeginSymName);
+ }
- void renameELFSection(const MCSectionELF *Section, StringRef Name);
+ MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ StringRef Group) {
+ return getELFSection(Section, Type, Flags, EntrySize, Group, nullptr);
+ }
- const MCSectionELF *CreateELFGroupSection();
+ MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ StringRef Group, const char *BeginSymName) {
+ return getELFSection(Section, Type, Flags, EntrySize, Group, ~0,
+ BeginSymName);
+ }
- const MCSectionCOFF *getCOFFSection(StringRef Section,
- unsigned Characteristics,
- SectionKind Kind,
- StringRef COMDATSymName, int Selection);
+ MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ StringRef Group, unsigned UniqueID) {
+ return getELFSection(Section, Type, Flags, EntrySize, Group, UniqueID,
+ nullptr);
+ }
- const MCSectionCOFF *getCOFFSection(StringRef Section,
- unsigned Characteristics,
- SectionKind Kind);
+ MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ StringRef Group, unsigned UniqueID,
+ const char *BeginSymName);
- const MCSectionCOFF *getCOFFSection(StringRef Section);
+ MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ const MCSymbol *Group, unsigned UniqueID,
+ const char *BeginSymName,
+ const MCSectionELF *Associated);
+
+ MCSectionELF *createELFRelSection(StringRef Name, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ const MCSymbol *Group,
+ const MCSectionELF *Associated);
+
+ void renameELFSection(MCSectionELF *Section, StringRef Name);
+
+ MCSectionELF *createELFGroupSection(const MCSymbol *Group);
+
+ MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
+ SectionKind Kind, StringRef COMDATSymName,
+ int Selection,
+ const char *BeginSymName = nullptr);
+
+ MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
+ SectionKind Kind,
+ const char *BeginSymName = nullptr);
+
+ MCSectionCOFF *getCOFFSection(StringRef Section);
/// Gets or creates a section equivalent to Sec that is associated with the
/// section containing KeySym. For example, to create a debug info section
/// associated with an inline function, pass the normal debug info section
/// as Sec and the function symbol as KeySym.
- const MCSectionCOFF *getAssociativeCOFFSection(const MCSectionCOFF *Sec,
- const MCSymbol *KeySym);
+ MCSectionCOFF *getAssociativeCOFFSection(MCSectionCOFF *Sec,
+ const MCSymbol *KeySym);
/// @}
- /// @name Dwarf Management
+ /// \name Dwarf Management
/// @{
/// \brief Get the compilation directory for DW_AT_comp_dir
@@ -323,8 +395,8 @@ namespace llvm {
/// \brief Set the main file name and override the default.
void setMainFileName(StringRef S) { MainFileName = S; }
- /// GetDwarfFile - creates an entry in the dwarf file and directory tables.
- unsigned GetDwarfFile(StringRef Directory, StringRef FileName,
+ /// Creates an entry in the dwarf file and directory tables.
+ unsigned getDwarfFile(StringRef Directory, StringRef FileName,
unsigned FileNumber, unsigned CUID);
bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0);
@@ -356,9 +428,7 @@ namespace llvm {
return true;
return false;
}
- unsigned getDwarfCompileUnitID() {
- return DwarfCompileUnitID;
- }
+ unsigned getDwarfCompileUnitID() { return DwarfCompileUnitID; }
void setDwarfCompileUnitID(unsigned CUIndex) {
DwarfCompileUnitID = CUIndex;
}
@@ -366,10 +436,10 @@ namespace llvm {
getMCDwarfLineTable(CUID).setCompilationDir(CompilationDir);
}
- /// setCurrentDwarfLoc - saves the information from the currently parsed
- /// dwarf .loc directive and sets DwarfLocSeen. When the next instruction
- /// is assembled an entry in the line number table with this information and
- /// the address of the instruction will be created.
+ /// Saves the information from the currently parsed dwarf .loc directive
+ /// and sets DwarfLocSeen. When the next instruction is assembled an entry
+ /// in the line number table with this information and the address of the
+ /// instruction will be created.
void setCurrentDwarfLoc(unsigned FileNum, unsigned Line, unsigned Column,
unsigned Flags, unsigned Isa,
unsigned Discriminator) {
@@ -381,7 +451,7 @@ namespace llvm {
CurrentDwarfLoc.setDiscriminator(Discriminator);
DwarfLocSeen = true;
}
- void ClearDwarfLocSeen() { DwarfLocSeen = false; }
+ void clearDwarfLocSeen() { DwarfLocSeen = false; }
bool getDwarfLocSeen() { return DwarfLocSeen; }
const MCDwarfLoc &getCurrentDwarfLoc() { return CurrentDwarfLoc; }
@@ -392,17 +462,13 @@ namespace llvm {
void setGenDwarfFileNumber(unsigned FileNumber) {
GenDwarfFileNumber = FileNumber;
}
- MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> > &
- getGenDwarfSectionSyms() {
- return SectionStartEndSyms;
+ const SetVector<MCSection *> &getGenDwarfSectionSyms() {
+ return SectionsForRanges;
}
- 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)));
+ bool addGenDwarfSection(MCSection *Sec) {
+ return SectionsForRanges.insert(Sec);
}
+
void finalizeDwarfSections(MCStreamer &MCOS);
const std::vector<MCGenDwarfLabelEntry> &getMCGenDwarfLabelEntries() const {
return MCGenDwarfLabelEntries;
@@ -425,56 +491,52 @@ namespace llvm {
char *getSecureLogFile() { return SecureLogFile; }
raw_ostream *getSecureLog() { return SecureLog; }
bool getSecureLogUsed() { return SecureLogUsed; }
- void setSecureLog(raw_ostream *Value) {
- SecureLog = Value;
- }
- void setSecureLogUsed(bool Value) {
- SecureLogUsed = Value;
- }
+ void setSecureLog(raw_ostream *Value) { SecureLog = Value; }
+ void setSecureLogUsed(bool Value) { SecureLogUsed = Value; }
- void *Allocate(unsigned Size, unsigned Align = 8) {
+ void *allocate(unsigned Size, unsigned Align = 8) {
return Allocator.Allocate(Size, Align);
}
- void Deallocate(void *Ptr) {
- }
+ void deallocate(void *Ptr) {}
// 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) const;
+ LLVM_ATTRIBUTE_NORETURN void reportFatalError(SMLoc L,
+ const Twine &Msg) const;
};
} // end namespace llvm
// operator new and delete aren't allowed inside namespaces.
// The throw specifications are mandated by the standard.
-/// @brief Placement new for using the MCContext's allocator.
+/// \brief Placement new for using the MCContext's allocator.
///
/// This placement form of operator new uses the MCContext's allocator for
/// obtaining memory. It is a non-throwing new, which means that it returns
/// null on error. (If that is what the allocator does. The current does, so if
/// this ever changes, this operator will have to be changed, too.)
/// Usage looks like this (assuming there's an MCContext 'Context' in scope):
-/// @code
-/// // Default alignment (16)
+/// \code
+/// // Default alignment (8)
/// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments);
/// // Specific alignment
-/// IntegerLiteral *Ex2 = new (Context, 8) IntegerLiteral(arguments);
-/// @endcode
+/// IntegerLiteral *Ex2 = new (Context, 4) IntegerLiteral(arguments);
+/// \endcode
/// Please note that you cannot use delete on the pointer; it must be
/// deallocated using an explicit destructor call followed by
-/// @c Context.Deallocate(Ptr).
+/// \c Context.Deallocate(Ptr).
///
-/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
-/// @param C The MCContext that provides the allocator.
-/// @param Alignment The alignment of the allocated memory (if the underlying
+/// \param Bytes The number of bytes to allocate. Calculated by the compiler.
+/// \param C The MCContext that provides the allocator.
+/// \param Alignment The alignment of the allocated memory (if the underlying
/// allocator supports it).
-/// @return The allocated memory. Could be NULL.
+/// \return The allocated memory. Could be NULL.
inline void *operator new(size_t Bytes, llvm::MCContext &C,
- size_t Alignment = 16) throw () {
- return C.Allocate(Bytes, Alignment);
+ size_t Alignment = 8) throw() {
+ return C.allocate(Bytes, Alignment);
}
-/// @brief Placement delete companion to the new above.
+/// \brief Placement delete companion to the new above.
///
/// This operator is just a companion to the new above. There is no way of
/// invoking it directly; see the new operator for more details. This operator
@@ -482,41 +544,41 @@ inline void *operator new(size_t Bytes, llvm::MCContext &C,
/// the MCContext throws in the object constructor.
inline void operator delete(void *Ptr, llvm::MCContext &C, size_t)
throw () {
- C.Deallocate(Ptr);
+ C.deallocate(Ptr);
}
/// This placement form of operator new[] uses the MCContext's allocator for
/// obtaining memory. It is a non-throwing new[], which means that it returns
/// null on error.
/// Usage looks like this (assuming there's an MCContext 'Context' in scope):
-/// @code
-/// // Default alignment (16)
+/// \code
+/// // Default alignment (8)
/// char *data = new (Context) char[10];
/// // Specific alignment
-/// char *data = new (Context, 8) char[10];
-/// @endcode
+/// char *data = new (Context, 4) char[10];
+/// \endcode
/// Please note that you cannot use delete on the pointer; it must be
/// deallocated using an explicit destructor call followed by
-/// @c Context.Deallocate(Ptr).
+/// \c Context.Deallocate(Ptr).
///
-/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
-/// @param C The MCContext that provides the allocator.
-/// @param Alignment The alignment of the allocated memory (if the underlying
+/// \param Bytes The number of bytes to allocate. Calculated by the compiler.
+/// \param C The MCContext that provides the allocator.
+/// \param Alignment The alignment of the allocated memory (if the underlying
/// allocator supports it).
-/// @return The allocated memory. Could be NULL.
+/// \return The allocated memory. Could be NULL.
inline void *operator new[](size_t Bytes, llvm::MCContext& C,
- size_t Alignment = 16) throw () {
- return C.Allocate(Bytes, Alignment);
+ size_t Alignment = 8) throw() {
+ return C.allocate(Bytes, Alignment);
}
-/// @brief Placement delete[] companion to the new[] above.
+/// \brief Placement delete[] companion to the new[] above.
///
/// This operator is just a companion to the new[] above. There is no way of
/// invoking it directly; see the new[] operator for more details. This operator
/// is called implicitly by the compiler if a placement new[] expression using
/// the MCContext throws in the object constructor.
inline void operator delete[](void *Ptr, llvm::MCContext &C) throw () {
- C.Deallocate(Ptr);
+ C.deallocate(Ptr);
}
#endif
diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h
index d6b0a305b1dae..57c40d660f642 100644
--- a/include/llvm/MC/MCDisassembler.h
+++ b/include/llvm/MC/MCDisassembler.h
@@ -11,7 +11,6 @@
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/MC/MCRelocationInfo.h"
#include "llvm/MC/MCSymbolizer.h"
#include "llvm/Support/DataTypes.h"
@@ -61,16 +60,16 @@ public:
/// Returns the disassembly of a single instruction.
///
- /// @param Instr - An MCInst to populate with the contents of the
+ /// \param Instr - An MCInst to populate with the contents of the
/// instruction.
- /// @param Size - A value to populate with the size of the instruction, or
+ /// \param Size - A value to populate with the size of the instruction, or
/// the number of bytes consumed while attempting to decode
/// an invalid instruction.
- /// @param Address - The address, in the memory space of region, of the first
+ /// \param Address - The address, in the memory space of region, of the first
/// byte of the instruction.
- /// @param VStream - The stream to print warnings and diagnostic messages on.
- /// @param CStream - The stream to print comments and annotations on.
- /// @return - MCDisassembler::Success if the instruction is valid,
+ /// \param VStream - The stream to print warnings and diagnostic messages on.
+ /// \param CStream - The stream to print comments and annotations on.
+ /// \return - MCDisassembler::Success if the instruction is valid,
/// MCDisassembler::SoftFail if the instruction was
/// disassemblable but invalid,
/// MCDisassembler::Fail if the instruction was invalid.
diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h
index c266acf2f09c5..c7bed8eccda93 100644
--- a/include/llvm/MC/MCDwarf.h
+++ b/include/llvm/MC/MCDwarf.h
@@ -37,34 +37,29 @@ class MCSymbol;
class SourceMgr;
class SMLoc;
-/// MCDwarfFile - Instances of this class represent the name of the dwarf
+/// \brief Instances of this class represent the name of the dwarf
/// .file directive and its associated dwarf file number in the MC file,
-/// and MCDwarfFile's are created and unique'd by the MCContext class where
+/// and MCDwarfFile's are created and uniqued 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).
struct MCDwarfFile {
- // Name - the base name of the file without its directory path.
+ // \brief The base name of the file without its directory path.
// The StringRef references memory allocated in the MCContext.
std::string Name;
- // DirIndex - the index into the list of directory names for this file name.
+ // \brief The index into the list of directory names for this file name.
unsigned DirIndex;
};
-/// MCDwarfLoc - Instances of this class represent the information from a
+/// \brief Instances of this class represent the information from a
/// dwarf .loc directive.
class MCDwarfLoc {
- // FileNum - the file number.
unsigned FileNum;
- // Line - the line number.
unsigned Line;
- // Column - the column position.
unsigned Column;
// Flags (see #define's below)
unsigned Flags;
- // Isa
unsigned Isa;
- // Discriminator
unsigned Discriminator;
// Flag that indicates the initial value of the is_stmt_start flag.
@@ -87,46 +82,46 @@ private: // MCContext manages these
// for an MCDwarfLoc object.
public:
- /// getFileNum - Get the FileNum of this MCDwarfLoc.
+ /// \brief Get the FileNum of this MCDwarfLoc.
unsigned getFileNum() const { return FileNum; }
- /// getLine - Get the Line of this MCDwarfLoc.
+ /// \brief Get the Line of this MCDwarfLoc.
unsigned getLine() const { return Line; }
- /// getColumn - Get the Column of this MCDwarfLoc.
+ /// \brief Get the Column of this MCDwarfLoc.
unsigned getColumn() const { return Column; }
- /// getFlags - Get the Flags of this MCDwarfLoc.
+ /// \brief Get the Flags of this MCDwarfLoc.
unsigned getFlags() const { return Flags; }
- /// getIsa - Get the Isa of this MCDwarfLoc.
+ /// \brief Get the Isa of this MCDwarfLoc.
unsigned getIsa() const { return Isa; }
- /// getDiscriminator - Get the Discriminator of this MCDwarfLoc.
+ /// \brief Get the Discriminator of this MCDwarfLoc.
unsigned getDiscriminator() const { return Discriminator; }
- /// setFileNum - Set the FileNum of this MCDwarfLoc.
+ /// \brief Set the FileNum of this MCDwarfLoc.
void setFileNum(unsigned fileNum) { FileNum = fileNum; }
- /// setLine - Set the Line of this MCDwarfLoc.
+ /// \brief Set the Line of this MCDwarfLoc.
void setLine(unsigned line) { Line = line; }
- /// setColumn - Set the Column of this MCDwarfLoc.
+ /// \brief Set the Column of this MCDwarfLoc.
void setColumn(unsigned column) { Column = column; }
- /// setFlags - Set the Flags of this MCDwarfLoc.
+ /// \brief Set the Flags of this MCDwarfLoc.
void setFlags(unsigned flags) { Flags = flags; }
- /// setIsa - Set the Isa of this MCDwarfLoc.
+ /// \brief Set the Isa of this MCDwarfLoc.
void setIsa(unsigned isa) { Isa = isa; }
- /// setDiscriminator - Set the Discriminator of this MCDwarfLoc.
+ /// \brief Set the Discriminator of this MCDwarfLoc.
void setDiscriminator(unsigned discriminator) {
Discriminator = discriminator;
}
};
-/// MCLineEntry - Instances of this class represent the line information for
+/// \brief Instances of this class represent the line information for
/// the dwarf line table entries. Which is created after a machine
/// instruction is assembled and uses an address from a temporary label
/// created at the current address in the current section and the info from
@@ -148,24 +143,24 @@ 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(MCObjectStreamer *MCOS, const MCSection *Section);
+ static void Make(MCObjectStreamer *MCOS, MCSection *Section);
};
-/// MCLineSection - Instances of this class represent the line information
-/// for a compile unit where machine instructions have been assembled after seeing
-/// .loc directives. This is the information used to build the dwarf line
+/// \brief Instances of this class represent the line information 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 {
public:
- // addLineEntry - adds an entry to this MCLineSection's line entries
- void addLineEntry(const MCLineEntry &LineEntry, const MCSection *Sec) {
+ // \brief Add an entry to this MCLineSection's line entries.
+ void addLineEntry(const MCLineEntry &LineEntry, MCSection *Sec) {
MCLineDivisions[Sec].push_back(LineEntry);
}
typedef std::vector<MCLineEntry> MCLineEntryCollection;
typedef MCLineEntryCollection::iterator iterator;
typedef MCLineEntryCollection::const_iterator const_iterator;
- typedef MapVector<const MCSection *, MCLineEntryCollection> MCLineDivisionMap;
+ typedef MapVector<MCSection *, MCLineEntryCollection> MCLineDivisionMap;
private:
// A collection of MCLineEntry for each section.
diff --git a/include/llvm/MC/MCELF.h b/include/llvm/MC/MCELF.h
index 294a51bf7c765..f409988d5726c 100644
--- a/include/llvm/MC/MCELF.h
+++ b/include/llvm/MC/MCELF.h
@@ -15,8 +15,6 @@
#ifndef LLVM_MC_MCELF_H
#define LLVM_MC_MCELF_H
-#include "llvm/MC/MCExpr.h"
-
namespace llvm {
class MCSymbolData;
diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h
index 421e7a0b2c194..cf73eca340d72 100644
--- a/include/llvm/MC/MCELFObjectWriter.h
+++ b/include/llvm/MC/MCELFObjectWriter.h
@@ -20,10 +20,21 @@ class MCAssembler;
class MCFixup;
class MCFragment;
class MCObjectWriter;
-class MCSectionData;
class MCSymbol;
class MCSymbolData;
class MCValue;
+class raw_pwrite_stream;
+
+struct ELFRelocationEntry {
+ uint64_t Offset; // Where is the relocation.
+ const MCSymbol *Symbol; // The symbol to relocate with.
+ unsigned Type; // The type of the relocation.
+ uint64_t Addend; // The addend to use.
+
+ ELFRelocationEntry(uint64_t Offset, const MCSymbol *Symbol, unsigned Type,
+ uint64_t Addend)
+ : Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend) {}
+};
class MCELFObjectTargetWriter {
const uint8_t OSABI;
@@ -41,6 +52,9 @@ protected:
public:
static uint8_t getOSABI(Triple::OSType OSType) {
switch (OSType) {
+ case Triple::CloudABI:
+ return ELF::ELFOSABI_CLOUDABI;
+ case Triple::PS4:
case Triple::FreeBSD:
return ELF::ELFOSABI_FREEBSD;
case Triple::Linux:
@@ -58,7 +72,10 @@ public:
virtual bool needsRelocateWithSymbol(const MCSymbolData &SD,
unsigned Type) const;
- /// @name Accessors
+ virtual void sortRelocs(const MCAssembler &Asm,
+ std::vector<ELFRelocationEntry> &Relocs);
+
+ /// \name Accessors
/// @{
uint8_t getOSABI() const { return OSABI; }
uint16_t getEMachine() const { return EMachine; }
@@ -113,7 +130,8 @@ public:
/// \param OS - The stream to write to.
/// \returns The constructed object writer.
MCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
- raw_ostream &OS, bool IsLittleEndian);
+ raw_pwrite_stream &OS,
+ bool IsLittleEndian);
} // End llvm namespace
#endif
diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h
index ab6c5e3d61240..97058f5e9981b 100644
--- a/include/llvm/MC/MCELFStreamer.h
+++ b/include/llvm/MC/MCELFStreamer.h
@@ -29,32 +29,26 @@ class raw_ostream;
class MCELFStreamer : public MCObjectStreamer {
public:
- MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS,
MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, TAB, OS, Emitter),
- SeenIdent(false) {}
+ : MCObjectStreamer(Context, TAB, OS, Emitter), SeenIdent(false) {}
- MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
- MCCodeEmitter *Emitter, MCAssembler *Assembler)
- : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler),
- SeenIdent(false) {}
-
- virtual ~MCELFStreamer();
+ ~MCELFStreamer() override;
/// state management
void reset() override {
+ SeenIdent = false;
LocalCommons.clear();
BindingExplicitlySet.clear();
- SeenIdent = false;
+ BundleGroups.clear();
MCObjectStreamer::reset();
}
- /// @name MCStreamer Interface
+ /// \name MCStreamer Interface
/// @{
void InitSections(bool NoExecStack) override;
- void ChangeSection(const MCSection *Section,
- const MCExpr *Subsection) override;
+ void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
void EmitLabel(MCSymbol *Symbol) override;
void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
void EmitThumbFunc(MCSymbol *Func) override;
@@ -73,10 +67,10 @@ public:
void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
- void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr,
+ void EmitZerofill(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 EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment = 0) override;
void EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc = SMLoc()) override;
@@ -95,15 +89,19 @@ public:
void EmitBundleUnlock() override;
private:
+ bool isBundleLocked() const;
void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override;
void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
void fixSymbolsInTLSFixups(const MCExpr *expr);
+ /// \brief Merge the content of the fragment \p EF into the fragment \p DF.
+ void mergeFragment(MCDataFragment *, MCEncodedFragmentWithFixups *);
+
bool SeenIdent;
struct LocalCommon {
- MCSymbolData *SD;
+ const MCSymbol *Symbol;
uint64_t Size;
unsigned ByteAlignment;
};
@@ -111,11 +109,16 @@ private:
std::vector<LocalCommon> LocalCommons;
SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
+
+ /// BundleGroups - The stack of fragments holding the bundle-locked
+ /// instructions.
+ llvm::SmallVector<MCDataFragment *, 4> BundleGroups;
};
MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *Emitter,
- bool RelaxAll, bool IsThumb);
+ raw_pwrite_stream &OS,
+ MCCodeEmitter *Emitter, bool RelaxAll,
+ bool IsThumb);
} // end namespace llvm
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index bd9b2bc4751ab..b38ad7daee3e6 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -21,15 +21,14 @@ class MCAssembler;
class MCContext;
class MCFixup;
class MCSection;
-class MCSectionData;
class MCStreamer;
class MCSymbol;
class MCValue;
class raw_ostream;
class StringRef;
-typedef DenseMap<const MCSectionData*, uint64_t> SectionAddrMap;
+typedef DenseMap<const MCSection *, uint64_t> SectionAddrMap;
-/// MCExpr - Base class for the full range of assembler expressions which are
+/// \brief Base class for the full range of assembler expressions which are
/// needed for parsing.
class MCExpr {
public:
@@ -44,8 +43,8 @@ public:
private:
ExprKind Kind;
- MCExpr(const MCExpr&) LLVM_DELETED_FUNCTION;
- void operator=(const MCExpr&) LLVM_DELETED_FUNCTION;
+ MCExpr(const MCExpr&) = delete;
+ void operator=(const MCExpr&) = delete;
bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
@@ -56,53 +55,52 @@ private:
const SectionAddrMap *Addrs, bool InSet) const;
protected:
- explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {}
+ explicit MCExpr(ExprKind Kind) : Kind(Kind) {}
bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
const MCFixup *Fixup,
- const SectionAddrMap *Addrs, bool InSet,
- bool ForceVarExpansion) const;
+ const SectionAddrMap *Addrs, bool InSet) const;
public:
- /// @name Accessors
+ /// \name Accessors
/// @{
ExprKind getKind() const { return Kind; }
/// @}
- /// @name Utility Methods
+ /// \name Utility Methods
/// @{
void print(raw_ostream &OS) const;
void dump() const;
/// @}
- /// @name Expression Evaluation
+ /// \name Expression Evaluation
/// @{
- /// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value.
+ /// \brief Try to evaluate the expression to an absolute value.
///
- /// @param Res - The absolute value, if evaluation succeeds.
- /// @param Layout - The assembler layout object to use for evaluating symbol
+ /// \param Res - The absolute value, if evaluation succeeds.
+ /// \param Layout - The assembler layout object to use for evaluating symbol
/// values. If not given, then only non-symbolic expressions will be
/// evaluated.
- /// @result - True on success.
+ /// \return - True on success.
bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout,
const SectionAddrMap &Addrs) const;
bool EvaluateAsAbsolute(int64_t &Res) const;
bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
- int64_t evaluateKnownAbsolute(const MCAsmLayout &Layout) const;
+ bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
- /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable
- /// value, i.e. an expression of the fixed form (a - b + constant).
+ /// \brief Try to evaluate the expression to a relocatable value, i.e. an
+ /// expression of the fixed form (a - b + constant).
///
- /// @param Res - The relocatable value, if evaluation succeeds.
- /// @param Layout - The assembler layout object to use for evaluating values.
- /// @param Fixup - The Fixup object if available.
- /// @result - True on success.
+ /// \param Res - The relocatable value, if evaluation succeeds.
+ /// \param Layout - The assembler layout object to use for evaluating values.
+ /// \param Fixup - The Fixup object if available.
+ /// \return - True on success.
bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout,
const MCFixup *Fixup) const;
@@ -110,16 +108,14 @@ public:
/// 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 MCFixup *Fixup) const;
+ /// use is for when relocations are not available, like the .size directive.
+ 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
+ /// \brief Find the "associated section" for this expression, which is
+ /// currently defined as the absolute section for constants, or
/// otherwise the section associated with the first defined symbol in the
/// expression.
- const MCSection *FindAssociatedSection() const;
+ MCSection *FindAssociatedSection() const;
/// @}
};
@@ -129,21 +125,21 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
return OS;
}
-//// MCConstantExpr - Represent a constant integer expression.
+//// \brief Represent a constant integer expression.
class MCConstantExpr : public MCExpr {
int64_t Value;
- explicit MCConstantExpr(int64_t _Value)
- : MCExpr(MCExpr::Constant), Value(_Value) {}
+ explicit MCConstantExpr(int64_t Value)
+ : MCExpr(MCExpr::Constant), Value(Value) {}
public:
- /// @name Construction
+ /// \name Construction
/// @{
static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx);
/// @}
- /// @name Accessors
+ /// \name Accessors
/// @{
int64_t getValue() const { return Value; }
@@ -155,15 +151,14 @@ public:
}
};
-/// MCSymbolRefExpr - Represent a reference to a symbol from inside an
-/// expression.
+/// \brief Represent a reference to a symbol from inside an expression.
///
/// A symbol reference in an expression may be a use of a label, a use of an
/// assembler variable (defined constant), or constitute an implicit definition
/// of the symbol as external.
class MCSymbolRefExpr : public MCExpr {
public:
- enum VariantKind {
+ enum VariantKind : uint16_t {
VK_None,
VK_Invalid,
@@ -188,6 +183,7 @@ public:
VK_GOTPAGE,
VK_GOTPAGEOFF,
VK_SECREL,
+ VK_SIZE, // symbol@SIZE
VK_WEAKREF, // The link between the symbols in .weakref foo, bar
VK_ARM_NONE,
@@ -280,12 +276,25 @@ public:
VK_Mips_PCREL_HI16,
VK_Mips_PCREL_LO16,
- VK_COFF_IMGREL32 // symbol@imgrel (image-relative)
+ VK_COFF_IMGREL32, // symbol@imgrel (image-relative)
+
+ VK_Hexagon_PCREL,
+ VK_Hexagon_LO16,
+ VK_Hexagon_HI16,
+ VK_Hexagon_GPREL,
+ VK_Hexagon_GD_GOT,
+ VK_Hexagon_LD_GOT,
+ VK_Hexagon_GD_PLT,
+ VK_Hexagon_LD_PLT,
+ VK_Hexagon_IE,
+ VK_Hexagon_IE_GOT,
+ VK_TPREL,
+ VK_DTPREL
};
private:
/// The symbol reference modifier.
- const unsigned Kind : 16;
+ const VariantKind Kind;
/// Specifies how the variant kind should be printed.
const unsigned UseParensForSymbolVariant : 1;
@@ -300,7 +309,7 @@ private:
const MCAsmInfo *MAI);
public:
- /// @name Construction
+ /// \name Construction
/// @{
static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) {
@@ -313,19 +322,19 @@ public:
MCContext &Ctx);
/// @}
- /// @name Accessors
+ /// \name Accessors
/// @{
const MCSymbol &getSymbol() const { return *Symbol; }
- VariantKind getKind() const { return static_cast<VariantKind>(Kind); }
+ VariantKind getKind() const { return Kind; }
void printVariantKind(raw_ostream &OS) const;
bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
/// @}
- /// @name Static Utility Functions
+ /// \name Static Utility Functions
/// @{
static StringRef getVariantKindName(VariantKind Kind);
@@ -339,7 +348,7 @@ public:
}
};
-/// MCUnaryExpr - Unary assembler expressions.
+/// \brief Unary assembler expressions.
class MCUnaryExpr : public MCExpr {
public:
enum Opcode {
@@ -353,11 +362,11 @@ private:
Opcode Op;
const MCExpr *Expr;
- MCUnaryExpr(Opcode _Op, const MCExpr *_Expr)
- : MCExpr(MCExpr::Unary), Op(_Op), Expr(_Expr) {}
+ MCUnaryExpr(Opcode Op, const MCExpr *Expr)
+ : MCExpr(MCExpr::Unary), Op(Op), Expr(Expr) {}
public:
- /// @name Construction
+ /// \name Construction
/// @{
static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr,
@@ -376,13 +385,13 @@ public:
}
/// @}
- /// @name Accessors
+ /// \name Accessors
/// @{
- /// getOpcode - Get the kind of this unary expression.
+ /// \brief Get the kind of this unary expression.
Opcode getOpcode() const { return Op; }
- /// getSubExpr - Get the child of this unary expression.
+ /// \brief Get the child of this unary expression.
const MCExpr *getSubExpr() const { return Expr; }
/// @}
@@ -392,7 +401,7 @@ public:
}
};
-/// MCBinaryExpr - Binary assembler expressions.
+/// \brief Binary assembler expressions.
class MCBinaryExpr : public MCExpr {
public:
enum Opcode {
@@ -415,7 +424,8 @@ public:
NE, ///< Inequality comparison.
Or, ///< Bitwise or.
Shl, ///< Shift left.
- Shr, ///< Shift right (arithmetic or logical, depending on target)
+ AShr, ///< Arithmetic shift right.
+ LShr, ///< Logical shift right.
Sub, ///< Subtraction.
Xor ///< Bitwise exclusive or.
};
@@ -424,11 +434,11 @@ private:
Opcode Op;
const MCExpr *LHS, *RHS;
- MCBinaryExpr(Opcode _Op, const MCExpr *_LHS, const MCExpr *_RHS)
- : MCExpr(MCExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {}
+ MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS)
+ : MCExpr(MCExpr::Binary), Op(Op), LHS(LHS), RHS(RHS) {}
public:
- /// @name Construction
+ /// \name Construction
/// @{
static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS,
@@ -493,9 +503,13 @@ public:
MCContext &Ctx) {
return Create(Shl, LHS, RHS, Ctx);
}
- static const MCBinaryExpr *CreateShr(const MCExpr *LHS, const MCExpr *RHS,
+ static const MCBinaryExpr *CreateAShr(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
- return Create(Shr, LHS, RHS, Ctx);
+ return Create(AShr, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateLShr(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(LShr, LHS, RHS, Ctx);
}
static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS,
MCContext &Ctx) {
@@ -507,16 +521,16 @@ public:
}
/// @}
- /// @name Accessors
+ /// \name Accessors
/// @{
- /// getOpcode - Get the kind of this binary expression.
+ /// \brief Get the kind of this binary expression.
Opcode getOpcode() const { return Op; }
- /// getLHS - Get the left-hand side expression of the binary operator.
+ /// \brief Get the left-hand side expression of the binary operator.
const MCExpr *getLHS() const { return LHS; }
- /// getRHS - Get the right-hand side expression of the binary operator.
+ /// \brief Get the right-hand side expression of the binary operator.
const MCExpr *getRHS() const { return RHS; }
/// @}
@@ -526,8 +540,8 @@ public:
}
};
-/// MCTargetExpr - This is an extension point for target-specific MCExpr
-/// subclasses to implement.
+/// \brief This is an extension point for target-specific MCExpr subclasses to
+/// implement.
///
/// NOTE: All subclasses are required to have trivial destructors because
/// MCExprs are bump pointer allocated and not destructed.
@@ -543,7 +557,7 @@ public:
const MCAsmLayout *Layout,
const MCFixup *Fixup) const = 0;
virtual void visitUsedExpr(MCStreamer& Streamer) const = 0;
- virtual const MCSection *FindAssociatedSection() const = 0;
+ virtual MCSection *FindAssociatedSection() const = 0;
virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h
index 98a1419a1934a..8ab477c401a1c 100644
--- a/include/llvm/MC/MCFixup.h
+++ b/include/llvm/MC/MCFixup.h
@@ -19,7 +19,7 @@
namespace llvm {
class MCExpr;
-/// MCFixupKind - Extensible enumeration to represent the type of a fixup.
+/// \brief Extensible enumeration to represent the type of a fixup.
enum MCFixupKind {
FK_Data_1 = 0, ///< A one-byte fixup.
FK_Data_2, ///< A two-byte fixup.
@@ -45,7 +45,7 @@ enum MCFixupKind {
MaxTargetFixupKind = (1 << 8)
};
-/// MCFixup - Encode information on a single operation to perform on a byte
+/// \brief Encode information on a single operation to perform on a byte
/// sequence (e.g., an encoded instruction) which requires assemble- or run-
/// time patching.
///
@@ -75,7 +75,7 @@ class MCFixup {
/// The source location which gave rise to the fixup, if any.
SMLoc Loc;
public:
- static MCFixup Create(uint32_t Offset, const MCExpr *Value,
+ static MCFixup create(uint32_t Offset, const MCExpr *Value,
MCFixupKind Kind, SMLoc Loc = SMLoc()) {
assert(unsigned(Kind) < MaxTargetFixupKind && "Kind out of range!");
MCFixup FI;
@@ -93,8 +93,8 @@ public:
const MCExpr *getValue() const { return Value; }
- /// getKindForSize - Return the generic fixup kind for a value with the given
- /// size. It is an error to pass an unsupported size.
+ /// \brief Return the generic fixup kind for a value with the given size. It
+ /// is an error to pass an unsupported size.
static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) {
switch (Size) {
default: llvm_unreachable("Invalid generic fixup size!");
diff --git a/include/llvm/MC/MCFixupKindInfo.h b/include/llvm/MC/MCFixupKindInfo.h
index 6979ad5807d03..58183bd778e63 100644
--- a/include/llvm/MC/MCFixupKindInfo.h
+++ b/include/llvm/MC/MCFixupKindInfo.h
@@ -12,7 +12,7 @@
namespace llvm {
-/// MCFixupKindInfo - Target independent information on a fixup kind.
+/// \brief Target independent information on a fixup kind.
struct MCFixupKindInfo {
enum FixupKindFlags {
/// Is this fixup kind PCrelative? This is used by the assembler backend to
diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h
index 25cd5ccb08fd6..2fc5091484039 100644
--- a/include/llvm/MC/MCInst.h
+++ b/include/llvm/MC/MCInst.h
@@ -28,7 +28,7 @@ class MCInstPrinter;
class MCExpr;
class MCInst;
-/// MCOperand - Instances of this class represent operands of the MCInst class.
+/// \brief Instances of this class represent operands of the MCInst class.
/// This is a simple discriminated union.
class MCOperand {
enum MachineOperandType : unsigned char {
@@ -59,13 +59,13 @@ public:
bool isExpr() const { return Kind == kExpr; }
bool isInst() const { return Kind == kInst; }
- /// getReg - Returns the register number.
+ /// \brief Returns the register number.
unsigned getReg() const {
assert(isReg() && "This is not a register operand!");
return RegVal;
}
- /// setReg - Set the register number.
+ /// \brief Set the register number.
void setReg(unsigned Reg) {
assert(isReg() && "This is not a register operand!");
RegVal = Reg;
@@ -108,44 +108,44 @@ public:
InstVal = Val;
}
- static MCOperand CreateReg(unsigned Reg) {
+ static MCOperand createReg(unsigned Reg) {
MCOperand Op;
Op.Kind = kRegister;
Op.RegVal = Reg;
return Op;
}
- static MCOperand CreateImm(int64_t Val) {
+ static MCOperand createImm(int64_t Val) {
MCOperand Op;
Op.Kind = kImmediate;
Op.ImmVal = Val;
return Op;
}
- static MCOperand CreateFPImm(double Val) {
+ static MCOperand createFPImm(double Val) {
MCOperand Op;
Op.Kind = kFPImmediate;
Op.FPImmVal = Val;
return Op;
}
- static MCOperand CreateExpr(const MCExpr *Val) {
+ static MCOperand createExpr(const MCExpr *Val) {
MCOperand Op;
Op.Kind = kExpr;
Op.ExprVal = Val;
return Op;
}
- static MCOperand CreateInst(const MCInst *Val) {
+ static MCOperand createInst(const MCInst *Val) {
MCOperand Op;
Op.Kind = kInst;
Op.InstVal = Val;
return Op;
}
- void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
+ void print(raw_ostream &OS) const;
void dump() const;
};
template <> struct isPodLike<MCOperand> { static const bool value = true; };
-/// MCInst - Instances of this class represent a single low-level machine
+/// \brief Instances of this class represent a single low-level machine
/// instruction.
class MCInst {
unsigned Opcode;
@@ -169,7 +169,7 @@ public:
}
void clear() { Operands.clear(); }
- size_t size() { return Operands.size(); }
+ size_t size() const { return Operands.size(); }
typedef SmallVectorImpl<MCOperand>::iterator iterator;
typedef SmallVectorImpl<MCOperand>::const_iterator const_iterator;
@@ -181,24 +181,23 @@ public:
return Operands.insert(I, Op);
}
- void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
+ void print(raw_ostream &OS) const;
void dump() const;
/// \brief Dump the MCInst as prettily as possible using the additional MC
/// structures, if given. Operators are separated by the \p Separator
/// string.
- void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI = nullptr,
- const MCInstPrinter *Printer = nullptr,
+ void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr,
StringRef Separator = " ") const;
};
inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
- MO.print(OS, nullptr);
+ MO.print(OS);
return OS;
}
inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
- MI.print(OS, nullptr);
+ MI.print(OS);
return OS;
}
diff --git a/include/llvm/MC/MCInstBuilder.h b/include/llvm/MC/MCInstBuilder.h
index c5acb26eecac3..30609bdb8b27a 100644
--- a/include/llvm/MC/MCInstBuilder.h
+++ b/include/llvm/MC/MCInstBuilder.h
@@ -30,31 +30,37 @@ public:
/// \brief Add a new register operand.
MCInstBuilder &addReg(unsigned Reg) {
- Inst.addOperand(MCOperand::CreateReg(Reg));
+ Inst.addOperand(MCOperand::createReg(Reg));
return *this;
}
/// \brief Add a new integer immediate operand.
MCInstBuilder &addImm(int64_t Val) {
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createImm(Val));
return *this;
}
/// \brief Add a new floating point immediate operand.
MCInstBuilder &addFPImm(double Val) {
- Inst.addOperand(MCOperand::CreateFPImm(Val));
+ Inst.addOperand(MCOperand::createFPImm(Val));
return *this;
}
/// \brief Add a new MCExpr operand.
MCInstBuilder &addExpr(const MCExpr *Val) {
- Inst.addOperand(MCOperand::CreateExpr(Val));
+ Inst.addOperand(MCOperand::createExpr(Val));
return *this;
}
/// \brief Add a new MCInst operand.
MCInstBuilder &addInst(const MCInst *Val) {
- Inst.addOperand(MCOperand::CreateInst(Val));
+ Inst.addOperand(MCOperand::createInst(Val));
+ return *this;
+ }
+
+ /// \brief Add an operand.
+ MCInstBuilder &addOperand(const MCOperand &Op) {
+ Inst.addOperand(Op);
return *this;
}
diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h
index 95124c3021dd2..7e8563a195d0f 100644
--- a/include/llvm/MC/MCInstPrinter.h
+++ b/include/llvm/MC/MCInstPrinter.h
@@ -19,6 +19,7 @@ class raw_ostream;
class MCAsmInfo;
class MCInstrInfo;
class MCRegisterInfo;
+class MCSubtargetInfo;
class StringRef;
namespace HexStyle {
@@ -28,21 +29,18 @@ namespace HexStyle {
};
}
-/// MCInstPrinter - This is an instance of a target assembly language printer
-/// that converts an MCInst to valid target assembly syntax.
+/// \brief This is an instance of a target assembly language printer that
+/// converts an MCInst to valid target assembly syntax.
class MCInstPrinter {
protected:
- /// CommentStream - a stream that comments can be emitted to if desired.
- /// Each comment must end with a newline. This will be null if verbose
- /// assembly emission is disable.
+ /// \brief A stream that comments can be emitted to if desired. Each comment
+ /// must end with a newline. This will be null if verbose assembly emission
+ /// is disable.
raw_ostream *CommentStream;
const MCAsmInfo &MAI;
const MCInstrInfo &MII;
const MCRegisterInfo &MRI;
- /// The current set of available features.
- uint64_t AvailableFeatures;
-
/// True if we are printing marked up assembly.
bool UseMarkup;
@@ -58,29 +56,25 @@ public:
MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii,
const MCRegisterInfo &mri)
: CommentStream(nullptr), MAI(mai), MII(mii), MRI(mri),
- AvailableFeatures(0), UseMarkup(0), PrintImmHex(0),
+ UseMarkup(0), PrintImmHex(0),
PrintHexStyle(HexStyle::C) {}
virtual ~MCInstPrinter();
- /// setCommentStream - Specify a stream to emit comments to.
+ /// \brief Specify a stream to emit comments to.
void setCommentStream(raw_ostream &OS) { CommentStream = &OS; }
- /// printInst - Print the specified MCInst to the specified raw_ostream.
- ///
+ /// \brief Print the specified MCInst to the specified raw_ostream.
virtual void printInst(const MCInst *MI, raw_ostream &OS,
- StringRef Annot) = 0;
+ StringRef Annot, const MCSubtargetInfo &STI) = 0;
- /// getOpcodeName - Return the name of the specified opcode enum (e.g.
- /// "MOV32ri") or empty if we can't resolve it.
+ /// \brief Return the name of the specified opcode enum (e.g. "MOV32ri") or
+ /// empty if we can't resolve it.
StringRef getOpcodeName(unsigned Opcode) const;
- /// printRegName - Print the assembler register name.
+ /// \brief Print the assembler register name.
virtual void printRegName(raw_ostream &OS, unsigned RegNo) const;
- uint64_t getAvailableFeatures() const { return AvailableFeatures; }
- void setAvailableFeatures(uint64_t Value) { AvailableFeatures = Value; }
-
bool getUseMarkup() const { return UseMarkup; }
void setUseMarkup(bool Value) { UseMarkup = Value; }
@@ -95,12 +89,14 @@ public:
void setPrintImmHex(HexStyle::Style Value) { PrintHexStyle = Value; }
/// Utility function to print immediates in decimal or hex.
- format_object1<int64_t> formatImm(const int64_t Value) const { return PrintImmHex ? formatHex(Value) : formatDec(Value); }
+ format_object<int64_t> formatImm(int64_t Value) const {
+ return PrintImmHex ? formatHex(Value) : formatDec(Value);
+ }
/// Utility functions to print decimal/hexadecimal values.
- format_object1<int64_t> formatDec(const int64_t Value) const;
- format_object1<int64_t> formatHex(const int64_t Value) const;
- format_object1<uint64_t> formatHex(const uint64_t Value) const;
+ format_object<int64_t> formatDec(int64_t Value) const;
+ format_object<int64_t> formatHex(int64_t Value) const;
+ format_object<uint64_t> formatHex(uint64_t Value) const;
};
} // namespace llvm
diff --git a/include/llvm/MC/MCInstrAnalysis.h b/include/llvm/MC/MCInstrAnalysis.h
index e921f768ac45f..8f5159e9e1c85 100644
--- a/include/llvm/MC/MCInstrAnalysis.h
+++ b/include/llvm/MC/MCInstrAnalysis.h
@@ -59,8 +59,8 @@ public:
return Info->get(Inst.getOpcode()).isTerminator();
}
- /// evaluateBranch - Given a branch instruction try to get the address the
- /// branch targets. Return true on success, and the address in Target.
+ /// \brief Given a branch instruction try to get the address the branch
+ /// targets. Return true on success, and the address in Target.
virtual bool
evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
uint64_t &Target) const;
diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h
index 360989305d3af..de3a1959e05c9 100644
--- a/include/llvm/MC/MCInstrDesc.h
+++ b/include/llvm/MC/MCInstrDesc.h
@@ -15,142 +15,142 @@
#ifndef LLVM_MC_MCINSTRDESC_H
#define LLVM_MC_MCINSTRDESC_H
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/DataTypes.h"
+#include <string>
namespace llvm {
+ class MCInst;
+ class MCRegisterInfo;
+ class MCSubtargetInfo;
+ class FeatureBitset;
//===----------------------------------------------------------------------===//
// Machine Operand Flags and Description
//===----------------------------------------------------------------------===//
namespace MCOI {
- // Operand constraints
- enum OperandConstraint {
- TIED_TO = 0, // Must be allocated the same register as.
- EARLY_CLOBBER // Operand is an early clobber register operand
- };
-
- /// OperandFlags - These are flags set on operands, but should be considered
- /// private, all access should go through the MCOperandInfo accessors.
- /// See the accessors for a description of what these are.
- enum OperandFlags {
- LookupPtrRegClass = 0,
- Predicate,
- OptionalDef
- };
-
- /// Operand Type - Operands are tagged with one of the values of this enum.
- enum OperandType {
- OPERAND_UNKNOWN = 0,
- OPERAND_IMMEDIATE = 1,
- OPERAND_REGISTER = 2,
- OPERAND_MEMORY = 3,
- OPERAND_PCREL = 4,
- OPERAND_FIRST_TARGET = 5
- };
+// Operand constraints
+enum OperandConstraint {
+ TIED_TO = 0, // Must be allocated the same register as.
+ EARLY_CLOBBER // Operand is an early clobber register operand
+};
+
+/// \brief These are flags set on operands, but should be considered
+/// private, all access should go through the MCOperandInfo accessors.
+/// See the accessors for a description of what these are.
+enum OperandFlags { LookupPtrRegClass = 0, Predicate, OptionalDef };
+
+/// \brief Operands are tagged with one of the values of this enum.
+enum OperandType {
+ OPERAND_UNKNOWN = 0,
+ OPERAND_IMMEDIATE = 1,
+ OPERAND_REGISTER = 2,
+ OPERAND_MEMORY = 3,
+ OPERAND_PCREL = 4,
+ OPERAND_FIRST_TARGET = 5
+};
}
-/// MCOperandInfo - This holds information about one operand of a machine
-/// instruction, indicating the register class for register operands, etc.
-///
+/// \brief This holds information about one operand of a machine instruction,
+/// indicating the register class for register operands, etc.
class MCOperandInfo {
public:
- /// RegClass - This specifies the register class enumeration of the operand
+ /// \brief This specifies the register class enumeration of the operand
/// if the operand is a register. If isLookupPtrRegClass is set, then this is
/// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to
/// get a dynamic register class.
int16_t RegClass;
- /// Flags - These are flags from the MCOI::OperandFlags enum.
+ /// \brief These are flags from the MCOI::OperandFlags enum.
uint8_t Flags;
- /// OperandType - Information about the type of the operand.
+ /// \brief Information about the type of the operand.
uint8_t OperandType;
-
- /// Lower 16 bits are used to specify which constraints are set. The higher 16
- /// bits are used to specify the value of constraints (4 bits each).
+ /// \brief The lower 16 bits are used to specify which constraints are set.
+ /// The higher 16 bits are used to specify the value of constraints (4 bits
+ /// each).
uint32_t Constraints;
- /// Currently no other information.
- /// isLookupPtrRegClass - Set if this operand is a pointer value and it
- /// requires a callback to look up its register class.
- bool isLookupPtrRegClass() const {return Flags&(1 <<MCOI::LookupPtrRegClass);}
+ /// \brief Set if this operand is a pointer value and it requires a callback
+ /// to look up its register class.
+ bool isLookupPtrRegClass() const {
+ return Flags & (1 << MCOI::LookupPtrRegClass);
+ }
- /// isPredicate - Set if this is one of the operands that made up of
- /// the predicate operand that controls an isPredicable() instruction.
+ /// \brief Set if this is one of the operands that made up of the predicate
+ /// operand that controls an isPredicable() instruction.
bool isPredicate() const { return Flags & (1 << MCOI::Predicate); }
- /// isOptionalDef - Set if this operand is a optional def.
- ///
+ /// \brief Set if this operand is a optional def.
bool isOptionalDef() const { return Flags & (1 << MCOI::OptionalDef); }
};
-
//===----------------------------------------------------------------------===//
// Machine Instruction Flags and Description
//===----------------------------------------------------------------------===//
-/// MCInstrDesc flags - These should be considered private to the
-/// implementation of the MCInstrDesc class. Clients should use the predicate
-/// methods on MCInstrDesc, not use these directly. These all correspond to
-/// bitfields in the MCInstrDesc::Flags field.
namespace MCID {
- enum {
- Variadic = 0,
- HasOptionalDef,
- Pseudo,
- Return,
- Call,
- Barrier,
- Terminator,
- Branch,
- IndirectBranch,
- Compare,
- MoveImm,
- Bitcast,
- Select,
- DelaySlot,
- FoldableAsLoad,
- MayLoad,
- MayStore,
- Predicable,
- NotDuplicable,
- UnmodeledSideEffects,
- Commutable,
- ConvertibleTo3Addr,
- UsesCustomInserter,
- HasPostISelHook,
- Rematerializable,
- CheapAsAMove,
- ExtraSrcRegAllocReq,
- ExtraDefRegAllocReq,
- RegSequence,
- ExtractSubreg,
- InsertSubreg
- };
+/// \brief These should be considered private to the implementation of the
+/// MCInstrDesc class. Clients should use the predicate methods on MCInstrDesc,
+/// not use these directly. These all correspond to bitfields in the
+/// MCInstrDesc::Flags field.
+enum Flag {
+ Variadic = 0,
+ HasOptionalDef,
+ Pseudo,
+ Return,
+ Call,
+ Barrier,
+ Terminator,
+ Branch,
+ IndirectBranch,
+ Compare,
+ MoveImm,
+ Bitcast,
+ Select,
+ DelaySlot,
+ FoldableAsLoad,
+ MayLoad,
+ MayStore,
+ Predicable,
+ NotDuplicable,
+ UnmodeledSideEffects,
+ Commutable,
+ ConvertibleTo3Addr,
+ UsesCustomInserter,
+ HasPostISelHook,
+ Rematerializable,
+ CheapAsAMove,
+ ExtraSrcRegAllocReq,
+ ExtraDefRegAllocReq,
+ RegSequence,
+ ExtractSubreg,
+ InsertSubreg
+};
}
-/// MCInstrDesc - Describe properties that are true of each instruction in the
-/// target description file. This captures information about side effects,
-/// register use and many other things. There is one instance of this struct
-/// for each target instruction class, and the MachineInstr class points to
-/// this struct directly to describe itself.
+/// \brief Describe properties that are true of each instruction in the target
+/// description file. This captures information about side effects, register
+/// use and many other things. There is one instance of this struct for each
+/// target instruction class, and the MachineInstr class points to this struct
+/// directly to describe itself.
class MCInstrDesc {
public:
- unsigned short Opcode; // The opcode number
- unsigned short NumOperands; // Num of args (may be more if variable_ops)
- unsigned short NumDefs; // Num of args that are definitions
- unsigned short SchedClass; // enum identifying instr sched class
- unsigned short Size; // Number of bytes in encoding.
- unsigned Flags; // Flags identifying machine instr class
- uint64_t TSFlags; // Target Specific Flag values
- const uint16_t *ImplicitUses; // Registers implicitly read by this instr
- const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr
- const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands
- uint64_t DeprecatedFeatureMask;// Feature bits that this is deprecated on, if any
+ unsigned short Opcode; // The opcode number
+ unsigned short NumOperands; // Num of args (may be more if variable_ops)
+ unsigned short NumDefs; // Num of args that are definitions
+ unsigned short SchedClass; // enum identifying instr sched class
+ unsigned short Size; // Number of bytes in encoding.
+ unsigned Flags; // Flags identifying machine instr class
+ uint64_t TSFlags; // Target Specific Flag values
+ const uint16_t *ImplicitUses; // Registers implicitly read by this instr
+ const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr
+ const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands
+ // Subtarget feature that this is deprecated on, if any
+ // -1 implies this is not deprecated by any single feature. It may still be
+ // deprecated due to a "complex" reason, below.
+ int64_t DeprecatedFeature;
+
// A complex method to determine is a certain is deprecated or not, and return
// the reason for deprecation.
bool (*ComplexDeprecationInfo)(MCInst &, MCSubtargetInfo &, std::string &);
@@ -170,38 +170,23 @@ public:
/// \brief Returns true if a certain instruction is deprecated and if so
/// returns the reason in \p Info.
bool getDeprecatedInfo(MCInst &MI, MCSubtargetInfo &STI,
- std::string &Info) const {
- if (ComplexDeprecationInfo)
- return ComplexDeprecationInfo(MI, STI, Info);
- if ((DeprecatedFeatureMask & STI.getFeatureBits()) != 0) {
- // FIXME: it would be nice to include the subtarget feature here.
- Info = "deprecated";
- return true;
- }
- return false;
- }
+ std::string &Info) const;
/// \brief Return the opcode number for this descriptor.
- unsigned getOpcode() const {
- return Opcode;
- }
+ unsigned getOpcode() const { return Opcode; }
/// \brief Return the number of declared MachineOperands for this
/// MachineInstruction. Note that variadic (isVariadic() returns true)
/// instructions may have additional operands at the end of the list, and note
/// that the machine instruction may include implicit register def/uses as
/// well.
- unsigned getNumOperands() const {
- return NumOperands;
- }
+ unsigned getNumOperands() const { return NumOperands; }
/// \brief Return the number of MachineOperands that are register
/// definitions. Register definitions always occur at the start of the
/// machine operand list. This is the number of "outs" in the .td file,
/// and does not include implicit defs.
- unsigned getNumDefs() const {
- return NumDefs;
- }
+ unsigned getNumDefs() const { return NumDefs; }
/// \brief Return flags of this instruction.
unsigned getFlags() const { return Flags; }
@@ -210,39 +195,26 @@ public:
/// operands. In this case, the variable operands will be after the normal
/// operands but before the implicit definitions and uses (if any are
/// present).
- bool isVariadic() const {
- return Flags & (1 << MCID::Variadic);
- }
+ bool isVariadic() const { return Flags & (1 << MCID::Variadic); }
/// \brief Set if this instruction has an optional definition, e.g.
/// ARM instructions which can set condition code if 's' bit is set.
- bool hasOptionalDef() const {
- return Flags & (1 << MCID::HasOptionalDef);
- }
+ bool hasOptionalDef() const { return Flags & (1 << MCID::HasOptionalDef); }
/// \brief Return true if this is a pseudo instruction that doesn't
/// correspond to a real machine instruction.
- ///
- bool isPseudo() const {
- return Flags & (1 << MCID::Pseudo);
- }
+ bool isPseudo() const { return Flags & (1 << MCID::Pseudo); }
/// \brief Return true if the instruction is a return.
- bool isReturn() const {
- return Flags & (1 << MCID::Return);
- }
+ bool isReturn() const { return Flags & (1 << MCID::Return); }
/// \brief Return true if the instruction is a call.
- bool isCall() const {
- return Flags & (1 << MCID::Call);
- }
+ bool isCall() const { return Flags & (1 << MCID::Call); }
/// \brief Returns true if the specified instruction stops control flow
/// from executing the instruction immediately following it. Examples include
/// unconditional branches and return instructions.
- bool isBarrier() const {
- return Flags & (1 << MCID::Barrier);
- }
+ bool isBarrier() const { return Flags & (1 << MCID::Barrier); }
/// \brief Returns true if this instruction part of the terminator for
/// a basic block. Typically this is things like return and branch
@@ -250,23 +222,17 @@ public:
///
/// Various passes use this to insert code into the bottom of a basic block,
/// but before control flow occurs.
- bool isTerminator() const {
- return Flags & (1 << MCID::Terminator);
- }
+ bool isTerminator() const { return Flags & (1 << MCID::Terminator); }
/// \brief Returns true if this is a conditional, unconditional, or
/// indirect branch. Predicates below can be used to discriminate between
/// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to
/// get more information.
- bool isBranch() const {
- return Flags & (1 << MCID::Branch);
- }
+ bool isBranch() const { return Flags & (1 << MCID::Branch); }
/// \brief Return true if this is an indirect branch, such as a
/// branch through a register.
- bool isIndirectBranch() const {
- return Flags & (1 << MCID::IndirectBranch);
- }
+ bool isIndirectBranch() const { return Flags & (1 << MCID::IndirectBranch); }
/// \brief Return true if this is a branch which may fall
/// through to the next instruction or may transfer control flow to some other
@@ -287,79 +253,44 @@ public:
/// \brief Return true if this is a branch or an instruction which directly
/// writes to the program counter. Considered 'may' affect rather than
/// 'does' affect as things like predication are not taken into account.
- bool mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const {
- if (isBranch() || isCall() || isReturn() || isIndirectBranch())
- return true;
- unsigned PC = RI.getProgramCounter();
- if (PC == 0)
- return false;
- if (hasDefOfPhysReg(MI, PC, RI))
- return true;
- // A variadic instruction may define PC in the variable operand list.
- // There's currently no indication of which entries in a variable
- // list are defs and which are uses. While that's the case, this function
- // needs to assume they're defs in order to be conservatively correct.
- for (int i = NumOperands, e = MI.getNumOperands(); i != e; ++i) {
- if (MI.getOperand(i).isReg() &&
- RI.isSubRegisterEq(PC, MI.getOperand(i).getReg()))
- return true;
- }
- return false;
- }
+ bool mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const;
/// \brief Return true if this instruction has a predicate operand
/// that controls execution. It may be set to 'always', or may be set to other
/// values. There are various methods in TargetInstrInfo that can be used to
/// control and modify the predicate in this instruction.
- bool isPredicable() const {
- return Flags & (1 << MCID::Predicable);
- }
+ bool isPredicable() const { return Flags & (1 << MCID::Predicable); }
/// \brief Return true if this instruction is a comparison.
- bool isCompare() const {
- return Flags & (1 << MCID::Compare);
- }
+ bool isCompare() const { return Flags & (1 << MCID::Compare); }
/// \brief Return true if this instruction is a move immediate
/// (including conditional moves) instruction.
- bool isMoveImmediate() const {
- return Flags & (1 << MCID::MoveImm);
- }
+ bool isMoveImmediate() const { return Flags & (1 << MCID::MoveImm); }
/// \brief Return true if this instruction is a bitcast instruction.
- bool isBitcast() const {
- return Flags & (1 << MCID::Bitcast);
- }
+ bool isBitcast() const { return Flags & (1 << MCID::Bitcast); }
/// \brief Return true if this is a select instruction.
- bool isSelect() const {
- return Flags & (1 << MCID::Select);
- }
+ bool isSelect() const { return Flags & (1 << MCID::Select); }
/// \brief Return true if this instruction cannot be safely
/// duplicated. For example, if the instruction has a unique labels attached
/// to it, duplicating it would cause multiple definition errors.
- bool isNotDuplicable() const {
- return Flags & (1 << MCID::NotDuplicable);
- }
+ bool isNotDuplicable() const { return Flags & (1 << MCID::NotDuplicable); }
- /// hasDelaySlot - Returns true if the specified instruction has a delay slot
- /// which must be filled by the code generator.
- bool hasDelaySlot() const {
- return Flags & (1 << MCID::DelaySlot);
- }
+ /// \brief Returns true if the specified instruction has a delay slot which
+ /// must be filled by the code generator.
+ bool hasDelaySlot() const { return Flags & (1 << MCID::DelaySlot); }
- /// canFoldAsLoad - Return true for instructions that can be folded as
- /// memory operands in other instructions. The most common use for this
- /// is instructions that are simple loads from memory that don't modify
- /// the loaded value in any way, but it can also be used for instructions
- /// that can be expressed as constant-pool loads, such as V_SETALLONES
- /// on x86, to allow them to be folded when it is beneficial.
- /// This should only be set on instructions that return a value in their
- /// only virtual register definition.
- bool canFoldAsLoad() const {
- return Flags & (1 << MCID::FoldableAsLoad);
- }
+ /// \brief Return true for instructions that can be folded as memory operands
+ /// in other instructions. The most common use for this is instructions that
+ /// are simple loads from memory that don't modify the loaded value in any
+ /// way, but it can also be used for instructions that can be expressed as
+ /// constant-pool loads, such as V_SETALLONES on x86, to allow them to be
+ /// folded when it is beneficial. This should only be set on instructions
+ /// that return a value in their only virtual register definition.
+ bool canFoldAsLoad() const { return Flags & (1 << MCID::FoldableAsLoad); }
/// \brief Return true if this instruction behaves
/// the same way as the generic REG_SEQUENCE instructions.
@@ -398,9 +329,7 @@ public:
/// Note that for the optimizers to be able to take advantage of
/// this property, TargetInstrInfo::getInsertSubregLikeInputs has to be
/// override accordingly.
- bool isInsertSubregLike() const {
- return Flags & (1 << MCID::InsertSubreg);
- }
+ bool isInsertSubregLike() const { return Flags & (1 << MCID::InsertSubreg); }
//===--------------------------------------------------------------------===//
// Side Effect Analysis
@@ -409,20 +338,15 @@ public:
/// \brief Return true if this instruction could possibly read memory.
/// Instructions with this flag set are not necessarily simple load
/// instructions, they may load a value and modify it, for example.
- bool mayLoad() const {
- return Flags & (1 << MCID::MayLoad);
- }
-
+ bool mayLoad() const { return Flags & (1 << MCID::MayLoad); }
/// \brief Return true if this instruction could possibly modify memory.
/// Instructions with this flag set are not necessarily simple store
/// instructions, they may store a modified value based on their operands, or
/// may not actually modify anything, for example.
- bool mayStore() const {
- return Flags & (1 << MCID::MayStore);
- }
+ bool mayStore() const { return Flags & (1 << MCID::MayStore); }
- /// hasUnmodeledSideEffects - Return true if this instruction has side
+ /// \brief Return true if this instruction has side
/// effects that are not modeled by other flags. This does not return true
/// for instructions whose effects are captured by:
///
@@ -434,7 +358,6 @@ public:
/// Examples of side effects would be modifying 'invisible' machine state like
/// a control register, flushing a cache, modifying a register invisible to
/// LLVM, etc.
- ///
bool hasUnmodeledSideEffects() const {
return Flags & (1 << MCID::UnmodeledSideEffects);
}
@@ -443,9 +366,9 @@ public:
// Flags that indicate whether an instruction can be modified by a method.
//===--------------------------------------------------------------------===//
- /// isCommutable - Return true if this may be a 2- or 3-address
- /// instruction (of the form "X = op Y, Z, ..."), which produces the same
- /// result if Y and Z are exchanged. If this flag is set, then the
+ /// \brief Return true if this may be a 2- or 3-address instruction (of the
+ /// form "X = op Y, Z, ..."), which produces the same result if Y and Z are
+ /// exchanged. If this flag is set, then the
/// TargetInstrInfo::commuteInstruction method may be used to hack on the
/// instruction.
///
@@ -453,18 +376,16 @@ public:
/// sometimes. In these cases, the call to commuteInstruction will fail.
/// Also note that some instructions require non-trivial modification to
/// commute them.
- bool isCommutable() const {
- return Flags & (1 << MCID::Commutable);
- }
-
- /// isConvertibleTo3Addr - Return true if this is a 2-address instruction
- /// which can be changed into a 3-address instruction if needed. Doing this
- /// transformation can be profitable in the register allocator, because it
- /// means that the instruction can use a 2-address form if possible, but
- /// degrade into a less efficient form if the source and dest register cannot
- /// be assigned to the same register. For example, this allows the x86
- /// backend to turn a "shl reg, 3" instruction into an LEA instruction, which
- /// is the same speed as the shift but has bigger code size.
+ bool isCommutable() const { return Flags & (1 << MCID::Commutable); }
+
+ /// \brief Return true if this is a 2-address instruction which can be changed
+ /// into a 3-address instruction if needed. Doing this transformation can be
+ /// profitable in the register allocator, because it means that the
+ /// instruction can use a 2-address form if possible, but degrade into a less
+ /// efficient form if the source and dest register cannot be assigned to the
+ /// same register. For example, this allows the x86 backend to turn a "shl
+ /// reg, 3" instruction into an LEA instruction, which is the same speed as
+ /// the shift but has bigger code size.
///
/// If this returns true, then the target must implement the
/// TargetInstrInfo::convertToThreeAddress method for this instruction, which
@@ -475,11 +396,11 @@ public:
return Flags & (1 << MCID::ConvertibleTo3Addr);
}
- /// usesCustomInsertionHook - Return true if this instruction requires
- /// custom insertion support when the DAG scheduler is inserting it into a
- /// machine basic block. If this is true for the instruction, it basically
- /// means that it is a pseudo instruction used at SelectionDAG time that is
- /// expanded out into magic code by the target when MachineInstrs are formed.
+ /// \brief Return true if this instruction requires custom insertion support
+ /// when the DAG scheduler is inserting it into a machine basic block. If
+ /// this is true for the instruction, it basically means that it is a pseudo
+ /// instruction used at SelectionDAG time that is expanded out into magic code
+ /// by the target when MachineInstrs are formed.
///
/// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method
/// is used to insert this into the MachineBasicBlock.
@@ -487,17 +408,14 @@ public:
return Flags & (1 << MCID::UsesCustomInserter);
}
- /// hasPostISelHook - Return true if this instruction requires *adjustment*
- /// after instruction selection by calling a target hook. For example, this
- /// can be used to fill in ARM 's' optional operand depending on whether
- /// the conditional flag register is used.
- bool hasPostISelHook() const {
- return Flags & (1 << MCID::HasPostISelHook);
- }
+ /// \brief Return true if this instruction requires *adjustment* after
+ /// instruction selection by calling a target hook. For example, this can be
+ /// used to fill in ARM 's' optional operand depending on whether the
+ /// conditional flag register is used.
+ bool hasPostISelHook() const { return Flags & (1 << MCID::HasPostISelHook); }
- /// isRematerializable - Returns true if this instruction is a candidate for
- /// remat. This flag is only used in TargetInstrInfo method
- /// isTriviallyRematerializable.
+ /// \brief Returns true if this instruction is a candidate for remat. This
+ /// flag is only used in TargetInstrInfo method isTriviallyRematerializable.
///
/// If this flag is set, the isReallyTriviallyReMaterializable()
/// or isReallyTriviallyReMaterializableGeneric methods are called to verify
@@ -506,80 +424,76 @@ public:
return Flags & (1 << MCID::Rematerializable);
}
- /// isAsCheapAsAMove - Returns true if this instruction has the same cost (or
- /// less) than a move instruction. This is useful during certain types of
- /// optimizations (e.g., remat during two-address conversion or machine licm)
- /// where we would like to remat or hoist the instruction, but not if it costs
- /// more than moving the instruction into the appropriate register. Note, we
- /// are not marking copies from and to the same register class with this flag.
+ /// \brief Returns true if this instruction has the same cost (or less) than a
+ /// move instruction. This is useful during certain types of optimizations
+ /// (e.g., remat during two-address conversion or machine licm) where we would
+ /// like to remat or hoist the instruction, but not if it costs more than
+ /// moving the instruction into the appropriate register. Note, we are not
+ /// marking copies from and to the same register class with this flag.
///
/// This method could be called by interface TargetInstrInfo::isAsCheapAsAMove
/// for different subtargets.
- bool isAsCheapAsAMove() const {
- return Flags & (1 << MCID::CheapAsAMove);
- }
-
- /// hasExtraSrcRegAllocReq - Returns true if this instruction source operands
- /// have special register allocation requirements that are not captured by the
- /// operand register classes. e.g. ARM::STRD's two source registers must be an
- /// even / odd pair, ARM::STM registers have to be in ascending order.
- /// Post-register allocation passes should not attempt to change allocations
- /// for sources of instructions with this flag.
+ bool isAsCheapAsAMove() const { return Flags & (1 << MCID::CheapAsAMove); }
+
+ /// \brief Returns true if this instruction source operands have special
+ /// register allocation requirements that are not captured by the operand
+ /// register classes. e.g. ARM::STRD's two source registers must be an even /
+ /// odd pair, ARM::STM registers have to be in ascending order. Post-register
+ /// allocation passes should not attempt to change allocations for sources of
+ /// instructions with this flag.
bool hasExtraSrcRegAllocReq() const {
return Flags & (1 << MCID::ExtraSrcRegAllocReq);
}
- /// hasExtraDefRegAllocReq - Returns true if this instruction def operands
- /// have special register allocation requirements that are not captured by the
- /// operand register classes. e.g. ARM::LDRD's two def registers must be an
- /// even / odd pair, ARM::LDM registers have to be in ascending order.
- /// Post-register allocation passes should not attempt to change allocations
- /// for definitions of instructions with this flag.
+ /// \brief Returns true if this instruction def operands have special register
+ /// allocation requirements that are not captured by the operand register
+ /// classes. e.g. ARM::LDRD's two def registers must be an even / odd pair,
+ /// ARM::LDM registers have to be in ascending order. Post-register
+ /// allocation passes should not attempt to change allocations for definitions
+ /// of instructions with this flag.
bool hasExtraDefRegAllocReq() const {
return Flags & (1 << MCID::ExtraDefRegAllocReq);
}
-
- /// getImplicitUses - Return a list of registers that are potentially
- /// read by any instance of this machine instruction. For example, on X86,
- /// the "adc" instruction adds two register operands and adds the carry bit in
- /// from the flags register. In this case, the instruction is marked as
- /// implicitly reading the flags. Likewise, the variable shift instruction on
- /// X86 is marked as implicitly reading the 'CL' register, which it always
- /// does.
+ /// \brief Return a list of registers that are potentially read by any
+ /// instance of this machine instruction. For example, on X86, the "adc"
+ /// instruction adds two register operands and adds the carry bit in from the
+ /// flags register. In this case, the instruction is marked as implicitly
+ /// reading the flags. Likewise, the variable shift instruction on X86 is
+ /// marked as implicitly reading the 'CL' register, which it always does.
///
/// This method returns null if the instruction has no implicit uses.
- const uint16_t *getImplicitUses() const {
- return ImplicitUses;
- }
+ const uint16_t *getImplicitUses() const { return ImplicitUses; }
/// \brief Return the number of implicit uses this instruction has.
unsigned getNumImplicitUses() const {
- if (!ImplicitUses) return 0;
+ if (!ImplicitUses)
+ return 0;
unsigned i = 0;
- for (; ImplicitUses[i]; ++i) /*empty*/;
+ for (; ImplicitUses[i]; ++i) /*empty*/
+ ;
return i;
}
- /// getImplicitDefs - Return a list of registers that are potentially
- /// written by any instance of this machine instruction. For example, on X86,
- /// many instructions implicitly set the flags register. In this case, they
- /// are marked as setting the FLAGS. Likewise, many instructions always
- /// deposit their result in a physical register. For example, the X86 divide
+ /// \brief Return a list of registers that are potentially written by any
+ /// instance of this machine instruction. For example, on X86, many
+ /// instructions implicitly set the flags register. In this case, they are
+ /// marked as setting the FLAGS. Likewise, many instructions always deposit
+ /// their result in a physical register. For example, the X86 divide
/// instruction always deposits the quotient and remainder in the EAX/EDX
/// registers. For that instruction, this will return a list containing the
/// EAX/EDX/EFLAGS registers.
///
/// This method returns null if the instruction has no implicit defs.
- const uint16_t *getImplicitDefs() const {
- return ImplicitDefs;
- }
+ const uint16_t *getImplicitDefs() const { return ImplicitDefs; }
/// \brief Return the number of implicit defs this instruct has.
unsigned getNumImplicitDefs() const {
- if (!ImplicitDefs) return 0;
+ if (!ImplicitDefs)
+ return 0;
unsigned i = 0;
- for (; ImplicitDefs[i]; ++i) /*empty*/;
+ for (; ImplicitDefs[i]; ++i) /*empty*/
+ ;
return i;
}
@@ -588,45 +502,25 @@ public:
bool hasImplicitUseOfPhysReg(unsigned Reg) const {
if (const uint16_t *ImpUses = ImplicitUses)
for (; *ImpUses; ++ImpUses)
- if (*ImpUses == Reg) return true;
+ if (*ImpUses == Reg)
+ return true;
return false;
}
/// \brief Return true if this instruction implicitly
/// defines the specified physical register.
bool hasImplicitDefOfPhysReg(unsigned Reg,
- const MCRegisterInfo *MRI = nullptr) const {
- if (const uint16_t *ImpDefs = ImplicitDefs)
- for (; *ImpDefs; ++ImpDefs)
- if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs)))
- return true;
- return false;
- }
-
- /// \brief Return true if this instruction defines the specified physical
- /// register, either explicitly or implicitly.
- bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg,
- const MCRegisterInfo &RI) const {
- for (int i = 0, e = NumDefs; i != e; ++i)
- if (MI.getOperand(i).isReg() &&
- RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg()))
- return true;
- return hasImplicitDefOfPhysReg(Reg, &RI);
- }
+ const MCRegisterInfo *MRI = nullptr) const;
/// \brief Return the scheduling class for this instruction. The
/// scheduling class is an index into the InstrItineraryData table. This
/// returns zero if there is no known scheduling information for the
/// instruction.
- unsigned getSchedClass() const {
- return SchedClass;
- }
+ unsigned getSchedClass() const { return SchedClass; }
/// \brief Return the number of bytes in the encoding of this instruction,
/// or zero if the encoding size cannot be known from the opcode.
- unsigned getSize() const {
- return Size;
- }
+ unsigned getSize() const { return Size; }
/// \brief Find the index of the first operand in the
/// operand list that is used to represent the predicate. It returns -1 if
@@ -639,6 +533,13 @@ public:
}
return -1;
}
+
+private:
+
+ /// \brief Return true if this instruction defines the specified physical
+ /// register, either explicitly or implicitly.
+ bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg,
+ const MCRegisterInfo &RI) const;
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCInstrInfo.h b/include/llvm/MC/MCInstrInfo.h
index 1d3a36ca7c73a..70c86587b08c5 100644
--- a/include/llvm/MC/MCInstrInfo.h
+++ b/include/llvm/MC/MCInstrInfo.h
@@ -20,9 +20,7 @@
namespace llvm {
//---------------------------------------------------------------------------
-///
-/// MCInstrInfo - Interface to description of machine instruction set
-///
+/// \brief Interface to description of machine instruction set.
class MCInstrInfo {
const MCInstrDesc *Desc; // Raw array to allow static init'n
const unsigned *InstrNameIndices; // Array for name indices in InstrNameData
@@ -30,8 +28,8 @@ class MCInstrInfo {
unsigned NumOpcodes; // Number of entries in the desc array
public:
- /// InitMCInstrInfo - Initialize MCInstrInfo, called by TableGen
- /// auto-generated routines. *DO NOT USE*.
+ /// \brief Initialize MCInstrInfo, called by TableGen auto-generated routines.
+ /// *DO NOT USE*.
void InitMCInstrInfo(const MCInstrDesc *D, const unsigned *NI, const char *ND,
unsigned NO) {
Desc = D;
@@ -42,15 +40,14 @@ public:
unsigned getNumOpcodes() const { return NumOpcodes; }
- /// get - Return the machine instruction descriptor that corresponds to the
+ /// \brief Return the machine instruction descriptor that corresponds to the
/// specified instruction opcode.
- ///
const MCInstrDesc &get(unsigned Opcode) const {
assert(Opcode < NumOpcodes && "Invalid opcode!");
return Desc[Opcode];
}
- /// getName - Returns the name for the instructions with the given opcode.
+ /// \brief Returns the name for the instructions with the given opcode.
const char *getName(unsigned Opcode) const {
assert(Opcode < NumOpcodes && "Invalid opcode!");
return &InstrNameData[InstrNameIndices[Opcode]];
diff --git a/include/llvm/MC/MCInstrItineraries.h b/include/llvm/MC/MCInstrItineraries.h
index 94d599f672af5..161705de7c4e1 100644
--- a/include/llvm/MC/MCInstrItineraries.h
+++ b/include/llvm/MC/MCInstrItineraries.h
@@ -67,12 +67,12 @@ struct InstrStage {
int NextCycles_; ///< Number of machine cycles to next stage
ReservationKinds Kind_; ///< Kind of the FU reservation
- /// Returns the number of cycles the stage is occupied.
+ /// \brief Returns the number of cycles the stage is occupied.
unsigned getCycles() const {
return Cycles_;
}
- /// Returns the choice of FUs.
+ /// \brief Returns the choice of FUs.
unsigned getUnits() const {
return Units_;
}
@@ -81,8 +81,8 @@ struct InstrStage {
return Kind_;
}
- /// Returns the number of cycles from the start of
- /// this stage to the start of the next stage in the itinerary
+ /// \brief Returns the number of cycles from the start of this stage to the
+ /// start of the next stage in the itinerary
unsigned getNextCycles() const {
return (NextCycles_ >= 0) ? (unsigned)NextCycles_ : Cycles_;
}
@@ -115,7 +115,6 @@ public:
const InstrItinerary *Itineraries; ///< Array of itineraries selected
/// Ctors.
- ///
InstrItineraryData() : SchedModel(MCSchedModel::GetDefaultSchedModel()),
Stages(nullptr), OperandCycles(nullptr),
Forwardings(nullptr), Itineraries(nullptr) {}
@@ -125,30 +124,30 @@ public:
: SchedModel(SM), Stages(S), OperandCycles(OS), Forwardings(F),
Itineraries(SchedModel.InstrItineraries) {}
- /// Returns true if there are no itineraries.
+ /// \brief Returns true if there are no itineraries.
bool isEmpty() const { return Itineraries == nullptr; }
- /// Returns true if the index is for the end marker itinerary.
+ /// \brief Returns true if the index is for the end marker itinerary.
bool isEndMarker(unsigned ItinClassIndx) const {
return ((Itineraries[ItinClassIndx].FirstStage == ~0U) &&
(Itineraries[ItinClassIndx].LastStage == ~0U));
}
- /// Return the first stage of the itinerary.
+ /// \brief Return the first stage of the itinerary.
const InstrStage *beginStage(unsigned ItinClassIndx) const {
unsigned StageIdx = Itineraries[ItinClassIndx].FirstStage;
return Stages + StageIdx;
}
- /// Return the last+1 stage of the itinerary.
+ /// \brief Return the last+1 stage of the itinerary.
const InstrStage *endStage(unsigned ItinClassIndx) const {
unsigned StageIdx = Itineraries[ItinClassIndx].LastStage;
return Stages + StageIdx;
}
- /// Return the total stage latency of the given class.
- /// The latency is the maximum completion time for any stage in the itinerary.
- /// If no stages exist, it defaults to one cycle.
+ /// \brief Return the total stage latency of the given class. The latency is
+ /// the maximum completion time for any stage in the itinerary. If no stages
+ /// exist, it defaults to one cycle.
unsigned getStageLatency(unsigned ItinClassIndx) const {
// If the target doesn't provide itinerary information, use a simple
// non-zero default value for all instructions.
@@ -165,8 +164,8 @@ public:
return Latency;
}
- /// Return the cycle for the given class and operand.
- /// Return -1 if no cycle is specified for the operand.
+ /// \brief Return the cycle for the given class and operand. Return -1 if no
+ /// cycle is specified for the operand.
int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const {
if (isEmpty())
return -1;
@@ -179,11 +178,11 @@ public:
return (int)OperandCycles[FirstIdx + OperandIdx];
}
- /// Return true if there is a pipeline forwarding
- /// between instructions of itinerary classes DefClass and UseClasses so that
- /// value produced by an instruction of itinerary class DefClass, operand
- /// index DefIdx can be bypassed when it's read by an instruction of
- /// itinerary class UseClass, operand index UseIdx.
+ /// \brief Return true if there is a pipeline forwarding between instructions
+ /// of itinerary classes DefClass and UseClasses so that value produced by an
+ /// instruction of itinerary class DefClass, operand index DefIdx can be
+ /// bypassed when it's read by an instruction of itinerary class UseClass,
+ /// operand index UseIdx.
bool hasPipelineForwarding(unsigned DefClass, unsigned DefIdx,
unsigned UseClass, unsigned UseIdx) const {
unsigned FirstDefIdx = Itineraries[DefClass].FirstOperandCycle;
@@ -202,9 +201,9 @@ public:
Forwardings[FirstUseIdx + UseIdx];
}
- /// Compute and return the use operand latency of a given
- /// itinerary class and operand index if the value is produced by an
- /// instruction of the specified itinerary class and def operand index.
+ /// \brief Compute and return the use operand latency of a given itinerary
+ /// class and operand index if the value is produced by an instruction of the
+ /// specified itinerary class and def operand index.
int getOperandLatency(unsigned DefClass, unsigned DefIdx,
unsigned UseClass, unsigned UseIdx) const {
if (isEmpty())
@@ -226,7 +225,7 @@ public:
return UseCycle;
}
- /// Return the number of micro-ops that the given class decodes to.
+ /// \brief Return the number of micro-ops that the given class decodes to.
/// Return -1 for classes that require dynamic lookup via TargetInstrInfo.
int getNumMicroOps(unsigned ItinClassIndx) const {
if (isEmpty())
diff --git a/include/llvm/MC/MCLabel.h b/include/llvm/MC/MCLabel.h
index f531de8b40d99..de2d0af1423a4 100644
--- a/include/llvm/MC/MCLabel.h
+++ b/include/llvm/MC/MCLabel.h
@@ -20,11 +20,11 @@ namespace llvm {
class MCContext;
class raw_ostream;
- /// MCLabel - Instances of this class represent a label name in the MC file,
- /// and MCLabel are created and unique'd by the MCContext class. MCLabel
+ /// \brief Instances of this class represent a label name in the MC file,
+ /// and MCLabel are created and uniqued by the MCContext class. MCLabel
/// should only be constructed for valid instances in the object file.
class MCLabel {
- // Instance - the instance number of this Directional Local Label
+ // \brief The instance number of this Directional Local Label.
unsigned Instance;
private: // MCContext creates and uniques these.
@@ -32,20 +32,19 @@ namespace llvm {
MCLabel(unsigned instance)
: Instance(instance) {}
- MCLabel(const MCLabel&) LLVM_DELETED_FUNCTION;
- void operator=(const MCLabel&) LLVM_DELETED_FUNCTION;
+ MCLabel(const MCLabel&) = delete;
+ void operator=(const MCLabel&) = delete;
public:
- /// getInstance - Get the current instance of this Directional Local Label.
+ /// \brief Get the current instance of this Directional Local Label.
unsigned getInstance() const { return Instance; }
- /// incInstance - Increment the current instance of this Directional Local
- /// Label.
+ /// \brief Increment the current instance of this Directional Local Label.
unsigned incInstance() { return ++Instance; }
- /// print - Print the value to the stream \p OS.
+ /// \brief Print the value to the stream \p OS.
void print(raw_ostream &OS) const;
- /// dump - Print the value to stderr.
+ /// \brief Print the value to stderr.
void dump() const;
};
diff --git a/include/llvm/MC/MCLinkerOptimizationHint.h b/include/llvm/MC/MCLinkerOptimizationHint.h
index 890d6385aacde..a186a14b8001f 100644
--- a/include/llvm/MC/MCLinkerOptimizationHint.h
+++ b/include/llvm/MC/MCLinkerOptimizationHint.h
@@ -103,8 +103,8 @@ class MCLOHDirective {
/// 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
+ /// 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;
@@ -128,8 +128,8 @@ public:
Emit_impl(OutStream, ObjWriter, Layout);
}
- /// Get the size in bytes of this directive if emitted in @p ObjWriter with
- /// the given @p 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 {
@@ -141,7 +141,7 @@ public:
public:
raw_counting_ostream() : Count(0) {}
- ~raw_counting_ostream() { flush(); }
+ ~raw_counting_ostream() override { flush(); }
};
raw_counting_ostream OutStream;
@@ -167,8 +167,8 @@ public:
return Directives;
}
- /// Add the directive of the given kind @p Kind with the given arguments
- /// @p Args to the container.
+ /// 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));
}
diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h
index 0c5aa8a180638..63c2a28a7c9c8 100644
--- a/include/llvm/MC/MCMachObjectWriter.h
+++ b/include/llvm/MC/MCMachObjectWriter.h
@@ -21,7 +21,6 @@
namespace llvm {
-class MCSectionData;
class MachObjectWriter;
class MCMachObjectTargetWriter {
@@ -45,14 +44,14 @@ protected:
public:
virtual ~MCMachObjectTargetWriter();
- /// @name Lifetime Management
+ /// \name Lifetime Management
/// @{
virtual void reset() {};
/// @}
- /// @name Accessors
+ /// \name Accessors
/// @{
bool is64Bit() const { return Is64Bit; }
@@ -65,15 +64,13 @@ public:
/// @}
- /// @name API
+ /// \name API
/// @{
- virtual void RecordRelocation(MachObjectWriter *Writer,
- const MCAssembler &Asm,
+ virtual void RecordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
- const MCFixup &Fixup,
- MCValue Target,
+ const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue) = 0;
/// @}
@@ -83,7 +80,7 @@ class MachObjectWriter : public MCObjectWriter {
/// MachSymbolData - Helper struct for containing some precomputed information
/// on symbols.
struct MachSymbolData {
- MCSymbolData *SymbolData;
+ const MCSymbol *Symbol;
uint64_t StringIndex;
uint8_t SectionIndex;
@@ -94,15 +91,21 @@ class MachObjectWriter : public MCObjectWriter {
/// The target specific Mach-O writer instance.
std::unique_ptr<MCMachObjectTargetWriter> TargetObjectWriter;
- /// @name Relocation Data
+ /// \name Relocation Data
/// @{
- llvm::DenseMap<const MCSectionData*,
- std::vector<MachO::any_relocation_info> > Relocations;
- llvm::DenseMap<const MCSectionData*, unsigned> IndirectSymBase;
+ struct RelAndSymbol {
+ const MCSymbol *Sym;
+ MachO::any_relocation_info MRE;
+ RelAndSymbol(const MCSymbol *Sym, const MachO::any_relocation_info &MRE)
+ : Sym(Sym), MRE(MRE) {}
+ };
+
+ llvm::DenseMap<const MCSection *, std::vector<RelAndSymbol>> Relocations;
+ llvm::DenseMap<const MCSection *, unsigned> IndirectSymBase;
/// @}
- /// @name Symbol Table Data
+ /// \name Symbol Table Data
/// @{
StringTableBuilder StringTable;
@@ -115,19 +118,20 @@ class MachObjectWriter : public MCObjectWriter {
MachSymbolData *findSymbolData(const MCSymbol &Sym);
public:
- MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS,
- bool _IsLittleEndian)
- : MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) {
- }
+ MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_pwrite_stream &OS,
+ bool IsLittleEndian)
+ : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {}
+
+ const MCSymbol &findAliasedSymbol(const MCSymbol &Sym) const;
- /// @name Lifetime management Methods
+ /// \name Lifetime management Methods
/// @{
void reset() override;
/// @}
- /// @name Utility Methods
+ /// \name Utility Methods
/// @{
bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
@@ -136,23 +140,21 @@ public:
SectionAddrMap &getSectionAddressMap() { return SectionAddress; }
- uint64_t getSectionAddress(const MCSectionData* SD) const {
- return SectionAddress.lookup(SD);
+ uint64_t getSectionAddress(const MCSection *Sec) const {
+ return SectionAddress.lookup(Sec);
}
- uint64_t getSymbolAddress(const MCSymbolData* SD,
- const MCAsmLayout &Layout) const;
+ uint64_t getSymbolAddress(const MCSymbol &S, const MCAsmLayout &Layout) const;
uint64_t getFragmentAddress(const MCFragment *Fragment,
const MCAsmLayout &Layout) const;
- uint64_t getPaddingSize(const MCSectionData *SD,
- const MCAsmLayout &Layout) const;
+ uint64_t getPaddingSize(const MCSection *SD, const MCAsmLayout &Layout) const;
- bool doesSymbolRequireExternRelocation(const MCSymbolData *SD);
+ bool doesSymbolRequireExternRelocation(const MCSymbol &S);
/// @}
- /// @name Target Writer Proxy Accessors
+ /// \name Target Writer Proxy Accessors
/// @{
bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
@@ -176,7 +178,7 @@ public:
uint64_t SectionDataSize);
void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
- const MCSectionData &SD, uint64_t FileOffset,
+ const MCSection &Sec, uint64_t FileOffset,
uint64_t RelocationsStart, unsigned NumRelocations);
void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
@@ -213,9 +215,15 @@ public:
// - Input errors, where something cannot be correctly encoded. 'as' allows
// these through in many cases.
- void addRelocation(const MCSectionData *SD,
+ // Add a relocation to be output in the object file. At the time this is
+ // called, the symbol indexes are not know, so if the relocation refers
+ // to a symbol it should be passed as \p RelSymbol so that it can be updated
+ // afterwards. If the relocation doesn't refer to a symbol, nullptr should be
+ // used.
+ void addRelocation(const MCSymbol *RelSymbol, const MCSection *Sec,
MachO::any_relocation_info &MRE) {
- Relocations[SD].push_back(MRE);
+ RelAndSymbol P(RelSymbol, MRE);
+ Relocations[Sec].push_back(P);
}
void RecordScatteredRelocation(const MCAssembler &Asm,
@@ -231,7 +239,7 @@ public:
const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue);
- void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
+ void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
MCValue Target, bool &IsPCRel,
uint64_t &FixedValue) override;
@@ -248,15 +256,12 @@ public:
void computeSectionAddresses(const MCAssembler &Asm,
const MCAsmLayout &Layout);
- void markAbsoluteVariableSymbols(MCAssembler &Asm,
- const MCAsmLayout &Layout);
void ExecutePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) override;
bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
- const MCSymbolData &DataA,
- const MCFragment &FB,
- bool InSet,
+ const MCSymbol &SymA,
+ const MCFragment &FB, bool InSet,
bool IsPCRel) const override;
void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
@@ -271,7 +276,8 @@ public:
/// \param OS - The stream to write to.
/// \returns The constructed object writer.
MCObjectWriter *createMachObjectWriter(MCMachObjectTargetWriter *MOTW,
- raw_ostream &OS, bool IsLittleEndian);
+ raw_pwrite_stream &OS,
+ bool IsLittleEndian);
} // End llvm namespace
diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h
index 321043c522ee4..f28b9c668cdc8 100644
--- a/include/llvm/MC/MCObjectFileInfo.h
+++ b/include/llvm/MC/MCObjectFileInfo.h
@@ -53,144 +53,139 @@ protected:
/// should emit only an EH frame.
unsigned CompactUnwindDwarfEHFrameOnly;
- /// TextSection - Section directive for standard text.
+ /// Section directive for standard text.
///
- const MCSection *TextSection;
+ MCSection *TextSection;
- /// DataSection - Section directive for standard data.
+ /// Section directive for standard data.
///
- const MCSection *DataSection;
+ MCSection *DataSection;
- /// BSSSection - Section that is default initialized to zero.
- const MCSection *BSSSection;
+ /// Section that is default initialized to zero.
+ MCSection *BSSSection;
- /// ReadOnlySection - Section that is readonly and can contain arbitrary
- /// initialized data. Targets are not required to have a readonly section.
- /// If they don't, various bits of code will fall back to using the data
- /// section for constants.
- const MCSection *ReadOnlySection;
+ /// Section that is readonly and can contain arbitrary initialized data.
+ /// Targets are not required to have a readonly section. If they don't,
+ /// various bits of code will fall back to using the data section for
+ /// constants.
+ MCSection *ReadOnlySection;
- /// StaticCtorSection - This section contains the static constructor pointer
- /// list.
- const MCSection *StaticCtorSection;
+ /// This section contains the static constructor pointer list.
+ MCSection *StaticCtorSection;
- /// StaticDtorSection - This section contains the static destructor pointer
- /// list.
- const MCSection *StaticDtorSection;
+ /// This section contains the static destructor pointer list.
+ MCSection *StaticDtorSection;
- /// LSDASection - If exception handling is supported by the target, this is
- /// the section the Language Specific Data Area information is emitted to.
- const MCSection *LSDASection;
+ /// If exception handling is supported by the target, this is the section the
+ /// Language Specific Data Area information is emitted to.
+ MCSection *LSDASection;
- /// CompactUnwindSection - If exception handling is supported by the target
- /// and the target can support a compact representation of the CIE and FDE,
- /// this is the section to emit them into.
- const MCSection *CompactUnwindSection;
+ /// If exception handling is supported by the target and the target can
+ /// support a compact representation of the CIE and FDE, this is the section
+ /// to emit them into.
+ MCSection *CompactUnwindSection;
// Dwarf sections for debug info. If a target supports debug info, these must
// be set.
- const MCSection *DwarfAbbrevSection;
- const MCSection *DwarfInfoSection;
- const MCSection *DwarfLineSection;
- const MCSection *DwarfFrameSection;
- const MCSection *DwarfPubTypesSection;
+ MCSection *DwarfAbbrevSection;
+ MCSection *DwarfInfoSection;
+ MCSection *DwarfLineSection;
+ MCSection *DwarfFrameSection;
+ MCSection *DwarfPubTypesSection;
const MCSection *DwarfDebugInlineSection;
- const MCSection *DwarfStrSection;
- const MCSection *DwarfLocSection;
- const MCSection *DwarfARangesSection;
- const MCSection *DwarfRangesSection;
- const MCSection *DwarfMacroInfoSection;
+ MCSection *DwarfStrSection;
+ MCSection *DwarfLocSection;
+ MCSection *DwarfARangesSection;
+ MCSection *DwarfRangesSection;
// The pubnames section is no longer generated by default. The generation
// can be enabled by a compiler flag.
- const MCSection *DwarfPubNamesSection;
+ MCSection *DwarfPubNamesSection;
// DWARF5 Experimental Debug Info Sections
/// DwarfAccelNamesSection, DwarfAccelObjCSection,
/// DwarfAccelNamespaceSection, DwarfAccelTypesSection -
/// If we use the DWARF accelerated hash tables then we want to emit these
/// sections.
- const MCSection *DwarfAccelNamesSection;
- const MCSection *DwarfAccelObjCSection;
- const MCSection *DwarfAccelNamespaceSection;
- const MCSection *DwarfAccelTypesSection;
+ MCSection *DwarfAccelNamesSection;
+ MCSection *DwarfAccelObjCSection;
+ MCSection *DwarfAccelNamespaceSection;
+ MCSection *DwarfAccelTypesSection;
/// These are used for the Fission separate debug information files.
- const MCSection *DwarfInfoDWOSection;
- const MCSection *DwarfTypesDWOSection;
- const MCSection *DwarfAbbrevDWOSection;
- const MCSection *DwarfStrDWOSection;
- const MCSection *DwarfLineDWOSection;
- const MCSection *DwarfLocDWOSection;
- const MCSection *DwarfStrOffDWOSection;
- const MCSection *DwarfAddrSection;
+ MCSection *DwarfInfoDWOSection;
+ MCSection *DwarfTypesDWOSection;
+ MCSection *DwarfAbbrevDWOSection;
+ MCSection *DwarfStrDWOSection;
+ MCSection *DwarfLineDWOSection;
+ MCSection *DwarfLocDWOSection;
+ MCSection *DwarfStrOffDWOSection;
+ MCSection *DwarfAddrSection;
/// Sections for newer gnu pubnames and pubtypes.
- const MCSection *DwarfGnuPubNamesSection;
- const MCSection *DwarfGnuPubTypesSection;
+ MCSection *DwarfGnuPubNamesSection;
+ MCSection *DwarfGnuPubTypesSection;
- const MCSection *COFFDebugSymbolsSection;
+ 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;
+ MCSection *TLSExtraDataSection;
- /// TLSDataSection - Section directive for Thread Local data.
- /// ELF, MachO and COFF.
- const MCSection *TLSDataSection; // Defaults to ".tdata".
+ /// Section directive for Thread Local data. ELF, MachO and COFF.
+ MCSection *TLSDataSection; // Defaults to ".tdata".
- /// TLSBSSSection - Section directive for Thread Local uninitialized data.
- /// Null if this target doesn't support a BSS section.
- /// ELF and MachO only.
- const MCSection *TLSBSSSection; // Defaults to ".tbss".
+ /// Section directive for Thread Local uninitialized data. Null if this target
+ /// doesn't support a BSS section. ELF and MachO only.
+ MCSection *TLSBSSSection; // Defaults to ".tbss".
/// StackMap section.
- const MCSection *StackMapSection;
+ MCSection *StackMapSection;
- /// EHFrameSection - EH frame section. It is initialized on demand so it
- /// can be overwritten (with uniquing).
- const MCSection *EHFrameSection;
+ /// EH frame section. It is initialized on demand so it can be overwritten
+ /// (with uniquing).
+ MCSection *EHFrameSection;
/// ELF specific sections.
///
- const MCSection *DataRelSection;
+ MCSection *DataRelSection;
const MCSection *DataRelLocalSection;
- const MCSection *DataRelROSection;
- const MCSection *DataRelROLocalSection;
- const MCSection *MergeableConst4Section;
- const MCSection *MergeableConst8Section;
- const MCSection *MergeableConst16Section;
+ MCSection *DataRelROSection;
+ MCSection *DataRelROLocalSection;
+ MCSection *MergeableConst4Section;
+ MCSection *MergeableConst8Section;
+ MCSection *MergeableConst16Section;
/// MachO specific sections.
///
- /// TLSTLVSection - Section for thread local structure information.
- /// Contains the source code name of the variable, visibility and a pointer
- /// to the initial value (.tdata or .tbss).
- const MCSection *TLSTLVSection; // Defaults to ".tlv".
+ /// Section for thread local structure information. Contains the source code
+ /// name of the variable, visibility and a pointer to the initial value
+ /// (.tdata or .tbss).
+ MCSection *TLSTLVSection; // Defaults to ".tlv".
/// TLSThreadInitSection - Section for thread local data initialization
/// functions.
const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func".
- const MCSection *CStringSection;
- const MCSection *UStringSection;
- const MCSection *TextCoalSection;
- const MCSection *ConstTextCoalSection;
- const MCSection *ConstDataSection;
- const MCSection *DataCoalSection;
- const MCSection *DataCommonSection;
- const MCSection *DataBSSSection;
- const MCSection *FourByteConstantSection;
- const MCSection *EightByteConstantSection;
- const MCSection *SixteenByteConstantSection;
- const MCSection *LazySymbolPointerSection;
- const MCSection *NonLazySymbolPointerSection;
+ MCSection *CStringSection;
+ MCSection *UStringSection;
+ MCSection *TextCoalSection;
+ MCSection *ConstTextCoalSection;
+ MCSection *ConstDataSection;
+ MCSection *DataCoalSection;
+ MCSection *DataCommonSection;
+ MCSection *DataBSSSection;
+ MCSection *FourByteConstantSection;
+ MCSection *EightByteConstantSection;
+ MCSection *SixteenByteConstantSection;
+ MCSection *LazySymbolPointerSection;
+ MCSection *NonLazySymbolPointerSection;
/// COFF specific sections.
///
- const MCSection *DrectveSection;
- const MCSection *PDataSection;
- const MCSection *XDataSection;
+ MCSection *DrectveSection;
+ MCSection *PDataSection;
+ MCSection *XDataSection;
public:
void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM,
@@ -215,97 +210,70 @@ public:
return CompactUnwindDwarfEHFrameOnly;
}
- const MCSection *getTextSection() const { return TextSection; }
- const MCSection *getDataSection() const { return DataSection; }
- const MCSection *getBSSSection() const { return BSSSection; }
- const MCSection *getLSDASection() const { return LSDASection; }
- const MCSection *getCompactUnwindSection() const{
- return CompactUnwindSection;
- }
- const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; }
- const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; }
- const MCSection *getDwarfLineSection() const { return DwarfLineSection; }
- const MCSection *getDwarfFrameSection() const { return DwarfFrameSection; }
- const MCSection *getDwarfPubNamesSection() const{return DwarfPubNamesSection;}
- const MCSection *getDwarfPubTypesSection() const{return DwarfPubTypesSection;}
- const MCSection *getDwarfGnuPubNamesSection() const {
+ MCSection *getTextSection() const { return TextSection; }
+ MCSection *getDataSection() const { return DataSection; }
+ MCSection *getBSSSection() const { return BSSSection; }
+ MCSection *getLSDASection() const { return LSDASection; }
+ MCSection *getCompactUnwindSection() const { return CompactUnwindSection; }
+ MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; }
+ MCSection *getDwarfInfoSection() const { return DwarfInfoSection; }
+ MCSection *getDwarfLineSection() const { return DwarfLineSection; }
+ MCSection *getDwarfFrameSection() const { return DwarfFrameSection; }
+ MCSection *getDwarfPubNamesSection() const { return DwarfPubNamesSection; }
+ MCSection *getDwarfPubTypesSection() const { return DwarfPubTypesSection; }
+ MCSection *getDwarfGnuPubNamesSection() const {
return DwarfGnuPubNamesSection;
}
- const MCSection *getDwarfGnuPubTypesSection() const {
+ MCSection *getDwarfGnuPubTypesSection() const {
return DwarfGnuPubTypesSection;
}
const MCSection *getDwarfDebugInlineSection() const {
return DwarfDebugInlineSection;
}
- const MCSection *getDwarfStrSection() const { return DwarfStrSection; }
- const MCSection *getDwarfLocSection() const { return DwarfLocSection; }
- const MCSection *getDwarfARangesSection() const { return DwarfARangesSection;}
- const MCSection *getDwarfRangesSection() const { return DwarfRangesSection; }
- const MCSection *getDwarfMacroInfoSection() const {
- return DwarfMacroInfoSection;
- }
+ MCSection *getDwarfStrSection() const { return DwarfStrSection; }
+ MCSection *getDwarfLocSection() const { return DwarfLocSection; }
+ MCSection *getDwarfARangesSection() const { return DwarfARangesSection; }
+ MCSection *getDwarfRangesSection() const { return DwarfRangesSection; }
// DWARF5 Experimental Debug Info Sections
- const MCSection *getDwarfAccelNamesSection() const {
+ MCSection *getDwarfAccelNamesSection() const {
return DwarfAccelNamesSection;
}
- const MCSection *getDwarfAccelObjCSection() const {
- return DwarfAccelObjCSection;
- }
- const MCSection *getDwarfAccelNamespaceSection() const {
+ MCSection *getDwarfAccelObjCSection() const { return DwarfAccelObjCSection; }
+ MCSection *getDwarfAccelNamespaceSection() const {
return DwarfAccelNamespaceSection;
}
- const MCSection *getDwarfAccelTypesSection() const {
+ MCSection *getDwarfAccelTypesSection() const {
return DwarfAccelTypesSection;
}
- const MCSection *getDwarfInfoDWOSection() const {
- return DwarfInfoDWOSection;
- }
- const MCSection *getDwarfTypesSection(uint64_t Hash) const;
- const MCSection *getDwarfTypesDWOSection() const {
- return DwarfTypesDWOSection;
- }
- const MCSection *getDwarfAbbrevDWOSection() const {
- return DwarfAbbrevDWOSection;
- }
- const MCSection *getDwarfStrDWOSection() const {
- return DwarfStrDWOSection;
- }
- const MCSection *getDwarfLineDWOSection() const {
- return DwarfLineDWOSection;
- }
- const MCSection *getDwarfLocDWOSection() const {
- return DwarfLocDWOSection;
- }
- const MCSection *getDwarfStrOffDWOSection() const {
- return DwarfStrOffDWOSection;
- }
- const MCSection *getDwarfAddrSection() const {
- return DwarfAddrSection;
- }
-
- const MCSection *getCOFFDebugSymbolsSection() const {
+ MCSection *getDwarfInfoDWOSection() const { return DwarfInfoDWOSection; }
+ MCSection *getDwarfTypesSection(uint64_t Hash) const;
+ MCSection *getDwarfTypesDWOSection() const { return DwarfTypesDWOSection; }
+ MCSection *getDwarfAbbrevDWOSection() const { return DwarfAbbrevDWOSection; }
+ MCSection *getDwarfStrDWOSection() const { return DwarfStrDWOSection; }
+ MCSection *getDwarfLineDWOSection() const { return DwarfLineDWOSection; }
+ MCSection *getDwarfLocDWOSection() const { return DwarfLocDWOSection; }
+ MCSection *getDwarfStrOffDWOSection() const { return DwarfStrOffDWOSection; }
+ MCSection *getDwarfAddrSection() const { return DwarfAddrSection; }
+
+ MCSection *getCOFFDebugSymbolsSection() const {
return COFFDebugSymbolsSection;
}
- const MCSection *getTLSExtraDataSection() const {
- return TLSExtraDataSection;
- }
+ MCSection *getTLSExtraDataSection() const { return TLSExtraDataSection; }
const MCSection *getTLSDataSection() const { return TLSDataSection; }
- const MCSection *getTLSBSSSection() const { return TLSBSSSection; }
+ MCSection *getTLSBSSSection() const { return TLSBSSSection; }
- const MCSection *getStackMapSection() const { return StackMapSection; }
+ MCSection *getStackMapSection() const { return StackMapSection; }
/// ELF specific sections.
///
- const MCSection *getDataRelSection() const { return DataRelSection; }
+ MCSection *getDataRelSection() const { return DataRelSection; }
const MCSection *getDataRelLocalSection() const {
return DataRelLocalSection;
}
- const MCSection *getDataRelROSection() const { return DataRelROSection; }
- const MCSection *getDataRelROLocalSection() const {
- return DataRelROLocalSection;
- }
+ MCSection *getDataRelROSection() const { return DataRelROSection; }
+ MCSection *getDataRelROLocalSection() const { return DataRelROLocalSection; }
const MCSection *getMergeableConst4Section() const {
return MergeableConst4Section;
}
@@ -324,14 +292,14 @@ public:
}
const MCSection *getCStringSection() const { return CStringSection; }
const MCSection *getUStringSection() const { return UStringSection; }
- const MCSection *getTextCoalSection() const { return TextCoalSection; }
+ MCSection *getTextCoalSection() const { return TextCoalSection; }
const MCSection *getConstTextCoalSection() const {
return ConstTextCoalSection;
}
const MCSection *getConstDataSection() const { return ConstDataSection; }
const MCSection *getDataCoalSection() const { return DataCoalSection; }
const MCSection *getDataCommonSection() const { return DataCommonSection; }
- const MCSection *getDataBSSSection() const { return DataBSSSection; }
+ MCSection *getDataBSSSection() const { return DataBSSSection; }
const MCSection *getFourByteConstantSection() const {
return FourByteConstantSection;
}
@@ -341,20 +309,20 @@ public:
const MCSection *getSixteenByteConstantSection() const {
return SixteenByteConstantSection;
}
- const MCSection *getLazySymbolPointerSection() const {
+ MCSection *getLazySymbolPointerSection() const {
return LazySymbolPointerSection;
}
- const MCSection *getNonLazySymbolPointerSection() const {
+ MCSection *getNonLazySymbolPointerSection() const {
return NonLazySymbolPointerSection;
}
/// COFF specific sections.
///
- const MCSection *getDrectveSection() const { return DrectveSection; }
- const MCSection *getPDataSection() const { return PDataSection; }
- const MCSection *getXDataSection() const { return XDataSection; }
+ MCSection *getDrectveSection() const { return DrectveSection; }
+ MCSection *getPDataSection() const { return PDataSection; }
+ MCSection *getXDataSection() const { return XDataSection; }
- const MCSection *getEHFrameSection() {
+ MCSection *getEHFrameSection() {
if (!EHFrameSection)
InitEHFrameSection();
return EHFrameSection;
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index 0866ff5a9fc08..e75bc86cc131b 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -12,18 +12,19 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
namespace llvm {
class MCAssembler;
class MCCodeEmitter;
-class MCSectionData;
class MCSubtargetInfo;
class MCExpr;
class MCFragment;
class MCDataFragment;
class MCAsmBackend;
class raw_ostream;
+class raw_pwrite_stream;
/// \brief Streaming object file generation interface.
///
@@ -34,8 +35,8 @@ class raw_ostream;
/// implementation.
class MCObjectStreamer : public MCStreamer {
MCAssembler *Assembler;
- MCSectionData *CurSectionData;
- MCSectionData::iterator CurInsertionPoint;
+ MCSection *CurSectionData;
+ MCSection::iterator CurInsertionPoint;
bool EmitEHFrame;
bool EmitDebugFrame;
SmallVector<MCSymbolData *, 2> PendingLabels;
@@ -44,16 +45,10 @@ class MCObjectStreamer : public MCStreamer {
void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
- // If any labels have been emitted but not assigned fragments, ensure that
- // they get assigned, either to F if possible or to a new data fragment.
- void flushPendingLabels(MCFragment *F);
-
protected:
- MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS,
- MCCodeEmitter *_Emitter);
- MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS,
- MCCodeEmitter *_Emitter, MCAssembler *_Assembler);
- ~MCObjectStreamer();
+ MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS,
+ MCCodeEmitter *Emitter);
+ ~MCObjectStreamer() override;
public:
/// state management
@@ -69,9 +64,7 @@ public:
void EmitCFISections(bool EH, bool Debug) override;
protected:
- MCSectionData *getCurrentSectionData() const {
- return CurSectionData;
- }
+ MCSection *getCurrentSectionData() const { return CurSectionData; }
MCFragment *getCurrentFragment() const;
@@ -85,12 +78,20 @@ protected:
/// fragment is not a data fragment.
MCDataFragment *getOrCreateDataFragment();
+ bool changeSectionImpl(MCSection *Section, const MCExpr *Subsection);
+
+ /// If any labels have been emitted but not assigned fragments, ensure that
+ /// they get assigned, either to F if possible or to a new data fragment.
+ /// Optionally, it is also possible to provide an offset \p FOffset, which
+ /// will be used as a symbol offset within the fragment.
+ void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0);
+
public:
void visitUsedSymbol(const MCSymbol &Sym) override;
MCAssembler &getAssembler() { return *Assembler; }
- /// @name MCStreamer Interface
+ /// \name MCStreamer Interface
/// @{
void EmitLabel(MCSymbol *Symbol) override;
@@ -100,8 +101,7 @@ public:
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 ChangeSection(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
@@ -133,9 +133,18 @@ public:
void EmitZeros(uint64_t NumBytes) override;
void FinishImpl() override;
- bool mayHaveInstructions() const override {
- return getCurrentSectionData()->hasInstructions();
- }
+ /// Emit the absolute difference between two symbols if possible.
+ ///
+ /// Emit the absolute difference between \c Hi and \c Lo, as long as we can
+ /// compute it. Currently, that requires that both symbols are in the same
+ /// data fragment. Otherwise, do nothing and return \c false.
+ ///
+ /// \pre Offset of \c Hi is greater than the offset \c Lo.
+ /// \return true on success.
+ bool emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
+ unsigned Size) override;
+
+ bool mayHaveInstructions(MCSection &Sec) const override;
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
index 55c828c6c179e..999d294712709 100644
--- a/include/llvm/MC/MCObjectWriter.h
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -13,6 +13,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/EndianStream.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
@@ -37,17 +38,17 @@ class MCValue;
/// The object writer also contains a number of helper methods for writing
/// binary data to the output stream.
class MCObjectWriter {
- MCObjectWriter(const MCObjectWriter &) LLVM_DELETED_FUNCTION;
- void operator=(const MCObjectWriter &) LLVM_DELETED_FUNCTION;
+ MCObjectWriter(const MCObjectWriter &) = delete;
+ void operator=(const MCObjectWriter &) = delete;
protected:
- raw_ostream &OS;
+ raw_pwrite_stream &OS;
unsigned IsLittleEndian : 1;
protected: // Can only create subclasses.
- MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian)
- : OS(_OS), IsLittleEndian(_IsLittleEndian) {}
+ MCObjectWriter(raw_pwrite_stream &OS, bool IsLittleEndian)
+ : OS(OS), IsLittleEndian(IsLittleEndian) {}
public:
virtual ~MCObjectWriter();
@@ -59,7 +60,7 @@ public:
raw_ostream &getStream() { return OS; }
- /// @name High-Level API
+ /// \name High-Level API
/// @{
/// \brief Perform any late binding of symbols (for example, to assign symbol
@@ -76,30 +77,31 @@ public:
/// post layout binding. The implementation is responsible for storing
/// information about the relocation so that it can be emitted during
/// WriteObject().
- virtual void RecordRelocation(const MCAssembler &Asm,
- const MCAsmLayout &Layout,
+ virtual void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
- bool &IsPCRel,
- uint64_t &FixedValue) = 0;
+ bool &IsPCRel, uint64_t &FixedValue) = 0;
/// \brief Check whether the difference (A - B) between two symbol
/// references is fully resolved.
///
/// Clients are not required to answer precisely and may conservatively return
/// false, even when a difference is fully resolved.
- bool
- IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
- const MCSymbolRefExpr *A,
- const MCSymbolRefExpr *B,
- bool InSet) const;
-
- virtual bool
- IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
- const MCSymbolData &DataA,
- const MCFragment &FB,
- bool InSet,
- bool IsPCRel) const;
+ bool IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
+ const MCSymbolRefExpr *A,
+ const MCSymbolRefExpr *B,
+ bool InSet) const;
+
+ virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbol &SymA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const;
+
+ /// \brief True if this symbol (which is a variable) is weak. This is not
+ /// just STB_WEAK, but more generally whether or not we can evaluate
+ /// past it.
+ virtual bool isWeak(const MCSymbol &Sym) const;
/// \brief Write the object file.
///
@@ -110,7 +112,7 @@ public:
const MCAsmLayout &Layout) = 0;
/// @}
- /// @name Binary Output
+ /// \name Binary Output
/// @{
void Write8(uint8_t Value) {
@@ -118,33 +120,27 @@ public:
}
void WriteLE16(uint16_t Value) {
- Write8(uint8_t(Value >> 0));
- Write8(uint8_t(Value >> 8));
+ support::endian::Writer<support::little>(OS).write(Value);
}
void WriteLE32(uint32_t Value) {
- WriteLE16(uint16_t(Value >> 0));
- WriteLE16(uint16_t(Value >> 16));
+ support::endian::Writer<support::little>(OS).write(Value);
}
void WriteLE64(uint64_t Value) {
- WriteLE32(uint32_t(Value >> 0));
- WriteLE32(uint32_t(Value >> 32));
+ support::endian::Writer<support::little>(OS).write(Value);
}
void WriteBE16(uint16_t Value) {
- Write8(uint8_t(Value >> 8));
- Write8(uint8_t(Value >> 0));
+ support::endian::Writer<support::big>(OS).write(Value);
}
void WriteBE32(uint32_t Value) {
- WriteBE16(uint16_t(Value >> 16));
- WriteBE16(uint16_t(Value >> 0));
+ support::endian::Writer<support::big>(OS).write(Value);
}
void WriteBE64(uint64_t Value) {
- WriteBE32(uint32_t(Value >> 32));
- WriteBE32(uint32_t(Value >> 0));
+ support::endian::Writer<support::big>(OS).write(Value);
}
void Write16(uint16_t Value) {
diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h
index a9a30f1720712..62d39b26c8600 100644
--- a/include/llvm/MC/MCParser/AsmLexer.h
+++ b/include/llvm/MC/MCParser/AsmLexer.h
@@ -31,8 +31,8 @@ class AsmLexer : public MCAsmLexer {
StringRef CurBuf;
bool isAtStartOfLine;
- void operator=(const AsmLexer&) LLVM_DELETED_FUNCTION;
- AsmLexer(const AsmLexer&) LLVM_DELETED_FUNCTION;
+ void operator=(const AsmLexer&) = delete;
+ AsmLexer(const AsmLexer&) = delete;
protected:
/// LexToken - Read the next token and return its code.
@@ -40,7 +40,7 @@ protected:
public:
AsmLexer(const MCAsmInfo &MAI);
- ~AsmLexer();
+ ~AsmLexer() override;
void setBuffer(StringRef Buf, const char *ptr = nullptr);
diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h
index b05891c13250b..71f15b37c331e 100644
--- a/include/llvm/MC/MCParser/MCAsmLexer.h
+++ b/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -63,10 +63,10 @@ private:
public:
AsmToken() {}
- 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) {}
+ 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; }
@@ -124,8 +124,8 @@ class MCAsmLexer {
SMLoc ErrLoc;
std::string Err;
- MCAsmLexer(const MCAsmLexer &) LLVM_DELETED_FUNCTION;
- void operator=(const MCAsmLexer &) LLVM_DELETED_FUNCTION;
+ MCAsmLexer(const MCAsmLexer &) = delete;
+ void operator=(const MCAsmLexer &) = delete;
protected: // Can only create subclasses.
const char *TokStart;
bool SkipSpace;
diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h
index 34188e66e62da..0538b9457f9eb 100644
--- a/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/include/llvm/MC/MCParser/MCAsmParser.h
@@ -45,7 +45,7 @@ public:
}
};
-/// Generic Sema callback for assembly parser.
+/// \brief Generic Sema callback for assembly parser.
class MCAsmParserSemaCallback {
public:
virtual ~MCAsmParserSemaCallback();
@@ -59,8 +59,8 @@ public:
unsigned &Offset) = 0;
};
-/// Generic assembler parser interface, for use by target specific assembly
-/// parsers.
+/// \brief Generic assembler parser interface, for use by target specific
+/// assembly parsers.
class MCAsmParser {
public:
typedef bool (*DirectiveHandler)(MCAsmParserExtension*, StringRef, SMLoc);
@@ -68,8 +68,8 @@ public:
ExtensionDirectiveHandler;
private:
- MCAsmParser(const MCAsmParser &) LLVM_DELETED_FUNCTION;
- void operator=(const MCAsmParser &) LLVM_DELETED_FUNCTION;
+ MCAsmParser(const MCAsmParser &) = delete;
+ void operator=(const MCAsmParser &) = delete;
MCTargetAsmParser *TargetParser;
@@ -84,6 +84,8 @@ public:
virtual void addDirectiveHandler(StringRef Directive,
ExtensionDirectiveHandler Handler) = 0;
+ virtual void addAliasForDirective(StringRef Directive, StringRef Alias) = 0;
+
virtual SourceMgr &getSourceManager() = 0;
virtual MCAsmLexer &getLexer() = 0;
@@ -93,7 +95,7 @@ public:
virtual MCContext &getContext() = 0;
- /// Return the output streamer for the assembler.
+ /// \brief Return the output streamer for the assembler.
virtual MCStreamer &getStreamer() = 0;
MCTargetAsmParser &getTargetParser() const { return *TargetParser; }
@@ -105,13 +107,13 @@ public:
bool getShowParsedOperands() const { return ShowParsedOperands; }
void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; }
- /// Run the parser on the input source buffer.
+ /// \brief Run the parser on the input source buffer.
virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0;
virtual void setParsingInlineAsm(bool V) = 0;
virtual bool isParsingInlineAsm() = 0;
- /// Parse ms-style inline assembly.
+ /// \brief Parse MS-style inline assembly.
virtual bool parseMSInlineAsm(
void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
@@ -119,35 +121,35 @@ public:
SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) = 0;
- /// Emit a note at the location \p L, with the message \p Msg.
+ /// \brief 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;
- /// Emit a warning at the location \p L, with the message \p Msg.
+ /// \brief Emit a warning at the location \p L, with the message \p Msg.
///
/// \return The return value is true, if warnings are fatal.
virtual bool Warning(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = None) = 0;
- /// Emit an error at the location \p L, with the message \p Msg.
+ /// \brief Emit an error at the location \p L, with the message \p Msg.
///
/// \return The return value is always true, as an idiomatic convenience to
/// clients.
virtual bool Error(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = None) = 0;
- /// Get the next AsmToken in the stream, possibly handling file inclusion
- /// first.
+ /// \brief Get the next AsmToken in the stream, possibly handling file
+ /// inclusion first.
virtual const AsmToken &Lex() = 0;
- /// Get the current AsmToken from the stream.
+ /// \brief Get the current AsmToken from the stream.
const AsmToken &getTok() const;
/// \brief Report an error at the current lexer location.
bool TokError(const Twine &Msg, ArrayRef<SMRange> Ranges = None);
- /// Parse an identifier or string (as a quoted identifier) and set \p Res to
- /// the identifier contents.
+ /// \brief Parse an identifier or string (as a quoted identifier) and set \p
+ /// Res to the identifier contents.
virtual bool parseIdentifier(StringRef &Res) = 0;
/// \brief Parse up to the end of statement and return the contents from the
@@ -155,51 +157,51 @@ public:
/// will be either the EndOfStatement or EOF.
virtual StringRef parseStringToEndOfStatement() = 0;
- /// Parse the current token as a string which may include escaped characters
- /// and return the string contents.
+ /// \brief Parse the current token as a string which may include escaped
+ /// characters and return the string contents.
virtual bool parseEscapedString(std::string &Data) = 0;
- /// Skip to the end of the current statement, for error recovery.
+ /// \brief Skip to the end of the current statement, for error recovery.
virtual void eatToEndOfStatement() = 0;
- /// Parse an arbitrary expression.
+ /// \brief Parse an arbitrary expression.
///
- /// @param Res - The value of the expression. The result is undefined
+ /// \param Res - The value of the expression. The result is undefined
/// on error.
- /// @result - False on success.
+ /// \return - False on success.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
bool parseExpression(const MCExpr *&Res);
- /// Parse a primary expression.
+ /// \brief Parse a primary expression.
///
- /// @param Res - The value of the expression. The result is undefined
+ /// \param Res - The value of the expression. The result is undefined
/// on error.
- /// @result - False on success.
+ /// \return - False on success.
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) = 0;
- /// Parse an arbitrary expression, assuming that an initial '(' has already
- /// been consumed.
+ /// \brief Parse an arbitrary expression, assuming that an initial '(' has
+ /// already been consumed.
///
- /// @param Res - The value of the expression. The result is undefined
+ /// \param Res - The value of the expression. The result is undefined
/// on error.
- /// @result - False on success.
+ /// \return - False on success.
virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
- /// Parse an expression which must evaluate to an absolute value.
+ /// \brief Parse an expression which must evaluate to an absolute value.
///
- /// @param Res - The value of the absolute expression. The result is undefined
+ /// \param Res - The value of the absolute expression. The result is undefined
/// on error.
- /// @result - False on success.
+ /// \return - False on success.
virtual bool parseAbsoluteExpression(int64_t &Res) = 0;
- /// Ensure that we have a valid section set in the streamer. Otherwise, report
- /// an error and switch to .text.
+ /// \brief Ensure that we have a valid section set in the streamer. Otherwise,
+ /// report an error and switch to .text.
virtual void checkForValidSection() = 0;
};
/// \brief Create an MCAsmParser instance.
-MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &,
- MCStreamer &, const MCAsmInfo &);
+MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &,
+ const MCAsmInfo &);
} // End llvm namespace
diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h
index bfc0afa132b7f..077fd21e073ce 100644
--- a/include/llvm/MC/MCParser/MCAsmParserExtension.h
+++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h
@@ -21,8 +21,8 @@ class Twine;
/// which is implemented by target and object file assembly parser
/// implementations.
class MCAsmParserExtension {
- MCAsmParserExtension(const MCAsmParserExtension &) LLVM_DELETED_FUNCTION;
- void operator=(const MCAsmParserExtension &) LLVM_DELETED_FUNCTION;
+ MCAsmParserExtension(const MCAsmParserExtension &) = delete;
+ void operator=(const MCAsmParserExtension &) = delete;
MCAsmParser *Parser;
@@ -48,7 +48,7 @@ public:
/// parsing routines.
virtual void Initialize(MCAsmParser &Parser);
- /// @name MCAsmParser Proxy Interfaces
+ /// \name MCAsmParser Proxy Interfaces
/// @{
MCContext &getContext() { return getParser().getContext(); }
diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
index e8740aa10aa2a..a25108a0effb0 100644
--- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h
+++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
@@ -10,8 +10,11 @@
#ifndef LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H
#define LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H
+#include <string>
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SMLoc.h"
+
namespace llvm {
-class SMLoc;
class raw_ostream;
/// MCParsedAsmOperand - This abstract class represents a source-level assembly
diff --git a/include/llvm/MC/MCRelocationInfo.h b/include/llvm/MC/MCRelocationInfo.h
index 9dab90099b7d1..40e0217b8d830 100644
--- a/include/llvm/MC/MCRelocationInfo.h
+++ b/include/llvm/MC/MCRelocationInfo.h
@@ -28,8 +28,8 @@ class MCContext;
/// \brief Create MCExprs from relocations found in an object file.
class MCRelocationInfo {
- MCRelocationInfo(const MCRelocationInfo &) LLVM_DELETED_FUNCTION;
- void operator=(const MCRelocationInfo &) LLVM_DELETED_FUNCTION;
+ MCRelocationInfo(const MCRelocationInfo &) = delete;
+ void operator=(const MCRelocationInfo &) = delete;
protected:
MCContext &Ctx;
diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h
index de2678adad61c..96a4ef135f217 100644
--- a/include/llvm/MC/MCSection.h
+++ b/include/llvm/MC/MCSection.h
@@ -14,66 +14,163 @@
#ifndef LLVM_MC_MCSECTION_H
#define LLVM_MC_MCSECTION_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
- class MCAsmInfo;
- class MCExpr;
- class raw_ostream;
-
- /// MCSection - Instances of this class represent a uniqued identifier for a
- /// section in the current translation unit. The MCContext class uniques and
- /// creates these.
- class MCSection {
- public:
- enum SectionVariant {
- SV_COFF = 0,
- SV_ELF,
- SV_MachO
- };
-
- private:
- MCSection(const MCSection&) LLVM_DELETED_FUNCTION;
- void operator=(const MCSection&) LLVM_DELETED_FUNCTION;
- protected:
- MCSection(SectionVariant V, SectionKind K) : Variant(V), Kind(K) {}
- SectionVariant Variant;
- SectionKind Kind;
- public:
- virtual ~MCSection();
-
- SectionKind getKind() const { return Kind; }
-
- SectionVariant getVariant() const { return Variant; }
-
- virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
- raw_ostream &OS,
- const MCExpr *Subsection) const = 0;
-
- // Convenience routines to get label names for the beginning/end of a
- // section.
- virtual std::string getLabelBeginName() const = 0;
- virtual std::string getLabelEndName() const = 0;
-
- /// isBaseAddressKnownZero - Return true if we know that this section will
- /// get a base address of zero. In cases where we know that this is true we
- /// can emit section offsets as direct references to avoid a subtraction
- /// from the base of the section, saving a relocation.
- virtual bool isBaseAddressKnownZero() const {
- return false;
- }
-
- // UseCodeAlign - Return true if a .align directive should use
- // "optimized nops" to fill instead of 0s.
- virtual bool UseCodeAlign() const = 0;
-
- /// isVirtualSection - Check whether this section is "virtual", that is
- /// has no actual object file contents.
- virtual bool isVirtualSection() const = 0;
+class MCAssembler;
+class MCAsmInfo;
+class MCContext;
+class MCExpr;
+class MCFragment;
+class MCSection;
+class MCSymbol;
+class raw_ostream;
+
+/// Instances of this class represent a uniqued identifier for a section in the
+/// current translation unit. The MCContext class uniques and creates these.
+class MCSection {
+public:
+ enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO };
+
+ /// \brief Express the state of bundle locked groups while emitting code.
+ enum BundleLockStateType {
+ NotBundleLocked,
+ BundleLocked,
+ BundleLockedAlignToEnd
};
+ typedef iplist<MCFragment> FragmentListType;
+
+ typedef FragmentListType::const_iterator const_iterator;
+ typedef FragmentListType::iterator iterator;
+
+ typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
+ typedef FragmentListType::reverse_iterator reverse_iterator;
+
+private:
+ MCSection(const MCSection &) = delete;
+ void operator=(const MCSection &) = delete;
+
+ MCSymbol *Begin;
+ MCSymbol *End = nullptr;
+ /// The alignment requirement of this section.
+ unsigned Alignment = 1;
+ /// The section index in the assemblers section list.
+ unsigned Ordinal = 0;
+ /// The index of this section in the layout order.
+ unsigned LayoutOrder;
+
+ /// \brief Keeping track of bundle-locked state.
+ BundleLockStateType BundleLockState = NotBundleLocked;
+
+ /// \brief Current nesting depth of bundle_lock directives.
+ unsigned BundleLockNestingDepth = 0;
+
+ /// \brief We've seen a bundle_lock directive but not its first instruction
+ /// yet.
+ bool BundleGroupBeforeFirstInst = false;
+
+ /// Whether this section has had instructions emitted into it.
+ unsigned HasInstructions : 1;
+
+ FragmentListType Fragments;
+
+ /// Mapping from subsection number to insertion point for subsection numbers
+ /// below that number.
+ SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap;
+
+protected:
+ MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin);
+ SectionVariant Variant;
+ SectionKind Kind;
+
+public:
+ virtual ~MCSection();
+
+ SectionKind getKind() const { return Kind; }
+
+ SectionVariant getVariant() const { return Variant; }
+
+ MCSymbol *getBeginSymbol() { return Begin; }
+ const MCSymbol *getBeginSymbol() const {
+ return const_cast<MCSection *>(this)->getBeginSymbol();
+ }
+ void setBeginSymbol(MCSymbol *Sym) {
+ assert(!Begin);
+ Begin = Sym;
+ }
+ MCSymbol *getEndSymbol(MCContext &Ctx);
+ bool hasEnded() const;
+
+ unsigned getAlignment() const { return Alignment; }
+ void setAlignment(unsigned Value) { Alignment = Value; }
+
+ unsigned getOrdinal() const { return Ordinal; }
+ void setOrdinal(unsigned Value) { Ordinal = Value; }
+
+ unsigned getLayoutOrder() const { return LayoutOrder; }
+ void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
+
+ BundleLockStateType getBundleLockState() const { return BundleLockState; }
+ void setBundleLockState(BundleLockStateType NewState);
+ bool isBundleLocked() const { return BundleLockState != NotBundleLocked; }
+
+ bool isBundleGroupBeforeFirstInst() const {
+ return BundleGroupBeforeFirstInst;
+ }
+ void setBundleGroupBeforeFirstInst(bool IsFirst) {
+ BundleGroupBeforeFirstInst = IsFirst;
+ }
+
+ bool hasInstructions() const { return HasInstructions; }
+ void setHasInstructions(bool Value) { HasInstructions = Value; }
+
+ MCSection::FragmentListType &getFragmentList() { return Fragments; }
+ const MCSection::FragmentListType &getFragmentList() const {
+ return const_cast<MCSection *>(this)->getFragmentList();
+ }
+
+ MCSection::iterator begin();
+ MCSection::const_iterator begin() const {
+ return const_cast<MCSection *>(this)->begin();
+ }
+
+ MCSection::iterator end();
+ MCSection::const_iterator end() const {
+ return const_cast<MCSection *>(this)->end();
+ }
+
+ MCSection::reverse_iterator rbegin();
+ MCSection::const_reverse_iterator rbegin() const {
+ return const_cast<MCSection *>(this)->rbegin();
+ }
+
+ MCSection::reverse_iterator rend();
+ MCSection::const_reverse_iterator rend() const {
+ return const_cast<MCSection *>(this)->rend();
+ }
+
+ MCSection::iterator getSubsectionInsertionPoint(unsigned Subsection);
+
+ void dump();
+
+ virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+ const MCExpr *Subsection) const = 0;
+
+ /// Return true if a .align directive should use "optimized nops" to fill
+ /// instead of 0s.
+ virtual bool UseCodeAlign() const = 0;
+
+ /// Check whether this section is "virtual", that is has no actual object
+ /// file contents.
+ virtual bool isVirtualSection() const = 0;
+};
+
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
index 0bbf3696686eb..237f6d31fb1b0 100644
--- a/include/llvm/MC/MCSectionCOFF.h
+++ b/include/llvm/MC/MCSectionCOFF.h
@@ -45,14 +45,15 @@ class MCSymbol;
private:
friend class MCContext;
MCSectionCOFF(StringRef Section, unsigned Characteristics,
- MCSymbol *COMDATSymbol, int Selection, SectionKind K)
- : MCSection(SV_COFF, K), SectionName(Section),
+ MCSymbol *COMDATSymbol, int Selection, SectionKind K,
+ MCSymbol *Begin)
+ : MCSection(SV_COFF, K, Begin), SectionName(Section),
Characteristics(Characteristics), COMDATSymbol(COMDATSymbol),
Selection(Selection) {
assert ((Characteristics & 0x00F00000) == 0 &&
"alignment must not be set upon section creation");
}
- ~MCSectionCOFF();
+ ~MCSectionCOFF() override;
public:
/// ShouldOmitSectionDirective - Decides whether a '.section' directive
@@ -60,12 +61,6 @@ class MCSymbol;
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
StringRef getSectionName() const { return SectionName; }
- std::string getLabelBeginName() const override {
- return SectionName.str() + "_begin";
- }
- std::string getLabelEndName() const override {
- return SectionName.str() + "_end";
- }
unsigned getCharacteristics() const { return Characteristics; }
MCSymbol *getCOMDATSymbol() const { return COMDATSymbol; }
int getSelection() const { return Selection; }
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
index 5ec23f1afad21..9efe1022f2957 100644
--- a/include/llvm/MC/MCSectionELF.h
+++ b/include/llvm/MC/MCSectionELF.h
@@ -39,6 +39,8 @@ class MCSectionELF : public MCSection {
/// below.
unsigned Flags;
+ unsigned UniqueID;
+
/// EntrySize - The size of each entry in this section. This size only
/// makes sense for sections that contain fixed-sized entries. If a
/// section does not contain fixed-sized entries 'EntrySize' will be 0.
@@ -46,13 +48,18 @@ class MCSectionELF : public MCSection {
const MCSymbol *Group;
+ /// Depending on the type of the section this is sh_link or sh_info.
+ const MCSectionELF *Associated;
+
private:
friend class MCContext;
- MCSectionELF(StringRef Section, unsigned type, unsigned flags,
- SectionKind K, unsigned entrySize, const MCSymbol *group)
- : MCSection(SV_ELF, K), SectionName(Section), Type(type), Flags(flags),
- EntrySize(entrySize), Group(group) {}
- ~MCSectionELF();
+ MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K,
+ unsigned entrySize, const MCSymbol *group, unsigned UniqueID,
+ MCSymbol *Begin, const MCSectionELF *Associated)
+ : MCSection(SV_ELF, K, Begin), SectionName(Section), Type(type),
+ Flags(flags), UniqueID(UniqueID), EntrySize(entrySize), Group(group),
+ Associated(Associated) {}
+ ~MCSectionELF() override;
void setSectionName(StringRef Name) { SectionName = Name; }
@@ -63,16 +70,6 @@ public:
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
StringRef getSectionName() const { return SectionName; }
- 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; }
unsigned getFlags() const { return Flags; }
unsigned getEntrySize() const { return EntrySize; }
@@ -83,19 +80,14 @@ public:
bool UseCodeAlign() const override;
bool isVirtualSection() const override;
- /// isBaseAddressKnownZero - We know that non-allocatable sections (like
- /// debug info) have a base of zero.
- bool isBaseAddressKnownZero() const override {
- return (getFlags() & ELF::SHF_ALLOC) == 0;
- }
+ bool isUnique() const { return UniqueID != ~0U; }
+ unsigned getUniqueID() const { return UniqueID; }
+
+ const MCSectionELF *getAssociatedSection() const { return Associated; }
static bool classof(const MCSection *S) {
return S->getVariant() == SV_ELF;
}
-
- // Return the entry size for sections with fixed-width data.
- static unsigned DetermineEntrySize(SectionKind Kind);
-
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h
index a5a2089a2974f..97227517c82d6 100644
--- a/include/llvm/MC/MCSectionMachO.h
+++ b/include/llvm/MC/MCSectionMachO.h
@@ -35,8 +35,8 @@ class MCSectionMachO : public MCSection {
/// size of stubs, for example.
unsigned Reserved2;
- MCSectionMachO(StringRef Segment, StringRef Section,
- unsigned TAA, unsigned reserved2, SectionKind K);
+ MCSectionMachO(StringRef Segment, StringRef Section, unsigned TAA,
+ unsigned reserved2, SectionKind K, MCSymbol *Begin);
friend class MCContext;
public:
@@ -53,14 +53,6 @@ public:
return StringRef(SectionName);
}
- std::string getLabelBeginName() const override {
- return StringRef(getSegmentName().str() + getSectionName().str() + "_begin");
- }
-
- std::string getLabelEndName() const override {
- return StringRef(getSegmentName().str() + getSectionName().str() + "_end");
- }
-
unsigned getTypeAndAttributes() const { return TypeAndAttributes; }
unsigned getStubSize() const { return Reserved2; }
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 18855f9cf03d8..957913e934c4a 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -16,12 +16,12 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCLinkerOptimizationHint.h"
#include "llvm/MC/MCWinEH.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/SMLoc.h"
#include <string>
namespace llvm {
@@ -42,7 +42,7 @@ class raw_ostream;
class formatted_raw_ostream;
class AssemblerConstantPools;
-typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair;
+typedef std::pair<MCSection *, const MCExpr *> MCSectionSubPair;
/// Target specific streamer interface. This is used so that targets can
/// implement support for target specific assembly directives.
@@ -87,35 +87,12 @@ public:
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();
-
- /// Callback used to implement the .inst directive.
- virtual void emitInst(uint32_t Inst);
-
-private:
- std::unique_ptr<AssemblerConstantPools> ConstantPools;
-};
-
// FIXME: declared here because it is used from
// lib/CodeGen/AsmPrinter/ARMException.cpp.
class ARMTargetStreamer : public MCTargetStreamer {
public:
ARMTargetStreamer(MCStreamer &S);
- ~ARMTargetStreamer();
+ ~ARMTargetStreamer() override;
virtual void emitFnStart();
virtual void emitFnEnd();
@@ -139,6 +116,7 @@ public:
StringRef StringValue = "");
virtual void emitFPU(unsigned FPU);
virtual void emitArch(unsigned Arch);
+ virtual void emitArchExtension(unsigned ArchExt);
virtual void emitObjectArch(unsigned Arch);
virtual void finishAttributeSection();
virtual void emitInst(uint32_t Inst, char Suffix = '\0');
@@ -162,11 +140,12 @@ private:
std::unique_ptr<AssemblerConstantPools> ConstantPools;
};
-/// MCStreamer - Streaming machine code generation interface. This interface
-/// is intended to provide a programatic interface that is very similar to the
-/// level that an assembler .s file provides. It has callbacks to emit bytes,
-/// handle directives, etc. The implementation of this interface retains
-/// state to know what the current section is etc.
+/// \brief Streaming machine code generation interface.
+///
+/// This interface is intended to provide a programatic interface that is very
+/// similar to the level that an assembler .s file provides. It has callbacks
+/// to emit bytes, handle directives, etc. The implementation of this interface
+/// retains state to know what the current section is etc.
///
/// There are multiple implementations of this interface: one for writing out
/// a .s file, and implementations that write out .o files of various formats.
@@ -175,8 +154,8 @@ class MCStreamer {
MCContext &Context;
std::unique_ptr<MCTargetStreamer> TargetStreamer;
- MCStreamer(const MCStreamer &) LLVM_DELETED_FUNCTION;
- MCStreamer &operator=(const MCStreamer &) LLVM_DELETED_FUNCTION;
+ MCStreamer(const MCStreamer &) = delete;
+ MCStreamer &operator=(const MCStreamer &) = delete;
std::vector<MCDwarfFrameInfo> DwarfFrameInfos;
MCDwarfFrameInfo *getCurrentDwarfFrameInfo();
@@ -188,12 +167,12 @@ class MCStreamer {
WinEH::FrameInfo *CurrentWinFrameInfo;
void EnsureValidWinFrameInfo();
- // SymbolOrdering - Tracks an index to represent the order
- // a symbol was emitted in. Zero means we did not emit that symbol.
+ /// \brief Tracks an index to represent the order a symbol was emitted in.
+ /// Zero means we did not emit that symbol.
DenseMap<const MCSymbol *, unsigned> SymbolOrdering;
- /// SectionStack - This is stack of current and previous section
- /// values saved by PushSection.
+ /// \brief This is stack of current and previous section values saved by
+ /// PushSection.
SmallVector<std::pair<MCSectionSubPair, MCSectionSubPair>, 4> SectionStack;
protected:
@@ -242,22 +221,24 @@ public:
void generateCompactUnwindEncodings(MCAsmBackend *MAB);
- /// @name Assembly File Formatting.
+ /// \name Assembly File Formatting.
/// @{
- /// isVerboseAsm - Return true if this streamer supports verbose assembly
- /// and if it is enabled.
+ /// \brief Return true if this streamer supports verbose assembly and if it is
+ /// enabled.
virtual bool isVerboseAsm() const { return false; }
- /// hasRawTextSupport - Return true if this asm streamer supports emitting
- /// unformatted text to the .s file with EmitRawText.
+ /// \brief Return true if this asm streamer supports emitting unformatted text
+ /// to the .s file with EmitRawText.
virtual bool hasRawTextSupport() const { return false; }
- /// Is the integrated assembler required for this streamer to function
+ /// \brief 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
+ /// \brief Add a textual command.
+ ///
+ /// Typically for comments that can be emitted to the generated .s
/// file if applicable as a QoI issue to make the output of the compiler
/// more readable. This only affects the MCAsmStreamer, and only when
/// verbose assembly output is enabled.
@@ -266,14 +247,14 @@ public:
/// prefix as appropriate. The added comment should not end with a \n.
virtual void AddComment(const Twine &T) {}
- /// GetCommentOS - Return a raw_ostream that comments can be written to.
- /// Unlike AddComment, you are required to terminate comments with \n if you
- /// use this method.
+ /// \brief Return a raw_ostream that comments can be written to. Unlike
+ /// AddComment, you are required to terminate comments with \n if you use this
+ /// method.
virtual raw_ostream &GetCommentOS();
- /// 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
+ /// \brief 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);
@@ -282,46 +263,43 @@ public:
/// @}
- /// @name Symbol & Section Management
+ /// \name Symbol & Section Management
/// @{
- /// getCurrentSection - Return the current section that the streamer is
- /// emitting code to.
+ /// \brief Return the current section that the streamer is emitting code to.
MCSectionSubPair getCurrentSection() const {
if (!SectionStack.empty())
return SectionStack.back().first;
return MCSectionSubPair();
}
- /// getPreviousSection - Return the previous section that the streamer is
- /// emitting code to.
+ /// \brief Return the previous section that the streamer is emitting code to.
MCSectionSubPair getPreviousSection() const {
if (!SectionStack.empty())
return SectionStack.back().second;
return MCSectionSubPair();
}
- /// GetSymbolOrder - Returns an index to represent the order
- /// a symbol was emitted in. (zero if we did not emit that symbol)
+ /// \brief Returns an index to represent the order a symbol was emitted in.
+ /// (zero if we did not emit that symbol)
unsigned GetSymbolOrder(const MCSymbol *Sym) const {
return SymbolOrdering.lookup(Sym);
}
- /// ChangeSection - Update streamer for a new active section.
+ /// \brief Update streamer for a new active section.
///
/// This is called by PopSection and SwitchSection, if the current
/// section changes.
- virtual void ChangeSection(const MCSection *, const MCExpr *);
+ virtual void ChangeSection(MCSection *, const MCExpr *);
- /// pushSection - Save the current and previous section on the
- /// section stack.
+ /// \brief Save the current and previous section on the section stack.
void PushSection() {
SectionStack.push_back(
std::make_pair(getCurrentSection(), getPreviousSection()));
}
- /// popSection - Restore the current and previous section from
- /// the section stack. Calls ChangeSection as needed.
+ /// \brief Restore the current and previous section from the section stack.
+ /// Calls ChangeSection as needed.
///
/// Returns false if the stack was empty.
bool PopSection() {
@@ -343,25 +321,17 @@ public:
return true;
}
- /// SwitchSection - Set the current section where code is being emitted to
- /// @p Section. This is required to update CurSection.
+ /// Set the current section where code is being emitted to \p Section. This
+ /// is required to update CurSection.
///
/// This corresponds to assembler directives like .section, .text, etc.
- virtual void SwitchSection(const MCSection *Section,
- const MCExpr *Subsection = nullptr) {
- assert(Section && "Cannot switch to a null section!");
- MCSectionSubPair curSection = SectionStack.back().first;
- SectionStack.back().second = curSection;
- if (MCSectionSubPair(Section, Subsection) != curSection) {
- SectionStack.back().first = MCSectionSubPair(Section, Subsection);
- ChangeSection(Section, Subsection);
- }
- }
+ virtual void SwitchSection(MCSection *Section,
+ const MCExpr *Subsection = nullptr);
- /// SwitchSectionNoChange - Set the current section where code is being
- /// emitted to @p Section. This is required to update CurSection. This
- /// version does not call ChangeSection.
- void SwitchSectionNoChange(const MCSection *Section,
+ /// \brief Set the current section where code is being emitted to \p Section.
+ /// This is required to update CurSection. This version does not call
+ /// ChangeSection.
+ void SwitchSectionNoChange(MCSection *Section,
const MCExpr *Subsection = nullptr) {
assert(Section && "Cannot switch to a null section!");
MCSectionSubPair curSection = SectionStack.back().first;
@@ -370,21 +340,23 @@ public:
SectionStack.back().first = MCSectionSubPair(Section, Subsection);
}
- /// Create the default sections and set the initial one.
+ /// \brief Create the default sections and set the initial one.
virtual void InitSections(bool NoExecStack);
- /// AssignSection - Sets the symbol's section.
+ MCSymbol *endSection(MCSection *Section);
+
+ /// \brief Sets the symbol's section.
///
/// Each emitted symbol will be tracked in the ordering table,
/// so we can sort on them later.
- void AssignSection(MCSymbol *Symbol, const MCSection *Section);
+ void AssignSection(MCSymbol *Symbol, MCSection *Section);
- /// EmitLabel - Emit a label for @p Symbol into the current section.
+ /// \brief Emit a label for \p Symbol into the current section.
///
/// This corresponds to an assembler statement such as:
/// foo:
///
- /// @param Symbol - The symbol to emit. A given symbol should only be
+ /// \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
@@ -393,25 +365,25 @@ public:
virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol);
- /// EmitAssemblerFlag - Note in the output the specified @p Flag.
+ /// \brief Note in the output the specified \p Flag.
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
- /// EmitLinkerOptions - Emit the given list @p Options of strings as linker
+ /// \brief Emit the given list \p Options of strings as linker
/// options into the output.
virtual void EmitLinkerOptions(ArrayRef<std::string> Kind) {}
- /// EmitDataRegion - Note in the output the specified region @p Kind.
+ /// \brief Note in the output the specified region \p Kind.
virtual void EmitDataRegion(MCDataRegionType Kind) {}
- /// EmitVersionMin - Specify the MachO minimum deployment target version.
+ /// \brief 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).
+ /// \brief Note in the output that the specified \p Func is a Thumb mode
+ /// function (ARM target only).
virtual void EmitThumbFunc(MCSymbol *Func);
- /// EmitAssignment - Emit an assignment of @p Value to @p Symbol.
+ /// \brief Emit an assignment of \p Value to \p Symbol.
///
/// This corresponds to an assembler statement such as:
/// symbol = value
@@ -420,133 +392,131 @@ public:
/// value in the current context. For the assembly streamer, this prints the
/// binding into the .s file.
///
- /// @param Symbol - The symbol being assigned to.
- /// @param Value - The value for the symbol.
+ /// \param Symbol - The symbol being assigned to.
+ /// \param Value - The value for the symbol.
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
- /// EmitWeakReference - Emit an weak reference from @p Alias to @p Symbol.
+ /// \brief Emit an weak reference from \p Alias to \p Symbol.
///
/// This corresponds to an assembler statement such as:
/// .weakref alias, symbol
///
- /// @param Alias - The alias that is being created.
- /// @param Symbol - The symbol being aliased.
+ /// \param Alias - The alias that is being created.
+ /// \param Symbol - The symbol being aliased.
virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
- /// EmitSymbolAttribute - Add the given @p Attribute to @p Symbol.
+ /// \brief Add the given \p Attribute to \p Symbol.
virtual bool EmitSymbolAttribute(MCSymbol *Symbol,
MCSymbolAttr Attribute) = 0;
- /// EmitSymbolDesc - Set the @p DescValue for the @p Symbol.
+ /// \brief Set the \p DescValue for the \p Symbol.
///
- /// @param Symbol - The symbol to have its n_desc field set.
- /// @param DescValue - The value to set into the n_desc field.
+ /// \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);
- /// BeginCOFFSymbolDef - Start emitting COFF symbol definition
+ /// \brief Start emitting COFF symbol definition
///
- /// @param Symbol - The symbol to have its External & Type fields set.
+ /// \param Symbol - The symbol to have its External & Type fields set.
virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
- /// EmitCOFFSymbolStorageClass - Emit the storage class of the symbol.
+ /// \brief Emit the storage class of the symbol.
///
- /// @param StorageClass - The storage class the symbol should have.
+ /// \param StorageClass - The storage class the symbol should have.
virtual void EmitCOFFSymbolStorageClass(int StorageClass);
- /// EmitCOFFSymbolType - Emit the type of the symbol.
+ /// \brief Emit the type of the symbol.
///
- /// @param Type - A COFF type identifier (see COFF::SymbolType in X86COFF.h)
+ /// \param Type - A COFF type identifier (see COFF::SymbolType in X86COFF.h)
virtual void EmitCOFFSymbolType(int Type);
- /// EndCOFFSymbolDef - Marks the end of the symbol definition.
+ /// \brief Marks the end of the symbol definition.
virtual void EndCOFFSymbolDef();
- /// EmitCOFFSectionIndex - Emits a COFF section index.
+ /// \brief Emits a COFF section index.
///
- /// @param Symbol - Symbol the section number relocation should point to.
+ /// \param Symbol - Symbol the section number relocation should point to.
virtual void EmitCOFFSectionIndex(MCSymbol const *Symbol);
- /// EmitCOFFSecRel32 - Emits a COFF section relative relocation.
+ /// \brief Emits a COFF section relative relocation.
///
- /// @param Symbol - Symbol the section relative relocation 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.
+ /// \brief Emit an ELF .size directive.
///
/// This corresponds to an assembler statement such as:
/// .size symbol, expression
- ///
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.
+ /// \brief Emit a common symbol.
///
- /// @param Symbol - The common symbol to emit.
- /// @param Size - The size of the common symbol.
- /// @param ByteAlignment - The alignment of the symbol if
+ /// \param Symbol - The common symbol to emit.
+ /// \param Size - The size of the common symbol.
+ /// \param ByteAlignment - The alignment of the symbol if
/// non-zero. This must be a power of 2.
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) = 0;
- /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
+ /// \brief Emit a local common (.lcomm) symbol.
///
- /// @param Symbol - The common symbol to emit.
- /// @param Size - The size of the common symbol.
- /// @param ByteAlignment - The alignment of the common symbol in bytes.
+ /// \param Symbol - The common symbol to emit.
+ /// \param Size - The size of the common symbol.
+ /// \param ByteAlignment - The alignment of the common symbol in bytes.
virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment);
- /// EmitZerofill - Emit the zerofill section and an optional symbol.
+ /// \brief Emit the zerofill section and an optional symbol.
///
- /// @param Section - The zerofill section to create and or to put the symbol
- /// @param Symbol - The zerofill symbol to emit, if non-NULL.
- /// @param Size - The size of the zerofill symbol.
- /// @param ByteAlignment - The alignment of the zerofill symbol if
+ /// \param Section - The zerofill section to create and or to put the symbol
+ /// \param Symbol - The zerofill symbol to emit, if non-NULL.
+ /// \param Size - The size of the zerofill symbol.
+ /// \param ByteAlignment - The alignment of the zerofill symbol if
/// non-zero. This must be a power of 2 on some targets.
- virtual void EmitZerofill(const MCSection *Section,
- MCSymbol *Symbol = nullptr, uint64_t Size = 0,
- unsigned ByteAlignment = 0) = 0;
+ virtual void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
+ uint64_t Size = 0, unsigned ByteAlignment = 0) = 0;
- /// EmitTBSSSymbol - Emit a thread local bss (.tbss) symbol.
+ /// \brief Emit a thread local bss (.tbss) symbol.
///
- /// @param Section - The thread local common section.
- /// @param Symbol - The thread local common symbol to emit.
- /// @param Size - The size of the symbol.
- /// @param ByteAlignment - The alignment of the thread local common symbol
+ /// \param Section - The thread local common section.
+ /// \param Symbol - The thread local common symbol to emit.
+ /// \param Size - The size of the symbol.
+ /// \param ByteAlignment - The alignment of the thread local common symbol
/// if non-zero. This must be a power of 2 on some targets.
- virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
+ virtual void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment = 0);
/// @}
- /// @name Generating Data
+ /// \name Generating Data
/// @{
- /// EmitBytes - Emit the bytes in \p Data into the output.
+ /// \brief Emit the bytes in \p Data into the output.
///
/// This is used to implement assembler directives such as .byte, .ascii,
/// etc.
virtual void EmitBytes(StringRef Data);
- /// EmitValue - Emit the expression @p Value into the output as a native
- /// integer of the given @p Size bytes.
+ /// \brief Emit the expression \p Value into the output as a native
+ /// integer of the given \p Size bytes.
///
/// This is used to implement assembler directives such as .word, .quad,
/// etc.
///
- /// @param Value - The value to emit.
- /// @param Size - The size of the integer (in bytes) to emit. This must
+ /// \param Value - The value to emit.
+ /// \param Size - The size of the integer (in bytes) to emit. This must
/// match a native machine width.
- /// @param Loc - The location of the expression for error reporting.
+ /// \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,
const SMLoc &Loc = SMLoc());
- /// EmitIntValue - Special case of EmitValue that avoids the client having
+ /// \brief Special case of EmitValue that avoids the client having
/// to pass in a MCExpr for constant integers.
virtual void EmitIntValue(uint64_t Value, unsigned Size);
@@ -554,112 +524,119 @@ public:
virtual void EmitSLEB128Value(const MCExpr *Value);
- /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
- /// client having to pass in a MCExpr for constant integers.
+ /// \brief Special case of EmitULEB128Value that avoids the client having to
+ /// pass in a MCExpr for constant integers.
void EmitULEB128IntValue(uint64_t Value, unsigned Padding = 0);
- /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
- /// client having to pass in a MCExpr for constant integers.
+ /// \brief Special case of EmitSLEB128Value that avoids the client having to
+ /// pass in a MCExpr for constant integers.
void EmitSLEB128IntValue(int64_t Value);
- /// EmitSymbolValue - Special case of EmitValue that avoids the client
- /// having to pass in a MCExpr for MCSymbols.
+ /// \brief Special case of EmitValue that avoids the client having to pass in
+ /// a MCExpr for MCSymbols.
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.
+ /// \brief Emit the expression \p Value into the output as a gprel64 (64-bit
+ /// GP relative) value.
///
/// This is used to implement assembler directives such as .gpdword on
/// targets that support them.
virtual void EmitGPRel64Value(const MCExpr *Value);
- /// EmitGPRel32Value - Emit the expression @p Value into the output as a
- /// gprel32 (32-bit GP relative) value.
+ /// \brief Emit the expression \p Value into the output as a gprel32 (32-bit
+ /// GP relative) value.
///
/// This is used to implement assembler directives such as .gprel32 on
/// targets that support them.
virtual void EmitGPRel32Value(const MCExpr *Value);
- /// EmitFill - Emit NumBytes bytes worth of the value specified by
- /// FillValue. This implements directives such as '.space'.
+ /// \brief Emit NumBytes bytes worth of the value specified by FillValue.
+ /// This implements directives such as '.space'.
virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue);
/// \brief Emit NumBytes worth of zeros.
/// This function properly handles data in virtual sections.
virtual void EmitZeros(uint64_t NumBytes);
- /// EmitValueToAlignment - Emit some number of copies of @p Value until
- /// the byte alignment @p ByteAlignment is reached.
+ /// \brief Emit some number of copies of \p Value until the byte alignment \p
+ /// ByteAlignment is reached.
///
/// If the number of bytes need to emit for the alignment is not a multiple
- /// of @p ValueSize, then the contents of the emitted fill bytes is
+ /// of \p ValueSize, then the contents of the emitted fill bytes is
/// undefined.
///
/// This used to implement the .align assembler directive.
///
- /// @param ByteAlignment - The alignment to reach. This must be a power of
+ /// \param ByteAlignment - The alignment to reach. This must be a power of
/// two on some targets.
- /// @param Value - The value to use when filling bytes.
- /// @param ValueSize - The size of the integer (in bytes) to emit for
- /// @p Value. This must match a native machine width.
- /// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
+ /// \param Value - The value to use when filling bytes.
+ /// \param ValueSize - The size of the integer (in bytes) to emit for
+ /// \p Value. This must match a native machine width.
+ /// \param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
/// the alignment cannot be reached in this many bytes, no bytes are
/// emitted.
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0);
- /// EmitCodeAlignment - Emit nops until the byte alignment @p ByteAlignment
- /// is reached.
+ /// \brief Emit nops until the byte alignment \p ByteAlignment is reached.
///
/// This used to align code where the alignment bytes may be executed. This
/// can emit different bytes for different sizes to optimize execution.
///
- /// @param ByteAlignment - The alignment to reach. This must be a power of
+ /// \param ByteAlignment - The alignment to reach. This must be a power of
/// two on some targets.
- /// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
+ /// \param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
/// the alignment cannot be reached in this many bytes, no bytes are
/// emitted.
virtual void EmitCodeAlignment(unsigned ByteAlignment,
unsigned MaxBytesToEmit = 0);
- /// EmitValueToOffset - Emit some number of copies of @p Value until the
- /// byte offset @p Offset is reached.
+ /// \brief Emit some number of copies of \p Value until the byte offset \p
+ /// Offset is reached.
///
/// This is used to implement assembler directives such as .org.
///
- /// @param Offset - The offset to reach. This may be an expression, but the
+ /// \param Offset - The offset to reach. This may be an expression, but the
/// expression must be associated with the current section.
- /// @param Value - The value to use when filling bytes.
- /// @return false on success, true if the offset was invalid.
+ /// \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);
/// @}
- /// EmitFileDirective - Switch to a new logical file. This is used to
- /// implement the '.file "foo.c"' assembler directive.
+ /// \brief Switch to a new logical file. This is used to implement the '.file
+ /// "foo.c"' assembler directive.
virtual void EmitFileDirective(StringRef Filename);
- /// Emit the "identifiers" directive. This implements the
+ /// \brief Emit the "identifiers" directive. This implements the
/// '.ident "version foo"' assembler directive.
virtual void EmitIdent(StringRef IdentString) {}
- /// EmitDwarfFileDirective - Associate a filename with a specified logical
- /// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler
- /// directive.
+ /// \brief Associate a filename with a specified logical file number. This
+ /// implements the DWARF2 '.file 4 "foo.c"' assembler directive.
virtual unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename,
unsigned CUID = 0);
- /// EmitDwarfLocDirective - This implements the DWARF2
- // '.loc fileno lineno ...' assembler directive.
+ /// \brief This implements the DWARF2 '.loc fileno lineno ...' assembler
+ /// directive.
virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
unsigned Column, unsigned Flags,
unsigned Isa, unsigned Discriminator,
StringRef FileName);
+ /// Emit the absolute difference between two symbols if possible.
+ ///
+ /// \pre Offset of \c Hi is greater than the offset \c Lo.
+ /// \return true on success.
+ virtual bool emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
+ unsigned Size) {
+ return false;
+ }
+
virtual MCSymbol *getDwarfLineTableSymbol(unsigned CUID);
virtual void EmitCFISections(bool EH, bool Debug);
void EmitCFIStartProc(bool IsSimple);
@@ -697,8 +674,7 @@ public:
virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except);
virtual void EmitWinEHHandlerData();
- /// EmitInstruction - Emit the given @p Instruction into the current
- /// section.
+ /// \brief Emit the given \p Instruction into the current section.
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI);
/// \brief Set the bundle alignment mode from now on in the section.
@@ -715,29 +691,28 @@ public:
/// \brief Ends a bundle-locked group.
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
- /// indicated by the hasRawTextSupport() predicate. By default this aborts.
+ /// \brief If this file is backed by a assembly streamer, this dumps the
+ /// specified string in the output .s file. This capability is indicated by
+ /// the hasRawTextSupport() predicate. By default this aborts.
void EmitRawText(const Twine &String);
- /// Flush - Causes any cached state to be written out.
+ /// \brief Causes any cached state to be written out.
virtual void Flush() {}
- /// FinishImpl - Streamer specific finalization.
+ /// \brief Streamer specific finalization.
virtual void FinishImpl();
- /// Finish - Finish emission of machine code.
+ /// \brief Finish emission of machine code.
void Finish();
- virtual bool mayHaveInstructions() const { return true; }
+ virtual bool mayHaveInstructions(MCSection &Sec) const { return true; }
};
-/// createNullStreamer - Create a dummy machine code streamer, which does
-/// nothing. This is useful for timing the assembler front end.
+/// Create a dummy machine code streamer, which does nothing. This is useful for
+/// timing the assembler front end.
MCStreamer *createNullStreamer(MCContext &Ctx);
-/// createAsmStreamer - Create a machine code streamer which will print out
-/// assembly for the native target, suitable for compiling with a native
-/// assembler.
+/// Create a machine code streamer which will print out assembly for the native
+/// target, suitable for compiling with a native assembler.
///
/// \param InstPrint - If given, the instruction printer to use. If not given
/// the MCInst representation will be printed. This method takes ownership of
@@ -752,26 +727,11 @@ MCStreamer *createNullStreamer(MCContext &Ctx);
///
/// \param ShowInst - Whether to show the MCInst representation inline with
/// the assembly.
-MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+MCStreamer *createAsmStreamer(MCContext &Ctx,
+ std::unique_ptr<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.
-///
-/// Takes ownership of \p TAB and \p CE.
-MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *CE,
- bool RelaxAll = false,
- bool LabelSections = false);
-
-/// createELFStreamer - Create a machine code streamer which will generate
-/// ELF format object files.
-MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *CE,
- bool RelaxAll);
-
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h
index 3f38bd59a5766..1778a6d13fb86 100644
--- a/include/llvm/MC/MCSubtargetInfo.h
+++ b/include/llvm/MC/MCSubtargetInfo.h
@@ -28,6 +28,7 @@ class StringRef;
///
class MCSubtargetInfo {
std::string TargetTriple; // Target triple
+ std::string CPU; // CPU being targeted.
ArrayRef<SubtargetFeatureKV> ProcFeatures; // Processor feature list
ArrayRef<SubtargetFeatureKV> ProcDesc; // Processor descriptions
@@ -41,7 +42,7 @@ class MCSubtargetInfo {
const InstrStage *Stages; // Instruction itinerary stages
const unsigned *OperandCycles; // Itinerary operand cycles
const unsigned *ForwardingPaths; // Forwarding paths
- uint64_t FeatureBits; // Feature bits for current CPU + FS
+ FeatureBitset FeatureBits; // Feature bits for current CPU + FS
public:
void InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
@@ -59,15 +60,20 @@ public:
return TargetTriple;
}
+ /// getCPU - Return the CPU string.
+ StringRef getCPU() const {
+ return CPU;
+ }
+
/// getFeatureBits - Return the feature bits.
///
- uint64_t getFeatureBits() const {
+ const FeatureBitset& getFeatureBits() const {
return FeatureBits;
}
/// setFeatureBits - Set the feature bits.
///
- void setFeatureBits(uint64_t FeatureBits_) { FeatureBits = FeatureBits_; }
+ void setFeatureBits(FeatureBitset& FeatureBits_) { FeatureBits = FeatureBits_; }
/// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with
/// feature string). Recompute feature bits and scheduling model.
@@ -78,11 +84,15 @@ public:
/// ToggleFeature - Toggle a feature and returns the re-computed feature
/// bits. This version does not change the implied bits.
- uint64_t ToggleFeature(uint64_t FB);
+ FeatureBitset ToggleFeature(uint64_t FB);
/// ToggleFeature - Toggle a feature and returns the re-computed feature
- /// bits. This version will also change all implied bits.
- uint64_t ToggleFeature(StringRef FS);
+ /// bits. This version does not change the implied bits.
+ FeatureBitset ToggleFeature(const FeatureBitset& FB);
+
+ /// ToggleFeature - Toggle a set of features and returns the re-computed
+ /// feature bits. This version will also change all implied bits.
+ FeatureBitset ToggleFeature(StringRef FS);
/// getSchedModelForCPU - Get the machine model of a CPU.
///
diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h
index 47a8789d463b7..cf99c919281e2 100644
--- a/include/llvm/MC/MCSymbol.h
+++ b/include/llvm/MC/MCSymbol.h
@@ -14,168 +14,298 @@
#ifndef LLVM_MC_MCSYMBOL_H
#define LLVM_MC_MCSYMBOL_H
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
- class MCExpr;
- class MCSection;
- class MCContext;
- class raw_ostream;
-
- /// MCSymbol - Instances of this class represent a symbol name in the MC file,
- /// and MCSymbols are created and unique'd by the MCContext class. MCSymbols
- /// should only be constructed with valid names for the object file.
+class MCExpr;
+class MCSymbol;
+class MCFragment;
+class MCSection;
+class MCContext;
+class raw_ostream;
+
+// TODO: Merge completely with MCSymbol.
+class MCSymbolData {
+ /// Fragment - The fragment this symbol's value is relative to, if any. Also
+ /// stores if this symbol is visible outside this translation unit (bit 0) or
+ /// if it is private extern (bit 1).
+ PointerIntPair<MCFragment *, 2> Fragment;
+
+ union {
+ /// Offset - The offset to apply to the fragment address to form this
+ /// symbol's value.
+ uint64_t Offset;
+
+ /// CommonSize - The size of the symbol, if it is 'common'.
+ uint64_t CommonSize;
+ };
+
+ /// SymbolSize - An expression describing how to calculate the size of
+ /// a symbol. If a symbol has no size this field will be NULL.
+ const MCExpr *SymbolSize = nullptr;
+
+ /// CommonAlign - The alignment of the symbol, if it is 'common', or -1.
+ //
+ // FIXME: Pack this in with other fields?
+ unsigned CommonAlign = -1U;
+
+ /// Flags - The Flags field is used by object file implementations to store
+ /// additional per symbol information which is not easily classified.
+ uint32_t Flags = 0;
+
+public:
+ MCSymbolData() { Offset = 0; }
+
+ MCFragment *getFragment() const { return Fragment.getPointer(); }
+ void setFragment(MCFragment *Value) { Fragment.setPointer(Value); }
+
+ uint64_t getOffset() const {
+ assert(!isCommon());
+ return Offset;
+ }
+ void setOffset(uint64_t Value) {
+ assert(!isCommon());
+ Offset = Value;
+ }
+
+ /// @}
+ /// \name Symbol Attributes
+ /// @{
+
+ bool isExternal() const { return Fragment.getInt() & 1; }
+ void setExternal(bool Value) {
+ Fragment.setInt((Fragment.getInt() & ~1) | unsigned(Value));
+ }
+
+ bool isPrivateExtern() const { return Fragment.getInt() & 2; }
+ void setPrivateExtern(bool Value) {
+ Fragment.setInt((Fragment.getInt() & ~2) | (unsigned(Value) << 1));
+ }
+
+ /// isCommon - Is this a 'common' symbol.
+ bool isCommon() const { return CommonAlign != -1U; }
+
+ /// setCommon - Mark this symbol as being 'common'.
///
- /// If the symbol is defined/emitted into the current translation unit, the
- /// Section member is set to indicate what section it lives in. Otherwise, if
- /// it is a reference to an external entity, it has a null section.
- class MCSymbol {
- // Special sentinal value for the absolute pseudo section.
- //
- // FIXME: Use a PointerInt wrapper for this?
- static const MCSection *AbsolutePseudoSection;
-
- /// Name - The name of the symbol. The referred-to string data is actually
- /// held by the StringMap that lives in MCContext.
- StringRef Name;
-
- /// Section - The section the symbol is defined in. This is null for
- /// undefined symbols, and the special AbsolutePseudoSection value for
- /// absolute symbols.
- const MCSection *Section;
-
- /// Value - If non-null, the value for a variable symbol.
- const MCExpr *Value;
-
- /// IsTemporary - True if this is an assembler temporary label, which
- /// typically does not survive in the .o file's symbol table. Usually
- /// "Lfoo" or ".foo".
- unsigned IsTemporary : 1;
-
- /// \brief True if this symbol can be redefined.
- unsigned IsRedefinable : 1;
-
- /// IsUsed - True if this symbol has been used.
- mutable unsigned IsUsed : 1;
-
- private: // MCContext creates and uniques these.
- friend class MCExpr;
- friend class MCContext;
- MCSymbol(StringRef name, bool isTemporary)
- : Name(name), Section(nullptr), Value(nullptr),
- IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false) {}
-
- MCSymbol(const MCSymbol&) LLVM_DELETED_FUNCTION;
- void operator=(const MCSymbol&) LLVM_DELETED_FUNCTION;
- public:
- /// getName - Get the symbol name.
- StringRef getName() const { return Name; }
-
- /// @name Accessors
- /// @{
-
- /// isTemporary - Check if this is an assembler temporary symbol.
- bool isTemporary() const { return IsTemporary; }
-
- /// isUsed - Check if this is used.
- bool isUsed() const { return IsUsed; }
- void setUsed(bool Value) const { IsUsed = Value; }
-
- /// \brief Check if this symbol is redefinable.
- bool isRedefinable() const { return IsRedefinable; }
- /// \brief Mark this symbol as redefinable.
- void setRedefinable(bool Value) { IsRedefinable = Value; }
- /// \brief Prepare this symbol to be redefined.
- void redefineIfPossible() {
- if (IsRedefinable) {
- Value = nullptr;
- Section = nullptr;
- IsRedefinable = false;
- }
- }
+ /// \param Size - The size of the symbol.
+ /// \param Align - The alignment of the symbol.
+ void setCommon(uint64_t Size, unsigned Align) {
+ assert(getOffset() == 0);
+ CommonSize = Size;
+ CommonAlign = Align;
+ }
- /// @}
- /// @name Associated Sections
- /// @{
+ /// getCommonSize - Return the size of a 'common' symbol.
+ uint64_t getCommonSize() const {
+ assert(isCommon() && "Not a 'common' symbol!");
+ return CommonSize;
+ }
- /// isDefined - Check if this symbol is defined (i.e., it has an address).
- ///
- /// Defined symbols are either absolute or in some section.
- bool isDefined() const {
- return Section != nullptr;
- }
+ void setSize(const MCExpr *SS) { SymbolSize = SS; }
- /// isInSection - Check if this symbol is defined in some section (i.e., it
- /// is defined but not absolute).
- bool isInSection() const {
- return isDefined() && !isAbsolute();
- }
+ const MCExpr *getSize() const { return SymbolSize; }
- /// isUndefined - Check if this symbol undefined (i.e., implicitly defined).
- bool isUndefined() const {
- return !isDefined();
- }
+ /// getCommonAlignment - Return the alignment of a 'common' symbol.
+ unsigned getCommonAlignment() const {
+ assert(isCommon() && "Not a 'common' symbol!");
+ return CommonAlign;
+ }
- /// isAbsolute - Check if this is an absolute symbol.
- bool isAbsolute() const {
- return Section == AbsolutePseudoSection;
- }
+ /// getFlags - Get the (implementation defined) symbol flags.
+ uint32_t getFlags() const { return Flags; }
- /// getSection - Get the section associated with a defined, non-absolute
- /// symbol.
- const MCSection &getSection() const {
- assert(isInSection() && "Invalid accessor!");
- return *Section;
- }
+ /// setFlags - Set the (implementation defined) symbol flags.
+ void setFlags(uint32_t Value) { Flags = Value; }
- /// setSection - Mark the symbol as defined in the section \p S.
- void setSection(const MCSection &S) { Section = &S; }
+ /// modifyFlags - Modify the flags via a mask
+ void modifyFlags(uint32_t Value, uint32_t Mask) {
+ Flags = (Flags & ~Mask) | Value;
+ }
+
+ /// @}
+
+ void dump() const;
+};
+
+/// MCSymbol - Instances of this class represent a symbol name in the MC file,
+/// and MCSymbols are created and uniqued by the MCContext class. MCSymbols
+/// should only be constructed with valid names for the object file.
+///
+/// If the symbol is defined/emitted into the current translation unit, the
+/// Section member is set to indicate what section it lives in. Otherwise, if
+/// it is a reference to an external entity, it has a null section.
+class MCSymbol {
+ // Special sentinal value for the absolute pseudo section.
+ //
+ // FIXME: Use a PointerInt wrapper for this?
+ static MCSection *AbsolutePseudoSection;
+
+ /// Name - The name of the symbol. The referred-to string data is actually
+ /// held by the StringMap that lives in MCContext.
+ const StringMapEntry<bool> *Name;
+
+ /// The section the symbol is defined in. This is null for undefined symbols,
+ /// and the special AbsolutePseudoSection value for absolute symbols. If this
+ /// is a variable symbol, this caches the variable value's section.
+ mutable MCSection *Section;
+
+ /// Value - If non-null, the value for a variable symbol.
+ const MCExpr *Value;
+
+ /// IsTemporary - True if this is an assembler temporary label, which
+ /// typically does not survive in the .o file's symbol table. Usually
+ /// "Lfoo" or ".foo".
+ unsigned IsTemporary : 1;
+
+ /// \brief True if this symbol can be redefined.
+ unsigned IsRedefinable : 1;
+
+ /// IsUsed - True if this symbol has been used.
+ mutable unsigned IsUsed : 1;
+
+ mutable bool HasData : 1;
+
+ /// Index field, for use by the object file implementation.
+ mutable uint64_t Index : 60;
+
+ mutable MCSymbolData Data;
+
+private: // MCContext creates and uniques these.
+ friend class MCExpr;
+ friend class MCContext;
+ MCSymbol(const StringMapEntry<bool> *Name, bool isTemporary)
+ : Name(Name), Section(nullptr), Value(nullptr), IsTemporary(isTemporary),
+ IsRedefinable(false), IsUsed(false), HasData(false), Index(0) {}
+
+ MCSymbol(const MCSymbol &) = delete;
+ void operator=(const MCSymbol &) = delete;
+ MCSection *getSectionPtr() const {
+ if (Section || !Value)
+ return Section;
+ return Section = Value->FindAssociatedSection();
+ }
+
+public:
+ /// getName - Get the symbol name.
+ StringRef getName() const { return Name ? Name->first() : ""; }
+
+ bool hasData() const { return HasData; }
+
+ /// Get associated symbol data.
+ MCSymbolData &getData() const {
+ assert(HasData && "Missing symbol data!");
+ return Data;
+ }
- /// setUndefined - Mark the symbol as undefined.
- void setUndefined() {
+ /// Initialize symbol data.
+ ///
+ /// Nothing really to do here, but this is enables an assertion that \a
+ /// MCAssembler::getOrCreateSymbolData() has actually been called before
+ /// anyone calls \a getData().
+ void initializeData() const { HasData = true; }
+
+ /// \name Accessors
+ /// @{
+
+ /// isTemporary - Check if this is an assembler temporary symbol.
+ bool isTemporary() const { return IsTemporary; }
+
+ /// isUsed - Check if this is used.
+ bool isUsed() const { return IsUsed; }
+ void setUsed(bool Value) const { IsUsed = Value; }
+
+ /// \brief Check if this symbol is redefinable.
+ bool isRedefinable() const { return IsRedefinable; }
+ /// \brief Mark this symbol as redefinable.
+ void setRedefinable(bool Value) { IsRedefinable = Value; }
+ /// \brief Prepare this symbol to be redefined.
+ void redefineIfPossible() {
+ if (IsRedefinable) {
+ Value = nullptr;
Section = nullptr;
+ IsRedefinable = false;
}
+ }
- /// setAbsolute - Mark the symbol as absolute.
- void setAbsolute() { Section = AbsolutePseudoSection; }
+ /// @}
+ /// \name Associated Sections
+ /// @{
- /// @}
- /// @name Variable Symbols
- /// @{
+ /// isDefined - Check if this symbol is defined (i.e., it has an address).
+ ///
+ /// Defined symbols are either absolute or in some section.
+ bool isDefined() const { return getSectionPtr() != nullptr; }
- /// isVariable - Check if this is a variable symbol.
- bool isVariable() const {
- return Value != nullptr;
- }
+ /// isInSection - Check if this symbol is defined in some section (i.e., it
+ /// is defined but not absolute).
+ bool isInSection() const { return isDefined() && !isAbsolute(); }
- /// getVariableValue() - Get the value for variable symbols.
- const MCExpr *getVariableValue() const {
- assert(isVariable() && "Invalid accessor!");
- IsUsed = true;
- return Value;
- }
+ /// isUndefined - Check if this symbol undefined (i.e., implicitly defined).
+ bool isUndefined() const { return !isDefined(); }
- // AliasedSymbol() - If this is an alias (a = b), return the symbol
- // we ultimately point to. For a non-alias, this just returns the symbol
- // itself.
- const MCSymbol &AliasedSymbol() const;
+ /// isAbsolute - Check if this is an absolute symbol.
+ bool isAbsolute() const { return getSectionPtr() == AbsolutePseudoSection; }
- void setVariableValue(const MCExpr *Value);
+ /// Get the section associated with a defined, non-absolute symbol.
+ MCSection &getSection() const {
+ assert(isInSection() && "Invalid accessor!");
+ return *getSectionPtr();
+ }
- /// @}
+ /// Mark the symbol as defined in the section \p S.
+ void setSection(MCSection &S) {
+ assert(!isVariable() && "Cannot set section of variable");
+ Section = &S;
+ }
- /// print - Print the value to the stream \p OS.
- void print(raw_ostream &OS) const;
+ /// setUndefined - Mark the symbol as undefined.
+ void setUndefined() { Section = nullptr; }
- /// dump - Print the value to stderr.
- void dump() const;
- };
+ /// @}
+ /// \name Variable Symbols
+ /// @{
+
+ /// isVariable - Check if this is a variable symbol.
+ bool isVariable() const { return Value != nullptr; }
+
+ /// getVariableValue() - Get the value for variable symbols.
+ const MCExpr *getVariableValue() const {
+ assert(isVariable() && "Invalid accessor!");
+ IsUsed = true;
+ return Value;
+ }
+
+ void setVariableValue(const MCExpr *Value);
- inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) {
- Sym.print(OS);
- return OS;
+ /// @}
+
+ /// Get the (implementation defined) index.
+ uint64_t getIndex() const {
+ assert(HasData && "Uninitialized symbol data");
+ return Index;
+ }
+
+ /// Set the (implementation defined) index.
+ void setIndex(uint64_t Value) const {
+ assert(HasData && "Uninitialized symbol data");
+ assert(!(Value >> 60) && "Not enough bits for value");
+ Index = Value;
}
+
+ /// print - Print the value to the stream \p OS.
+ void print(raw_ostream &OS) const;
+
+ /// dump - Print the value to stderr.
+ void dump() const;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) {
+ Sym.print(OS);
+ return OS;
+}
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCSymbolizer.h b/include/llvm/MC/MCSymbolizer.h
index cbbb591f1b80c..2ef17673f091e 100644
--- a/include/llvm/MC/MCSymbolizer.h
+++ b/include/llvm/MC/MCSymbolizer.h
@@ -38,8 +38,8 @@ class raw_ostream;
/// operands are actually symbolizable, and in what way. I don't think this
/// information exists right now.
class MCSymbolizer {
- MCSymbolizer(const MCSymbolizer &) LLVM_DELETED_FUNCTION;
- void operator=(const MCSymbolizer &) LLVM_DELETED_FUNCTION;
+ MCSymbolizer(const MCSymbolizer &) = delete;
+ void operator=(const MCSymbolizer &) = delete;
protected:
MCContext &Ctx;
@@ -59,14 +59,14 @@ public:
/// represent this immediate in a more understandable way, for instance as a
/// symbol or an offset from a symbol. Relocations can also be used to enrich
/// the symbolic expression.
- /// @param Inst - The MCInst where to insert the symbolic operand.
- /// @param cStream - Stream to print comments and annotations on.
- /// @param Value - Operand value, pc-adjusted by the caller if necessary.
- /// @param Address - Load address of the instruction.
- /// @param IsBranch - Is the instruction a branch?
- /// @param Offset - Byte offset of the operand inside the inst.
- /// @param InstSize - Size of the instruction in bytes.
- /// @return Whether a symbolic operand was added.
+ /// \param Inst - The MCInst where to insert the symbolic operand.
+ /// \param cStream - Stream to print comments and annotations on.
+ /// \param Value - Operand value, pc-adjusted by the caller if necessary.
+ /// \param Address - Load address of the instruction.
+ /// \param IsBranch - Is the instruction a branch?
+ /// \param Offset - Byte offset of the operand inside the inst.
+ /// \param InstSize - Size of the instruction in bytes.
+ /// \return Whether a symbolic operand was added.
virtual bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream,
int64_t Value, uint64_t Address,
bool IsBranch, uint64_t Offset,
diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h
index ea71d1f433a45..36db3914f0174 100644
--- a/include/llvm/MC/MCTargetAsmParser.h
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -75,8 +75,6 @@ struct ParseInstructionInfo {
ParseInstructionInfo() : AsmRewrites(nullptr) {}
ParseInstructionInfo(SmallVectorImpl<AsmRewrite> *rewrites)
: AsmRewrites(rewrites) {}
-
- ~ParseInstructionInfo() {}
};
/// MCTargetAsmParser - Generic interface to target specific assembly parsers.
@@ -91,8 +89,8 @@ public:
};
private:
- MCTargetAsmParser(const MCTargetAsmParser &) LLVM_DELETED_FUNCTION;
- void operator=(const MCTargetAsmParser &) LLVM_DELETED_FUNCTION;
+ MCTargetAsmParser(const MCTargetAsmParser &) = delete;
+ void operator=(const MCTargetAsmParser &) = delete;
protected: // Can only create subclasses.
MCTargetAsmParser();
@@ -110,7 +108,7 @@ protected: // Can only create subclasses.
MCTargetOptions MCOptions;
public:
- virtual ~MCTargetAsmParser();
+ ~MCTargetAsmParser() override;
uint64_t getAvailableFeatures() const { return AvailableFeatures; }
void setAvailableFeatures(uint64_t Value) { AvailableFeatures = Value; }
diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h
index dd86979690cfc..6bdf43685f211 100644
--- a/include/llvm/MC/MCValue.h
+++ b/include/llvm/MC/MCValue.h
@@ -23,10 +23,11 @@ namespace llvm {
class MCAsmInfo;
class raw_ostream;
-/// 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.
+/// \brief 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
@@ -51,13 +52,13 @@ public:
const MCSymbolRefExpr *getSymB() const { return SymB; }
uint32_t getRefKind() const { return RefKind; }
- /// isAbsolute - Is this an absolute (as opposed to relocatable) value.
+ /// \brief Is this an absolute (as opposed to relocatable) value.
bool isAbsolute() const { return !SymA && !SymB; }
- /// print - Print the value to the stream \p OS.
- void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
+ /// \brief Print the value to the stream \p OS.
+ void print(raw_ostream &OS) const;
- /// dump - Print the value to stderr.
+ /// \brief Print the value to stderr.
void dump() const;
MCSymbolRefExpr::VariantKind getAccessVariant() const;
diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h
index dad7bb597039b..e2e95c7df7101 100644
--- a/include/llvm/MC/MCWinCOFFObjectWriter.h
+++ b/include/llvm/MC/MCWinCOFFObjectWriter.h
@@ -11,10 +11,12 @@
#define LLVM_MC_MCWINCOFFOBJECTWRITER_H
namespace llvm {
- class MCFixup;
- class MCObjectWriter;
- class MCValue;
- class raw_ostream;
+class MCAsmBackend;
+class MCFixup;
+class MCObjectWriter;
+class MCValue;
+class raw_ostream;
+class raw_pwrite_stream;
class MCWinCOFFObjectTargetWriter {
virtual void anchor();
@@ -27,9 +29,9 @@ namespace llvm {
virtual ~MCWinCOFFObjectTargetWriter() {}
unsigned getMachine() const { return Machine; }
- virtual unsigned getRelocType(const MCValue &Target,
- const MCFixup &Fixup,
- bool IsCrossSection) const = 0;
+ virtual unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
+ bool IsCrossSection,
+ const MCAsmBackend &MAB) const = 0;
virtual bool recordRelocation(const MCFixup &) const { return true; }
};
@@ -39,7 +41,7 @@ namespace llvm {
/// \param OS - The stream to write to.
/// \returns The constructed object writer.
MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
- raw_ostream &OS);
+ raw_pwrite_stream &OS);
} // End llvm namespace
#endif
diff --git a/include/llvm/MC/MCWinCOFFStreamer.h b/include/llvm/MC/MCWinCOFFStreamer.h
index 57a75cec22047..6a83e02298ffc 100644
--- a/include/llvm/MC/MCWinCOFFStreamer.h
+++ b/include/llvm/MC/MCWinCOFFStreamer.h
@@ -24,11 +24,12 @@ class MCSubtargetInfo;
class MCSymbol;
class StringRef;
class raw_ostream;
+class raw_pwrite_stream;
class MCWinCOFFStreamer : public MCObjectStreamer {
public:
MCWinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB, MCCodeEmitter &CE,
- raw_ostream &OS);
+ raw_pwrite_stream &OS);
/// state management
void reset() override {
@@ -56,9 +57,9 @@ public:
unsigned ByteAlignment) override;
void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
- void EmitZerofill(const MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ void EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
- void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
void EmitFileDirective(StringRef Filename) override;
void EmitIdent(StringRef IdentString) override;
diff --git a/include/llvm/MC/MCWinEH.h b/include/llvm/MC/MCWinEH.h
index 05b58c753b661..723d7a397c496 100644
--- a/include/llvm/MC/MCWinEH.h
+++ b/include/llvm/MC/MCWinEH.h
@@ -65,10 +65,10 @@ struct FrameInfo {
class UnwindEmitter {
public:
- static const MCSection *getPDataSection(const MCSymbol *Function,
- MCContext &Context);
- static const MCSection *getXDataSection(const MCSymbol *Function,
- MCContext &Context);
+ static MCSection *getPDataSection(const MCSymbol *Function,
+ MCContext &Context);
+ static MCSection *getXDataSection(const MCSymbol *Function,
+ MCContext &Context);
virtual ~UnwindEmitter() { }
diff --git a/include/llvm/MC/SectionKind.h b/include/llvm/MC/SectionKind.h
index 85a91c6b16988..9e8b68f4340c9 100644
--- a/include/llvm/MC/SectionKind.h
+++ b/include/llvm/MC/SectionKind.h
@@ -55,7 +55,6 @@ class SectionKind {
/// MergeableConst - These are sections for merging fixed-length
/// constants together. For example, this can be used to unique
/// constant pool entries etc.
- MergeableConst,
/// MergeableConst4 - This is a section used by 4-byte constants,
/// for example, floats.
@@ -151,8 +150,8 @@ public:
bool isMergeable4ByteCString() const { return K == Mergeable4ByteCString; }
bool isMergeableConst() const {
- return K == MergeableConst || K == MergeableConst4 ||
- K == MergeableConst8 || K == MergeableConst16;
+ return K == MergeableConst4 || K == MergeableConst8 ||
+ K == MergeableConst16;
}
bool isMergeableConst4() const { return K == MergeableConst4; }
bool isMergeableConst8() const { return K == MergeableConst8; }
@@ -216,7 +215,6 @@ public:
static SectionKind getMergeable4ByteCString() {
return get(Mergeable4ByteCString);
}
- static SectionKind getMergeableConst() { return get(MergeableConst); }
static SectionKind getMergeableConst4() { return get(MergeableConst4); }
static SectionKind getMergeableConst8() { return get(MergeableConst8); }
static SectionKind getMergeableConst16() { return get(MergeableConst16); }
diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h
index bfecb8ba6ab0a..6a631ffe79bd3 100644
--- a/include/llvm/MC/SubtargetFeature.h
+++ b/include/llvm/MC/SubtargetFeature.h
@@ -21,11 +21,29 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/DataTypes.h"
+#include <bitset>
namespace llvm {
class raw_ostream;
class StringRef;
+// A container class for subtarget features.
+// This is convenient because std::bitset does not have a constructor
+// with an initializer list of set bits.
+const unsigned MAX_SUBTARGET_FEATURES = 64;
+class FeatureBitset : public std::bitset<MAX_SUBTARGET_FEATURES> {
+public:
+ // Cannot inherit constructors because it's not supported by VC++..
+ FeatureBitset() : bitset() {}
+
+ FeatureBitset(const bitset<MAX_SUBTARGET_FEATURES>& B) : bitset(B) {}
+
+ FeatureBitset(std::initializer_list<unsigned> Init) : bitset() {
+ for (auto I = Init.begin() , E = Init.end(); I != E; ++I)
+ set(*I);
+ }
+};
+
//===----------------------------------------------------------------------===//
///
/// SubtargetFeatureKV - Used to provide key value pairs for feature and
@@ -34,8 +52,8 @@ namespace llvm {
struct SubtargetFeatureKV {
const char *Key; // K-V key string
const char *Desc; // Help descriptor
- uint64_t Value; // K-V integer value
- uint64_t Implies; // K-V bit mask
+ FeatureBitset Value; // K-V integer value
+ FeatureBitset Implies; // K-V bit mask
// Compare routine for std::lower_bound
bool operator<(StringRef S) const {
@@ -78,15 +96,15 @@ public:
std::string getString() const;
/// Adding Features.
- void AddFeature(StringRef String);
+ void AddFeature(StringRef String, bool Enable = true);
/// ToggleFeature - Toggle a feature and returns the newly updated feature
/// bits.
- uint64_t ToggleFeature(uint64_t Bits, StringRef String,
+ FeatureBitset ToggleFeature(FeatureBitset Bits, StringRef String,
ArrayRef<SubtargetFeatureKV> FeatureTable);
/// Get feature bits of a CPU.
- uint64_t getFeatureBits(StringRef CPU,
+ FeatureBitset getFeatureBits(StringRef CPU,
ArrayRef<SubtargetFeatureKV> CPUTable,
ArrayRef<SubtargetFeatureKV> FeatureTable);