]> granicus.if.org Git - llvm/commitdiff
Revert r283690, "MC: Remove unused entities."
authorPeter Collingbourne <peter@pcc.me.uk>
Mon, 10 Oct 2016 22:49:37 +0000 (22:49 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Mon, 10 Oct 2016 22:49:37 +0000 (22:49 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283814 91177308-0d34-0410-b5e6-96231b3b80d8

24 files changed:
include/llvm/MC/MCInstrDesc.h
include/llvm/MC/MCMachObjectWriter.h
include/llvm/MC/MCParser/MCParsedAsmOperand.h
include/llvm/MC/MCParser/MCTargetAsmParser.h
include/llvm/MC/MCStreamer.h
include/llvm/MC/MCWin64EH.h
include/llvm/MC/MCWinEH.h
lib/MC/CMakeLists.txt
lib/MC/MCAsmStreamer.cpp
lib/MC/MCStreamer.cpp
lib/MC/MCWinEH.cpp [new file with mode: 0644]
lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
lib/Target/Lanai/AsmParser/LanaiAsmParser.cpp
lib/Target/Mips/AsmParser/MipsAsmParser.cpp
lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
lib/Target/X86/AsmParser/X86AsmParser.cpp
lib/Target/X86/AsmParser/X86Operand.h
lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp
utils/TableGen/AsmMatcherEmitter.cpp

index 778a864c6bb1fe47e316f2604a300d98d759b9fc..340d8253b8c99f5506195b9c64f57fb668f6ad64 100644 (file)
@@ -294,13 +294,80 @@ public:
   /// \brief Return true if this instruction is a comparison.
   bool isCompare() const { return Flags & (1ULL << MCID::Compare); }
 
+  /// \brief Return true if this instruction is a move immediate
+  /// (including conditional moves) instruction.
+  bool isMoveImmediate() const { return Flags & (1ULL << MCID::MoveImm); }
+
+  /// \brief Return true if this instruction is a bitcast instruction.
+  bool isBitcast() const { return Flags & (1ULL << MCID::Bitcast); }
+
   /// \brief Return true if this is a select instruction.
   bool isSelect() const { return Flags & (1ULL << MCID::Select); }
 
+  /// \brief Return true if this instruction cannot be safely
+  /// duplicated.  For example, if the instruction has a unique labels attached
+  /// to it, duplicating it would cause multiple definition errors.
+  bool isNotDuplicable() const { return Flags & (1ULL << MCID::NotDuplicable); }
+
   /// \brief 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); }
 
+  /// \brief Return true for instructions that can be folded as memory operands
+  /// in other instructions. The most common use for this is instructions that
+  /// are simple loads from memory that don't modify the loaded value in any
+  /// way, but it can also be used for instructions that can be expressed as
+  /// constant-pool loads, such as V_SETALLONES on x86, to allow them to be
+  /// folded when it is beneficial.  This should only be set on instructions
+  /// that return a value in their only virtual register definition.
+  bool canFoldAsLoad() const { return Flags & (1ULL << MCID::FoldableAsLoad); }
+
+  /// \brief 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); }
+
+  /// \brief 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);
+  }
+
+  /// \brief 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); }
+
+
+  /// \brief 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); }
+
   //===--------------------------------------------------------------------===//
   // Side Effect Analysis
   //===--------------------------------------------------------------------===//
@@ -316,6 +383,22 @@ public:
   /// may not actually modify anything, for example.
   bool mayStore() const { return Flags & (1ULL << MCID::MayStore); }
 
+  /// \brief Return true if this instruction has side
+  /// effects that are not modeled by other flags.  This does not return true
+  /// for instructions whose effects are captured by:
+  ///
+  ///  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.
   //===--------------------------------------------------------------------===//
@@ -332,6 +415,36 @@ public:
   /// commute them.
   bool isCommutable() const { return Flags & (1ULL << MCID::Commutable); }
 
+  /// \brief Return true if this is a 2-address instruction which can be changed
+  /// into a 3-address instruction if needed.  Doing this transformation can be
+  /// profitable in the register allocator, because it means that the
+  /// instruction can use a 2-address form if possible, but degrade into a less
+  /// efficient form if the source and dest register cannot be assigned to the
+  /// same register.  For example, this allows the x86 backend to turn a "shl
+  /// reg, 3" instruction into an LEA instruction, which is the same speed as
+  /// the shift but has bigger code size.
+  ///
+  /// If this returns true, then the target must implement the
+  /// TargetInstrInfo::convertToThreeAddress method for this instruction, which
+  /// 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);
+  }
+
+  /// \brief Return true if this instruction requires custom insertion support
+  /// when the DAG scheduler is inserting it into a machine basic block.  If
+  /// this is true for the instruction, it basically means that it is a pseudo
+  /// instruction used at SelectionDAG time that is expanded out into magic code
+  /// by the target when MachineInstrs are formed.
+  ///
+  /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method
+  /// is used to insert this into the MachineBasicBlock.
+  bool usesCustomInsertionHook() const {
+    return Flags & (1ULL << MCID::UsesCustomInserter);
+  }
+
   /// \brief Return true if this instruction requires *adjustment* after
   /// instruction selection by calling a target hook. For example, this can be
   /// used to fill in ARM 's' optional operand depending on whether the
@@ -348,6 +461,37 @@ public:
     return Flags & (1ULL << MCID::Rematerializable);
   }
 
+  /// \brief Returns true if this instruction has the same cost (or less) than a
+  /// move instruction. This is useful during certain types of optimizations
+  /// (e.g., remat during two-address conversion or machine licm) where we would
+  /// like to remat or hoist the instruction, but not if it costs more than
+  /// moving the instruction into the appropriate register. Note, we are not
+  /// marking copies from and to the same register class with this flag.
+  ///
+  /// This method could be called by interface TargetInstrInfo::isAsCheapAsAMove
+  /// for different subtargets.
+  bool isAsCheapAsAMove() const { return Flags & (1ULL << MCID::CheapAsAMove); }
+
+  /// \brief Returns true if this instruction source operands have special
+  /// register allocation requirements that are not captured by the operand
+  /// register classes. e.g. ARM::STRD's two source registers must be an even /
+  /// odd pair, ARM::STM registers have to be in ascending order.  Post-register
+  /// allocation passes should not attempt to change allocations for sources of
+  /// instructions with this flag.
+  bool hasExtraSrcRegAllocReq() const {
+    return Flags & (1ULL << MCID::ExtraSrcRegAllocReq);
+  }
+
+  /// \brief Returns true if this instruction def operands have special register
+  /// allocation requirements that are not captured by the operand register
+  /// classes. e.g. ARM::LDRD's two def registers must be an even / odd pair,
+  /// ARM::LDM registers have to be in ascending order.  Post-register
+  /// allocation passes should not attempt to change allocations for definitions
+  /// of instructions with this flag.
+  bool hasExtraDefRegAllocReq() const {
+    return Flags & (1ULL << MCID::ExtraDefRegAllocReq);
+  }
+
   /// \brief Return a list of registers that are potentially read by any
   /// instance of this machine instruction.  For example, on X86, the "adc"
   /// instruction adds two register operands and adds the carry bit in from the
@@ -390,6 +534,16 @@ public:
     return i;
   }
 
+  /// \brief 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;
+  }
+
   /// \brief Return true if this instruction implicitly
   /// defines the specified physical register.
   bool hasImplicitDefOfPhysReg(unsigned Reg,
index 5e5640e9e3ddcccecb707a393c10c7ba8f0e9e1a..1a685dbd608eebf7a040c723865300d25d2f70aa 100644 (file)
@@ -27,11 +27,16 @@ class MCMachObjectTargetWriter {
   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();
 
@@ -48,6 +53,9 @@ public:
   bool is64Bit() const { return Is64Bit; }
   uint32_t getCPUType() const { return CPUType; }
   uint32_t getCPUSubtype() const { return CPUSubtype; }
+  unsigned getLocalDifferenceRelocationType() const {
+    return LocalDifference_RIT;
+  }
 
   /// @}
 
index fabae706b31d79bda31a50292bd79a07a99011a0..a90d280c240ce2e17e36be1bef01fb4bdba90736 100644 (file)
@@ -64,11 +64,21 @@ public:
 
   /// 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.
index cab926f9afd559cc077e5452041d331facf4be3b..b2f7b8ee5a871268c5a32ca412884991e0e63892 100644 (file)
@@ -209,6 +209,9 @@ public:
     return Match_Success;
   }
 
+  virtual void convertToMapAndConstraints(unsigned Kind,
+                                          const OperandVector &Operands) = 0;
+
   // 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
index 54c0b6b3a41c54d1fd4f82cdfcbed5b81bb33ed1..99d07ff200366f18d0c722d2af095a188c768ece 100644 (file)
@@ -199,6 +199,8 @@ protected:
     return CurrentWinFrameInfo;
   }
 
+  virtual void EmitWindowsUnwindTables();
+
   virtual void EmitRawTextImpl(StringRef String);
 
 public:
@@ -275,6 +277,8 @@ public:
   /// \brief 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);
+  /// \brief Emit added explicit comments.
+  virtual void emitExplicitComments();
 
   /// AddBlankLine - Emit a blank line to a .s file to pretty it up.
   virtual void AddBlankLine() {}
index a7e89bb99615ba587c1469d2f9fe45095bb8c5d1..83ea738de8c3d918a1416b5c9cf0697681413253 100644 (file)
@@ -51,10 +51,10 @@ struct Instruction {
   }
 };
 
-class UnwindEmitter {
+class UnwindEmitter : public WinEH::UnwindEmitter {
 public:
-  void Emit(MCStreamer &Streamer) const;
-  void EmitUnwindInfo(MCStreamer &Streamer, WinEH::FrameInfo *FI) const;
+  void Emit(MCStreamer &Streamer) const override;
+  void EmitUnwindInfo(MCStreamer &Streamer, WinEH::FrameInfo *FI) const override;
 };
 }
 } // end namespace llvm
index d7adb81ffa2b47cf1692ccc12d15ed8162abd834..4ca52a6654eb7f51ffd24ce82064d281d0935dc8 100644 (file)
@@ -52,6 +52,15 @@ struct FrameInfo {
       : 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;
+};
 }
 }
 
index c207aac0cf20131184b62d55db9f5070cb89142c..2f1b39e58e33fa4a07ed4de97ce097989e631ce9 100644 (file)
@@ -41,6 +41,7 @@ add_llvm_library(LLVMMC
   MCTargetOptions.cpp
   MCValue.cpp
   MCWin64EH.cpp
+  MCWinEH.cpp
   MachObjectWriter.cpp
   StringTableBuilder.cpp
   SubtargetFeature.cpp
index a8c37e0f27222175fee70fcd732aa25bbb14d6f5..7b1c59f1c045a92d6ec05a2954cc3aae221cbd94 100644 (file)
@@ -117,7 +117,7 @@ public:
   void emitRawComment(const Twine &T, bool TabPrefix = true) override;
 
   void addExplicitComment(const Twine &T) override;
-  void emitExplicitComments();
+  void emitExplicitComments() override;
 
   /// AddBlankLine - Emit a blank line to a .s file to pretty it up.
   void AddBlankLine() override {
index 11c548a97280047dc88c3d3e6f4d84e13ca34757..124a1911a9a15584d6efaf6a10b06d219f64fc38 100644 (file)
@@ -72,6 +72,7 @@ raw_ostream &MCStreamer::GetCommentOS() {
 void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
 
 void MCStreamer::addExplicitComment(const Twine &T) {}
+void MCStreamer::emitExplicitComments() {}
 
 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
   for (auto &FI : DwarfFrameInfos)
@@ -712,6 +713,9 @@ void MCStreamer::EmitRawText(const Twine &T) {
   EmitRawTextImpl(T.toStringRef(Str));
 }
 
+void MCStreamer::EmitWindowsUnwindTables() {
+}
+
 void MCStreamer::Finish() {
   if (!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End)
     report_fatal_error("Unfinished frame!");
diff --git a/lib/MC/MCWinEH.cpp b/lib/MC/MCWinEH.cpp
new file mode 100644 (file)
index 0000000..21a9139
--- /dev/null
@@ -0,0 +1,26 @@
+//===- lib/MC/MCWinEH.cpp - Windows EH implementation ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCSectionCOFF.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCWinEH.h"
+#include "llvm/Support/COFF.h"
+
+namespace llvm {
+namespace WinEH {
+
+UnwindEmitter::~UnwindEmitter() {}
+
+}
+}
+
index b9207ef0e0fd0febe03814b6b6216a461e89b4ef..733b4391b9b68aaeb9061b38596efc230affed95 100644 (file)
@@ -326,7 +326,7 @@ public:
   /// getStartLoc - Get the location of the first token of this operand.
   SMLoc getStartLoc() const override { return StartLoc; }
   /// getEndLoc - Get the location of the last token of this operand.
-  SMLoc getEndLoc() const { return EndLoc; }
+  SMLoc getEndLoc() const override { return EndLoc; }
 
   StringRef getToken() const {
     assert(Kind == k_Token && "Invalid access!");
index 239d7e963acef564577c0e8d280648b735c1f502..839a5559f92d07746d6fa5326860941c63b427cf 100644 (file)
@@ -379,7 +379,7 @@ public:
     return StartLoc;
   }
 
-  SMLoc getEndLoc() const {
+  SMLoc getEndLoc() const override {
     return EndLoc;
   }
 
index 1160a6c4f96b5aeff17c9c94b2fdc90fa96cd6cd..8c9318b406168be29f5b8b61df891dcd82343a87 100644 (file)
@@ -752,7 +752,7 @@ public:
   /// getStartLoc - Get the location of the first token of this operand.
   SMLoc getStartLoc() const override { return StartLoc; }
   /// getEndLoc - Get the location of the last token of this operand.
-  SMLoc getEndLoc() const { return EndLoc; }
+  SMLoc getEndLoc() const override { return EndLoc; }
   /// getLocRange - Get the range between the first and last token of this
   /// operand.
   SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
index 1d17e90aba44837363a4ab60a59af8c73d234d4a..9cbf7286306a70e32b552d7ebaeaa4c9cc785ad5 100644 (file)
@@ -222,7 +222,7 @@ public:
   SMLoc getStartLoc() const { return StartLoc; }
 
   /// getEndLoc - Get the location of the last token of this operand.
-  SMLoc getEndLoc() { return EndLoc; }
+  SMLoc getEndLoc() const { return EndLoc; }
 
   unsigned getReg() const {
     assert(Kind == Register && "Invalid access!");
index 25e586924065b7765a6de71c9a25b6220557068f..ed83591058a2ae0aca929a04bfc7c69c22039ce5 100644 (file)
@@ -134,7 +134,7 @@ public:
   SMLoc getStartLoc() const override { return StartLoc; }
 
   // getEndLoc - Gets location of the last token of this operand
-  SMLoc getEndLoc() const { return EndLoc; }
+  SMLoc getEndLoc() const override { return EndLoc; }
 
   unsigned getReg() const override {
     assert(isReg() && "Invalid type access!");
index 3425088550877631b3147684dee1445c7d2ef061..f6765cdf21e387cc08b02918d4ab5e4554faa44b 100644 (file)
@@ -1474,7 +1474,7 @@ public:
   /// getStartLoc - Get the location of the first token of this operand.
   SMLoc getStartLoc() const override { return StartLoc; }
   /// getEndLoc - Get the location of the last token of this operand.
-  SMLoc getEndLoc() const { return EndLoc; }
+  SMLoc getEndLoc() const override { return EndLoc; }
 
   virtual ~MipsOperand() {
     switch (Kind) {
index 0d7a6375cedb4b459c30b9b9ed64b09bf7c9e16a..ac05859f422d6eff27e3e9c8640ccbf98d3fe783 100644 (file)
@@ -394,7 +394,7 @@ public:
   SMLoc getStartLoc() const override { return StartLoc; }
 
   /// getEndLoc - Get the location of the last token of this operand.
-  SMLoc getEndLoc() const { return EndLoc; }
+  SMLoc getEndLoc() const override { return EndLoc; }
 
   /// isPPC64 - True if this operand is for an instruction in 64-bit mode.
   bool isPPC64() const { return IsPPC64; }
index 6232ba9a6616c304c7cd63c42bd9584411b8b135..a9cca8094cd2b8c283253b1563982cc0b2e2edf9 100644 (file)
@@ -281,7 +281,7 @@ public:
     return StartLoc;
   }
   /// getEndLoc - Get the location of the last token of this operand.
-  SMLoc getEndLoc() const {
+  SMLoc getEndLoc() const override {
     return EndLoc;
   }
 
index fcf0766c89c9cdf7318f10cd0c7d36e72868be26..5acb81d054e4ad7dfad2ab8858c805c46b65ac19 100644 (file)
@@ -261,7 +261,7 @@ public:
 
   // Override MCParsedAsmOperand.
   SMLoc getStartLoc() const override { return StartLoc; }
-  SMLoc getEndLoc() const { return EndLoc; }
+  SMLoc getEndLoc() const override { return EndLoc; }
   void print(raw_ostream &OS) const override;
 
   // Used by the TableGen code to add particular types of operand
index 8cb75ae0f06448278a11f733f69cbb7959f7e07d..539cda2c8c7d6023d5be013b1b0c3372514f91aa 100644 (file)
@@ -1696,7 +1696,7 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
   unsigned RegNo = is64BitMode() ? X86::RBX : (Parse32 ? X86::EBX : X86::BX);
 
   return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
-                               Identifier, Info.OpDecl);
+                               OffsetOfLoc, Identifier, Info.OpDecl);
 }
 
 enum IntelOperatorKind {
index 6894915ac148718643e327c1d08b3aa64bc16ce9..a04c2f5c84a530acde8dc6557fb1052e16ee9225 100644 (file)
@@ -31,6 +31,7 @@ struct X86Operand : public MCParsedAsmOperand {
   } Kind;
 
   SMLoc StartLoc, EndLoc;
+  SMLoc OffsetOfLoc;
   StringRef SymName;
   void *OpDecl;
   bool AddressOf;
@@ -74,10 +75,12 @@ struct X86Operand : public MCParsedAsmOperand {
   /// getStartLoc - Get the location of the first token of this operand.
   SMLoc getStartLoc() const override { return StartLoc; }
   /// getEndLoc - Get the location of the last token of this operand.
-  SMLoc getEndLoc() const { return EndLoc; }
+  SMLoc getEndLoc() const override { return EndLoc; }
   /// getLocRange - Get the range between the first and last token of this
   /// operand.
   SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
+  /// getOffsetOfLoc - Get the location of the offset operator.
+  SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
 
   void print(raw_ostream &OS) const override {}
 
@@ -194,6 +197,10 @@ struct X86Operand : public MCParsedAsmOperand {
     return isImmUnsignedi8Value(CE->getValue());
   }
 
+  bool isOffsetOf() const override {
+    return OffsetOfLoc.getPointer();
+  }
+
   bool needAddressOf() const override {
     return AddressOf;
   }
@@ -467,11 +474,12 @@ struct X86Operand : public MCParsedAsmOperand {
 
   static std::unique_ptr<X86Operand>
   CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
-            bool AddressOf = false, StringRef SymName = StringRef(),
-            void *OpDecl = nullptr) {
+            bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
+            StringRef SymName = StringRef(), void *OpDecl = nullptr) {
     auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
     Res->Reg.RegNo = RegNo;
     Res->AddressOf = AddressOf;
+    Res->OffsetOfLoc = OffsetOfLoc;
     Res->SymName = SymName;
     Res->OpDecl = OpDecl;
     return Res;
index ea1ed167761bb64164f6459222653dccac7b4525..d04511873b46a95d30bc89a38c7d07477ff04574 100644 (file)
@@ -22,7 +22,7 @@ public:
       : MCWinCOFFStreamer(C, AB, *CE, OS) {}
 
   void EmitWinEHHandlerData() override;
-  void EmitWindowsUnwindTables();
+  void EmitWindowsUnwindTables() override;
   void FinishImpl() override;
 };
 
index 0052a6a6a3eb598b9e99f7802b9a3ba51486f3a8..fb715364b7143dec586249f65d3c8859c2f861b6 100644 (file)
@@ -2893,7 +2893,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
        << "                       const OperandVector &Operands);\n";
   }
   OS << "  void convertToMapAndConstraints(unsigned Kind,\n                ";
-  OS << "           const OperandVector &Operands);\n";
+  OS << "           const OperandVector &Operands) override;\n";
   if (HasMnemonicFirst)
     OS << "  bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);\n";
   OS << "  unsigned MatchInstructionImpl(const OperandVector &Operands,\n"