summaryrefslogtreecommitdiff
path: root/clang-r353983/include/llvm/MC
diff options
context:
space:
mode:
Diffstat (limited to 'clang-r353983/include/llvm/MC')
-rw-r--r--clang-r353983/include/llvm/MC/ConstantPools.h102
-rw-r--r--clang-r353983/include/llvm/MC/LaneBitmask.h101
-rw-r--r--clang-r353983/include/llvm/MC/MCAsmBackend.h225
-rw-r--r--clang-r353983/include/llvm/MC/MCAsmInfo.h641
-rw-r--r--clang-r353983/include/llvm/MC/MCAsmInfoCOFF.h39
-rw-r--r--clang-r353983/include/llvm/MC/MCAsmInfoDarwin.h30
-rw-r--r--clang-r353983/include/llvm/MC/MCAsmInfoELF.h30
-rw-r--r--clang-r353983/include/llvm/MC/MCAsmInfoWasm.h23
-rw-r--r--clang-r353983/include/llvm/MC/MCAsmLayout.h106
-rw-r--r--clang-r353983/include/llvm/MC/MCAsmMacro.h157
-rw-r--r--clang-r353983/include/llvm/MC/MCAssembler.h468
-rw-r--r--clang-r353983/include/llvm/MC/MCCodeEmitter.h42
-rw-r--r--clang-r353983/include/llvm/MC/MCCodePadder.h241
-rw-r--r--clang-r353983/include/llvm/MC/MCCodeView.h264
-rw-r--r--clang-r353983/include/llvm/MC/MCContext.h741
-rw-r--r--clang-r353983/include/llvm/MC/MCDirectives.h73
-rw-r--r--clang-r353983/include/llvm/MC/MCDisassembler/MCDisassembler.h132
-rw-r--r--clang-r353983/include/llvm/MC/MCDisassembler/MCExternalSymbolizer.h57
-rw-r--r--clang-r353983/include/llvm/MC/MCDisassembler/MCRelocationInfo.h44
-rw-r--r--clang-r353983/include/llvm/MC/MCDisassembler/MCSymbolizer.h82
-rw-r--r--clang-r353983/include/llvm/MC/MCDwarf.h617
-rw-r--r--clang-r353983/include/llvm/MC/MCELFObjectWriter.h161
-rw-r--r--clang-r353983/include/llvm/MC/MCELFStreamer.h108
-rw-r--r--clang-r353983/include/llvm/MC/MCExpr.h609
-rw-r--r--clang-r353983/include/llvm/MC/MCFixedLenDisassembler.h33
-rw-r--r--clang-r353983/include/llvm/MC/MCFixup.h170
-rw-r--r--clang-r353983/include/llvm/MC/MCFixupKindInfo.h42
-rw-r--r--clang-r353983/include/llvm/MC/MCFragment.h667
-rw-r--r--clang-r353983/include/llvm/MC/MCInst.h224
-rw-r--r--clang-r353983/include/llvm/MC/MCInstBuilder.h73
-rw-r--r--clang-r353983/include/llvm/MC/MCInstPrinter.h107
-rw-r--r--clang-r353983/include/llvm/MC/MCInstrAnalysis.h165
-rw-r--r--clang-r353983/include/llvm/MC/MCInstrDesc.h602
-rw-r--r--clang-r353983/include/llvm/MC/MCInstrInfo.h58
-rw-r--r--clang-r353983/include/llvm/MC/MCInstrItineraries.h234
-rw-r--r--clang-r353983/include/llvm/MC/MCLabel.h56
-rw-r--r--clang-r353983/include/llvm/MC/MCLinkerOptimizationHint.h186
-rw-r--r--clang-r353983/include/llvm/MC/MCMachObjectWriter.h287
-rw-r--r--clang-r353983/include/llvm/MC/MCObjectFileInfo.h413
-rw-r--r--clang-r353983/include/llvm/MC/MCObjectStreamer.h205
-rw-r--r--clang-r353983/include/llvm/MC/MCObjectWriter.h123
-rw-r--r--clang-r353983/include/llvm/MC/MCParser/AsmCond.h39
-rw-r--r--clang-r353983/include/llvm/MC/MCParser/AsmLexer.h73
-rw-r--r--clang-r353983/include/llvm/MC/MCParser/MCAsmLexer.h157
-rw-r--r--clang-r353983/include/llvm/MC/MCParser/MCAsmParser.h309
-rw-r--r--clang-r353983/include/llvm/MC/MCParser/MCAsmParserExtension.h120
-rw-r--r--clang-r353983/include/llvm/MC/MCParser/MCAsmParserUtils.h33
-rw-r--r--clang-r353983/include/llvm/MC/MCParser/MCParsedAsmOperand.h99
-rw-r--r--clang-r353983/include/llvm/MC/MCParser/MCTargetAsmParser.h499
-rw-r--r--clang-r353983/include/llvm/MC/MCRegisterInfo.h727
-rw-r--r--clang-r353983/include/llvm/MC/MCSchedule.h385
-rw-r--r--clang-r353983/include/llvm/MC/MCSection.h193
-rw-r--r--clang-r353983/include/llvm/MC/MCSectionCOFF.h97
-rw-r--r--clang-r353983/include/llvm/MC/MCSectionELF.h96
-rw-r--r--clang-r353983/include/llvm/MC/MCSectionMachO.h91
-rw-r--r--clang-r353983/include/llvm/MC/MCSectionWasm.h83
-rw-r--r--clang-r353983/include/llvm/MC/MCStreamer.h1012
-rw-r--r--clang-r353983/include/llvm/MC/MCSubtargetInfo.h187
-rw-r--r--clang-r353983/include/llvm/MC/MCSymbol.h428
-rw-r--r--clang-r353983/include/llvm/MC/MCSymbolCOFF.h66
-rw-r--r--clang-r353983/include/llvm/MC/MCSymbolELF.h53
-rw-r--r--clang-r353983/include/llvm/MC/MCSymbolMachO.h140
-rw-r--r--clang-r353983/include/llvm/MC/MCSymbolWasm.h99
-rw-r--r--clang-r353983/include/llvm/MC/MCTargetOptions.h79
-rw-r--r--clang-r353983/include/llvm/MC/MCTargetOptionsCommandFlags.inc79
-rw-r--r--clang-r353983/include/llvm/MC/MCValue.h86
-rw-r--r--clang-r353983/include/llvm/MC/MCWasmObjectWriter.h55
-rw-r--r--clang-r353983/include/llvm/MC/MCWasmStreamer.h87
-rw-r--r--clang-r353983/include/llvm/MC/MCWin64EH.h69
-rw-r--r--clang-r353983/include/llvm/MC/MCWinCOFFObjectWriter.h56
-rw-r--r--clang-r353983/include/llvm/MC/MCWinCOFFStreamer.h82
-rw-r--r--clang-r353983/include/llvm/MC/MCWinEH.h69
-rw-r--r--clang-r353983/include/llvm/MC/MachineLocation.h58
-rw-r--r--clang-r353983/include/llvm/MC/SectionKind.h207
-rw-r--r--clang-r353983/include/llvm/MC/StringTableBuilder.h74
-rw-r--r--clang-r353983/include/llvm/MC/SubtargetFeature.h132
76 files changed, 14857 insertions, 0 deletions
diff --git a/clang-r353983/include/llvm/MC/ConstantPools.h b/clang-r353983/include/llvm/MC/ConstantPools.h
new file mode 100644
index 00000000..2fe5ce25
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/ConstantPools.h
@@ -0,0 +1,102 @@
+//===- ConstantPools.h - Keep track of assembler-generated ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the ConstantPool and AssemblerConstantPools classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_CONSTANTPOOLS_H
+#define LLVM_MC_CONSTANTPOOLS_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/SMLoc.h"
+#include <cstdint>
+#include <map>
+
+namespace llvm {
+
+class MCContext;
+class MCExpr;
+class MCSection;
+class MCStreamer;
+class MCSymbol;
+class MCSymbolRefExpr;
+
+struct ConstantPoolEntry {
+ ConstantPoolEntry(MCSymbol *L, const MCExpr *Val, unsigned Sz, SMLoc Loc_)
+ : Label(L), Value(Val), Size(Sz), Loc(Loc_) {}
+
+ MCSymbol *Label;
+ const MCExpr *Value;
+ unsigned Size;
+ SMLoc Loc;
+};
+
+// A class to keep track of assembler-generated constant pools that are use to
+// implement the ldr-pseudo.
+class ConstantPool {
+ using EntryVecTy = SmallVector<ConstantPoolEntry, 4>;
+ EntryVecTy Entries;
+ std::map<int64_t, const MCSymbolRefExpr *> CachedEntries;
+
+public:
+ // Initialize a new empty constant pool
+ ConstantPool() = default;
+
+ // Add a new entry to the constant pool in the next slot.
+ // \param Value is the new entry to put in the constant pool.
+ // \param Size is the size in bytes of the entry
+ //
+ // \returns a MCExpr that references the newly inserted value
+ const MCExpr *addEntry(const MCExpr *Value, MCContext &Context,
+ unsigned Size, SMLoc Loc);
+
+ // Emit the contents of the constant pool using the provided streamer.
+ void emitEntries(MCStreamer &Streamer);
+
+ // Return true if the constant pool is empty
+ bool empty();
+
+ void clearCache();
+};
+
+class AssemblerConstantPools {
+ // Map type used to keep track of per-Section constant pools used by the
+ // ldr-pseudo opcode. The map associates a section to its constant pool. The
+ // constant pool is a vector of (label, value) pairs. When the ldr
+ // pseudo is parsed we insert a new (label, value) pair into the constant pool
+ // for the current section and add MCSymbolRefExpr to the new label as
+ // an opcode to the ldr. After we have parsed all the user input we
+ // output the (label, value) pairs in each constant pool at the end of the
+ // section.
+ //
+ // We use the MapVector for the map type to ensure stable iteration of
+ // the sections at the end of the parse. We need to iterate over the
+ // sections in a stable order to ensure that we have print the
+ // constant pools in a deterministic order when printing an assembly
+ // file.
+ using ConstantPoolMapTy = MapVector<MCSection *, ConstantPool>;
+ ConstantPoolMapTy ConstantPools;
+
+public:
+ void emitAll(MCStreamer &Streamer);
+ void emitForCurrentSection(MCStreamer &Streamer);
+ void clearCacheForCurrentSection(MCStreamer &Streamer);
+ const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Expr,
+ unsigned Size, SMLoc Loc);
+
+private:
+ ConstantPool *getConstantPool(MCSection *Section);
+ ConstantPool &getOrCreateConstantPool(MCSection *Section);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_CONSTANTPOOLS_H
diff --git a/clang-r353983/include/llvm/MC/LaneBitmask.h b/clang-r353983/include/llvm/MC/LaneBitmask.h
new file mode 100644
index 00000000..d5f69287
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/LaneBitmask.h
@@ -0,0 +1,101 @@
+//===- llvm/MC/LaneBitmask.h ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// A common definition of LaneBitmask for use in TableGen and CodeGen.
+///
+/// A lane mask is a bitmask representing the covering of a register with
+/// sub-registers.
+///
+/// This is typically used to track liveness at sub-register granularity.
+/// Lane masks for sub-register indices are similar to register units for
+/// physical registers. The individual bits in a lane mask can't be assigned
+/// any specific meaning. They can be used to check if two sub-register
+/// indices overlap.
+///
+/// Iff the target has a register such that:
+///
+/// getSubReg(Reg, A) overlaps getSubReg(Reg, B)
+///
+/// then:
+///
+/// (getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B)) != 0
+
+#ifndef LLVM_MC_LANEBITMASK_H
+#define LLVM_MC_LANEBITMASK_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/Printable.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+ struct LaneBitmask {
+ // When changing the underlying type, change the format string as well.
+ using Type = unsigned;
+ enum : unsigned { BitWidth = 8*sizeof(Type) };
+ constexpr static const char *const FormatStr = "%08X";
+
+ constexpr LaneBitmask() = default;
+ explicit constexpr LaneBitmask(Type V) : Mask(V) {}
+
+ constexpr bool operator== (LaneBitmask M) const { return Mask == M.Mask; }
+ constexpr bool operator!= (LaneBitmask M) const { return Mask != M.Mask; }
+ constexpr bool operator< (LaneBitmask M) const { return Mask < M.Mask; }
+ constexpr bool none() const { return Mask == 0; }
+ constexpr bool any() const { return Mask != 0; }
+ constexpr bool all() const { return ~Mask == 0; }
+
+ constexpr LaneBitmask operator~() const {
+ return LaneBitmask(~Mask);
+ }
+ constexpr LaneBitmask operator|(LaneBitmask M) const {
+ return LaneBitmask(Mask | M.Mask);
+ }
+ constexpr LaneBitmask operator&(LaneBitmask M) const {
+ return LaneBitmask(Mask & M.Mask);
+ }
+ LaneBitmask &operator|=(LaneBitmask M) {
+ Mask |= M.Mask;
+ return *this;
+ }
+ LaneBitmask &operator&=(LaneBitmask M) {
+ Mask &= M.Mask;
+ return *this;
+ }
+
+ constexpr Type getAsInteger() const { return Mask; }
+
+ unsigned getNumLanes() const {
+ return countPopulation(Mask);
+ }
+ unsigned getHighestLane() const {
+ return Log2_32(Mask);
+ }
+
+ static constexpr LaneBitmask getNone() { return LaneBitmask(0); }
+ static constexpr LaneBitmask getAll() { return ~LaneBitmask(0); }
+ static constexpr LaneBitmask getLane(unsigned Lane) {
+ return LaneBitmask(Type(1) << Lane);
+ }
+
+ private:
+ Type Mask = 0;
+ };
+
+ /// Create Printable object to print LaneBitmasks on a \ref raw_ostream.
+ inline Printable PrintLaneMask(LaneBitmask LaneMask) {
+ return Printable([LaneMask](raw_ostream &OS) {
+ OS << format(LaneBitmask::FormatStr, LaneMask.getAsInteger());
+ });
+ }
+
+} // end namespace llvm
+
+#endif // LLVM_MC_LANEBITMASK_H
diff --git a/clang-r353983/include/llvm/MC/MCAsmBackend.h b/clang-r353983/include/llvm/MC/MCAsmBackend.h
new file mode 100644
index 00000000..1f3ad6c1
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCAsmBackend.h
@@ -0,0 +1,225 @@
+//===- llvm/MC/MCAsmBackend.h - MC Asm Backend ------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMBACKEND_H
+#define LLVM_MC_MCASMBACKEND_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCFragment.h"
+#include "llvm/Support/Endian.h"
+#include <cstdint>
+#include <memory>
+
+namespace llvm {
+
+class MCAsmLayout;
+class MCAssembler;
+class MCCFIInstruction;
+class MCCodePadder;
+struct MCFixupKindInfo;
+class MCFragment;
+class MCInst;
+class MCObjectStreamer;
+class MCObjectTargetWriter;
+class MCObjectWriter;
+struct MCCodePaddingContext;
+class MCRelaxableFragment;
+class MCSubtargetInfo;
+class MCValue;
+class raw_pwrite_stream;
+
+/// Generic interface to target specific assembler backends.
+class MCAsmBackend {
+ std::unique_ptr<MCCodePadder> CodePadder;
+
+protected: // Can only create subclasses.
+ MCAsmBackend(support::endianness Endian);
+
+public:
+ MCAsmBackend(const MCAsmBackend &) = delete;
+ MCAsmBackend &operator=(const MCAsmBackend &) = delete;
+ virtual ~MCAsmBackend();
+
+ const support::endianness Endian;
+
+ /// lifetime management
+ virtual void reset() {}
+
+ /// Create a new MCObjectWriter instance for use by the assembler backend to
+ /// emit the final object file.
+ std::unique_ptr<MCObjectWriter>
+ createObjectWriter(raw_pwrite_stream &OS) const;
+
+ /// Create an MCObjectWriter that writes two object files: a .o file which is
+ /// linked into the final program and a .dwo file which is used by debuggers.
+ /// This function is only supported with ELF targets.
+ std::unique_ptr<MCObjectWriter>
+ createDwoObjectWriter(raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS) const;
+
+ virtual std::unique_ptr<MCObjectTargetWriter>
+ createObjectTargetWriter() const = 0;
+
+ /// \name Target Fixup Interfaces
+ /// @{
+
+ /// Get the number of target specific fixup kinds.
+ virtual unsigned getNumFixupKinds() const = 0;
+
+ /// Map a relocation name used in .reloc to a fixup kind.
+ virtual Optional<MCFixupKind> getFixupKind(StringRef Name) const;
+
+ /// Get information on a fixup kind.
+ virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const;
+
+ /// Hook to check if a relocation is needed for some target specific reason.
+ virtual bool shouldForceRelocation(const MCAssembler &Asm,
+ const MCFixup &Fixup,
+ const MCValue &Target) {
+ return false;
+ }
+
+ /// Hook to check if extra nop bytes must be inserted for alignment directive.
+ /// For some targets this may be necessary in order to support linker
+ /// relaxation. The number of bytes to insert are returned in Size.
+ virtual bool shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment &AF,
+ unsigned &Size) {
+ return false;
+ }
+
+ /// Hook which indicates if the target requires a fixup to be generated when
+ /// handling an align directive in an executable section
+ virtual bool shouldInsertFixupForCodeAlign(MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ MCAlignFragment &AF) {
+ return false;
+ }
+
+ /// 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. Errors (such as an out of range fixup value) should be
+ /// reported via \p Ctx.
+ /// The \p STI is present only for fragments of type MCRelaxableFragment and
+ /// MCDataFragment with hasInstructions() == true.
+ virtual void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
+ const MCValue &Target, MutableArrayRef<char> Data,
+ uint64_t Value, bool IsResolved,
+ const MCSubtargetInfo *STI) const = 0;
+
+ /// Check whether the given target requires emitting differences of two
+ /// symbols as a set of relocations.
+ virtual bool requiresDiffExpressionRelocations() const { return false; }
+
+ /// @}
+
+ /// \name Target Relaxation Interfaces
+ /// @{
+
+ /// Check whether the given instruction may need relaxation.
+ ///
+ /// \param Inst - The instruction to test.
+ /// \param STI - The MCSubtargetInfo in effect when the instruction was
+ /// encoded.
+ virtual bool mayNeedRelaxation(const MCInst &Inst,
+ const MCSubtargetInfo &STI) const = 0;
+
+ /// Target specific predicate for whether a given fixup requires the
+ /// associated instruction to be relaxed.
+ virtual bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
+ uint64_t Value,
+ const MCRelaxableFragment *DF,
+ const MCAsmLayout &Layout,
+ const bool WasForced) const;
+
+ /// Simple predicate for targets where !Resolved implies requiring relaxation
+ virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
+ const MCRelaxableFragment *DF,
+ const MCAsmLayout &Layout) const = 0;
+
+ /// Relax the instruction in the given fragment to the next wider instruction.
+ ///
+ /// \param Inst The instruction to relax, which may be the same as the
+ /// output.
+ /// \param STI the subtarget information for the associated instruction.
+ /// \param [out] Res On return, the relaxed instruction.
+ virtual void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
+ MCInst &Res) const = 0;
+
+ /// @}
+
+ /// 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; }
+
+ /// 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(raw_ostream &OS, uint64_t Count) const = 0;
+
+ /// Give backend an opportunity to finish layout after relaxation
+ virtual void finishLayout(MCAssembler const &Asm,
+ MCAsmLayout &Layout) const {}
+
+ /// Handle any target-specific assembler flags. By default, do nothing.
+ virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {}
+
+ /// Generate the compact unwind encoding for the CFI instructions.
+ virtual uint32_t
+ generateCompactUnwindEncoding(ArrayRef<MCCFIInstruction>) const {
+ return 0;
+ }
+
+ /// Check whether a given symbol has been flagged with MICROMIPS flag.
+ virtual bool isMicroMips(const MCSymbol *Sym) const {
+ return false;
+ }
+
+ /// Handles all target related code padding when starting to write a new
+ /// basic block to an object file.
+ ///
+ /// \param OS The streamer used for writing the padding data and function.
+ /// \param Context the context of the padding, Embeds the basic block's
+ /// parameters.
+ void handleCodePaddingBasicBlockStart(MCObjectStreamer *OS,
+ const MCCodePaddingContext &Context);
+ /// Handles all target related code padding after writing a block to an object
+ /// file.
+ ///
+ /// \param Context the context of the padding, Embeds the basic block's
+ /// parameters.
+ void handleCodePaddingBasicBlockEnd(const MCCodePaddingContext &Context);
+ /// Handles all target related code padding before writing a new instruction
+ /// to an object file.
+ ///
+ /// \param Inst the instruction.
+ void handleCodePaddingInstructionBegin(const MCInst &Inst);
+ /// Handles all target related code padding after writing an instruction to an
+ /// object file.
+ ///
+ /// \param Inst the instruction.
+ void handleCodePaddingInstructionEnd(const MCInst &Inst);
+
+ /// Relaxes a fragment (changes the size of the padding) according to target
+ /// requirements. The new size computation is done w.r.t a layout.
+ ///
+ /// \param PF The fragment to relax.
+ /// \param Layout Code layout information.
+ ///
+ /// \returns true iff any relaxation occurred.
+ bool relaxFragment(MCPaddingFragment *PF, MCAsmLayout &Layout);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCASMBACKEND_H
diff --git a/clang-r353983/include/llvm/MC/MCAsmInfo.h b/clang-r353983/include/llvm/MC/MCAsmInfo.h
new file mode 100644
index 00000000..e861df5b
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCAsmInfo.h
@@ -0,0 +1,641 @@
+//===-- llvm/MC/MCAsmInfo.h - Asm info --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a class to be used as the basis for target specific
+// asm writers. This class primarily takes care of global printing constants,
+// which are used in very similar ways across all targets.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMINFO_H
+#define LLVM_MC_MCASMINFO_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCTargetOptions.h"
+#include <vector>
+
+namespace llvm {
+
+class MCContext;
+class MCExpr;
+class MCSection;
+class MCStreamer;
+class MCSymbol;
+
+namespace WinEH {
+
+enum class EncodingType {
+ Invalid, /// Invalid
+ Alpha, /// Windows Alpha
+ Alpha64, /// Windows AXP64
+ 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,
+};
+
+} // end namespace WinEH
+
+namespace LCOMM {
+
+enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment };
+
+} // end namespace LCOMM
+
+/// This class is intended to be used as a base class for asm
+/// properties and features specific to the target.
+class MCAsmInfo {
+protected:
+ //===------------------------------------------------------------------===//
+ // Properties to be set by the target writer, used to configure asm printer.
+ //
+
+ /// Code pointer size in bytes. Default is 4.
+ unsigned CodePointerSize = 4;
+
+ /// Size of the stack slot reserved for callee-saved registers, in bytes.
+ /// Default is same as pointer size.
+ unsigned CalleeSaveStackSlotSize = 4;
+
+ /// True if target is little endian. Default is true.
+ bool IsLittleEndian = true;
+
+ /// True if target stack grow up. Default is false.
+ bool StackGrowsUp = false;
+
+ /// True if this target has the MachO .subsections_via_symbols directive.
+ /// Default is false.
+ bool HasSubsectionsViaSymbols = false;
+
+ /// True if this is a MachO target that supports the macho-specific .zerofill
+ /// directive for emitting BSS Symbols. Default is false.
+ bool HasMachoZeroFillDirective = false;
+
+ /// True if this is a MachO target that supports the macho-specific .tbss
+ /// directive for emitting thread local BSS Symbols. Default is false.
+ bool HasMachoTBSSDirective = false;
+
+ /// True if this is a non-GNU COFF target. The COFF port of the GNU linker
+ /// doesn't handle associative comdats in the way that we would like to use
+ /// them.
+ bool HasCOFFAssociativeComdats = false;
+
+ /// True if this is a non-GNU COFF target. For GNU targets, we don't generate
+ /// constants into comdat sections.
+ bool HasCOFFComdatConstants = false;
+
+ /// This is the maximum possible length of an instruction, which is needed to
+ /// compute the size of an inline asm. Defaults to 4.
+ unsigned MaxInstLength = 4;
+
+ /// Every possible instruction length is a multiple of this value. Factored
+ /// out in .debug_frame and .debug_line. Defaults to 1.
+ unsigned MinInstAlignment = 1;
+
+ /// The '$' token, when not referencing an identifier or constant, refers to
+ /// the current PC. Defaults to false.
+ bool DollarIsPC = false;
+
+ /// This string, if specified, is used to separate instructions from each
+ /// other when on the same line. Defaults to ';'
+ const char *SeparatorString;
+
+ /// This indicates the comment character used by the assembler. Defaults to
+ /// "#"
+ StringRef CommentString;
+
+ /// This is appended to emitted labels. Defaults to ":"
+ const char *LabelSuffix;
+
+ // Print the EH begin symbol with an assignment. Defaults to false.
+ bool UseAssignmentForEHBegin = false;
+
+ // Do we need to create a local symbol for .size?
+ bool NeedsLocalForSize = false;
+
+ /// 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"
+ StringRef PrivateGlobalPrefix;
+
+ /// This prefix is used for labels for basic blocks. Defaults to the same as
+ /// PrivateGlobalPrefix.
+ StringRef PrivateLabelPrefix;
+
+ /// This prefix is used for symbols that should be passed through the
+ /// assembler but be removed by the linker. This is 'l' on Darwin, currently
+ /// used for some ObjC metadata. The default of "" meast that for this system
+ /// a plain private symbol should be used. Defaults to "".
+ StringRef LinkerPrivateGlobalPrefix;
+
+ /// If these are nonempty, they contain a directive to emit before and after
+ /// an inline assembly statement. Defaults to "#APP\n", "#NO_APP\n"
+ const char *InlineAsmStart;
+ const char *InlineAsmEnd;
+
+ /// These are assembly directives that tells the assembler to interpret the
+ /// following instructions differently. Defaults to ".code16", ".code32",
+ /// ".code64".
+ const char *Code16Directive;
+ const char *Code32Directive;
+ const char *Code64Directive;
+
+ /// Which dialect of an assembler variant to use. Defaults to 0
+ unsigned AssemblerDialect = 0;
+
+ /// This is true if the assembler allows @ characters in symbol names.
+ /// Defaults to false.
+ bool AllowAtInName = false;
+
+ /// If this is true, symbol names with invalid characters will be printed in
+ /// quotes.
+ bool SupportsQuotedNames = true;
+
+ /// This is true if data region markers should be printed as
+ /// ".data_region/.end_data_region" directives. If false, use "$d/$a" labels
+ /// instead.
+ bool UseDataRegionDirectives = false;
+
+ //===--- Data Emission Directives -------------------------------------===//
+
+ /// This should be set to the directive used to get some number of zero bytes
+ /// emitted to the current section. Common cases are "\t.zero\t" and
+ /// "\t.space\t". If this is set to null, the Data*bitsDirective's will be
+ /// used to emit zero bytes. Defaults to "\t.zero\t"
+ const char *ZeroDirective;
+
+ /// This directive allows emission of an ascii string with the standard C
+ /// escape characters embedded into it. If a target doesn't support this, it
+ /// can be set to null. Defaults to "\t.ascii\t"
+ const char *AsciiDirective;
+
+ /// If not null, this allows for special handling of zero terminated strings
+ /// on this target. This is commonly supported as ".asciz". If a target
+ /// doesn't support this, it can be set to null. Defaults to "\t.asciz\t"
+ const char *AscizDirective;
+
+ /// These directives are used to output some unit of integer data to the
+ /// current section. If a data directive is set to null, smaller data
+ /// directives will be used to emit the large sizes. Defaults to "\t.byte\t",
+ /// "\t.short\t", "\t.long\t", "\t.quad\t"
+ const char *Data8bitsDirective;
+ const char *Data16bitsDirective;
+ const char *Data32bitsDirective;
+ const char *Data64bitsDirective;
+
+ /// If non-null, a directive that is used to emit a word which should be
+ /// relocated as a 64-bit GP-relative offset, e.g. .gpdword on Mips. Defaults
+ /// to nullptr.
+ const char *GPRel64Directive = nullptr;
+
+ /// If non-null, a directive that is used to emit a word which should be
+ /// relocated as a 32-bit GP-relative offset, e.g. .gpword on Mips or .gprel32
+ /// on Alpha. Defaults to nullptr.
+ const char *GPRel32Directive = nullptr;
+
+ /// If non-null, directives that are used to emit a word/dword which should
+ /// be relocated as a 32/64-bit DTP/TP-relative offset, e.g. .dtprelword/
+ /// .dtpreldword/.tprelword/.tpreldword on Mips.
+ const char *DTPRel32Directive = nullptr;
+ const char *DTPRel64Directive = nullptr;
+ const char *TPRel32Directive = nullptr;
+ const char *TPRel64Directive = nullptr;
+
+ /// This is true if this target uses "Sun Style" syntax for section switching
+ /// ("#alloc,#write" etc) instead of the normal ELF syntax (,"a,w") in
+ /// .section directives. Defaults to false.
+ bool SunStyleELFSectionSwitchSyntax = false;
+
+ /// This is true if this target uses ELF '.section' directive before the
+ /// '.bss' one. It's used for PPC/Linux which doesn't support the '.bss'
+ /// directive only. Defaults to false.
+ bool UsesELFSectionDirectiveForBSS = false;
+
+ bool NeedsDwarfSectionOffsetDirective = false;
+
+ //===--- Alignment Information ----------------------------------------===//
+
+ /// If this is true (the default) then the asmprinter emits ".align N"
+ /// directives, where N is the number of bytes to align to. Otherwise, it
+ /// emits ".align log2(N)", e.g. 3 to align to an 8 byte boundary. Defaults
+ /// to true.
+ bool AlignmentIsInBytes = true;
+
+ /// If non-zero, this is used to fill the executable space created as the
+ /// result of a alignment directive. Defaults to 0
+ unsigned TextAlignFillValue = 0;
+
+ //===--- Global Variable Emission Directives --------------------------===//
+
+ /// This is the directive used to declare a global entity. Defaults to
+ /// ".globl".
+ const char *GlobalDirective;
+
+ /// True if the expression
+ /// .long f - g
+ /// uses a relocation but it can be suppressed by writing
+ /// a = f - g
+ /// .long a
+ bool SetDirectiveSuppressesReloc = false;
+
+ /// False if the assembler requires that we use
+ /// \code
+ /// Lc = a - b
+ /// .long Lc
+ /// \endcode
+ //
+ /// instead of
+ //
+ /// \code
+ /// .long a - b
+ /// \endcode
+ ///
+ /// Defaults to true.
+ bool HasAggressiveSymbolFolding = true;
+
+ /// True is .comm's and .lcomms optional alignment is to be specified in bytes
+ /// instead of log2(n). Defaults to true.
+ bool COMMDirectiveAlignmentIsInBytes = true;
+
+ /// Describes if the .lcomm directive for the target supports an alignment
+ /// argument and how it is interpreted. Defaults to NoAlignment.
+ LCOMM::LCOMMType LCOMMDirectiveAlignmentType = LCOMM::NoAlignment;
+
+ // True if the target allows .align directives on functions. This is true for
+ // most targets, so defaults to true.
+ bool HasFunctionAlignment = true;
+
+ /// True if the target has .type and .size directives, this is true for most
+ /// ELF targets. Defaults to true.
+ bool HasDotTypeDotSizeDirective = true;
+
+ /// True if the target has a single parameter .file directive, this is true
+ /// for ELF targets. Defaults to true.
+ bool HasSingleParameterDotFile = true;
+
+ /// True if the target has a .ident directive, this is true for ELF targets.
+ /// Defaults to false.
+ bool HasIdentDirective = false;
+
+ /// True if this target supports the MachO .no_dead_strip directive. Defaults
+ /// to false.
+ bool HasNoDeadStrip = false;
+
+ /// True if this target supports the MachO .alt_entry directive. Defaults to
+ /// false.
+ bool HasAltEntry = false;
+
+ /// Used to declare a global as being a weak symbol. Defaults to ".weak".
+ const char *WeakDirective;
+
+ /// This directive, if non-null, is used to declare a global as being a weak
+ /// undefined symbol. Defaults to nullptr.
+ const char *WeakRefDirective = nullptr;
+
+ /// True if we have a directive to declare a global as being a weak defined
+ /// symbol. Defaults to false.
+ bool HasWeakDefDirective = false;
+
+ /// True if we have a directive to declare a global as being a weak defined
+ /// symbol that can be hidden (unexported). Defaults to false.
+ bool HasWeakDefCanBeHiddenDirective = false;
+
+ /// True if we have a .linkonce directive. This is used on cygwin/mingw.
+ /// Defaults to false.
+ bool HasLinkOnceDirective = false;
+
+ /// This attribute, if not MCSA_Invalid, is used to declare a symbol as having
+ /// hidden visibility. Defaults to MCSA_Hidden.
+ MCSymbolAttr HiddenVisibilityAttr = MCSA_Hidden;
+
+ /// This attribute, if not MCSA_Invalid, is used to declare an undefined
+ /// symbol as having hidden visibility. Defaults to MCSA_Hidden.
+ MCSymbolAttr HiddenDeclarationVisibilityAttr = MCSA_Hidden;
+
+ /// This attribute, if not MCSA_Invalid, is used to declare a symbol as having
+ /// protected visibility. Defaults to MCSA_Protected
+ MCSymbolAttr ProtectedVisibilityAttr = MCSA_Protected;
+
+ //===--- Dwarf Emission Directives -----------------------------------===//
+
+ /// True if target supports emission of debugging information. Defaults to
+ /// false.
+ bool SupportsDebugInformation = false;
+
+ /// Exception handling format for the target. Defaults to None.
+ ExceptionHandling ExceptionsType = ExceptionHandling::None;
+
+ /// Windows exception handling data (.pdata) encoding. Defaults to Invalid.
+ WinEH::EncodingType WinEHEncodingType = WinEH::EncodingType::Invalid;
+
+ /// True if Dwarf2 output generally uses relocations for references to other
+ /// .debug_* sections.
+ bool DwarfUsesRelocationsAcrossSections = true;
+
+ /// True if DWARF FDE symbol reference relocations should be replaced by an
+ /// absolute difference.
+ bool DwarfFDESymbolsUseAbsDiff = false;
+
+ /// True if dwarf register numbers are printed instead of symbolic register
+ /// names in .cfi_* directives. Defaults to false.
+ bool DwarfRegNumForCFI = false;
+
+ /// True if target uses parens to indicate the symbol variant instead of @.
+ /// For example, foo(plt) instead of foo@plt. Defaults to false.
+ bool UseParensForSymbolVariant = false;
+
+ /// True if the target supports flags in ".loc" directive, false if only
+ /// location is allowed.
+ bool SupportsExtendedDwarfLocDirective = true;
+
+ //===--- Prologue State ----------------------------------------------===//
+
+ std::vector<MCCFIInstruction> InitialFrameState;
+
+ //===--- Integrated Assembler Information ----------------------------===//
+
+ /// Should we use the integrated assembler?
+ /// The integrated assembler should be enabled by default (by the
+ /// constructors) when failing to parse a valid piece of assembly (inline
+ /// or otherwise) is considered a bug. It may then be overridden after
+ /// construction (see LLVMTargetMachine::initAsmInfo()).
+ bool UseIntegratedAssembler;
+
+ /// Preserve Comments in assembly
+ bool PreserveAsmComments;
+
+ /// Compress DWARF debug sections. Defaults to no compression.
+ DebugCompressionType CompressDebugSections = DebugCompressionType::None;
+
+ /// True if the integrated assembler should interpret 'a >> b' constant
+ /// expressions as logical rather than arithmetic.
+ bool UseLogicalShr = true;
+
+ // If true, emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL, on
+ // X86_64 ELF.
+ bool RelaxELFRelocations = true;
+
+ // If true, then the lexer and expression parser will support %neg(),
+ // %hi(), and similar unary operators.
+ bool HasMipsExpressions = false;
+
+public:
+ explicit MCAsmInfo();
+ virtual ~MCAsmInfo();
+
+ /// Get the code pointer size in bytes.
+ unsigned getCodePointerSize() const { return CodePointerSize; }
+
+ /// Get the callee-saved register stack slot
+ /// size in bytes.
+ unsigned getCalleeSaveStackSlotSize() const {
+ return CalleeSaveStackSlotSize;
+ }
+
+ /// True if the target is little endian.
+ bool isLittleEndian() const { return IsLittleEndian; }
+
+ /// True if target stack grow up.
+ bool isStackGrowthDirectionUp() const { return StackGrowsUp; }
+
+ bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
+
+ // Data directive accessors.
+
+ const char *getData8bitsDirective() const { return Data8bitsDirective; }
+ const char *getData16bitsDirective() const { return Data16bitsDirective; }
+ const char *getData32bitsDirective() const { return Data32bitsDirective; }
+ const char *getData64bitsDirective() const { return Data64bitsDirective; }
+ const char *getGPRel64Directive() const { return GPRel64Directive; }
+ const char *getGPRel32Directive() const { return GPRel32Directive; }
+ const char *getDTPRel64Directive() const { return DTPRel64Directive; }
+ const char *getDTPRel32Directive() const { return DTPRel32Directive; }
+ const char *getTPRel64Directive() const { return TPRel64Directive; }
+ const char *getTPRel32Directive() const { return TPRel32Directive; }
+
+ /// 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 MCSection *getNonexecutableStackSection(MCContext &Ctx) const {
+ return nullptr;
+ }
+
+ /// True if the section is atomized using the symbols in it.
+ /// This is false if the section is not atomized at all (most ELF sections) or
+ /// if it is atomized based on its contents (MachO' __TEXT,__cstring for
+ /// example).
+ virtual bool isSectionAtomizableBySymbols(const MCSection &Section) const;
+
+ virtual const MCExpr *getExprForPersonalitySymbol(const MCSymbol *Sym,
+ unsigned Encoding,
+ MCStreamer &Streamer) const;
+
+ virtual const MCExpr *getExprForFDESymbol(const MCSymbol *Sym,
+ unsigned Encoding,
+ MCStreamer &Streamer) const;
+
+ /// Return true if the identifier \p Name does not need quotes to be
+ /// syntactically correct.
+ virtual bool isValidUnquotedName(StringRef Name) const;
+
+ /// Return true if the .section directive should be omitted when
+ /// emitting \p SectionName. For example:
+ ///
+ /// shouldOmitSectionDirective(".text")
+ ///
+ /// returns false => .section .text,#alloc,#execinstr
+ /// returns true => .text
+ virtual bool shouldOmitSectionDirective(StringRef SectionName) const;
+
+ bool usesSunStyleELFSectionSwitchSyntax() const {
+ return SunStyleELFSectionSwitchSyntax;
+ }
+
+ bool usesELFSectionDirectiveForBSS() const {
+ return UsesELFSectionDirectiveForBSS;
+ }
+
+ bool needsDwarfSectionOffsetDirective() const {
+ return NeedsDwarfSectionOffsetDirective;
+ }
+
+ // Accessors.
+
+ bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; }
+ bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; }
+ bool hasCOFFAssociativeComdats() const { return HasCOFFAssociativeComdats; }
+ bool hasCOFFComdatConstants() const { return HasCOFFComdatConstants; }
+ unsigned getMaxInstLength() const { return MaxInstLength; }
+ unsigned getMinInstAlignment() const { return MinInstAlignment; }
+ bool getDollarIsPC() const { return DollarIsPC; }
+ const char *getSeparatorString() const { return SeparatorString; }
+
+ /// This indicates the column (zero-based) at which asm comments should be
+ /// printed.
+ unsigned getCommentColumn() const { return 40; }
+
+ StringRef getCommentString() const { return CommentString; }
+ const char *getLabelSuffix() const { return LabelSuffix; }
+
+ bool useAssignmentForEHBegin() const { return UseAssignmentForEHBegin; }
+ bool needsLocalForSize() const { return NeedsLocalForSize; }
+ StringRef getPrivateGlobalPrefix() const { return PrivateGlobalPrefix; }
+ StringRef getPrivateLabelPrefix() const { return PrivateLabelPrefix; }
+
+ bool hasLinkerPrivateGlobalPrefix() const {
+ return !LinkerPrivateGlobalPrefix.empty();
+ }
+
+ StringRef getLinkerPrivateGlobalPrefix() const {
+ if (hasLinkerPrivateGlobalPrefix())
+ return LinkerPrivateGlobalPrefix;
+ return getPrivateGlobalPrefix();
+ }
+
+ const char *getInlineAsmStart() const { return InlineAsmStart; }
+ const char *getInlineAsmEnd() const { return InlineAsmEnd; }
+ const char *getCode16Directive() const { return Code16Directive; }
+ const char *getCode32Directive() const { return Code32Directive; }
+ const char *getCode64Directive() const { return Code64Directive; }
+ unsigned getAssemblerDialect() const { return AssemblerDialect; }
+ bool doesAllowAtInName() const { return AllowAtInName; }
+ bool supportsNameQuoting() const { return SupportsQuotedNames; }
+
+ bool doesSupportDataRegionDirectives() const {
+ return UseDataRegionDirectives;
+ }
+
+ const char *getZeroDirective() const { return ZeroDirective; }
+ const char *getAsciiDirective() const { return AsciiDirective; }
+ const char *getAscizDirective() const { return AscizDirective; }
+ bool getAlignmentIsInBytes() const { return AlignmentIsInBytes; }
+ unsigned getTextAlignFillValue() const { return TextAlignFillValue; }
+ const char *getGlobalDirective() const { return GlobalDirective; }
+
+ bool doesSetDirectiveSuppressReloc() const {
+ return SetDirectiveSuppressesReloc;
+ }
+
+ bool hasAggressiveSymbolFolding() const { return HasAggressiveSymbolFolding; }
+
+ bool getCOMMDirectiveAlignmentIsInBytes() const {
+ return COMMDirectiveAlignmentIsInBytes;
+ }
+
+ 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; }
+ bool hasNoDeadStrip() const { return HasNoDeadStrip; }
+ bool hasAltEntry() const { return HasAltEntry; }
+ const char *getWeakDirective() const { return WeakDirective; }
+ const char *getWeakRefDirective() const { return WeakRefDirective; }
+ bool hasWeakDefDirective() const { return HasWeakDefDirective; }
+
+ bool hasWeakDefCanBeHiddenDirective() const {
+ return HasWeakDefCanBeHiddenDirective;
+ }
+
+ bool hasLinkOnceDirective() const { return HasLinkOnceDirective; }
+
+ MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr; }
+
+ MCSymbolAttr getHiddenDeclarationVisibilityAttr() const {
+ return HiddenDeclarationVisibilityAttr;
+ }
+
+ MCSymbolAttr getProtectedVisibilityAttr() const {
+ return ProtectedVisibilityAttr;
+ }
+
+ bool doesSupportDebugInformation() const { return SupportsDebugInformation; }
+
+ bool doesSupportExceptionHandling() const {
+ return ExceptionsType != ExceptionHandling::None;
+ }
+
+ ExceptionHandling getExceptionHandlingType() const { return ExceptionsType; }
+ WinEH::EncodingType getWinEHEncodingType() const { return WinEHEncodingType; }
+
+ void setExceptionsType(ExceptionHandling EH) {
+ ExceptionsType = EH;
+ }
+
+ /// 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 || usesWindowsCFI());
+ }
+
+ bool usesWindowsCFI() const {
+ return ExceptionsType == ExceptionHandling::WinEH &&
+ (WinEHEncodingType != WinEH::EncodingType::Invalid &&
+ WinEHEncodingType != WinEH::EncodingType::X86);
+ }
+
+ bool doesDwarfUseRelocationsAcrossSections() const {
+ return DwarfUsesRelocationsAcrossSections;
+ }
+
+ bool doDwarfFDESymbolsUseAbsDiff() const { return DwarfFDESymbolsUseAbsDiff; }
+ bool useDwarfRegNumForCFI() const { return DwarfRegNumForCFI; }
+ bool useParensForSymbolVariant() const { return UseParensForSymbolVariant; }
+ bool supportsExtendedDwarfLocDirective() const {
+ return SupportsExtendedDwarfLocDirective;
+ }
+
+ void addInitialFrameState(const MCCFIInstruction &Inst) {
+ InitialFrameState.push_back(Inst);
+ }
+
+ const std::vector<MCCFIInstruction> &getInitialFrameState() const {
+ return InitialFrameState;
+ }
+
+ /// Return true if assembly (inline or otherwise) should be parsed.
+ bool useIntegratedAssembler() const { return UseIntegratedAssembler; }
+
+ /// Set whether assembly (inline or otherwise) should be parsed.
+ virtual void setUseIntegratedAssembler(bool Value) {
+ UseIntegratedAssembler = Value;
+ }
+
+ /// Return true if assembly (inline or otherwise) should be parsed.
+ bool preserveAsmComments() const { return PreserveAsmComments; }
+
+ /// Set whether assembly (inline or otherwise) should be parsed.
+ virtual void setPreserveAsmComments(bool Value) {
+ PreserveAsmComments = Value;
+ }
+
+ DebugCompressionType compressDebugSections() const {
+ return CompressDebugSections;
+ }
+
+ void setCompressDebugSections(DebugCompressionType CompressDebugSections) {
+ this->CompressDebugSections = CompressDebugSections;
+ }
+
+ bool shouldUseLogicalShr() const { return UseLogicalShr; }
+
+ bool canRelaxRelocations() const { return RelaxELFRelocations; }
+ void setRelaxELFRelocations(bool V) { RelaxELFRelocations = V; }
+ bool hasMipsExpressions() const { return HasMipsExpressions; }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCASMINFO_H
diff --git a/clang-r353983/include/llvm/MC/MCAsmInfoCOFF.h b/clang-r353983/include/llvm/MC/MCAsmInfoCOFF.h
new file mode 100644
index 00000000..1dfb4750
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCAsmInfoCOFF.h
@@ -0,0 +1,39 @@
+//===- MCAsmInfoCOFF.h - COFF asm properties --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMINFOCOFF_H
+#define LLVM_MC_MCASMINFOCOFF_H
+
+#include "llvm/MC/MCAsmInfo.h"
+
+namespace llvm {
+
+class MCAsmInfoCOFF : public MCAsmInfo {
+ virtual void anchor();
+
+protected:
+ explicit MCAsmInfoCOFF();
+};
+
+class MCAsmInfoMicrosoft : public MCAsmInfoCOFF {
+ void anchor() override;
+
+protected:
+ explicit MCAsmInfoMicrosoft();
+};
+
+class MCAsmInfoGNUCOFF : public MCAsmInfoCOFF {
+ void anchor() override;
+
+protected:
+ explicit MCAsmInfoGNUCOFF();
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCASMINFOCOFF_H
diff --git a/clang-r353983/include/llvm/MC/MCAsmInfoDarwin.h b/clang-r353983/include/llvm/MC/MCAsmInfoDarwin.h
new file mode 100644
index 00000000..c889ce99
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCAsmInfoDarwin.h
@@ -0,0 +1,30 @@
+//===- MCAsmInfoDarwin.h - Darwin asm properties ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines target asm properties related what form asm statements
+// should take in general on Darwin-based targets
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMINFODARWIN_H
+#define LLVM_MC_MCASMINFODARWIN_H
+
+#include "llvm/MC/MCAsmInfo.h"
+
+namespace llvm {
+
+class MCAsmInfoDarwin : public MCAsmInfo {
+public:
+ explicit MCAsmInfoDarwin();
+
+ bool isSectionAtomizableBySymbols(const MCSection &Section) const override;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCASMINFODARWIN_H
diff --git a/clang-r353983/include/llvm/MC/MCAsmInfoELF.h b/clang-r353983/include/llvm/MC/MCAsmInfoELF.h
new file mode 100644
index 00000000..aa2e5873
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCAsmInfoELF.h
@@ -0,0 +1,30 @@
+//===- llvm/MC/MCAsmInfoELF.h - ELF Asm info --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMINFOELF_H
+#define LLVM_MC_MCASMINFOELF_H
+
+#include "llvm/MC/MCAsmInfo.h"
+
+namespace llvm {
+
+class MCAsmInfoELF : public MCAsmInfo {
+ virtual void anchor();
+ MCSection *getNonexecutableStackSection(MCContext &Ctx) const final;
+
+protected:
+ /// Targets which have non-executable stacks by default can set this to false
+ /// to disable the special section which requests a non-executable stack.
+ bool UsesNonexecutableStackSection = true;
+
+ MCAsmInfoELF();
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCASMINFOELF_H
diff --git a/clang-r353983/include/llvm/MC/MCAsmInfoWasm.h b/clang-r353983/include/llvm/MC/MCAsmInfoWasm.h
new file mode 100644
index 00000000..3afc610b
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCAsmInfoWasm.h
@@ -0,0 +1,23 @@
+//===-- llvm/MC/MCAsmInfoWasm.h - Wasm Asm info -----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMINFOWASM_H
+#define LLVM_MC_MCASMINFOWASM_H
+
+#include "llvm/MC/MCAsmInfo.h"
+
+namespace llvm {
+class MCAsmInfoWasm : public MCAsmInfo {
+ virtual void anchor();
+
+protected:
+ MCAsmInfoWasm();
+};
+} // namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCAsmLayout.h b/clang-r353983/include/llvm/MC/MCAsmLayout.h
new file mode 100644
index 00000000..45ac96f0
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCAsmLayout.h
@@ -0,0 +1,106 @@
+//===- MCAsmLayout.h - Assembly Layout Object -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMLAYOUT_H
+#define LLVM_MC_MCASMLAYOUT_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+class MCAssembler;
+class MCFragment;
+class MCSection;
+class MCSymbol;
+
+/// Encapsulates the layout of an assembly file at a particular point in time.
+///
+/// Assembly may require computing multiple layouts for a particular assembly
+/// file as part of the relaxation process. This class encapsulates the layout
+/// at a single point in time in such a way that it is always possible to
+/// efficiently compute the exact address of any symbol in the assembly file,
+/// even during the relaxation process.
+class MCAsmLayout {
+ MCAssembler &Assembler;
+
+ /// List of sections in layout order.
+ 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 MCSection *, MCFragment *> LastValidFragment;
+
+ /// Make sure that the layout for the given fragment is valid, lazily
+ /// computing it if necessary.
+ void ensureValid(const MCFragment *F) const;
+
+ /// Is the layout for this fragment valid?
+ bool isFragmentValid(const MCFragment *F) const;
+
+public:
+ MCAsmLayout(MCAssembler &Assembler);
+
+ /// Get the assembler object this is a layout for.
+ MCAssembler &getAssembler() const { return Assembler; }
+
+ /// Invalidate the fragments starting with F because it has been
+ /// resized. The fragment's size should have already been updated, but
+ /// its bundle padding will be recomputed.
+ void invalidateFragmentsFrom(MCFragment *F);
+
+ /// Perform layout for a single fragment, assuming that the previous
+ /// fragment has already been laid out correctly, and the parent section has
+ /// been initialized.
+ void layoutFragment(MCFragment *Fragment);
+
+ /// \name Section Access (in layout order)
+ /// @{
+
+ llvm::SmallVectorImpl<MCSection *> &getSectionOrder() { return SectionOrder; }
+ const llvm::SmallVectorImpl<MCSection *> &getSectionOrder() const {
+ return SectionOrder;
+ }
+
+ /// @}
+ /// \name Fragment Layout Data
+ /// @{
+
+ /// Get the offset of the given fragment inside its containing section.
+ uint64_t getFragmentOffset(const MCFragment *F) const;
+
+ /// @}
+ /// \name Utility Functions
+ /// @{
+
+ /// 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 MCSection *Sec) const;
+
+ /// 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 MCSection *Sec) const;
+
+ /// Get the offset of the given symbol, as computed in the current
+ /// layout.
+ /// \return True on success.
+ bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const;
+
+ /// Variant that reports a fatal error if the offset is not computable.
+ uint64_t getSymbolOffset(const MCSymbol &S) const;
+
+ /// If this symbol is equivalent to A + Constant, return A.
+ const MCSymbol *getBaseSymbol(const MCSymbol &Symbol) const;
+
+ /// @}
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCAsmMacro.h b/clang-r353983/include/llvm/MC/MCAsmMacro.h
new file mode 100644
index 00000000..364d3b5f
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCAsmMacro.h
@@ -0,0 +1,157 @@
+//===- MCAsmMacro.h - Assembly Macros ---------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMMACRO_H
+#define LLVM_MC_MCASMMACRO_H
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/SMLoc.h"
+#include <vector>
+
+namespace llvm {
+
+/// Target independent representation for an assembler token.
+class AsmToken {
+public:
+ enum TokenKind {
+ // Markers
+ Eof, Error,
+
+ // String values.
+ Identifier,
+ String,
+
+ // Integer values.
+ Integer,
+ BigNum, // larger than 64 bits
+
+ // Real values.
+ Real,
+
+ // Comments
+ Comment,
+ HashDirective,
+ // No-value.
+ EndOfStatement,
+ Colon,
+ Space,
+ Plus, Minus, Tilde,
+ Slash, // '/'
+ BackSlash, // '\'
+ LParen, RParen, LBrac, RBrac, LCurly, RCurly,
+ Star, Dot, Comma, Dollar, Equal, EqualEqual,
+
+ Pipe, PipePipe, Caret,
+ Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash,
+ Less, LessEqual, LessLess, LessGreater,
+ Greater, GreaterEqual, GreaterGreater, At, MinusGreater,
+
+ // MIPS unary expression operators such as %neg.
+ PercentCall16, PercentCall_Hi, PercentCall_Lo, PercentDtprel_Hi,
+ PercentDtprel_Lo, PercentGot, PercentGot_Disp, PercentGot_Hi, PercentGot_Lo,
+ PercentGot_Ofst, PercentGot_Page, PercentGottprel, PercentGp_Rel, PercentHi,
+ PercentHigher, PercentHighest, PercentLo, PercentNeg, PercentPcrel_Hi,
+ PercentPcrel_Lo, PercentTlsgd, PercentTlsldm, PercentTprel_Hi,
+ PercentTprel_Lo
+ };
+
+private:
+ TokenKind Kind;
+
+ /// A reference to the entire token contents; this is always a pointer into
+ /// a memory buffer owned by the source manager.
+ StringRef Str;
+
+ APInt IntVal;
+
+public:
+ AsmToken() = default;
+ AsmToken(TokenKind Kind, StringRef Str, APInt IntVal)
+ : Kind(Kind), Str(Str), IntVal(std::move(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; }
+ bool isNot(TokenKind K) const { return Kind != K; }
+
+ SMLoc getLoc() const;
+ SMLoc getEndLoc() const;
+ SMRange getLocRange() const;
+
+ /// Get the contents of a string token (without quotes).
+ StringRef getStringContents() const {
+ assert(Kind == String && "This token isn't a string!");
+ return Str.slice(1, Str.size() - 1);
+ }
+
+ /// Get the identifier string for the current token, which should be an
+ /// identifier or a string. This gets the portion of the string which should
+ /// be used as the identifier, e.g., it does not include the quotes on
+ /// strings.
+ StringRef getIdentifier() const {
+ if (Kind == Identifier)
+ return getString();
+ return getStringContents();
+ }
+
+ /// Get the string for the current token, this includes all characters (for
+ /// example, the quotes on strings) in the token.
+ ///
+ /// The returned StringRef points into the source manager's memory buffer, and
+ /// is safe to store across calls to Lex().
+ StringRef getString() const { return Str; }
+
+ // FIXME: Don't compute this in advance, it makes every token larger, and is
+ // also not generally what we want (it is nicer for recovery etc. to lex 123br
+ // as a single token, then diagnose as an invalid number).
+ int64_t getIntVal() const {
+ assert(Kind == Integer && "This token isn't an integer!");
+ return IntVal.getZExtValue();
+ }
+
+ APInt getAPIntVal() const {
+ assert((Kind == Integer || Kind == BigNum) &&
+ "This token isn't an integer!");
+ return IntVal;
+ }
+
+ void dump(raw_ostream &OS) const;
+ void dump() const { dump(dbgs()); }
+};
+
+struct MCAsmMacroParameter {
+ StringRef Name;
+ std::vector<AsmToken> Value;
+ bool Required = false;
+ bool Vararg = false;
+
+ MCAsmMacroParameter() = default;
+
+ void dump() const { dump(dbgs()); }
+ void dump(raw_ostream &OS) const;
+};
+
+typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters;
+struct MCAsmMacro {
+ StringRef Name;
+ StringRef Body;
+ MCAsmMacroParameters Parameters;
+
+public:
+ MCAsmMacro(StringRef N, StringRef B, MCAsmMacroParameters P)
+ : Name(N), Body(B), Parameters(std::move(P)) {}
+
+ void dump() const { dump(dbgs()); }
+ void dump(raw_ostream &OS) const;
+};
+} // namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCAssembler.h b/clang-r353983/include/llvm/MC/MCAssembler.h
new file mode 100644
index 00000000..45430189
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCAssembler.h
@@ -0,0 +1,468 @@
+//===- MCAssembler.h - Object File Generation -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASSEMBLER_H
+#define LLVM_MC_MCASSEMBLER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCFragment.h"
+#include "llvm/MC/MCLinkerOptimizationHint.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/VersionTuple.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+class MCAsmBackend;
+class MCAsmLayout;
+class MCContext;
+class MCCodeEmitter;
+class MCFragment;
+class MCObjectWriter;
+class MCSection;
+class MCValue;
+
+// FIXME: This really doesn't belong here. See comments below.
+struct IndirectSymbolData {
+ MCSymbol *Symbol;
+ MCSection *Section;
+};
+
+// FIXME: Ditto this. Purely so the Streamer and the ObjectWriter can talk
+// to one another.
+struct DataRegionData {
+ // This enum should be kept in sync w/ the mach-o definition in
+ // llvm/Object/MachOFormat.h.
+ enum KindTy { Data = 1, JumpTable8, JumpTable16, JumpTable32 } Kind;
+ MCSymbol *Start;
+ MCSymbol *End;
+};
+
+class MCAssembler {
+ friend class MCAsmLayout;
+
+public:
+ using SectionListType = std::vector<MCSection *>;
+ using SymbolDataListType = std::vector<const MCSymbol *>;
+
+ using const_iterator = pointee_iterator<SectionListType::const_iterator>;
+ using iterator = pointee_iterator<SectionListType::iterator>;
+
+ using const_symbol_iterator =
+ pointee_iterator<SymbolDataListType::const_iterator>;
+ using symbol_iterator = pointee_iterator<SymbolDataListType::iterator>;
+
+ using symbol_range = iterator_range<symbol_iterator>;
+ using const_symbol_range = iterator_range<const_symbol_iterator>;
+
+ using const_indirect_symbol_iterator =
+ std::vector<IndirectSymbolData>::const_iterator;
+ using indirect_symbol_iterator = std::vector<IndirectSymbolData>::iterator;
+
+ using const_data_region_iterator =
+ std::vector<DataRegionData>::const_iterator;
+ using data_region_iterator = std::vector<DataRegionData>::iterator;
+
+ /// MachO specific deployment target version info.
+ // A Major version of 0 indicates that no version information was supplied
+ // and so the corresponding load command should not be emitted.
+ using VersionInfoType = struct {
+ bool EmitBuildVersion;
+ union {
+ MCVersionMinType Type; ///< Used when EmitBuildVersion==false.
+ MachO::PlatformType Platform; ///< Used when EmitBuildVersion==true.
+ } TypeOrPlatform;
+ unsigned Major;
+ unsigned Minor;
+ unsigned Update;
+ /// An optional version of the SDK that was used to build the source.
+ VersionTuple SDKVersion;
+ };
+
+private:
+ MCContext &Context;
+
+ std::unique_ptr<MCAsmBackend> Backend;
+
+ std::unique_ptr<MCCodeEmitter> Emitter;
+
+ std::unique_ptr<MCObjectWriter> Writer;
+
+ SectionListType Sections;
+
+ SymbolDataListType Symbols;
+
+ 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;
+
+ /// List of declared file names
+ std::vector<std::string> FileNames;
+
+ MCDwarfLineTableParams LTParams;
+
+ /// The set of function symbols for which a .thumb_func directive has
+ /// been seen.
+ //
+ // FIXME: We really would like this in target specific code rather than
+ // here. Maybe when the relocation stuff moves to target specific,
+ // this can go with it? The streamer would need some target specific
+ // refactoring too.
+ mutable SmallPtrSet<const MCSymbol *, 32> ThumbFuncs;
+
+ /// The bundle alignment size currently set in the assembler.
+ ///
+ /// By default it's 0, which means bundling is disabled.
+ unsigned BundleAlignSize;
+
+ bool RelaxAll : 1;
+ bool SubsectionsViaSymbols : 1;
+ bool IncrementalLinkerCompatible : 1;
+
+ /// ELF specific e_header flags
+ // It would be good if there were an MCELFAssembler class to hold this.
+ // ELF header flags are used both by the integrated and standalone assemblers.
+ // Access to the flags is necessary in cases where assembler directives affect
+ // which flags to be set.
+ unsigned ELFHeaderEFlags;
+
+ /// Used to communicate Linker Optimization Hint information between
+ /// the Streamer and the .o writer
+ MCLOHContainer LOHContainer;
+
+ VersionInfoType VersionInfo;
+
+ /// Evaluate a fixup to a relocatable expression and the value which should be
+ /// placed into the fixup.
+ ///
+ /// \param Layout The layout to use for evaluation.
+ /// \param Fixup The fixup to evaluate.
+ /// \param DF The fragment the fixup is inside.
+ /// \param Target [out] On return, the relocatable expression the fixup
+ /// evaluates to.
+ /// \param Value [out] On return, the value of the fixup as currently laid
+ /// out.
+ /// \param WasForced [out] On return, the value in the fixup is set to the
+ /// correct value if WasForced is true, even if evaluateFixup returns false.
+ /// \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, bool &WasForced) 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).
+ bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF,
+ const MCAsmLayout &Layout) const;
+
+ /// Check whether the given fragment needs relaxation.
+ bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF,
+ const MCAsmLayout &Layout) const;
+
+ /// Perform one layout iteration and return true if any offsets
+ /// were adjusted.
+ bool layoutOnce(MCAsmLayout &Layout);
+
+ /// Perform one layout iteration of the given section and return true
+ /// if any offsets were adjusted.
+ bool layoutSectionOnce(MCAsmLayout &Layout, MCSection &Sec);
+
+ bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF);
+
+ bool relaxPaddingFragment(MCAsmLayout &Layout, MCPaddingFragment &PF);
+
+ bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
+
+ bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF);
+ bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
+ MCDwarfCallFrameFragment &DF);
+ bool relaxCVInlineLineTable(MCAsmLayout &Layout,
+ MCCVInlineLineTableFragment &DF);
+ bool relaxCVDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &DF);
+
+ /// finishLayout - Finalize a layout, including fragment lowering.
+ void finishLayout(MCAsmLayout &Layout);
+
+ std::tuple<MCValue, uint64_t, bool>
+ handleFixup(const MCAsmLayout &Layout, MCFragment &F, const MCFixup &Fixup);
+
+public:
+ std::vector<std::pair<StringRef, const MCSymbol *>> Symvers;
+
+ /// Construct a new assembler instance.
+ //
+ // FIXME: How are we going to parameterize this? Two obvious options are stay
+ // concrete and require clients to pass in a target like object. The other
+ // option is to make this abstract, and have targets provide concrete
+ // implementations as we do with AsmParser.
+ MCAssembler(MCContext &Context, std::unique_ptr<MCAsmBackend> Backend,
+ std::unique_ptr<MCCodeEmitter> Emitter,
+ std::unique_ptr<MCObjectWriter> Writer);
+ MCAssembler(const MCAssembler &) = delete;
+ MCAssembler &operator=(const MCAssembler &) = delete;
+ ~MCAssembler();
+
+ /// Compute the effective fragment size assuming it is laid out at the given
+ /// \p SectionAddress and \p FragmentOffset.
+ uint64_t computeFragmentSize(const MCAsmLayout &Layout,
+ const MCFragment &F) const;
+
+ /// Find the symbol which defines the atom containing the given symbol, or
+ /// null if there is no such symbol.
+ const 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
+ /// also effects whether the assembler treats the label as potentially
+ /// defining a separate atom.
+ bool isSymbolLinkerVisible(const MCSymbol &SD) const;
+
+ /// Emit the section contents to \p OS.
+ void writeSectionData(raw_ostream &OS, const MCSection *Section,
+ const MCAsmLayout &Layout) const;
+
+ /// Check whether a given symbol has been flagged with .thumb_func.
+ bool isThumbFunc(const MCSymbol *Func) const;
+
+ /// Flag a function symbol as the target of a .thumb_func directive.
+ void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
+
+ /// ELF e_header flags
+ unsigned getELFHeaderEFlags() const { return ELFHeaderEFlags; }
+ void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags; }
+
+ /// MachO deployment target version information.
+ const VersionInfoType &getVersionInfo() const { return VersionInfo; }
+ void setVersionMin(MCVersionMinType Type, unsigned Major, unsigned Minor,
+ unsigned Update,
+ VersionTuple SDKVersion = VersionTuple()) {
+ VersionInfo.EmitBuildVersion = false;
+ VersionInfo.TypeOrPlatform.Type = Type;
+ VersionInfo.Major = Major;
+ VersionInfo.Minor = Minor;
+ VersionInfo.Update = Update;
+ VersionInfo.SDKVersion = SDKVersion;
+ }
+ void setBuildVersion(MachO::PlatformType Platform, unsigned Major,
+ unsigned Minor, unsigned Update,
+ VersionTuple SDKVersion = VersionTuple()) {
+ VersionInfo.EmitBuildVersion = true;
+ VersionInfo.TypeOrPlatform.Platform = Platform;
+ VersionInfo.Major = Major;
+ VersionInfo.Minor = Minor;
+ VersionInfo.Update = Update;
+ VersionInfo.SDKVersion = SDKVersion;
+ }
+
+ /// Reuse an assembler instance
+ ///
+ void reset();
+
+ MCContext &getContext() const { return Context; }
+
+ MCAsmBackend *getBackendPtr() const { return Backend.get(); }
+
+ MCCodeEmitter *getEmitterPtr() const { return Emitter.get(); }
+
+ MCObjectWriter *getWriterPtr() const { return Writer.get(); }
+
+ MCAsmBackend &getBackend() const { return *Backend; }
+
+ MCCodeEmitter &getEmitter() const { return *Emitter; }
+
+ MCObjectWriter &getWriter() const { return *Writer; }
+
+ MCDwarfLineTableParams getDWARFLinetableParams() const { return LTParams; }
+ void setDWARFLinetableParams(MCDwarfLineTableParams P) { LTParams = P; }
+
+ /// Finish - Do final processing and write the object to the output stream.
+ /// \p Writer is used for custom object writer (as the MCJIT does),
+ /// if not specified it is automatically created from backend.
+ void Finish();
+
+ // Layout all section and prepare them for emission.
+ void layout(MCAsmLayout &Layout);
+
+ // FIXME: This does not belong here.
+ bool getSubsectionsViaSymbols() const { return SubsectionsViaSymbols; }
+ void setSubsectionsViaSymbols(bool Value) { SubsectionsViaSymbols = Value; }
+
+ bool isIncrementalLinkerCompatible() const {
+ return IncrementalLinkerCompatible;
+ }
+ void setIncrementalLinkerCompatible(bool Value) {
+ IncrementalLinkerCompatible = Value;
+ }
+
+ bool getRelaxAll() const { return RelaxAll; }
+ void setRelaxAll(bool Value) { RelaxAll = Value; }
+
+ bool isBundlingEnabled() const { return BundleAlignSize != 0; }
+
+ unsigned getBundleAlignSize() const { return BundleAlignSize; }
+
+ void setBundleAlignSize(unsigned Size) {
+ assert((Size == 0 || !(Size & (Size - 1))) &&
+ "Expect a power-of-two bundle align size");
+ BundleAlignSize = Size;
+ }
+
+ /// \name Section List Access
+ /// @{
+
+ iterator begin() { return Sections.begin(); }
+ const_iterator begin() const { return Sections.begin(); }
+
+ iterator end() { return Sections.end(); }
+ const_iterator end() const { return Sections.end(); }
+
+ size_t size() const { return Sections.size(); }
+
+ /// @}
+ /// \name Symbol List Access
+ /// @{
+ symbol_iterator symbol_begin() { return Symbols.begin(); }
+ const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
+
+ symbol_iterator symbol_end() { return Symbols.end(); }
+ const_symbol_iterator symbol_end() const { return Symbols.end(); }
+
+ symbol_range symbols() { return make_range(symbol_begin(), symbol_end()); }
+ const_symbol_range symbols() const {
+ return make_range(symbol_begin(), symbol_end());
+ }
+
+ size_t symbol_size() const { return Symbols.size(); }
+
+ /// @}
+ /// \name Indirect Symbol 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<IndirectSymbolData> &getIndirectSymbols() {
+ return IndirectSymbols;
+ }
+
+ indirect_symbol_iterator indirect_symbol_begin() {
+ return IndirectSymbols.begin();
+ }
+ const_indirect_symbol_iterator indirect_symbol_begin() const {
+ return IndirectSymbols.begin();
+ }
+
+ indirect_symbol_iterator indirect_symbol_end() {
+ return IndirectSymbols.end();
+ }
+ const_indirect_symbol_iterator indirect_symbol_end() const {
+ return IndirectSymbols.end();
+ }
+
+ size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
+
+ /// @}
+ /// \name Linker Option List Access
+ /// @{
+
+ std::vector<std::vector<std::string>> &getLinkerOptions() {
+ return LinkerOptions;
+ }
+
+ /// @}
+ /// \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; }
+
+ 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(); }
+ const_data_region_iterator data_region_end() const {
+ return DataRegions.end();
+ }
+
+ size_t data_region_size() const { return DataRegions.size(); }
+
+ /// @}
+ /// \name Data Region List Access
+ /// @{
+
+ // FIXME: This is a total hack, this should not be here. Once things are
+ // factored so that the streamer has direct access to the .o writer, it can
+ // disappear.
+ MCLOHContainer &getLOHContainer() { return LOHContainer; }
+ const MCLOHContainer &getLOHContainer() const {
+ return const_cast<MCAssembler *>(this)->getLOHContainer();
+ }
+
+ struct CGProfileEntry {
+ const MCSymbolRefExpr *From;
+ const MCSymbolRefExpr *To;
+ uint64_t Count;
+ };
+ std::vector<CGProfileEntry> CGProfile;
+ /// @}
+ /// \name Backend Data Access
+ /// @{
+
+ bool registerSection(MCSection &Section);
+
+ void registerSymbol(const MCSymbol &Symbol, bool *Created = nullptr);
+
+ ArrayRef<std::string> getFileNames() { return FileNames; }
+
+ void addFileName(StringRef FileName) {
+ if (!is_contained(FileNames, FileName))
+ FileNames.push_back(FileName);
+ }
+
+ /// Write the necessary bundle padding to \p OS.
+ /// Expects a fragment \p F containing instructions and its size \p FSize.
+ void writeFragmentPadding(raw_ostream &OS, const MCEncodedFragment &F,
+ uint64_t FSize) const;
+
+ /// @}
+
+ void dump() const;
+};
+
+/// 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 MCEncodedFragment *F, uint64_t FOffset,
+ uint64_t FSize);
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCASSEMBLER_H
diff --git a/clang-r353983/include/llvm/MC/MCCodeEmitter.h b/clang-r353983/include/llvm/MC/MCCodeEmitter.h
new file mode 100644
index 00000000..04b4367a
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCCodeEmitter.h
@@ -0,0 +1,42 @@
+//===- llvm/MC/MCCodeEmitter.h - Instruction Encoding -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCCODEEMITTER_H
+#define LLVM_MC_MCCODEEMITTER_H
+
+namespace llvm {
+
+class MCFixup;
+class MCInst;
+class MCSubtargetInfo;
+class raw_ostream;
+template<typename T> class SmallVectorImpl;
+
+/// MCCodeEmitter - Generic instruction encoding interface.
+class MCCodeEmitter {
+protected: // Can only create subclasses.
+ MCCodeEmitter();
+
+public:
+ MCCodeEmitter(const MCCodeEmitter &) = delete;
+ MCCodeEmitter &operator=(const MCCodeEmitter &) = delete;
+ virtual ~MCCodeEmitter();
+
+ /// Lifetime management
+ virtual void reset() {}
+
+ /// EncodeInstruction - Encode the given \p Inst to bytes on the output
+ /// stream \p OS.
+ virtual void encodeInstruction(const MCInst &Inst, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const = 0;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCCODEEMITTER_H
diff --git a/clang-r353983/include/llvm/MC/MCCodePadder.h b/clang-r353983/include/llvm/MC/MCCodePadder.h
new file mode 100644
index 00000000..f7b1a211
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCCodePadder.h
@@ -0,0 +1,241 @@
+//===- llvm/MC/MCCodePadder.h - MC Code Padder ------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCCODEPADDER_H
+#define LLVM_MC_MCCODEPADDER_H
+
+#include "MCFragment.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+
+class MCAsmLayout;
+class MCCodePaddingPolicy;
+class MCFragment;
+class MCInst;
+class MCObjectStreamer;
+class MCSection;
+
+typedef SmallVector<const MCPaddingFragment *, 8> MCPFRange;
+
+struct MCCodePaddingContext {
+ bool IsPaddingActive;
+ bool IsBasicBlockReachableViaFallthrough;
+ bool IsBasicBlockReachableViaBranch;
+};
+
+/// Target-independent base class incharge of all code padding decisions for a
+/// target. During encoding it determines if and where MCPaddingFragments will
+/// be located, as later on, when layout information is available, it determines
+/// their sizes.
+class MCCodePadder {
+ MCCodePadder(const MCCodePadder &) = delete;
+ void operator=(const MCCodePadder &) = delete;
+
+ /// Determines if the MCCodePaddingPolicies are active.
+ bool ArePoliciesActive;
+
+ /// All the supported MCCodePaddingPolicies.
+ SmallPtrSet<MCCodePaddingPolicy *, 4> CodePaddingPolicies;
+
+ /// A pointer to the fragment of the instruction whose padding is currently
+ /// done for.
+ MCPaddingFragment *CurrHandledInstFragment;
+
+ /// A map holding the jurisdiction for each padding fragment. Key: padding
+ /// fragment. Value: The fragment's jurisdiction. A jurisdiction is a vector
+ /// of padding fragments whose conditions are being controlled by another
+ /// fragment, the key fragment.
+ DenseMap<MCPaddingFragment *, MCPFRange> FragmentToJurisdiction;
+ MCPFRange &getJurisdiction(MCPaddingFragment *Fragment, MCAsmLayout &Layout);
+
+ /// A map holding the maximal instruction window size relevant for a padding
+ /// fragment.
+ DenseMap<MCPaddingFragment *, uint64_t> FragmentToMaxWindowSize;
+ uint64_t getMaxWindowSize(MCPaddingFragment *Fragment, MCAsmLayout &Layout);
+
+protected:
+ /// The current streamer, used to stream code padding.
+ MCObjectStreamer *OS;
+
+ bool addPolicy(MCCodePaddingPolicy *Policy);
+
+ virtual bool
+ basicBlockRequiresInsertionPoint(const MCCodePaddingContext &Context) {
+ return false;
+ }
+
+ virtual bool instructionRequiresInsertionPoint(const MCInst &Inst) {
+ return false;
+ }
+
+ virtual bool usePoliciesForBasicBlock(const MCCodePaddingContext &Context) {
+ return Context.IsPaddingActive;
+ }
+
+public:
+ MCCodePadder()
+ : ArePoliciesActive(false), CurrHandledInstFragment(nullptr),
+ OS(nullptr) {}
+ virtual ~MCCodePadder();
+
+ /// Handles all target related code padding when starting to write a new
+ /// basic block to an object file.
+ ///
+ /// \param OS The streamer used for writing the padding data and function.
+ /// \param Context the context of the padding, Embeds the basic block's
+ /// parameters.
+ void handleBasicBlockStart(MCObjectStreamer *OS,
+ const MCCodePaddingContext &Context);
+ /// Handles all target related code padding when done writing a block to an
+ /// object file.
+ ///
+ /// \param Context the context of the padding, Embeds the basic block's
+ /// parameters.
+ void handleBasicBlockEnd(const MCCodePaddingContext &Context);
+ /// Handles all target related code padding before writing a new instruction
+ /// to an object file.
+ ///
+ /// \param Inst the instruction.
+ void handleInstructionBegin(const MCInst &Inst);
+ /// Handles all target related code padding after writing an instruction to an
+ /// object file.
+ ///
+ /// \param Inst the instruction.
+ void handleInstructionEnd(const MCInst &Inst);
+
+ /// Relaxes a fragment (changes the size of the padding) according to target
+ /// requirements. The new size computation is done w.r.t a layout.
+ ///
+ /// \param Fragment The fragment to relax.
+ /// \param Layout Code layout information.
+ ///
+ /// \returns true iff any relaxation occurred.
+ bool relaxFragment(MCPaddingFragment *Fragment, MCAsmLayout &Layout);
+};
+
+/// The base class for all padding policies, i.e. a rule or set of rules to pad
+/// the generated code.
+class MCCodePaddingPolicy {
+ MCCodePaddingPolicy() = delete;
+ MCCodePaddingPolicy(const MCCodePaddingPolicy &) = delete;
+ void operator=(const MCCodePaddingPolicy &) = delete;
+
+protected:
+ /// A mask holding the kind of this policy, i.e. only the i'th bit will be set
+ /// where i is the kind number.
+ const uint64_t KindMask;
+ /// Instruction window size relevant to this policy.
+ const uint64_t WindowSize;
+ /// A boolean indicating which byte of the instruction determies its
+ /// instruction window. If true - the last byte of the instructions, o.w. -
+ /// the first byte of the instruction.
+ const bool InstByteIsLastByte;
+
+ MCCodePaddingPolicy(uint64_t Kind, uint64_t WindowSize,
+ bool InstByteIsLastByte)
+ : KindMask(UINT64_C(1) << Kind), WindowSize(WindowSize),
+ InstByteIsLastByte(InstByteIsLastByte) {}
+
+ /// Computes and returns the offset of the consecutive fragment of a given
+ /// fragment.
+ ///
+ /// \param Fragment The fragment whose consecutive offset will be computed.
+ /// \param Layout Code layout information.
+ ///
+ /// \returns the offset of the consecutive fragment of \p Fragment.
+ static uint64_t getNextFragmentOffset(const MCFragment *Fragment,
+ const MCAsmLayout &Layout);
+ /// Returns the instruction byte of an instruction pointed by a given
+ /// MCPaddingFragment. An instruction byte is the address of the byte of an
+ /// instruction which determines its instruction window.
+ ///
+ /// \param Fragment The fragment pointing to the instruction.
+ /// \param Layout Code layout information.
+ ///
+ /// \returns the instruction byte of an instruction pointed by \p Fragment.
+ uint64_t getFragmentInstByte(const MCPaddingFragment *Fragment,
+ MCAsmLayout &Layout) const;
+ uint64_t computeWindowEndAddress(const MCPaddingFragment *Fragment,
+ uint64_t Offset, MCAsmLayout &Layout) const;
+
+ /// Computes and returns the penalty weight of a first instruction window in a
+ /// range. This requires a special function since the first window does not
+ /// contain all the padding fragments in that window. It only contains all the
+ /// padding fragments starting from the relevant insertion point.
+ ///
+ /// \param Window The first window.
+ /// \param Offset The offset of the parent section relative to the beginning
+ /// of the file, mod the window size.
+ /// \param Layout Code layout information.
+ ///
+ /// \returns the penalty weight of a first instruction window in a range, \p
+ /// Window.
+ double computeFirstWindowPenaltyWeight(const MCPFRange &Window,
+ uint64_t Offset,
+ MCAsmLayout &Layout) const;
+ /// Computes and returns the penalty caused by an instruction window.
+ ///
+ /// \param Window The instruction window.
+ /// \param Offset The offset of the parent section relative to the beginning
+ /// of the file, mod the window size.
+ /// \param Layout Code layout information.
+ ///
+ /// \returns the penalty caused by \p Window.
+ virtual double computeWindowPenaltyWeight(const MCPFRange &Window,
+ uint64_t Offset,
+ MCAsmLayout &Layout) const = 0;
+
+public:
+ virtual ~MCCodePaddingPolicy() {}
+
+ /// Returns the kind mask of this policy - A mask holding the kind of this
+ /// policy, i.e. only the i'th bit will be set where i is the kind number.
+ uint64_t getKindMask() const { return KindMask; }
+ /// Returns the instruction window size relevant to this policy.
+ uint64_t getWindowSize() const { return WindowSize; }
+ /// Returns true if the last byte of an instruction determines its instruction
+ /// window, or false if the first of an instruction determines it.
+ bool isInstByteLastByte() const { return InstByteIsLastByte; }
+
+ /// Returns true iff this policy needs padding for a given basic block.
+ ///
+ /// \param Context the context of the padding, Embeds the basic block's
+ /// parameters.
+ ///
+ /// \returns true iff this policy needs padding for the basic block.
+ virtual bool
+ basicBlockRequiresPaddingFragment(const MCCodePaddingContext &Context) const {
+ return false;
+ }
+ /// Returns true iff this policy needs padding for a given instruction.
+ ///
+ /// \param Inst The given instruction.
+ ///
+ /// \returns true iff this policy needs padding for \p Inst.
+ virtual bool instructionRequiresPaddingFragment(const MCInst &Inst) const {
+ return false;
+ }
+ /// Computes and returns the penalty caused by a range of instruction windows.
+ /// The weight is computed for each window separelty and then accumulated.
+ ///
+ /// \param Range The range.
+ /// \param Offset The offset of the parent section relative to the beginning
+ /// of the file, mod the window size.
+ /// \param Layout Code layout information.
+ ///
+ /// \returns the penalty caused by \p Range.
+ double computeRangePenaltyWeight(const MCPFRange &Range, uint64_t Offset,
+ MCAsmLayout &Layout) const;
+};
+
+} // namespace llvm
+
+#endif // LLVM_MC_MCCODEPADDER_H
diff --git a/clang-r353983/include/llvm/MC/MCCodeView.h b/clang-r353983/include/llvm/MC/MCCodeView.h
new file mode 100644
index 00000000..2126354c
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCCodeView.h
@@ -0,0 +1,264 @@
+//===- MCCodeView.h - Machine Code CodeView support -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Holds state from .cv_file and .cv_loc directives for later emission.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCCODEVIEW_H
+#define LLVM_MC_MCCODEVIEW_H
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCFragment.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include <map>
+#include <vector>
+
+namespace llvm {
+class MCContext;
+class MCObjectStreamer;
+class MCStreamer;
+class CodeViewContext;
+
+/// Instances of this class represent the information from a
+/// .cv_loc directive.
+class MCCVLoc {
+ const MCSymbol *Label = nullptr;
+ uint32_t FunctionId;
+ uint32_t FileNum;
+ uint32_t Line;
+ uint16_t Column;
+ uint16_t PrologueEnd : 1;
+ uint16_t IsStmt : 1;
+
+private: // CodeViewContext manages these
+ friend class CodeViewContext;
+ MCCVLoc(const MCSymbol *Label, unsigned functionid, unsigned fileNum,
+ unsigned line, unsigned column, bool prologueend, bool isstmt)
+ : Label(Label), FunctionId(functionid), FileNum(fileNum), Line(line),
+ Column(column), PrologueEnd(prologueend), IsStmt(isstmt) {}
+
+ // Allow the default copy constructor and assignment operator to be used
+ // for an MCCVLoc object.
+
+public:
+ const MCSymbol *getLabel() const { return Label; }
+
+ unsigned getFunctionId() const { return FunctionId; }
+
+ /// Get the FileNum of this MCCVLoc.
+ unsigned getFileNum() const { return FileNum; }
+
+ /// Get the Line of this MCCVLoc.
+ unsigned getLine() const { return Line; }
+
+ /// Get the Column of this MCCVLoc.
+ unsigned getColumn() const { return Column; }
+
+ bool isPrologueEnd() const { return PrologueEnd; }
+ bool isStmt() const { return IsStmt; }
+
+ void setLabel(const MCSymbol *L) { Label = L; }
+
+ void setFunctionId(unsigned FID) { FunctionId = FID; }
+
+ /// Set the FileNum of this MCCVLoc.
+ void setFileNum(unsigned fileNum) { FileNum = fileNum; }
+
+ /// Set the Line of this MCCVLoc.
+ void setLine(unsigned line) { Line = line; }
+
+ /// Set the Column of this MCCVLoc.
+ void setColumn(unsigned column) {
+ assert(column <= UINT16_MAX);
+ Column = column;
+ }
+
+ void setPrologueEnd(bool PE) { PrologueEnd = PE; }
+ void setIsStmt(bool IS) { IsStmt = IS; }
+};
+
+/// Information describing a function or inlined call site introduced by
+/// .cv_func_id or .cv_inline_site_id. Accumulates information from .cv_loc
+/// directives used with this function's id or the id of an inlined call site
+/// within this function or inlined call site.
+struct MCCVFunctionInfo {
+ /// If this represents an inlined call site, then ParentFuncIdPlusOne will be
+ /// the parent function id plus one. If this represents a normal function,
+ /// then there is no parent, and ParentFuncIdPlusOne will be FunctionSentinel.
+ /// If this struct is an unallocated slot in the function info vector, then
+ /// ParentFuncIdPlusOne will be zero.
+ unsigned ParentFuncIdPlusOne = 0;
+
+ enum : unsigned { FunctionSentinel = ~0U };
+
+ struct LineInfo {
+ unsigned File;
+ unsigned Line;
+ unsigned Col;
+ };
+
+ LineInfo InlinedAt;
+
+ /// The section of the first .cv_loc directive used for this function, or null
+ /// if none has been seen yet.
+ MCSection *Section = nullptr;
+
+ /// Map from inlined call site id to the inlined at location to use for that
+ /// call site. Call chains are collapsed, so for the call chain 'f -> g -> h',
+ /// the InlinedAtMap of 'f' will contain entries for 'g' and 'h' that both
+ /// list the line info for the 'g' call site.
+ DenseMap<unsigned, LineInfo> InlinedAtMap;
+
+ /// Returns true if this is function info has not yet been used in a
+ /// .cv_func_id or .cv_inline_site_id directive.
+ bool isUnallocatedFunctionInfo() const { return ParentFuncIdPlusOne == 0; }
+
+ /// Returns true if this represents an inlined call site, meaning
+ /// ParentFuncIdPlusOne is neither zero nor ~0U.
+ bool isInlinedCallSite() const {
+ return !isUnallocatedFunctionInfo() &&
+ ParentFuncIdPlusOne != FunctionSentinel;
+ }
+
+ unsigned getParentFuncId() const {
+ assert(isInlinedCallSite());
+ return ParentFuncIdPlusOne - 1;
+ }
+};
+
+/// Holds state from .cv_file and .cv_loc directives for later emission.
+class CodeViewContext {
+public:
+ CodeViewContext();
+ ~CodeViewContext();
+
+ bool isValidFileNumber(unsigned FileNumber) const;
+ bool addFile(MCStreamer &OS, unsigned FileNumber, StringRef Filename,
+ ArrayRef<uint8_t> ChecksumBytes, uint8_t ChecksumKind);
+
+ /// Records the function id of a normal function. Returns false if the
+ /// function id has already been used, and true otherwise.
+ bool recordFunctionId(unsigned FuncId);
+
+ /// Records the function id of an inlined call site. Records the "inlined at"
+ /// location info of the call site, including what function or inlined call
+ /// site it was inlined into. Returns false if the function id has already
+ /// been used, and true otherwise.
+ bool recordInlinedCallSiteId(unsigned FuncId, unsigned IAFunc,
+ unsigned IAFile, unsigned IALine,
+ unsigned IACol);
+
+ /// Retreive the function info if this is a valid function id, or nullptr.
+ MCCVFunctionInfo *getCVFunctionInfo(unsigned FuncId);
+
+ /// Saves the information from the currently parsed .cv_loc directive
+ /// and sets CVLocSeen. 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 recordCVLoc(MCContext &Ctx, const MCSymbol *Label, unsigned FunctionId,
+ unsigned FileNo, unsigned Line, unsigned Column,
+ bool PrologueEnd, bool IsStmt);
+
+ bool isValidCVFileNumber(unsigned FileNumber);
+
+ /// Add a line entry.
+ void addLineEntry(const MCCVLoc &LineEntry);
+
+ std::vector<MCCVLoc> getFunctionLineEntries(unsigned FuncId);
+
+ std::pair<size_t, size_t> getLineExtent(unsigned FuncId);
+
+ ArrayRef<MCCVLoc> getLinesForExtent(size_t L, size_t R);
+
+ /// Emits a line table substream.
+ void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId,
+ const MCSymbol *FuncBegin,
+ const MCSymbol *FuncEnd);
+
+ void emitInlineLineTableForFunction(MCObjectStreamer &OS,
+ unsigned PrimaryFunctionId,
+ unsigned SourceFileId,
+ unsigned SourceLineNum,
+ const MCSymbol *FnStartSym,
+ const MCSymbol *FnEndSym);
+
+ /// Encodes the binary annotations once we have a layout.
+ void encodeInlineLineTable(MCAsmLayout &Layout,
+ MCCVInlineLineTableFragment &F);
+
+ MCFragment *
+ emitDefRange(MCObjectStreamer &OS,
+ ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
+ StringRef FixedSizePortion);
+
+ void encodeDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &F);
+
+ /// Emits the string table substream.
+ void emitStringTable(MCObjectStreamer &OS);
+
+ /// Emits the file checksum substream.
+ void emitFileChecksums(MCObjectStreamer &OS);
+
+ /// Emits the offset into the checksum table of the given file number.
+ void emitFileChecksumOffset(MCObjectStreamer &OS, unsigned FileNo);
+
+ /// Add something to the string table. Returns the final string as well as
+ /// offset into the string table.
+ std::pair<StringRef, unsigned> addToStringTable(StringRef S);
+
+private:
+ /// Map from string to string table offset.
+ StringMap<unsigned> StringTable;
+
+ /// The fragment that ultimately holds our strings.
+ MCDataFragment *StrTabFragment = nullptr;
+ bool InsertedStrTabFragment = false;
+
+ MCDataFragment *getStringTableFragment();
+
+ /// Get a string table offset.
+ unsigned getStringTableOffset(StringRef S);
+
+ struct FileInfo {
+ unsigned StringTableOffset;
+
+ // Indicates if this FileInfo corresponds to an actual file, or hasn't been
+ // set yet.
+ bool Assigned = false;
+
+ uint8_t ChecksumKind;
+
+ ArrayRef<uint8_t> Checksum;
+
+ // Checksum offset stored as a symbol because it might be requested
+ // before it has been calculated, so a fixup may be needed.
+ MCSymbol *ChecksumTableOffset;
+ };
+
+ /// Array storing added file information.
+ SmallVector<FileInfo, 4> Files;
+
+ /// The offset of the first and last .cv_loc directive for a given function
+ /// id.
+ std::map<unsigned, std::pair<size_t, size_t>> MCCVLineStartStop;
+
+ /// A collection of MCCVLoc for each section.
+ std::vector<MCCVLoc> MCCVLines;
+
+ /// All known functions and inlined call sites, indexed by function id.
+ std::vector<MCCVFunctionInfo> Functions;
+
+ /// Indicate whether we have already laid out the checksum table addresses or
+ /// not.
+ bool ChecksumOffsetsAssigned = false;
+};
+
+} // end namespace llvm
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCContext.h b/clang-r353983/include/llvm/MC/MCContext.h
new file mode 100644
index 00000000..b964965c
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCContext.h
@@ -0,0 +1,741 @@
+//===- MCContext.h - Machine Code Context -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCCONTEXT_H
+#define LLVM_MC_MCCONTEXT_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/MC/MCAsmMacro.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MD5.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+ class CodeViewContext;
+ class MCAsmInfo;
+ class MCLabel;
+ class MCObjectFileInfo;
+ class MCRegisterInfo;
+ class MCSection;
+ class MCSectionCOFF;
+ class MCSectionELF;
+ class MCSectionMachO;
+ class MCSectionWasm;
+ class MCStreamer;
+ class MCSymbol;
+ class MCSymbolELF;
+ class MCSymbolWasm;
+ class SMLoc;
+ class SourceMgr;
+
+ /// Context object for machine code objects. This class owns all of the
+ /// sections that it creates.
+ ///
+ class MCContext {
+ public:
+ using SymbolTable = StringMap<MCSymbol *, BumpPtrAllocator &>;
+
+ private:
+ /// The SourceMgr for this object, if any.
+ const SourceMgr *SrcMgr;
+
+ /// The SourceMgr for inline assembly, if any.
+ SourceMgr *InlineSrcMgr;
+
+ /// The MCAsmInfo for this target.
+ const MCAsmInfo *MAI;
+
+ /// The MCRegisterInfo for this target.
+ const MCRegisterInfo *MRI;
+
+ /// The MCObjectFileInfo for this target.
+ const MCObjectFileInfo *MOFI;
+
+ std::unique_ptr<CodeViewContext> CVContext;
+
+ /// 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;
+
+ SpecificBumpPtrAllocator<MCSectionCOFF> COFFAllocator;
+ SpecificBumpPtrAllocator<MCSectionELF> ELFAllocator;
+ SpecificBumpPtrAllocator<MCSectionMachO> MachOAllocator;
+ SpecificBumpPtrAllocator<MCSectionWasm> WasmAllocator;
+
+ /// Bindings of names to symbols.
+ SymbolTable Symbols;
+
+ /// 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;
+
+ /// Keeps tracks of names that were used both for used declared and
+ /// artificial symbols. The value is "true" if the name has been used for a
+ /// non-section symbol (there can be at most one of those, plus an unlimited
+ /// number of section symbols with the same name).
+ StringMap<bool, BumpPtrAllocator &> UsedNames;
+
+ /// 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;
+ /// NextInstance() creates the next instance of the directional local label
+ /// for the LocalLabelVal and adds it to the map if needed.
+ unsigned NextInstance(unsigned LocalLabelVal);
+ /// GetInstance() gets the current instance of the directional local label
+ /// for the LocalLabelVal and adds it to the map if needed.
+ unsigned GetInstance(unsigned LocalLabelVal);
+
+ /// The file name of the log file from the environment variable
+ /// AS_SECURE_LOG_FILE. Which must be set before the .secure_log_unique
+ /// directive is used or it is an error.
+ char *SecureLogFile;
+ /// The stream that gets written to for the .secure_log_unique directive.
+ std::unique_ptr<raw_fd_ostream> SecureLog;
+ /// Boolean toggled when .secure_log_unique / .secure_log_reset is seen to
+ /// catch errors if .secure_log_unique appears twice without
+ /// .secure_log_reset appearing between them.
+ bool SecureLogUsed = false;
+
+ /// The compilation directory to use for DW_AT_comp_dir.
+ SmallString<128> CompilationDir;
+
+ /// Prefix replacement map for source file information.
+ std::map<const std::string, const std::string> DebugPrefixMap;
+
+ /// The main file name if passed in explicitly.
+ std::string MainFileName;
+
+ /// The dwarf file and directory tables from the dwarf .file directive.
+ /// We now emit a line table for each compile unit. To reduce the prologue
+ /// size of each line table, the files and directories used by each compile
+ /// unit are separated.
+ std::map<unsigned, MCDwarfLineTable> MCDwarfLineTablesCUMap;
+
+ /// The current dwarf line information from the last dwarf .loc directive.
+ MCDwarfLoc CurrentDwarfLoc;
+ bool DwarfLocSeen = false;
+
+ /// Generate dwarf debugging info for assembly source files.
+ bool GenDwarfForAssembly = false;
+
+ /// The current dwarf file number when generate dwarf debugging info for
+ /// assembly source files.
+ unsigned GenDwarfFileNumber = 0;
+
+ /// 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.
+ std::vector<MCGenDwarfLabelEntry> MCGenDwarfLabelEntries;
+
+ /// The string to embed in the debug information for the compile unit, if
+ /// non-empty.
+ StringRef DwarfDebugFlags;
+
+ /// The string to embed in as the dwarf AT_producer for the compile unit, if
+ /// non-empty.
+ StringRef DwarfDebugProducer;
+
+ /// The maximum version of dwarf that we should emit.
+ uint16_t DwarfVersion = 4;
+
+ /// Honor temporary labels, this is useful for debugging semantic
+ /// differences between temporary and non-temporary labels (primarily on
+ /// Darwin).
+ bool AllowTemporaryLabels = true;
+ bool UseNamesOnTempLabels = true;
+
+ /// The Compile Unit ID that we are currently processing.
+ unsigned DwarfCompileUnitID = 0;
+
+ 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;
+ unsigned UniqueID;
+
+ COFFSectionKey(StringRef SectionName, StringRef GroupName,
+ int SelectionKey, unsigned UniqueID)
+ : SectionName(SectionName), GroupName(GroupName),
+ SelectionKey(SelectionKey), UniqueID(UniqueID) {}
+
+ bool operator<(const COFFSectionKey &Other) const {
+ if (SectionName != Other.SectionName)
+ return SectionName < Other.SectionName;
+ if (GroupName != Other.GroupName)
+ return GroupName < Other.GroupName;
+ if (SelectionKey != Other.SelectionKey)
+ return SelectionKey < Other.SelectionKey;
+ return UniqueID < Other.UniqueID;
+ }
+ };
+
+ struct WasmSectionKey {
+ std::string SectionName;
+ StringRef GroupName;
+ unsigned UniqueID;
+
+ WasmSectionKey(StringRef SectionName, StringRef GroupName,
+ unsigned UniqueID)
+ : SectionName(SectionName), GroupName(GroupName), UniqueID(UniqueID) {
+ }
+
+ bool operator<(const WasmSectionKey &Other) const {
+ if (SectionName != Other.SectionName)
+ return SectionName < Other.SectionName;
+ if (GroupName != Other.GroupName)
+ return GroupName < Other.GroupName;
+ return UniqueID < Other.UniqueID;
+ }
+ };
+
+ StringMap<MCSectionMachO *> MachOUniquingMap;
+ std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap;
+ std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
+ std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap;
+ StringMap<bool> RelSecNames;
+
+ SpecificBumpPtrAllocator<MCSubtargetInfo> MCSubtargetAllocator;
+
+ /// Do automatic reset in destructor
+ bool AutoReset;
+
+ bool HadError = false;
+
+ MCSymbol *createSymbolImpl(const StringMapEntry<bool> *Name,
+ bool CanBeUnnamed);
+ MCSymbol *createSymbol(StringRef Name, bool AlwaysAddSuffix,
+ bool IsTemporary);
+
+ MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
+ unsigned Instance);
+
+ MCSectionELF *createELFSectionImpl(StringRef Section, unsigned Type,
+ unsigned Flags, SectionKind K,
+ unsigned EntrySize,
+ const MCSymbolELF *Group,
+ unsigned UniqueID,
+ const MCSymbolELF *Associated);
+
+ /// Map of currently defined macros.
+ StringMap<MCAsmMacro> MacroMap;
+
+ public:
+ explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI,
+ const MCObjectFileInfo *MOFI,
+ const SourceMgr *Mgr = nullptr, bool DoAutoReset = true);
+ MCContext(const MCContext &) = delete;
+ MCContext &operator=(const MCContext &) = delete;
+ ~MCContext();
+
+ const SourceMgr *getSourceManager() const { return SrcMgr; }
+
+ void setInlineSourceManager(SourceMgr *SM) { InlineSrcMgr = SM; }
+
+ const MCAsmInfo *getAsmInfo() const { return MAI; }
+
+ const MCRegisterInfo *getRegisterInfo() const { return MRI; }
+
+ const MCObjectFileInfo *getObjectFileInfo() const { return MOFI; }
+
+ CodeViewContext &getCVContext();
+
+ void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; }
+ void setUseNamesOnTempLabels(bool Value) { UseNamesOnTempLabels = Value; }
+
+ /// \name Module Lifetime Management
+ /// @{
+
+ /// reset - return object to right after construction state to prepare
+ /// to process a new module
+ void reset();
+
+ /// @}
+
+ /// \name Symbol Management
+ /// @{
+
+ /// Create and return a new linker temporary symbol with a unique but
+ /// unspecified name.
+ MCSymbol *createLinkerPrivateTempSymbol();
+
+ /// Create and return a new assembler temporary symbol with a unique but
+ /// unspecified name.
+ MCSymbol *createTempSymbol(bool CanBeUnnamed = true);
+
+ MCSymbol *createTempSymbol(const Twine &Name, bool AlwaysAddSuffix,
+ bool CanBeUnnamed = true);
+
+ /// Create the definition of a directional local symbol for numbered label
+ /// (used for "1:" definitions).
+ 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);
+
+ /// 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(const Twine &Name);
+
+ /// 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.localescape.
+ MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName, unsigned Idx);
+
+ MCSymbol *getOrCreateParentFrameOffsetSymbol(StringRef FuncName);
+
+ MCSymbol *getOrCreateLSDASymbol(StringRef FuncName);
+
+ /// Get the symbol for \p Name, or null.
+ MCSymbol *lookupSymbol(const Twine &Name) const;
+
+ /// Set value for a symbol.
+ void setSymbolValue(MCStreamer &Streamer, StringRef Sym, uint64_t Val);
+
+ /// getSymbols - Get a reference for the symbol table for clients that
+ /// want to, for example, iterate over all symbols. 'const' because we
+ /// still want any modifications to the table itself to use the MCContext
+ /// APIs.
+ const SymbolTable &getSymbols() const { return Symbols; }
+
+ /// @}
+
+ /// \name Section Management
+ /// @{
+
+ enum : unsigned {
+ /// Pass this value as the UniqueID during section creation to get the
+ /// generic section with the given name and characteristics. The usual
+ /// sections such as .text use this ID.
+ GenericSectionID = ~0U
+ };
+
+ /// 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);
+ }
+
+ MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
+ unsigned Flags) {
+ return getELFSection(Section, Type, Flags, 0, "");
+ }
+
+ MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ const Twine &Group) {
+ return getELFSection(Section, Type, Flags, EntrySize, Group, ~0);
+ }
+
+ MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ const Twine &Group, unsigned UniqueID) {
+ return getELFSection(Section, Type, Flags, EntrySize, Group, UniqueID,
+ nullptr);
+ }
+
+ MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ const Twine &Group, unsigned UniqueID,
+ const MCSymbolELF *Associated);
+
+ MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ const MCSymbolELF *Group, unsigned UniqueID,
+ const MCSymbolELF *Associated);
+
+ /// Get a section with the provided group identifier. This section is
+ /// named by concatenating \p Prefix with '.' then \p Suffix. The \p Type
+ /// describes the type of the section and \p Flags are used to further
+ /// configure this named section.
+ MCSectionELF *getELFNamedSection(const Twine &Prefix, const Twine &Suffix,
+ unsigned Type, unsigned Flags,
+ unsigned EntrySize = 0);
+
+ MCSectionELF *createELFRelSection(const Twine &Name, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ const MCSymbolELF *Group,
+ const MCSectionELF *RelInfoSection);
+
+ void renameELFSection(MCSectionELF *Section, StringRef Name);
+
+ MCSectionELF *createELFGroupSection(const MCSymbolELF *Group);
+
+ MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
+ SectionKind Kind, StringRef COMDATSymName,
+ int Selection,
+ unsigned UniqueID = GenericSectionID,
+ 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.
+ MCSectionCOFF *
+ getAssociativeCOFFSection(MCSectionCOFF *Sec, const MCSymbol *KeySym,
+ unsigned UniqueID = GenericSectionID);
+
+ MCSectionWasm *getWasmSection(const Twine &Section, SectionKind K) {
+ return getWasmSection(Section, K, nullptr);
+ }
+
+ MCSectionWasm *getWasmSection(const Twine &Section, SectionKind K,
+ const char *BeginSymName) {
+ return getWasmSection(Section, K, "", ~0, BeginSymName);
+ }
+
+ MCSectionWasm *getWasmSection(const Twine &Section, SectionKind K,
+ const Twine &Group, unsigned UniqueID) {
+ return getWasmSection(Section, K, Group, UniqueID, nullptr);
+ }
+
+ MCSectionWasm *getWasmSection(const Twine &Section, SectionKind K,
+ const Twine &Group, unsigned UniqueID,
+ const char *BeginSymName);
+
+ MCSectionWasm *getWasmSection(const Twine &Section, SectionKind K,
+ const MCSymbolWasm *Group, unsigned UniqueID,
+ const char *BeginSymName);
+
+ // Create and save a copy of STI and return a reference to the copy.
+ MCSubtargetInfo &getSubtargetCopy(const MCSubtargetInfo &STI);
+
+ /// @}
+
+ /// \name Dwarf Management
+ /// @{
+
+ /// Get the compilation directory for DW_AT_comp_dir
+ /// The compilation directory should be set with \c setCompilationDir before
+ /// calling this function. If it is unset, an empty string will be returned.
+ StringRef getCompilationDir() const { return CompilationDir; }
+
+ /// Set the compilation directory for DW_AT_comp_dir
+ void setCompilationDir(StringRef S) { CompilationDir = S.str(); }
+
+ /// Get the debug prefix map.
+ const std::map<const std::string, const std::string> &
+ getDebugPrefixMap() const {
+ return DebugPrefixMap;
+ }
+
+ /// Add an entry to the debug prefix map.
+ void addDebugPrefixMapEntry(const std::string &From, const std::string &To);
+
+ // Remaps all debug directory paths in-place as per the debug prefix map.
+ void RemapDebugPaths();
+
+ /// Get the main file name for use in error messages and debug
+ /// info. This can be set to ensure we've got the correct file name
+ /// after preprocessing or for -save-temps.
+ const std::string &getMainFileName() const { return MainFileName; }
+
+ /// Set the main file name and override the default.
+ void setMainFileName(StringRef S) { MainFileName = S; }
+
+ /// Creates an entry in the dwarf file and directory tables.
+ Expected<unsigned> getDwarfFile(StringRef Directory, StringRef FileName,
+ unsigned FileNumber,
+ MD5::MD5Result *Checksum,
+ Optional<StringRef> Source, unsigned CUID);
+
+ bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0);
+
+ const std::map<unsigned, MCDwarfLineTable> &getMCDwarfLineTables() const {
+ return MCDwarfLineTablesCUMap;
+ }
+
+ MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) {
+ return MCDwarfLineTablesCUMap[CUID];
+ }
+
+ const MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) const {
+ auto I = MCDwarfLineTablesCUMap.find(CUID);
+ assert(I != MCDwarfLineTablesCUMap.end());
+ return I->second;
+ }
+
+ const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles(unsigned CUID = 0) {
+ return getMCDwarfLineTable(CUID).getMCDwarfFiles();
+ }
+
+ const SmallVectorImpl<std::string> &getMCDwarfDirs(unsigned CUID = 0) {
+ return getMCDwarfLineTable(CUID).getMCDwarfDirs();
+ }
+
+ bool hasMCLineSections() const {
+ for (const auto &Table : MCDwarfLineTablesCUMap)
+ if (!Table.second.getMCDwarfFiles().empty() || Table.second.getLabel())
+ return true;
+ return false;
+ }
+
+ unsigned getDwarfCompileUnitID() { return DwarfCompileUnitID; }
+
+ void setDwarfCompileUnitID(unsigned CUIndex) {
+ DwarfCompileUnitID = CUIndex;
+ }
+
+ /// Specifies the "root" file and directory of the compilation unit.
+ /// These are "file 0" and "directory 0" in DWARF v5.
+ void setMCLineTableRootFile(unsigned CUID, StringRef CompilationDir,
+ StringRef Filename, MD5::MD5Result *Checksum,
+ Optional<StringRef> Source) {
+ getMCDwarfLineTable(CUID).setRootFile(CompilationDir, Filename, Checksum,
+ Source);
+ }
+
+ /// Reports whether MD5 checksum usage is consistent (all-or-none).
+ bool isDwarfMD5UsageConsistent(unsigned CUID) const {
+ return getMCDwarfLineTable(CUID).isMD5UsageConsistent();
+ }
+
+ /// Saves the information from the currently parsed dwarf .loc directive
+ /// and sets DwarfLocSeen. When the next instruction is assembled an entry
+ /// in the line number table with this information and the address of the
+ /// instruction will be created.
+ void setCurrentDwarfLoc(unsigned FileNum, unsigned Line, unsigned Column,
+ unsigned Flags, unsigned Isa,
+ unsigned Discriminator) {
+ CurrentDwarfLoc.setFileNum(FileNum);
+ CurrentDwarfLoc.setLine(Line);
+ CurrentDwarfLoc.setColumn(Column);
+ CurrentDwarfLoc.setFlags(Flags);
+ CurrentDwarfLoc.setIsa(Isa);
+ CurrentDwarfLoc.setDiscriminator(Discriminator);
+ DwarfLocSeen = true;
+ }
+
+ void clearDwarfLocSeen() { DwarfLocSeen = false; }
+
+ bool getDwarfLocSeen() { return DwarfLocSeen; }
+ const MCDwarfLoc &getCurrentDwarfLoc() { return CurrentDwarfLoc; }
+
+ bool getGenDwarfForAssembly() { return GenDwarfForAssembly; }
+ void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; }
+ unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; }
+
+ void setGenDwarfFileNumber(unsigned FileNumber) {
+ GenDwarfFileNumber = FileNumber;
+ }
+
+ const SetVector<MCSection *> &getGenDwarfSectionSyms() {
+ return SectionsForRanges;
+ }
+
+ bool addGenDwarfSection(MCSection *Sec) {
+ return SectionsForRanges.insert(Sec);
+ }
+
+ void finalizeDwarfSections(MCStreamer &MCOS);
+
+ const std::vector<MCGenDwarfLabelEntry> &getMCGenDwarfLabelEntries() const {
+ return MCGenDwarfLabelEntries;
+ }
+
+ void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry &E) {
+ MCGenDwarfLabelEntries.push_back(E);
+ }
+
+ void setDwarfDebugFlags(StringRef S) { DwarfDebugFlags = S; }
+ StringRef getDwarfDebugFlags() { return DwarfDebugFlags; }
+
+ void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; }
+ StringRef getDwarfDebugProducer() { return DwarfDebugProducer; }
+
+ dwarf::DwarfFormat getDwarfFormat() const {
+ // TODO: Support DWARF64
+ return dwarf::DWARF32;
+ }
+
+ void setDwarfVersion(uint16_t v) { DwarfVersion = v; }
+ uint16_t getDwarfVersion() const { return DwarfVersion; }
+
+ /// @}
+
+ char *getSecureLogFile() { return SecureLogFile; }
+ raw_fd_ostream *getSecureLog() { return SecureLog.get(); }
+
+ void setSecureLog(std::unique_ptr<raw_fd_ostream> Value) {
+ SecureLog = std::move(Value);
+ }
+
+ bool getSecureLogUsed() { return SecureLogUsed; }
+ void setSecureLogUsed(bool Value) { SecureLogUsed = Value; }
+
+ void *allocate(unsigned Size, unsigned Align = 8) {
+ return Allocator.Allocate(Size, Align);
+ }
+
+ void deallocate(void *Ptr) {}
+
+ bool hadError() { return HadError; }
+ void reportError(SMLoc L, const Twine &Msg);
+ // 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 reportFatalError(SMLoc L,
+ const Twine &Msg);
+
+ const MCAsmMacro *lookupMacro(StringRef Name) {
+ StringMap<MCAsmMacro>::iterator I = MacroMap.find(Name);
+ return (I == MacroMap.end()) ? nullptr : &I->getValue();
+ }
+
+ void defineMacro(StringRef Name, MCAsmMacro Macro) {
+ MacroMap.insert(std::make_pair(Name, std::move(Macro)));
+ }
+
+ void undefineMacro(StringRef Name) { MacroMap.erase(Name); }
+ };
+
+} // end namespace llvm
+
+// operator new and delete aren't allowed inside namespaces.
+// The throw specifications are mandated by the standard.
+/// 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 (8)
+/// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments);
+/// // Specific alignment
+/// 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).
+///
+/// \param Bytes The number of bytes to allocate. Calculated by the compiler.
+/// \param C The MCContext that provides the allocator.
+/// \param Alignment The alignment of the allocated memory (if the underlying
+/// allocator supports it).
+/// \return The allocated memory. Could be NULL.
+inline void *operator new(size_t Bytes, llvm::MCContext &C,
+ size_t Alignment = 8) noexcept {
+ return C.allocate(Bytes, Alignment);
+}
+/// Placement delete companion to the new above.
+///
+/// This operator is just a companion to the new above. There is no way of
+/// invoking it directly; see the new operator for more details. This operator
+/// is called implicitly by the compiler if a placement new expression using
+/// the MCContext throws in the object constructor.
+inline void operator delete(void *Ptr, llvm::MCContext &C, size_t) noexcept {
+ 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 (8)
+/// char *data = new (Context) char[10];
+/// // Specific alignment
+/// 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).
+///
+/// \param Bytes The number of bytes to allocate. Calculated by the compiler.
+/// \param C The MCContext that provides the allocator.
+/// \param Alignment The alignment of the allocated memory (if the underlying
+/// allocator supports it).
+/// \return The allocated memory. Could be NULL.
+inline void *operator new[](size_t Bytes, llvm::MCContext &C,
+ size_t Alignment = 8) noexcept {
+ return C.allocate(Bytes, Alignment);
+}
+
+/// 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) noexcept {
+ C.deallocate(Ptr);
+}
+
+#endif // LLVM_MC_MCCONTEXT_H
diff --git a/clang-r353983/include/llvm/MC/MCDirectives.h b/clang-r353983/include/llvm/MC/MCDirectives.h
new file mode 100644
index 00000000..4029264c
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCDirectives.h
@@ -0,0 +1,73 @@
+//===- MCDirectives.h - Enums for directives on various targets -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines various enums that represent target-specific directives.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCDIRECTIVES_H
+#define LLVM_MC_MCDIRECTIVES_H
+
+namespace llvm {
+
+enum MCSymbolAttr {
+ MCSA_Invalid = 0, ///< Not a valid directive.
+
+ // Various directives in alphabetical order.
+ MCSA_Cold, ///< .cold (MachO)
+ MCSA_ELF_TypeFunction, ///< .type _foo, STT_FUNC # aka @function
+ MCSA_ELF_TypeIndFunction, ///< .type _foo, STT_GNU_IFUNC
+ MCSA_ELF_TypeObject, ///< .type _foo, STT_OBJECT # aka @object
+ MCSA_ELF_TypeTLS, ///< .type _foo, STT_TLS # aka @tls_object
+ MCSA_ELF_TypeCommon, ///< .type _foo, STT_COMMON # aka @common
+ MCSA_ELF_TypeNoType, ///< .type _foo, STT_NOTYPE # aka @notype
+ MCSA_ELF_TypeGnuUniqueObject, /// .type _foo, @gnu_unique_object
+ MCSA_Global, ///< .globl
+ MCSA_Hidden, ///< .hidden (ELF)
+ MCSA_IndirectSymbol, ///< .indirect_symbol (MachO)
+ MCSA_Internal, ///< .internal (ELF)
+ MCSA_LazyReference, ///< .lazy_reference (MachO)
+ MCSA_Local, ///< .local (ELF)
+ MCSA_NoDeadStrip, ///< .no_dead_strip (MachO)
+ MCSA_SymbolResolver, ///< .symbol_resolver (MachO)
+ MCSA_AltEntry, ///< .alt_entry (MachO)
+ MCSA_PrivateExtern, ///< .private_extern (MachO)
+ MCSA_Protected, ///< .protected (ELF)
+ MCSA_Reference, ///< .reference (MachO)
+ MCSA_Weak, ///< .weak
+ MCSA_WeakDefinition, ///< .weak_definition (MachO)
+ MCSA_WeakReference, ///< .weak_reference (MachO)
+ MCSA_WeakDefAutoPrivate ///< .weak_def_can_be_hidden (MachO)
+};
+
+enum MCAssemblerFlag {
+ MCAF_SyntaxUnified, ///< .syntax (ARM/ELF)
+ MCAF_SubsectionsViaSymbols, ///< .subsections_via_symbols (MachO)
+ MCAF_Code16, ///< .code16 (X86) / .code 16 (ARM)
+ MCAF_Code32, ///< .code32 (X86) / .code 32 (ARM)
+ MCAF_Code64 ///< .code64 (X86)
+};
+
+enum MCDataRegionType {
+ MCDR_DataRegion, ///< .data_region
+ MCDR_DataRegionJT8, ///< .data_region jt8
+ MCDR_DataRegionJT16, ///< .data_region jt16
+ MCDR_DataRegionJT32, ///< .data_region jt32
+ MCDR_DataRegionEnd ///< .end_data_region
+};
+
+enum MCVersionMinType {
+ MCVM_IOSVersionMin, ///< .ios_version_min
+ MCVM_OSXVersionMin, ///< .macosx_version_min
+ MCVM_TvOSVersionMin, ///< .tvos_version_min
+ MCVM_WatchOSVersionMin, ///< .watchos_version_min
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCDisassembler/MCDisassembler.h b/clang-r353983/include/llvm/MC/MCDisassembler/MCDisassembler.h
new file mode 100644
index 00000000..268f3cca
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCDisassembler/MCDisassembler.h
@@ -0,0 +1,132 @@
+//===- llvm/MC/MCDisassembler.h - Disassembler interface --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H
+#define LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H
+
+#include "llvm/MC/MCDisassembler/MCSymbolizer.h"
+#include <cstdint>
+#include <memory>
+
+namespace llvm {
+
+template <typename T> class ArrayRef;
+class StringRef;
+class MCContext;
+class MCInst;
+class MCSubtargetInfo;
+class raw_ostream;
+
+/// Superclass for all disassemblers. Consumes a memory region and provides an
+/// array of assembly instructions.
+class MCDisassembler {
+public:
+ /// Ternary decode status. Most backends will just use Fail and
+ /// Success, however some have a concept of an instruction with
+ /// understandable semantics but which is architecturally
+ /// incorrect. An example of this is ARM UNPREDICTABLE instructions
+ /// which are disassemblable but cause undefined behaviour.
+ ///
+ /// Because it makes sense to disassemble these instructions, there
+ /// is a "soft fail" failure mode that indicates the MCInst& is
+ /// valid but architecturally incorrect.
+ ///
+ /// The enum numbers are deliberately chosen such that reduction
+ /// from Success->SoftFail ->Fail can be done with a simple
+ /// bitwise-AND:
+ ///
+ /// LEFT & TOP = | Success Unpredictable Fail
+ /// --------------+-----------------------------------
+ /// Success | Success Unpredictable Fail
+ /// Unpredictable | Unpredictable Unpredictable Fail
+ /// Fail | Fail Fail Fail
+ ///
+ /// An easy way of encoding this is as 0b11, 0b01, 0b00 for
+ /// Success, SoftFail, Fail respectively.
+ enum DecodeStatus {
+ Fail = 0,
+ SoftFail = 1,
+ Success = 3
+ };
+
+ MCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
+ : Ctx(Ctx), STI(STI) {}
+
+ virtual ~MCDisassembler();
+
+ /// Returns the disassembly of a single instruction.
+ ///
+ /// \param Instr - An MCInst to populate with the contents of the
+ /// instruction.
+ /// \param Size - A value to populate with the size of the instruction, or
+ /// the number of bytes consumed while attempting to decode
+ /// an invalid instruction.
+ /// \param Address - The address, in the memory space of region, of the first
+ /// byte of the instruction.
+ /// \param Bytes - A reference to the actual bytes of the instruction.
+ /// \param VStream - The stream to print warnings and diagnostic messages on.
+ /// \param CStream - The stream to print comments and annotations on.
+ /// \return - MCDisassembler::Success if the instruction is valid,
+ /// MCDisassembler::SoftFail if the instruction was
+ /// disassemblable but invalid,
+ /// MCDisassembler::Fail if the instruction was invalid.
+ virtual DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
+ ArrayRef<uint8_t> Bytes, uint64_t Address,
+ raw_ostream &VStream,
+ raw_ostream &CStream) const = 0;
+
+ /// May parse any prelude that precedes instructions after the start of a
+ /// symbol. Needed for some targets, e.g. WebAssembly.
+ ///
+ /// \param Name - The name of the symbol.
+ /// \param Size - The number of bytes consumed.
+ /// \param Address - The address, in the memory space of region, of the first
+ /// byte of the symbol.
+ /// \param Bytes - A reference to the actual bytes at the symbol location.
+ /// \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 bytes are valid,
+ /// MCDisassembler::Fail if the bytes were invalid.
+ virtual DecodeStatus onSymbolStart(StringRef Name, uint64_t &Size,
+ ArrayRef<uint8_t> Bytes, uint64_t Address,
+ raw_ostream &VStream,
+ raw_ostream &CStream) const;
+
+private:
+ MCContext &Ctx;
+
+protected:
+ // Subtarget information, for instruction decoding predicates if required.
+ const MCSubtargetInfo &STI;
+ std::unique_ptr<MCSymbolizer> Symbolizer;
+
+public:
+ // Helpers around MCSymbolizer
+ bool tryAddingSymbolicOperand(MCInst &Inst,
+ int64_t Value,
+ uint64_t Address, bool IsBranch,
+ uint64_t Offset, uint64_t InstSize) const;
+
+ void tryAddingPcLoadReferenceComment(int64_t Value, uint64_t Address) const;
+
+ /// Set \p Symzer as the current symbolizer.
+ /// This takes ownership of \p Symzer, and deletes the previously set one.
+ void setSymbolizer(std::unique_ptr<MCSymbolizer> Symzer);
+
+ MCContext& getContext() const { return Ctx; }
+
+ const MCSubtargetInfo& getSubtargetInfo() const { return STI; }
+
+ // Marked mutable because we cache it inside the disassembler, rather than
+ // having to pass it around as an argument through all the autogenerated code.
+ mutable raw_ostream *CommentStream = nullptr;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H
diff --git a/clang-r353983/include/llvm/MC/MCDisassembler/MCExternalSymbolizer.h b/clang-r353983/include/llvm/MC/MCDisassembler/MCExternalSymbolizer.h
new file mode 100644
index 00000000..ffac5ee5
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCDisassembler/MCExternalSymbolizer.h
@@ -0,0 +1,57 @@
+//===-- llvm/MC/MCExternalSymbolizer.h - ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCExternalSymbolizer class, which
+// enables library users to provide callbacks (through the C API) to do the
+// symbolization externally.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCDISASSEMBLER_MCEXTERNALSYMBOLIZER_H
+#define LLVM_MC_MCDISASSEMBLER_MCEXTERNALSYMBOLIZER_H
+
+#include "llvm-c/Disassembler.h"
+#include "llvm/MC/MCDisassembler/MCSymbolizer.h"
+#include <memory>
+
+namespace llvm {
+
+/// Symbolize using user-provided, C API, callbacks.
+///
+/// See llvm-c/Disassembler.h.
+class MCExternalSymbolizer : public MCSymbolizer {
+protected:
+ /// \name Hooks for symbolic disassembly via the public 'C' interface.
+ /// @{
+ /// The function to get the symbolic information for operands.
+ LLVMOpInfoCallback GetOpInfo;
+ /// The function to lookup a symbol name.
+ LLVMSymbolLookupCallback SymbolLookUp;
+ /// The pointer to the block of symbolic information for above call back.
+ void *DisInfo;
+ /// @}
+
+public:
+ MCExternalSymbolizer(MCContext &Ctx,
+ std::unique_ptr<MCRelocationInfo> RelInfo,
+ LLVMOpInfoCallback getOpInfo,
+ LLVMSymbolLookupCallback symbolLookUp, void *disInfo)
+ : MCSymbolizer(Ctx, std::move(RelInfo)), GetOpInfo(getOpInfo),
+ SymbolLookUp(symbolLookUp), DisInfo(disInfo) {}
+
+ bool tryAddingSymbolicOperand(MCInst &MI, raw_ostream &CommentStream,
+ int64_t Value, uint64_t Address, bool IsBranch,
+ uint64_t Offset, uint64_t InstSize) override;
+ void tryAddingPcLoadReferenceComment(raw_ostream &CommentStream,
+ int64_t Value,
+ uint64_t Address) override;
+};
+
+}
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCDisassembler/MCRelocationInfo.h b/clang-r353983/include/llvm/MC/MCDisassembler/MCRelocationInfo.h
new file mode 100644
index 00000000..efc59da1
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCDisassembler/MCRelocationInfo.h
@@ -0,0 +1,44 @@
+//===- llvm/MC/MCRelocationInfo.h -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCRelocationInfo class, which provides methods to
+// create MCExprs from relocations, either found in an object::ObjectFile
+// (object::RelocationRef), or provided through the C API.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCDISASSEMBLER_MCRELOCATIONINFO_H
+#define LLVM_MC_MCDISASSEMBLER_MCRELOCATIONINFO_H
+
+namespace llvm {
+
+class MCContext;
+class MCExpr;
+
+/// Create MCExprs from relocations found in an object file.
+class MCRelocationInfo {
+protected:
+ MCContext &Ctx;
+
+public:
+ MCRelocationInfo(MCContext &Ctx);
+ MCRelocationInfo(const MCRelocationInfo &) = delete;
+ MCRelocationInfo &operator=(const MCRelocationInfo &) = delete;
+ virtual ~MCRelocationInfo();
+
+ /// Create an MCExpr for the target-specific \p VariantKind.
+ /// The VariantKinds are defined in llvm-c/Disassembler.h.
+ /// Used by MCExternalSymbolizer.
+ /// \returns If possible, an MCExpr corresponding to VariantKind, else 0.
+ virtual const MCExpr *createExprForCAPIVariantKind(const MCExpr *SubExpr,
+ unsigned VariantKind);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCDISASSEMBLER_MCRELOCATIONINFO_H
diff --git a/clang-r353983/include/llvm/MC/MCDisassembler/MCSymbolizer.h b/clang-r353983/include/llvm/MC/MCDisassembler/MCSymbolizer.h
new file mode 100644
index 00000000..b7ca83a5
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCDisassembler/MCSymbolizer.h
@@ -0,0 +1,82 @@
+//===- llvm/MC/MCSymbolizer.h - MCSymbolizer class --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCSymbolizer class, which is used
+// to symbolize instructions decoded from an object, that is, transform their
+// immediate operands to MCExprs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCDISASSEMBLER_MCSYMBOLIZER_H
+#define LLVM_MC_MCDISASSEMBLER_MCSYMBOLIZER_H
+
+#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+
+namespace llvm {
+
+class MCContext;
+class MCInst;
+class raw_ostream;
+
+/// Symbolize and annotate disassembled instructions.
+///
+/// For now this mimics the old symbolization logic (from both ARM and x86), that
+/// relied on user-provided (C API) callbacks to do the actual symbol lookup in
+/// the object file. This was moved to MCExternalSymbolizer.
+/// A better API would not rely on actually calling the two methods here from
+/// inside each disassembler, but would use the instr info to determine what
+/// operands are actually symbolizable, and in what way. I don't think this
+/// information exists right now.
+class MCSymbolizer {
+protected:
+ MCContext &Ctx;
+ std::unique_ptr<MCRelocationInfo> RelInfo;
+
+public:
+ /// Construct an MCSymbolizer, taking ownership of \p RelInfo.
+ MCSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> RelInfo)
+ : Ctx(Ctx), RelInfo(std::move(RelInfo)) {
+ }
+
+ MCSymbolizer(const MCSymbolizer &) = delete;
+ MCSymbolizer &operator=(const MCSymbolizer &) = delete;
+ virtual ~MCSymbolizer();
+
+ /// Try to add a symbolic operand instead of \p Value to the MCInst.
+ ///
+ /// Instead of having a difficult to read immediate, a symbolic operand would
+ /// 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.
+ virtual bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream,
+ int64_t Value, uint64_t Address,
+ bool IsBranch, uint64_t Offset,
+ uint64_t InstSize) = 0;
+
+ /// Try to add a comment on the PC-relative load.
+ /// For instance, in Mach-O, this is used to add annotations to instructions
+ /// that use C string literals, as found in __cstring.
+ virtual void tryAddingPcLoadReferenceComment(raw_ostream &cStream,
+ int64_t Value,
+ uint64_t Address) = 0;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCDISASSEMBLER_MCSYMBOLIZER_H
diff --git a/clang-r353983/include/llvm/MC/MCDwarf.h b/clang-r353983/include/llvm/MC/MCDwarf.h
new file mode 100644
index 00000000..8eaa1523
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCDwarf.h
@@ -0,0 +1,617 @@
+//===- MCDwarf.h - Machine Code Dwarf support -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCDwarfFile to support the dwarf
+// .file directive and the .loc directive.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCDWARF_H
+#define LLVM_MC_MCDWARF_H
+
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MD5.h"
+#include <cassert>
+#include <cstdint>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+template <typename T> class ArrayRef;
+class MCAsmBackend;
+class MCContext;
+class MCDwarfLineStr;
+class MCObjectStreamer;
+class MCStreamer;
+class MCSymbol;
+class raw_ostream;
+class SMLoc;
+class SourceMgr;
+
+/// 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 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 {
+ // The base name of the file without its directory path.
+ std::string Name;
+
+ // The index into the list of directory names for this file name.
+ unsigned DirIndex;
+
+ /// The MD5 checksum, if there is one. Non-owning pointer to data allocated
+ /// in MCContext.
+ MD5::MD5Result *Checksum = nullptr;
+
+ /// The source code of the file. Non-owning reference to data allocated in
+ /// MCContext.
+ Optional<StringRef> Source;
+};
+
+/// Instances of this class represent the information from a
+/// dwarf .loc directive.
+class MCDwarfLoc {
+ uint32_t FileNum;
+ uint32_t Line;
+ uint16_t Column;
+ // Flags (see #define's below)
+ uint8_t Flags;
+ uint8_t Isa;
+ uint32_t Discriminator;
+
+// Flag that indicates the initial value of the is_stmt_start flag.
+#define DWARF2_LINE_DEFAULT_IS_STMT 1
+
+#define DWARF2_FLAG_IS_STMT (1 << 0)
+#define DWARF2_FLAG_BASIC_BLOCK (1 << 1)
+#define DWARF2_FLAG_PROLOGUE_END (1 << 2)
+#define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3)
+
+private: // MCContext manages these
+ friend class MCContext;
+ friend class MCDwarfLineEntry;
+
+ MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
+ unsigned isa, unsigned discriminator)
+ : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa),
+ Discriminator(discriminator) {}
+
+ // Allow the default copy constructor and assignment operator to be used
+ // for an MCDwarfLoc object.
+
+public:
+ /// Get the FileNum of this MCDwarfLoc.
+ unsigned getFileNum() const { return FileNum; }
+
+ /// Get the Line of this MCDwarfLoc.
+ unsigned getLine() const { return Line; }
+
+ /// Get the Column of this MCDwarfLoc.
+ unsigned getColumn() const { return Column; }
+
+ /// Get the Flags of this MCDwarfLoc.
+ unsigned getFlags() const { return Flags; }
+
+ /// Get the Isa of this MCDwarfLoc.
+ unsigned getIsa() const { return Isa; }
+
+ /// Get the Discriminator of this MCDwarfLoc.
+ unsigned getDiscriminator() const { return Discriminator; }
+
+ /// Set the FileNum of this MCDwarfLoc.
+ void setFileNum(unsigned fileNum) { FileNum = fileNum; }
+
+ /// Set the Line of this MCDwarfLoc.
+ void setLine(unsigned line) { Line = line; }
+
+ /// Set the Column of this MCDwarfLoc.
+ void setColumn(unsigned column) {
+ assert(column <= UINT16_MAX);
+ Column = column;
+ }
+
+ /// Set the Flags of this MCDwarfLoc.
+ void setFlags(unsigned flags) {
+ assert(flags <= UINT8_MAX);
+ Flags = flags;
+ }
+
+ /// Set the Isa of this MCDwarfLoc.
+ void setIsa(unsigned isa) {
+ assert(isa <= UINT8_MAX);
+ Isa = isa;
+ }
+
+ /// Set the Discriminator of this MCDwarfLoc.
+ void setDiscriminator(unsigned discriminator) {
+ Discriminator = discriminator;
+ }
+};
+
+/// Instances of this class represent the line information for
+/// the dwarf line table entries. Which is created after a machine
+/// instruction is assembled and uses an address from a temporary label
+/// created at the current address in the current section and the info from
+/// the last .loc directive seen as stored in the context.
+class MCDwarfLineEntry : public MCDwarfLoc {
+ MCSymbol *Label;
+
+private:
+ // Allow the default copy constructor and assignment operator to be used
+ // for an MCDwarfLineEntry object.
+
+public:
+ // Constructor to create an MCDwarfLineEntry given a symbol and the dwarf loc.
+ MCDwarfLineEntry(MCSymbol *label, const MCDwarfLoc loc)
+ : MCDwarfLoc(loc), Label(label) {}
+
+ MCSymbol *getLabel() const { return Label; }
+
+ // This is called when an instruction is assembled into the specified
+ // section and if there is information from the last .loc directive that
+ // has yet to have a line entry made for it is made.
+ static void Make(MCObjectStreamer *MCOS, MCSection *Section);
+};
+
+/// 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:
+ // Add an entry to this MCLineSection's line entries.
+ void addLineEntry(const MCDwarfLineEntry &LineEntry, MCSection *Sec) {
+ MCLineDivisions[Sec].push_back(LineEntry);
+ }
+
+ using MCDwarfLineEntryCollection = std::vector<MCDwarfLineEntry>;
+ using iterator = MCDwarfLineEntryCollection::iterator;
+ using const_iterator = MCDwarfLineEntryCollection::const_iterator;
+ using MCLineDivisionMap = MapVector<MCSection *, MCDwarfLineEntryCollection>;
+
+private:
+ // A collection of MCDwarfLineEntry for each section.
+ MCLineDivisionMap MCLineDivisions;
+
+public:
+ // Returns the collection of MCDwarfLineEntry for a given Compile Unit ID.
+ const MCLineDivisionMap &getMCLineEntries() const {
+ return MCLineDivisions;
+ }
+};
+
+struct MCDwarfLineTableParams {
+ /// First special line opcode - leave room for the standard opcodes.
+ /// Note: If you want to change this, you'll have to update the
+ /// "StandardOpcodeLengths" table that is emitted in
+ /// \c Emit().
+ uint8_t DWARF2LineOpcodeBase = 13;
+ /// Minimum line offset in a special line info. opcode. The value
+ /// -5 was chosen to give a reasonable range of values.
+ int8_t DWARF2LineBase = -5;
+ /// Range of line offsets in a special line info. opcode.
+ uint8_t DWARF2LineRange = 14;
+};
+
+struct MCDwarfLineTableHeader {
+ MCSymbol *Label = nullptr;
+ SmallVector<std::string, 3> MCDwarfDirs;
+ SmallVector<MCDwarfFile, 3> MCDwarfFiles;
+ StringMap<unsigned> SourceIdMap;
+ std::string CompilationDir;
+ MCDwarfFile RootFile;
+ bool HasSource = false;
+private:
+ bool HasAllMD5 = true;
+ bool HasAnyMD5 = false;
+
+public:
+ MCDwarfLineTableHeader() = default;
+
+ Expected<unsigned> tryGetFile(StringRef &Directory, StringRef &FileName,
+ MD5::MD5Result *Checksum,
+ Optional<StringRef> &Source,
+ unsigned FileNumber = 0);
+ std::pair<MCSymbol *, MCSymbol *>
+ Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
+ Optional<MCDwarfLineStr> &LineStr) const;
+ std::pair<MCSymbol *, MCSymbol *>
+ Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
+ ArrayRef<char> SpecialOpcodeLengths,
+ Optional<MCDwarfLineStr> &LineStr) const;
+ void resetMD5Usage() {
+ HasAllMD5 = true;
+ HasAnyMD5 = false;
+ }
+ void trackMD5Usage(bool MD5Used) {
+ HasAllMD5 &= MD5Used;
+ HasAnyMD5 |= MD5Used;
+ }
+ bool isMD5UsageConsistent() const {
+ return MCDwarfFiles.empty() || (HasAllMD5 == HasAnyMD5);
+ }
+
+private:
+ void emitV2FileDirTables(MCStreamer *MCOS) const;
+ void emitV5FileDirTables(MCStreamer *MCOS, Optional<MCDwarfLineStr> &LineStr,
+ StringRef CtxCompilationDir) const;
+};
+
+class MCDwarfDwoLineTable {
+ MCDwarfLineTableHeader Header;
+
+public:
+ void maybeSetRootFile(StringRef Directory, StringRef FileName,
+ MD5::MD5Result *Checksum, Optional<StringRef> Source) {
+ if (!Header.RootFile.Name.empty())
+ return;
+ Header.CompilationDir = Directory;
+ Header.RootFile.Name = FileName;
+ Header.RootFile.DirIndex = 0;
+ Header.RootFile.Checksum = Checksum;
+ Header.RootFile.Source = Source;
+ Header.trackMD5Usage(Checksum);
+ Header.HasSource = Source.hasValue();
+ }
+
+ unsigned getFile(StringRef Directory, StringRef FileName,
+ MD5::MD5Result *Checksum, Optional<StringRef> Source) {
+ return cantFail(Header.tryGetFile(Directory, FileName, Checksum, Source));
+ }
+
+ void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params,
+ MCSection *Section) const;
+};
+
+class MCDwarfLineTable {
+ MCDwarfLineTableHeader Header;
+ MCLineSection MCLineSections;
+
+public:
+ // This emits the Dwarf file and the line tables for all Compile Units.
+ static void Emit(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params);
+
+ // This emits the Dwarf file and the line tables for a given Compile Unit.
+ void EmitCU(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params,
+ Optional<MCDwarfLineStr> &LineStr) const;
+
+ Expected<unsigned> tryGetFile(StringRef &Directory, StringRef &FileName,
+ MD5::MD5Result *Checksum,
+ Optional<StringRef> Source,
+ unsigned FileNumber = 0);
+ unsigned getFile(StringRef &Directory, StringRef &FileName,
+ MD5::MD5Result *Checksum, Optional<StringRef> &Source,
+ unsigned FileNumber = 0) {
+ return cantFail(tryGetFile(Directory, FileName, Checksum, Source,
+ FileNumber));
+ }
+
+ void setRootFile(StringRef Directory, StringRef FileName,
+ MD5::MD5Result *Checksum, Optional<StringRef> Source) {
+ Header.CompilationDir = Directory;
+ Header.RootFile.Name = FileName;
+ Header.RootFile.DirIndex = 0;
+ Header.RootFile.Checksum = Checksum;
+ Header.RootFile.Source = Source;
+ Header.trackMD5Usage(Checksum);
+ Header.HasSource = Source.hasValue();
+ }
+
+ void resetRootFile() {
+ assert(Header.MCDwarfFiles.empty());
+ Header.RootFile.Name.clear();
+ Header.resetMD5Usage();
+ Header.HasSource = false;
+ }
+
+ bool hasRootFile() const { return !Header.RootFile.Name.empty(); }
+
+ // Report whether MD5 usage has been consistent (all-or-none).
+ bool isMD5UsageConsistent() const { return Header.isMD5UsageConsistent(); }
+
+ MCSymbol *getLabel() const {
+ return Header.Label;
+ }
+
+ void setLabel(MCSymbol *Label) {
+ Header.Label = Label;
+ }
+
+ const SmallVectorImpl<std::string> &getMCDwarfDirs() const {
+ return Header.MCDwarfDirs;
+ }
+
+ SmallVectorImpl<std::string> &getMCDwarfDirs() {
+ return Header.MCDwarfDirs;
+ }
+
+ const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() const {
+ return Header.MCDwarfFiles;
+ }
+
+ SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() {
+ return Header.MCDwarfFiles;
+ }
+
+ const MCLineSection &getMCLineSections() const {
+ return MCLineSections;
+ }
+ MCLineSection &getMCLineSections() {
+ return MCLineSections;
+ }
+};
+
+class MCDwarfLineAddr {
+public:
+ /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
+ static void Encode(MCContext &Context, MCDwarfLineTableParams Params,
+ int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS);
+
+ /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas using
+ /// fixed length operands.
+ static bool FixedEncode(MCContext &Context,
+ MCDwarfLineTableParams Params,
+ int64_t LineDelta, uint64_t AddrDelta,
+ raw_ostream &OS, uint32_t *Offset, uint32_t *Size);
+
+ /// Utility function to emit the encoding to a streamer.
+ static void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
+ int64_t LineDelta, uint64_t AddrDelta);
+};
+
+class MCGenDwarfInfo {
+public:
+ //
+ // When generating dwarf for assembly source files this emits the Dwarf
+ // sections.
+ //
+ static void Emit(MCStreamer *MCOS);
+};
+
+// When generating dwarf for assembly source files this is the info that is
+// needed to be gathered for each symbol that will have a dwarf label.
+class MCGenDwarfLabelEntry {
+private:
+ // Name of the symbol without a leading underbar, if any.
+ StringRef Name;
+ // The dwarf file number this symbol is in.
+ unsigned FileNumber;
+ // The line number this symbol is at.
+ unsigned LineNumber;
+ // The low_pc for the dwarf label is taken from this symbol.
+ MCSymbol *Label;
+
+public:
+ MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, unsigned lineNumber,
+ MCSymbol *label)
+ : Name(name), FileNumber(fileNumber), LineNumber(lineNumber),
+ Label(label) {}
+
+ StringRef getName() const { return Name; }
+ unsigned getFileNumber() const { return FileNumber; }
+ unsigned getLineNumber() const { return LineNumber; }
+ MCSymbol *getLabel() const { return Label; }
+
+ // This is called when label is created when we are generating dwarf for
+ // assembly source files.
+ static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr,
+ SMLoc &Loc);
+};
+
+class MCCFIInstruction {
+public:
+ enum OpType {
+ OpSameValue,
+ OpRememberState,
+ OpRestoreState,
+ OpOffset,
+ OpDefCfaRegister,
+ OpDefCfaOffset,
+ OpDefCfa,
+ OpRelOffset,
+ OpAdjustCfaOffset,
+ OpEscape,
+ OpRestore,
+ OpUndefined,
+ OpRegister,
+ OpWindowSave,
+ OpNegateRAState,
+ OpGnuArgsSize
+ };
+
+private:
+ OpType Operation;
+ MCSymbol *Label;
+ unsigned Register;
+ union {
+ int Offset;
+ unsigned Register2;
+ };
+ std::vector<char> Values;
+
+ MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V)
+ : Operation(Op), Label(L), Register(R), Offset(O),
+ Values(V.begin(), V.end()) {
+ assert(Op != OpRegister);
+ }
+
+ MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2)
+ : Operation(Op), Label(L), Register(R1), Register2(R2) {
+ assert(Op == OpRegister);
+ }
+
+public:
+ /// .cfi_def_cfa defines a rule for computing CFA as: take address from
+ /// Register and add Offset to it.
+ static MCCFIInstruction createDefCfa(MCSymbol *L, unsigned Register,
+ int Offset) {
+ return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
+ }
+
+ /// .cfi_def_cfa_register modifies a rule for computing CFA. From now
+ /// on Register will be used instead of the old one. Offset remains the same.
+ static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register) {
+ return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, "");
+ }
+
+ /// .cfi_def_cfa_offset modifies a rule for computing CFA. Register
+ /// remains the same, but offset is new. Note that it is the absolute offset
+ /// that will be added to a defined register to the compute CFA address.
+ static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
+ return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
+ }
+
+ /// .cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but
+ /// Offset is a relative value that is added/subtracted from the previous
+ /// offset.
+ static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int Adjustment) {
+ return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");
+ }
+
+ /// .cfi_offset Previous value of Register is saved at offset Offset
+ /// from CFA.
+ static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register,
+ int Offset) {
+ return MCCFIInstruction(OpOffset, L, Register, Offset, "");
+ }
+
+ /// .cfi_rel_offset Previous value of Register is saved at offset
+ /// Offset from the current CFA register. This is transformed to .cfi_offset
+ /// using the known displacement of the CFA register from the CFA.
+ static MCCFIInstruction createRelOffset(MCSymbol *L, unsigned Register,
+ int Offset) {
+ return MCCFIInstruction(OpRelOffset, L, Register, Offset, "");
+ }
+
+ /// .cfi_register Previous value of Register1 is saved in
+ /// register Register2.
+ static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1,
+ unsigned Register2) {
+ return MCCFIInstruction(OpRegister, L, Register1, Register2);
+ }
+
+ /// .cfi_window_save SPARC register window is saved.
+ static MCCFIInstruction createWindowSave(MCSymbol *L) {
+ return MCCFIInstruction(OpWindowSave, L, 0, 0, "");
+ }
+
+ /// .cfi_negate_ra_state AArch64 negate RA state.
+ static MCCFIInstruction createNegateRAState(MCSymbol *L) {
+ return MCCFIInstruction(OpNegateRAState, L, 0, 0, "");
+ }
+
+ /// .cfi_restore says that the rule for Register is now the same as it
+ /// was at the beginning of the function, after all initial instructions added
+ /// by .cfi_startproc were executed.
+ static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) {
+ return MCCFIInstruction(OpRestore, L, Register, 0, "");
+ }
+
+ /// .cfi_undefined From now on the previous value of Register can't be
+ /// restored anymore.
+ static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) {
+ return MCCFIInstruction(OpUndefined, L, Register, 0, "");
+ }
+
+ /// .cfi_same_value Current value of Register is the same as in the
+ /// previous frame. I.e., no restoration is needed.
+ static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) {
+ return MCCFIInstruction(OpSameValue, L, Register, 0, "");
+ }
+
+ /// .cfi_remember_state Save all current rules for all registers.
+ static MCCFIInstruction createRememberState(MCSymbol *L) {
+ return MCCFIInstruction(OpRememberState, L, 0, 0, "");
+ }
+
+ /// .cfi_restore_state Restore the previously saved state.
+ static MCCFIInstruction createRestoreState(MCSymbol *L) {
+ return MCCFIInstruction(OpRestoreState, L, 0, 0, "");
+ }
+
+ /// .cfi_escape Allows the user to add arbitrary bytes to the unwind
+ /// info.
+ static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) {
+ return MCCFIInstruction(OpEscape, L, 0, 0, Vals);
+ }
+
+ /// A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE
+ static MCCFIInstruction createGnuArgsSize(MCSymbol *L, int Size) {
+ return MCCFIInstruction(OpGnuArgsSize, L, 0, Size, "");
+ }
+
+ OpType getOperation() const { return Operation; }
+ MCSymbol *getLabel() const { return Label; }
+
+ unsigned getRegister() const {
+ assert(Operation == OpDefCfa || Operation == OpOffset ||
+ Operation == OpRestore || Operation == OpUndefined ||
+ Operation == OpSameValue || Operation == OpDefCfaRegister ||
+ Operation == OpRelOffset || Operation == OpRegister);
+ return Register;
+ }
+
+ unsigned getRegister2() const {
+ assert(Operation == OpRegister);
+ return Register2;
+ }
+
+ int getOffset() const {
+ assert(Operation == OpDefCfa || Operation == OpOffset ||
+ Operation == OpRelOffset || Operation == OpDefCfaOffset ||
+ Operation == OpAdjustCfaOffset || Operation == OpGnuArgsSize);
+ return Offset;
+ }
+
+ StringRef getValues() const {
+ assert(Operation == OpEscape);
+ return StringRef(&Values[0], Values.size());
+ }
+};
+
+struct MCDwarfFrameInfo {
+ MCDwarfFrameInfo() = default;
+
+ MCSymbol *Begin = nullptr;
+ MCSymbol *End = nullptr;
+ const MCSymbol *Personality = nullptr;
+ const MCSymbol *Lsda = nullptr;
+ std::vector<MCCFIInstruction> Instructions;
+ unsigned CurrentCfaRegister = 0;
+ unsigned PersonalityEncoding = 0;
+ unsigned LsdaEncoding = 0;
+ uint32_t CompactUnwindEncoding = 0;
+ bool IsSignalFrame = false;
+ bool IsSimple = false;
+ unsigned RAReg = static_cast<unsigned>(INT_MAX);
+ bool IsBKeyFrame = false;
+};
+
+class MCDwarfFrameEmitter {
+public:
+ //
+ // This emits the frame info section.
+ //
+ static void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH);
+ static void EmitAdvanceLoc(MCObjectStreamer &Streamer, uint64_t AddrDelta);
+ static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta,
+ raw_ostream &OS);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCDWARF_H
diff --git a/clang-r353983/include/llvm/MC/MCELFObjectWriter.h b/clang-r353983/include/llvm/MC/MCELFObjectWriter.h
new file mode 100644
index 00000000..9ff7011d
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCELFObjectWriter.h
@@ -0,0 +1,161 @@
+//===- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCELFOBJECTWRITER_H
+#define LLVM_MC_MCELFOBJECTWRITER_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSectionELF.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+
+class MCAssembler;
+class MCContext;
+class MCFixup;
+class MCObjectWriter;
+class MCSymbol;
+class MCSymbolELF;
+class MCValue;
+
+struct ELFRelocationEntry {
+ uint64_t Offset; // Where is the relocation.
+ const MCSymbolELF *Symbol; // The symbol to relocate with.
+ unsigned Type; // The type of the relocation.
+ uint64_t Addend; // The addend to use.
+ const MCSymbolELF *OriginalSymbol; // The original value of Symbol if we changed it.
+ uint64_t OriginalAddend; // The original value of addend.
+
+ ELFRelocationEntry(uint64_t Offset, const MCSymbolELF *Symbol, unsigned Type,
+ uint64_t Addend, const MCSymbolELF *OriginalSymbol,
+ uint64_t OriginalAddend)
+ : Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend),
+ OriginalSymbol(OriginalSymbol), OriginalAddend(OriginalAddend) {}
+
+ void print(raw_ostream &Out) const {
+ Out << "Off=" << Offset << ", Sym=" << Symbol << ", Type=" << Type
+ << ", Addend=" << Addend << ", OriginalSymbol=" << OriginalSymbol
+ << ", OriginalAddend=" << OriginalAddend;
+ }
+
+ void dump() const { print(errs()); }
+};
+
+class MCELFObjectTargetWriter : public MCObjectTargetWriter {
+ const uint8_t OSABI;
+ const uint16_t EMachine;
+ const unsigned HasRelocationAddend : 1;
+ const unsigned Is64Bit : 1;
+
+protected:
+ MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_, uint16_t EMachine_,
+ bool HasRelocationAddend);
+
+public:
+ virtual ~MCELFObjectTargetWriter() = default;
+
+ virtual Triple::ObjectFormatType getFormat() const { return Triple::ELF; }
+ static bool classof(const MCObjectTargetWriter *W) {
+ return W->getFormat() == Triple::ELF;
+ }
+
+ static uint8_t getOSABI(Triple::OSType OSType) {
+ switch (OSType) {
+ case Triple::CloudABI:
+ return ELF::ELFOSABI_CLOUDABI;
+ case Triple::HermitCore:
+ return ELF::ELFOSABI_STANDALONE;
+ case Triple::PS4:
+ case Triple::FreeBSD:
+ return ELF::ELFOSABI_FREEBSD;
+ default:
+ return ELF::ELFOSABI_NONE;
+ }
+ }
+
+ virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
+ const MCFixup &Fixup, bool IsPCRel) const = 0;
+
+ virtual bool needsRelocateWithSymbol(const MCSymbol &Sym,
+ unsigned Type) const;
+
+ virtual void sortRelocs(const MCAssembler &Asm,
+ std::vector<ELFRelocationEntry> &Relocs);
+
+ virtual void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec);
+
+ /// \name Accessors
+ /// @{
+ uint8_t getOSABI() const { return OSABI; }
+ uint16_t getEMachine() const { return EMachine; }
+ bool hasRelocationAddend() const { return HasRelocationAddend; }
+ bool is64Bit() const { return Is64Bit; }
+ /// @}
+
+ // Instead of changing everyone's API we pack the N64 Type fields
+ // into the existing 32 bit data unsigned.
+#define R_TYPE_SHIFT 0
+#define R_TYPE_MASK 0xffffff00
+#define R_TYPE2_SHIFT 8
+#define R_TYPE2_MASK 0xffff00ff
+#define R_TYPE3_SHIFT 16
+#define R_TYPE3_MASK 0xff00ffff
+#define R_SSYM_SHIFT 24
+#define R_SSYM_MASK 0x00ffffff
+
+ // N64 relocation type accessors
+ uint8_t getRType(uint32_t Type) const {
+ return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff);
+ }
+ uint8_t getRType2(uint32_t Type) const {
+ return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff);
+ }
+ uint8_t getRType3(uint32_t Type) const {
+ return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff);
+ }
+ uint8_t getRSsym(uint32_t Type) const {
+ return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff);
+ }
+
+ // N64 relocation type setting
+ unsigned setRType(unsigned Value, unsigned Type) const {
+ return ((Type & R_TYPE_MASK) | ((Value & 0xff) << R_TYPE_SHIFT));
+ }
+ unsigned setRType2(unsigned Value, unsigned Type) const {
+ return (Type & R_TYPE2_MASK) | ((Value & 0xff) << R_TYPE2_SHIFT);
+ }
+ unsigned setRType3(unsigned Value, unsigned Type) const {
+ return (Type & R_TYPE3_MASK) | ((Value & 0xff) << R_TYPE3_SHIFT);
+ }
+ unsigned setRSsym(unsigned Value, unsigned Type) const {
+ return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT);
+ }
+};
+
+/// Construct a new ELF writer instance.
+///
+/// \param MOTW - The target specific ELF writer subclass.
+/// \param OS - The stream to write to.
+/// \returns The constructed object writer.
+std::unique_ptr<MCObjectWriter>
+createELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
+ raw_pwrite_stream &OS, bool IsLittleEndian);
+
+std::unique_ptr<MCObjectWriter>
+createELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
+ raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS,
+ bool IsLittleEndian);
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCELFOBJECTWRITER_H
diff --git a/clang-r353983/include/llvm/MC/MCELFStreamer.h b/clang-r353983/include/llvm/MC/MCELFStreamer.h
new file mode 100644
index 00000000..8838d53d
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCELFStreamer.h
@@ -0,0 +1,108 @@
+//===- MCELFStreamer.h - MCStreamer ELF Object File Interface ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCELFSTREAMER_H
+#define LLVM_MC_MCELFSTREAMER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCObjectStreamer.h"
+
+namespace llvm {
+
+class MCAsmBackend;
+class MCCodeEmitter;
+class MCExpr;
+class MCInst;
+
+class MCELFStreamer : public MCObjectStreamer {
+public:
+ MCELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
+ std::unique_ptr<MCObjectWriter> OW,
+ std::unique_ptr<MCCodeEmitter> Emitter);
+
+ ~MCELFStreamer() override = default;
+
+ /// state management
+ void reset() override {
+ SeenIdent = false;
+ BundleGroups.clear();
+ MCObjectStreamer::reset();
+ }
+
+ /// \name MCStreamer Interface
+ /// @{
+
+ void InitSections(bool NoExecStack) override;
+ void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
+ void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
+ void EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) override;
+ void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
+ void EmitThumbFunc(MCSymbol *Func) override;
+ void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
+ bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+ void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
+ void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+
+ void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
+ void emitELFSymverDirective(StringRef AliasName,
+ const MCSymbol *Aliasee) override;
+
+ void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+
+ void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
+ uint64_t Size = 0, unsigned ByteAlignment = 0,
+ SMLoc L = SMLoc()) override;
+ void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment = 0) override;
+ void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ SMLoc Loc = SMLoc()) override;
+
+ void EmitIdent(StringRef IdentString) override;
+
+ void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned) override;
+
+ void emitCGProfileEntry(const MCSymbolRefExpr *From,
+ const MCSymbolRefExpr *To, uint64_t Count) override;
+
+ void FinishImpl() override;
+
+ void EmitBundleAlignMode(unsigned AlignPow2) override;
+ void EmitBundleLock(bool AlignToEnd) override;
+ 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);
+ void finalizeCGProfileEntry(const MCSymbolRefExpr *&S);
+ void finalizeCGProfile();
+
+ /// Merge the content of the fragment \p EF into the fragment \p DF.
+ void mergeFragment(MCDataFragment *, MCDataFragment *);
+
+ bool SeenIdent = false;
+
+ /// BundleGroups - The stack of fragments holding the bundle-locked
+ /// instructions.
+ SmallVector<MCDataFragment *, 4> BundleGroups;
+};
+
+MCELFStreamer *createARMELFStreamer(MCContext &Context,
+ std::unique_ptr<MCAsmBackend> TAB,
+ std::unique_ptr<MCObjectWriter> OW,
+ std::unique_ptr<MCCodeEmitter> Emitter,
+ bool RelaxAll, bool IsThumb);
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCELFSTREAMER_H
diff --git a/clang-r353983/include/llvm/MC/MCExpr.h b/clang-r353983/include/llvm/MC/MCExpr.h
new file mode 100644
index 00000000..85316303
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCExpr.h
@@ -0,0 +1,609 @@
+//===- MCExpr.h - Assembly Level Expressions --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCEXPR_H
+#define LLVM_MC_MCEXPR_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/SMLoc.h"
+#include <cstdint>
+
+namespace llvm {
+
+class MCAsmInfo;
+class MCAsmLayout;
+class MCAssembler;
+class MCContext;
+class MCFixup;
+class MCFragment;
+class MCSection;
+class MCStreamer;
+class MCSymbol;
+class MCValue;
+class raw_ostream;
+class StringRef;
+
+using SectionAddrMap = DenseMap<const MCSection *, uint64_t>;
+
+/// Base class for the full range of assembler expressions which are
+/// needed for parsing.
+class MCExpr {
+public:
+ enum ExprKind {
+ Binary, ///< Binary expressions.
+ Constant, ///< Constant expressions.
+ SymbolRef, ///< References to labels and assigned expressions.
+ Unary, ///< Unary expressions.
+ Target ///< Target specific expression.
+ };
+
+private:
+ ExprKind Kind;
+ SMLoc Loc;
+
+ bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
+ const MCAsmLayout *Layout,
+ const SectionAddrMap *Addrs) const;
+
+ bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
+ const MCAsmLayout *Layout,
+ const SectionAddrMap *Addrs, bool InSet) const;
+
+protected:
+ explicit MCExpr(ExprKind Kind, SMLoc Loc) : Kind(Kind), Loc(Loc) {}
+
+ bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
+ const MCAsmLayout *Layout,
+ const MCFixup *Fixup,
+ const SectionAddrMap *Addrs, bool InSet) const;
+
+public:
+ MCExpr(const MCExpr &) = delete;
+ MCExpr &operator=(const MCExpr &) = delete;
+
+ /// \name Accessors
+ /// @{
+
+ ExprKind getKind() const { return Kind; }
+ SMLoc getLoc() const { return Loc; }
+
+ /// @}
+ /// \name Utility Methods
+ /// @{
+
+ void print(raw_ostream &OS, const MCAsmInfo *MAI,
+ bool InParens = false) const;
+ void dump() const;
+
+ /// @}
+ /// \name Expression Evaluation
+ /// @{
+
+ /// Try to evaluate the expression to an absolute value.
+ ///
+ /// \param Res - The absolute value, if evaluation succeeds.
+ /// \param Layout - The assembler layout object to use for evaluating symbol
+ /// values. If not given, then only non-symbolic expressions will be
+ /// evaluated.
+ /// \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 MCAssembler *Asm) const;
+ bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
+
+ bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
+
+ /// 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.
+ /// \return - True on success.
+ bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout,
+ const MCFixup *Fixup) const;
+
+ /// Try to evaluate the expression to the form (a - b + constant) where
+ /// neither a nor b are variables.
+ ///
+ /// This is a more aggressive variant of evaluateAsRelocatable. The intended
+ /// use is for when relocations are not available, like the .size directive.
+ bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const;
+
+ /// 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.
+ MCFragment *findAssociatedFragment() const;
+
+ /// @}
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
+ E.print(OS, nullptr);
+ return OS;
+}
+
+//// Represent a constant integer expression.
+class MCConstantExpr : public MCExpr {
+ int64_t Value;
+
+ explicit MCConstantExpr(int64_t Value)
+ : MCExpr(MCExpr::Constant, SMLoc()), Value(Value) {}
+
+public:
+ /// \name Construction
+ /// @{
+
+ static const MCConstantExpr *create(int64_t Value, MCContext &Ctx);
+
+ /// @}
+ /// \name Accessors
+ /// @{
+
+ int64_t getValue() const { return Value; }
+
+ /// @}
+
+ static bool classof(const MCExpr *E) {
+ return E->getKind() == MCExpr::Constant;
+ }
+};
+
+/// 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 : uint16_t {
+ VK_None,
+ VK_Invalid,
+
+ VK_GOT,
+ VK_GOTOFF,
+ VK_GOTREL,
+ VK_GOTPCREL,
+ VK_GOTTPOFF,
+ VK_INDNTPOFF,
+ VK_NTPOFF,
+ VK_GOTNTPOFF,
+ VK_PLT,
+ VK_TLSGD,
+ VK_TLSLD,
+ VK_TLSLDM,
+ VK_TPOFF,
+ VK_DTPOFF,
+ VK_TLSCALL, // symbol(tlscall)
+ VK_TLSDESC, // symbol(tlsdesc)
+ VK_TLVP, // Mach-O thread local variable relocations
+ VK_TLVPPAGE,
+ VK_TLVPPAGEOFF,
+ VK_PAGE,
+ VK_PAGEOFF,
+ VK_GOTPAGE,
+ VK_GOTPAGEOFF,
+ VK_SECREL,
+ VK_SIZE, // symbol@SIZE
+ VK_WEAKREF, // The link between the symbols in .weakref foo, bar
+
+ VK_X86_ABS8,
+
+ VK_ARM_NONE,
+ VK_ARM_GOT_PREL,
+ VK_ARM_TARGET1,
+ VK_ARM_TARGET2,
+ VK_ARM_PREL31,
+ VK_ARM_SBREL, // symbol(sbrel)
+ VK_ARM_TLSLDO, // symbol(tlsldo)
+ VK_ARM_TLSDESCSEQ,
+
+ VK_AVR_NONE,
+ VK_AVR_LO8,
+ VK_AVR_HI8,
+ VK_AVR_HLO8,
+ VK_AVR_DIFF8,
+ VK_AVR_DIFF16,
+ VK_AVR_DIFF32,
+
+ VK_PPC_LO, // symbol@l
+ VK_PPC_HI, // symbol@h
+ VK_PPC_HA, // symbol@ha
+ VK_PPC_HIGH, // symbol@high
+ VK_PPC_HIGHA, // symbol@higha
+ VK_PPC_HIGHER, // symbol@higher
+ VK_PPC_HIGHERA, // symbol@highera
+ VK_PPC_HIGHEST, // symbol@highest
+ VK_PPC_HIGHESTA, // symbol@highesta
+ VK_PPC_GOT_LO, // symbol@got@l
+ VK_PPC_GOT_HI, // symbol@got@h
+ VK_PPC_GOT_HA, // symbol@got@ha
+ VK_PPC_TOCBASE, // symbol@tocbase
+ VK_PPC_TOC, // symbol@toc
+ VK_PPC_TOC_LO, // symbol@toc@l
+ VK_PPC_TOC_HI, // symbol@toc@h
+ VK_PPC_TOC_HA, // symbol@toc@ha
+ VK_PPC_DTPMOD, // symbol@dtpmod
+ VK_PPC_TPREL_LO, // symbol@tprel@l
+ VK_PPC_TPREL_HI, // symbol@tprel@h
+ VK_PPC_TPREL_HA, // symbol@tprel@ha
+ VK_PPC_TPREL_HIGH, // symbol@tprel@high
+ VK_PPC_TPREL_HIGHA, // symbol@tprel@higha
+ VK_PPC_TPREL_HIGHER, // symbol@tprel@higher
+ VK_PPC_TPREL_HIGHERA, // symbol@tprel@highera
+ VK_PPC_TPREL_HIGHEST, // symbol@tprel@highest
+ VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta
+ VK_PPC_DTPREL_LO, // symbol@dtprel@l
+ VK_PPC_DTPREL_HI, // symbol@dtprel@h
+ VK_PPC_DTPREL_HA, // symbol@dtprel@ha
+ VK_PPC_DTPREL_HIGH, // symbol@dtprel@high
+ VK_PPC_DTPREL_HIGHA, // symbol@dtprel@higha
+ VK_PPC_DTPREL_HIGHER, // symbol@dtprel@higher
+ VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera
+ VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest
+ VK_PPC_DTPREL_HIGHESTA,// symbol@dtprel@highesta
+ VK_PPC_GOT_TPREL, // symbol@got@tprel
+ VK_PPC_GOT_TPREL_LO, // symbol@got@tprel@l
+ VK_PPC_GOT_TPREL_HI, // symbol@got@tprel@h
+ VK_PPC_GOT_TPREL_HA, // symbol@got@tprel@ha
+ VK_PPC_GOT_DTPREL, // symbol@got@dtprel
+ VK_PPC_GOT_DTPREL_LO, // symbol@got@dtprel@l
+ VK_PPC_GOT_DTPREL_HI, // symbol@got@dtprel@h
+ VK_PPC_GOT_DTPREL_HA, // symbol@got@dtprel@ha
+ VK_PPC_TLS, // symbol@tls
+ VK_PPC_GOT_TLSGD, // symbol@got@tlsgd
+ VK_PPC_GOT_TLSGD_LO, // symbol@got@tlsgd@l
+ VK_PPC_GOT_TLSGD_HI, // symbol@got@tlsgd@h
+ VK_PPC_GOT_TLSGD_HA, // symbol@got@tlsgd@ha
+ VK_PPC_TLSGD, // symbol@tlsgd
+ VK_PPC_GOT_TLSLD, // symbol@got@tlsld
+ VK_PPC_GOT_TLSLD_LO, // symbol@got@tlsld@l
+ VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h
+ VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha
+ VK_PPC_TLSLD, // symbol@tlsld
+ VK_PPC_LOCAL, // symbol@local
+
+ 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_WebAssembly_FUNCTION, // Function table index, rather than virtual addr
+ VK_WebAssembly_GLOBAL, // Global object index
+ VK_WebAssembly_TYPEINDEX,// Type table index
+ VK_WebAssembly_EVENT, // Event index
+
+ VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo
+ VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi
+ VK_AMDGPU_REL32_LO, // symbol@rel32@lo
+ VK_AMDGPU_REL32_HI, // symbol@rel32@hi
+ VK_AMDGPU_REL64, // symbol@rel64
+
+ VK_TPREL,
+ VK_DTPREL
+ };
+
+private:
+ /// The symbol reference modifier.
+ const VariantKind Kind;
+
+ /// Specifies how the variant kind should be printed.
+ const unsigned UseParensForSymbolVariant : 1;
+
+ // FIXME: Remove this bit.
+ const unsigned HasSubsectionsViaSymbols : 1;
+
+ /// The symbol being referenced.
+ const MCSymbol *Symbol;
+
+ explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
+ const MCAsmInfo *MAI, SMLoc Loc = SMLoc());
+
+public:
+ /// \name Construction
+ /// @{
+
+ static const MCSymbolRefExpr *create(const MCSymbol *Symbol, MCContext &Ctx) {
+ return MCSymbolRefExpr::create(Symbol, VK_None, Ctx);
+ }
+
+ static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind,
+ MCContext &Ctx, SMLoc Loc = SMLoc());
+ static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind,
+ MCContext &Ctx);
+
+ /// @}
+ /// \name Accessors
+ /// @{
+
+ const MCSymbol &getSymbol() const { return *Symbol; }
+
+ VariantKind getKind() const { return Kind; }
+
+ void printVariantKind(raw_ostream &OS) const;
+
+ bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
+
+ /// @}
+ /// \name Static Utility Functions
+ /// @{
+
+ static StringRef getVariantKindName(VariantKind Kind);
+
+ static VariantKind getVariantKindForName(StringRef Name);
+
+ /// @}
+
+ static bool classof(const MCExpr *E) {
+ return E->getKind() == MCExpr::SymbolRef;
+ }
+};
+
+/// Unary assembler expressions.
+class MCUnaryExpr : public MCExpr {
+public:
+ enum Opcode {
+ LNot, ///< Logical negation.
+ Minus, ///< Unary minus.
+ Not, ///< Bitwise negation.
+ Plus ///< Unary plus.
+ };
+
+private:
+ Opcode Op;
+ const MCExpr *Expr;
+
+ MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc)
+ : MCExpr(MCExpr::Unary, Loc), Op(Op), Expr(Expr) {}
+
+public:
+ /// \name Construction
+ /// @{
+
+ static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr,
+ MCContext &Ctx, SMLoc Loc = SMLoc());
+
+ static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
+ return create(LNot, Expr, Ctx, Loc);
+ }
+
+ static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
+ return create(Minus, Expr, Ctx, Loc);
+ }
+
+ static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
+ return create(Not, Expr, Ctx, Loc);
+ }
+
+ static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
+ return create(Plus, Expr, Ctx, Loc);
+ }
+
+ /// @}
+ /// \name Accessors
+ /// @{
+
+ /// Get the kind of this unary expression.
+ Opcode getOpcode() const { return Op; }
+
+ /// Get the child of this unary expression.
+ const MCExpr *getSubExpr() const { return Expr; }
+
+ /// @}
+
+ static bool classof(const MCExpr *E) {
+ return E->getKind() == MCExpr::Unary;
+ }
+};
+
+/// Binary assembler expressions.
+class MCBinaryExpr : public MCExpr {
+public:
+ enum Opcode {
+ Add, ///< Addition.
+ And, ///< Bitwise and.
+ Div, ///< Signed division.
+ EQ, ///< Equality comparison.
+ GT, ///< Signed greater than comparison (result is either 0 or some
+ ///< target-specific non-zero value)
+ GTE, ///< Signed greater than or equal comparison (result is either 0 or
+ ///< some target-specific non-zero value).
+ LAnd, ///< Logical and.
+ LOr, ///< Logical or.
+ LT, ///< Signed less than comparison (result is either 0 or
+ ///< some target-specific non-zero value).
+ LTE, ///< Signed less than or equal comparison (result is either 0 or
+ ///< some target-specific non-zero value).
+ Mod, ///< Signed remainder.
+ Mul, ///< Multiplication.
+ NE, ///< Inequality comparison.
+ Or, ///< Bitwise or.
+ Shl, ///< Shift left.
+ AShr, ///< Arithmetic shift right.
+ LShr, ///< Logical shift right.
+ Sub, ///< Subtraction.
+ Xor ///< Bitwise exclusive or.
+ };
+
+private:
+ Opcode Op;
+ const MCExpr *LHS, *RHS;
+
+ MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS,
+ SMLoc Loc = SMLoc())
+ : MCExpr(MCExpr::Binary, Loc), Op(Op), LHS(LHS), RHS(RHS) {}
+
+public:
+ /// \name Construction
+ /// @{
+
+ static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS,
+ const MCExpr *RHS, MCContext &Ctx,
+ SMLoc Loc = SMLoc());
+
+ static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(Add, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(And, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(Div, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(EQ, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(GT, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(GTE, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(LAnd, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(LOr, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(LT, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(LTE, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(Mod, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(Mul, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(NE, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(Or, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(Shl, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &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) {
+ return create(Sub, LHS, RHS, Ctx);
+ }
+
+ static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return create(Xor, LHS, RHS, Ctx);
+ }
+
+ /// @}
+ /// \name Accessors
+ /// @{
+
+ /// Get the kind of this binary expression.
+ Opcode getOpcode() const { return Op; }
+
+ /// Get the left-hand side expression of the binary operator.
+ const MCExpr *getLHS() const { return LHS; }
+
+ /// Get the right-hand side expression of the binary operator.
+ const MCExpr *getRHS() const { return RHS; }
+
+ /// @}
+
+ static bool classof(const MCExpr *E) {
+ return E->getKind() == MCExpr::Binary;
+ }
+};
+
+/// This is an extension point for target-specific MCExpr subclasses to
+/// implement.
+///
+/// NOTE: All subclasses are required to have trivial destructors because
+/// MCExprs are bump pointer allocated and not destructed.
+class MCTargetExpr : public MCExpr {
+ virtual void anchor();
+
+protected:
+ MCTargetExpr() : MCExpr(Target, SMLoc()) {}
+ virtual ~MCTargetExpr() = default;
+
+public:
+ virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0;
+ virtual bool evaluateAsRelocatableImpl(MCValue &Res,
+ const MCAsmLayout *Layout,
+ const MCFixup *Fixup) const = 0;
+ // allow Target Expressions to be checked for equality
+ virtual bool isEqualTo(const MCExpr *x) const { return false; }
+ // This should be set when assigned expressions are not valid ".set"
+ // expressions, e.g. registers, and must be inlined.
+ virtual bool inlineAssignedExpr() const { return false; }
+ virtual void visitUsedExpr(MCStreamer& Streamer) const = 0;
+ virtual MCFragment *findAssociatedFragment() const = 0;
+
+ virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
+
+ static bool classof(const MCExpr *E) {
+ return E->getKind() == MCExpr::Target;
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCEXPR_H
diff --git a/clang-r353983/include/llvm/MC/MCFixedLenDisassembler.h b/clang-r353983/include/llvm/MC/MCFixedLenDisassembler.h
new file mode 100644
index 00000000..218ae0d1
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCFixedLenDisassembler.h
@@ -0,0 +1,33 @@
+//===-- llvm/MC/MCFixedLenDisassembler.h - Decoder driver -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// Fixed length disassembler decoder state machine driver.
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_MC_MCFIXEDLENDISASSEMBLER_H
+#define LLVM_MC_MCFIXEDLENDISASSEMBLER_H
+
+namespace llvm {
+
+namespace MCD {
+// Disassembler state machine opcodes.
+enum DecoderOps {
+ OPC_ExtractField = 1, // OPC_ExtractField(uint8_t Start, uint8_t Len)
+ OPC_FilterValue, // OPC_FilterValue(uleb128 Val, uint16_t NumToSkip)
+ OPC_CheckField, // OPC_CheckField(uint8_t Start, uint8_t Len,
+ // uleb128 Val, uint16_t NumToSkip)
+ OPC_CheckPredicate, // OPC_CheckPredicate(uleb128 PIdx, uint16_t NumToSkip)
+ OPC_Decode, // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
+ OPC_TryDecode, // OPC_TryDecode(uleb128 Opcode, uleb128 DIdx,
+ // uint16_t NumToSkip)
+ OPC_SoftFail, // OPC_SoftFail(uleb128 PMask, uleb128 NMask)
+ OPC_Fail // OPC_Fail()
+};
+
+} // namespace MCDecode
+} // namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCFixup.h b/clang-r353983/include/llvm/MC/MCFixup.h
new file mode 100644
index 00000000..559a19e9
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCFixup.h
@@ -0,0 +1,170 @@
+//===-- llvm/MC/MCFixup.h - Instruction Relocation and Patching -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCFIXUP_H
+#define LLVM_MC_MCFIXUP_H
+
+#include "llvm/MC/MCExpr.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SMLoc.h"
+#include <cassert>
+
+namespace llvm {
+class MCExpr;
+
+/// Extensible enumeration to represent the type of a fixup.
+enum MCFixupKind {
+ FK_Data_1 = 0, ///< A one-byte fixup.
+ FK_Data_2, ///< A two-byte fixup.
+ FK_Data_4, ///< A four-byte fixup.
+ FK_Data_8, ///< A eight-byte fixup.
+ FK_PCRel_1, ///< A one-byte pc relative fixup.
+ FK_PCRel_2, ///< A two-byte pc relative fixup.
+ FK_PCRel_4, ///< A four-byte pc relative fixup.
+ FK_PCRel_8, ///< A eight-byte pc relative fixup.
+ FK_GPRel_1, ///< A one-byte gp relative fixup.
+ FK_GPRel_2, ///< A two-byte gp relative fixup.
+ FK_GPRel_4, ///< A four-byte gp relative fixup.
+ FK_GPRel_8, ///< A eight-byte gp relative fixup.
+ FK_DTPRel_4, ///< A four-byte dtp relative fixup.
+ FK_DTPRel_8, ///< A eight-byte dtp relative fixup.
+ FK_TPRel_4, ///< A four-byte tp relative fixup.
+ FK_TPRel_8, ///< A eight-byte tp relative fixup.
+ FK_SecRel_1, ///< A one-byte section relative fixup.
+ FK_SecRel_2, ///< A two-byte section relative fixup.
+ FK_SecRel_4, ///< A four-byte section relative fixup.
+ FK_SecRel_8, ///< A eight-byte section relative fixup.
+ FK_Data_Add_1, ///< A one-byte add fixup.
+ FK_Data_Add_2, ///< A two-byte add fixup.
+ FK_Data_Add_4, ///< A four-byte add fixup.
+ FK_Data_Add_8, ///< A eight-byte add fixup.
+ FK_Data_Sub_1, ///< A one-byte sub fixup.
+ FK_Data_Sub_2, ///< A two-byte sub fixup.
+ FK_Data_Sub_4, ///< A four-byte sub fixup.
+ FK_Data_Sub_8, ///< A eight-byte sub fixup.
+
+ FirstTargetFixupKind = 128,
+
+ // Limit range of target fixups, in case we want to pack more efficiently
+ // later.
+ MaxTargetFixupKind = (1 << 8)
+};
+
+/// Encode information on a single operation to perform on a byte
+/// sequence (e.g., an encoded instruction) which requires assemble- or run-
+/// time patching.
+///
+/// Fixups are used any time the target instruction encoder needs to represent
+/// some value in an instruction which is not yet concrete. The encoder will
+/// encode the instruction assuming the value is 0, and emit a fixup which
+/// communicates to the assembler backend how it should rewrite the encoded
+/// value.
+///
+/// During the process of relaxation, the assembler will apply fixups as
+/// symbolic values become concrete. When relaxation is complete, any remaining
+/// fixups become relocations in the object file (or errors, if the fixup cannot
+/// be encoded on the target).
+class MCFixup {
+ /// The value to put into the fixup location. The exact interpretation of the
+ /// expression is target dependent, usually it will be one of the operands to
+ /// an instruction or an assembler directive.
+ const MCExpr *Value;
+
+ /// The byte index of start of the relocation inside the MCFragment.
+ uint32_t Offset;
+
+ /// The target dependent kind of fixup item this is. The kind is used to
+ /// determine how the operand value should be encoded into the instruction.
+ unsigned Kind;
+
+ /// The source location which gave rise to the fixup, if any.
+ SMLoc Loc;
+public:
+ static MCFixup create(uint32_t Offset, const MCExpr *Value,
+ MCFixupKind Kind, SMLoc Loc = SMLoc()) {
+ assert(unsigned(Kind) < MaxTargetFixupKind && "Kind out of range!");
+ MCFixup FI;
+ FI.Value = Value;
+ FI.Offset = Offset;
+ FI.Kind = unsigned(Kind);
+ FI.Loc = Loc;
+ return FI;
+ }
+
+ /// Return a fixup corresponding to the add half of a add/sub fixup pair for
+ /// the given Fixup.
+ static MCFixup createAddFor(const MCFixup &Fixup) {
+ MCFixup FI;
+ FI.Value = Fixup.getValue();
+ FI.Offset = Fixup.getOffset();
+ FI.Kind = (unsigned)getAddKindForKind(Fixup.getKind());
+ FI.Loc = Fixup.getLoc();
+ return FI;
+ }
+
+ /// Return a fixup corresponding to the sub half of a add/sub fixup pair for
+ /// the given Fixup.
+ static MCFixup createSubFor(const MCFixup &Fixup) {
+ MCFixup FI;
+ FI.Value = Fixup.getValue();
+ FI.Offset = Fixup.getOffset();
+ FI.Kind = (unsigned)getSubKindForKind(Fixup.getKind());
+ FI.Loc = Fixup.getLoc();
+ return FI;
+ }
+
+ MCFixupKind getKind() const { return MCFixupKind(Kind); }
+
+ uint32_t getOffset() const { return Offset; }
+ void setOffset(uint32_t Value) { Offset = Value; }
+
+ const MCExpr *getValue() const { return Value; }
+
+ /// Return the generic fixup kind for a value with the given size. It
+ /// is an error to pass an unsupported size.
+ static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) {
+ switch (Size) {
+ default: llvm_unreachable("Invalid generic fixup size!");
+ case 1: return isPCRel ? FK_PCRel_1 : FK_Data_1;
+ case 2: return isPCRel ? FK_PCRel_2 : FK_Data_2;
+ case 4: return isPCRel ? FK_PCRel_4 : FK_Data_4;
+ case 8: return isPCRel ? FK_PCRel_8 : FK_Data_8;
+ }
+ }
+
+ /// Return the generic fixup kind for an addition with a given size. It
+ /// is an error to pass an unsupported size.
+ static MCFixupKind getAddKindForKind(unsigned Kind) {
+ switch (Kind) {
+ default: llvm_unreachable("Unknown type to convert!");
+ case FK_Data_1: return FK_Data_Add_1;
+ case FK_Data_2: return FK_Data_Add_2;
+ case FK_Data_4: return FK_Data_Add_4;
+ case FK_Data_8: return FK_Data_Add_8;
+ }
+ }
+
+ /// Return the generic fixup kind for an subtraction with a given size. It
+ /// is an error to pass an unsupported size.
+ static MCFixupKind getSubKindForKind(unsigned Kind) {
+ switch (Kind) {
+ default: llvm_unreachable("Unknown type to convert!");
+ case FK_Data_1: return FK_Data_Sub_1;
+ case FK_Data_2: return FK_Data_Sub_2;
+ case FK_Data_4: return FK_Data_Sub_4;
+ case FK_Data_8: return FK_Data_Sub_8;
+ }
+ }
+
+ SMLoc getLoc() const { return Loc; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCFixupKindInfo.h b/clang-r353983/include/llvm/MC/MCFixupKindInfo.h
new file mode 100644
index 00000000..0ea34866
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCFixupKindInfo.h
@@ -0,0 +1,42 @@
+//===-- llvm/MC/MCFixupKindInfo.h - Fixup Descriptors -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCFIXUPKINDINFO_H
+#define LLVM_MC_MCFIXUPKINDINFO_H
+
+namespace llvm {
+
+/// Target independent information on a fixup kind.
+struct MCFixupKindInfo {
+ enum FixupKindFlags {
+ /// Is this fixup kind PCrelative? This is used by the assembler backend to
+ /// evaluate fixup values in a target independent manner when possible.
+ FKF_IsPCRel = (1 << 0),
+
+ /// Should this fixup kind force a 4-byte aligned effective PC value?
+ FKF_IsAlignedDownTo32Bits = (1 << 1)
+ };
+
+ /// A target specific name for the fixup kind. The names will be unique for
+ /// distinct kinds on any given target.
+ const char *Name;
+
+ /// The bit offset to write the relocation into.
+ unsigned TargetOffset;
+
+ /// The number of bits written by this fixup. The bits are assumed to be
+ /// contiguous.
+ unsigned TargetSize;
+
+ /// Flags describing additional information on this fixup kind.
+ unsigned Flags;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCFragment.h b/clang-r353983/include/llvm/MC/MCFragment.h
new file mode 100644
index 00000000..aadf2ce7
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCFragment.h
@@ -0,0 +1,667 @@
+//===- MCFragment.h - Fragment type hierarchy -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCFRAGMENT_H
+#define LLVM_MC_MCFRAGMENT_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/SMLoc.h"
+#include <cstdint>
+#include <utility>
+
+namespace llvm {
+
+class MCSection;
+class MCSubtargetInfo;
+class MCSymbol;
+
+class MCFragment : public ilist_node_with_parent<MCFragment, MCSection> {
+ friend class MCAsmLayout;
+
+public:
+ enum FragmentType : uint8_t {
+ FT_Align,
+ FT_Data,
+ FT_CompactEncodedInst,
+ FT_Fill,
+ FT_Relaxable,
+ FT_Org,
+ FT_Dwarf,
+ FT_DwarfFrame,
+ FT_LEB,
+ FT_Padding,
+ FT_SymbolId,
+ FT_CVInlineLines,
+ FT_CVDefRange,
+ FT_Dummy
+ };
+
+private:
+ FragmentType Kind;
+
+protected:
+ bool HasInstructions;
+
+private:
+ /// LayoutOrder - The layout order of this fragment.
+ unsigned LayoutOrder;
+
+ /// The data for the section this fragment is in.
+ MCSection *Parent;
+
+ /// Atom - The atom this fragment is in, as represented by its defining
+ /// symbol.
+ const MCSymbol *Atom;
+
+ /// \name Assembler Backend Data
+ /// @{
+ //
+ // FIXME: This could all be kept private to the assembler implementation.
+
+ /// Offset - The offset of this fragment in its section. This is ~0 until
+ /// initialized.
+ uint64_t Offset;
+
+ /// @}
+
+protected:
+ MCFragment(FragmentType Kind, bool HasInstructions,
+ MCSection *Parent = nullptr);
+
+ ~MCFragment();
+
+public:
+ MCFragment() = delete;
+ MCFragment(const MCFragment &) = delete;
+ MCFragment &operator=(const MCFragment &) = delete;
+
+ /// Destroys the current fragment.
+ ///
+ /// This must be used instead of delete as MCFragment is non-virtual.
+ /// This method will dispatch to the appropriate subclass.
+ void destroy();
+
+ FragmentType getKind() const { return Kind; }
+
+ MCSection *getParent() const { return Parent; }
+ void setParent(MCSection *Value) { Parent = 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; }
+
+ /// Does this fragment have instructions emitted into it? By default
+ /// this is false, but specific fragment types may set it to true.
+ bool hasInstructions() const { return HasInstructions; }
+
+ /// Return true if given frgment has FT_Dummy type.
+ bool isDummy() const { return Kind == FT_Dummy; }
+
+ void dump() const;
+};
+
+class MCDummyFragment : public MCFragment {
+public:
+ explicit MCDummyFragment(MCSection *Sec) : MCFragment(FT_Dummy, false, Sec) {}
+
+ static bool classof(const MCFragment *F) { return F->getKind() == FT_Dummy; }
+};
+
+/// Interface implemented by fragments that contain encoded instructions and/or
+/// data.
+///
+class MCEncodedFragment : public MCFragment {
+ /// Should this fragment be aligned to the end of a bundle?
+ bool AlignToBundleEnd = false;
+
+ uint8_t BundlePadding = 0;
+
+protected:
+ MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions,
+ MCSection *Sec)
+ : MCFragment(FType, HasInstructions, Sec) {}
+
+ /// STI - The MCSubtargetInfo in effect when the instruction was encoded.
+ /// must be non-null for instructions.
+ const MCSubtargetInfo *STI = nullptr;
+
+public:
+ 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:
+ case MCFragment::FT_Dwarf:
+ return true;
+ }
+ }
+
+ /// Should this fragment be placed at the end of an aligned bundle?
+ bool alignToBundleEnd() const { return AlignToBundleEnd; }
+ void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
+
+ /// 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.
+ uint8_t getBundlePadding() const { return BundlePadding; }
+
+ /// Set the padding size for this fragment. By default it's a no-op,
+ /// and only some fragments have a meaningful implementation.
+ void setBundlePadding(uint8_t N) { BundlePadding = N; }
+
+ /// Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
+ /// Guaranteed to be non-null if hasInstructions() == true
+ const MCSubtargetInfo *getSubtargetInfo() const { return STI; }
+
+ /// Record that the fragment contains instructions with the MCSubtargetInfo in
+ /// effect when the instruction was encoded.
+ void setHasInstructions(const MCSubtargetInfo &STI) {
+ HasInstructions = true;
+ this->STI = &STI;
+ }
+};
+
+/// Interface implemented by fragments that contain encoded instructions and/or
+/// data.
+///
+template<unsigned ContentsSize>
+class MCEncodedFragmentWithContents : public MCEncodedFragment {
+ SmallVector<char, ContentsSize> Contents;
+
+protected:
+ MCEncodedFragmentWithContents(MCFragment::FragmentType FType,
+ bool HasInstructions,
+ MCSection *Sec)
+ : MCEncodedFragment(FType, HasInstructions, Sec) {}
+
+public:
+ SmallVectorImpl<char> &getContents() { return Contents; }
+ const SmallVectorImpl<char> &getContents() const { return Contents; }
+};
+
+/// Interface implemented by fragments that contain encoded instructions and/or
+/// data and also have fixups registered.
+///
+template<unsigned ContentsSize, unsigned FixupsSize>
+class MCEncodedFragmentWithFixups :
+ public MCEncodedFragmentWithContents<ContentsSize> {
+
+ /// Fixups - The list of fixups in this fragment.
+ SmallVector<MCFixup, FixupsSize> Fixups;
+
+protected:
+ MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
+ bool HasInstructions,
+ MCSection *Sec)
+ : MCEncodedFragmentWithContents<ContentsSize>(FType, HasInstructions,
+ Sec) {}
+
+public:
+
+ using const_fixup_iterator = SmallVectorImpl<MCFixup>::const_iterator;
+ using fixup_iterator = SmallVectorImpl<MCFixup>::iterator;
+
+ SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
+ const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
+
+ fixup_iterator fixup_begin() { return Fixups.begin(); }
+ const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
+
+ fixup_iterator fixup_end() { return Fixups.end(); }
+ const_fixup_iterator fixup_end() const { return Fixups.end(); }
+
+ static bool classof(const MCFragment *F) {
+ MCFragment::FragmentType Kind = F->getKind();
+ return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data ||
+ Kind == MCFragment::FT_CVDefRange || Kind == MCFragment::FT_Dwarf;;
+ }
+};
+
+/// Fragment for data and encoded instructions.
+///
+class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
+public:
+ MCDataFragment(MCSection *Sec = nullptr)
+ : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Data;
+ }
+};
+
+/// This is a compact (memory-size-wise) fragment for holding an encoded
+/// instruction (non-relaxable) that has no fixups registered. When applicable,
+/// it can be used instead of MCDataFragment and lead to lower memory
+/// consumption.
+///
+class MCCompactEncodedInstFragment : public MCEncodedFragmentWithContents<4> {
+public:
+ MCCompactEncodedInstFragment(MCSection *Sec = nullptr)
+ : MCEncodedFragmentWithContents(FT_CompactEncodedInst, true, Sec) {
+ }
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_CompactEncodedInst;
+ }
+};
+
+/// A relaxable fragment holds on to its MCInst, since it may need to be
+/// relaxed during the assembler layout and relaxation stage.
+///
+class MCRelaxableFragment : public MCEncodedFragmentWithFixups<8, 1> {
+
+ /// Inst - The instruction this is a fragment for.
+ MCInst Inst;
+
+public:
+ MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI,
+ MCSection *Sec = nullptr)
+ : MCEncodedFragmentWithFixups(FT_Relaxable, true, Sec),
+ Inst(Inst) { this->STI = &STI; }
+
+ const MCInst &getInst() const { return Inst; }
+ void setInst(const MCInst &Value) { Inst = Value; }
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Relaxable;
+ }
+};
+
+class MCAlignFragment : public MCFragment {
+ /// Alignment - The alignment to ensure, in bytes.
+ unsigned Alignment;
+
+ /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
+ /// of using the provided value. The exact interpretation of this flag is
+ /// target dependent.
+ bool EmitNops : 1;
+
+ /// Value - Value to use for filling padding bytes.
+ int64_t Value;
+
+ /// ValueSize - The size of the integer (in bytes) of \p Value.
+ unsigned ValueSize;
+
+ /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
+ /// cannot be satisfied in this width then this fragment is ignored.
+ unsigned MaxBytesToEmit;
+
+public:
+ MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize,
+ unsigned MaxBytesToEmit, MCSection *Sec = nullptr)
+ : MCFragment(FT_Align, false, Sec), Alignment(Alignment), EmitNops(false),
+ Value(Value), ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
+
+ /// \name Accessors
+ /// @{
+
+ unsigned getAlignment() const { return Alignment; }
+
+ int64_t getValue() const { return Value; }
+
+ unsigned getValueSize() const { return ValueSize; }
+
+ unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
+
+ bool hasEmitNops() const { return EmitNops; }
+ void setEmitNops(bool Value) { EmitNops = Value; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Align;
+ }
+};
+
+/// Fragment for adding required padding.
+/// This fragment is always inserted before an instruction, and holds that
+/// instruction as context information (as well as a mask of kinds) for
+/// determining the padding size.
+///
+class MCPaddingFragment : public MCFragment {
+ /// A mask containing all the kinds relevant to this fragment. i.e. the i'th
+ /// bit will be set iff kind i is relevant to this fragment.
+ uint64_t PaddingPoliciesMask;
+ /// A boolean indicating if this fragment will actually hold padding. If its
+ /// value is false, then this fragment serves only as a placeholder,
+ /// containing data to assist other insertion point in their decision making.
+ bool IsInsertionPoint;
+
+ uint64_t Size;
+
+ struct MCInstInfo {
+ bool IsInitialized;
+ MCInst Inst;
+ /// A boolean indicating whether the instruction pointed by this fragment is
+ /// a fixed size instruction or a relaxable instruction held by a
+ /// MCRelaxableFragment.
+ bool IsImmutableSizedInst;
+ union {
+ /// If the instruction is a fixed size instruction, hold its size.
+ size_t InstSize;
+ /// Otherwise, hold a pointer to the MCRelaxableFragment holding it.
+ MCRelaxableFragment *InstFragment;
+ };
+ };
+ MCInstInfo InstInfo;
+
+public:
+ static const uint64_t PFK_None = UINT64_C(0);
+
+ enum MCPaddingFragmentKind {
+ // values 0-7 are reserved for future target independet values.
+
+ FirstTargetPerfNopFragmentKind = 8,
+
+ /// Limit range of target MCPerfNopFragment kinds to fit in uint64_t
+ MaxTargetPerfNopFragmentKind = 63
+ };
+
+ MCPaddingFragment(MCSection *Sec = nullptr)
+ : MCFragment(FT_Padding, false, Sec), PaddingPoliciesMask(PFK_None),
+ IsInsertionPoint(false), Size(UINT64_C(0)),
+ InstInfo({false, MCInst(), false, {0}}) {}
+
+ bool isInsertionPoint() const { return IsInsertionPoint; }
+ void setAsInsertionPoint() { IsInsertionPoint = true; }
+ uint64_t getPaddingPoliciesMask() const { return PaddingPoliciesMask; }
+ void setPaddingPoliciesMask(uint64_t Value) { PaddingPoliciesMask = Value; }
+ bool hasPaddingPolicy(uint64_t PolicyMask) const {
+ assert(isPowerOf2_64(PolicyMask) &&
+ "Policy mask must contain exactly one policy");
+ return (getPaddingPoliciesMask() & PolicyMask) != PFK_None;
+ }
+ const MCInst &getInst() const {
+ assert(isInstructionInitialized() && "Fragment has no instruction!");
+ return InstInfo.Inst;
+ }
+ size_t getInstSize() const {
+ assert(isInstructionInitialized() && "Fragment has no instruction!");
+ if (InstInfo.IsImmutableSizedInst)
+ return InstInfo.InstSize;
+ assert(InstInfo.InstFragment != nullptr &&
+ "Must have a valid InstFragment to retrieve InstSize from");
+ return InstInfo.InstFragment->getContents().size();
+ }
+ void setInstAndInstSize(const MCInst &Inst, size_t InstSize) {
+ InstInfo.IsInitialized = true;
+ InstInfo.IsImmutableSizedInst = true;
+ InstInfo.Inst = Inst;
+ InstInfo.InstSize = InstSize;
+ }
+ void setInstAndInstFragment(const MCInst &Inst,
+ MCRelaxableFragment *InstFragment) {
+ InstInfo.IsInitialized = true;
+ InstInfo.IsImmutableSizedInst = false;
+ InstInfo.Inst = Inst;
+ InstInfo.InstFragment = InstFragment;
+ }
+ uint64_t getSize() const { return Size; }
+ void setSize(uint64_t Value) { Size = Value; }
+ bool isInstructionInitialized() const { return InstInfo.IsInitialized; }
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Padding;
+ }
+};
+
+class MCFillFragment : public MCFragment {
+ /// Value to use for filling bytes.
+ uint64_t Value;
+ uint8_t ValueSize;
+ /// The number of bytes to insert.
+ const MCExpr &NumValues;
+
+ /// Source location of the directive that this fragment was created for.
+ SMLoc Loc;
+
+public:
+ MCFillFragment(uint64_t Value, uint8_t VSize, const MCExpr &NumValues,
+ SMLoc Loc, MCSection *Sec = nullptr)
+ : MCFragment(FT_Fill, false, Sec), Value(Value), ValueSize(VSize),
+ NumValues(NumValues), Loc(Loc) {}
+
+ uint64_t getValue() const { return Value; }
+ uint8_t getValueSize() const { return ValueSize; }
+ const MCExpr &getNumValues() const { return NumValues; }
+
+ SMLoc getLoc() const { return Loc; }
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Fill;
+ }
+};
+
+class MCOrgFragment : public MCFragment {
+ /// The offset this fragment should start at.
+ const MCExpr *Offset;
+
+ /// Value to use for filling bytes.
+ int8_t Value;
+
+ /// Source location of the directive that this fragment was created for.
+ SMLoc Loc;
+
+public:
+ MCOrgFragment(const MCExpr &Offset, int8_t Value, SMLoc Loc,
+ MCSection *Sec = nullptr)
+ : MCFragment(FT_Org, false, Sec), Offset(&Offset), Value(Value), Loc(Loc) {}
+
+ /// \name Accessors
+ /// @{
+
+ const MCExpr &getOffset() const { return *Offset; }
+
+ uint8_t getValue() const { return Value; }
+
+ SMLoc getLoc() const { return Loc; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Org;
+ }
+};
+
+class MCLEBFragment : public MCFragment {
+ /// Value - The value this fragment should contain.
+ const MCExpr *Value;
+
+ /// IsSigned - True if this is a sleb128, false if uleb128.
+ bool IsSigned;
+
+ SmallString<8> Contents;
+
+public:
+ MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
+ : MCFragment(FT_LEB, false, Sec), Value(&Value_), IsSigned(IsSigned_) {
+ Contents.push_back(0);
+ }
+
+ /// \name Accessors
+ /// @{
+
+ const MCExpr &getValue() const { return *Value; }
+
+ bool isSigned() const { return IsSigned; }
+
+ SmallString<8> &getContents() { return Contents; }
+ const SmallString<8> &getContents() const { return Contents; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_LEB;
+ }
+};
+
+class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
+ /// LineDelta - the value of the difference between the two line numbers
+ /// between two .loc dwarf directives.
+ int64_t LineDelta;
+
+ /// AddrDelta - The expression for the difference of the two symbols that
+ /// make up the address delta between two .loc dwarf directives.
+ const MCExpr *AddrDelta;
+
+public:
+ MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta,
+ MCSection *Sec = nullptr)
+ : MCEncodedFragmentWithFixups<8, 1>(FT_Dwarf, false, Sec),
+ LineDelta(LineDelta), AddrDelta(&AddrDelta) {}
+
+ /// \name Accessors
+ /// @{
+
+ int64_t getLineDelta() const { return LineDelta; }
+
+ const MCExpr &getAddrDelta() const { return *AddrDelta; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Dwarf;
+ }
+};
+
+class MCDwarfCallFrameFragment : public MCFragment {
+ /// AddrDelta - The expression for the difference of the two symbols that
+ /// make up the address delta between two .cfi_* dwarf directives.
+ const MCExpr *AddrDelta;
+
+ SmallString<8> Contents;
+
+public:
+ MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
+ : MCFragment(FT_DwarfFrame, false, Sec), AddrDelta(&AddrDelta) {
+ Contents.push_back(0);
+ }
+
+ /// \name Accessors
+ /// @{
+
+ const MCExpr &getAddrDelta() const { return *AddrDelta; }
+
+ SmallString<8> &getContents() { return Contents; }
+ const SmallString<8> &getContents() const { return Contents; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_DwarfFrame;
+ }
+};
+
+/// Represents a symbol table index fragment.
+class MCSymbolIdFragment : public MCFragment {
+ const MCSymbol *Sym;
+
+public:
+ MCSymbolIdFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
+ : MCFragment(FT_SymbolId, false, Sec), Sym(Sym) {}
+
+ /// \name Accessors
+ /// @{
+
+ const MCSymbol *getSymbol() { return Sym; }
+ const MCSymbol *getSymbol() const { return Sym; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_SymbolId;
+ }
+};
+
+/// Fragment representing the binary annotations produced by the
+/// .cv_inline_linetable directive.
+class MCCVInlineLineTableFragment : public MCFragment {
+ unsigned SiteFuncId;
+ unsigned StartFileId;
+ unsigned StartLineNum;
+ const MCSymbol *FnStartSym;
+ const MCSymbol *FnEndSym;
+ SmallString<8> Contents;
+
+ /// CodeViewContext has the real knowledge about this format, so let it access
+ /// our members.
+ friend class CodeViewContext;
+
+public:
+ MCCVInlineLineTableFragment(unsigned SiteFuncId, unsigned StartFileId,
+ unsigned StartLineNum, const MCSymbol *FnStartSym,
+ const MCSymbol *FnEndSym,
+ MCSection *Sec = nullptr)
+ : MCFragment(FT_CVInlineLines, false, Sec), SiteFuncId(SiteFuncId),
+ StartFileId(StartFileId), StartLineNum(StartLineNum),
+ FnStartSym(FnStartSym), FnEndSym(FnEndSym) {}
+
+ /// \name Accessors
+ /// @{
+
+ const MCSymbol *getFnStartSym() const { return FnStartSym; }
+ const MCSymbol *getFnEndSym() const { return FnEndSym; }
+
+ SmallString<8> &getContents() { return Contents; }
+ const SmallString<8> &getContents() const { return Contents; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_CVInlineLines;
+ }
+};
+
+/// Fragment representing the .cv_def_range directive.
+class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups<32, 4> {
+ SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 2> Ranges;
+ SmallString<32> FixedSizePortion;
+
+ /// CodeViewContext has the real knowledge about this format, so let it access
+ /// our members.
+ friend class CodeViewContext;
+
+public:
+ MCCVDefRangeFragment(
+ ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
+ StringRef FixedSizePortion, MCSection *Sec = nullptr)
+ : MCEncodedFragmentWithFixups<32, 4>(FT_CVDefRange, false, Sec),
+ Ranges(Ranges.begin(), Ranges.end()),
+ FixedSizePortion(FixedSizePortion) {}
+
+ /// \name Accessors
+ /// @{
+ ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges() const {
+ return Ranges;
+ }
+
+ StringRef getFixedSizePortion() const { return FixedSizePortion; }
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_CVDefRange;
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCFRAGMENT_H
diff --git a/clang-r353983/include/llvm/MC/MCInst.h b/clang-r353983/include/llvm/MC/MCInst.h
new file mode 100644
index 00000000..9675b786
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCInst.h
@@ -0,0 +1,224 @@
+//===- llvm/MC/MCInst.h - MCInst class --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCInst and MCOperand classes, which
+// is the basic representation used to represent low-level machine code
+// instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINST_H
+#define LLVM_MC_MCINST_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SMLoc.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+
+namespace llvm {
+
+class MCExpr;
+class MCInst;
+class MCInstPrinter;
+class raw_ostream;
+
+/// Instances of this class represent operands of the MCInst class.
+/// This is a simple discriminated union.
+class MCOperand {
+ enum MachineOperandType : unsigned char {
+ kInvalid, ///< Uninitialized.
+ kRegister, ///< Register operand.
+ kImmediate, ///< Immediate operand.
+ kFPImmediate, ///< Floating-point immediate operand.
+ kExpr, ///< Relocatable immediate operand.
+ kInst ///< Sub-instruction operand.
+ };
+ MachineOperandType Kind = kInvalid;
+
+ union {
+ unsigned RegVal;
+ int64_t ImmVal;
+ double FPImmVal;
+ const MCExpr *ExprVal;
+ const MCInst *InstVal;
+ };
+
+public:
+ MCOperand() : FPImmVal(0.0) {}
+
+ bool isValid() const { return Kind != kInvalid; }
+ bool isReg() const { return Kind == kRegister; }
+ bool isImm() const { return Kind == kImmediate; }
+ bool isFPImm() const { return Kind == kFPImmediate; }
+ bool isExpr() const { return Kind == kExpr; }
+ bool isInst() const { return Kind == kInst; }
+
+ /// Returns the register number.
+ unsigned getReg() const {
+ assert(isReg() && "This is not a register operand!");
+ return RegVal;
+ }
+
+ /// Set the register number.
+ void setReg(unsigned Reg) {
+ assert(isReg() && "This is not a register operand!");
+ RegVal = Reg;
+ }
+
+ int64_t getImm() const {
+ assert(isImm() && "This is not an immediate");
+ return ImmVal;
+ }
+
+ void setImm(int64_t Val) {
+ assert(isImm() && "This is not an immediate");
+ ImmVal = Val;
+ }
+
+ double getFPImm() const {
+ assert(isFPImm() && "This is not an FP immediate");
+ return FPImmVal;
+ }
+
+ void setFPImm(double Val) {
+ assert(isFPImm() && "This is not an FP immediate");
+ FPImmVal = Val;
+ }
+
+ const MCExpr *getExpr() const {
+ assert(isExpr() && "This is not an expression");
+ return ExprVal;
+ }
+
+ void setExpr(const MCExpr *Val) {
+ assert(isExpr() && "This is not an expression");
+ ExprVal = Val;
+ }
+
+ const MCInst *getInst() const {
+ assert(isInst() && "This is not a sub-instruction");
+ return InstVal;
+ }
+
+ void setInst(const MCInst *Val) {
+ assert(isInst() && "This is not a sub-instruction");
+ InstVal = Val;
+ }
+
+ static MCOperand createReg(unsigned Reg) {
+ MCOperand Op;
+ Op.Kind = kRegister;
+ Op.RegVal = Reg;
+ return Op;
+ }
+
+ static MCOperand createImm(int64_t Val) {
+ MCOperand Op;
+ Op.Kind = kImmediate;
+ Op.ImmVal = Val;
+ return Op;
+ }
+
+ static MCOperand createFPImm(double Val) {
+ MCOperand Op;
+ Op.Kind = kFPImmediate;
+ Op.FPImmVal = Val;
+ return Op;
+ }
+
+ static MCOperand createExpr(const MCExpr *Val) {
+ MCOperand Op;
+ Op.Kind = kExpr;
+ Op.ExprVal = Val;
+ return Op;
+ }
+
+ static MCOperand createInst(const MCInst *Val) {
+ MCOperand Op;
+ Op.Kind = kInst;
+ Op.InstVal = Val;
+ return Op;
+ }
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
+ bool isBareSymbolRef() const;
+ bool evaluateAsConstantImm(int64_t &Imm) const;
+};
+
+/// Instances of this class represent a single low-level machine
+/// instruction.
+class MCInst {
+ unsigned Opcode = 0;
+ SMLoc Loc;
+ SmallVector<MCOperand, 8> Operands;
+ // These flags could be used to pass some info from one target subcomponent
+ // to another, for example, from disassembler to asm printer. The values of
+ // the flags have any sense on target level only (e.g. prefixes on x86).
+ unsigned Flags = 0;
+
+public:
+ MCInst() = default;
+
+ void setOpcode(unsigned Op) { Opcode = Op; }
+ unsigned getOpcode() const { return Opcode; }
+
+ void setFlags(unsigned F) { Flags = F; }
+ unsigned getFlags() const { return Flags; }
+
+ void setLoc(SMLoc loc) { Loc = loc; }
+ SMLoc getLoc() const { return Loc; }
+
+ const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
+ MCOperand &getOperand(unsigned i) { return Operands[i]; }
+ unsigned getNumOperands() const { return Operands.size(); }
+
+ void addOperand(const MCOperand &Op) { Operands.push_back(Op); }
+
+ using iterator = SmallVectorImpl<MCOperand>::iterator;
+ using const_iterator = SmallVectorImpl<MCOperand>::const_iterator;
+
+ void clear() { Operands.clear(); }
+ void erase(iterator I) { Operands.erase(I); }
+ size_t size() const { return Operands.size(); }
+ iterator begin() { return Operands.begin(); }
+ const_iterator begin() const { return Operands.begin(); }
+ iterator end() { return Operands.end(); }
+ const_iterator end() const { return Operands.end(); }
+
+ iterator insert(iterator I, const MCOperand &Op) {
+ return Operands.insert(I, Op);
+ }
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
+
+ /// 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 MCInstPrinter *Printer = nullptr,
+ StringRef Separator = " ") const;
+ void dump_pretty(raw_ostream &OS, StringRef Name,
+ StringRef Separator = " ") const;
+};
+
+inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
+ MO.print(OS);
+ return OS;
+}
+
+inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
+ MI.print(OS);
+ return OS;
+}
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCINST_H
diff --git a/clang-r353983/include/llvm/MC/MCInstBuilder.h b/clang-r353983/include/llvm/MC/MCInstBuilder.h
new file mode 100644
index 00000000..0c8e01fd
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCInstBuilder.h
@@ -0,0 +1,73 @@
+//===-- llvm/MC/MCInstBuilder.h - Simplify creation of MCInsts --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the MCInstBuilder class for convenient creation of
+// MCInsts.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTBUILDER_H
+#define LLVM_MC_MCINSTBUILDER_H
+
+#include "llvm/MC/MCInst.h"
+
+namespace llvm {
+
+class MCInstBuilder {
+ MCInst Inst;
+
+public:
+ /// Create a new MCInstBuilder for an MCInst with a specific opcode.
+ MCInstBuilder(unsigned Opcode) {
+ Inst.setOpcode(Opcode);
+ }
+
+ /// Add a new register operand.
+ MCInstBuilder &addReg(unsigned Reg) {
+ Inst.addOperand(MCOperand::createReg(Reg));
+ return *this;
+ }
+
+ /// Add a new integer immediate operand.
+ MCInstBuilder &addImm(int64_t Val) {
+ Inst.addOperand(MCOperand::createImm(Val));
+ return *this;
+ }
+
+ /// Add a new floating point immediate operand.
+ MCInstBuilder &addFPImm(double Val) {
+ Inst.addOperand(MCOperand::createFPImm(Val));
+ return *this;
+ }
+
+ /// Add a new MCExpr operand.
+ MCInstBuilder &addExpr(const MCExpr *Val) {
+ Inst.addOperand(MCOperand::createExpr(Val));
+ return *this;
+ }
+
+ /// Add a new MCInst operand.
+ MCInstBuilder &addInst(const MCInst *Val) {
+ Inst.addOperand(MCOperand::createInst(Val));
+ return *this;
+ }
+
+ /// Add an operand.
+ MCInstBuilder &addOperand(const MCOperand &Op) {
+ Inst.addOperand(Op);
+ return *this;
+ }
+
+ operator MCInst&() {
+ return Inst;
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCInstPrinter.h b/clang-r353983/include/llvm/MC/MCInstPrinter.h
new file mode 100644
index 00000000..916aa892
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCInstPrinter.h
@@ -0,0 +1,107 @@
+//===- MCInstPrinter.h - MCInst to target assembly syntax -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTPRINTER_H
+#define LLVM_MC_MCINSTPRINTER_H
+
+#include "llvm/Support/Format.h"
+#include <cstdint>
+
+namespace llvm {
+
+class MCAsmInfo;
+class MCInst;
+class MCInstrInfo;
+class MCRegisterInfo;
+class MCSubtargetInfo;
+class raw_ostream;
+class StringRef;
+
+/// Convert `Bytes' to a hex string and output to `OS'
+void dumpBytes(ArrayRef<uint8_t> Bytes, raw_ostream &OS);
+
+namespace HexStyle {
+
+enum Style {
+ C, ///< 0xff
+ Asm ///< 0ffh
+};
+
+} // end namespace HexStyle
+
+/// This is an instance of a target assembly language printer that
+/// converts an MCInst to valid target assembly syntax.
+class MCInstPrinter {
+protected:
+ /// 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 disabled.
+ raw_ostream *CommentStream = nullptr;
+ const MCAsmInfo &MAI;
+ const MCInstrInfo &MII;
+ const MCRegisterInfo &MRI;
+
+ /// True if we are printing marked up assembly.
+ bool UseMarkup = false;
+
+ /// True if we are printing immediates as hex.
+ bool PrintImmHex = false;
+
+ /// Which style to use for printing hexadecimal values.
+ HexStyle::Style PrintHexStyle = HexStyle::C;
+
+ /// Utility function for printing annotations.
+ void printAnnotation(raw_ostream &OS, StringRef Annot);
+
+public:
+ MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii,
+ const MCRegisterInfo &mri) : MAI(mai), MII(mii), MRI(mri) {}
+
+ virtual ~MCInstPrinter();
+
+ /// Specify a stream to emit comments to.
+ void setCommentStream(raw_ostream &OS) { CommentStream = &OS; }
+
+ /// Print the specified MCInst to the specified raw_ostream.
+ virtual void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot,
+ const MCSubtargetInfo &STI) = 0;
+
+ /// Return the name of the specified opcode enum (e.g. "MOV32ri") or
+ /// empty if we can't resolve it.
+ StringRef getOpcodeName(unsigned Opcode) const;
+
+ /// Print the assembler register name.
+ virtual void printRegName(raw_ostream &OS, unsigned RegNo) const;
+
+ bool getUseMarkup() const { return UseMarkup; }
+ void setUseMarkup(bool Value) { UseMarkup = Value; }
+
+ /// Utility functions to make adding mark ups simpler.
+ StringRef markup(StringRef s) const;
+ StringRef markup(StringRef a, StringRef b) const;
+
+ bool getPrintImmHex() const { return PrintImmHex; }
+ void setPrintImmHex(bool Value) { PrintImmHex = Value; }
+
+ HexStyle::Style getPrintHexStyle() const { return PrintHexStyle; }
+ void setPrintHexStyle(HexStyle::Style Value) { PrintHexStyle = Value; }
+
+ /// Utility function to print immediates in decimal or hex.
+ format_object<int64_t> formatImm(int64_t Value) const {
+ return PrintImmHex ? formatHex(Value) : formatDec(Value);
+ }
+
+ /// Utility functions to print decimal/hexadecimal values.
+ 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;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCINSTPRINTER_H
diff --git a/clang-r353983/include/llvm/MC/MCInstrAnalysis.h b/clang-r353983/include/llvm/MC/MCInstrAnalysis.h
new file mode 100644
index 00000000..dfefd7e7
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCInstrAnalysis.h
@@ -0,0 +1,165 @@
+//===- llvm/MC/MCInstrAnalysis.h - InstrDesc target hooks -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MCInstrAnalysis class which the MCTargetDescs can
+// derive from to give additional information to MC.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRANALYSIS_H
+#define LLVM_MC_MCINSTRANALYSIS_H
+
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include <cstdint>
+
+namespace llvm {
+
+class MCRegisterInfo;
+class Triple;
+
+class MCInstrAnalysis {
+protected:
+ friend class Target;
+
+ const MCInstrInfo *Info;
+
+public:
+ MCInstrAnalysis(const MCInstrInfo *Info) : Info(Info) {}
+ virtual ~MCInstrAnalysis() = default;
+
+ virtual bool isBranch(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isBranch();
+ }
+
+ virtual bool isConditionalBranch(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isConditionalBranch();
+ }
+
+ virtual bool isUnconditionalBranch(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isUnconditionalBranch();
+ }
+
+ virtual bool isIndirectBranch(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isIndirectBranch();
+ }
+
+ virtual bool isCall(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isCall();
+ }
+
+ virtual bool isReturn(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isReturn();
+ }
+
+ virtual bool isTerminator(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isTerminator();
+ }
+
+ /// Returns true if at least one of the register writes performed by
+ /// \param Inst implicitly clears the upper portion of all super-registers.
+ ///
+ /// Example: on X86-64, a write to EAX implicitly clears the upper half of
+ /// RAX. Also (still on x86) an XMM write perfomed by an AVX 128-bit
+ /// instruction implicitly clears the upper portion of the correspondent
+ /// YMM register.
+ ///
+ /// This method also updates an APInt which is used as mask of register
+ /// writes. There is one bit for every explicit/implicit write performed by
+ /// the instruction. If a write implicitly clears its super-registers, then
+ /// the corresponding bit is set (vic. the corresponding bit is cleared).
+ ///
+ /// The first bits in the APint are related to explicit writes. The remaining
+ /// bits are related to implicit writes. The sequence of writes follows the
+ /// machine operand sequence. For implicit writes, the sequence is defined by
+ /// the MCInstrDesc.
+ ///
+ /// The assumption is that the bit-width of the APInt is correctly set by
+ /// the caller. The default implementation conservatively assumes that none of
+ /// the writes clears the upper portion of a super-register.
+ virtual bool clearsSuperRegisters(const MCRegisterInfo &MRI,
+ const MCInst &Inst,
+ APInt &Writes) const;
+
+ /// Returns true if MI is a dependency breaking zero-idiom for the given
+ /// subtarget.
+ ///
+ /// Mask is used to identify input operands that have their dependency
+ /// broken. Each bit of the mask is associated with a specific input operand.
+ /// Bits associated with explicit input operands are laid out first in the
+ /// mask; implicit operands come after explicit operands.
+ ///
+ /// Dependencies are broken only for operands that have their corresponding bit
+ /// set. Operands that have their bit cleared, or that don't have a
+ /// corresponding bit in the mask don't have their dependency broken. Note
+ /// that Mask may not be big enough to describe all operands. The assumption
+ /// for operands that don't have a correspondent bit in the mask is that those
+ /// are still data dependent.
+ ///
+ /// The only exception to the rule is for when Mask has all zeroes.
+ /// A zero mask means: dependencies are broken for all explicit register
+ /// operands.
+ virtual bool isZeroIdiom(const MCInst &MI, APInt &Mask,
+ unsigned CPUID) const {
+ return false;
+ }
+
+ /// Returns true if MI is a dependency breaking instruction for the
+ /// subtarget associated with CPUID .
+ ///
+ /// The value computed by a dependency breaking instruction is not dependent
+ /// on the inputs. An example of dependency breaking instruction on X86 is
+ /// `XOR %eax, %eax`.
+ ///
+ /// If MI is a dependency breaking instruction for subtarget CPUID, then Mask
+ /// can be inspected to identify independent operands.
+ ///
+ /// Essentially, each bit of the mask corresponds to an input operand.
+ /// Explicit operands are laid out first in the mask; implicit operands follow
+ /// explicit operands. Bits are set for operands that are independent.
+ ///
+ /// Note that the number of bits in Mask may not be equivalent to the sum of
+ /// explicit and implicit operands in MI. Operands that don't have a
+ /// corresponding bit in Mask are assumed "not independente".
+ ///
+ /// The only exception is for when Mask is all zeroes. That means: explicit
+ /// input operands of MI are independent.
+ virtual bool isDependencyBreaking(const MCInst &MI, APInt &Mask,
+ unsigned CPUID) const {
+ return isZeroIdiom(MI, Mask, CPUID);
+ }
+
+ /// Returns true if MI is a candidate for move elimination.
+ ///
+ /// Different subtargets may apply different constraints to optimizable
+ /// register moves. For example, on most X86 subtargets, a candidate for move
+ /// elimination cannot specify the same register for both source and
+ /// destination.
+ virtual bool isOptimizableRegisterMove(const MCInst &MI,
+ unsigned CPUID) const {
+ return false;
+ }
+
+ /// 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;
+
+ /// Returns (PLT virtual address, GOT virtual address) pairs for PLT entries.
+ virtual std::vector<std::pair<uint64_t, uint64_t>>
+ findPltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents,
+ uint64_t GotPltSectionVA, const Triple &TargetTriple) const {
+ return {};
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCINSTRANALYSIS_H
diff --git a/clang-r353983/include/llvm/MC/MCInstrDesc.h b/clang-r353983/include/llvm/MC/MCInstrDesc.h
new file mode 100644
index 00000000..ad5a3e9c
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCInstrDesc.h
@@ -0,0 +1,602 @@
+//===-- llvm/MC/MCInstrDesc.h - Instruction Descriptors -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MCOperandInfo and MCInstrDesc classes, which
+// are used to describe target instructions and their operands.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRDESC_H
+#define LLVM_MC_MCINSTRDESC_H
+
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+ class MCInst;
+ 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
+};
+
+/// 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 };
+
+/// 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_GENERIC = 6,
+ OPERAND_GENERIC_0 = 6,
+ OPERAND_GENERIC_1 = 7,
+ OPERAND_GENERIC_2 = 8,
+ OPERAND_GENERIC_3 = 9,
+ OPERAND_GENERIC_4 = 10,
+ OPERAND_GENERIC_5 = 11,
+ OPERAND_LAST_GENERIC = 11,
+
+ OPERAND_FIRST_TARGET = 12,
+};
+
+}
+
+/// This holds information about one operand of a machine instruction,
+/// indicating the register class for register operands, etc.
+class MCOperandInfo {
+public:
+ /// 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;
+
+ /// These are flags from the MCOI::OperandFlags enum.
+ uint8_t Flags;
+
+ /// Information about the type of the operand.
+ uint8_t OperandType;
+ /// 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;
+
+ /// 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);
+ }
+
+ /// 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); }
+
+ /// Set if this operand is a optional def.
+ bool isOptionalDef() const { return Flags & (1 << MCOI::OptionalDef); }
+
+ bool isGenericType() const {
+ return OperandType >= MCOI::OPERAND_FIRST_GENERIC &&
+ OperandType <= MCOI::OPERAND_LAST_GENERIC;
+ }
+
+ unsigned getGenericTypeIndex() const {
+ assert(isGenericType() && "non-generic types don't have an index");
+ return OperandType - MCOI::OPERAND_FIRST_GENERIC;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Machine Instruction Flags and Description
+//===----------------------------------------------------------------------===//
+
+namespace MCID {
+/// 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,
+ EHScopeReturn,
+ Call,
+ Barrier,
+ Terminator,
+ Branch,
+ IndirectBranch,
+ Compare,
+ MoveImm,
+ MoveReg,
+ Bitcast,
+ Select,
+ DelaySlot,
+ FoldableAsLoad,
+ MayLoad,
+ MayStore,
+ Predicable,
+ NotDuplicable,
+ UnmodeledSideEffects,
+ Commutable,
+ ConvertibleTo3Addr,
+ UsesCustomInserter,
+ HasPostISelHook,
+ Rematerializable,
+ CheapAsAMove,
+ ExtraSrcRegAllocReq,
+ ExtraDefRegAllocReq,
+ RegSequence,
+ ExtractSubreg,
+ InsertSubreg,
+ Convergent,
+ Add,
+ Trap,
+ VariadicOpsAreDefs,
+};
+}
+
+/// 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 char NumDefs; // Num of args that are definitions
+ unsigned char Size; // Number of bytes in encoding.
+ unsigned short SchedClass; // enum identifying instr sched class
+ uint64_t Flags; // Flags identifying machine instr class
+ uint64_t TSFlags; // Target Specific Flag values
+ const MCPhysReg *ImplicitUses; // Registers implicitly read by this instr
+ const MCPhysReg *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 if a certain instruction is deprecated or
+ // not, and return the reason for deprecation.
+ bool (*ComplexDeprecationInfo)(MCInst &, const MCSubtargetInfo &,
+ std::string &);
+
+ /// Returns the value of the specific constraint if
+ /// it is set. Returns -1 if it is not set.
+ int getOperandConstraint(unsigned OpNum,
+ MCOI::OperandConstraint Constraint) const {
+ if (OpNum < NumOperands &&
+ (OpInfo[OpNum].Constraints & (1 << Constraint))) {
+ unsigned Pos = 16 + Constraint * 4;
+ return (int)(OpInfo[OpNum].Constraints >> Pos) & 0xf;
+ }
+ return -1;
+ }
+
+ /// Returns true if a certain instruction is deprecated and if so
+ /// returns the reason in \p Info.
+ bool getDeprecatedInfo(MCInst &MI, const MCSubtargetInfo &STI,
+ std::string &Info) const;
+
+ /// Return the opcode number for this descriptor.
+ unsigned getOpcode() const { return Opcode; }
+
+ /// 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; }
+
+ using const_opInfo_iterator = const MCOperandInfo *;
+
+ const_opInfo_iterator opInfo_begin() const { return OpInfo; }
+ const_opInfo_iterator opInfo_end() const { return OpInfo + NumOperands; }
+
+ iterator_range<const_opInfo_iterator> operands() const {
+ return make_range(opInfo_begin(), opInfo_end());
+ }
+
+ /// 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; }
+
+ /// Return flags of this instruction.
+ uint64_t getFlags() const { return Flags; }
+
+ /// Return true if this instruction can have a variable number of
+ /// operands. In this case, the variable operands will be after the normal
+ /// operands but before the implicit definitions and uses (if any are
+ /// present).
+ bool isVariadic() const { return Flags & (1ULL << MCID::Variadic); }
+
+ /// 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 & (1ULL << MCID::HasOptionalDef); }
+
+ /// Return true if this is a pseudo instruction that doesn't
+ /// correspond to a real machine instruction.
+ bool isPseudo() const { return Flags & (1ULL << MCID::Pseudo); }
+
+ /// Return true if the instruction is a return.
+ bool isReturn() const { return Flags & (1ULL << MCID::Return); }
+
+ /// Return true if the instruction is an add instruction.
+ bool isAdd() const { return Flags & (1ULL << MCID::Add); }
+
+ /// Return true if this instruction is a trap.
+ bool isTrap() const { return Flags & (1ULL << MCID::Trap); }
+
+ /// Return true if the instruction is a register to register move.
+ bool isMoveReg() const { return Flags & (1ULL << MCID::MoveReg); }
+
+ /// Return true if the instruction is a call.
+ bool isCall() const { return Flags & (1ULL << MCID::Call); }
+
+ /// 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 & (1ULL << MCID::Barrier); }
+
+ /// Returns true if this instruction part of the terminator for
+ /// a basic block. Typically this is things like return and branch
+ /// instructions.
+ ///
+ /// Various passes use this to insert code into the bottom of a basic block,
+ /// but before control flow occurs.
+ bool isTerminator() const { return Flags & (1ULL << MCID::Terminator); }
+
+ /// 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 & (1ULL << MCID::Branch); }
+
+ /// Return true if this is an indirect branch, such as a
+ /// branch through a register.
+ bool isIndirectBranch() const { return Flags & (1ULL << MCID::IndirectBranch); }
+
+ /// Return true if this is a branch which may fall
+ /// through to the next instruction or may transfer control flow to some other
+ /// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more
+ /// information about this branch.
+ bool isConditionalBranch() const {
+ return isBranch() & !isBarrier() & !isIndirectBranch();
+ }
+
+ /// Return true if this is a branch which always
+ /// transfers control flow to some other block. The
+ /// TargetInstrInfo::AnalyzeBranch method can be used to get more information
+ /// about this branch.
+ bool isUnconditionalBranch() const {
+ return isBranch() & isBarrier() & !isIndirectBranch();
+ }
+
+ /// 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;
+
+ /// 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 & (1ULL << MCID::Predicable); }
+
+ /// Return true if this instruction is a comparison.
+ bool isCompare() const { return Flags & (1ULL << MCID::Compare); }
+
+ /// Return true if this instruction is a move immediate
+ /// (including conditional moves) instruction.
+ bool isMoveImmediate() const { return Flags & (1ULL << MCID::MoveImm); }
+
+ /// Return true if this instruction is a bitcast instruction.
+ bool isBitcast() const { return Flags & (1ULL << MCID::Bitcast); }
+
+ /// Return true if this is a select instruction.
+ bool isSelect() const { return Flags & (1ULL << MCID::Select); }
+
+ /// 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 & (1ULL << MCID::NotDuplicable); }
+
+ /// Returns true if the specified instruction has a delay slot which
+ /// must be filled by the code generator.
+ bool hasDelaySlot() const { return Flags & (1ULL << MCID::DelaySlot); }
+
+ /// 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 & (1ULL << MCID::FoldableAsLoad); }
+
+ /// Return true if this instruction behaves
+ /// the same way as the generic REG_SEQUENCE instructions.
+ /// E.g., on ARM,
+ /// dX VMOVDRR rY, rZ
+ /// is equivalent to
+ /// dX = REG_SEQUENCE rY, ssub_0, rZ, ssub_1.
+ ///
+ /// Note that for the optimizers to be able to take advantage of
+ /// this property, TargetInstrInfo::getRegSequenceLikeInputs has to be
+ /// override accordingly.
+ bool isRegSequenceLike() const { return Flags & (1ULL << MCID::RegSequence); }
+
+ /// Return true if this instruction behaves
+ /// the same way as the generic EXTRACT_SUBREG instructions.
+ /// E.g., on ARM,
+ /// rX, rY VMOVRRD dZ
+ /// is equivalent to two EXTRACT_SUBREG:
+ /// rX = EXTRACT_SUBREG dZ, ssub_0
+ /// rY = EXTRACT_SUBREG dZ, ssub_1
+ ///
+ /// Note that for the optimizers to be able to take advantage of
+ /// this property, TargetInstrInfo::getExtractSubregLikeInputs has to be
+ /// override accordingly.
+ bool isExtractSubregLike() const {
+ return Flags & (1ULL << MCID::ExtractSubreg);
+ }
+
+ /// Return true if this instruction behaves
+ /// the same way as the generic INSERT_SUBREG instructions.
+ /// E.g., on ARM,
+ /// dX = VSETLNi32 dY, rZ, Imm
+ /// is equivalent to a INSERT_SUBREG:
+ /// dX = INSERT_SUBREG dY, rZ, translateImmToSubIdx(Imm)
+ ///
+ /// 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 & (1ULL << MCID::InsertSubreg); }
+
+
+ /// Return true if this instruction is convergent.
+ ///
+ /// Convergent instructions may not be made control-dependent on any
+ /// additional values.
+ bool isConvergent() const { return Flags & (1ULL << MCID::Convergent); }
+
+ /// Return true if variadic operands of this instruction are definitions.
+ bool variadicOpsAreDefs() const {
+ return Flags & (1ULL << MCID::VariadicOpsAreDefs);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Side Effect Analysis
+ //===--------------------------------------------------------------------===//
+
+ /// 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 & (1ULL << MCID::MayLoad); }
+
+ /// 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 & (1ULL << MCID::MayStore); }
+
+ /// Return true if this instruction has side
+ /// effects that are not modeled by other flags. This does not return true
+ /// for instructions whose effects are captured by:
+ ///
+ /// 1. Their operand list and implicit definition/use list. Register use/def
+ /// info is explicit for instructions.
+ /// 2. Memory accesses. Use mayLoad/mayStore.
+ /// 3. Calling, branching, returning: use isCall/isReturn/isBranch.
+ ///
+ /// Examples of side effects would be modifying 'invisible' machine state like
+ /// a control register, flushing a cache, modifying a register invisible to
+ /// LLVM, etc.
+ bool hasUnmodeledSideEffects() const {
+ return Flags & (1ULL << MCID::UnmodeledSideEffects);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Flags that indicate whether an instruction can be modified by a method.
+ //===--------------------------------------------------------------------===//
+
+ /// Return true if this may be a 2- or 3-address instruction (of the
+ /// form "X = op Y, Z, ..."), which produces the same result if Y and Z are
+ /// exchanged. If this flag is set, then the
+ /// TargetInstrInfo::commuteInstruction method may be used to hack on the
+ /// instruction.
+ ///
+ /// Note that this flag may be set on instructions that are only commutable
+ /// sometimes. In these cases, the call to commuteInstruction will fail.
+ /// Also note that some instructions require non-trivial modification to
+ /// commute them.
+ bool isCommutable() const { return Flags & (1ULL << MCID::Commutable); }
+
+ /// Return true if this is a 2-address instruction which can be changed
+ /// into a 3-address instruction if needed. Doing this transformation can be
+ /// profitable in the register allocator, because it means that the
+ /// instruction can use a 2-address form if possible, but degrade into a less
+ /// efficient form if the source and dest register cannot be assigned to the
+ /// same register. For example, this allows the x86 backend to turn a "shl
+ /// reg, 3" instruction into an LEA instruction, which is the same speed as
+ /// the shift but has bigger code size.
+ ///
+ /// If this returns true, then the target must implement the
+ /// TargetInstrInfo::convertToThreeAddress method for this instruction, which
+ /// is allowed to fail if the transformation isn't valid for this specific
+ /// instruction (e.g. shl reg, 4 on x86).
+ ///
+ bool isConvertibleTo3Addr() const {
+ return Flags & (1ULL << MCID::ConvertibleTo3Addr);
+ }
+
+ /// Return true if this instruction requires custom insertion support
+ /// when the DAG scheduler is inserting it into a machine basic block. If
+ /// this is true for the instruction, it basically means that it is a pseudo
+ /// instruction used at SelectionDAG time that is expanded out into magic code
+ /// by the target when MachineInstrs are formed.
+ ///
+ /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method
+ /// is used to insert this into the MachineBasicBlock.
+ bool usesCustomInsertionHook() const {
+ return Flags & (1ULL << MCID::UsesCustomInserter);
+ }
+
+ /// 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 & (1ULL << MCID::HasPostISelHook); }
+
+ /// 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
+ /// the instruction is really rematable.
+ bool isRematerializable() const {
+ return Flags & (1ULL << MCID::Rematerializable);
+ }
+
+ /// 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 & (1ULL << MCID::CheapAsAMove); }
+
+ /// 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 & (1ULL << MCID::ExtraSrcRegAllocReq);
+ }
+
+ /// 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 & (1ULL << MCID::ExtraDefRegAllocReq);
+ }
+
+ /// 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 MCPhysReg *getImplicitUses() const { return ImplicitUses; }
+
+ /// Return the number of implicit uses this instruction has.
+ unsigned getNumImplicitUses() const {
+ if (!ImplicitUses)
+ return 0;
+ unsigned i = 0;
+ for (; ImplicitUses[i]; ++i) /*empty*/
+ ;
+ return i;
+ }
+
+ /// 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 MCPhysReg *getImplicitDefs() const { return ImplicitDefs; }
+
+ /// Return the number of implicit defs this instruct has.
+ unsigned getNumImplicitDefs() const {
+ if (!ImplicitDefs)
+ return 0;
+ unsigned i = 0;
+ for (; ImplicitDefs[i]; ++i) /*empty*/
+ ;
+ return i;
+ }
+
+ /// Return true if this instruction implicitly
+ /// uses the specified physical register.
+ bool hasImplicitUseOfPhysReg(unsigned Reg) const {
+ if (const MCPhysReg *ImpUses = ImplicitUses)
+ for (; *ImpUses; ++ImpUses)
+ if (*ImpUses == Reg)
+ return true;
+ return false;
+ }
+
+ /// Return true if this instruction implicitly
+ /// defines the specified physical register.
+ bool hasImplicitDefOfPhysReg(unsigned Reg,
+ const MCRegisterInfo *MRI = nullptr) const;
+
+ /// 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; }
+
+ /// 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; }
+
+ /// Find the index of the first operand in the
+ /// operand list that is used to represent the predicate. It returns -1 if
+ /// none is found.
+ int findFirstPredOperandIdx() const {
+ if (isPredicable()) {
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ if (OpInfo[i].isPredicate())
+ return i;
+ }
+ return -1;
+ }
+
+ /// 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
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCInstrInfo.h b/clang-r353983/include/llvm/MC/MCInstrInfo.h
new file mode 100644
index 00000000..874b1e46
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCInstrInfo.h
@@ -0,0 +1,58 @@
+//===-- llvm/MC/MCInstrInfo.h - Target Instruction Info ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the target machine instruction set.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRINFO_H
+#define LLVM_MC_MCINSTRINFO_H
+
+#include "llvm/MC/MCInstrDesc.h"
+#include <cassert>
+
+namespace llvm {
+
+//---------------------------------------------------------------------------
+/// Interface to description of machine instruction set.
+class MCInstrInfo {
+ const MCInstrDesc *Desc; // Raw array to allow static init'n
+ const unsigned *InstrNameIndices; // Array for name indices in InstrNameData
+ const char *InstrNameData; // Instruction name string pool
+ unsigned NumOpcodes; // Number of entries in the desc array
+
+public:
+ /// Initialize MCInstrInfo, called by TableGen auto-generated routines.
+ /// *DO NOT USE*.
+ void InitMCInstrInfo(const MCInstrDesc *D, const unsigned *NI, const char *ND,
+ unsigned NO) {
+ Desc = D;
+ InstrNameIndices = NI;
+ InstrNameData = ND;
+ NumOpcodes = NO;
+ }
+
+ unsigned getNumOpcodes() const { return NumOpcodes; }
+
+ /// 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];
+ }
+
+ /// Returns the name for the instructions with the given opcode.
+ StringRef getName(unsigned Opcode) const {
+ assert(Opcode < NumOpcodes && "Invalid opcode!");
+ return StringRef(&InstrNameData[InstrNameIndices[Opcode]]);
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCInstrItineraries.h b/clang-r353983/include/llvm/MC/MCInstrItineraries.h
new file mode 100644
index 00000000..485aa663
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCInstrItineraries.h
@@ -0,0 +1,234 @@
+//===- llvm/MC/MCInstrItineraries.h - Scheduling ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the structures used for instruction
+// itineraries, stages, and operand reads/writes. This is used by
+// schedulers to determine instruction stages and latencies.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRITINERARIES_H
+#define LLVM_MC_MCINSTRITINERARIES_H
+
+#include "llvm/MC/MCSchedule.h"
+#include <algorithm>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// These values represent a non-pipelined step in
+/// the execution of an instruction. Cycles represents the number of
+/// discrete time slots needed to complete the stage. Units represent
+/// the choice of functional units that can be used to complete the
+/// stage. Eg. IntUnit1, IntUnit2. NextCycles indicates how many
+/// cycles should elapse from the start of this stage to the start of
+/// the next stage in the itinerary. A value of -1 indicates that the
+/// next stage should start immediately after the current one.
+/// For example:
+///
+/// { 1, x, -1 }
+/// indicates that the stage occupies FU x for 1 cycle and that
+/// the next stage starts immediately after this one.
+///
+/// { 2, x|y, 1 }
+/// indicates that the stage occupies either FU x or FU y for 2
+/// consecutive cycles and that the next stage starts one cycle
+/// after this stage starts. That is, the stage requirements
+/// overlap in time.
+///
+/// { 1, x, 0 }
+/// indicates that the stage occupies FU x for 1 cycle and that
+/// the next stage starts in this same cycle. This can be used to
+/// indicate that the instruction requires multiple stages at the
+/// same time.
+///
+/// FU reservation can be of two different kinds:
+/// - FUs which instruction actually requires
+/// - FUs which instruction just reserves. Reserved unit is not available for
+/// execution of other instruction. However, several instructions can reserve
+/// the same unit several times.
+/// Such two types of units reservation is used to model instruction domain
+/// change stalls, FUs using the same resource (e.g. same register file), etc.
+
+struct InstrStage {
+ enum ReservationKinds {
+ Required = 0,
+ Reserved = 1
+ };
+
+ unsigned Cycles_; ///< Length of stage in machine cycles
+ unsigned Units_; ///< Choice of functional units
+ int NextCycles_; ///< Number of machine cycles to next stage
+ ReservationKinds Kind_; ///< Kind of the FU reservation
+
+ /// Returns the number of cycles the stage is occupied.
+ unsigned getCycles() const {
+ return Cycles_;
+ }
+
+ /// Returns the choice of FUs.
+ unsigned getUnits() const {
+ return Units_;
+ }
+
+ ReservationKinds getReservationKind() const {
+ return Kind_;
+ }
+
+ /// 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_;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// An itinerary represents the scheduling information for an instruction.
+/// This includes a set of stages occupied by the instruction and the pipeline
+/// cycle in which operands are read and written.
+///
+struct InstrItinerary {
+ int16_t NumMicroOps; ///< # of micro-ops, -1 means it's variable
+ uint16_t FirstStage; ///< Index of first stage in itinerary
+ uint16_t LastStage; ///< Index of last + 1 stage in itinerary
+ uint16_t FirstOperandCycle; ///< Index of first operand rd/wr
+ uint16_t LastOperandCycle; ///< Index of last + 1 operand rd/wr
+};
+
+//===----------------------------------------------------------------------===//
+/// Itinerary data supplied by a subtarget to be used by a target.
+///
+class InstrItineraryData {
+public:
+ MCSchedModel SchedModel =
+ MCSchedModel::GetDefaultSchedModel(); ///< Basic machine properties.
+ const InstrStage *Stages = nullptr; ///< Array of stages selected
+ const unsigned *OperandCycles = nullptr; ///< Array of operand cycles selected
+ const unsigned *Forwardings = nullptr; ///< Array of pipeline forwarding paths
+ const InstrItinerary *Itineraries =
+ nullptr; ///< Array of itineraries selected
+
+ InstrItineraryData() = default;
+ InstrItineraryData(const MCSchedModel &SM, const InstrStage *S,
+ const unsigned *OS, const unsigned *F)
+ : SchedModel(SM), Stages(S), OperandCycles(OS), Forwardings(F),
+ Itineraries(SchedModel.InstrItineraries) {}
+
+ /// Returns true if there are no itineraries.
+ bool isEmpty() const { return Itineraries == nullptr; }
+
+ /// Returns true if the index is for the end marker itinerary.
+ bool isEndMarker(unsigned ItinClassIndx) const {
+ return ((Itineraries[ItinClassIndx].FirstStage == UINT16_MAX) &&
+ (Itineraries[ItinClassIndx].LastStage == UINT16_MAX));
+ }
+
+ /// 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.
+ 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.
+ unsigned getStageLatency(unsigned ItinClassIndx) const {
+ // If the target doesn't provide itinerary information, use a simple
+ // non-zero default value for all instructions.
+ if (isEmpty())
+ return 1;
+
+ // Calculate the maximum completion time for any stage.
+ unsigned Latency = 0, StartCycle = 0;
+ for (const InstrStage *IS = beginStage(ItinClassIndx),
+ *E = endStage(ItinClassIndx); IS != E; ++IS) {
+ Latency = std::max(Latency, StartCycle + IS->getCycles());
+ StartCycle += IS->getNextCycles();
+ }
+ return Latency;
+ }
+
+ /// Return the cycle for the given class and operand. Return -1 if no
+ /// cycle is specified for the operand.
+ int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const {
+ if (isEmpty())
+ return -1;
+
+ unsigned FirstIdx = Itineraries[ItinClassIndx].FirstOperandCycle;
+ unsigned LastIdx = Itineraries[ItinClassIndx].LastOperandCycle;
+ if ((FirstIdx + OperandIdx) >= LastIdx)
+ return -1;
+
+ return (int)OperandCycles[FirstIdx + OperandIdx];
+ }
+
+ /// Return true if there is a pipeline forwarding between instructions
+ /// of itinerary classes DefClass and UseClasses so that value produced by an
+ /// instruction of itinerary class DefClass, operand index DefIdx can be
+ /// bypassed when it's read by an instruction of itinerary class UseClass,
+ /// operand index UseIdx.
+ bool hasPipelineForwarding(unsigned DefClass, unsigned DefIdx,
+ unsigned UseClass, unsigned UseIdx) const {
+ unsigned FirstDefIdx = Itineraries[DefClass].FirstOperandCycle;
+ unsigned LastDefIdx = Itineraries[DefClass].LastOperandCycle;
+ if ((FirstDefIdx + DefIdx) >= LastDefIdx)
+ return false;
+ if (Forwardings[FirstDefIdx + DefIdx] == 0)
+ return false;
+
+ unsigned FirstUseIdx = Itineraries[UseClass].FirstOperandCycle;
+ unsigned LastUseIdx = Itineraries[UseClass].LastOperandCycle;
+ if ((FirstUseIdx + UseIdx) >= LastUseIdx)
+ return false;
+
+ return Forwardings[FirstDefIdx + DefIdx] ==
+ Forwardings[FirstUseIdx + UseIdx];
+ }
+
+ /// Compute and return the use operand latency of a given itinerary
+ /// class and operand index if the value is produced by an instruction of the
+ /// specified itinerary class and def operand index.
+ int getOperandLatency(unsigned DefClass, unsigned DefIdx,
+ unsigned UseClass, unsigned UseIdx) const {
+ if (isEmpty())
+ return -1;
+
+ int DefCycle = getOperandCycle(DefClass, DefIdx);
+ if (DefCycle == -1)
+ return -1;
+
+ int UseCycle = getOperandCycle(UseClass, UseIdx);
+ if (UseCycle == -1)
+ return -1;
+
+ UseCycle = DefCycle - UseCycle + 1;
+ if (UseCycle > 0 &&
+ hasPipelineForwarding(DefClass, DefIdx, UseClass, UseIdx))
+ // FIXME: This assumes one cycle benefit for every pipeline forwarding.
+ --UseCycle;
+ return UseCycle;
+ }
+
+ /// Return the number of micro-ops that the given class decodes to.
+ /// Return -1 for classes that require dynamic lookup via TargetInstrInfo.
+ int getNumMicroOps(unsigned ItinClassIndx) const {
+ if (isEmpty())
+ return 1;
+ return Itineraries[ItinClassIndx].NumMicroOps;
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCINSTRITINERARIES_H
diff --git a/clang-r353983/include/llvm/MC/MCLabel.h b/clang-r353983/include/llvm/MC/MCLabel.h
new file mode 100644
index 00000000..0b8afac8
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCLabel.h
@@ -0,0 +1,56 @@
+//===- MCLabel.h - Machine Code Directional Local Labels --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCLabel class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCLABEL_H
+#define LLVM_MC_MCLABEL_H
+
+namespace llvm {
+
+class raw_ostream;
+
+/// 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 {
+ // The instance number of this Directional Local Label.
+ unsigned Instance;
+
+private: // MCContext creates and uniques these.
+ friend class MCContext;
+
+ MCLabel(unsigned instance) : Instance(instance) {}
+
+public:
+ MCLabel(const MCLabel &) = delete;
+ MCLabel &operator=(const MCLabel &) = delete;
+
+ /// Get the current instance of this Directional Local Label.
+ unsigned getInstance() const { return Instance; }
+
+ /// Increment the current instance of this Directional Local Label.
+ unsigned incInstance() { return ++Instance; }
+
+ /// Print the value to the stream \p OS.
+ void print(raw_ostream &OS) const;
+
+ /// Print the value to stderr.
+ void dump() const;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) {
+ Label.print(OS);
+ return OS;
+}
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCLABEL_H
diff --git a/clang-r353983/include/llvm/MC/MCLinkerOptimizationHint.h b/clang-r353983/include/llvm/MC/MCLinkerOptimizationHint.h
new file mode 100644
index 00000000..f2a1364a
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCLinkerOptimizationHint.h
@@ -0,0 +1,186 @@
+//===- MCLinkerOptimizationHint.h - LOH interface ---------------*- C++ -*-===//
+//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares some helpers classes to handle Linker Optimization Hint
+// (LOH).
+//
+// FIXME: LOH interface supports only MachO format at the moment.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
+#define LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstdint>
+
+namespace llvm {
+
+class MachObjectWriter;
+class MCAsmLayout;
+class MCSymbol;
+
+/// Linker Optimization Hint Type.
+enum MCLOHType {
+ MCLOH_AdrpAdrp = 0x1u, ///< Adrp xY, _v1@PAGE -> Adrp xY, _v2@PAGE.
+ MCLOH_AdrpLdr = 0x2u, ///< Adrp _v@PAGE -> Ldr _v@PAGEOFF.
+ MCLOH_AdrpAddLdr = 0x3u, ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Ldr.
+ MCLOH_AdrpLdrGotLdr = 0x4u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Ldr.
+ MCLOH_AdrpAddStr = 0x5u, ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Str.
+ MCLOH_AdrpLdrGotStr = 0x6u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Str.
+ MCLOH_AdrpAdd = 0x7u, ///< Adrp _v@PAGE -> Add _v@PAGEOFF.
+ MCLOH_AdrpLdrGot = 0x8u ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF.
+};
+
+static inline StringRef MCLOHDirectiveName() {
+ return StringRef(".loh");
+}
+
+static inline bool isValidMCLOHType(unsigned Kind) {
+ return Kind >= MCLOH_AdrpAdrp && Kind <= MCLOH_AdrpLdrGot;
+}
+
+static inline int MCLOHNameToId(StringRef Name) {
+#define MCLOHCaseNameToId(Name) .Case(#Name, MCLOH_ ## Name)
+ return StringSwitch<int>(Name)
+ MCLOHCaseNameToId(AdrpAdrp)
+ MCLOHCaseNameToId(AdrpLdr)
+ MCLOHCaseNameToId(AdrpAddLdr)
+ MCLOHCaseNameToId(AdrpLdrGotLdr)
+ MCLOHCaseNameToId(AdrpAddStr)
+ MCLOHCaseNameToId(AdrpLdrGotStr)
+ MCLOHCaseNameToId(AdrpAdd)
+ MCLOHCaseNameToId(AdrpLdrGot)
+ .Default(-1);
+}
+
+static inline StringRef MCLOHIdToName(MCLOHType Kind) {
+#define MCLOHCaseIdToName(Name) case MCLOH_ ## Name: return StringRef(#Name);
+ switch (Kind) {
+ MCLOHCaseIdToName(AdrpAdrp);
+ MCLOHCaseIdToName(AdrpLdr);
+ MCLOHCaseIdToName(AdrpAddLdr);
+ MCLOHCaseIdToName(AdrpLdrGotLdr);
+ MCLOHCaseIdToName(AdrpAddStr);
+ MCLOHCaseIdToName(AdrpLdrGotStr);
+ MCLOHCaseIdToName(AdrpAdd);
+ MCLOHCaseIdToName(AdrpLdrGot);
+ }
+ return StringRef();
+}
+
+static inline int MCLOHIdToNbArgs(MCLOHType Kind) {
+ switch (Kind) {
+ // LOH with two arguments
+ case MCLOH_AdrpAdrp:
+ case MCLOH_AdrpLdr:
+ case MCLOH_AdrpAdd:
+ case MCLOH_AdrpLdrGot:
+ return 2;
+ // LOH with three arguments
+ case MCLOH_AdrpAddLdr:
+ case MCLOH_AdrpLdrGotLdr:
+ case MCLOH_AdrpAddStr:
+ case MCLOH_AdrpLdrGotStr:
+ return 3;
+ }
+ return -1;
+}
+
+/// Store Linker Optimization Hint information (LOH).
+class MCLOHDirective {
+ MCLOHType Kind;
+
+ /// Arguments of this directive. Order matters.
+ SmallVector<MCSymbol *, 3> Args;
+
+ /// Emit this directive in \p OutStream using the information available
+ /// in the given \p ObjWriter and \p Layout to get the address of the
+ /// arguments within the object file.
+ void emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter,
+ const MCAsmLayout &Layout) const;
+
+public:
+ using LOHArgs = SmallVectorImpl<MCSymbol *>;
+
+ MCLOHDirective(MCLOHType Kind, const LOHArgs &Args)
+ : Kind(Kind), Args(Args.begin(), Args.end()) {
+ assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!");
+ }
+
+ MCLOHType getKind() const { return Kind; }
+
+ const LOHArgs &getArgs() const { return Args; }
+
+ /// Emit this directive as:
+ /// <kind, numArgs, addr1, ..., addrN>
+ void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const;
+
+ /// 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 MCLOHContainer {
+ /// Keep track of the emit size of all the LOHs.
+ mutable uint64_t EmitSize = 0;
+
+ /// Keep track of all LOH directives.
+ SmallVector<MCLOHDirective, 32> Directives;
+
+public:
+ using LOHDirectives = SmallVectorImpl<MCLOHDirective>;
+
+ MCLOHContainer() = default;
+
+ /// Const accessor to the directives.
+ const LOHDirectives &getDirectives() const {
+ return Directives;
+ }
+
+ /// Add the directive of the given kind \p Kind with the given arguments
+ /// \p Args to the container.
+ void addDirective(MCLOHType Kind, const MCLOHDirective::LOHArgs &Args) {
+ Directives.push_back(MCLOHDirective(Kind, Args));
+ }
+
+ /// Get the size of the directives if emitted.
+ uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
+ const MCAsmLayout &Layout) const {
+ if (!EmitSize) {
+ for (const MCLOHDirective &D : Directives)
+ EmitSize += D.getEmitSize(ObjWriter, Layout);
+ }
+ return EmitSize;
+ }
+
+ /// Emit all Linker Optimization Hint in one big table.
+ /// Each line of the table is emitted by LOHDirective::emit.
+ void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {
+ for (const MCLOHDirective &D : Directives)
+ D.emit(ObjWriter, Layout);
+ }
+
+ void reset() {
+ Directives.clear();
+ EmitSize = 0;
+ }
+};
+
+// Add types for specialized template using MCSymbol.
+using MCLOHArgs = MCLOHDirective::LOHArgs;
+using MCLOHDirectives = MCLOHContainer::LOHDirectives;
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
diff --git a/clang-r353983/include/llvm/MC/MCMachObjectWriter.h b/clang-r353983/include/llvm/MC/MCMachObjectWriter.h
new file mode 100644
index 00000000..278aebee
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCMachObjectWriter.h
@@ -0,0 +1,287 @@
+//===- llvm/MC/MCMachObjectWriter.h - Mach Object Writer --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCMACHOBJECTWRITER_H
+#define LLVM_MC_MCMACHOBJECTWRITER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/StringTableBuilder.h"
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+class MachObjectWriter;
+
+class MCMachObjectTargetWriter : public MCObjectTargetWriter {
+ const unsigned Is64Bit : 1;
+ const uint32_t CPUType;
+ const uint32_t CPUSubtype;
+ unsigned LocalDifference_RIT;
+
+protected:
+ MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_,
+ uint32_t CPUSubtype_);
+
+ void setLocalDifferenceRelocationType(unsigned Type) {
+ LocalDifference_RIT = Type;
+ }
+
+public:
+ virtual ~MCMachObjectTargetWriter();
+
+ virtual Triple::ObjectFormatType getFormat() const { return Triple::MachO; }
+ static bool classof(const MCObjectTargetWriter *W) {
+ return W->getFormat() == Triple::MachO;
+ }
+
+ /// \name Lifetime Management
+ /// @{
+
+ virtual void reset() {}
+
+ /// @}
+
+ /// \name Accessors
+ /// @{
+
+ bool is64Bit() const { return Is64Bit; }
+ uint32_t getCPUType() const { return CPUType; }
+ uint32_t getCPUSubtype() const { return CPUSubtype; }
+ unsigned getLocalDifferenceRelocationType() const {
+ return LocalDifference_RIT;
+ }
+
+ /// @}
+
+ /// \name API
+ /// @{
+
+ virtual void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup, MCValue Target,
+ uint64_t &FixedValue) = 0;
+
+ /// @}
+};
+
+class MachObjectWriter : public MCObjectWriter {
+ /// Helper struct for containing some precomputed information on symbols.
+ struct MachSymbolData {
+ const MCSymbol *Symbol;
+ uint64_t StringIndex;
+ uint8_t SectionIndex;
+
+ // Support lexicographic sorting.
+ bool operator<(const MachSymbolData &RHS) const;
+ };
+
+ /// The target specific Mach-O writer instance.
+ std::unique_ptr<MCMachObjectTargetWriter> TargetObjectWriter;
+
+ /// \name Relocation Data
+ /// @{
+
+ struct RelAndSymbol {
+ const MCSymbol *Sym;
+ MachO::any_relocation_info MRE;
+ RelAndSymbol(const MCSymbol *Sym, const MachO::any_relocation_info &MRE)
+ : Sym(Sym), MRE(MRE) {}
+ };
+
+ DenseMap<const MCSection *, std::vector<RelAndSymbol>> Relocations;
+ DenseMap<const MCSection *, unsigned> IndirectSymBase;
+
+ SectionAddrMap SectionAddress;
+
+ /// @}
+ /// \name Symbol Table Data
+ /// @{
+
+ StringTableBuilder StringTable{StringTableBuilder::MachO};
+ std::vector<MachSymbolData> LocalSymbolData;
+ std::vector<MachSymbolData> ExternalSymbolData;
+ std::vector<MachSymbolData> UndefinedSymbolData;
+
+ /// @}
+
+ MachSymbolData *findSymbolData(const MCSymbol &Sym);
+
+ void writeWithPadding(StringRef Str, uint64_t Size);
+
+public:
+ MachObjectWriter(std::unique_ptr<MCMachObjectTargetWriter> MOTW,
+ raw_pwrite_stream &OS, bool IsLittleEndian)
+ : TargetObjectWriter(std::move(MOTW)),
+ W(OS, IsLittleEndian ? support::little : support::big) {}
+
+ support::endian::Writer W;
+
+ const MCSymbol &findAliasedSymbol(const MCSymbol &Sym) const;
+
+ /// \name Lifetime management Methods
+ /// @{
+
+ void reset() override;
+
+ /// @}
+
+ /// \name Utility Methods
+ /// @{
+
+ bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
+
+ SectionAddrMap &getSectionAddressMap() { return SectionAddress; }
+
+ uint64_t getSectionAddress(const MCSection *Sec) const {
+ return SectionAddress.lookup(Sec);
+ }
+ uint64_t getSymbolAddress(const MCSymbol &S, const MCAsmLayout &Layout) const;
+
+ uint64_t getFragmentAddress(const MCFragment *Fragment,
+ const MCAsmLayout &Layout) const;
+
+ uint64_t getPaddingSize(const MCSection *SD, const MCAsmLayout &Layout) const;
+
+ bool doesSymbolRequireExternRelocation(const MCSymbol &S);
+
+ /// @}
+
+ /// \name Target Writer Proxy Accessors
+ /// @{
+
+ bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
+ bool isX86_64() const {
+ uint32_t CPUType = TargetObjectWriter->getCPUType();
+ return CPUType == MachO::CPU_TYPE_X86_64;
+ }
+
+ /// @}
+
+ void writeHeader(MachO::HeaderFileType Type, unsigned NumLoadCommands,
+ unsigned LoadCommandsSize, bool SubsectionsViaSymbols);
+
+ /// Write a segment load command.
+ ///
+ /// \param NumSections The number of sections in this segment.
+ /// \param SectionDataSize The total size of the sections.
+ void writeSegmentLoadCommand(StringRef Name, unsigned NumSections,
+ uint64_t VMAddr, uint64_t VMSize,
+ uint64_t SectionDataStartOffset,
+ uint64_t SectionDataSize, uint32_t MaxProt,
+ uint32_t InitProt);
+
+ void writeSection(const MCAsmLayout &Layout, const MCSection &Sec,
+ uint64_t VMAddr, uint64_t FileOffset, unsigned Flags,
+ uint64_t RelocationsStart, unsigned NumRelocations);
+
+ void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
+ uint32_t StringTableOffset,
+ uint32_t StringTableSize);
+
+ void writeDysymtabLoadCommand(
+ uint32_t FirstLocalSymbol, uint32_t NumLocalSymbols,
+ uint32_t FirstExternalSymbol, uint32_t NumExternalSymbols,
+ uint32_t FirstUndefinedSymbol, uint32_t NumUndefinedSymbols,
+ uint32_t IndirectSymbolOffset, uint32_t NumIndirectSymbols);
+
+ void writeNlist(MachSymbolData &MSD, const MCAsmLayout &Layout);
+
+ void writeLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset,
+ uint32_t DataSize);
+
+ void writeLinkerOptionsLoadCommand(const std::vector<std::string> &Options);
+
+ // FIXME: We really need to improve the relocation validation. Basically, we
+ // want to implement a separate computation which evaluates the relocation
+ // entry as the linker would, and verifies that the resultant fixup value is
+ // exactly what the encoder wanted. This will catch several classes of
+ // problems:
+ //
+ // - Relocation entry bugs, the two algorithms are unlikely to have the same
+ // exact bug.
+ //
+ // - Relaxation issues, where we forget to relax something.
+ //
+ // - Input errors, where something cannot be correctly encoded. 'as' allows
+ // these through in many cases.
+
+ // 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) {
+ RelAndSymbol P(RelSymbol, MRE);
+ Relocations[Sec].push_back(P);
+ }
+
+ void recordScatteredRelocation(const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup, MCValue Target,
+ unsigned Log2Size, uint64_t &FixedValue);
+
+ void recordTLVPRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCFragment *Fragment, const MCFixup &Fixup,
+ MCValue Target, uint64_t &FixedValue);
+
+ void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCFragment *Fragment, const MCFixup &Fixup,
+ MCValue Target, uint64_t &FixedValue) override;
+
+ void bindIndirectSymbols(MCAssembler &Asm);
+
+ /// Compute the symbol table data.
+ void computeSymbolTable(MCAssembler &Asm,
+ std::vector<MachSymbolData> &LocalSymbolData,
+ std::vector<MachSymbolData> &ExternalSymbolData,
+ std::vector<MachSymbolData> &UndefinedSymbolData);
+
+ void computeSectionAddresses(const MCAssembler &Asm,
+ const MCAsmLayout &Layout);
+
+ void executePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) override;
+
+ bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbol &A,
+ const MCSymbol &B,
+ bool InSet) const override;
+
+ bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbol &SymA,
+ const MCFragment &FB, bool InSet,
+ bool IsPCRel) const override;
+
+ uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
+};
+
+/// Construct a new Mach-O writer instance.
+///
+/// This routine takes ownership of the target writer subclass.
+///
+/// \param MOTW - The target specific Mach-O writer subclass.
+/// \param OS - The stream to write to.
+/// \returns The constructed object writer.
+std::unique_ptr<MCObjectWriter>
+createMachObjectWriter(std::unique_ptr<MCMachObjectTargetWriter> MOTW,
+ raw_pwrite_stream &OS, bool IsLittleEndian);
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCMACHOBJECTWRITER_H
diff --git a/clang-r353983/include/llvm/MC/MCObjectFileInfo.h b/clang-r353983/include/llvm/MC/MCObjectFileInfo.h
new file mode 100644
index 00000000..0c1ade48
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCObjectFileInfo.h
@@ -0,0 +1,413 @@
+//===-- llvm/MC/MCObjectFileInfo.h - Object File Info -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes common object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCOBJECTFILEINFO_H
+#define LLVM_MC_MCOBJECTFILEINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/VersionTuple.h"
+
+namespace llvm {
+class MCContext;
+class MCSection;
+
+class MCObjectFileInfo {
+protected:
+ /// True if .comm supports alignment. This is a hack for as long as we
+ /// support 10.4 Tiger, whose assembler doesn't support alignment on comm.
+ bool CommDirectiveSupportsAlignment;
+
+ /// True if target object file supports a weak_definition of constant 0 for an
+ /// omitted EH frame.
+ bool SupportsWeakOmittedEHFrame;
+
+ /// True if the target object file supports emitting a compact unwind section
+ /// without an associated EH frame section.
+ bool SupportsCompactUnwindWithoutEHFrame;
+
+ /// OmitDwarfIfHaveCompactUnwind - True if the target object file
+ /// supports having some functions with compact unwind and other with
+ /// dwarf unwind.
+ bool OmitDwarfIfHaveCompactUnwind;
+
+ /// FDE CFI encoding. Controls the encoding of the begin label in the
+ /// .eh_frame section. Unlike the LSDA encoding, personality encoding, and
+ /// type encodings, this is something that the assembler just "knows" about
+ /// its target
+ unsigned FDECFIEncoding = 0;
+
+ /// Compact unwind encoding indicating that we should emit only an EH frame.
+ unsigned CompactUnwindDwarfEHFrameOnly;
+
+ /// Section directive for standard text.
+ MCSection *TextSection;
+
+ /// Section directive for standard data.
+ MCSection *DataSection;
+
+ /// Section that is default initialized to zero.
+ MCSection *BSSSection;
+
+ /// 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;
+
+ /// If exception handling is supported by the target, this is the section the
+ /// Language Specific Data Area information is emitted to.
+ MCSection *LSDASection;
+
+ /// 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.
+ MCSection *DwarfAbbrevSection;
+ MCSection *DwarfInfoSection;
+ MCSection *DwarfLineSection;
+ MCSection *DwarfLineStrSection;
+ MCSection *DwarfFrameSection;
+ MCSection *DwarfPubTypesSection;
+ const MCSection *DwarfDebugInlineSection;
+ MCSection *DwarfStrSection;
+ MCSection *DwarfLocSection;
+ MCSection *DwarfARangesSection;
+ MCSection *DwarfRangesSection;
+ MCSection *DwarfMacinfoSection;
+ // The pubnames section is no longer generated by default. The generation
+ // can be enabled by a compiler flag.
+ MCSection *DwarfPubNamesSection;
+
+ /// Accelerator table sections. DwarfDebugNamesSection is the DWARF v5
+ /// accelerator table, while DwarfAccelNamesSection, DwarfAccelObjCSection,
+ /// DwarfAccelNamespaceSection, DwarfAccelTypesSection are pre-DWARF v5
+ /// extensions.
+ MCSection *DwarfDebugNamesSection;
+ MCSection *DwarfAccelNamesSection;
+ MCSection *DwarfAccelObjCSection;
+ MCSection *DwarfAccelNamespaceSection;
+ MCSection *DwarfAccelTypesSection;
+
+ // These are used for the Fission separate debug information files.
+ MCSection *DwarfInfoDWOSection;
+ MCSection *DwarfTypesDWOSection;
+ MCSection *DwarfAbbrevDWOSection;
+ MCSection *DwarfStrDWOSection;
+ MCSection *DwarfLineDWOSection;
+ MCSection *DwarfLocDWOSection;
+ MCSection *DwarfStrOffDWOSection;
+
+ /// The DWARF v5 string offset and address table sections.
+ MCSection *DwarfStrOffSection;
+ MCSection *DwarfAddrSection;
+ /// The DWARF v5 range list section.
+ MCSection *DwarfRnglistsSection;
+ /// The DWARF v5 locations list section.
+ MCSection *DwarfLoclistsSection;
+
+ /// The DWARF v5 range list section for fission.
+ MCSection *DwarfRnglistsDWOSection;
+
+ // These are for Fission DWP files.
+ MCSection *DwarfCUIndexSection;
+ MCSection *DwarfTUIndexSection;
+
+ /// Section for newer gnu pubnames.
+ MCSection *DwarfGnuPubNamesSection;
+ /// Section for newer gnu pubtypes.
+ MCSection *DwarfGnuPubTypesSection;
+
+ // Section for Swift AST
+ MCSection *DwarfSwiftASTSection;
+
+ MCSection *COFFDebugSymbolsSection;
+ MCSection *COFFDebugTypesSection;
+ MCSection *COFFGlobalTypeHashesSection;
+
+ /// Extra TLS Variable Data section.
+ ///
+ /// If the target needs to put additional information for a TLS variable,
+ /// it'll go here.
+ MCSection *TLSExtraDataSection;
+
+ /// Section directive for Thread Local data. ELF, MachO, COFF, and Wasm.
+ MCSection *TLSDataSection; // Defaults to ".tdata".
+
+ /// 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.
+ MCSection *StackMapSection;
+
+ /// FaultMap section.
+ MCSection *FaultMapSection;
+
+ /// EH frame section.
+ ///
+ /// It is initialized on demand so it can be overwritten (with uniquing).
+ MCSection *EHFrameSection;
+
+ /// Section containing metadata on function stack sizes.
+ MCSection *StackSizesSection;
+ mutable DenseMap<const MCSymbol *, unsigned> StackSizesUniquing;
+
+ // ELF specific sections.
+ MCSection *DataRelROSection;
+ MCSection *MergeableConst4Section;
+ MCSection *MergeableConst8Section;
+ MCSection *MergeableConst16Section;
+ MCSection *MergeableConst32Section;
+
+ // MachO specific sections.
+
+ /// 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".
+
+ /// Section for thread local data initialization functions.
+ const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func".
+
+ MCSection *CStringSection;
+ MCSection *UStringSection;
+ MCSection *TextCoalSection;
+ MCSection *ConstTextCoalSection;
+ MCSection *ConstDataSection;
+ MCSection *DataCoalSection;
+ MCSection *ConstDataCoalSection;
+ MCSection *DataCommonSection;
+ MCSection *DataBSSSection;
+ MCSection *FourByteConstantSection;
+ MCSection *EightByteConstantSection;
+ MCSection *SixteenByteConstantSection;
+ MCSection *LazySymbolPointerSection;
+ MCSection *NonLazySymbolPointerSection;
+ MCSection *ThreadLocalPointerSection;
+
+ /// COFF specific sections.
+ MCSection *DrectveSection;
+ MCSection *PDataSection;
+ MCSection *XDataSection;
+ MCSection *SXDataSection;
+ MCSection *GFIDsSection;
+
+public:
+ void InitMCObjectFileInfo(const Triple &TT, bool PIC, MCContext &ctx,
+ bool LargeCodeModel = false);
+
+ bool getSupportsWeakOmittedEHFrame() const {
+ return SupportsWeakOmittedEHFrame;
+ }
+ bool getSupportsCompactUnwindWithoutEHFrame() const {
+ return SupportsCompactUnwindWithoutEHFrame;
+ }
+ bool getOmitDwarfIfHaveCompactUnwind() const {
+ return OmitDwarfIfHaveCompactUnwind;
+ }
+
+ bool getCommDirectiveSupportsAlignment() const {
+ return CommDirectiveSupportsAlignment;
+ }
+
+ unsigned getFDEEncoding() const { return FDECFIEncoding; }
+
+ unsigned getCompactUnwindDwarfEHFrameOnly() const {
+ return CompactUnwindDwarfEHFrameOnly;
+ }
+
+ MCSection *getTextSection() const { return TextSection; }
+ MCSection *getDataSection() const { return DataSection; }
+ MCSection *getBSSSection() const { return BSSSection; }
+ MCSection *getReadOnlySection() const { return ReadOnlySection; }
+ MCSection *getLSDASection() const { return LSDASection; }
+ MCSection *getCompactUnwindSection() const { return CompactUnwindSection; }
+ MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; }
+ MCSection *getDwarfInfoSection() const { return DwarfInfoSection; }
+ MCSection *getDwarfInfoSection(uint64_t Hash) const {
+ return getDwarfComdatSection(".debug_info", Hash);
+ }
+ MCSection *getDwarfLineSection() const { return DwarfLineSection; }
+ MCSection *getDwarfLineStrSection() const { return DwarfLineStrSection; }
+ MCSection *getDwarfFrameSection() const { return DwarfFrameSection; }
+ MCSection *getDwarfPubNamesSection() const { return DwarfPubNamesSection; }
+ MCSection *getDwarfPubTypesSection() const { return DwarfPubTypesSection; }
+ MCSection *getDwarfGnuPubNamesSection() const {
+ return DwarfGnuPubNamesSection;
+ }
+ MCSection *getDwarfGnuPubTypesSection() const {
+ return DwarfGnuPubTypesSection;
+ }
+ const MCSection *getDwarfDebugInlineSection() const {
+ return DwarfDebugInlineSection;
+ }
+ MCSection *getDwarfStrSection() const { return DwarfStrSection; }
+ MCSection *getDwarfLocSection() const { return DwarfLocSection; }
+ MCSection *getDwarfARangesSection() const { return DwarfARangesSection; }
+ MCSection *getDwarfRangesSection() const { return DwarfRangesSection; }
+ MCSection *getDwarfRnglistsSection() const { return DwarfRnglistsSection; }
+ MCSection *getDwarfLoclistsSection() const { return DwarfLoclistsSection; }
+ MCSection *getDwarfMacinfoSection() const { return DwarfMacinfoSection; }
+
+ MCSection *getDwarfDebugNamesSection() const {
+ return DwarfDebugNamesSection;
+ }
+ MCSection *getDwarfAccelNamesSection() const {
+ return DwarfAccelNamesSection;
+ }
+ MCSection *getDwarfAccelObjCSection() const { return DwarfAccelObjCSection; }
+ MCSection *getDwarfAccelNamespaceSection() const {
+ return DwarfAccelNamespaceSection;
+ }
+ MCSection *getDwarfAccelTypesSection() const {
+ return DwarfAccelTypesSection;
+ }
+ MCSection *getDwarfInfoDWOSection() const { return DwarfInfoDWOSection; }
+ MCSection *getDwarfTypesSection(uint64_t Hash) const {
+ return getDwarfComdatSection(".debug_types", Hash);
+ }
+ 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 *getDwarfStrOffSection() const { return DwarfStrOffSection; }
+ MCSection *getDwarfAddrSection() const { return DwarfAddrSection; }
+ MCSection *getDwarfRnglistsDWOSection() const {
+ return DwarfRnglistsDWOSection;
+ }
+ MCSection *getDwarfCUIndexSection() const { return DwarfCUIndexSection; }
+ MCSection *getDwarfTUIndexSection() const { return DwarfTUIndexSection; }
+ MCSection *getDwarfSwiftASTSection() const { return DwarfSwiftASTSection; }
+
+ MCSection *getCOFFDebugSymbolsSection() const {
+ return COFFDebugSymbolsSection;
+ }
+ MCSection *getCOFFDebugTypesSection() const {
+ return COFFDebugTypesSection;
+ }
+ MCSection *getCOFFGlobalTypeHashesSection() const {
+ return COFFGlobalTypeHashesSection;
+ }
+
+ MCSection *getTLSExtraDataSection() const { return TLSExtraDataSection; }
+ const MCSection *getTLSDataSection() const { return TLSDataSection; }
+ MCSection *getTLSBSSSection() const { return TLSBSSSection; }
+
+ MCSection *getStackMapSection() const { return StackMapSection; }
+ MCSection *getFaultMapSection() const { return FaultMapSection; }
+
+ MCSection *getStackSizesSection(const MCSection &TextSec) const;
+
+ // ELF specific sections.
+ MCSection *getDataRelROSection() const { return DataRelROSection; }
+ const MCSection *getMergeableConst4Section() const {
+ return MergeableConst4Section;
+ }
+ const MCSection *getMergeableConst8Section() const {
+ return MergeableConst8Section;
+ }
+ const MCSection *getMergeableConst16Section() const {
+ return MergeableConst16Section;
+ }
+ const MCSection *getMergeableConst32Section() const {
+ return MergeableConst32Section;
+ }
+
+ // MachO specific sections.
+ const MCSection *getTLSTLVSection() const { return TLSTLVSection; }
+ const MCSection *getTLSThreadInitSection() const {
+ return TLSThreadInitSection;
+ }
+ const MCSection *getCStringSection() const { return CStringSection; }
+ const MCSection *getUStringSection() const { return UStringSection; }
+ 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 *getConstDataCoalSection() const {
+ return ConstDataCoalSection;
+ }
+ const MCSection *getDataCommonSection() const { return DataCommonSection; }
+ MCSection *getDataBSSSection() const { return DataBSSSection; }
+ const MCSection *getFourByteConstantSection() const {
+ return FourByteConstantSection;
+ }
+ const MCSection *getEightByteConstantSection() const {
+ return EightByteConstantSection;
+ }
+ const MCSection *getSixteenByteConstantSection() const {
+ return SixteenByteConstantSection;
+ }
+ MCSection *getLazySymbolPointerSection() const {
+ return LazySymbolPointerSection;
+ }
+ MCSection *getNonLazySymbolPointerSection() const {
+ return NonLazySymbolPointerSection;
+ }
+ MCSection *getThreadLocalPointerSection() const {
+ return ThreadLocalPointerSection;
+ }
+
+ // COFF specific sections.
+ MCSection *getDrectveSection() const { return DrectveSection; }
+ MCSection *getPDataSection() const { return PDataSection; }
+ MCSection *getXDataSection() const { return XDataSection; }
+ MCSection *getSXDataSection() const { return SXDataSection; }
+ MCSection *getGFIDsSection() const { return GFIDsSection; }
+
+ MCSection *getEHFrameSection() {
+ return EHFrameSection;
+ }
+
+ enum Environment { IsMachO, IsELF, IsCOFF, IsWasm };
+ Environment getObjectFileType() const { return Env; }
+
+ bool isPositionIndependent() const { return PositionIndependent; }
+
+private:
+ Environment Env;
+ bool PositionIndependent;
+ MCContext *Ctx;
+ Triple TT;
+ VersionTuple SDKVersion;
+
+ void initMachOMCObjectFileInfo(const Triple &T);
+ void initELFMCObjectFileInfo(const Triple &T, bool Large);
+ void initCOFFMCObjectFileInfo(const Triple &T);
+ void initWasmMCObjectFileInfo(const Triple &T);
+ MCSection *getDwarfComdatSection(const char *Name, uint64_t Hash) const;
+
+public:
+ const Triple &getTargetTriple() const { return TT; }
+
+ void setSDKVersion(const VersionTuple &TheSDKVersion) {
+ SDKVersion = TheSDKVersion;
+ }
+
+ const VersionTuple &getSDKVersion() const { return SDKVersion; }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCObjectStreamer.h b/clang-r353983/include/llvm/MC/MCObjectStreamer.h
new file mode 100644
index 00000000..8affca49
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCObjectStreamer.h
@@ -0,0 +1,205 @@
+//===- MCObjectStreamer.h - MCStreamer Object File Interface ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCOBJECTSTREAMER_H
+#define LLVM_MC_MCOBJECTSTREAMER_H
+
+#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 MCSubtargetInfo;
+class MCExpr;
+class MCFragment;
+class MCDataFragment;
+class MCAsmBackend;
+class raw_ostream;
+class raw_pwrite_stream;
+
+/// Streaming object file generation interface.
+///
+/// This class provides an implementation of the MCStreamer interface which is
+/// suitable for use with the assembler backend. Specific object file formats
+/// are expected to subclass this interface to implement directives specific
+/// to that file format or custom semantics expected by the object writer
+/// implementation.
+class MCObjectStreamer : public MCStreamer {
+ std::unique_ptr<MCAssembler> Assembler;
+ MCSection::iterator CurInsertionPoint;
+ bool EmitEHFrame;
+ bool EmitDebugFrame;
+ SmallVector<MCSymbol *, 2> PendingLabels;
+ struct PendingMCFixup {
+ const MCSymbol *Sym;
+ MCFixup Fixup;
+ MCDataFragment *DF;
+ PendingMCFixup(const MCSymbol *McSym, MCDataFragment *F, MCFixup McFixup)
+ : Sym(McSym), Fixup(McFixup), DF(F) {}
+ };
+ SmallVector<PendingMCFixup, 2> PendingFixups;
+
+ virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0;
+ void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
+ void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
+ MCSymbol *EmitCFILabel() override;
+ void EmitInstructionImpl(const MCInst &Inst, const MCSubtargetInfo &STI);
+ void resolvePendingFixups();
+
+protected:
+ MCObjectStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
+ std::unique_ptr<MCObjectWriter> OW,
+ std::unique_ptr<MCCodeEmitter> Emitter);
+ ~MCObjectStreamer();
+
+public:
+ /// state management
+ void reset() override;
+
+ /// Object streamers require the integrated assembler.
+ bool isIntegratedAssemblerRequired() const override { return true; }
+
+ void EmitFrames(MCAsmBackend *MAB);
+ void EmitCFISections(bool EH, bool Debug) override;
+
+ MCFragment *getCurrentFragment() const;
+
+ void insert(MCFragment *F) {
+ flushPendingLabels(F);
+ MCSection *CurSection = getCurrentSectionOnly();
+ CurSection->getFragmentList().insert(CurInsertionPoint, F);
+ F->setParent(CurSection);
+ }
+
+ /// Get a data fragment to write into, creating a new one if the current
+ /// fragment is not a data fragment.
+ /// Optionally a \p STI can be passed in so that a new fragment is created
+ /// if the Subtarget differs from the current fragment.
+ MCDataFragment *getOrCreateDataFragment(const MCSubtargetInfo* STI = nullptr);
+ MCPaddingFragment *getOrCreatePaddingFragment();
+
+protected:
+ 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;
+
+ /// Create a dummy fragment to assign any pending labels.
+ void flushPendingLabels() { flushPendingLabels(nullptr); }
+
+ MCAssembler &getAssembler() { return *Assembler; }
+ MCAssembler *getAssemblerPtr() override;
+ /// \name MCStreamer Interface
+ /// @{
+
+ void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
+ virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F);
+ void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
+ void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ SMLoc Loc = SMLoc()) override;
+ void EmitULEB128Value(const MCExpr *Value) override;
+ void EmitSLEB128Value(const MCExpr *Value) override;
+ void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
+ void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
+ void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
+
+ /// Emit an instruction to a special fragment, because this instruction
+ /// can change its size during relaxation.
+ virtual void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &);
+
+ void EmitBundleAlignMode(unsigned AlignPow2) override;
+ void EmitBundleLock(bool AlignToEnd) override;
+ void EmitBundleUnlock() override;
+ void EmitBytes(StringRef Data) override;
+ void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
+ unsigned ValueSize = 1,
+ unsigned MaxBytesToEmit = 0) override;
+ void EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit = 0) override;
+ void emitValueToOffset(const MCExpr *Offset, unsigned char Value,
+ SMLoc Loc) override;
+ void
+ EmitCodePaddingBasicBlockStart(const MCCodePaddingContext &Context) override;
+ void
+ EmitCodePaddingBasicBlockEnd(const MCCodePaddingContext &Context) override;
+ void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
+ unsigned Column, unsigned Flags,
+ unsigned Isa, unsigned Discriminator,
+ StringRef FileName) override;
+ void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
+ const MCSymbol *Label,
+ unsigned PointerSize);
+ void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
+ const MCSymbol *Label);
+ void EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
+ unsigned Column, bool PrologueEnd, bool IsStmt,
+ StringRef FileName, SMLoc Loc) override;
+ void EmitCVLinetableDirective(unsigned FunctionId, const MCSymbol *Begin,
+ const MCSymbol *End) override;
+ void EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
+ unsigned SourceFileId,
+ unsigned SourceLineNum,
+ const MCSymbol *FnStartSym,
+ const MCSymbol *FnEndSym) override;
+ void EmitCVDefRangeDirective(
+ ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
+ StringRef FixedSizePortion) override;
+ void EmitCVStringTableDirective() override;
+ void EmitCVFileChecksumsDirective() override;
+ void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override;
+ void EmitDTPRel32Value(const MCExpr *Value) override;
+ void EmitDTPRel64Value(const MCExpr *Value) override;
+ void EmitTPRel32Value(const MCExpr *Value) override;
+ void EmitTPRel64Value(const MCExpr *Value) override;
+ void EmitGPRel32Value(const MCExpr *Value) override;
+ void EmitGPRel64Value(const MCExpr *Value) override;
+ bool EmitRelocDirective(const MCExpr &Offset, StringRef Name,
+ const MCExpr *Expr, SMLoc Loc,
+ const MCSubtargetInfo &STI) override;
+ using MCStreamer::emitFill;
+ void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
+ SMLoc Loc = SMLoc()) override;
+ void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
+ SMLoc Loc = SMLoc()) override;
+ void EmitFileDirective(StringRef Filename) override;
+
+ void EmitAddrsig() override;
+ void EmitAddrsigSym(const MCSymbol *Sym) override;
+
+ void FinishImpl() override;
+
+ /// 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 and that the target has not specified that diff expressions
+ /// require relocations to be emitted. Otherwise, do nothing and return
+ /// \c false.
+ ///
+ /// \pre Offset of \c Hi is greater than the offset \c Lo.
+ void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
+ unsigned Size) override;
+
+ void emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
+ const MCSymbol *Lo) override;
+
+ bool mayHaveInstructions(MCSection &Sec) const override;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCObjectWriter.h b/clang-r353983/include/llvm/MC/MCObjectWriter.h
new file mode 100644
index 00000000..2547b2b7
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCObjectWriter.h
@@ -0,0 +1,123 @@
+//===- llvm/MC/MCObjectWriter.h - Object File Writer Interface --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCOBJECTWRITER_H
+#define LLVM_MC_MCOBJECTWRITER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstdint>
+
+namespace llvm {
+
+class MCAsmLayout;
+class MCAssembler;
+class MCFixup;
+class MCFragment;
+class MCSymbol;
+class MCSymbolRefExpr;
+class MCValue;
+
+/// Defines the object file and target independent interfaces used by the
+/// assembler backend to write native file format object files.
+///
+/// The object writer contains a few callbacks used by the assembler to allow
+/// the object writer to modify the assembler data structures at appropriate
+/// points. Once assembly is complete, the object writer is given the
+/// MCAssembler instance, which contains all the symbol and section data which
+/// should be emitted as part of writeObject().
+class MCObjectWriter {
+protected:
+ MCObjectWriter() = default;
+
+public:
+ MCObjectWriter(const MCObjectWriter &) = delete;
+ MCObjectWriter &operator=(const MCObjectWriter &) = delete;
+ virtual ~MCObjectWriter();
+
+ /// lifetime management
+ virtual void reset() {}
+
+ /// \name High-Level API
+ /// @{
+
+ /// Perform any late binding of symbols (for example, to assign symbol
+ /// indices for use when generating relocations).
+ ///
+ /// This routine is called by the assembler after layout and relaxation is
+ /// complete.
+ virtual void executePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) = 0;
+
+ /// Record a relocation entry.
+ ///
+ /// This routine is called by the assembler after layout and relaxation, and
+ /// post layout binding. The implementation is responsible for storing
+ /// information about the relocation so that it can be emitted during
+ /// writeObject().
+ virtual void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup, MCValue Target,
+ uint64_t &FixedValue) = 0;
+
+ /// 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 MCSymbol &A,
+ const MCSymbol &B,
+ bool InSet) const;
+
+ virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbol &SymA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const;
+
+ /// Tell the object writer to emit an address-significance table during
+ /// writeObject(). If this function is not called, all symbols are treated as
+ /// address-significant.
+ virtual void emitAddrsigSection() {}
+
+ /// Record the given symbol in the address-significance table to be written
+ /// diring writeObject().
+ virtual void addAddrsigSymbol(const MCSymbol *Sym) {}
+
+ /// Write the object file and returns the number of bytes written.
+ ///
+ /// This routine is called by the assembler after layout and relaxation is
+ /// complete, fixups have been evaluated and applied, and relocations
+ /// generated.
+ virtual uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) = 0;
+
+ /// @}
+};
+
+/// Base class for classes that define behaviour that is specific to both the
+/// target and the object format.
+class MCObjectTargetWriter {
+public:
+ virtual ~MCObjectTargetWriter() = default;
+ virtual Triple::ObjectFormatType getFormat() const = 0;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCOBJECTWRITER_H
diff --git a/clang-r353983/include/llvm/MC/MCParser/AsmCond.h b/clang-r353983/include/llvm/MC/MCParser/AsmCond.h
new file mode 100644
index 00000000..ea215501
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCParser/AsmCond.h
@@ -0,0 +1,39 @@
+//===- AsmCond.h - Assembly file conditional assembly ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCPARSER_ASMCOND_H
+#define LLVM_MC_MCPARSER_ASMCOND_H
+
+namespace llvm {
+
+/// AsmCond - Class to support conditional assembly
+///
+/// The conditional assembly feature (.if, .else, .elseif and .endif) is
+/// implemented with AsmCond that tells us what we are in the middle of
+/// processing. Ignore can be either true or false. When true we are ignoring
+/// the block of code in the middle of a conditional.
+
+class AsmCond {
+public:
+ enum ConditionalAssemblyType {
+ NoCond, // no conditional is being processed
+ IfCond, // inside if conditional
+ ElseIfCond, // inside elseif conditional
+ ElseCond // inside else conditional
+ };
+
+ ConditionalAssemblyType TheCond = NoCond;
+ bool CondMet = false;
+ bool Ignore = false;
+
+ AsmCond() = default;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCPARSER_ASMCOND_H
diff --git a/clang-r353983/include/llvm/MC/MCParser/AsmLexer.h b/clang-r353983/include/llvm/MC/MCParser/AsmLexer.h
new file mode 100644
index 00000000..b7294493
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCParser/AsmLexer.h
@@ -0,0 +1,73 @@
+//===- AsmLexer.h - Lexer for Assembly Files --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This class declares the lexer for assembly files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCPARSER_ASMLEXER_H
+#define LLVM_MC_MCPARSER_ASMLEXER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include <string>
+
+namespace llvm {
+
+class MCAsmInfo;
+
+/// AsmLexer - Lexer class for assembly files.
+class AsmLexer : public MCAsmLexer {
+ const MCAsmInfo &MAI;
+
+ const char *CurPtr = nullptr;
+ StringRef CurBuf;
+ bool IsAtStartOfLine = true;
+ bool IsAtStartOfStatement = true;
+ bool IsPeeking = false;
+
+protected:
+ /// LexToken - Read the next token and return its code.
+ AsmToken LexToken() override;
+
+public:
+ AsmLexer(const MCAsmInfo &MAI);
+ AsmLexer(const AsmLexer &) = delete;
+ AsmLexer &operator=(const AsmLexer &) = delete;
+ ~AsmLexer() override;
+
+ void setBuffer(StringRef Buf, const char *ptr = nullptr);
+
+ StringRef LexUntilEndOfStatement() override;
+
+ size_t peekTokens(MutableArrayRef<AsmToken> Buf,
+ bool ShouldSkipSpace = true) override;
+
+ const MCAsmInfo &getMAI() const { return MAI; }
+
+private:
+ bool isAtStartOfComment(const char *Ptr);
+ bool isAtStatementSeparator(const char *Ptr);
+ int getNextChar();
+ AsmToken ReturnError(const char *Loc, const std::string &Msg);
+
+ AsmToken LexIdentifier();
+ AsmToken LexSlash();
+ AsmToken LexLineComment();
+ AsmToken LexDigit();
+ AsmToken LexSingleQuote();
+ AsmToken LexQuote();
+ AsmToken LexFloatLiteral();
+ AsmToken LexHexFloatLiteral(bool NoIntDigits);
+
+ StringRef LexUntilEndOfLine();
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCPARSER_ASMLEXER_H
diff --git a/clang-r353983/include/llvm/MC/MCParser/MCAsmLexer.h b/clang-r353983/include/llvm/MC/MCParser/MCAsmLexer.h
new file mode 100644
index 00000000..e89abeaa
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -0,0 +1,157 @@
+//===- llvm/MC/MCAsmLexer.h - Abstract Asm Lexer Interface ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCPARSER_MCASMLEXER_H
+#define LLVM_MC_MCPARSER_MCASMLEXER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCAsmMacro.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+namespace llvm {
+
+/// A callback class which is notified of each comment in an assembly file as
+/// it is lexed.
+class AsmCommentConsumer {
+public:
+ virtual ~AsmCommentConsumer() = default;
+
+ /// Callback function for when a comment is lexed. Loc is the start of the
+ /// comment text (excluding the comment-start marker). CommentText is the text
+ /// of the comment, excluding the comment start and end markers, and the
+ /// newline for single-line comments.
+ virtual void HandleComment(SMLoc Loc, StringRef CommentText) = 0;
+};
+
+
+/// Generic assembler lexer interface, for use by target specific assembly
+/// lexers.
+class MCAsmLexer {
+ /// The current token, stored in the base class for faster access.
+ SmallVector<AsmToken, 1> CurTok;
+
+ /// The location and description of the current error
+ SMLoc ErrLoc;
+ std::string Err;
+
+protected: // Can only create subclasses.
+ const char *TokStart = nullptr;
+ bool SkipSpace = true;
+ bool AllowAtInIdentifier;
+ bool IsAtStartOfStatement = true;
+ bool LexMasmIntegers = false;
+ AsmCommentConsumer *CommentConsumer = nullptr;
+
+ MCAsmLexer();
+
+ virtual AsmToken LexToken() = 0;
+
+ void SetError(SMLoc errLoc, const std::string &err) {
+ ErrLoc = errLoc;
+ Err = err;
+ }
+
+public:
+ MCAsmLexer(const MCAsmLexer &) = delete;
+ MCAsmLexer &operator=(const MCAsmLexer &) = delete;
+ virtual ~MCAsmLexer();
+
+ /// Consume the next token from the input stream and return it.
+ ///
+ /// The lexer will continuously return the end-of-file token once the end of
+ /// the main input file has been reached.
+ const AsmToken &Lex() {
+ assert(!CurTok.empty());
+ // Mark if we parsing out a EndOfStatement.
+ IsAtStartOfStatement = CurTok.front().getKind() == AsmToken::EndOfStatement;
+ CurTok.erase(CurTok.begin());
+ // LexToken may generate multiple tokens via UnLex but will always return
+ // the first one. Place returned value at head of CurTok vector.
+ if (CurTok.empty()) {
+ AsmToken T = LexToken();
+ CurTok.insert(CurTok.begin(), T);
+ }
+ return CurTok.front();
+ }
+
+ void UnLex(AsmToken const &Token) {
+ IsAtStartOfStatement = false;
+ CurTok.insert(CurTok.begin(), Token);
+ }
+
+ bool isAtStartOfStatement() { return IsAtStartOfStatement; }
+
+ virtual StringRef LexUntilEndOfStatement() = 0;
+
+ /// Get the current source location.
+ SMLoc getLoc() const;
+
+ /// Get the current (last) lexed token.
+ const AsmToken &getTok() const {
+ return CurTok[0];
+ }
+
+ /// Look ahead at the next token to be lexed.
+ const AsmToken peekTok(bool ShouldSkipSpace = true) {
+ AsmToken Tok;
+
+ MutableArrayRef<AsmToken> Buf(Tok);
+ size_t ReadCount = peekTokens(Buf, ShouldSkipSpace);
+
+ assert(ReadCount == 1);
+ (void)ReadCount;
+
+ return Tok;
+ }
+
+ /// Look ahead an arbitrary number of tokens.
+ virtual size_t peekTokens(MutableArrayRef<AsmToken> Buf,
+ bool ShouldSkipSpace = true) = 0;
+
+ /// Get the current error location
+ SMLoc getErrLoc() {
+ return ErrLoc;
+ }
+
+ /// Get the current error string
+ const std::string &getErr() {
+ return Err;
+ }
+
+ /// Get the kind of current token.
+ AsmToken::TokenKind getKind() const { return getTok().getKind(); }
+
+ /// Check if the current token has kind \p K.
+ bool is(AsmToken::TokenKind K) const { return getTok().is(K); }
+
+ /// Check if the current token has kind \p K.
+ bool isNot(AsmToken::TokenKind K) const { return getTok().isNot(K); }
+
+ /// Set whether spaces should be ignored by the lexer
+ void setSkipSpace(bool val) { SkipSpace = val; }
+
+ bool getAllowAtInIdentifier() { return AllowAtInIdentifier; }
+ void setAllowAtInIdentifier(bool v) { AllowAtInIdentifier = v; }
+
+ void setCommentConsumer(AsmCommentConsumer *CommentConsumer) {
+ this->CommentConsumer = CommentConsumer;
+ }
+
+ /// Set whether to lex masm-style binary and hex literals. They look like
+ /// 0b1101 and 0ABCh respectively.
+ void setLexMasmIntegers(bool V) { LexMasmIntegers = V; }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCPARSER_MCASMLEXER_H
diff --git a/clang-r353983/include/llvm/MC/MCParser/MCAsmParser.h b/clang-r353983/include/llvm/MC/MCParser/MCAsmParser.h
new file mode 100644
index 00000000..da5653ee
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCParser/MCAsmParser.h
@@ -0,0 +1,309 @@
+//===- llvm/MC/MCAsmParser.h - Abstract Asm Parser Interface ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCPARSER_MCASMPARSER_H
+#define LLVM_MC_MCPARSER_MCASMPARSER_H
+
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/Support/SMLoc.h"
+#include <cstdint>
+#include <string>
+#include <utility>
+
+namespace llvm {
+
+class MCAsmInfo;
+class MCAsmParserExtension;
+class MCContext;
+class MCExpr;
+class MCInstPrinter;
+class MCInstrInfo;
+class MCStreamer;
+class MCTargetAsmParser;
+class SourceMgr;
+
+struct InlineAsmIdentifierInfo {
+ enum IdKind {
+ IK_Invalid, // Initial state. Unexpected after a successful parsing.
+ IK_Label, // Function/Label reference.
+ IK_EnumVal, // Value of enumeration type.
+ IK_Var // Variable.
+ };
+ // Represents an Enum value
+ struct EnumIdentifier {
+ int64_t EnumVal;
+ };
+ // Represents a label/function reference
+ struct LabelIdentifier {
+ void *Decl;
+ };
+ // Represents a variable
+ struct VariableIdentifier {
+ void *Decl;
+ bool IsGlobalLV;
+ unsigned Length;
+ unsigned Size;
+ unsigned Type;
+ };
+ // An InlineAsm identifier can only be one of those
+ union {
+ EnumIdentifier Enum;
+ LabelIdentifier Label;
+ VariableIdentifier Var;
+ };
+ bool isKind(IdKind kind) const { return Kind == kind; }
+ // Initializers
+ void setEnum(int64_t enumVal) {
+ assert(isKind(IK_Invalid) && "should be initialized only once");
+ Kind = IK_EnumVal;
+ Enum.EnumVal = enumVal;
+ }
+ void setLabel(void *decl) {
+ assert(isKind(IK_Invalid) && "should be initialized only once");
+ Kind = IK_Label;
+ Label.Decl = decl;
+ }
+ void setVar(void *decl, bool isGlobalLV, unsigned size, unsigned type) {
+ assert(isKind(IK_Invalid) && "should be initialized only once");
+ Kind = IK_Var;
+ Var.Decl = decl;
+ Var.IsGlobalLV = isGlobalLV;
+ Var.Size = size;
+ Var.Type = type;
+ Var.Length = size / type;
+ }
+ InlineAsmIdentifierInfo() : Kind(IK_Invalid) {}
+
+private:
+ // Discriminate using the current kind.
+ IdKind Kind;
+};
+
+/// Generic Sema callback for assembly parser.
+class MCAsmParserSemaCallback {
+public:
+ virtual ~MCAsmParserSemaCallback();
+
+ virtual void LookupInlineAsmIdentifier(StringRef &LineBuf,
+ InlineAsmIdentifierInfo &Info,
+ bool IsUnevaluatedContext) = 0;
+ virtual StringRef LookupInlineAsmLabel(StringRef Identifier, SourceMgr &SM,
+ SMLoc Location, bool Create) = 0;
+ virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
+ unsigned &Offset) = 0;
+};
+
+/// Generic assembler parser interface, for use by target specific
+/// assembly parsers.
+class MCAsmParser {
+public:
+ using DirectiveHandler = bool (*)(MCAsmParserExtension*, StringRef, SMLoc);
+ using ExtensionDirectiveHandler =
+ std::pair<MCAsmParserExtension*, DirectiveHandler>;
+
+ struct MCPendingError {
+ SMLoc Loc;
+ SmallString<64> Msg;
+ SMRange Range;
+ };
+
+private:
+ MCTargetAsmParser *TargetParser = nullptr;
+
+protected: // Can only create subclasses.
+ MCAsmParser();
+
+ SmallVector<MCPendingError, 0> PendingErrors;
+
+ /// Flag tracking whether any errors have been encountered.
+ bool HadError = false;
+
+ bool ShowParsedOperands = false;
+
+public:
+ MCAsmParser(const MCAsmParser &) = delete;
+ MCAsmParser &operator=(const MCAsmParser &) = delete;
+ virtual ~MCAsmParser();
+
+ virtual void addDirectiveHandler(StringRef Directive,
+ ExtensionDirectiveHandler Handler) = 0;
+
+ virtual void addAliasForDirective(StringRef Directive, StringRef Alias) = 0;
+
+ virtual SourceMgr &getSourceManager() = 0;
+
+ virtual MCAsmLexer &getLexer() = 0;
+ const MCAsmLexer &getLexer() const {
+ return const_cast<MCAsmParser*>(this)->getLexer();
+ }
+
+ virtual MCContext &getContext() = 0;
+
+ /// Return the output streamer for the assembler.
+ virtual MCStreamer &getStreamer() = 0;
+
+ MCTargetAsmParser &getTargetParser() const { return *TargetParser; }
+ void setTargetParser(MCTargetAsmParser &P);
+
+ virtual unsigned getAssemblerDialect() { return 0;}
+ virtual void setAssemblerDialect(unsigned i) { }
+
+ bool getShowParsedOperands() const { return ShowParsedOperands; }
+ void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; }
+
+ /// Run 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.
+ virtual bool parseMSInlineAsm(
+ void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
+ unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
+ SmallVectorImpl<std::string> &Constraints,
+ SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
+ const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) = 0;
+
+ /// Emit a note at the location \p L, with the message \p Msg.
+ virtual void Note(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
+
+ /// 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, SMRange Range = None) = 0;
+
+ /// Return an error at the location \p L, with the message \p Msg. This
+ /// may be modified before being emitted.
+ ///
+ /// \return The return value is always true, as an idiomatic convenience to
+ /// clients.
+ bool Error(SMLoc L, const Twine &Msg, SMRange Range = None);
+
+ /// 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 printError(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
+
+ bool hasPendingError() { return !PendingErrors.empty(); }
+
+ bool printPendingErrors() {
+ bool rv = !PendingErrors.empty();
+ for (auto Err : PendingErrors) {
+ printError(Err.Loc, Twine(Err.Msg), Err.Range);
+ }
+ PendingErrors.clear();
+ return rv;
+ }
+
+ void clearPendingErrors() { PendingErrors.clear(); }
+
+ bool addErrorSuffix(const Twine &Suffix);
+
+ /// Get the next AsmToken in the stream, possibly handling file
+ /// inclusion first.
+ virtual const AsmToken &Lex() = 0;
+
+ /// Get the current AsmToken from the stream.
+ const AsmToken &getTok() const;
+
+ /// Report an error at the current lexer location.
+ bool TokError(const Twine &Msg, SMRange Range = None);
+
+ bool parseTokenLoc(SMLoc &Loc);
+ bool parseToken(AsmToken::TokenKind T, const Twine &Msg = "unexpected token");
+ /// Attempt to parse and consume token, returning true on
+ /// success.
+ bool parseOptionalToken(AsmToken::TokenKind T);
+
+ bool parseEOL(const Twine &ErrMsg);
+
+ bool parseMany(function_ref<bool()> parseOne, bool hasComma = true);
+
+ bool parseIntToken(int64_t &V, const Twine &ErrMsg);
+
+ bool check(bool P, const Twine &Msg);
+ bool check(bool P, SMLoc Loc, const Twine &Msg);
+
+ /// Parse an identifier or string (as a quoted identifier) and set \p
+ /// Res to the identifier contents.
+ virtual bool parseIdentifier(StringRef &Res) = 0;
+
+ /// Parse up to the end of statement and return the contents from the
+ /// current token until the end of the statement; the current token on exit
+ /// will be either the EndOfStatement or EOF.
+ virtual StringRef parseStringToEndOfStatement() = 0;
+
+ /// 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.
+ virtual void eatToEndOfStatement() = 0;
+
+ /// Parse an arbitrary expression.
+ ///
+ /// \param Res - The value of the expression. The result is undefined
+ /// on error.
+ /// \return - False on success.
+ virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
+ bool parseExpression(const MCExpr *&Res);
+
+ /// Parse a primary expression.
+ ///
+ /// \param Res - The value of the expression. The result is undefined
+ /// on error.
+ /// \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.
+ ///
+ /// \param Res - The value of the expression. The result is undefined
+ /// on error.
+ /// \return - False on success.
+ virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
+
+ /// Parse an expression which must evaluate to an absolute value.
+ ///
+ /// \param Res - The value of the absolute expression. The result is undefined
+ /// on error.
+ /// \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.
+ /// \return - False on success.
+ virtual bool checkForValidSection() = 0;
+
+ /// Parse an arbitrary expression of a specified parenthesis depth,
+ /// assuming that the initial '(' characters have already been consumed.
+ ///
+ /// \param ParenDepth - Specifies how many trailing expressions outside the
+ /// current parentheses we have to parse.
+ /// \param Res - The value of the expression. The result is undefined
+ /// on error.
+ /// \return - False on success.
+ virtual bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
+ SMLoc &EndLoc) = 0;
+};
+
+/// Create an MCAsmParser instance.
+MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &,
+ const MCAsmInfo &, unsigned CB = 0);
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCPARSER_MCASMPARSER_H
diff --git a/clang-r353983/include/llvm/MC/MCParser/MCAsmParserExtension.h b/clang-r353983/include/llvm/MC/MCParser/MCAsmParserExtension.h
new file mode 100644
index 00000000..5d2afe81
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCParser/MCAsmParserExtension.h
@@ -0,0 +1,120 @@
+//===- llvm/MC/MCAsmParserExtension.h - Asm Parser Hooks --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
+#define LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/Support/SMLoc.h"
+
+namespace llvm {
+
+class Twine;
+
+/// Generic interface for extending the MCAsmParser,
+/// which is implemented by target and object file assembly parser
+/// implementations.
+class MCAsmParserExtension {
+ MCAsmParser *Parser;
+
+protected:
+ MCAsmParserExtension();
+
+ // Helper template for implementing static dispatch functions.
+ template<typename T, bool (T::*Handler)(StringRef, SMLoc)>
+ static bool HandleDirective(MCAsmParserExtension *Target,
+ StringRef Directive,
+ SMLoc DirectiveLoc) {
+ T *Obj = static_cast<T*>(Target);
+ return (Obj->*Handler)(Directive, DirectiveLoc);
+ }
+
+ bool BracketExpressionsSupported = false;
+
+public:
+ MCAsmParserExtension(const MCAsmParserExtension &) = delete;
+ MCAsmParserExtension &operator=(const MCAsmParserExtension &) = delete;
+ virtual ~MCAsmParserExtension();
+
+ /// Initialize the extension for parsing using the given \p Parser.
+ /// The extension should use the AsmParser interfaces to register its
+ /// parsing routines.
+ virtual void Initialize(MCAsmParser &Parser);
+
+ /// \name MCAsmParser Proxy Interfaces
+ /// @{
+
+ MCContext &getContext() { return getParser().getContext(); }
+
+ MCAsmLexer &getLexer() { return getParser().getLexer(); }
+ const MCAsmLexer &getLexer() const {
+ return const_cast<MCAsmParserExtension *>(this)->getLexer();
+ }
+
+ MCAsmParser &getParser() { return *Parser; }
+ const MCAsmParser &getParser() const {
+ return const_cast<MCAsmParserExtension*>(this)->getParser();
+ }
+
+ SourceMgr &getSourceManager() { return getParser().getSourceManager(); }
+ MCStreamer &getStreamer() { return getParser().getStreamer(); }
+
+ bool Warning(SMLoc L, const Twine &Msg) {
+ return getParser().Warning(L, Msg);
+ }
+
+ bool Error(SMLoc L, const Twine &Msg, SMRange Range = SMRange()) {
+ return getParser().Error(L, Msg, Range);
+ }
+
+ void Note(SMLoc L, const Twine &Msg) {
+ getParser().Note(L, Msg);
+ }
+
+ bool TokError(const Twine &Msg) {
+ return getParser().TokError(Msg);
+ }
+
+ const AsmToken &Lex() { return getParser().Lex(); }
+ const AsmToken &getTok() { return getParser().getTok(); }
+ bool parseToken(AsmToken::TokenKind T,
+ const Twine &Msg = "unexpected token") {
+ return getParser().parseToken(T, Msg);
+ }
+
+ bool parseMany(function_ref<bool()> parseOne, bool hasComma = true) {
+ return getParser().parseMany(parseOne, hasComma);
+ }
+
+ bool parseOptionalToken(AsmToken::TokenKind T) {
+ return getParser().parseOptionalToken(T);
+ }
+
+ bool check(bool P, const Twine &Msg) {
+ return getParser().check(P, Msg);
+ }
+
+ bool check(bool P, SMLoc Loc, const Twine &Msg) {
+ return getParser().check(P, Loc, Msg);
+ }
+
+ bool addErrorSuffix(const Twine &Suffix) {
+ return getParser().addErrorSuffix(Suffix);
+ }
+
+ bool HasBracketExpressions() const { return BracketExpressionsSupported; }
+
+ /// @}
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
diff --git a/clang-r353983/include/llvm/MC/MCParser/MCAsmParserUtils.h b/clang-r353983/include/llvm/MC/MCParser/MCAsmParserUtils.h
new file mode 100644
index 00000000..d692da74
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCParser/MCAsmParserUtils.h
@@ -0,0 +1,33 @@
+//===- llvm/MC/MCAsmParserUtils.h - Asm Parser Utilities --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCPARSER_MCASMPARSERUTILS_H
+#define LLVM_MC_MCPARSER_MCASMPARSERUTILS_H
+
+namespace llvm {
+
+class MCAsmParser;
+class MCExpr;
+class MCSymbol;
+class StringRef;
+
+namespace MCParserUtils {
+
+/// Parse a value expression and return whether it can be assigned to a symbol
+/// with the given name.
+///
+/// On success, returns false and sets the Symbol and Value output parameters.
+bool parseAssignmentExpression(StringRef Name, bool allow_redef,
+ MCAsmParser &Parser, MCSymbol *&Symbol,
+ const MCExpr *&Value);
+
+} // namespace MCParserUtils
+
+} // namespace llvm
+
+#endif // LLVM_MC_MCPARSER_MCASMPARSERUTILS_H
diff --git a/clang-r353983/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/clang-r353983/include/llvm/MC/MCParser/MCParsedAsmOperand.h
new file mode 100644
index 00000000..2b6e2aa4
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCParser/MCParsedAsmOperand.h
@@ -0,0 +1,99 @@
+//===- llvm/MC/MCParsedAsmOperand.h - Asm Parser Operand --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H
+#define LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SMLoc.h"
+#include <string>
+
+namespace llvm {
+
+class raw_ostream;
+
+/// MCParsedAsmOperand - This abstract class represents a source-level assembly
+/// instruction operand. It should be subclassed by target-specific code. This
+/// base class is used by target-independent clients and is the interface
+/// between parsing an asm instruction and recognizing it.
+class MCParsedAsmOperand {
+ /// MCOperandNum - The corresponding MCInst operand number. Only valid when
+ /// parsing MS-style inline assembly.
+ unsigned MCOperandNum;
+
+ /// Constraint - The constraint on this operand. Only valid when parsing
+ /// MS-style inline assembly.
+ std::string Constraint;
+
+protected:
+ // This only seems to need to be movable (by ARMOperand) but ARMOperand has
+ // lots of members and MSVC doesn't support defaulted move ops, so to avoid
+ // that verbosity, just rely on defaulted copy ops. It's only the Constraint
+ // string member that would benefit from movement anyway.
+ MCParsedAsmOperand() = default;
+ MCParsedAsmOperand(const MCParsedAsmOperand &RHS) = default;
+ MCParsedAsmOperand &operator=(const MCParsedAsmOperand &) = default;
+
+public:
+ virtual ~MCParsedAsmOperand() = default;
+
+ void setConstraint(StringRef C) { Constraint = C.str(); }
+ StringRef getConstraint() { return Constraint; }
+
+ void setMCOperandNum (unsigned OpNum) { MCOperandNum = OpNum; }
+ unsigned getMCOperandNum() { return MCOperandNum; }
+
+ virtual StringRef getSymName() { return StringRef(); }
+ virtual void *getOpDecl() { return nullptr; }
+
+ /// isToken - Is this a token operand?
+ virtual bool isToken() const = 0;
+ /// isImm - Is this an immediate operand?
+ virtual bool isImm() const = 0;
+ /// isReg - Is this a register operand?
+ virtual bool isReg() const = 0;
+ virtual unsigned getReg() const = 0;
+
+ /// isMem - Is this a memory operand?
+ virtual bool isMem() const = 0;
+
+ /// getStartLoc - Get the location of the first token of this operand.
+ virtual SMLoc getStartLoc() const = 0;
+ /// getEndLoc - Get the location of the last token of this operand.
+ virtual SMLoc getEndLoc() const = 0;
+
+ /// needAddressOf - Do we need to emit code to get the address of the
+ /// variable/label? Only valid when parsing MS-style inline assembly.
+ virtual bool needAddressOf() const { return false; }
+
+ /// isOffsetOf - Do we need to emit code to get the offset of the variable,
+ /// rather then the value of the variable? Only valid when parsing MS-style
+ /// inline assembly.
+ virtual bool isOffsetOf() const { return false; }
+
+ /// getOffsetOfLoc - Get the location of the offset operator.
+ virtual SMLoc getOffsetOfLoc() const { return SMLoc(); }
+
+ /// print - Print a debug representation of the operand to the given stream.
+ virtual void print(raw_ostream &OS) const = 0;
+
+ /// dump - Print to the debug stream.
+ virtual void dump() const;
+};
+
+//===----------------------------------------------------------------------===//
+// Debugging Support
+
+inline raw_ostream& operator<<(raw_ostream &OS, const MCParsedAsmOperand &MO) {
+ MO.print(OS);
+ return OS;
+}
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H
diff --git a/clang-r353983/include/llvm/MC/MCParser/MCTargetAsmParser.h b/clang-r353983/include/llvm/MC/MCParser/MCTargetAsmParser.h
new file mode 100644
index 00000000..c5683b74
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCParser/MCTargetAsmParser.h
@@ -0,0 +1,499 @@
+//===- llvm/MC/MCTargetAsmParser.h - Target Assembly Parser -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCPARSER_MCTARGETASMPARSER_H
+#define LLVM_MC_MCPARSER_MCTARGETASMPARSER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
+#include "llvm/MC/MCParser/MCAsmParserExtension.h"
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Support/SMLoc.h"
+#include <cstdint>
+#include <memory>
+
+namespace llvm {
+
+class MCInst;
+class MCParsedAsmOperand;
+class MCStreamer;
+class MCSubtargetInfo;
+template <typename T> class SmallVectorImpl;
+
+using OperandVector = SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>>;
+
+enum AsmRewriteKind {
+ AOK_Align, // Rewrite align as .align.
+ AOK_EVEN, // Rewrite even as .even.
+ AOK_Emit, // Rewrite _emit as .byte.
+ AOK_Input, // Rewrite in terms of $N.
+ AOK_Output, // Rewrite in terms of $N.
+ AOK_SizeDirective, // Add a sizing directive (e.g., dword ptr).
+ AOK_Label, // Rewrite local labels.
+ AOK_EndOfStatement, // Add EndOfStatement (e.g., "\n\t").
+ AOK_Skip, // Skip emission (e.g., offset/type operators).
+ AOK_IntelExpr // SizeDirective SymDisp [BaseReg + IndexReg * Scale + ImmDisp]
+};
+
+const char AsmRewritePrecedence [] = {
+ 2, // AOK_Align
+ 2, // AOK_EVEN
+ 2, // AOK_Emit
+ 3, // AOK_Input
+ 3, // AOK_Output
+ 5, // AOK_SizeDirective
+ 1, // AOK_Label
+ 5, // AOK_EndOfStatement
+ 2, // AOK_Skip
+ 2 // AOK_IntelExpr
+};
+
+// Represnt the various parts which makes up an intel expression,
+// used for emitting compound intel expressions
+struct IntelExpr {
+ bool NeedBracs;
+ int64_t Imm;
+ StringRef BaseReg;
+ StringRef IndexReg;
+ unsigned Scale;
+
+ IntelExpr(bool needBracs = false) : NeedBracs(needBracs), Imm(0),
+ BaseReg(StringRef()), IndexReg(StringRef()),
+ Scale(1) {}
+ // Compund immediate expression
+ IntelExpr(int64_t imm, bool needBracs) : IntelExpr(needBracs) {
+ Imm = imm;
+ }
+ // [Reg + ImmediateExpression]
+ // We don't bother to emit an immediate expression evaluated to zero
+ IntelExpr(StringRef reg, int64_t imm = 0, unsigned scale = 0,
+ bool needBracs = true) :
+ IntelExpr(imm, needBracs) {
+ IndexReg = reg;
+ if (scale)
+ Scale = scale;
+ }
+ // [BaseReg + IndexReg * ScaleExpression + ImmediateExpression]
+ IntelExpr(StringRef baseReg, StringRef indexReg, unsigned scale = 0,
+ int64_t imm = 0, bool needBracs = true) :
+ IntelExpr(indexReg, imm, scale, needBracs) {
+ BaseReg = baseReg;
+ }
+ bool hasBaseReg() const {
+ return BaseReg.size();
+ }
+ bool hasIndexReg() const {
+ return IndexReg.size();
+ }
+ bool hasRegs() const {
+ return hasBaseReg() || hasIndexReg();
+ }
+ bool isValid() const {
+ return (Scale == 1) ||
+ (hasIndexReg() && (Scale == 2 || Scale == 4 || Scale == 8));
+ }
+};
+
+struct AsmRewrite {
+ AsmRewriteKind Kind;
+ SMLoc Loc;
+ unsigned Len;
+ int64_t Val;
+ StringRef Label;
+ IntelExpr IntelExp;
+
+public:
+ AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len = 0, int64_t val = 0)
+ : Kind(kind), Loc(loc), Len(len), Val(val) {}
+ AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len, StringRef label)
+ : AsmRewrite(kind, loc, len) { Label = label; }
+ AsmRewrite(SMLoc loc, unsigned len, IntelExpr exp)
+ : AsmRewrite(AOK_IntelExpr, loc, len) { IntelExp = exp; }
+};
+
+struct ParseInstructionInfo {
+ SmallVectorImpl<AsmRewrite> *AsmRewrites = nullptr;
+
+ ParseInstructionInfo() = default;
+ ParseInstructionInfo(SmallVectorImpl<AsmRewrite> *rewrites)
+ : AsmRewrites(rewrites) {}
+};
+
+enum OperandMatchResultTy {
+ MatchOperand_Success, // operand matched successfully
+ MatchOperand_NoMatch, // operand did not match
+ MatchOperand_ParseFail // operand matched but had errors
+};
+
+enum class DiagnosticPredicateTy {
+ Match,
+ NearMatch,
+ NoMatch,
+};
+
+// When an operand is parsed, the assembler will try to iterate through a set of
+// possible operand classes that the operand might match and call the
+// corresponding PredicateMethod to determine that.
+//
+// If there are two AsmOperands that would give a specific diagnostic if there
+// is no match, there is currently no mechanism to distinguish which operand is
+// a closer match. The DiagnosticPredicate distinguishes between 'completely
+// no match' and 'near match', so the assembler can decide whether to give a
+// specific diagnostic, or use 'InvalidOperand' and continue to find a
+// 'better matching' diagnostic.
+//
+// For example:
+// opcode opnd0, onpd1, opnd2
+//
+// where:
+// opnd2 could be an 'immediate of range [-8, 7]'
+// opnd2 could be a 'register + shift/extend'.
+//
+// If opnd2 is a valid register, but with a wrong shift/extend suffix, it makes
+// little sense to give a diagnostic that the operand should be an immediate
+// in range [-8, 7].
+//
+// This is a light-weight alternative to the 'NearMissInfo' approach
+// below which collects *all* possible diagnostics. This alternative
+// is optional and fully backward compatible with existing
+// PredicateMethods that return a 'bool' (match or no match).
+struct DiagnosticPredicate {
+ DiagnosticPredicateTy Type;
+
+ explicit DiagnosticPredicate(bool Match)
+ : Type(Match ? DiagnosticPredicateTy::Match
+ : DiagnosticPredicateTy::NearMatch) {}
+ DiagnosticPredicate(DiagnosticPredicateTy T) : Type(T) {}
+ DiagnosticPredicate(const DiagnosticPredicate &) = default;
+
+ operator bool() const { return Type == DiagnosticPredicateTy::Match; }
+ bool isMatch() const { return Type == DiagnosticPredicateTy::Match; }
+ bool isNearMatch() const { return Type == DiagnosticPredicateTy::NearMatch; }
+ bool isNoMatch() const { return Type == DiagnosticPredicateTy::NoMatch; }
+};
+
+// When matching of an assembly instruction fails, there may be multiple
+// encodings that are close to being a match. It's often ambiguous which one
+// the programmer intended to use, so we want to report an error which mentions
+// each of these "near-miss" encodings. This struct contains information about
+// one such encoding, and why it did not match the parsed instruction.
+class NearMissInfo {
+public:
+ enum NearMissKind {
+ NoNearMiss,
+ NearMissOperand,
+ NearMissFeature,
+ NearMissPredicate,
+ NearMissTooFewOperands,
+ };
+
+ // The encoding is valid for the parsed assembly string. This is only used
+ // internally to the table-generated assembly matcher.
+ static NearMissInfo getSuccess() { return NearMissInfo(); }
+
+ // The instruction encoding is not valid because it requires some target
+ // features that are not currently enabled. MissingFeatures has a bit set for
+ // each feature that the encoding needs but which is not enabled.
+ static NearMissInfo getMissedFeature(uint64_t MissingFeatures) {
+ NearMissInfo Result;
+ Result.Kind = NearMissFeature;
+ Result.Features = MissingFeatures;
+ return Result;
+ }
+
+ // The instruction encoding is not valid because the target-specific
+ // predicate function returned an error code. FailureCode is the
+ // target-specific error code returned by the predicate.
+ static NearMissInfo getMissedPredicate(unsigned FailureCode) {
+ NearMissInfo Result;
+ Result.Kind = NearMissPredicate;
+ Result.PredicateError = FailureCode;
+ return Result;
+ }
+
+ // The instruction encoding is not valid because one (and only one) parsed
+ // operand is not of the correct type. OperandError is the error code
+ // relating to the operand class expected by the encoding. OperandClass is
+ // the type of the expected operand. Opcode is the opcode of the encoding.
+ // OperandIndex is the index into the parsed operand list.
+ static NearMissInfo getMissedOperand(unsigned OperandError,
+ unsigned OperandClass, unsigned Opcode,
+ unsigned OperandIndex) {
+ NearMissInfo Result;
+ Result.Kind = NearMissOperand;
+ Result.MissedOperand.Error = OperandError;
+ Result.MissedOperand.Class = OperandClass;
+ Result.MissedOperand.Opcode = Opcode;
+ Result.MissedOperand.Index = OperandIndex;
+ return Result;
+ }
+
+ // The instruction encoding is not valid because it expects more operands
+ // than were parsed. OperandClass is the class of the expected operand that
+ // was not provided. Opcode is the instruction encoding.
+ static NearMissInfo getTooFewOperands(unsigned OperandClass,
+ unsigned Opcode) {
+ NearMissInfo Result;
+ Result.Kind = NearMissTooFewOperands;
+ Result.TooFewOperands.Class = OperandClass;
+ Result.TooFewOperands.Opcode = Opcode;
+ return Result;
+ }
+
+ operator bool() const { return Kind != NoNearMiss; }
+
+ NearMissKind getKind() const { return Kind; }
+
+ // Feature flags required by the instruction, that the current target does
+ // not have.
+ uint64_t getFeatures() const {
+ assert(Kind == NearMissFeature);
+ return Features;
+ }
+ // Error code returned by the target predicate when validating this
+ // instruction encoding.
+ unsigned getPredicateError() const {
+ assert(Kind == NearMissPredicate);
+ return PredicateError;
+ }
+ // MatchClassKind of the operand that we expected to see.
+ unsigned getOperandClass() const {
+ assert(Kind == NearMissOperand || Kind == NearMissTooFewOperands);
+ return MissedOperand.Class;
+ }
+ // Opcode of the encoding we were trying to match.
+ unsigned getOpcode() const {
+ assert(Kind == NearMissOperand || Kind == NearMissTooFewOperands);
+ return MissedOperand.Opcode;
+ }
+ // Error code returned when validating the operand.
+ unsigned getOperandError() const {
+ assert(Kind == NearMissOperand);
+ return MissedOperand.Error;
+ }
+ // Index of the actual operand we were trying to match in the list of parsed
+ // operands.
+ unsigned getOperandIndex() const {
+ assert(Kind == NearMissOperand);
+ return MissedOperand.Index;
+ }
+
+private:
+ NearMissKind Kind;
+
+ // These two structs share a common prefix, so we can safely rely on the fact
+ // that they overlap in the union.
+ struct MissedOpInfo {
+ unsigned Class;
+ unsigned Opcode;
+ unsigned Error;
+ unsigned Index;
+ };
+
+ struct TooFewOperandsInfo {
+ unsigned Class;
+ unsigned Opcode;
+ };
+
+ union {
+ uint64_t Features;
+ unsigned PredicateError;
+ MissedOpInfo MissedOperand;
+ TooFewOperandsInfo TooFewOperands;
+ };
+
+ NearMissInfo() : Kind(NoNearMiss) {}
+};
+
+/// MCTargetAsmParser - Generic interface to target specific assembly parsers.
+class MCTargetAsmParser : public MCAsmParserExtension {
+public:
+ enum MatchResultTy {
+ Match_InvalidOperand,
+ Match_InvalidTiedOperand,
+ Match_MissingFeature,
+ Match_MnemonicFail,
+ Match_Success,
+ Match_NearMisses,
+ FIRST_TARGET_MATCH_RESULT_TY
+ };
+
+protected: // Can only create subclasses.
+ MCTargetAsmParser(MCTargetOptions const &, const MCSubtargetInfo &STI,
+ const MCInstrInfo &MII);
+
+ /// Create a copy of STI and return a non-const reference to it.
+ MCSubtargetInfo &copySTI();
+
+ /// AvailableFeatures - The current set of available features.
+ uint64_t AvailableFeatures = 0;
+
+ /// ParsingInlineAsm - Are we parsing ms-style inline assembly?
+ bool ParsingInlineAsm = false;
+
+ /// SemaCallback - The Sema callback implementation. Must be set when parsing
+ /// ms-style inline assembly.
+ MCAsmParserSemaCallback *SemaCallback;
+
+ /// Set of options which affects instrumentation of inline assembly.
+ MCTargetOptions MCOptions;
+
+ /// Current STI.
+ const MCSubtargetInfo *STI;
+
+ const MCInstrInfo &MII;
+
+public:
+ MCTargetAsmParser(const MCTargetAsmParser &) = delete;
+ MCTargetAsmParser &operator=(const MCTargetAsmParser &) = delete;
+
+ ~MCTargetAsmParser() override;
+
+ const MCSubtargetInfo &getSTI() const;
+
+ uint64_t getAvailableFeatures() const { return AvailableFeatures; }
+ void setAvailableFeatures(uint64_t Value) { AvailableFeatures = Value; }
+
+ bool isParsingInlineAsm () { return ParsingInlineAsm; }
+ void setParsingInlineAsm (bool Value) { ParsingInlineAsm = Value; }
+
+ MCTargetOptions getTargetOptions() const { return MCOptions; }
+
+ void setSemaCallback(MCAsmParserSemaCallback *Callback) {
+ SemaCallback = Callback;
+ }
+
+ // Target-specific parsing of expression.
+ virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
+ return getParser().parsePrimaryExpr(Res, EndLoc);
+ }
+
+ virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
+ SMLoc &EndLoc) = 0;
+
+ /// Sets frame register corresponding to the current MachineFunction.
+ virtual void SetFrameRegister(unsigned RegNo) {}
+
+ /// ParseInstruction - Parse one assembly instruction.
+ ///
+ /// The parser is positioned following the instruction name. The target
+ /// specific instruction parser should parse the entire instruction and
+ /// construct the appropriate MCInst, or emit an error. On success, the entire
+ /// line should be parsed up to and including the end-of-statement token. On
+ /// failure, the parser is not required to read to the end of the line.
+ //
+ /// \param Name - The instruction name.
+ /// \param NameLoc - The source location of the name.
+ /// \param Operands [out] - The list of parsed operands, this returns
+ /// ownership of them to the caller.
+ /// \return True on failure.
+ virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
+ SMLoc NameLoc, OperandVector &Operands) = 0;
+ virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
+ AsmToken Token, OperandVector &Operands) {
+ return ParseInstruction(Info, Name, Token.getLoc(), Operands);
+ }
+
+ /// ParseDirective - Parse a target specific assembler directive
+ ///
+ /// The parser is positioned following the directive name. The target
+ /// specific directive parser should parse the entire directive doing or
+ /// recording any target specific work, or return true and do nothing if the
+ /// directive is not target specific. If the directive is specific for
+ /// the target, the entire line is parsed up to and including the
+ /// end-of-statement token and false is returned.
+ ///
+ /// \param DirectiveID - the identifier token of the directive.
+ virtual bool ParseDirective(AsmToken DirectiveID) = 0;
+
+ /// MatchAndEmitInstruction - Recognize a series of operands of a parsed
+ /// instruction as an actual MCInst and emit it to the specified MCStreamer.
+ /// This returns false on success and returns true on failure to match.
+ ///
+ /// On failure, the target parser is responsible for emitting a diagnostic
+ /// explaining the match failure.
+ virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
+ OperandVector &Operands, MCStreamer &Out,
+ uint64_t &ErrorInfo,
+ bool MatchingInlineAsm) = 0;
+
+ /// Allows targets to let registers opt out of clobber lists.
+ virtual bool OmitRegisterFromClobberLists(unsigned RegNo) { return false; }
+
+ /// Allow a target to add special case operand matching for things that
+ /// tblgen doesn't/can't handle effectively. For example, literal
+ /// immediates on ARM. TableGen expects a token operand, but the parser
+ /// will recognize them as immediates.
+ virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
+ unsigned Kind) {
+ return Match_InvalidOperand;
+ }
+
+ /// Validate the instruction match against any complex target predicates
+ /// before rendering any operands to it.
+ virtual unsigned
+ checkEarlyTargetMatchPredicate(MCInst &Inst, const OperandVector &Operands) {
+ return Match_Success;
+ }
+
+ /// checkTargetMatchPredicate - Validate the instruction match against
+ /// any complex target predicates not expressible via match classes.
+ virtual unsigned checkTargetMatchPredicate(MCInst &Inst) {
+ return Match_Success;
+ }
+
+ virtual void convertToMapAndConstraints(unsigned Kind,
+ const OperandVector &Operands) = 0;
+
+ /// Returns whether two registers are equal and is used by the tied-operands
+ /// checks in the AsmMatcher. This method can be overridden allow e.g. a
+ /// sub- or super-register as the tied operand.
+ virtual bool regsEqual(const MCParsedAsmOperand &Op1,
+ const MCParsedAsmOperand &Op2) const {
+ assert(Op1.isReg() && Op2.isReg() && "Operands not all regs");
+ return Op1.getReg() == Op2.getReg();
+ }
+
+ // Return whether this parser uses assignment statements with equals tokens
+ virtual bool equalIsAsmAssignment() { return true; };
+ // Return whether this start of statement identifier is a label
+ virtual bool isLabel(AsmToken &Token) { return true; };
+ // Return whether this parser accept star as start of statement
+ virtual bool starIsStartOfStatement() { return false; };
+
+ virtual const MCExpr *applyModifierToExpr(const MCExpr *E,
+ MCSymbolRefExpr::VariantKind,
+ MCContext &Ctx) {
+ return nullptr;
+ }
+
+ // For actions that have to be performed before a label is emitted
+ virtual void doBeforeLabelEmit(MCSymbol *Symbol) {}
+
+ virtual void onLabelParsed(MCSymbol *Symbol) {}
+
+ /// Ensure that all previously parsed instructions have been emitted to the
+ /// output streamer, if the target does not emit them immediately.
+ virtual void flushPendingInstructions(MCStreamer &Out) {}
+
+ virtual const MCExpr *createTargetUnaryExpr(const MCExpr *E,
+ AsmToken::TokenKind OperatorToken,
+ MCContext &Ctx) {
+ return nullptr;
+ }
+
+ // For any checks or cleanups at the end of parsing.
+ virtual void onEndOfFile() {}
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCPARSER_MCTARGETASMPARSER_H
diff --git a/clang-r353983/include/llvm/MC/MCRegisterInfo.h b/clang-r353983/include/llvm/MC/MCRegisterInfo.h
new file mode 100644
index 00000000..92d39c3f
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCRegisterInfo.h
@@ -0,0 +1,727 @@
+//===- MC/MCRegisterInfo.h - Target Register Description --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes an abstract interface used to get information about a
+// target machines register file. This information is used for a variety of
+// purposed, especially register allocation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCREGISTERINFO_H
+#define LLVM_MC_MCREGISTERINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/MC/LaneBitmask.h"
+#include <cassert>
+#include <cstdint>
+#include <utility>
+
+namespace llvm {
+
+/// An unsigned integer type large enough to represent all physical registers,
+/// but not necessarily virtual registers.
+using MCPhysReg = uint16_t;
+
+/// MCRegisterClass - Base class of TargetRegisterClass.
+class MCRegisterClass {
+public:
+ using iterator = const MCPhysReg*;
+ using const_iterator = const MCPhysReg*;
+
+ const iterator RegsBegin;
+ const uint8_t *const RegSet;
+ const uint32_t NameIdx;
+ const uint16_t RegsSize;
+ const uint16_t RegSetSize;
+ const uint16_t ID;
+ const int8_t CopyCost;
+ const bool Allocatable;
+
+ /// getID() - Return the register class ID number.
+ ///
+ unsigned getID() const { return ID; }
+
+ /// begin/end - Return all of the registers in this class.
+ ///
+ iterator begin() const { return RegsBegin; }
+ iterator end() const { return RegsBegin + RegsSize; }
+
+ /// getNumRegs - Return the number of registers in this class.
+ ///
+ unsigned getNumRegs() const { return RegsSize; }
+
+ /// getRegister - Return the specified register in the class.
+ ///
+ unsigned getRegister(unsigned i) const {
+ assert(i < getNumRegs() && "Register number out of range!");
+ return RegsBegin[i];
+ }
+
+ /// contains - Return true if the specified register is included in this
+ /// register class. This does not include virtual registers.
+ bool contains(unsigned Reg) const {
+ unsigned InByte = Reg % 8;
+ unsigned Byte = Reg / 8;
+ if (Byte >= RegSetSize)
+ return false;
+ return (RegSet[Byte] & (1 << InByte)) != 0;
+ }
+
+ /// contains - Return true if both registers are in this class.
+ bool contains(unsigned Reg1, unsigned Reg2) const {
+ return contains(Reg1) && contains(Reg2);
+ }
+
+ /// getCopyCost - Return the cost of copying a value between two registers in
+ /// this class. A negative number means the register class is very expensive
+ /// to copy e.g. status flag register classes.
+ int getCopyCost() const { return CopyCost; }
+
+ /// isAllocatable - Return true if this register class may be used to create
+ /// virtual registers.
+ bool isAllocatable() const { return Allocatable; }
+};
+
+/// MCRegisterDesc - This record contains information about a particular
+/// register. The SubRegs field is a zero terminated array of registers that
+/// are sub-registers of the specific register, e.g. AL, AH are sub-registers
+/// of AX. The SuperRegs field is a zero terminated array of registers that are
+/// super-registers of the specific register, e.g. RAX, EAX, are
+/// super-registers of AX.
+///
+struct MCRegisterDesc {
+ uint32_t Name; // Printable name for the reg (for debugging)
+ uint32_t SubRegs; // Sub-register set, described above
+ uint32_t SuperRegs; // Super-register set, described above
+
+ // Offset into MCRI::SubRegIndices of a list of sub-register indices for each
+ // sub-register in SubRegs.
+ uint32_t SubRegIndices;
+
+ // RegUnits - Points to the list of register units. The low 4 bits holds the
+ // Scale, the high bits hold an offset into DiffLists. See MCRegUnitIterator.
+ uint32_t RegUnits;
+
+ /// Index into list with lane mask sequences. The sequence contains a lanemask
+ /// for every register unit.
+ uint16_t RegUnitLaneMasks;
+};
+
+/// MCRegisterInfo base class - We assume that the target defines a static
+/// array of MCRegisterDesc objects that represent all of the machine
+/// registers that the target has. As such, we simply have to track a pointer
+/// to this array so that we can turn register number into a register
+/// descriptor.
+///
+/// Note this class is designed to be a base class of TargetRegisterInfo, which
+/// is the interface used by codegen. However, specific targets *should never*
+/// specialize this class. MCRegisterInfo should only contain getters to access
+/// TableGen generated physical register data. It must not be extended with
+/// virtual methods.
+///
+class MCRegisterInfo {
+public:
+ using regclass_iterator = const MCRegisterClass *;
+
+ /// DwarfLLVMRegPair - Emitted by tablegen so Dwarf<->LLVM reg mappings can be
+ /// performed with a binary search.
+ struct DwarfLLVMRegPair {
+ unsigned FromReg;
+ unsigned ToReg;
+
+ bool operator<(DwarfLLVMRegPair RHS) const { return FromReg < RHS.FromReg; }
+ };
+
+ /// SubRegCoveredBits - Emitted by tablegen: bit range covered by a subreg
+ /// index, -1 in any being invalid.
+ struct SubRegCoveredBits {
+ uint16_t Offset;
+ uint16_t Size;
+ };
+
+private:
+ const MCRegisterDesc *Desc; // Pointer to the descriptor array
+ unsigned NumRegs; // Number of entries in the array
+ unsigned RAReg; // Return address register
+ unsigned PCReg; // Program counter register
+ const MCRegisterClass *Classes; // Pointer to the regclass array
+ unsigned NumClasses; // Number of entries in the array
+ unsigned NumRegUnits; // Number of regunits.
+ const MCPhysReg (*RegUnitRoots)[2]; // Pointer to regunit root table.
+ const MCPhysReg *DiffLists; // Pointer to the difflists array
+ const LaneBitmask *RegUnitMaskSequences; // Pointer to lane mask sequences
+ // for register units.
+ const char *RegStrings; // Pointer to the string table.
+ const char *RegClassStrings; // Pointer to the class strings.
+ const uint16_t *SubRegIndices; // Pointer to the subreg lookup
+ // array.
+ const SubRegCoveredBits *SubRegIdxRanges; // Pointer to the subreg covered
+ // bit ranges array.
+ unsigned NumSubRegIndices; // Number of subreg indices.
+ const uint16_t *RegEncodingTable; // Pointer to array of register
+ // encodings.
+
+ unsigned L2DwarfRegsSize;
+ unsigned EHL2DwarfRegsSize;
+ unsigned Dwarf2LRegsSize;
+ unsigned EHDwarf2LRegsSize;
+ const DwarfLLVMRegPair *L2DwarfRegs; // LLVM to Dwarf regs mapping
+ const DwarfLLVMRegPair *EHL2DwarfRegs; // LLVM to Dwarf regs mapping EH
+ const DwarfLLVMRegPair *Dwarf2LRegs; // Dwarf to LLVM regs mapping
+ const DwarfLLVMRegPair *EHDwarf2LRegs; // Dwarf to LLVM regs mapping EH
+ DenseMap<unsigned, int> L2SEHRegs; // LLVM to SEH regs mapping
+ DenseMap<unsigned, int> L2CVRegs; // LLVM to CV regs mapping
+
+public:
+ /// DiffListIterator - Base iterator class that can traverse the
+ /// differentially encoded register and regunit lists in DiffLists.
+ /// Don't use this class directly, use one of the specialized sub-classes
+ /// defined below.
+ class DiffListIterator {
+ uint16_t Val = 0;
+ const MCPhysReg *List = nullptr;
+
+ protected:
+ /// Create an invalid iterator. Call init() to point to something useful.
+ DiffListIterator() = default;
+
+ /// init - Point the iterator to InitVal, decoding subsequent values from
+ /// DiffList. The iterator will initially point to InitVal, sub-classes are
+ /// responsible for skipping the seed value if it is not part of the list.
+ void init(MCPhysReg InitVal, const MCPhysReg *DiffList) {
+ Val = InitVal;
+ List = DiffList;
+ }
+
+ /// advance - Move to the next list position, return the applied
+ /// differential. This function does not detect the end of the list, that
+ /// is the caller's responsibility (by checking for a 0 return value).
+ unsigned advance() {
+ assert(isValid() && "Cannot move off the end of the list.");
+ MCPhysReg D = *List++;
+ Val += D;
+ return D;
+ }
+
+ public:
+ /// isValid - returns true if this iterator is not yet at the end.
+ bool isValid() const { return List; }
+
+ /// Dereference the iterator to get the value at the current position.
+ unsigned operator*() const { return Val; }
+
+ /// Pre-increment to move to the next position.
+ void operator++() {
+ // The end of the list is encoded as a 0 differential.
+ if (!advance())
+ List = nullptr;
+ }
+ };
+
+ // These iterators are allowed to sub-class DiffListIterator and access
+ // internal list pointers.
+ friend class MCSubRegIterator;
+ friend class MCSubRegIndexIterator;
+ friend class MCSuperRegIterator;
+ friend class MCRegUnitIterator;
+ friend class MCRegUnitMaskIterator;
+ friend class MCRegUnitRootIterator;
+
+ /// Initialize MCRegisterInfo, called by TableGen
+ /// auto-generated routines. *DO NOT USE*.
+ void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA,
+ unsigned PC,
+ const MCRegisterClass *C, unsigned NC,
+ const MCPhysReg (*RURoots)[2],
+ unsigned NRU,
+ const MCPhysReg *DL,
+ const LaneBitmask *RUMS,
+ const char *Strings,
+ const char *ClassStrings,
+ const uint16_t *SubIndices,
+ unsigned NumIndices,
+ const SubRegCoveredBits *SubIdxRanges,
+ const uint16_t *RET) {
+ Desc = D;
+ NumRegs = NR;
+ RAReg = RA;
+ PCReg = PC;
+ Classes = C;
+ DiffLists = DL;
+ RegUnitMaskSequences = RUMS;
+ RegStrings = Strings;
+ RegClassStrings = ClassStrings;
+ NumClasses = NC;
+ RegUnitRoots = RURoots;
+ NumRegUnits = NRU;
+ SubRegIndices = SubIndices;
+ NumSubRegIndices = NumIndices;
+ SubRegIdxRanges = SubIdxRanges;
+ RegEncodingTable = RET;
+
+ // Initialize DWARF register mapping variables
+ EHL2DwarfRegs = nullptr;
+ EHL2DwarfRegsSize = 0;
+ L2DwarfRegs = nullptr;
+ L2DwarfRegsSize = 0;
+ EHDwarf2LRegs = nullptr;
+ EHDwarf2LRegsSize = 0;
+ Dwarf2LRegs = nullptr;
+ Dwarf2LRegsSize = 0;
+ }
+
+ /// Used to initialize LLVM register to Dwarf
+ /// register number mapping. Called by TableGen auto-generated routines.
+ /// *DO NOT USE*.
+ void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size,
+ bool isEH) {
+ if (isEH) {
+ EHL2DwarfRegs = Map;
+ EHL2DwarfRegsSize = Size;
+ } else {
+ L2DwarfRegs = Map;
+ L2DwarfRegsSize = Size;
+ }
+ }
+
+ /// Used to initialize Dwarf register to LLVM
+ /// register number mapping. Called by TableGen auto-generated routines.
+ /// *DO NOT USE*.
+ void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size,
+ bool isEH) {
+ if (isEH) {
+ EHDwarf2LRegs = Map;
+ EHDwarf2LRegsSize = Size;
+ } else {
+ Dwarf2LRegs = Map;
+ Dwarf2LRegsSize = Size;
+ }
+ }
+
+ /// mapLLVMRegToSEHReg - Used to initialize LLVM register to SEH register
+ /// number mapping. By default the SEH register number is just the same
+ /// as the LLVM register number.
+ /// FIXME: TableGen these numbers. Currently this requires target specific
+ /// initialization code.
+ void mapLLVMRegToSEHReg(unsigned LLVMReg, int SEHReg) {
+ L2SEHRegs[LLVMReg] = SEHReg;
+ }
+
+ void mapLLVMRegToCVReg(unsigned LLVMReg, int CVReg) {
+ L2CVRegs[LLVMReg] = CVReg;
+ }
+
+ /// This method should return the register where the return
+ /// address can be found.
+ unsigned getRARegister() const {
+ return RAReg;
+ }
+
+ /// Return the register which is the program counter.
+ unsigned getProgramCounter() const {
+ return PCReg;
+ }
+
+ const MCRegisterDesc &operator[](unsigned RegNo) const {
+ assert(RegNo < NumRegs &&
+ "Attempting to access record for invalid register number!");
+ return Desc[RegNo];
+ }
+
+ /// Provide a get method, equivalent to [], but more useful with a
+ /// pointer to this object.
+ const MCRegisterDesc &get(unsigned RegNo) const {
+ return operator[](RegNo);
+ }
+
+ /// Returns the physical register number of sub-register "Index"
+ /// for physical register RegNo. Return zero if the sub-register does not
+ /// exist.
+ unsigned getSubReg(unsigned Reg, unsigned Idx) const;
+
+ /// Return a super-register of the specified register
+ /// Reg so its sub-register of index SubIdx is Reg.
+ unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx,
+ const MCRegisterClass *RC) const;
+
+ /// For a given register pair, return the sub-register index
+ /// if the second register is a sub-register of the first. Return zero
+ /// otherwise.
+ unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const;
+
+ /// Get the size of the bit range covered by a sub-register index.
+ /// If the index isn't continuous, return the sum of the sizes of its parts.
+ /// If the index is used to access subregisters of different sizes, return -1.
+ unsigned getSubRegIdxSize(unsigned Idx) const;
+
+ /// Get the offset of the bit range covered by a sub-register index.
+ /// If an Offset doesn't make sense (the index isn't continuous, or is used to
+ /// access sub-registers at different offsets), return -1.
+ unsigned getSubRegIdxOffset(unsigned Idx) const;
+
+ /// Return the human-readable symbolic target-specific name for the
+ /// specified physical register.
+ const char *getName(unsigned RegNo) const {
+ return RegStrings + get(RegNo).Name;
+ }
+
+ /// Return the number of registers this target has (useful for
+ /// sizing arrays holding per register information)
+ unsigned getNumRegs() const {
+ return NumRegs;
+ }
+
+ /// Return the number of sub-register indices
+ /// understood by the target. Index 0 is reserved for the no-op sub-register,
+ /// while 1 to getNumSubRegIndices() - 1 represent real sub-registers.
+ unsigned getNumSubRegIndices() const {
+ return NumSubRegIndices;
+ }
+
+ /// Return the number of (native) register units in the
+ /// target. Register units are numbered from 0 to getNumRegUnits() - 1. They
+ /// can be accessed through MCRegUnitIterator defined below.
+ unsigned getNumRegUnits() const {
+ return NumRegUnits;
+ }
+
+ /// Map a target register to an equivalent dwarf register
+ /// number. Returns -1 if there is no equivalent value. The second
+ /// parameter allows targets to use different numberings for EH info and
+ /// debugging info.
+ int getDwarfRegNum(unsigned RegNum, bool isEH) const;
+
+ /// Map a dwarf register back to a target register.
+ int getLLVMRegNum(unsigned RegNum, bool isEH) const;
+
+ /// Map a DWARF EH register back to a target register (same as
+ /// getLLVMRegNum(RegNum, true)) but return -1 if there is no mapping,
+ /// rather than asserting that there must be one.
+ int getLLVMRegNumFromEH(unsigned RegNum) const;
+
+ /// Map a target EH register number to an equivalent DWARF register
+ /// number.
+ int getDwarfRegNumFromDwarfEHRegNum(unsigned RegNum) const;
+
+ /// Map a target register to an equivalent SEH register
+ /// number. Returns LLVM register number if there is no equivalent value.
+ int getSEHRegNum(unsigned RegNum) const;
+
+ /// Map a target register to an equivalent CodeView register
+ /// number.
+ int getCodeViewRegNum(unsigned RegNum) const;
+
+ regclass_iterator regclass_begin() const { return Classes; }
+ regclass_iterator regclass_end() const { return Classes+NumClasses; }
+ iterator_range<regclass_iterator> regclasses() const {
+ return make_range(regclass_begin(), regclass_end());
+ }
+
+ unsigned getNumRegClasses() const {
+ return (unsigned)(regclass_end()-regclass_begin());
+ }
+
+ /// Returns the register class associated with the enumeration
+ /// value. See class MCOperandInfo.
+ const MCRegisterClass& getRegClass(unsigned i) const {
+ assert(i < getNumRegClasses() && "Register Class ID out of range");
+ return Classes[i];
+ }
+
+ const char *getRegClassName(const MCRegisterClass *Class) const {
+ return RegClassStrings + Class->NameIdx;
+ }
+
+ /// Returns the encoding for RegNo
+ uint16_t getEncodingValue(unsigned RegNo) const {
+ assert(RegNo < NumRegs &&
+ "Attempting to get encoding for invalid register number!");
+ return RegEncodingTable[RegNo];
+ }
+
+ /// Returns true if RegB is a sub-register of RegA.
+ bool isSubRegister(unsigned RegA, unsigned RegB) const {
+ return isSuperRegister(RegB, RegA);
+ }
+
+ /// Returns true if RegB is a super-register of RegA.
+ bool isSuperRegister(unsigned RegA, unsigned RegB) const;
+
+ /// Returns true if RegB is a sub-register of RegA or if RegB == RegA.
+ bool isSubRegisterEq(unsigned RegA, unsigned RegB) const {
+ return isSuperRegisterEq(RegB, RegA);
+ }
+
+ /// Returns true if RegB is a super-register of RegA or if
+ /// RegB == RegA.
+ bool isSuperRegisterEq(unsigned RegA, unsigned RegB) const {
+ return RegA == RegB || isSuperRegister(RegA, RegB);
+ }
+
+ /// Returns true if RegB is a super-register or sub-register of RegA
+ /// or if RegB == RegA.
+ bool isSuperOrSubRegisterEq(unsigned RegA, unsigned RegB) const {
+ return isSubRegisterEq(RegA, RegB) || isSuperRegister(RegA, RegB);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Register List Iterators
+//===----------------------------------------------------------------------===//
+
+// MCRegisterInfo provides lists of super-registers, sub-registers, and
+// aliasing registers. Use these iterator classes to traverse the lists.
+
+/// MCSubRegIterator enumerates all sub-registers of Reg.
+/// If IncludeSelf is set, Reg itself is included in the list.
+class MCSubRegIterator : public MCRegisterInfo::DiffListIterator {
+public:
+ MCSubRegIterator(unsigned Reg, const MCRegisterInfo *MCRI,
+ bool IncludeSelf = false) {
+ init(Reg, MCRI->DiffLists + MCRI->get(Reg).SubRegs);
+ // Initially, the iterator points to Reg itself.
+ if (!IncludeSelf)
+ ++*this;
+ }
+};
+
+/// Iterator that enumerates the sub-registers of a Reg and the associated
+/// sub-register indices.
+class MCSubRegIndexIterator {
+ MCSubRegIterator SRIter;
+ const uint16_t *SRIndex;
+
+public:
+ /// Constructs an iterator that traverses subregisters and their
+ /// associated subregister indices.
+ MCSubRegIndexIterator(unsigned Reg, const MCRegisterInfo *MCRI)
+ : SRIter(Reg, MCRI) {
+ SRIndex = MCRI->SubRegIndices + MCRI->get(Reg).SubRegIndices;
+ }
+
+ /// Returns current sub-register.
+ unsigned getSubReg() const {
+ return *SRIter;
+ }
+
+ /// Returns sub-register index of the current sub-register.
+ unsigned getSubRegIndex() const {
+ return *SRIndex;
+ }
+
+ /// Returns true if this iterator is not yet at the end.
+ bool isValid() const { return SRIter.isValid(); }
+
+ /// Moves to the next position.
+ void operator++() {
+ ++SRIter;
+ ++SRIndex;
+ }
+};
+
+/// MCSuperRegIterator enumerates all super-registers of Reg.
+/// If IncludeSelf is set, Reg itself is included in the list.
+class MCSuperRegIterator : public MCRegisterInfo::DiffListIterator {
+public:
+ MCSuperRegIterator() = default;
+
+ MCSuperRegIterator(unsigned Reg, const MCRegisterInfo *MCRI,
+ bool IncludeSelf = false) {
+ init(Reg, MCRI->DiffLists + MCRI->get(Reg).SuperRegs);
+ // Initially, the iterator points to Reg itself.
+ if (!IncludeSelf)
+ ++*this;
+ }
+};
+
+// Definition for isSuperRegister. Put it down here since it needs the
+// iterator defined above in addition to the MCRegisterInfo class itself.
+inline bool MCRegisterInfo::isSuperRegister(unsigned RegA, unsigned RegB) const{
+ for (MCSuperRegIterator I(RegA, this); I.isValid(); ++I)
+ if (*I == RegB)
+ return true;
+ return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Register Units
+//===----------------------------------------------------------------------===//
+
+// Register units are used to compute register aliasing. Every register has at
+// least one register unit, but it can have more. Two registers overlap if and
+// only if they have a common register unit.
+//
+// A target with a complicated sub-register structure will typically have many
+// fewer register units than actual registers. MCRI::getNumRegUnits() returns
+// the number of register units in the target.
+
+// MCRegUnitIterator enumerates a list of register units for Reg. The list is
+// in ascending numerical order.
+class MCRegUnitIterator : public MCRegisterInfo::DiffListIterator {
+public:
+ /// MCRegUnitIterator - Create an iterator that traverses the register units
+ /// in Reg.
+ MCRegUnitIterator() = default;
+
+ MCRegUnitIterator(unsigned Reg, const MCRegisterInfo *MCRI) {
+ assert(Reg && "Null register has no regunits");
+ // Decode the RegUnits MCRegisterDesc field.
+ unsigned RU = MCRI->get(Reg).RegUnits;
+ unsigned Scale = RU & 15;
+ unsigned Offset = RU >> 4;
+
+ // Initialize the iterator to Reg * Scale, and the List pointer to
+ // DiffLists + Offset.
+ init(Reg * Scale, MCRI->DiffLists + Offset);
+
+ // That may not be a valid unit, we need to advance by one to get the real
+ // unit number. The first differential can be 0 which would normally
+ // terminate the list, but since we know every register has at least one
+ // unit, we can allow a 0 differential here.
+ advance();
+ }
+};
+
+/// MCRegUnitMaskIterator enumerates a list of register units and their
+/// associated lane masks for Reg. The register units are in ascending
+/// numerical order.
+class MCRegUnitMaskIterator {
+ MCRegUnitIterator RUIter;
+ const LaneBitmask *MaskListIter;
+
+public:
+ MCRegUnitMaskIterator() = default;
+
+ /// Constructs an iterator that traverses the register units and their
+ /// associated LaneMasks in Reg.
+ MCRegUnitMaskIterator(unsigned Reg, const MCRegisterInfo *MCRI)
+ : RUIter(Reg, MCRI) {
+ uint16_t Idx = MCRI->get(Reg).RegUnitLaneMasks;
+ MaskListIter = &MCRI->RegUnitMaskSequences[Idx];
+ }
+
+ /// Returns a (RegUnit, LaneMask) pair.
+ std::pair<unsigned,LaneBitmask> operator*() const {
+ return std::make_pair(*RUIter, *MaskListIter);
+ }
+
+ /// Returns true if this iterator is not yet at the end.
+ bool isValid() const { return RUIter.isValid(); }
+
+ /// Moves to the next position.
+ void operator++() {
+ ++MaskListIter;
+ ++RUIter;
+ }
+};
+
+// Each register unit has one or two root registers. The complete set of
+// registers containing a register unit is the union of the roots and their
+// super-registers. All registers aliasing Unit can be visited like this:
+//
+// for (MCRegUnitRootIterator RI(Unit, MCRI); RI.isValid(); ++RI) {
+// for (MCSuperRegIterator SI(*RI, MCRI, true); SI.isValid(); ++SI)
+// visit(*SI);
+// }
+
+/// MCRegUnitRootIterator enumerates the root registers of a register unit.
+class MCRegUnitRootIterator {
+ uint16_t Reg0 = 0;
+ uint16_t Reg1 = 0;
+
+public:
+ MCRegUnitRootIterator() = default;
+
+ MCRegUnitRootIterator(unsigned RegUnit, const MCRegisterInfo *MCRI) {
+ assert(RegUnit < MCRI->getNumRegUnits() && "Invalid register unit");
+ Reg0 = MCRI->RegUnitRoots[RegUnit][0];
+ Reg1 = MCRI->RegUnitRoots[RegUnit][1];
+ }
+
+ /// Dereference to get the current root register.
+ unsigned operator*() const {
+ return Reg0;
+ }
+
+ /// Check if the iterator is at the end of the list.
+ bool isValid() const {
+ return Reg0;
+ }
+
+ /// Preincrement to move to the next root register.
+ void operator++() {
+ assert(isValid() && "Cannot move off the end of the list.");
+ Reg0 = Reg1;
+ Reg1 = 0;
+ }
+};
+
+/// MCRegAliasIterator enumerates all registers aliasing Reg. If IncludeSelf is
+/// set, Reg itself is included in the list. This iterator does not guarantee
+/// any ordering or that entries are unique.
+class MCRegAliasIterator {
+private:
+ unsigned Reg;
+ const MCRegisterInfo *MCRI;
+ bool IncludeSelf;
+
+ MCRegUnitIterator RI;
+ MCRegUnitRootIterator RRI;
+ MCSuperRegIterator SI;
+
+public:
+ MCRegAliasIterator(unsigned Reg, const MCRegisterInfo *MCRI,
+ bool IncludeSelf)
+ : Reg(Reg), MCRI(MCRI), IncludeSelf(IncludeSelf) {
+ // Initialize the iterators.
+ for (RI = MCRegUnitIterator(Reg, MCRI); RI.isValid(); ++RI) {
+ for (RRI = MCRegUnitRootIterator(*RI, MCRI); RRI.isValid(); ++RRI) {
+ for (SI = MCSuperRegIterator(*RRI, MCRI, true); SI.isValid(); ++SI) {
+ if (!(!IncludeSelf && Reg == *SI))
+ return;
+ }
+ }
+ }
+ }
+
+ bool isValid() const { return RI.isValid(); }
+
+ unsigned operator*() const {
+ assert(SI.isValid() && "Cannot dereference an invalid iterator.");
+ return *SI;
+ }
+
+ void advance() {
+ // Assuming SI is valid.
+ ++SI;
+ if (SI.isValid()) return;
+
+ ++RRI;
+ if (RRI.isValid()) {
+ SI = MCSuperRegIterator(*RRI, MCRI, true);
+ return;
+ }
+
+ ++RI;
+ if (RI.isValid()) {
+ RRI = MCRegUnitRootIterator(*RI, MCRI);
+ SI = MCSuperRegIterator(*RRI, MCRI, true);
+ }
+ }
+
+ void operator++() {
+ assert(isValid() && "Cannot move off the end of the list.");
+ do advance();
+ while (!IncludeSelf && isValid() && *SI == Reg);
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCREGISTERINFO_H
diff --git a/clang-r353983/include/llvm/MC/MCSchedule.h b/clang-r353983/include/llvm/MC/MCSchedule.h
new file mode 100644
index 00000000..df3248ee
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCSchedule.h
@@ -0,0 +1,385 @@
+//===-- llvm/MC/MCSchedule.h - Scheduling -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the classes used to describe a subtarget's machine model
+// for scheduling and other instruction cost heuristics.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSCHEDULE_H
+#define LLVM_MC_MCSCHEDULE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+
+struct InstrItinerary;
+class MCSubtargetInfo;
+class MCInstrInfo;
+class MCInst;
+class InstrItineraryData;
+
+/// Define a kind of processor resource that will be modeled by the scheduler.
+struct MCProcResourceDesc {
+ const char *Name;
+ unsigned NumUnits; // Number of resource of this kind
+ unsigned SuperIdx; // Index of the resources kind that contains this kind.
+
+ // Number of resources that may be buffered.
+ //
+ // Buffered resources (BufferSize != 0) may be consumed at some indeterminate
+ // cycle after dispatch. This should be used for out-of-order cpus when
+ // instructions that use this resource can be buffered in a reservaton
+ // station.
+ //
+ // Unbuffered resources (BufferSize == 0) always consume their resource some
+ // fixed number of cycles after dispatch. If a resource is unbuffered, then
+ // the scheduler will avoid scheduling instructions with conflicting resources
+ // in the same cycle. This is for in-order cpus, or the in-order portion of
+ // an out-of-order cpus.
+ int BufferSize;
+
+ // If the resource has sub-units, a pointer to the first element of an array
+ // of `NumUnits` elements containing the ProcResourceIdx of the sub units.
+ // nullptr if the resource does not have sub-units.
+ const unsigned *SubUnitsIdxBegin;
+
+ bool operator==(const MCProcResourceDesc &Other) const {
+ return NumUnits == Other.NumUnits && SuperIdx == Other.SuperIdx
+ && BufferSize == Other.BufferSize;
+ }
+};
+
+/// Identify one of the processor resource kinds consumed by a particular
+/// scheduling class for the specified number of cycles.
+struct MCWriteProcResEntry {
+ uint16_t ProcResourceIdx;
+ uint16_t Cycles;
+
+ bool operator==(const MCWriteProcResEntry &Other) const {
+ return ProcResourceIdx == Other.ProcResourceIdx && Cycles == Other.Cycles;
+ }
+};
+
+/// Specify the latency in cpu cycles for a particular scheduling class and def
+/// index. -1 indicates an invalid latency. Heuristics would typically consider
+/// an instruction with invalid latency to have infinite latency. Also identify
+/// the WriteResources of this def. When the operand expands to a sequence of
+/// writes, this ID is the last write in the sequence.
+struct MCWriteLatencyEntry {
+ int16_t Cycles;
+ uint16_t WriteResourceID;
+
+ bool operator==(const MCWriteLatencyEntry &Other) const {
+ return Cycles == Other.Cycles && WriteResourceID == Other.WriteResourceID;
+ }
+};
+
+/// Specify the number of cycles allowed after instruction issue before a
+/// particular use operand reads its registers. This effectively reduces the
+/// write's latency. Here we allow negative cycles for corner cases where
+/// latency increases. This rule only applies when the entry's WriteResource
+/// matches the write's WriteResource.
+///
+/// MCReadAdvanceEntries are sorted first by operand index (UseIdx), then by
+/// WriteResourceIdx.
+struct MCReadAdvanceEntry {
+ unsigned UseIdx;
+ unsigned WriteResourceID;
+ int Cycles;
+
+ bool operator==(const MCReadAdvanceEntry &Other) const {
+ return UseIdx == Other.UseIdx && WriteResourceID == Other.WriteResourceID
+ && Cycles == Other.Cycles;
+ }
+};
+
+/// Summarize the scheduling resources required for an instruction of a
+/// particular scheduling class.
+///
+/// Defined as an aggregate struct for creating tables with initializer lists.
+struct MCSchedClassDesc {
+ static const unsigned short InvalidNumMicroOps = (1U << 14) - 1;
+ static const unsigned short VariantNumMicroOps = InvalidNumMicroOps - 1;
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ const char* Name;
+#endif
+ uint16_t NumMicroOps : 14;
+ bool BeginGroup : 1;
+ bool EndGroup : 1;
+ uint16_t WriteProcResIdx; // First index into WriteProcResTable.
+ uint16_t NumWriteProcResEntries;
+ uint16_t WriteLatencyIdx; // First index into WriteLatencyTable.
+ uint16_t NumWriteLatencyEntries;
+ uint16_t ReadAdvanceIdx; // First index into ReadAdvanceTable.
+ uint16_t NumReadAdvanceEntries;
+
+ bool isValid() const {
+ return NumMicroOps != InvalidNumMicroOps;
+ }
+ bool isVariant() const {
+ return NumMicroOps == VariantNumMicroOps;
+ }
+};
+
+/// Specify the cost of a register definition in terms of number of physical
+/// register allocated at register renaming stage. For example, AMD Jaguar.
+/// natively supports 128-bit data types, and operations on 256-bit registers
+/// (i.e. YMM registers) are internally split into two COPs (complex operations)
+/// and each COP updates a physical register. Basically, on Jaguar, a YMM
+/// register write effectively consumes two physical registers. That means,
+/// the cost of a YMM write in the BtVer2 model is 2.
+struct MCRegisterCostEntry {
+ unsigned RegisterClassID;
+ unsigned Cost;
+ bool AllowMoveElimination;
+};
+
+/// A register file descriptor.
+///
+/// This struct allows to describe processor register files. In particular, it
+/// helps describing the size of the register file, as well as the cost of
+/// allocating a register file at register renaming stage.
+/// FIXME: this struct can be extended to provide information about the number
+/// of read/write ports to the register file. A value of zero for field
+/// 'NumPhysRegs' means: this register file has an unbounded number of physical
+/// registers.
+struct MCRegisterFileDesc {
+ const char *Name;
+ uint16_t NumPhysRegs;
+ uint16_t NumRegisterCostEntries;
+ // Index of the first cost entry in MCExtraProcessorInfo::RegisterCostTable.
+ uint16_t RegisterCostEntryIdx;
+ // A value of zero means: there is no limit in the number of moves that can be
+ // eliminated every cycle.
+ uint16_t MaxMovesEliminatedPerCycle;
+ // Ture if this register file only knows how to optimize register moves from
+ // known zero registers.
+ bool AllowZeroMoveEliminationOnly;
+};
+
+/// Provide extra details about the machine processor.
+///
+/// This is a collection of "optional" processor information that is not
+/// normally used by the LLVM machine schedulers, but that can be consumed by
+/// external tools like llvm-mca to improve the quality of the peformance
+/// analysis.
+struct MCExtraProcessorInfo {
+ // Actual size of the reorder buffer in hardware.
+ unsigned ReorderBufferSize;
+ // Number of instructions retired per cycle.
+ unsigned MaxRetirePerCycle;
+ const MCRegisterFileDesc *RegisterFiles;
+ unsigned NumRegisterFiles;
+ const MCRegisterCostEntry *RegisterCostTable;
+ unsigned NumRegisterCostEntries;
+ unsigned LoadQueueID;
+ unsigned StoreQueueID;
+};
+
+/// Machine model for scheduling, bundling, and heuristics.
+///
+/// The machine model directly provides basic information about the
+/// microarchitecture to the scheduler in the form of properties. It also
+/// optionally refers to scheduler resource tables and itinerary
+/// tables. Scheduler resource tables model the latency and cost for each
+/// instruction type. Itinerary tables are an independent mechanism that
+/// provides a detailed reservation table describing each cycle of instruction
+/// execution. Subtargets may define any or all of the above categories of data
+/// depending on the type of CPU and selected scheduler.
+///
+/// The machine independent properties defined here are used by the scheduler as
+/// an abstract machine model. A real micro-architecture has a number of
+/// buffers, queues, and stages. Declaring that a given machine-independent
+/// abstract property corresponds to a specific physical property across all
+/// subtargets can't be done. Nonetheless, the abstract model is
+/// useful. Futhermore, subtargets typically extend this model with processor
+/// specific resources to model any hardware features that can be exploited by
+/// sceduling heuristics and aren't sufficiently represented in the abstract.
+///
+/// The abstract pipeline is built around the notion of an "issue point". This
+/// is merely a reference point for counting machine cycles. The physical
+/// machine will have pipeline stages that delay execution. The scheduler does
+/// not model those delays because they are irrelevant as long as they are
+/// consistent. Inaccuracies arise when instructions have different execution
+/// delays relative to each other, in addition to their intrinsic latency. Those
+/// special cases can be handled by TableGen constructs such as, ReadAdvance,
+/// which reduces latency when reading data, and ResourceCycles, which consumes
+/// a processor resource when writing data for a number of abstract
+/// cycles.
+///
+/// TODO: One tool currently missing is the ability to add a delay to
+/// ResourceCycles. That would be easy to add and would likely cover all cases
+/// currently handled by the legacy itinerary tables.
+///
+/// A note on out-of-order execution and, more generally, instruction
+/// buffers. Part of the CPU pipeline is always in-order. The issue point, which
+/// is the point of reference for counting cycles, only makes sense as an
+/// in-order part of the pipeline. Other parts of the pipeline are sometimes
+/// falling behind and sometimes catching up. It's only interesting to model
+/// those other, decoupled parts of the pipeline if they may be predictably
+/// resource constrained in a way that the scheduler can exploit.
+///
+/// The LLVM machine model distinguishes between in-order constraints and
+/// out-of-order constraints so that the target's scheduling strategy can apply
+/// appropriate heuristics. For a well-balanced CPU pipeline, out-of-order
+/// resources would not typically be treated as a hard scheduling
+/// constraint. For example, in the GenericScheduler, a delay caused by limited
+/// out-of-order resources is not directly reflected in the number of cycles
+/// that the scheduler sees between issuing an instruction and its dependent
+/// instructions. In other words, out-of-order resources don't directly increase
+/// the latency between pairs of instructions. However, they can still be used
+/// to detect potential bottlenecks across a sequence of instructions and bias
+/// the scheduling heuristics appropriately.
+struct MCSchedModel {
+ // IssueWidth is the maximum number of instructions that may be scheduled in
+ // the same per-cycle group. This is meant to be a hard in-order constraint
+ // (a.k.a. "hazard"). In the GenericScheduler strategy, no more than
+ // IssueWidth micro-ops can ever be scheduled in a particular cycle.
+ //
+ // In practice, IssueWidth is useful to model any bottleneck between the
+ // decoder (after micro-op expansion) and the out-of-order reservation
+ // stations or the decoder bandwidth itself. If the total number of
+ // reservation stations is also a bottleneck, or if any other pipeline stage
+ // has a bandwidth limitation, then that can be naturally modeled by adding an
+ // out-of-order processor resource.
+ unsigned IssueWidth;
+ static const unsigned DefaultIssueWidth = 1;
+
+ // MicroOpBufferSize is the number of micro-ops that the processor may buffer
+ // for out-of-order execution.
+ //
+ // "0" means operations that are not ready in this cycle are not considered
+ // for scheduling (they go in the pending queue). Latency is paramount. This
+ // may be more efficient if many instructions are pending in a schedule.
+ //
+ // "1" means all instructions are considered for scheduling regardless of
+ // whether they are ready in this cycle. Latency still causes issue stalls,
+ // but we balance those stalls against other heuristics.
+ //
+ // "> 1" means the processor is out-of-order. This is a machine independent
+ // estimate of highly machine specific characteristics such as the register
+ // renaming pool and reorder buffer.
+ unsigned MicroOpBufferSize;
+ static const unsigned DefaultMicroOpBufferSize = 0;
+
+ // LoopMicroOpBufferSize is the number of micro-ops that the processor may
+ // buffer for optimized loop execution. More generally, this represents the
+ // optimal number of micro-ops in a loop body. A loop may be partially
+ // unrolled to bring the count of micro-ops in the loop body closer to this
+ // number.
+ unsigned LoopMicroOpBufferSize;
+ static const unsigned DefaultLoopMicroOpBufferSize = 0;
+
+ // LoadLatency is the expected latency of load instructions.
+ unsigned LoadLatency;
+ static const unsigned DefaultLoadLatency = 4;
+
+ // HighLatency is the expected latency of "very high latency" operations.
+ // See TargetInstrInfo::isHighLatencyDef().
+ // By default, this is set to an arbitrarily high number of cycles
+ // likely to have some impact on scheduling heuristics.
+ unsigned HighLatency;
+ static const unsigned DefaultHighLatency = 10;
+
+ // MispredictPenalty is the typical number of extra cycles the processor
+ // takes to recover from a branch misprediction.
+ unsigned MispredictPenalty;
+ static const unsigned DefaultMispredictPenalty = 10;
+
+ bool PostRAScheduler; // default value is false
+
+ bool CompleteModel;
+
+ unsigned ProcID;
+ const MCProcResourceDesc *ProcResourceTable;
+ const MCSchedClassDesc *SchedClassTable;
+ unsigned NumProcResourceKinds;
+ unsigned NumSchedClasses;
+ // Instruction itinerary tables used by InstrItineraryData.
+ friend class InstrItineraryData;
+ const InstrItinerary *InstrItineraries;
+
+ const MCExtraProcessorInfo *ExtraProcessorInfo;
+
+ bool hasExtraProcessorInfo() const { return ExtraProcessorInfo; }
+
+ unsigned getProcessorID() const { return ProcID; }
+
+ /// Does this machine model include instruction-level scheduling.
+ bool hasInstrSchedModel() const { return SchedClassTable; }
+
+ const MCExtraProcessorInfo &getExtraProcessorInfo() const {
+ assert(hasExtraProcessorInfo() &&
+ "No extra information available for this model");
+ return *ExtraProcessorInfo;
+ }
+
+ /// Return true if this machine model data for all instructions with a
+ /// scheduling class (itinerary class or SchedRW list).
+ bool isComplete() const { return CompleteModel; }
+
+ /// Return true if machine supports out of order execution.
+ bool isOutOfOrder() const { return MicroOpBufferSize > 1; }
+
+ unsigned getNumProcResourceKinds() const {
+ return NumProcResourceKinds;
+ }
+
+ const MCProcResourceDesc *getProcResource(unsigned ProcResourceIdx) const {
+ assert(hasInstrSchedModel() && "No scheduling machine model");
+
+ assert(ProcResourceIdx < NumProcResourceKinds && "bad proc resource idx");
+ return &ProcResourceTable[ProcResourceIdx];
+ }
+
+ const MCSchedClassDesc *getSchedClassDesc(unsigned SchedClassIdx) const {
+ assert(hasInstrSchedModel() && "No scheduling machine model");
+
+ assert(SchedClassIdx < NumSchedClasses && "bad scheduling class idx");
+ return &SchedClassTable[SchedClassIdx];
+ }
+
+ /// Returns the latency value for the scheduling class.
+ static int computeInstrLatency(const MCSubtargetInfo &STI,
+ const MCSchedClassDesc &SCDesc);
+
+ int computeInstrLatency(const MCSubtargetInfo &STI, unsigned SClass) const;
+ int computeInstrLatency(const MCSubtargetInfo &STI, const MCInstrInfo &MCII,
+ const MCInst &Inst) const;
+
+ // Returns the reciprocal throughput information from a MCSchedClassDesc.
+ static double
+ getReciprocalThroughput(const MCSubtargetInfo &STI,
+ const MCSchedClassDesc &SCDesc);
+
+ static double
+ getReciprocalThroughput(unsigned SchedClass, const InstrItineraryData &IID);
+
+ double
+ getReciprocalThroughput(const MCSubtargetInfo &STI, const MCInstrInfo &MCII,
+ const MCInst &Inst) const;
+
+ /// Returns the maximum forwarding delay for register reads dependent on
+ /// writes of scheduling class WriteResourceIdx.
+ static unsigned getForwardingDelayCycles(ArrayRef<MCReadAdvanceEntry> Entries,
+ unsigned WriteResourceIdx = 0);
+
+ /// Returns the default initialized model.
+ static const MCSchedModel &GetDefaultSchedModel() { return Default; }
+ static const MCSchedModel Default;
+};
+
+} // namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCSection.h b/clang-r353983/include/llvm/MC/MCSection.h
new file mode 100644
index 00000000..27490dc8
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCSection.h
@@ -0,0 +1,193 @@
+//===- MCSection.h - Machine Code Sections ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCSection class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTION_H
+#define LLVM_MC_MCSECTION_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/MC/MCFragment.h"
+#include "llvm/MC/SectionKind.h"
+#include <cassert>
+#include <utility>
+
+namespace llvm {
+
+class MCAsmInfo;
+class MCContext;
+class MCExpr;
+class MCSymbol;
+class raw_ostream;
+class Triple;
+
+template <> struct ilist_alloc_traits<MCFragment> {
+ static void deleteNode(MCFragment *V);
+};
+
+/// 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, SV_Wasm };
+
+ /// Express the state of bundle locked groups while emitting code.
+ enum BundleLockStateType {
+ NotBundleLocked,
+ BundleLocked,
+ BundleLockedAlignToEnd
+ };
+
+ using FragmentListType = iplist<MCFragment>;
+
+ using const_iterator = FragmentListType::const_iterator;
+ using iterator = FragmentListType::iterator;
+
+ using const_reverse_iterator = FragmentListType::const_reverse_iterator;
+ using reverse_iterator = FragmentListType::reverse_iterator;
+
+private:
+ 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;
+
+ /// Keeping track of bundle-locked state.
+ BundleLockStateType BundleLockState = NotBundleLocked;
+
+ /// Current nesting depth of bundle_lock directives.
+ unsigned BundleLockNestingDepth = 0;
+
+ /// We've seen a bundle_lock directive but not its first instruction
+ /// yet.
+ bool BundleGroupBeforeFirstInst : 1;
+
+ /// Whether this section has had instructions emitted into it.
+ bool HasInstructions : 1;
+
+ /// Whether this section has had data emitted into it.
+ /// Right now this is only used by the ARM backend.
+ bool HasData : 1;
+
+ bool IsRegistered : 1;
+
+ MCDummyFragment DummyFragment;
+
+ FragmentListType Fragments;
+
+ /// Mapping from subsection number to insertion point for subsection numbers
+ /// below that number.
+ SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap;
+
+protected:
+ SectionVariant Variant;
+ SectionKind Kind;
+
+ MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin);
+ ~MCSection();
+
+public:
+ MCSection(const MCSection &) = delete;
+ MCSection &operator=(const MCSection &) = delete;
+
+ 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; }
+
+ bool hasData() const { return HasData; }
+ void setHasData(bool Value) { HasData = Value; }
+
+ bool isRegistered() const { return IsRegistered; }
+ void setIsRegistered(bool Value) { IsRegistered = Value; }
+
+ MCSection::FragmentListType &getFragmentList() { return Fragments; }
+ const MCSection::FragmentListType &getFragmentList() const {
+ return const_cast<MCSection *>(this)->getFragmentList();
+ }
+
+ /// Support for MCFragment::getNextNode().
+ static FragmentListType MCSection::*getSublistAccess(MCFragment *) {
+ return &MCSection::Fragments;
+ }
+
+ const MCDummyFragment &getDummyFragment() const { return DummyFragment; }
+ MCDummyFragment &getDummyFragment() { return DummyFragment; }
+
+ 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(); }
+
+ MCSection::iterator getSubsectionInsertionPoint(unsigned Subsection);
+
+ void dump() const;
+
+ virtual void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
+ 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 // LLVM_MC_MCSECTION_H
diff --git a/clang-r353983/include/llvm/MC/MCSectionCOFF.h b/clang-r353983/include/llvm/MC/MCSectionCOFF.h
new file mode 100644
index 00000000..8be95e0f
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCSectionCOFF.h
@@ -0,0 +1,97 @@
+//===- MCSectionCOFF.h - COFF Machine Code Sections -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCSectionCOFF class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTIONCOFF_H
+#define LLVM_MC_MCSECTIONCOFF_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/SectionKind.h"
+#include <cassert>
+
+namespace llvm {
+
+class MCSymbol;
+
+/// This represents a section on Windows
+class MCSectionCOFF final : public MCSection {
+ // The memory for this string is stored in the same MCContext as *this.
+ StringRef SectionName;
+
+ // FIXME: The following fields should not be mutable, but are for now so the
+ // asm parser can honor the .linkonce directive.
+
+ /// This is the Characteristics field of a section, drawn from the enums
+ /// below.
+ mutable unsigned Characteristics;
+
+ /// The unique IDs used with the .pdata and .xdata sections created internally
+ /// by the assembler. This ID is used to ensure that for every .text section,
+ /// there is exactly one .pdata and one .xdata section, which is required by
+ /// the Microsoft incremental linker. This data is mutable because this ID is
+ /// not notionally part of the section.
+ mutable unsigned WinCFISectionID = ~0U;
+
+ /// The COMDAT symbol of this section. Only valid if this is a COMDAT section.
+ /// Two COMDAT sections are merged if they have the same COMDAT symbol.
+ MCSymbol *COMDATSymbol;
+
+ /// This is the Selection field for the section symbol, if it is a COMDAT
+ /// section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
+ mutable int Selection;
+
+private:
+ friend class MCContext;
+ MCSectionCOFF(StringRef Section, unsigned Characteristics,
+ 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");
+ }
+
+public:
+ /// Decides whether a '.section' directive should be printed before the
+ /// section name
+ bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
+
+ StringRef getSectionName() const { return SectionName; }
+ unsigned getCharacteristics() const { return Characteristics; }
+ MCSymbol *getCOMDATSymbol() const { return COMDATSymbol; }
+ int getSelection() const { return Selection; }
+
+ void setSelection(int Selection) const;
+
+ void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
+ raw_ostream &OS,
+ const MCExpr *Subsection) const override;
+ bool UseCodeAlign() const override;
+ bool isVirtualSection() const override;
+
+ unsigned getOrAssignWinCFISectionID(unsigned *NextID) const {
+ if (WinCFISectionID == ~0U)
+ WinCFISectionID = (*NextID)++;
+ return WinCFISectionID;
+ }
+
+ static bool isImplicitlyDiscardable(StringRef Name) {
+ return Name.startswith(".debug");
+ }
+
+ static bool classof(const MCSection *S) { return S->getVariant() == SV_COFF; }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCSECTIONCOFF_H
diff --git a/clang-r353983/include/llvm/MC/MCSectionELF.h b/clang-r353983/include/llvm/MC/MCSectionELF.h
new file mode 100644
index 00000000..fe6b2d7a
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCSectionELF.h
@@ -0,0 +1,96 @@
+//===- MCSectionELF.h - ELF Machine Code Sections ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCSectionELF class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTIONELF_H
+#define LLVM_MC_MCSECTIONELF_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSymbolELF.h"
+#include "llvm/MC/SectionKind.h"
+
+namespace llvm {
+
+class MCSymbol;
+
+/// This represents a section on linux, lots of unix variants and some bare
+/// metal systems.
+class MCSectionELF final : public MCSection {
+ /// This is the name of the section. The referenced memory is owned by
+ /// TargetLoweringObjectFileELF's ELFUniqueMap.
+ StringRef SectionName;
+
+ /// This is the sh_type field of a section, drawn from the enums below.
+ unsigned Type;
+
+ /// This is the sh_flags field of a section, drawn from the enums below.
+ unsigned Flags;
+
+ unsigned UniqueID;
+
+ /// The size of each entry in this section. This size only makes sense for
+ /// sections that contain fixed-sized entries. If a section does not contain
+ /// fixed-sized entries 'EntrySize' will be 0.
+ unsigned EntrySize;
+
+ const MCSymbolELF *Group;
+
+ /// sh_info for SHF_LINK_ORDER (can be null).
+ const MCSymbol *AssociatedSymbol;
+
+private:
+ friend class MCContext;
+
+ MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K,
+ unsigned entrySize, const MCSymbolELF *group, unsigned UniqueID,
+ MCSymbol *Begin, const MCSymbolELF *AssociatedSymbol)
+ : MCSection(SV_ELF, K, Begin), SectionName(Section), Type(type),
+ Flags(flags), UniqueID(UniqueID), EntrySize(entrySize), Group(group),
+ AssociatedSymbol(AssociatedSymbol) {
+ if (Group)
+ Group->setIsSignature();
+ }
+
+ void setSectionName(StringRef Name) { SectionName = Name; }
+
+public:
+ /// Decides whether a '.section' directive should be printed before the
+ /// section name
+ bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
+
+ StringRef getSectionName() const { return SectionName; }
+ unsigned getType() const { return Type; }
+ unsigned getFlags() const { return Flags; }
+ unsigned getEntrySize() const { return EntrySize; }
+ void setFlags(unsigned F) { Flags = F; }
+ const MCSymbolELF *getGroup() const { return Group; }
+
+ void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
+ raw_ostream &OS,
+ const MCExpr *Subsection) const override;
+ bool UseCodeAlign() const override;
+ bool isVirtualSection() const override;
+
+ bool isUnique() const { return UniqueID != ~0U; }
+ unsigned getUniqueID() const { return UniqueID; }
+
+ const MCSection *getAssociatedSection() const { return &AssociatedSymbol->getSection(); }
+ const MCSymbol *getAssociatedSymbol() const { return AssociatedSymbol; }
+
+ static bool classof(const MCSection *S) {
+ return S->getVariant() == SV_ELF;
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCSECTIONELF_H
diff --git a/clang-r353983/include/llvm/MC/MCSectionMachO.h b/clang-r353983/include/llvm/MC/MCSectionMachO.h
new file mode 100644
index 00000000..2c73661f
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCSectionMachO.h
@@ -0,0 +1,91 @@
+//===- MCSectionMachO.h - MachO Machine Code Sections -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCSectionMachO class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTIONMACHO_H
+#define LLVM_MC_MCSECTIONMACHO_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/MC/MCSection.h"
+
+namespace llvm {
+
+/// This represents a section on a Mach-O system (used by Mac OS X). On a Mac
+/// system, these are also described in /usr/include/mach-o/loader.h.
+class MCSectionMachO final : public MCSection {
+ char SegmentName[16]; // Not necessarily null terminated!
+ char SectionName[16]; // Not necessarily null terminated!
+
+ /// This is the SECTION_TYPE and SECTION_ATTRIBUTES field of a section, drawn
+ /// from the enums below.
+ unsigned TypeAndAttributes;
+
+ /// The 'reserved2' field of a section, used to represent the size of stubs,
+ /// for example.
+ unsigned Reserved2;
+
+ MCSectionMachO(StringRef Segment, StringRef Section, unsigned TAA,
+ unsigned reserved2, SectionKind K, MCSymbol *Begin);
+ friend class MCContext;
+public:
+
+ StringRef getSegmentName() const {
+ // SegmentName is not necessarily null terminated!
+ if (SegmentName[15])
+ return StringRef(SegmentName, 16);
+ return StringRef(SegmentName);
+ }
+ StringRef getSectionName() const {
+ // SectionName is not necessarily null terminated!
+ if (SectionName[15])
+ return StringRef(SectionName, 16);
+ return StringRef(SectionName);
+ }
+
+ unsigned getTypeAndAttributes() const { return TypeAndAttributes; }
+ unsigned getStubSize() const { return Reserved2; }
+
+ MachO::SectionType getType() const {
+ return static_cast<MachO::SectionType>(TypeAndAttributes &
+ MachO::SECTION_TYPE);
+ }
+ bool hasAttribute(unsigned Value) const {
+ return (TypeAndAttributes & Value) != 0;
+ }
+
+ /// Parse the section specifier indicated by "Spec". This is a string that can
+ /// appear after a .section directive in a mach-o flavored .s file. If
+ /// successful, this fills in the specified Out parameters and returns an
+ /// empty string. When an invalid section specifier is present, this returns
+ /// a string indicating the problem. If no TAA was parsed, TAA is not altered,
+ /// and TAAWasSet becomes false.
+ static std::string ParseSectionSpecifier(StringRef Spec, // In.
+ StringRef &Segment, // Out.
+ StringRef &Section, // Out.
+ unsigned &TAA, // Out.
+ bool &TAAParsed, // Out.
+ unsigned &StubSize); // Out.
+
+ void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
+ raw_ostream &OS,
+ const MCExpr *Subsection) const override;
+ bool UseCodeAlign() const override;
+ bool isVirtualSection() const override;
+
+ static bool classof(const MCSection *S) {
+ return S->getVariant() == SV_MachO;
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCSectionWasm.h b/clang-r353983/include/llvm/MC/MCSectionWasm.h
new file mode 100644
index 00000000..0e576b7b
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCSectionWasm.h
@@ -0,0 +1,83 @@
+//===- MCSectionWasm.h - Wasm Machine Code Sections -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCSectionWasm class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTIONWASM_H
+#define LLVM_MC_MCSECTIONWASM_H
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSymbolWasm.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+class MCSymbol;
+
+/// This represents a section on wasm.
+class MCSectionWasm final : public MCSection {
+ /// This is the name of the section. The referenced memory is owned by
+ /// TargetLoweringObjectFileWasm's WasmUniqueMap.
+ StringRef SectionName;
+
+ unsigned UniqueID;
+
+ const MCSymbolWasm *Group;
+
+ // The offset of the MC function/data section in the wasm code/data section.
+ // For data relocations the offset is relative to start of the data payload
+ // itself and does not include the size of the section header.
+ uint64_t SectionOffset = 0;
+
+ // For data sections, this is the index of of the corresponding wasm data
+ // segment
+ uint32_t SegmentIndex = 0;
+
+ friend class MCContext;
+ MCSectionWasm(StringRef Section, SectionKind K, const MCSymbolWasm *group,
+ unsigned UniqueID, MCSymbol *Begin)
+ : MCSection(SV_Wasm, K, Begin), SectionName(Section), UniqueID(UniqueID),
+ Group(group) {}
+
+public:
+ /// Decides whether a '.section' directive should be printed before the
+ /// section name
+ bool shouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
+
+ StringRef getSectionName() const { return SectionName; }
+ const MCSymbolWasm *getGroup() const { return Group; }
+
+ void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
+ raw_ostream &OS,
+ const MCExpr *Subsection) const override;
+ bool UseCodeAlign() const override;
+ bool isVirtualSection() const override;
+
+ bool isWasmData() const {
+ return Kind.isGlobalWriteableData() || Kind.isReadOnly();
+ }
+
+ bool isUnique() const { return UniqueID != ~0U; }
+ unsigned getUniqueID() const { return UniqueID; }
+
+ uint64_t getSectionOffset() const { return SectionOffset; }
+ void setSectionOffset(uint64_t Offset) { SectionOffset = Offset; }
+
+ uint32_t getSegmentIndex() const { return SegmentIndex; }
+ void setSegmentIndex(uint32_t Index) { SegmentIndex = Index; }
+
+ static bool classof(const MCSection *S) { return S->getVariant() == SV_Wasm; }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCStreamer.h b/clang-r353983/include/llvm/MC/MCStreamer.h
new file mode 100644
index 00000000..dc2386fc
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCStreamer.h
@@ -0,0 +1,1012 @@
+//===- MCStreamer.h - High-level Streaming Machine Code Output --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCStreamer class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSTREAMER_H
+#define LLVM_MC_MCSTREAMER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCLinkerOptimizationHint.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCWinEH.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MD5.h"
+#include "llvm/Support/SMLoc.h"
+#include "llvm/Support/TargetParser.h"
+#include "llvm/Support/VersionTuple.h"
+#include <cassert>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+class AssemblerConstantPools;
+class formatted_raw_ostream;
+class MCAsmBackend;
+class MCCodeEmitter;
+struct MCCodePaddingContext;
+class MCContext;
+class MCExpr;
+class MCInst;
+class MCInstPrinter;
+class MCSection;
+class MCStreamer;
+class MCSymbolRefExpr;
+class MCSubtargetInfo;
+class raw_ostream;
+class Twine;
+
+using MCSectionSubPair = std::pair<MCSection *, const MCExpr *>;
+
+/// Target specific streamer interface. This is used so that targets can
+/// implement support for target specific assembly directives.
+///
+/// If target foo wants to use this, it should implement 3 classes:
+/// * FooTargetStreamer : public MCTargetStreamer
+/// * FooTargetAsmStreamer : public FooTargetStreamer
+/// * FooTargetELFStreamer : public FooTargetStreamer
+///
+/// FooTargetStreamer should have a pure virtual method for each directive. For
+/// example, for a ".bar symbol_name" directive, it should have
+/// virtual emitBar(const MCSymbol &Symbol) = 0;
+///
+/// The FooTargetAsmStreamer and FooTargetELFStreamer classes implement the
+/// method. The assembly streamer just prints ".bar symbol_name". The object
+/// streamer does whatever is needed to implement .bar in the object file.
+///
+/// In the assembly printer and parser the target streamer can be used by
+/// calling getTargetStreamer and casting it to FooTargetStreamer:
+///
+/// MCTargetStreamer &TS = OutStreamer.getTargetStreamer();
+/// FooTargetStreamer &ATS = static_cast<FooTargetStreamer &>(TS);
+///
+/// The base classes FooTargetAsmStreamer and FooTargetELFStreamer should
+/// *never* be treated differently. Callers should always talk to a
+/// FooTargetStreamer.
+class MCTargetStreamer {
+protected:
+ MCStreamer &Streamer;
+
+public:
+ MCTargetStreamer(MCStreamer &S);
+ virtual ~MCTargetStreamer();
+
+ MCStreamer &getStreamer() { return Streamer; }
+
+ // Allow a target to add behavior to the EmitLabel of MCStreamer.
+ virtual void emitLabel(MCSymbol *Symbol);
+ // Allow a target to add behavior to the emitAssignment of MCStreamer.
+ virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value);
+
+ virtual void prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS,
+ const MCInst &Inst, const MCSubtargetInfo &STI);
+
+ virtual void emitDwarfFileDirective(StringRef Directive);
+
+ /// Update streamer for a new active section.
+ ///
+ /// This is called by PopSection and SwitchSection, if the current
+ /// section changes.
+ virtual void changeSection(const MCSection *CurSection, MCSection *Section,
+ const MCExpr *SubSection, raw_ostream &OS);
+
+ virtual void emitValue(const MCExpr *Value);
+
+ /// Emit the bytes in \p Data into the output.
+ ///
+ /// This is used to emit bytes in \p Data as sequence of .byte directives.
+ virtual void emitRawBytes(StringRef Data);
+
+ virtual void finish();
+};
+
+// FIXME: declared here because it is used from
+// lib/CodeGen/AsmPrinter/ARMException.cpp.
+class ARMTargetStreamer : public MCTargetStreamer {
+public:
+ ARMTargetStreamer(MCStreamer &S);
+ ~ARMTargetStreamer() override;
+
+ virtual void emitFnStart();
+ virtual void emitFnEnd();
+ virtual void emitCantUnwind();
+ virtual void emitPersonality(const MCSymbol *Personality);
+ virtual void emitPersonalityIndex(unsigned Index);
+ virtual void emitHandlerData();
+ virtual void emitSetFP(unsigned FpReg, unsigned SpReg,
+ int64_t Offset = 0);
+ virtual void emitMovSP(unsigned Reg, int64_t Offset = 0);
+ virtual void emitPad(int64_t Offset);
+ virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
+ bool isVector);
+ virtual void emitUnwindRaw(int64_t StackOffset,
+ const SmallVectorImpl<uint8_t> &Opcodes);
+
+ virtual void switchVendor(StringRef Vendor);
+ virtual void emitAttribute(unsigned Attribute, unsigned Value);
+ virtual void emitTextAttribute(unsigned Attribute, StringRef String);
+ virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
+ StringRef StringValue = "");
+ virtual void emitFPU(unsigned FPU);
+ virtual void emitArch(ARM::ArchKind Arch);
+ virtual void emitArchExtension(unsigned ArchExt);
+ virtual void emitObjectArch(ARM::ArchKind Arch);
+ void emitTargetAttributes(const MCSubtargetInfo &STI);
+ virtual void finishAttributeSection();
+ virtual void emitInst(uint32_t Inst, char Suffix = '\0');
+
+ virtual void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE);
+
+ virtual void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value);
+
+ void finish() override;
+
+ /// Reset any state between object emissions, i.e. the equivalent of
+ /// MCStreamer's reset method.
+ virtual void reset();
+
+ /// 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 *, SMLoc Loc);
+
+ /// Callback used to implemnt the .ltorg directive.
+ /// Emit contents of constant pool for the current section.
+ void emitCurrentConstantPool();
+
+private:
+ std::unique_ptr<AssemblerConstantPools> ConstantPools;
+};
+
+/// Streaming machine code generation interface.
+///
+/// This interface is intended to provide a programatic interface that is very
+/// similar to the level that an assembler .s file provides. It has callbacks
+/// to emit bytes, handle directives, etc. The implementation of this interface
+/// retains state to know what the current section is etc.
+///
+/// There are multiple implementations of this interface: one for writing out
+/// a .s file, and implementations that write out .o files of various formats.
+///
+class MCStreamer {
+ MCContext &Context;
+ std::unique_ptr<MCTargetStreamer> TargetStreamer;
+
+ std::vector<MCDwarfFrameInfo> DwarfFrameInfos;
+ MCDwarfFrameInfo *getCurrentDwarfFrameInfo();
+
+ /// Similar to DwarfFrameInfos, but for SEH unwind info. Chained frames may
+ /// refer to each other, so use std::unique_ptr to provide pointer stability.
+ std::vector<std::unique_ptr<WinEH::FrameInfo>> WinFrameInfos;
+
+ WinEH::FrameInfo *CurrentWinFrameInfo;
+
+ /// 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;
+
+ /// This is stack of current and previous section values saved by
+ /// PushSection.
+ SmallVector<std::pair<MCSectionSubPair, MCSectionSubPair>, 4> SectionStack;
+
+ /// The next unique ID to use when creating a WinCFI-related section (.pdata
+ /// or .xdata). This ID ensures that we have a one-to-one mapping from
+ /// code section to unwind info section, which MSVC's incremental linker
+ /// requires.
+ unsigned NextWinCFIID = 0;
+
+ bool UseAssemblerInfoForParsing;
+
+protected:
+ MCStreamer(MCContext &Ctx);
+
+ virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
+ virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame);
+
+ WinEH::FrameInfo *getCurrentWinFrameInfo() {
+ return CurrentWinFrameInfo;
+ }
+
+ virtual void EmitWindowsUnwindTables();
+
+ virtual void EmitRawTextImpl(StringRef String);
+
+ /// Returns true if the the .cv_loc directive is in the right section.
+ bool checkCVLocSection(unsigned FuncId, unsigned FileNo, SMLoc Loc);
+
+public:
+ MCStreamer(const MCStreamer &) = delete;
+ MCStreamer &operator=(const MCStreamer &) = delete;
+ virtual ~MCStreamer();
+
+ void visitUsedExpr(const MCExpr &Expr);
+ virtual void visitUsedSymbol(const MCSymbol &Sym);
+
+ void setTargetStreamer(MCTargetStreamer *TS) {
+ TargetStreamer.reset(TS);
+ }
+
+ /// State management
+ ///
+ virtual void reset();
+
+ MCContext &getContext() const { return Context; }
+
+ virtual MCAssembler *getAssemblerPtr() { return nullptr; }
+
+ void setUseAssemblerInfoForParsing(bool v) { UseAssemblerInfoForParsing = v; }
+ bool getUseAssemblerInfoForParsing() { return UseAssemblerInfoForParsing; }
+
+ MCTargetStreamer *getTargetStreamer() {
+ return TargetStreamer.get();
+ }
+
+ /// When emitting an object file, create and emit a real label. When emitting
+ /// textual assembly, this should do nothing to avoid polluting our output.
+ virtual MCSymbol *EmitCFILabel();
+
+ /// Retreive the current frame info if one is available and it is not yet
+ /// closed. Otherwise, issue an error and return null.
+ WinEH::FrameInfo *EnsureValidWinFrameInfo(SMLoc Loc);
+
+ unsigned getNumFrameInfos() { return DwarfFrameInfos.size(); }
+ ArrayRef<MCDwarfFrameInfo> getDwarfFrameInfos() const {
+ return DwarfFrameInfos;
+ }
+
+ bool hasUnfinishedDwarfFrameInfo();
+
+ unsigned getNumWinFrameInfos() { return WinFrameInfos.size(); }
+ ArrayRef<std::unique_ptr<WinEH::FrameInfo>> getWinFrameInfos() const {
+ return WinFrameInfos;
+ }
+
+ void generateCompactUnwindEncodings(MCAsmBackend *MAB);
+
+ /// \name Assembly File Formatting.
+ /// @{
+
+ /// Return true if this streamer supports verbose assembly and if it is
+ /// enabled.
+ virtual bool isVerboseAsm() const { return false; }
+
+ /// 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
+ /// correctly?
+ virtual bool isIntegratedAssemblerRequired() const { return false; }
+
+ /// Add a textual comment.
+ ///
+ /// 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.
+ ///
+ /// If the comment includes embedded \n's, they will each get the comment
+ /// prefix as appropriate. The added comment should not end with a \n.
+ /// By default, each comment is terminated with an end of line, i.e. the
+ /// EOL param is set to true by default. If one prefers not to end the
+ /// comment with a new line then the EOL param should be passed
+ /// with a false value.
+ virtual void AddComment(const Twine &T, bool EOL = true) {}
+
+ /// 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
+ /// only prints comments, the object streamer ignores it instead of asserting.
+ virtual void emitRawComment(const Twine &T, bool TabPrefix = true);
+
+ /// Add explicit comment T. T is required to be a valid
+ /// comment in the output and does not need to be escaped.
+ virtual void addExplicitComment(const Twine &T);
+
+ /// Emit added explicit comments.
+ virtual void emitExplicitComments();
+
+ /// AddBlankLine - Emit a blank line to a .s file to pretty it up.
+ virtual void AddBlankLine() {}
+
+ /// @}
+
+ /// \name Symbol & Section Management
+ /// @{
+
+ /// Return the current section that the streamer is emitting code to.
+ MCSectionSubPair getCurrentSection() const {
+ if (!SectionStack.empty())
+ return SectionStack.back().first;
+ return MCSectionSubPair();
+ }
+ MCSection *getCurrentSectionOnly() const { return getCurrentSection().first; }
+
+ /// Return the previous section that the streamer is emitting code to.
+ MCSectionSubPair getPreviousSection() const {
+ if (!SectionStack.empty())
+ return SectionStack.back().second;
+ return MCSectionSubPair();
+ }
+
+ /// 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);
+ }
+
+ /// Update streamer for a new active section.
+ ///
+ /// This is called by PopSection and SwitchSection, if the current
+ /// section changes.
+ virtual void ChangeSection(MCSection *, const MCExpr *);
+
+ /// Save the current and previous section on the section stack.
+ void PushSection() {
+ SectionStack.push_back(
+ std::make_pair(getCurrentSection(), getPreviousSection()));
+ }
+
+ /// Restore the current and previous section from the section stack.
+ /// Calls ChangeSection as needed.
+ ///
+ /// Returns false if the stack was empty.
+ bool PopSection() {
+ if (SectionStack.size() <= 1)
+ return false;
+ auto I = SectionStack.end();
+ --I;
+ MCSectionSubPair OldSection = I->first;
+ --I;
+ MCSectionSubPair NewSection = I->first;
+
+ if (OldSection != NewSection)
+ ChangeSection(NewSection.first, NewSection.second);
+ SectionStack.pop_back();
+ return true;
+ }
+
+ bool SubSection(const MCExpr *Subsection) {
+ if (SectionStack.empty())
+ return false;
+
+ SwitchSection(SectionStack.back().first.first, Subsection);
+ return true;
+ }
+
+ /// 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(MCSection *Section,
+ const MCExpr *Subsection = nullptr);
+
+ /// 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;
+ SectionStack.back().second = curSection;
+ if (MCSectionSubPair(Section, Subsection) != curSection)
+ SectionStack.back().first = MCSectionSubPair(Section, Subsection);
+ }
+
+ /// Create the default sections and set the initial one.
+ virtual void InitSections(bool NoExecStack);
+
+ MCSymbol *endSection(MCSection *Section);
+
+ /// Sets the symbol's section.
+ ///
+ /// Each emitted symbol will be tracked in the ordering table,
+ /// so we can sort on them later.
+ void AssignFragment(MCSymbol *Symbol, MCFragment *Fragment);
+
+ /// Emit a label for \p Symbol into the current section.
+ ///
+ /// This corresponds to an assembler statement such as:
+ /// foo:
+ ///
+ /// \param Symbol - The symbol to emit. A given symbol should only be
+ /// emitted as a label once, and symbols emitted as a label should never be
+ /// used in an assignment.
+ // FIXME: These emission are non-const because we mutate the symbol to
+ // add the section we're emitting it to later.
+ virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc());
+
+ virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol);
+
+ /// Note in the output the specified \p Flag.
+ virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
+
+ /// Emit the given list \p Options of strings as linker
+ /// options into the output.
+ virtual void EmitLinkerOptions(ArrayRef<std::string> Kind) {}
+
+ /// Note in the output the specified region \p Kind.
+ virtual void EmitDataRegion(MCDataRegionType Kind) {}
+
+ /// Specify the Mach-O minimum deployment target version.
+ virtual void EmitVersionMin(MCVersionMinType Type, unsigned Major,
+ unsigned Minor, unsigned Update,
+ VersionTuple SDKVersion) {}
+
+ /// Emit/Specify Mach-O build version command.
+ /// \p Platform should be one of MachO::PlatformType.
+ virtual void EmitBuildVersion(unsigned Platform, unsigned Major,
+ unsigned Minor, unsigned Update,
+ VersionTuple SDKVersion) {}
+
+ void EmitVersionForTarget(const Triple &Target,
+ const VersionTuple &SDKVersion);
+
+ /// Note in the output that the specified \p Func is a Thumb mode
+ /// function (ARM target only).
+ virtual void EmitThumbFunc(MCSymbol *Func);
+
+ /// Emit an assignment of \p Value to \p Symbol.
+ ///
+ /// This corresponds to an assembler statement such as:
+ /// symbol = value
+ ///
+ /// The assignment generates no code, but has the side effect of binding the
+ /// value in the current context. For the assembly streamer, this prints the
+ /// binding into the .s file.
+ ///
+ /// \param Symbol - The symbol being assigned to.
+ /// \param Value - The value for the symbol.
+ virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
+
+ /// Emit an weak reference from \p Alias to \p Symbol.
+ ///
+ /// This corresponds to an assembler statement such as:
+ /// .weakref alias, symbol
+ ///
+ /// \param Alias - The alias that is being created.
+ /// \param Symbol - The symbol being aliased.
+ virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
+
+ /// Add the given \p Attribute to \p Symbol.
+ virtual bool EmitSymbolAttribute(MCSymbol *Symbol,
+ MCSymbolAttr Attribute) = 0;
+
+ /// Set the \p DescValue for the \p Symbol.
+ ///
+ /// \param Symbol - The symbol to have its n_desc field set.
+ /// \param DescValue - The value to set into the n_desc field.
+ virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
+
+ /// Start emitting COFF symbol definition
+ ///
+ /// \param Symbol - The symbol to have its External & Type fields set.
+ virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
+
+ /// Emit the storage class of the symbol.
+ ///
+ /// \param StorageClass - The storage class the symbol should have.
+ virtual void EmitCOFFSymbolStorageClass(int StorageClass);
+
+ /// Emit the type of the symbol.
+ ///
+ /// \param Type - A COFF type identifier (see COFF::SymbolType in X86COFF.h)
+ virtual void EmitCOFFSymbolType(int Type);
+
+ /// Marks the end of the symbol definition.
+ virtual void EndCOFFSymbolDef();
+
+ virtual void EmitCOFFSafeSEH(MCSymbol const *Symbol);
+
+ /// Emits the symbol table index of a Symbol into the current section.
+ virtual void EmitCOFFSymbolIndex(MCSymbol const *Symbol);
+
+ /// Emits a COFF section index.
+ ///
+ /// \param Symbol - Symbol the section number relocation should point to.
+ virtual void EmitCOFFSectionIndex(MCSymbol const *Symbol);
+
+ /// Emits a COFF section relative relocation.
+ ///
+ /// \param Symbol - Symbol the section relative relocation should point to.
+ virtual void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset);
+
+ /// Emits a COFF image relative relocation.
+ ///
+ /// \param Symbol - Symbol the image relative relocation should point to.
+ virtual void EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset);
+
+ /// Emit an ELF .size directive.
+ ///
+ /// This corresponds to an assembler statement such as:
+ /// .size symbol, expression
+ virtual void emitELFSize(MCSymbol *Symbol, const MCExpr *Value);
+
+ /// Emit an ELF .symver directive.
+ ///
+ /// This corresponds to an assembler statement such as:
+ /// .symver _start, foo@@SOME_VERSION
+ /// \param AliasName - The versioned alias (i.e. "foo@@SOME_VERSION")
+ /// \param Aliasee - The aliased symbol (i.e. "_start")
+ virtual void emitELFSymverDirective(StringRef AliasName,
+ const MCSymbol *Aliasee);
+
+ /// Emit a Linker Optimization Hint (LOH) directive.
+ /// \param Args - Arguments of the LOH.
+ virtual void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {}
+
+ /// Emit a common symbol.
+ ///
+ /// \param Symbol - The common symbol to emit.
+ /// \param Size - The size of the common symbol.
+ /// \param ByteAlignment - The alignment of the symbol if
+ /// non-zero. This must be a power of 2.
+ virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) = 0;
+
+ /// Emit a local common (.lcomm) symbol.
+ ///
+ /// \param Symbol - The common symbol to emit.
+ /// \param Size - The size of the common symbol.
+ /// \param ByteAlignment - The alignment of the common symbol in bytes.
+ virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment);
+
+ /// Emit the zerofill section and an optional symbol.
+ ///
+ /// \param Section - The zerofill section to create and or to put the symbol
+ /// \param Symbol - The zerofill symbol to emit, if non-NULL.
+ /// \param Size - The size of the zerofill symbol.
+ /// \param ByteAlignment - The alignment of the zerofill symbol if
+ /// non-zero. This must be a power of 2 on some targets.
+ virtual void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
+ uint64_t Size = 0, unsigned ByteAlignment = 0,
+ SMLoc Loc = SMLoc()) = 0;
+
+ /// Emit a thread local bss (.tbss) symbol.
+ ///
+ /// \param Section - The thread local common section.
+ /// \param Symbol - The thread local common symbol to emit.
+ /// \param Size - The size of the symbol.
+ /// \param ByteAlignment - The alignment of the thread local common symbol
+ /// if non-zero. This must be a power of 2 on some targets.
+ virtual void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
+ uint64_t Size, unsigned ByteAlignment = 0);
+
+ /// @}
+ /// \name Generating Data
+ /// @{
+
+ /// 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);
+
+ /// Functionally identical to EmitBytes. When emitting textual assembly, this
+ /// method uses .byte directives instead of .ascii or .asciz for readability.
+ virtual void EmitBinaryData(StringRef Data);
+
+ /// Emit the expression \p Value into the output as a native
+ /// integer of the given \p Size bytes.
+ ///
+ /// This is used to implement assembler directives such as .word, .quad,
+ /// etc.
+ ///
+ /// \param Value - The value to emit.
+ /// \param Size - The size of the integer (in bytes) to emit. This must
+ /// match a native machine width.
+ /// \param Loc - The location of the expression for error reporting.
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ SMLoc Loc = SMLoc());
+
+ void EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc = SMLoc());
+
+ /// 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);
+
+ virtual void EmitULEB128Value(const MCExpr *Value);
+
+ virtual void EmitSLEB128Value(const MCExpr *Value);
+
+ /// Special case of EmitULEB128Value that avoids the client having to
+ /// pass in a MCExpr for constant integers.
+ void EmitULEB128IntValue(uint64_t Value);
+
+ /// Special case of EmitSLEB128Value that avoids the client having to
+ /// pass in a MCExpr for constant integers.
+ void EmitSLEB128IntValue(int64_t Value);
+
+ /// 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);
+
+ /// Emit the expression \p Value into the output as a dtprel
+ /// (64-bit DTP relative) value.
+ ///
+ /// This is used to implement assembler directives such as .dtpreldword on
+ /// targets that support them.
+ virtual void EmitDTPRel64Value(const MCExpr *Value);
+
+ /// Emit the expression \p Value into the output as a dtprel
+ /// (32-bit DTP relative) value.
+ ///
+ /// This is used to implement assembler directives such as .dtprelword on
+ /// targets that support them.
+ virtual void EmitDTPRel32Value(const MCExpr *Value);
+
+ /// Emit the expression \p Value into the output as a tprel
+ /// (64-bit TP relative) value.
+ ///
+ /// This is used to implement assembler directives such as .tpreldword on
+ /// targets that support them.
+ virtual void EmitTPRel64Value(const MCExpr *Value);
+
+ /// Emit the expression \p Value into the output as a tprel
+ /// (32-bit TP relative) value.
+ ///
+ /// This is used to implement assembler directives such as .tprelword on
+ /// targets that support them.
+ virtual void EmitTPRel32Value(const MCExpr *Value);
+
+ /// 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);
+
+ /// 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);
+
+ /// Emit NumBytes bytes worth of the value specified by FillValue.
+ /// This implements directives such as '.space'.
+ void emitFill(uint64_t NumBytes, uint8_t FillValue);
+
+ /// Emit \p Size bytes worth of the value specified by \p FillValue.
+ ///
+ /// This is used to implement assembler directives such as .space or .skip.
+ ///
+ /// \param NumBytes - The number of bytes to emit.
+ /// \param FillValue - The value to use when filling bytes.
+ /// \param Loc - The location of the expression for error reporting.
+ virtual void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
+ SMLoc Loc = SMLoc());
+
+ /// Emit \p NumValues copies of \p Size bytes. Each \p Size bytes is
+ /// taken from the lowest order 4 bytes of \p Expr expression.
+ ///
+ /// This is used to implement assembler directives such as .fill.
+ ///
+ /// \param NumValues - The number of copies of \p Size bytes to emit.
+ /// \param Size - The size (in bytes) of each repeated value.
+ /// \param Expr - The expression from which \p Size bytes are used.
+ virtual void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
+ SMLoc Loc = SMLoc());
+
+ /// Emit NumBytes worth of zeros.
+ /// This function properly handles data in virtual sections.
+ void EmitZeros(uint64_t NumBytes);
+
+ /// Emit some number of copies of \p Value until the byte alignment \p
+ /// ByteAlignment is reached.
+ ///
+ /// If the number of bytes need to emit for the alignment is not a multiple
+ /// of \p ValueSize, then the contents of the emitted fill bytes is
+ /// undefined.
+ ///
+ /// This used to implement the .align assembler directive.
+ ///
+ /// \param ByteAlignment - The alignment to reach. This must be a power of
+ /// two on some targets.
+ /// \param Value - The value to use when filling bytes.
+ /// \param ValueSize - The size of the integer (in bytes) to emit for
+ /// \p Value. This must match a native machine width.
+ /// \param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
+ /// the alignment cannot be reached in this many bytes, no bytes are
+ /// emitted.
+ virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
+ unsigned ValueSize = 1,
+ unsigned MaxBytesToEmit = 0);
+
+ /// Emit nops until the byte alignment \p ByteAlignment is reached.
+ ///
+ /// This used to align code where the alignment bytes may be executed. This
+ /// can emit different bytes for different sizes to optimize execution.
+ ///
+ /// \param ByteAlignment - The alignment to reach. This must be a power of
+ /// two on some targets.
+ /// \param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
+ /// the alignment cannot be reached in this many bytes, no bytes are
+ /// emitted.
+ virtual void EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit = 0);
+
+ /// Emit some number of copies of \p Value until the byte offset \p
+ /// Offset is reached.
+ ///
+ /// This is used to implement assembler directives such as .org.
+ ///
+ /// \param Offset - The offset to reach. This may be an expression, but the
+ /// expression must be associated with the current section.
+ /// \param Value - The value to use when filling bytes.
+ virtual void emitValueToOffset(const MCExpr *Offset, unsigned char Value,
+ SMLoc Loc);
+
+ virtual void
+ EmitCodePaddingBasicBlockStart(const MCCodePaddingContext &Context) {}
+
+ virtual void
+ EmitCodePaddingBasicBlockEnd(const MCCodePaddingContext &Context) {}
+
+ /// @}
+
+ /// 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
+ /// '.ident "version foo"' assembler directive.
+ virtual void EmitIdent(StringRef IdentString) {}
+
+ /// Associate a filename with a specified logical file number. This
+ /// implements the DWARF2 '.file 4 "foo.c"' assembler directive.
+ unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
+ StringRef Filename,
+ MD5::MD5Result *Checksum = nullptr,
+ Optional<StringRef> Source = None,
+ unsigned CUID = 0) {
+ return cantFail(
+ tryEmitDwarfFileDirective(FileNo, Directory, Filename, Checksum,
+ Source, CUID));
+ }
+
+ /// Associate a filename with a specified logical file number.
+ /// Also associate a directory, optional checksum, and optional source
+ /// text with the logical file. This implements the DWARF2
+ /// '.file 4 "dir/foo.c"' assembler directive, and the DWARF5
+ /// '.file 4 "dir/foo.c" md5 "..." source "..."' assembler directive.
+ virtual Expected<unsigned> tryEmitDwarfFileDirective(
+ unsigned FileNo, StringRef Directory, StringRef Filename,
+ MD5::MD5Result *Checksum = nullptr, Optional<StringRef> Source = None,
+ unsigned CUID = 0);
+
+ /// Specify the "root" file of the compilation, using the ".file 0" extension.
+ virtual void emitDwarfFile0Directive(StringRef Directory, StringRef Filename,
+ MD5::MD5Result *Checksum,
+ Optional<StringRef> Source,
+ unsigned CUID = 0);
+
+ virtual void EmitCFIBKeyFrame();
+
+ /// 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);
+
+ /// Associate a filename with a specified logical file number, and also
+ /// specify that file's checksum information. This implements the '.cv_file 4
+ /// "foo.c"' assembler directive. Returns true on success.
+ virtual bool EmitCVFileDirective(unsigned FileNo, StringRef Filename,
+ ArrayRef<uint8_t> Checksum,
+ unsigned ChecksumKind);
+
+ /// Introduces a function id for use with .cv_loc.
+ virtual bool EmitCVFuncIdDirective(unsigned FunctionId);
+
+ /// Introduces an inline call site id for use with .cv_loc. Includes
+ /// extra information for inline line table generation.
+ virtual bool EmitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc,
+ unsigned IAFile, unsigned IALine,
+ unsigned IACol, SMLoc Loc);
+
+ /// This implements the CodeView '.cv_loc' assembler directive.
+ virtual void EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
+ unsigned Line, unsigned Column,
+ bool PrologueEnd, bool IsStmt,
+ StringRef FileName, SMLoc Loc);
+
+ /// This implements the CodeView '.cv_linetable' assembler directive.
+ virtual void EmitCVLinetableDirective(unsigned FunctionId,
+ const MCSymbol *FnStart,
+ const MCSymbol *FnEnd);
+
+ /// This implements the CodeView '.cv_inline_linetable' assembler
+ /// directive.
+ virtual void EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
+ unsigned SourceFileId,
+ unsigned SourceLineNum,
+ const MCSymbol *FnStartSym,
+ const MCSymbol *FnEndSym);
+
+ /// This implements the CodeView '.cv_def_range' assembler
+ /// directive.
+ virtual void EmitCVDefRangeDirective(
+ ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
+ StringRef FixedSizePortion);
+
+ /// This implements the CodeView '.cv_stringtable' assembler directive.
+ virtual void EmitCVStringTableDirective() {}
+
+ /// This implements the CodeView '.cv_filechecksums' assembler directive.
+ virtual void EmitCVFileChecksumsDirective() {}
+
+ /// This implements the CodeView '.cv_filechecksumoffset' assembler
+ /// directive.
+ virtual void EmitCVFileChecksumOffsetDirective(unsigned FileNo) {}
+
+ /// This implements the CodeView '.cv_fpo_data' assembler directive.
+ virtual void EmitCVFPOData(const MCSymbol *ProcSym, SMLoc Loc = {}) {}
+
+ /// Emit the absolute difference between two symbols.
+ ///
+ /// \pre Offset of \c Hi is greater than the offset \c Lo.
+ virtual void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
+ unsigned Size);
+
+ /// Emit the absolute difference between two symbols encoded with ULEB128.
+ virtual void emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
+ const MCSymbol *Lo);
+
+ virtual MCSymbol *getDwarfLineTableSymbol(unsigned CUID);
+ virtual void EmitCFISections(bool EH, bool Debug);
+ void EmitCFIStartProc(bool IsSimple, SMLoc Loc = SMLoc());
+ void EmitCFIEndProc();
+ virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
+ virtual void EmitCFIDefCfaOffset(int64_t Offset);
+ virtual void EmitCFIDefCfaRegister(int64_t Register);
+ virtual void EmitCFIOffset(int64_t Register, int64_t Offset);
+ virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
+ virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
+ virtual void EmitCFIRememberState();
+ virtual void EmitCFIRestoreState();
+ virtual void EmitCFISameValue(int64_t Register);
+ virtual void EmitCFIRestore(int64_t Register);
+ virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
+ virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
+ virtual void EmitCFIEscape(StringRef Values);
+ virtual void EmitCFIReturnColumn(int64_t Register);
+ virtual void EmitCFIGnuArgsSize(int64_t Size);
+ virtual void EmitCFISignalFrame();
+ virtual void EmitCFIUndefined(int64_t Register);
+ virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
+ virtual void EmitCFIWindowSave();
+ virtual void EmitCFINegateRAState();
+
+ virtual void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc = SMLoc());
+ virtual void EmitWinCFIEndProc(SMLoc Loc = SMLoc());
+ /// This is used on platforms, such as Windows on ARM64, that require function
+ /// or funclet sizes to be emitted in .xdata before the End marker is emitted
+ /// for the frame. We cannot use the End marker, as it is not set at the
+ /// point of emitting .xdata, in order to indicate that the frame is active.
+ virtual void EmitWinCFIFuncletOrFuncEnd(SMLoc Loc = SMLoc());
+ virtual void EmitWinCFIStartChained(SMLoc Loc = SMLoc());
+ virtual void EmitWinCFIEndChained(SMLoc Loc = SMLoc());
+ virtual void EmitWinCFIPushReg(unsigned Register, SMLoc Loc = SMLoc());
+ virtual void EmitWinCFISetFrame(unsigned Register, unsigned Offset,
+ SMLoc Loc = SMLoc());
+ virtual void EmitWinCFIAllocStack(unsigned Size, SMLoc Loc = SMLoc());
+ virtual void EmitWinCFISaveReg(unsigned Register, unsigned Offset,
+ SMLoc Loc = SMLoc());
+ virtual void EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
+ SMLoc Loc = SMLoc());
+ virtual void EmitWinCFIPushFrame(bool Code, SMLoc Loc = SMLoc());
+ virtual void EmitWinCFIEndProlog(SMLoc Loc = SMLoc());
+ virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
+ SMLoc Loc = SMLoc());
+ virtual void EmitWinEHHandlerData(SMLoc Loc = SMLoc());
+
+ virtual void emitCGProfileEntry(const MCSymbolRefExpr *From,
+ const MCSymbolRefExpr *To, uint64_t Count);
+
+ /// Get the .pdata section used for the given section. Typically the given
+ /// section is either the main .text section or some other COMDAT .text
+ /// section, but it may be any section containing code.
+ MCSection *getAssociatedPDataSection(const MCSection *TextSec);
+
+ /// Get the .xdata section used for the given section.
+ MCSection *getAssociatedXDataSection(const MCSection *TextSec);
+
+ virtual void EmitSyntaxDirective();
+
+ /// Emit a .reloc directive.
+ /// Returns true if the relocation could not be emitted because Name is not
+ /// known.
+ virtual bool EmitRelocDirective(const MCExpr &Offset, StringRef Name,
+ const MCExpr *Expr, SMLoc Loc,
+ const MCSubtargetInfo &STI) {
+ return true;
+ }
+
+ virtual void EmitAddrsig() {}
+ virtual void EmitAddrsigSym(const MCSymbol *Sym) {}
+
+ /// Emit the given \p Instruction into the current section.
+ virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI);
+
+ /// Set the bundle alignment mode from now on in the section.
+ /// The argument is the power of 2 to which the alignment is set. The
+ /// value 0 means turn the bundle alignment off.
+ virtual void EmitBundleAlignMode(unsigned AlignPow2);
+
+ /// The following instructions are a bundle-locked group.
+ ///
+ /// \param AlignToEnd - If true, the bundle-locked group will be aligned to
+ /// the end of a bundle.
+ virtual void EmitBundleLock(bool AlignToEnd);
+
+ /// Ends a bundle-locked group.
+ virtual void EmitBundleUnlock();
+
+ /// 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);
+
+ /// Streamer specific finalization.
+ virtual void FinishImpl();
+ /// Finish emission of machine code.
+ void Finish();
+
+ virtual bool mayHaveInstructions(MCSection &Sec) const { return true; }
+};
+
+/// Create a dummy machine code streamer, which does nothing. This is useful for
+/// timing the assembler front end.
+MCStreamer *createNullStreamer(MCContext &Ctx);
+
+/// Create a machine code streamer which will print out assembly for the native
+/// target, suitable for compiling with a native assembler.
+///
+/// \param InstPrint - If given, the instruction printer to use. If not given
+/// the MCInst representation will be printed. This method takes ownership of
+/// InstPrint.
+///
+/// \param CE - If given, a code emitter to use to show the instruction
+/// encoding inline with the assembly. This method takes ownership of \p CE.
+///
+/// \param TAB - If given, a target asm backend to use to show the fixup
+/// information in conjunction with encoding information. This method takes
+/// ownership of \p TAB.
+///
+/// \param ShowInst - Whether to show the MCInst representation inline with
+/// the assembly.
+MCStreamer *createAsmStreamer(MCContext &Ctx,
+ std::unique_ptr<formatted_raw_ostream> OS,
+ bool isVerboseAsm, bool useDwarfDirectory,
+ MCInstPrinter *InstPrint, MCCodeEmitter *CE,
+ MCAsmBackend *TAB, bool ShowInst);
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCSTREAMER_H
diff --git a/clang-r353983/include/llvm/MC/MCSubtargetInfo.h b/clang-r353983/include/llvm/MC/MCSubtargetInfo.h
new file mode 100644
index 00000000..c7472a28
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCSubtargetInfo.h
@@ -0,0 +1,187 @@
+//===- llvm/MC/MCSubtargetInfo.h - Subtarget Information --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the subtarget options of a Target machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSUBTARGETINFO_H
+#define LLVM_MC_MCSUBTARGETINFO_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/MC/MCInstrItineraries.h"
+#include "llvm/MC/MCSchedule.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <string>
+
+namespace llvm {
+
+class MCInst;
+
+//===----------------------------------------------------------------------===//
+///
+/// Generic base class for all target subtargets.
+///
+class MCSubtargetInfo {
+ Triple TargetTriple;
+ std::string CPU; // CPU being targeted.
+ ArrayRef<SubtargetFeatureKV> ProcFeatures; // Processor feature list
+ ArrayRef<SubtargetFeatureKV> ProcDesc; // Processor descriptions
+
+ // Scheduler machine model
+ const SubtargetInfoKV *ProcSchedModels;
+ const MCWriteProcResEntry *WriteProcResTable;
+ const MCWriteLatencyEntry *WriteLatencyTable;
+ const MCReadAdvanceEntry *ReadAdvanceTable;
+ const MCSchedModel *CPUSchedModel;
+
+ const InstrStage *Stages; // Instruction itinerary stages
+ const unsigned *OperandCycles; // Itinerary operand cycles
+ const unsigned *ForwardingPaths;
+ FeatureBitset FeatureBits; // Feature bits for current CPU + FS
+
+public:
+ MCSubtargetInfo(const MCSubtargetInfo &) = default;
+ MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
+ ArrayRef<SubtargetFeatureKV> PF,
+ ArrayRef<SubtargetFeatureKV> PD,
+ const SubtargetInfoKV *ProcSched,
+ const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
+ const MCReadAdvanceEntry *RA, const InstrStage *IS,
+ const unsigned *OC, const unsigned *FP);
+ MCSubtargetInfo() = delete;
+ MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
+ MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
+ virtual ~MCSubtargetInfo() = default;
+
+ const Triple &getTargetTriple() const { return TargetTriple; }
+ StringRef getCPU() const { return CPU; }
+
+ const FeatureBitset& getFeatureBits() const { return FeatureBits; }
+ void setFeatureBits(const FeatureBitset &FeatureBits_) {
+ FeatureBits = FeatureBits_;
+ }
+
+ bool hasFeature(unsigned Feature) const {
+ return FeatureBits[Feature];
+ }
+
+protected:
+ /// Initialize the scheduling model and feature bits.
+ ///
+ /// FIXME: Find a way to stick this in the constructor, since it should only
+ /// be called during initialization.
+ void InitMCProcessorInfo(StringRef CPU, StringRef FS);
+
+public:
+ /// Set the features to the default for the given CPU with an appended feature
+ /// string.
+ void setDefaultFeatures(StringRef CPU, StringRef FS);
+
+ /// Toggle a feature and return the re-computed feature bits.
+ /// This version does not change the implied bits.
+ FeatureBitset ToggleFeature(uint64_t FB);
+
+ /// Toggle a feature and return the re-computed feature bits.
+ /// This version does not change the implied bits.
+ FeatureBitset ToggleFeature(const FeatureBitset& FB);
+
+ /// Toggle a set of features and return the re-computed feature bits.
+ /// This version will also change all implied bits.
+ FeatureBitset ToggleFeature(StringRef FS);
+
+ /// Apply a feature flag and return the re-computed feature bits, including
+ /// all feature bits implied by the flag.
+ FeatureBitset ApplyFeatureFlag(StringRef FS);
+
+ /// Check whether the subtarget features are enabled/disabled as per
+ /// the provided string, ignoring all other features.
+ bool checkFeatures(StringRef FS) const;
+
+ /// Get the machine model of a CPU.
+ const MCSchedModel &getSchedModelForCPU(StringRef CPU) const;
+
+ /// Get the machine model for this subtarget's CPU.
+ const MCSchedModel &getSchedModel() const { return *CPUSchedModel; }
+
+ /// Return an iterator at the first process resource consumed by the given
+ /// scheduling class.
+ const MCWriteProcResEntry *getWriteProcResBegin(
+ const MCSchedClassDesc *SC) const {
+ return &WriteProcResTable[SC->WriteProcResIdx];
+ }
+ const MCWriteProcResEntry *getWriteProcResEnd(
+ const MCSchedClassDesc *SC) const {
+ return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
+ }
+
+ const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
+ unsigned DefIdx) const {
+ assert(DefIdx < SC->NumWriteLatencyEntries &&
+ "MachineModel does not specify a WriteResource for DefIdx");
+
+ return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
+ }
+
+ int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
+ unsigned WriteResID) const {
+ // TODO: The number of read advance entries in a class can be significant
+ // (~50). Consider compressing the WriteID into a dense ID of those that are
+ // used by ReadAdvance and representing them as a bitset.
+ for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
+ *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
+ if (I->UseIdx < UseIdx)
+ continue;
+ if (I->UseIdx > UseIdx)
+ break;
+ // Find the first WriteResIdx match, which has the highest cycle count.
+ if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
+ return I->Cycles;
+ }
+ }
+ return 0;
+ }
+
+ /// Return the set of ReadAdvance entries declared by the scheduling class
+ /// descriptor in input.
+ ArrayRef<MCReadAdvanceEntry>
+ getReadAdvanceEntries(const MCSchedClassDesc &SC) const {
+ if (!SC.NumReadAdvanceEntries)
+ return ArrayRef<MCReadAdvanceEntry>();
+ return ArrayRef<MCReadAdvanceEntry>(&ReadAdvanceTable[SC.ReadAdvanceIdx],
+ SC.NumReadAdvanceEntries);
+ }
+
+ /// Get scheduling itinerary of a CPU.
+ InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
+
+ /// Initialize an InstrItineraryData instance.
+ void initInstrItins(InstrItineraryData &InstrItins) const;
+
+ /// Resolve a variant scheduling class for the given MCInst and CPU.
+ virtual unsigned
+ resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI,
+ unsigned CPUID) const {
+ return 0;
+ }
+
+ /// Check whether the CPU string is valid.
+ bool isCPUStringValid(StringRef CPU) const {
+ auto Found = std::lower_bound(ProcDesc.begin(), ProcDesc.end(), CPU);
+ return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCSUBTARGETINFO_H
diff --git a/clang-r353983/include/llvm/MC/MCSymbol.h b/clang-r353983/include/llvm/MC/MCSymbol.h
new file mode 100644
index 00000000..273e5a33
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCSymbol.h
@@ -0,0 +1,428 @@
+//===- MCSymbol.h - Machine Code Symbols ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCSymbol class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSYMBOL_H
+#define LLVM_MC_MCSYMBOL_H
+
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCFragment.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+
+namespace llvm {
+
+class MCAsmInfo;
+class MCContext;
+class MCExpr;
+class MCSection;
+class raw_ostream;
+
+/// 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 {
+protected:
+ /// The kind of the symbol. If it is any value other than unset then this
+ /// class is actually one of the appropriate subclasses of MCSymbol.
+ enum SymbolKind {
+ SymbolKindUnset,
+ SymbolKindCOFF,
+ SymbolKindELF,
+ SymbolKindMachO,
+ SymbolKindWasm,
+ };
+
+ /// A symbol can contain an Offset, or Value, or be Common, but never more
+ /// than one of these.
+ enum Contents : uint8_t {
+ SymContentsUnset,
+ SymContentsOffset,
+ SymContentsVariable,
+ SymContentsCommon,
+ };
+
+ // Special sentinal value for the absolute pseudo fragment.
+ static MCFragment *AbsolutePseudoFragment;
+
+ /// If a symbol has a Fragment, the section is implied, so we only need
+ /// one pointer.
+ /// The special AbsolutePseudoFragment value is for absolute symbols.
+ /// If this is a variable symbol, this caches the variable value's fragment.
+ /// FIXME: We might be able to simplify this by having the asm streamer create
+ /// dummy fragments.
+ /// If this is a section, then it gives the symbol is defined in. This is null
+ /// for undefined symbols.
+ ///
+ /// If this is a fragment, then it gives the fragment this symbol's value is
+ /// relative to, if any.
+ ///
+ /// For the 'HasName' integer, this is true if this symbol is named.
+ /// A named symbol will have a pointer to the name allocated in the bytes
+ /// immediately prior to the MCSymbol.
+ mutable PointerIntPair<MCFragment *, 1> FragmentAndHasName;
+
+ /// 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;
+
+ /// True if this symbol can be redefined.
+ unsigned IsRedefinable : 1;
+
+ /// IsUsed - True if this symbol has been used.
+ mutable unsigned IsUsed : 1;
+
+ mutable unsigned IsRegistered : 1;
+
+ /// This symbol is visible outside this translation unit.
+ mutable unsigned IsExternal : 1;
+
+ /// This symbol is private extern.
+ mutable unsigned IsPrivateExtern : 1;
+
+ /// LLVM RTTI discriminator. This is actually a SymbolKind enumerator, but is
+ /// unsigned to avoid sign extension and achieve better bitpacking with MSVC.
+ unsigned Kind : 3;
+
+ /// True if we have created a relocation that uses this symbol.
+ mutable unsigned IsUsedInReloc : 1;
+
+ /// This is actually a Contents enumerator, but is unsigned to avoid sign
+ /// extension and achieve better bitpacking with MSVC.
+ unsigned SymbolContents : 2;
+
+ /// The alignment of the symbol, if it is 'common', or -1.
+ ///
+ /// The alignment is stored as log2(align) + 1. This allows all values from
+ /// 0 to 2^31 to be stored which is every power of 2 representable by an
+ /// unsigned.
+ enum : unsigned { NumCommonAlignmentBits = 5 };
+ unsigned CommonAlignLog2 : NumCommonAlignmentBits;
+
+ /// The Flags field is used by object file implementations to store
+ /// additional per symbol information which is not easily classified.
+ enum : unsigned { NumFlagsBits = 16 };
+ mutable uint32_t Flags : NumFlagsBits;
+
+ /// Index field, for use by the object file implementation.
+ mutable uint32_t Index = 0;
+
+ union {
+ /// The offset to apply to the fragment address to form this symbol's value.
+ uint64_t Offset;
+
+ /// The size of the symbol, if it is 'common'.
+ uint64_t CommonSize;
+
+ /// If non-null, the value for a variable symbol.
+ const MCExpr *Value;
+ };
+
+ // MCContext creates and uniques these.
+ friend class MCExpr;
+ friend class MCContext;
+
+ /// The name for a symbol.
+ /// MCSymbol contains a uint64_t so is probably aligned to 8. On a 32-bit
+ /// system, the name is a pointer so isn't going to satisfy the 8 byte
+ /// alignment of uint64_t. Account for that here.
+ using NameEntryStorageTy = union {
+ const StringMapEntry<bool> *NameEntry;
+ uint64_t AlignmentPadding;
+ };
+
+ MCSymbol(SymbolKind Kind, const StringMapEntry<bool> *Name, bool isTemporary)
+ : IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false),
+ IsRegistered(false), IsExternal(false), IsPrivateExtern(false),
+ Kind(Kind), IsUsedInReloc(false), SymbolContents(SymContentsUnset),
+ CommonAlignLog2(0), Flags(0) {
+ Offset = 0;
+ FragmentAndHasName.setInt(!!Name);
+ if (Name)
+ getNameEntryPtr() = Name;
+ }
+
+ // Provide custom new/delete as we will only allocate space for a name
+ // if we need one.
+ void *operator new(size_t s, const StringMapEntry<bool> *Name,
+ MCContext &Ctx);
+
+private:
+ void operator delete(void *);
+ /// Placement delete - required by std, but never called.
+ void operator delete(void*, unsigned) {
+ llvm_unreachable("Constructor throws?");
+ }
+ /// Placement delete - required by std, but never called.
+ void operator delete(void*, unsigned, bool) {
+ llvm_unreachable("Constructor throws?");
+ }
+
+ MCSection *getSectionPtr() const {
+ if (MCFragment *F = getFragment()) {
+ assert(F != AbsolutePseudoFragment);
+ return F->getParent();
+ }
+ return nullptr;
+ }
+
+ /// Get a reference to the name field. Requires that we have a name
+ const StringMapEntry<bool> *&getNameEntryPtr() {
+ assert(FragmentAndHasName.getInt() && "Name is required");
+ NameEntryStorageTy *Name = reinterpret_cast<NameEntryStorageTy *>(this);
+ return (*(Name - 1)).NameEntry;
+ }
+ const StringMapEntry<bool> *&getNameEntryPtr() const {
+ return const_cast<MCSymbol*>(this)->getNameEntryPtr();
+ }
+
+public:
+ MCSymbol(const MCSymbol &) = delete;
+ MCSymbol &operator=(const MCSymbol &) = delete;
+
+ /// getName - Get the symbol name.
+ StringRef getName() const {
+ if (!FragmentAndHasName.getInt())
+ return StringRef();
+
+ return getNameEntryPtr()->first();
+ }
+
+ bool isRegistered() const { return IsRegistered; }
+ void setIsRegistered(bool Value) const { IsRegistered = Value; }
+
+ void setUsedInReloc() const { IsUsedInReloc = true; }
+ bool isUsedInReloc() const { return IsUsedInReloc; }
+
+ /// \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; }
+
+ /// Check if this symbol is redefinable.
+ bool isRedefinable() const { return IsRedefinable; }
+ /// Mark this symbol as redefinable.
+ void setRedefinable(bool Value) { IsRedefinable = Value; }
+ /// Prepare this symbol to be redefined.
+ void redefineIfPossible() {
+ if (IsRedefinable) {
+ if (SymbolContents == SymContentsVariable) {
+ Value = nullptr;
+ SymbolContents = SymContentsUnset;
+ }
+ setUndefined();
+ IsRedefinable = false;
+ }
+ }
+
+ /// @}
+ /// \name Associated Sections
+ /// @{
+
+ /// isDefined - Check if this symbol is defined (i.e., it has an address).
+ ///
+ /// Defined symbols are either absolute or in some section.
+ bool isDefined() const { return !isUndefined(); }
+
+ /// isInSection - Check if this symbol is defined in some section (i.e., it
+ /// is defined but not absolute).
+ bool isInSection() const {
+ return isDefined() && !isAbsolute();
+ }
+
+ /// isUndefined - Check if this symbol undefined (i.e., implicitly defined).
+ bool isUndefined(bool SetUsed = true) const {
+ return getFragment(SetUsed) == nullptr;
+ }
+
+ /// isAbsolute - Check if this is an absolute symbol.
+ bool isAbsolute() const {
+ return getFragment() == AbsolutePseudoFragment;
+ }
+
+ /// 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 fragment \p F.
+ void setFragment(MCFragment *F) const {
+ assert(!isVariable() && "Cannot set fragment of variable");
+ FragmentAndHasName.setPointer(F);
+ }
+
+ /// Mark the symbol as undefined.
+ void setUndefined() { FragmentAndHasName.setPointer(nullptr); }
+
+ bool isELF() const { return Kind == SymbolKindELF; }
+
+ bool isCOFF() const { return Kind == SymbolKindCOFF; }
+
+ bool isMachO() const { return Kind == SymbolKindMachO; }
+
+ bool isWasm() const { return Kind == SymbolKindWasm; }
+
+ /// @}
+ /// \name Variable Symbols
+ /// @{
+
+ /// isVariable - Check if this is a variable symbol.
+ bool isVariable() const {
+ return SymbolContents == SymContentsVariable;
+ }
+
+ /// getVariableValue - Get the value for variable symbols.
+ const MCExpr *getVariableValue(bool SetUsed = true) const {
+ assert(isVariable() && "Invalid accessor!");
+ IsUsed |= SetUsed;
+ return Value;
+ }
+
+ void setVariableValue(const MCExpr *Value);
+
+ /// @}
+
+ /// Get the (implementation defined) index.
+ uint32_t getIndex() const {
+ return Index;
+ }
+
+ /// Set the (implementation defined) index.
+ void setIndex(uint32_t Value) const {
+ Index = Value;
+ }
+
+ bool isUnset() const { return SymbolContents == SymContentsUnset; }
+
+ uint64_t getOffset() const {
+ assert((SymbolContents == SymContentsUnset ||
+ SymbolContents == SymContentsOffset) &&
+ "Cannot get offset for a common/variable symbol");
+ return Offset;
+ }
+ void setOffset(uint64_t Value) {
+ assert((SymbolContents == SymContentsUnset ||
+ SymbolContents == SymContentsOffset) &&
+ "Cannot set offset for a common/variable symbol");
+ Offset = Value;
+ SymbolContents = SymContentsOffset;
+ }
+
+ /// Return the size of a 'common' symbol.
+ uint64_t getCommonSize() const {
+ assert(isCommon() && "Not a 'common' symbol!");
+ return CommonSize;
+ }
+
+ /// 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;
+ SymbolContents = SymContentsCommon;
+
+ assert((!Align || isPowerOf2_32(Align)) &&
+ "Alignment must be a power of 2");
+ unsigned Log2Align = Log2_32(Align) + 1;
+ assert(Log2Align < (1U << NumCommonAlignmentBits) &&
+ "Out of range alignment");
+ CommonAlignLog2 = Log2Align;
+ }
+
+ /// Return the alignment of a 'common' symbol.
+ unsigned getCommonAlignment() const {
+ assert(isCommon() && "Not a 'common' symbol!");
+ return CommonAlignLog2 ? (1U << (CommonAlignLog2 - 1)) : 0;
+ }
+
+ /// Declare this symbol as being 'common'.
+ ///
+ /// \param Size - The size of the symbol.
+ /// \param Align - The alignment of the symbol.
+ /// \return True if symbol was already declared as a different type
+ bool declareCommon(uint64_t Size, unsigned Align) {
+ assert(isCommon() || getOffset() == 0);
+ if(isCommon()) {
+ if(CommonSize != Size || getCommonAlignment() != Align)
+ return true;
+ } else
+ setCommon(Size, Align);
+ return false;
+ }
+
+ /// Is this a 'common' symbol.
+ bool isCommon() const {
+ return SymbolContents == SymContentsCommon;
+ }
+
+ MCFragment *getFragment(bool SetUsed = true) const {
+ MCFragment *Fragment = FragmentAndHasName.getPointer();
+ if (Fragment || !isVariable())
+ return Fragment;
+ Fragment = getVariableValue(SetUsed)->findAssociatedFragment();
+ FragmentAndHasName.setPointer(Fragment);
+ return Fragment;
+ }
+
+ bool isExternal() const { return IsExternal; }
+ void setExternal(bool Value) const { IsExternal = Value; }
+
+ bool isPrivateExtern() const { return IsPrivateExtern; }
+ void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
+
+ /// print - Print the value to the stream \p OS.
+ void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
+
+ /// dump - Print the value to stderr.
+ void dump() const;
+
+protected:
+ /// Get the (implementation defined) symbol flags.
+ uint32_t getFlags() const { return Flags; }
+
+ /// Set the (implementation defined) symbol flags.
+ void setFlags(uint32_t Value) const {
+ assert(Value < (1U << NumFlagsBits) && "Out of range flags");
+ Flags = Value;
+ }
+
+ /// Modify the flags via a mask
+ void modifyFlags(uint32_t Value, uint32_t Mask) const {
+ assert(Value < (1U << NumFlagsBits) && "Out of range flags");
+ Flags = (Flags & ~Mask) | Value;
+ }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) {
+ Sym.print(OS, nullptr);
+ return OS;
+}
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCSYMBOL_H
diff --git a/clang-r353983/include/llvm/MC/MCSymbolCOFF.h b/clang-r353983/include/llvm/MC/MCSymbolCOFF.h
new file mode 100644
index 00000000..94087ce8
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCSymbolCOFF.h
@@ -0,0 +1,66 @@
+//===- MCSymbolCOFF.h - ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSYMBOLCOFF_H
+#define LLVM_MC_MCSYMBOLCOFF_H
+
+#include "llvm/MC/MCSymbol.h"
+#include <cstdint>
+
+namespace llvm {
+
+class MCSymbolCOFF : public MCSymbol {
+ /// This corresponds to the e_type field of the COFF symbol.
+ mutable uint16_t Type = 0;
+
+ enum SymbolFlags : uint16_t {
+ SF_ClassMask = 0x00FF,
+ SF_ClassShift = 0,
+
+ SF_WeakExternal = 0x0100,
+ SF_SafeSEH = 0x0200,
+ };
+
+public:
+ MCSymbolCOFF(const StringMapEntry<bool> *Name, bool isTemporary)
+ : MCSymbol(SymbolKindCOFF, Name, isTemporary) {}
+
+ uint16_t getType() const {
+ return Type;
+ }
+ void setType(uint16_t Ty) const {
+ Type = Ty;
+ }
+
+ uint16_t getClass() const {
+ return (getFlags() & SF_ClassMask) >> SF_ClassShift;
+ }
+ void setClass(uint16_t StorageClass) const {
+ modifyFlags(StorageClass << SF_ClassShift, SF_ClassMask);
+ }
+
+ bool isWeakExternal() const {
+ return getFlags() & SF_WeakExternal;
+ }
+ void setIsWeakExternal() const {
+ modifyFlags(SF_WeakExternal, SF_WeakExternal);
+ }
+
+ bool isSafeSEH() const {
+ return getFlags() & SF_SafeSEH;
+ }
+ void setIsSafeSEH() const {
+ modifyFlags(SF_SafeSEH, SF_SafeSEH);
+ }
+
+ static bool classof(const MCSymbol *S) { return S->isCOFF(); }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCSYMBOLCOFF_H
diff --git a/clang-r353983/include/llvm/MC/MCSymbolELF.h b/clang-r353983/include/llvm/MC/MCSymbolELF.h
new file mode 100644
index 00000000..34e5c434
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCSymbolELF.h
@@ -0,0 +1,53 @@
+//===- MCSymbolELF.h - -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_MC_MCSYMBOLELF_H
+#define LLVM_MC_MCSYMBOLELF_H
+
+#include "llvm/MC/MCSymbol.h"
+
+namespace llvm {
+class MCSymbolELF : public MCSymbol {
+ /// 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;
+
+public:
+ MCSymbolELF(const StringMapEntry<bool> *Name, bool isTemporary)
+ : MCSymbol(SymbolKindELF, Name, isTemporary) {}
+ void setSize(const MCExpr *SS) { SymbolSize = SS; }
+
+ const MCExpr *getSize() const { return SymbolSize; }
+
+ void setVisibility(unsigned Visibility);
+ unsigned getVisibility() const;
+
+ void setOther(unsigned Other);
+ unsigned getOther() const;
+
+ void setType(unsigned Type) const;
+ unsigned getType() const;
+
+ void setBinding(unsigned Binding) const;
+ unsigned getBinding() const;
+
+ bool isBindingSet() const;
+
+ void setIsWeakrefUsedInReloc() const;
+ bool isWeakrefUsedInReloc() const;
+
+ void setIsSignature() const;
+ bool isSignature() const;
+
+ static bool classof(const MCSymbol *S) { return S->isELF(); }
+
+private:
+ void setIsBindingSet() const;
+};
+}
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCSymbolMachO.h b/clang-r353983/include/llvm/MC/MCSymbolMachO.h
new file mode 100644
index 00000000..8f9ff564
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCSymbolMachO.h
@@ -0,0 +1,140 @@
+//===- MCSymbolMachO.h - ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_MC_MCSYMBOLMACHO_H
+#define LLVM_MC_MCSYMBOLMACHO_H
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/MC/MCSymbol.h"
+
+namespace llvm {
+class MCSymbolMachO : public MCSymbol {
+ /// We store the value for the 'desc' symbol field in the
+ /// lowest 16 bits of the implementation defined flags.
+ enum MachOSymbolFlags : uint16_t { // See <mach-o/nlist.h>.
+ SF_DescFlagsMask = 0xFFFF,
+
+ // Reference type flags.
+ SF_ReferenceTypeMask = 0x0007,
+ SF_ReferenceTypeUndefinedNonLazy = 0x0000,
+ SF_ReferenceTypeUndefinedLazy = 0x0001,
+ SF_ReferenceTypeDefined = 0x0002,
+ SF_ReferenceTypePrivateDefined = 0x0003,
+ SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004,
+ SF_ReferenceTypePrivateUndefinedLazy = 0x0005,
+
+ // Other 'desc' flags.
+ SF_ThumbFunc = 0x0008,
+ SF_NoDeadStrip = 0x0020,
+ SF_WeakReference = 0x0040,
+ SF_WeakDefinition = 0x0080,
+ SF_SymbolResolver = 0x0100,
+ SF_AltEntry = 0x0200,
+ SF_Cold = 0x0400,
+
+ // Common alignment
+ SF_CommonAlignmentMask = 0xF0FF,
+ SF_CommonAlignmentShift = 8
+ };
+
+public:
+ MCSymbolMachO(const StringMapEntry<bool> *Name, bool isTemporary)
+ : MCSymbol(SymbolKindMachO, Name, isTemporary) {}
+
+ // Reference type methods.
+
+ void clearReferenceType() const {
+ modifyFlags(0, SF_ReferenceTypeMask);
+ }
+
+ void setReferenceTypeUndefinedLazy(bool Value) const {
+ modifyFlags(Value ? SF_ReferenceTypeUndefinedLazy : 0,
+ SF_ReferenceTypeUndefinedLazy);
+ }
+
+ // Other 'desc' methods.
+
+ void setThumbFunc() const {
+ modifyFlags(SF_ThumbFunc, SF_ThumbFunc);
+ }
+
+ bool isNoDeadStrip() const {
+ return getFlags() & SF_NoDeadStrip;
+ }
+ void setNoDeadStrip() const {
+ modifyFlags(SF_NoDeadStrip, SF_NoDeadStrip);
+ }
+
+ bool isWeakReference() const {
+ return getFlags() & SF_WeakReference;
+ }
+ void setWeakReference() const {
+ modifyFlags(SF_WeakReference, SF_WeakReference);
+ }
+
+ bool isWeakDefinition() const {
+ return getFlags() & SF_WeakDefinition;
+ }
+ void setWeakDefinition() const {
+ modifyFlags(SF_WeakDefinition, SF_WeakDefinition);
+ }
+
+ bool isSymbolResolver() const {
+ return getFlags() & SF_SymbolResolver;
+ }
+ void setSymbolResolver() const {
+ modifyFlags(SF_SymbolResolver, SF_SymbolResolver);
+ }
+
+ void setAltEntry() const {
+ modifyFlags(SF_AltEntry, SF_AltEntry);
+ }
+
+ bool isAltEntry() const {
+ return getFlags() & SF_AltEntry;
+ }
+
+ void setCold() const { modifyFlags(SF_Cold, SF_Cold); }
+
+ bool isCold() const { return getFlags() & SF_Cold; }
+
+ void setDesc(unsigned Value) const {
+ assert(Value == (Value & SF_DescFlagsMask) &&
+ "Invalid .desc value!");
+ setFlags(Value & SF_DescFlagsMask);
+ }
+
+ /// Get the encoded value of the flags as they will be emitted in to
+ /// the MachO binary
+ uint16_t getEncodedFlags(bool EncodeAsAltEntry) const {
+ uint16_t Flags = getFlags();
+
+ // Common alignment is packed into the 'desc' bits.
+ if (isCommon()) {
+ if (unsigned Align = getCommonAlignment()) {
+ unsigned Log2Size = Log2_32(Align);
+ assert((1U << Log2Size) == Align && "Invalid 'common' alignment!");
+ if (Log2Size > 15)
+ report_fatal_error("invalid 'common' alignment '" +
+ Twine(Align) + "' for '" + getName() + "'",
+ false);
+ Flags = (Flags & SF_CommonAlignmentMask) |
+ (Log2Size << SF_CommonAlignmentShift);
+ }
+ }
+
+ if (EncodeAsAltEntry)
+ Flags |= SF_AltEntry;
+
+ return Flags;
+ }
+
+ static bool classof(const MCSymbol *S) { return S->isMachO(); }
+};
+}
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCSymbolWasm.h b/clang-r353983/include/llvm/MC/MCSymbolWasm.h
new file mode 100644
index 00000000..88759fe4
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCSymbolWasm.h
@@ -0,0 +1,99 @@
+//===- MCSymbolWasm.h - ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_MC_MCSYMBOLWASM_H
+#define LLVM_MC_MCSYMBOLWASM_H
+
+#include "llvm/BinaryFormat/Wasm.h"
+#include "llvm/MC/MCSymbol.h"
+
+namespace llvm {
+
+class MCSymbolWasm : public MCSymbol {
+ wasm::WasmSymbolType Type = wasm::WASM_SYMBOL_TYPE_DATA;
+ bool IsWeak = false;
+ bool IsHidden = false;
+ bool IsComdat = false;
+ Optional<std::string> ImportModule;
+ Optional<std::string> ImportName;
+ wasm::WasmSignature *Signature = nullptr;
+ Optional<wasm::WasmGlobalType> GlobalType;
+ Optional<wasm::WasmEventType> EventType;
+
+ /// 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;
+
+public:
+ // Use a module name of "env" for now, for compatibility with existing tools.
+ // This is temporary, and may change, as the ABI is not yet stable.
+ MCSymbolWasm(const StringMapEntry<bool> *Name, bool isTemporary)
+ : MCSymbol(SymbolKindWasm, Name, isTemporary) {}
+ static bool classof(const MCSymbol *S) { return S->isWasm(); }
+
+ const MCExpr *getSize() const { return SymbolSize; }
+ void setSize(const MCExpr *SS) { SymbolSize = SS; }
+
+ bool isFunction() const { return Type == wasm::WASM_SYMBOL_TYPE_FUNCTION; }
+ bool isData() const { return Type == wasm::WASM_SYMBOL_TYPE_DATA; }
+ bool isGlobal() const { return Type == wasm::WASM_SYMBOL_TYPE_GLOBAL; }
+ bool isSection() const { return Type == wasm::WASM_SYMBOL_TYPE_SECTION; }
+ bool isEvent() const { return Type == wasm::WASM_SYMBOL_TYPE_EVENT; }
+ wasm::WasmSymbolType getType() const { return Type; }
+ void setType(wasm::WasmSymbolType type) { Type = type; }
+
+ bool isExported() const {
+ return getFlags() & wasm::WASM_SYMBOL_EXPORTED;
+ }
+ void setExported() const {
+ modifyFlags(wasm::WASM_SYMBOL_EXPORTED, wasm::WASM_SYMBOL_EXPORTED);
+ }
+
+ bool isWeak() const { return IsWeak; }
+ void setWeak(bool isWeak) { IsWeak = isWeak; }
+
+ bool isHidden() const { return IsHidden; }
+ void setHidden(bool isHidden) { IsHidden = isHidden; }
+
+ bool isComdat() const { return IsComdat; }
+ void setComdat(bool isComdat) { IsComdat = isComdat; }
+
+ const StringRef getImportModule() const {
+ if (ImportModule.hasValue()) {
+ return ImportModule.getValue();
+ }
+ return "env";
+ }
+ void setImportModule(StringRef Name) { ImportModule = Name; }
+
+ const StringRef getImportName() const {
+ if (ImportName.hasValue()) {
+ return ImportName.getValue();
+ }
+ return getName();
+ }
+ void setImportName(StringRef Name) { ImportName = Name; }
+
+ const wasm::WasmSignature *getSignature() const { return Signature; }
+ void setSignature(wasm::WasmSignature *Sig) { Signature = Sig; }
+
+ const wasm::WasmGlobalType &getGlobalType() const {
+ assert(GlobalType.hasValue());
+ return GlobalType.getValue();
+ }
+ void setGlobalType(wasm::WasmGlobalType GT) { GlobalType = GT; }
+
+ const wasm::WasmEventType &getEventType() const {
+ assert(EventType.hasValue());
+ return EventType.getValue();
+ }
+ void setEventType(wasm::WasmEventType ET) { EventType = ET; }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCSYMBOLWASM_H
diff --git a/clang-r353983/include/llvm/MC/MCTargetOptions.h b/clang-r353983/include/llvm/MC/MCTargetOptions.h
new file mode 100644
index 00000000..087d1553
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCTargetOptions.h
@@ -0,0 +1,79 @@
+//===- MCTargetOptions.h - MC Target Options --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCTARGETOPTIONS_H
+#define LLVM_MC_MCTARGETOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+enum class ExceptionHandling {
+ None, /// No exception support
+ DwarfCFI, /// DWARF-like instruction based exceptions
+ SjLj, /// setjmp/longjmp based exceptions
+ ARM, /// ARM EHABI
+ WinEH, /// Windows Exception Handling
+ Wasm, /// WebAssembly Exception Handling
+};
+
+enum class DebugCompressionType {
+ None, /// No compression
+ GNU, /// zlib-gnu style compression
+ Z, /// zlib style complession
+};
+
+class StringRef;
+
+class MCTargetOptions {
+public:
+ enum AsmInstrumentation {
+ AsmInstrumentationNone,
+ AsmInstrumentationAddress
+ };
+
+ /// Enables AddressSanitizer instrumentation at machine level.
+ bool SanitizeAddress : 1;
+
+ bool MCRelaxAll : 1;
+ bool MCNoExecStack : 1;
+ bool MCFatalWarnings : 1;
+ bool MCNoWarn : 1;
+ bool MCNoDeprecatedWarn : 1;
+ bool MCSaveTempLabels : 1;
+ bool MCUseDwarfDirectory : 1;
+ bool MCIncrementalLinkerCompatible : 1;
+ bool MCPIECopyRelocations : 1;
+ bool ShowMCEncoding : 1;
+ bool ShowMCInst : 1;
+ bool AsmVerbose : 1;
+
+ /// Preserve Comments in Assembly.
+ bool PreserveAsmComments : 1;
+
+ int DwarfVersion = 0;
+
+ std::string ABIName;
+ std::string SplitDwarfFile;
+
+ /// Additional paths to search for `.include` directives when using the
+ /// integrated assembler.
+ std::vector<std::string> IASSearchPaths;
+
+ MCTargetOptions();
+
+ /// getABIName - If this returns a non-empty string this represents the
+ /// textual name of the ABI that we want the backend to use, e.g. o32, or
+ /// aapcs-linux.
+ StringRef getABIName() const;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCTARGETOPTIONS_H
diff --git a/clang-r353983/include/llvm/MC/MCTargetOptionsCommandFlags.inc b/clang-r353983/include/llvm/MC/MCTargetOptionsCommandFlags.inc
new file mode 100644
index 00000000..f8129463
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCTargetOptionsCommandFlags.inc
@@ -0,0 +1,79 @@
+//===-- MCTargetOptionsCommandFlags.h --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains machine code-specific flags that are shared between
+// different command line tools.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCTARGETOPTIONSCOMMANDFLAGS_H
+#define LLVM_MC_MCTARGETOPTIONSCOMMANDFLAGS_H
+
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Support/CommandLine.h"
+using namespace llvm;
+
+static cl::opt<MCTargetOptions::AsmInstrumentation> AsmInstrumentation(
+ "asm-instrumentation", cl::desc("Instrumentation of inline assembly and "
+ "assembly source files"),
+ cl::init(MCTargetOptions::AsmInstrumentationNone),
+ cl::values(clEnumValN(MCTargetOptions::AsmInstrumentationNone, "none",
+ "no instrumentation at all"),
+ clEnumValN(MCTargetOptions::AsmInstrumentationAddress, "address",
+ "instrument instructions with memory arguments")));
+
+static cl::opt<bool> RelaxAll("mc-relax-all",
+ cl::desc("When used with filetype=obj, "
+ "relax all fixups in the emitted object file"));
+
+static cl::opt<bool> IncrementalLinkerCompatible(
+ "incremental-linker-compatible",
+ cl::desc(
+ "When used with filetype=obj, "
+ "emit an object file which can be used with an incremental linker"));
+
+static cl::opt<bool> PIECopyRelocations("pie-copy-relocations", cl::desc("PIE Copy Relocations"));
+
+static cl::opt<int> DwarfVersion("dwarf-version", cl::desc("Dwarf version"),
+ cl::init(0));
+
+static cl::opt<bool> ShowMCInst("asm-show-inst",
+ cl::desc("Emit internal instruction representation to "
+ "assembly file"));
+
+static cl::opt<bool> FatalWarnings("fatal-warnings",
+ cl::desc("Treat warnings as errors"));
+
+static cl::opt<bool> NoWarn("no-warn", cl::desc("Suppress all warnings"));
+static cl::alias NoWarnW("W", cl::desc("Alias for --no-warn"), cl::aliasopt(NoWarn));
+
+static cl::opt<bool> NoDeprecatedWarn("no-deprecated-warn",
+ cl::desc("Suppress all deprecated warnings"));
+
+static cl::opt<std::string>
+ABIName("target-abi", cl::Hidden,
+ cl::desc("The name of the ABI to be targeted from the backend."),
+ cl::init(""));
+
+static MCTargetOptions InitMCTargetOptionsFromFlags() {
+ MCTargetOptions Options;
+ Options.SanitizeAddress =
+ (AsmInstrumentation == MCTargetOptions::AsmInstrumentationAddress);
+ Options.MCRelaxAll = RelaxAll;
+ Options.MCIncrementalLinkerCompatible = IncrementalLinkerCompatible;
+ Options.MCPIECopyRelocations = PIECopyRelocations;
+ Options.DwarfVersion = DwarfVersion;
+ Options.ShowMCInst = ShowMCInst;
+ Options.ABIName = ABIName;
+ Options.MCFatalWarnings = FatalWarnings;
+ Options.MCNoWarn = NoWarn;
+ Options.MCNoDeprecatedWarn = NoDeprecatedWarn;
+ return Options;
+}
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCValue.h b/clang-r353983/include/llvm/MC/MCValue.h
new file mode 100644
index 00000000..0be7ce70
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCValue.h
@@ -0,0 +1,86 @@
+//===-- llvm/MC/MCValue.h - MCValue class -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCValue class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCVALUE_H
+#define LLVM_MC_MCVALUE_H
+
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+class MCAsmInfo;
+class raw_ostream;
+
+/// This represents an "assembler immediate".
+///
+/// In its most general form, this can hold ":Kind:(SymbolA - SymbolB +
+/// imm64)". Not all targets supports relocations of this general form, but we
+/// need to represent this anyway.
+///
+/// In general both SymbolA and SymbolB will also have a modifier
+/// analogous to the top-level Kind. Current targets are not expected
+/// to make use of both though. The choice comes down to whether
+/// relocation modifiers apply to the closest symbol or the whole
+/// expression.
+///
+/// Note that this class must remain a simple POD value class, because we need
+/// it to live in unions etc.
+class MCValue {
+ const MCSymbolRefExpr *SymA = nullptr, *SymB = nullptr;
+ int64_t Cst = 0;
+ uint32_t RefKind = 0;
+
+public:
+ MCValue() = default;
+ int64_t getConstant() const { return Cst; }
+ const MCSymbolRefExpr *getSymA() const { return SymA; }
+ const MCSymbolRefExpr *getSymB() const { return SymB; }
+ uint32_t getRefKind() const { return RefKind; }
+
+ /// Is this an absolute (as opposed to relocatable) value.
+ bool isAbsolute() const { return !SymA && !SymB; }
+
+ /// Print the value to the stream \p OS.
+ void print(raw_ostream &OS) const;
+
+ /// Print the value to stderr.
+ void dump() const;
+
+ MCSymbolRefExpr::VariantKind getAccessVariant() const;
+
+ static MCValue get(const MCSymbolRefExpr *SymA,
+ const MCSymbolRefExpr *SymB = nullptr,
+ int64_t Val = 0, uint32_t RefKind = 0) {
+ MCValue R;
+ R.Cst = Val;
+ R.SymA = SymA;
+ R.SymB = SymB;
+ R.RefKind = RefKind;
+ return R;
+ }
+
+ static MCValue get(int64_t Val) {
+ MCValue R;
+ R.Cst = Val;
+ R.SymA = nullptr;
+ R.SymB = nullptr;
+ R.RefKind = 0;
+ return R;
+ }
+
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCWasmObjectWriter.h b/clang-r353983/include/llvm/MC/MCWasmObjectWriter.h
new file mode 100644
index 00000000..4adbca28
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCWasmObjectWriter.h
@@ -0,0 +1,55 @@
+//===-- llvm/MC/MCWasmObjectWriter.h - Wasm Object Writer -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCWASMOBJECTWRITER_H
+#define LLVM_MC_MCWASMOBJECTWRITER_H
+
+#include "llvm/MC/MCObjectWriter.h"
+#include <memory>
+
+namespace llvm {
+
+class MCFixup;
+class MCValue;
+class raw_pwrite_stream;
+
+class MCWasmObjectTargetWriter : public MCObjectTargetWriter {
+ const unsigned Is64Bit : 1;
+
+protected:
+ explicit MCWasmObjectTargetWriter(bool Is64Bit_);
+
+public:
+ virtual ~MCWasmObjectTargetWriter();
+
+ virtual Triple::ObjectFormatType getFormat() const { return Triple::Wasm; }
+ static bool classof(const MCObjectTargetWriter *W) {
+ return W->getFormat() == Triple::Wasm;
+ }
+
+ virtual unsigned getRelocType(const MCValue &Target,
+ const MCFixup &Fixup) const = 0;
+
+ /// \name Accessors
+ /// @{
+ bool is64Bit() const { return Is64Bit; }
+ /// @}
+};
+
+/// Construct a new Wasm writer instance.
+///
+/// \param MOTW - The target specific Wasm writer subclass.
+/// \param OS - The stream to write to.
+/// \returns The constructed object writer.
+std::unique_ptr<MCObjectWriter>
+createWasmObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> MOTW,
+ raw_pwrite_stream &OS);
+
+} // namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCWasmStreamer.h b/clang-r353983/include/llvm/MC/MCWasmStreamer.h
new file mode 100644
index 00000000..2d7f2b99
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCWasmStreamer.h
@@ -0,0 +1,87 @@
+//===- MCWasmStreamer.h - MCStreamer Wasm Object File Interface -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCWASMSTREAMER_H
+#define LLVM_MC_MCWASMSTREAMER_H
+
+#include "MCAsmBackend.h"
+#include "MCCodeEmitter.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+class MCAssembler;
+class MCExpr;
+class MCInst;
+class raw_ostream;
+
+class MCWasmStreamer : public MCObjectStreamer {
+public:
+ MCWasmStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
+ std::unique_ptr<MCObjectWriter> OW,
+ std::unique_ptr<MCCodeEmitter> Emitter)
+ : MCObjectStreamer(Context, std::move(TAB), std::move(OW),
+ std::move(Emitter)),
+ SeenIdent(false) {}
+
+ ~MCWasmStreamer() override;
+
+ /// state management
+ void reset() override {
+ SeenIdent = false;
+ MCObjectStreamer::reset();
+ }
+
+ /// \name MCStreamer Interface
+ /// @{
+
+ void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
+ void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
+ void EmitThumbFunc(MCSymbol *Func) override;
+ void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
+ bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+ void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
+ void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+
+ void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
+
+ void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+
+ void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
+ uint64_t Size = 0, unsigned ByteAlignment = 0,
+ SMLoc Loc = SMLoc()) override;
+ void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment = 0) override;
+ void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ SMLoc Loc = SMLoc()) override;
+
+ void EmitIdent(StringRef IdentString) override;
+
+ void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned) override;
+
+ void FinishImpl() override;
+
+private:
+ void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override;
+ void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
+
+ /// Merge the content of the fragment \p EF into the fragment \p DF.
+ void mergeFragment(MCDataFragment *, MCDataFragment *);
+
+ bool SeenIdent;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCWin64EH.h b/clang-r353983/include/llvm/MC/MCWin64EH.h
new file mode 100644
index 00000000..60ec06e6
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCWin64EH.h
@@ -0,0 +1,69 @@
+//===- MCWin64EH.h - Machine Code Win64 EH support --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains declarations to support the Win64 Exception Handling
+// scheme in MC.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCWIN64EH_H
+#define LLVM_MC_MCWIN64EH_H
+
+#include "llvm/MC/MCWinEH.h"
+#include "llvm/Support/Win64EH.h"
+
+namespace llvm {
+class MCStreamer;
+class MCSymbol;
+
+namespace Win64EH {
+struct Instruction {
+ static WinEH::Instruction PushNonVol(MCSymbol *L, unsigned Reg) {
+ return WinEH::Instruction(Win64EH::UOP_PushNonVol, L, Reg, -1);
+ }
+ static WinEH::Instruction Alloc(MCSymbol *L, unsigned Size) {
+ return WinEH::Instruction(Size > 128 ? UOP_AllocLarge : UOP_AllocSmall, L,
+ -1, Size);
+ }
+ static WinEH::Instruction PushMachFrame(MCSymbol *L, bool Code) {
+ return WinEH::Instruction(UOP_PushMachFrame, L, -1, Code ? 1 : 0);
+ }
+ static WinEH::Instruction SaveNonVol(MCSymbol *L, unsigned Reg,
+ unsigned Offset) {
+ return WinEH::Instruction(Offset > 512 * 1024 - 8 ? UOP_SaveNonVolBig
+ : UOP_SaveNonVol,
+ L, Reg, Offset);
+ }
+ static WinEH::Instruction SaveXMM(MCSymbol *L, unsigned Reg,
+ unsigned Offset) {
+ return WinEH::Instruction(Offset > 512 * 1024 - 8 ? UOP_SaveXMM128Big
+ : UOP_SaveXMM128,
+ L, Reg, Offset);
+ }
+ static WinEH::Instruction SetFPReg(MCSymbol *L, unsigned Reg, unsigned Off) {
+ return WinEH::Instruction(UOP_SetFPReg, L, Reg, Off);
+ }
+};
+
+class UnwindEmitter : public WinEH::UnwindEmitter {
+public:
+ void Emit(MCStreamer &Streamer) const override;
+ void EmitUnwindInfo(MCStreamer &Streamer, WinEH::FrameInfo *FI) const override;
+};
+
+class ARM64UnwindEmitter : public WinEH::UnwindEmitter {
+public:
+ void Emit(MCStreamer &Streamer) const override;
+ void EmitUnwindInfo(MCStreamer &Streamer,
+ WinEH::FrameInfo *FI) const override;
+};
+
+}
+} // end namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MCWinCOFFObjectWriter.h b/clang-r353983/include/llvm/MC/MCWinCOFFObjectWriter.h
new file mode 100644
index 00000000..3fe124fd
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCWinCOFFObjectWriter.h
@@ -0,0 +1,56 @@
+//===- llvm/MC/MCWinCOFFObjectWriter.h - Win COFF Object Writer -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCWINCOFFOBJECTWRITER_H
+#define LLVM_MC_MCWINCOFFOBJECTWRITER_H
+
+#include "llvm/MC/MCObjectWriter.h"
+#include <memory>
+
+namespace llvm {
+
+class MCAsmBackend;
+class MCContext;
+class MCFixup;
+class MCValue;
+class raw_pwrite_stream;
+
+ class MCWinCOFFObjectTargetWriter : public MCObjectTargetWriter {
+ virtual void anchor();
+
+ const unsigned Machine;
+
+ protected:
+ MCWinCOFFObjectTargetWriter(unsigned Machine_);
+
+ public:
+ virtual ~MCWinCOFFObjectTargetWriter() = default;
+
+ virtual Triple::ObjectFormatType getFormat() const { return Triple::COFF; }
+ static bool classof(const MCObjectTargetWriter *W) {
+ return W->getFormat() == Triple::COFF;
+ }
+
+ unsigned getMachine() const { return Machine; }
+ virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
+ const MCFixup &Fixup, bool IsCrossSection,
+ const MCAsmBackend &MAB) const = 0;
+ virtual bool recordRelocation(const MCFixup &) const { return true; }
+ };
+
+ /// Construct a new Win COFF writer instance.
+ ///
+ /// \param MOTW - The target specific WinCOFF writer subclass.
+ /// \param OS - The stream to write to.
+ /// \returns The constructed object writer.
+ std::unique_ptr<MCObjectWriter>
+ createWinCOFFObjectWriter(std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW,
+ raw_pwrite_stream &OS);
+} // end namespace llvm
+
+#endif // LLVM_MC_MCWINCOFFOBJECTWRITER_H
diff --git a/clang-r353983/include/llvm/MC/MCWinCOFFStreamer.h b/clang-r353983/include/llvm/MC/MCWinCOFFStreamer.h
new file mode 100644
index 00000000..c1c1ec56
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCWinCOFFStreamer.h
@@ -0,0 +1,82 @@
+//===- MCWinCOFFStreamer.h - COFF Object File Interface ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCWINCOFFSTREAMER_H
+#define LLVM_MC_MCWINCOFFSTREAMER_H
+
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCObjectStreamer.h"
+
+namespace llvm {
+
+class MCAsmBackend;
+class MCContext;
+class MCCodeEmitter;
+class MCInst;
+class MCSection;
+class MCSubtargetInfo;
+class MCSymbol;
+class StringRef;
+class raw_pwrite_stream;
+
+class MCWinCOFFStreamer : public MCObjectStreamer {
+public:
+ MCWinCOFFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
+ std::unique_ptr<MCCodeEmitter> CE,
+ std::unique_ptr<MCObjectWriter> OW);
+
+ /// state management
+ void reset() override {
+ CurSymbol = nullptr;
+ MCObjectStreamer::reset();
+ }
+
+ /// \name MCStreamer interface
+ /// \{
+
+ void InitSections(bool NoExecStack) override;
+ void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
+ void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
+ void EmitThumbFunc(MCSymbol *Func) override;
+ bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+ void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
+ void BeginCOFFSymbolDef(MCSymbol const *Symbol) override;
+ void EmitCOFFSymbolStorageClass(int StorageClass) override;
+ void EmitCOFFSymbolType(int Type) override;
+ void EndCOFFSymbolDef() override;
+ void EmitCOFFSafeSEH(MCSymbol const *Symbol) override;
+ void EmitCOFFSymbolIndex(MCSymbol const *Symbol) override;
+ void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
+ void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
+ void EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) override;
+ void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+ void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+ void EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment, SMLoc Loc = SMLoc()) override;
+ void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+ void EmitIdent(StringRef IdentString) override;
+ void EmitWinEHHandlerData(SMLoc Loc) override;
+ void FinishImpl() override;
+
+ /// \}
+
+protected:
+ const MCSymbol *CurSymbol;
+
+ void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
+
+private:
+ void Error(const Twine &Msg) const;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCWINCOFFSTREAMER_H
diff --git a/clang-r353983/include/llvm/MC/MCWinEH.h b/clang-r353983/include/llvm/MC/MCWinEH.h
new file mode 100644
index 00000000..b1c28c0e
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCWinEH.h
@@ -0,0 +1,69 @@
+//===- MCWinEH.h - Windows Unwinding Support --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCWINEH_H
+#define LLVM_MC_MCWINEH_H
+
+#include "llvm/ADT/MapVector.h"
+#include <vector>
+
+namespace llvm {
+class MCSection;
+class MCStreamer;
+class MCSymbol;
+
+namespace WinEH {
+struct Instruction {
+ const MCSymbol *Label;
+ unsigned Offset;
+ unsigned Register;
+ unsigned Operation;
+
+ Instruction(unsigned Op, MCSymbol *L, unsigned Reg, unsigned Off)
+ : Label(L), Offset(Off), Register(Reg), Operation(Op) {}
+};
+
+struct FrameInfo {
+ const MCSymbol *Begin = nullptr;
+ const MCSymbol *End = nullptr;
+ const MCSymbol *FuncletOrFuncEnd = nullptr;
+ const MCSymbol *ExceptionHandler = nullptr;
+ const MCSymbol *Function = nullptr;
+ const MCSymbol *PrologEnd = nullptr;
+ const MCSymbol *Symbol = nullptr;
+ const MCSection *TextSection = nullptr;
+
+ bool HandlesUnwind = false;
+ bool HandlesExceptions = false;
+
+ int LastFrameInst = -1;
+ const FrameInfo *ChainedParent = nullptr;
+ std::vector<Instruction> Instructions;
+ MapVector<MCSymbol*, std::vector<Instruction>> EpilogMap;
+
+ FrameInfo() = default;
+ FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel)
+ : Begin(BeginFuncEHLabel), Function(Function) {}
+ FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel,
+ const FrameInfo *ChainedParent)
+ : Begin(BeginFuncEHLabel), Function(Function),
+ ChainedParent(ChainedParent) {}
+};
+
+class UnwindEmitter {
+public:
+ virtual ~UnwindEmitter();
+
+ /// This emits the unwind info sections (.pdata and .xdata in PE/COFF).
+ virtual void Emit(MCStreamer &Streamer) const = 0;
+ virtual void EmitUnwindInfo(MCStreamer &Streamer, FrameInfo *FI) const = 0;
+};
+}
+}
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/MachineLocation.h b/clang-r353983/include/llvm/MC/MachineLocation.h
new file mode 100644
index 00000000..5872540e
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MachineLocation.h
@@ -0,0 +1,58 @@
+//===- llvm/MC/MachineLocation.h --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// The MachineLocation class is used to represent a simple location in a machine
+// frame. Locations will be one of two forms; a register or an address formed
+// from a base address plus an offset. Register indirection can be specified by
+// explicitly passing an offset to the constructor.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MACHINELOCATION_H
+#define LLVM_MC_MACHINELOCATION_H
+
+#include <cstdint>
+#include <cassert>
+
+namespace llvm {
+
+class MachineLocation {
+private:
+ bool IsRegister = false; ///< True if location is a register.
+ unsigned Register = 0; ///< gcc/gdb register number.
+
+public:
+ enum : uint32_t {
+ // The target register number for an abstract frame pointer. The value is
+ // an arbitrary value that doesn't collide with any real target register.
+ VirtualFP = ~0U
+ };
+
+ MachineLocation() = default;
+ /// Create a direct register location.
+ explicit MachineLocation(unsigned R, bool Indirect = false)
+ : IsRegister(!Indirect), Register(R) {}
+
+ bool operator==(const MachineLocation &Other) const {
+ return IsRegister == Other.IsRegister && Register == Other.Register;
+ }
+
+ // Accessors.
+ /// \return true iff this is a register-indirect location.
+ bool isIndirect() const { return !IsRegister; }
+ bool isReg() const { return IsRegister; }
+ unsigned getReg() const { return Register; }
+ void setIsRegister(bool Is) { IsRegister = Is; }
+ void setRegister(unsigned R) { Register = R; }
+};
+
+inline bool operator!=(const MachineLocation &LHS, const MachineLocation &RHS) {
+ return !(LHS == RHS);
+}
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MACHINELOCATION_H
diff --git a/clang-r353983/include/llvm/MC/SectionKind.h b/clang-r353983/include/llvm/MC/SectionKind.h
new file mode 100644
index 00000000..0342c4cf
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/SectionKind.h
@@ -0,0 +1,207 @@
+//===-- llvm/MC/SectionKind.h - Classification of sections ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_SECTIONKIND_H
+#define LLVM_MC_SECTIONKIND_H
+
+namespace llvm {
+
+/// SectionKind - This is a simple POD value that classifies the properties of
+/// a section. A section is classified into the deepest possible
+/// classification, and then the target maps them onto their sections based on
+/// what capabilities they have.
+///
+/// The comments below describe these as if they were an inheritance hierarchy
+/// in order to explain the predicates below.
+///
+class SectionKind {
+ enum Kind {
+ /// Metadata - Debug info sections or other metadata.
+ Metadata,
+
+ /// Text - Text section, used for functions and other executable code.
+ Text,
+
+ /// ExecuteOnly, Text section that is not readable.
+ ExecuteOnly,
+
+ /// ReadOnly - Data that is never written to at program runtime by the
+ /// program or the dynamic linker. Things in the top-level readonly
+ /// SectionKind are not mergeable.
+ ReadOnly,
+
+ /// MergableCString - Any null-terminated string which allows merging.
+ /// These values are known to end in a nul value of the specified size,
+ /// not otherwise contain a nul value, and be mergable. This allows the
+ /// linker to unique the strings if it so desires.
+
+ /// Mergeable1ByteCString - 1 byte mergable, null terminated, string.
+ Mergeable1ByteCString,
+
+ /// Mergeable2ByteCString - 2 byte mergable, null terminated, string.
+ Mergeable2ByteCString,
+
+ /// Mergeable4ByteCString - 4 byte mergable, null terminated, string.
+ Mergeable4ByteCString,
+
+ /// MergeableConst - These are sections for merging fixed-length
+ /// constants together. For example, this can be used to unique
+ /// constant pool entries etc.
+
+ /// MergeableConst4 - This is a section used by 4-byte constants,
+ /// for example, floats.
+ MergeableConst4,
+
+ /// MergeableConst8 - This is a section used by 8-byte constants,
+ /// for example, doubles.
+ MergeableConst8,
+
+ /// MergeableConst16 - This is a section used by 16-byte constants,
+ /// for example, vectors.
+ MergeableConst16,
+
+ /// MergeableConst32 - This is a section used by 32-byte constants,
+ /// for example, vectors.
+ MergeableConst32,
+
+ /// Writeable - This is the base of all segments that need to be written
+ /// to during program runtime.
+
+ /// ThreadLocal - This is the base of all TLS segments. All TLS
+ /// objects must be writeable, otherwise there is no reason for them to
+ /// be thread local!
+
+ /// ThreadBSS - Zero-initialized TLS data objects.
+ ThreadBSS,
+
+ /// ThreadData - Initialized TLS data objects.
+ ThreadData,
+
+ /// GlobalWriteableData - Writeable data that is global (not thread
+ /// local).
+
+ /// BSS - Zero initialized writeable data.
+ BSS,
+
+ /// BSSLocal - This is BSS (zero initialized and writable) data
+ /// which has local linkage.
+ BSSLocal,
+
+ /// BSSExtern - This is BSS data with normal external linkage.
+ BSSExtern,
+
+ /// Common - Data with common linkage. These represent tentative
+ /// definitions, which always have a zero initializer and are never
+ /// marked 'constant'.
+ Common,
+
+ /// This is writeable data that has a non-zero initializer.
+ Data,
+
+ /// ReadOnlyWithRel - These are global variables that are never
+ /// written to by the program, but that have relocations, so they
+ /// must be stuck in a writeable section so that the dynamic linker
+ /// can write to them. If it chooses to, the dynamic linker can
+ /// mark the pages these globals end up on as read-only after it is
+ /// done with its relocation phase.
+ ReadOnlyWithRel
+ } K : 8;
+public:
+
+ bool isMetadata() const { return K == Metadata; }
+
+ bool isText() const { return K == Text || K == ExecuteOnly; }
+
+ bool isExecuteOnly() const { return K == ExecuteOnly; }
+
+ bool isReadOnly() const {
+ return K == ReadOnly || isMergeableCString() ||
+ isMergeableConst();
+ }
+
+ bool isMergeableCString() const {
+ return K == Mergeable1ByteCString || K == Mergeable2ByteCString ||
+ K == Mergeable4ByteCString;
+ }
+ bool isMergeable1ByteCString() const { return K == Mergeable1ByteCString; }
+ bool isMergeable2ByteCString() const { return K == Mergeable2ByteCString; }
+ bool isMergeable4ByteCString() const { return K == Mergeable4ByteCString; }
+
+ bool isMergeableConst() const {
+ return K == MergeableConst4 || K == MergeableConst8 ||
+ K == MergeableConst16 || K == MergeableConst32;
+ }
+ bool isMergeableConst4() const { return K == MergeableConst4; }
+ bool isMergeableConst8() const { return K == MergeableConst8; }
+ bool isMergeableConst16() const { return K == MergeableConst16; }
+ bool isMergeableConst32() const { return K == MergeableConst32; }
+
+ bool isWriteable() const {
+ return isThreadLocal() || isGlobalWriteableData();
+ }
+
+ bool isThreadLocal() const {
+ return K == ThreadData || K == ThreadBSS;
+ }
+
+ bool isThreadBSS() const { return K == ThreadBSS; }
+ bool isThreadData() const { return K == ThreadData; }
+
+ bool isGlobalWriteableData() const {
+ return isBSS() || isCommon() || isData() || isReadOnlyWithRel();
+ }
+
+ bool isBSS() const { return K == BSS || K == BSSLocal || K == BSSExtern; }
+ bool isBSSLocal() const { return K == BSSLocal; }
+ bool isBSSExtern() const { return K == BSSExtern; }
+
+ bool isCommon() const { return K == Common; }
+
+ bool isData() const { return K == Data; }
+
+ bool isReadOnlyWithRel() const {
+ return K == ReadOnlyWithRel;
+ }
+private:
+ static SectionKind get(Kind K) {
+ SectionKind Res;
+ Res.K = K;
+ return Res;
+ }
+public:
+
+ static SectionKind getMetadata() { return get(Metadata); }
+ static SectionKind getText() { return get(Text); }
+ static SectionKind getExecuteOnly() { return get(ExecuteOnly); }
+ static SectionKind getReadOnly() { return get(ReadOnly); }
+ static SectionKind getMergeable1ByteCString() {
+ return get(Mergeable1ByteCString);
+ }
+ static SectionKind getMergeable2ByteCString() {
+ return get(Mergeable2ByteCString);
+ }
+ static SectionKind getMergeable4ByteCString() {
+ return get(Mergeable4ByteCString);
+ }
+ static SectionKind getMergeableConst4() { return get(MergeableConst4); }
+ static SectionKind getMergeableConst8() { return get(MergeableConst8); }
+ static SectionKind getMergeableConst16() { return get(MergeableConst16); }
+ static SectionKind getMergeableConst32() { return get(MergeableConst32); }
+ static SectionKind getThreadBSS() { return get(ThreadBSS); }
+ static SectionKind getThreadData() { return get(ThreadData); }
+ static SectionKind getBSS() { return get(BSS); }
+ static SectionKind getBSSLocal() { return get(BSSLocal); }
+ static SectionKind getBSSExtern() { return get(BSSExtern); }
+ static SectionKind getCommon() { return get(Common); }
+ static SectionKind getData() { return get(Data); }
+ static SectionKind getReadOnlyWithRel() { return get(ReadOnlyWithRel); }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/clang-r353983/include/llvm/MC/StringTableBuilder.h b/clang-r353983/include/llvm/MC/StringTableBuilder.h
new file mode 100644
index 00000000..c83eca4e
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/StringTableBuilder.h
@@ -0,0 +1,74 @@
+//===- StringTableBuilder.h - String table building utility -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_STRINGTABLEBUILDER_H
+#define LLVM_MC_STRINGTABLEBUILDER_H
+
+#include "llvm/ADT/CachedHashString.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <cstddef>
+#include <cstdint>
+
+namespace llvm {
+
+class raw_ostream;
+
+/// Utility for building string tables with deduplicated suffixes.
+class StringTableBuilder {
+public:
+ enum Kind { ELF, WinCOFF, MachO, RAW, DWARF };
+
+private:
+ DenseMap<CachedHashStringRef, size_t> StringIndexMap;
+ size_t Size = 0;
+ Kind K;
+ unsigned Alignment;
+ bool Finalized = false;
+
+ void finalizeStringTable(bool Optimize);
+ void initSize();
+
+public:
+ StringTableBuilder(Kind K, unsigned Alignment = 1);
+ ~StringTableBuilder();
+
+ /// Add a string to the builder. Returns the position of S in the
+ /// table. The position will be changed if finalize is used.
+ /// Can only be used before the table is finalized.
+ size_t add(CachedHashStringRef S);
+ size_t add(StringRef S) { return add(CachedHashStringRef(S)); }
+
+ /// Analyze the strings and build the final table. No more strings can
+ /// be added after this point.
+ void finalize();
+
+ /// Finalize the string table without reording it. In this mode, offsets
+ /// returned by add will still be valid.
+ void finalizeInOrder();
+
+ /// Get the offest of a string in the string table. Can only be used
+ /// after the table is finalized.
+ size_t getOffset(CachedHashStringRef S) const;
+ size_t getOffset(StringRef S) const {
+ return getOffset(CachedHashStringRef(S));
+ }
+
+ size_t getSize() const { return Size; }
+ void clear();
+
+ void write(raw_ostream &OS) const;
+ void write(uint8_t *Buf) const;
+
+private:
+ bool isFinalized() const { return Finalized; }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_STRINGTABLEBUILDER_H
diff --git a/clang-r353983/include/llvm/MC/SubtargetFeature.h b/clang-r353983/include/llvm/MC/SubtargetFeature.h
new file mode 100644
index 00000000..5f49d389
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/SubtargetFeature.h
@@ -0,0 +1,132 @@
+//===- llvm/MC/SubtargetFeature.h - CPU characteristics ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file Defines and manages user or tool specified CPU characteristics.
+/// The intent is to be able to package specific features that should or should
+/// not be used on a specific target processor. A tool, such as llc, could, as
+/// as example, gather chip info from the command line, a long with features
+/// that should be used on that chip.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_SUBTARGETFEATURE_H
+#define LLVM_MC_SUBTARGETFEATURE_H
+
+#include "llvm/ADT/StringRef.h"
+#include <bitset>
+#include <initializer_list>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+template <typename T> class ArrayRef;
+class raw_ostream;
+class Triple;
+
+const unsigned MAX_SUBTARGET_FEATURES = 192;
+/// Container class for subtarget features.
+/// This is convenient because std::bitset does not have a constructor
+/// with an initializer list of set bits.
+class FeatureBitset : public std::bitset<MAX_SUBTARGET_FEATURES> {
+public:
+ // Cannot inherit constructors because it's not supported by VC++..
+ FeatureBitset() = default;
+
+ FeatureBitset(const bitset<MAX_SUBTARGET_FEATURES>& B) : bitset(B) {}
+
+ FeatureBitset(std::initializer_list<unsigned> Init) {
+ for (auto I : Init)
+ set(I);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+
+/// Used to provide key value pairs for feature and CPU bit flags.
+struct SubtargetFeatureKV {
+ const char *Key; ///< K-V key string
+ const char *Desc; ///< Help descriptor
+ FeatureBitset Value; ///< K-V integer value
+ FeatureBitset Implies; ///< K-V bit mask
+
+ /// Compare routine for std::lower_bound
+ bool operator<(StringRef S) const {
+ return StringRef(Key) < S;
+ }
+
+ /// Compare routine for std::is_sorted.
+ bool operator<(const SubtargetFeatureKV &Other) const {
+ return StringRef(Key) < StringRef(Other.Key);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+
+/// Used to provide key value pairs for CPU and arbitrary pointers.
+struct SubtargetInfoKV {
+ const char *Key; ///< K-V key string
+ const void *Value; ///< K-V pointer value
+
+ /// Compare routine for std::lower_bound
+ bool operator<(StringRef S) const {
+ return StringRef(Key) < S;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+
+/// Manages the enabling and disabling of subtarget specific features.
+///
+/// Features are encoded as a string of the form
+/// "+attr1,+attr2,-attr3,...,+attrN"
+/// A comma separates each feature from the next (all lowercase.)
+/// Each of the remaining features is prefixed with + or - indicating whether
+/// that feature should be enabled or disabled contrary to the cpu
+/// specification.
+class SubtargetFeatures {
+ std::vector<std::string> Features; ///< Subtarget features as a vector
+
+public:
+ explicit SubtargetFeatures(StringRef Initial = "");
+
+ /// Returns features as a string.
+ std::string getString() const;
+
+ /// Adds Features.
+ void AddFeature(StringRef String, bool Enable = true);
+
+ /// Toggles a feature and update the feature bits.
+ static void ToggleFeature(FeatureBitset &Bits, StringRef String,
+ ArrayRef<SubtargetFeatureKV> FeatureTable);
+
+ /// Applies the feature flag and update the feature bits.
+ static void ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature,
+ ArrayRef<SubtargetFeatureKV> FeatureTable);
+
+ /// Returns feature bits of a CPU.
+ FeatureBitset getFeatureBits(StringRef CPU,
+ ArrayRef<SubtargetFeatureKV> CPUTable,
+ ArrayRef<SubtargetFeatureKV> FeatureTable);
+
+ /// Returns the vector of individual subtarget features.
+ const std::vector<std::string> &getFeatures() const { return Features; }
+
+ /// Prints feature string.
+ void print(raw_ostream &OS) const;
+
+ // Dumps feature info.
+ void dump() const;
+
+ /// Adds the default features for the specified target triple.
+ void getDefaultSubtargetFeatures(const Triple& Triple);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_SUBTARGETFEATURE_H