1 //===- bolt/Core/MCPlusBuilder.h - Interface for MCPlus ---------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the declaration of MCPlusBuilder class, which provides
10 // means to create/analyze/modify instructions at MCPlus level.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef BOLT_CORE_MCPLUSBUILDER_H
15 #define BOLT_CORE_MCPLUSBUILDER_H
16 
17 #include "bolt/Core/MCPlus.h"
18 #include "bolt/Core/Relocation.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/BitVector.h"
21 #include "llvm/ADT/Optional.h"
22 #include "llvm/ADT/StringMap.h"
23 #include "llvm/MC/MCAsmBackend.h"
24 #include "llvm/MC/MCDisassembler/MCSymbolizer.h"
25 #include "llvm/MC/MCExpr.h"
26 #include "llvm/MC/MCInst.h"
27 #include "llvm/MC/MCInstrAnalysis.h"
28 #include "llvm/MC/MCInstrDesc.h"
29 #include "llvm/MC/MCInstrInfo.h"
30 #include "llvm/Support/Allocator.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/ErrorOr.h"
33 #include <cassert>
34 #include <cstdint>
35 #include <map>
36 #include <system_error>
37 #include <unordered_map>
38 #include <unordered_set>
39 
40 namespace llvm {
41 class MCContext;
42 class MCFixup;
43 class MCRegisterInfo;
44 class MCSymbol;
45 class raw_ostream;
46 
47 namespace bolt {
48 class BinaryFunction;
49 
50 /// Different types of indirect branches encountered during disassembly.
51 enum class IndirectBranchType : char {
52   UNKNOWN = 0,             /// Unable to determine type.
53   POSSIBLE_TAIL_CALL,      /// Possibly a tail call.
54   POSSIBLE_JUMP_TABLE,     /// Possibly a switch/jump table.
55   POSSIBLE_PIC_JUMP_TABLE, /// Possibly a jump table for PIC.
56   POSSIBLE_GOTO,           /// Possibly a gcc's computed goto.
57   POSSIBLE_FIXED_BRANCH,   /// Possibly an indirect branch to a fixed location.
58 };
59 
60 class MCPlusBuilder {
61 public:
62   using AllocatorIdTy = uint16_t;
63 
64 private:
65   /// A struct that represents a single annotation allocator
66   struct AnnotationAllocator {
67     SpecificBumpPtrAllocator<MCInst> MCInstAllocator;
68     BumpPtrAllocator ValueAllocator;
69     std::unordered_set<MCPlus::MCAnnotation *> AnnotationPool;
70   };
71 
72   /// A set of annotation allocators
73   std::unordered_map<AllocatorIdTy, AnnotationAllocator> AnnotationAllocators;
74 
75   /// A variable that is used to generate unique ids for annotation allocators
76   AllocatorIdTy MaxAllocatorId = 0;
77 
78   /// We encode Index and Value into a 64-bit immediate operand value.
encodeAnnotationImm(uint8_t Index,int64_t Value)79   static int64_t encodeAnnotationImm(uint8_t Index, int64_t Value) {
80     if (LLVM_UNLIKELY(Value != extractAnnotationValue(Value)))
81       report_fatal_error("annotation value out of range");
82 
83     Value &= 0xff'ffff'ffff'ffff;
84     Value |= (int64_t)Index << 56;
85 
86     return Value;
87   }
88 
89   /// Extract annotation index from immediate operand value.
90   static uint8_t extractAnnotationIndex(int64_t ImmValue) {
91     return ImmValue >> 56;
92   }
93 
94   /// Extract annotation value from immediate operand value.
95   static int64_t extractAnnotationValue(int64_t ImmValue) {
96     return SignExtend64<56>(ImmValue & 0xff'ffff'ffff'ffffULL);
97   }
98 
getAnnotationInst(const MCInst & Inst)99   MCInst *getAnnotationInst(const MCInst &Inst) const {
100     if (Inst.getNumOperands() == 0)
101       return nullptr;
102 
103     const MCOperand &LastOp = Inst.getOperand(Inst.getNumOperands() - 1);
104     if (!LastOp.isInst())
105       return nullptr;
106 
107     MCInst *AnnotationInst = const_cast<MCInst *>(LastOp.getInst());
108     assert(AnnotationInst->getOpcode() == TargetOpcode::ANNOTATION_LABEL);
109 
110     return AnnotationInst;
111   }
112 
113   void setAnnotationOpValue(MCInst &Inst, unsigned Index, int64_t Value,
114                             AllocatorIdTy AllocatorId = 0) {
115     MCInst *AnnotationInst = getAnnotationInst(Inst);
116     if (!AnnotationInst) {
117       AnnotationAllocator &Allocator = getAnnotationAllocator(AllocatorId);
118       AnnotationInst = new (Allocator.MCInstAllocator.Allocate()) MCInst();
119       AnnotationInst->setOpcode(TargetOpcode::ANNOTATION_LABEL);
120       Inst.addOperand(MCOperand::createInst(AnnotationInst));
121     }
122 
123     const int64_t AnnotationValue = encodeAnnotationImm(Index, Value);
124     for (int I = AnnotationInst->getNumOperands() - 1; I >= 0; --I) {
125       int64_t ImmValue = AnnotationInst->getOperand(I).getImm();
126       if (extractAnnotationIndex(ImmValue) == Index) {
127         AnnotationInst->getOperand(I).setImm(AnnotationValue);
128         return;
129       }
130     }
131 
132     AnnotationInst->addOperand(MCOperand::createImm(AnnotationValue));
133   }
134 
getAnnotationOpValue(const MCInst & Inst,unsigned Index)135   Optional<int64_t> getAnnotationOpValue(const MCInst &Inst,
136                                          unsigned Index) const {
137     const MCInst *AnnotationInst = getAnnotationInst(Inst);
138     if (!AnnotationInst)
139       return NoneType();
140 
141     for (int I = AnnotationInst->getNumOperands() - 1; I >= 0; --I) {
142       int64_t ImmValue = AnnotationInst->getOperand(I).getImm();
143       if (extractAnnotationIndex(ImmValue) == Index) {
144         return extractAnnotationValue(ImmValue);
145       }
146     }
147 
148     return NoneType();
149   }
150 
151 protected:
152   const MCInstrAnalysis *Analysis;
153   const MCInstrInfo *Info;
154   const MCRegisterInfo *RegInfo;
155 
156   /// Map annotation name into an annotation index.
157   StringMap<uint64_t> AnnotationNameIndexMap;
158 
159   /// Names of non-standard annotations.
160   SmallVector<std::string, 8> AnnotationNames;
161 
162   /// Allocate the TailCall annotation value. Clients of the target-specific
163   /// MCPlusBuilder classes must use convert/lower/create* interfaces instead.
164   void setTailCall(MCInst &Inst);
165 
166 public:
167   class InstructionIterator
168       : public std::iterator<std::bidirectional_iterator_tag, MCInst> {
169   public:
170     class Impl {
171     public:
172       virtual Impl *Copy() const = 0;
173       virtual void Next() = 0;
174       virtual void Prev() = 0;
175       virtual MCInst &Deref() = 0;
176       virtual bool Compare(const Impl &Other) const = 0;
~Impl()177       virtual ~Impl() {}
178     };
179 
180     template <typename T> class SeqImpl : public Impl {
181     public:
Copy()182       virtual Impl *Copy() const override { return new SeqImpl(Itr); }
Next()183       virtual void Next() override { ++Itr; }
Prev()184       virtual void Prev() override { --Itr; }
Deref()185       virtual MCInst &Deref() override { return const_cast<MCInst &>(*Itr); }
Compare(const Impl & Other)186       virtual bool Compare(const Impl &Other) const override {
187         // assumes that Other is same underlying type
188         return Itr == static_cast<const SeqImpl<T> &>(Other).Itr;
189       }
SeqImpl(T && Itr)190       explicit SeqImpl(T &&Itr) : Itr(std::move(Itr)) {}
SeqImpl(const T & Itr)191       explicit SeqImpl(const T &Itr) : Itr(Itr) {}
192 
193     private:
194       T Itr;
195     };
196 
197     template <typename T> class MapImpl : public Impl {
198     public:
Copy()199       virtual Impl *Copy() const override { return new MapImpl(Itr); }
Next()200       virtual void Next() override { ++Itr; }
Prev()201       virtual void Prev() override { --Itr; }
Deref()202       virtual MCInst &Deref() override {
203         return const_cast<MCInst &>(Itr->second);
204       }
Compare(const Impl & Other)205       virtual bool Compare(const Impl &Other) const override {
206         // assumes that Other is same underlying type
207         return Itr == static_cast<const MapImpl<T> &>(Other).Itr;
208       }
MapImpl(T && Itr)209       explicit MapImpl(T &&Itr) : Itr(std::move(Itr)) {}
MapImpl(const T & Itr)210       explicit MapImpl(const T &Itr) : Itr(Itr) {}
211 
212     private:
213       T Itr;
214     };
215 
216     InstructionIterator &operator++() {
217       Itr->Next();
218       return *this;
219     }
220     InstructionIterator &operator--() {
221       Itr->Prev();
222       return *this;
223     }
224     InstructionIterator operator++(int) {
225       std::unique_ptr<Impl> Tmp(Itr->Copy());
226       Itr->Next();
227       return InstructionIterator(std::move(Tmp));
228     }
229     InstructionIterator operator--(int) {
230       std::unique_ptr<Impl> Tmp(Itr->Copy());
231       Itr->Prev();
232       return InstructionIterator(std::move(Tmp));
233     }
234     bool operator==(const InstructionIterator &Other) const {
235       return Itr->Compare(*Other.Itr);
236     }
237     bool operator!=(const InstructionIterator &Other) const {
238       return !Itr->Compare(*Other.Itr);
239     }
240     MCInst &operator*() { return Itr->Deref(); }
241     MCInst *operator->() { return &Itr->Deref(); }
242 
243     InstructionIterator &operator=(InstructionIterator &&Other) {
244       Itr = std::move(Other.Itr);
245       return *this;
246     }
247     InstructionIterator &operator=(const InstructionIterator &Other) {
248       if (this != &Other)
249         Itr.reset(Other.Itr->Copy());
250       return *this;
251     }
InstructionIterator()252     InstructionIterator() {}
InstructionIterator(const InstructionIterator & Other)253     InstructionIterator(const InstructionIterator &Other)
254         : Itr(Other.Itr->Copy()) {}
InstructionIterator(InstructionIterator && Other)255     InstructionIterator(InstructionIterator &&Other)
256         : Itr(std::move(Other.Itr)) {}
InstructionIterator(std::unique_ptr<Impl> Itr)257     explicit InstructionIterator(std::unique_ptr<Impl> Itr)
258         : Itr(std::move(Itr)) {}
259 
InstructionIterator(InstructionListType::iterator Itr)260     InstructionIterator(InstructionListType::iterator Itr)
261         : Itr(new SeqImpl<InstructionListType::iterator>(Itr)) {}
262 
263     template <typename T>
InstructionIterator(T * Itr)264     InstructionIterator(T *Itr) : Itr(new SeqImpl<T *>(Itr)) {}
265 
InstructionIterator(ArrayRef<MCInst>::iterator Itr)266     InstructionIterator(ArrayRef<MCInst>::iterator Itr)
267         : Itr(new SeqImpl<ArrayRef<MCInst>::iterator>(Itr)) {}
268 
InstructionIterator(MutableArrayRef<MCInst>::iterator Itr)269     InstructionIterator(MutableArrayRef<MCInst>::iterator Itr)
270         : Itr(new SeqImpl<MutableArrayRef<MCInst>::iterator>(Itr)) {}
271 
272     // TODO: it would be nice to templatize this on the key type.
InstructionIterator(std::map<uint32_t,MCInst>::iterator Itr)273     InstructionIterator(std::map<uint32_t, MCInst>::iterator Itr)
274         : Itr(new MapImpl<std::map<uint32_t, MCInst>::iterator>(Itr)) {}
275 
276   private:
277     std::unique_ptr<Impl> Itr;
278   };
279 
280 public:
MCPlusBuilder(const MCInstrAnalysis * Analysis,const MCInstrInfo * Info,const MCRegisterInfo * RegInfo)281   MCPlusBuilder(const MCInstrAnalysis *Analysis, const MCInstrInfo *Info,
282                 const MCRegisterInfo *RegInfo)
283       : Analysis(Analysis), Info(Info), RegInfo(RegInfo) {
284     // Initialize the default annotation allocator with id 0
285     AnnotationAllocators.emplace(0, AnnotationAllocator());
286     MaxAllocatorId++;
287     // Build alias map
288     initAliases();
289   }
290 
291   /// Create and return target-specific MC symbolizer for the \p Function.
292   virtual std::unique_ptr<MCSymbolizer>
createTargetSymbolizer(BinaryFunction & Function)293   createTargetSymbolizer(BinaryFunction &Function) const {
294     return nullptr;
295   }
296 
297   /// Initialize a new annotation allocator and return its id
initializeNewAnnotationAllocator()298   AllocatorIdTy initializeNewAnnotationAllocator() {
299     AnnotationAllocators.emplace(MaxAllocatorId, AnnotationAllocator());
300     return MaxAllocatorId++;
301   }
302 
303   /// Return the annotation allocator of a given id
getAnnotationAllocator(AllocatorIdTy AllocatorId)304   AnnotationAllocator &getAnnotationAllocator(AllocatorIdTy AllocatorId) {
305     assert(AnnotationAllocators.count(AllocatorId) &&
306            "allocator not initialized");
307     return AnnotationAllocators.find(AllocatorId)->second;
308   }
309 
310   // Check if an annotation allocator with the given id exists
checkAllocatorExists(AllocatorIdTy AllocatorId)311   bool checkAllocatorExists(AllocatorIdTy AllocatorId) {
312     return AnnotationAllocators.count(AllocatorId);
313   }
314 
315   /// Free the values allocator within the annotation allocator
freeValuesAllocator(AllocatorIdTy AllocatorId)316   void freeValuesAllocator(AllocatorIdTy AllocatorId) {
317     AnnotationAllocator &Allocator = getAnnotationAllocator(AllocatorId);
318     for (MCPlus::MCAnnotation *Annotation : Allocator.AnnotationPool)
319       Annotation->~MCAnnotation();
320 
321     Allocator.AnnotationPool.clear();
322     Allocator.ValueAllocator.Reset();
323   }
324 
~MCPlusBuilder()325   virtual ~MCPlusBuilder() { freeAnnotations(); }
326 
327   /// Free all memory allocated for annotations
freeAnnotations()328   void freeAnnotations() {
329     for (auto &Element : AnnotationAllocators) {
330       AnnotationAllocator &Allocator = Element.second;
331       for (MCPlus::MCAnnotation *Annotation : Allocator.AnnotationPool)
332         Annotation->~MCAnnotation();
333 
334       Allocator.AnnotationPool.clear();
335       Allocator.ValueAllocator.Reset();
336       Allocator.MCInstAllocator.DestroyAll();
337     }
338   }
339 
340   using CompFuncTy = std::function<bool(const MCSymbol *, const MCSymbol *)>;
341 
342   bool equals(const MCInst &A, const MCInst &B, CompFuncTy Comp) const;
343 
344   bool equals(const MCOperand &A, const MCOperand &B, CompFuncTy Comp) const;
345 
346   bool equals(const MCExpr &A, const MCExpr &B, CompFuncTy Comp) const;
347 
348   virtual bool equals(const MCTargetExpr &A, const MCTargetExpr &B,
349                       CompFuncTy Comp) const;
350 
isBranch(const MCInst & Inst)351   virtual bool isBranch(const MCInst &Inst) const {
352     return Analysis->isBranch(Inst);
353   }
354 
isConditionalBranch(const MCInst & Inst)355   virtual bool isConditionalBranch(const MCInst &Inst) const {
356     return Analysis->isConditionalBranch(Inst);
357   }
358 
359   /// Returns true if Inst is a condtional move instruction
isConditionalMove(const MCInst & Inst)360   virtual bool isConditionalMove(const MCInst &Inst) const {
361     llvm_unreachable("not implemented");
362     return false;
363   }
364 
isUnconditionalBranch(const MCInst & Inst)365   virtual bool isUnconditionalBranch(const MCInst &Inst) const {
366     return Analysis->isUnconditionalBranch(Inst) && !isTailCall(Inst);
367   }
368 
isIndirectBranch(const MCInst & Inst)369   virtual bool isIndirectBranch(const MCInst &Inst) const {
370     return Analysis->isIndirectBranch(Inst);
371   }
372 
373   /// Returns true if the instruction is memory indirect call or jump
isBranchOnMem(const MCInst & Inst)374   virtual bool isBranchOnMem(const MCInst &Inst) const {
375     llvm_unreachable("not implemented");
376     return false;
377   }
378 
379   /// Returns true if the instruction is register indirect call or jump
isBranchOnReg(const MCInst & Inst)380   virtual bool isBranchOnReg(const MCInst &Inst) const {
381     llvm_unreachable("not implemented");
382     return false;
383   }
384 
385   /// Check whether we support inverting this branch
isUnsupportedBranch(unsigned Opcode)386   virtual bool isUnsupportedBranch(unsigned Opcode) const { return false; }
387 
388   /// Return true of the instruction is of pseudo kind.
isPseudo(const MCInst & Inst)389   bool isPseudo(const MCInst &Inst) const {
390     return Info->get(Inst.getOpcode()).isPseudo();
391   }
392 
393   /// Creates x86 pause instruction.
createPause(MCInst & Inst)394   virtual void createPause(MCInst &Inst) const {
395     llvm_unreachable("not implemented");
396   }
397 
createLfence(MCInst & Inst)398   virtual void createLfence(MCInst &Inst) const {
399     llvm_unreachable("not implemented");
400   }
401 
createPushRegister(MCInst & Inst,MCPhysReg Reg,unsigned Size)402   virtual void createPushRegister(MCInst &Inst, MCPhysReg Reg,
403                                   unsigned Size) const {
404     llvm_unreachable("not implemented");
405   }
406 
createPopRegister(MCInst & Inst,MCPhysReg Reg,unsigned Size)407   virtual void createPopRegister(MCInst &Inst, MCPhysReg Reg,
408                                  unsigned Size) const {
409     llvm_unreachable("not implemented");
410   }
411 
createPushFlags(MCInst & Inst,unsigned Size)412   virtual void createPushFlags(MCInst &Inst, unsigned Size) const {
413     llvm_unreachable("not implemented");
414   }
415 
createPopFlags(MCInst & Inst,unsigned Size)416   virtual void createPopFlags(MCInst &Inst, unsigned Size) const {
417     llvm_unreachable("not implemented");
418   }
419 
createDirectCall(MCInst & Inst,const MCSymbol * Target,MCContext * Ctx,bool IsTailCall)420   virtual bool createDirectCall(MCInst &Inst, const MCSymbol *Target,
421                                 MCContext *Ctx, bool IsTailCall) {
422     llvm_unreachable("not implemented");
423     return false;
424   }
425 
getX86R11()426   virtual MCPhysReg getX86R11() const { llvm_unreachable("not implemented"); }
427 
428   /// Create increment contents of target by 1 for Instrumentation
createInstrIncMemory(InstructionListType & Instrs,const MCSymbol * Target,MCContext * Ctx,bool IsLeaf)429   virtual void createInstrIncMemory(InstructionListType &Instrs,
430                                     const MCSymbol *Target, MCContext *Ctx,
431                                     bool IsLeaf) const {
432     llvm_unreachable("not implemented");
433   }
434 
435   /// Return a register number that is guaranteed to not match with
436   /// any real register on the underlying architecture.
getNoRegister()437   MCPhysReg getNoRegister() const { return MCRegister::NoRegister; }
438 
439   /// Return a register corresponding to a function integer argument \p ArgNo
440   /// if the argument is passed in a register. Or return the result of
441   /// getNoRegister() otherwise. The enumeration starts at 0.
442   ///
443   /// Note: this should depend on a used calling convention.
getIntArgRegister(unsigned ArgNo)444   virtual MCPhysReg getIntArgRegister(unsigned ArgNo) const {
445     llvm_unreachable("not implemented");
446   }
447 
isIndirectCall(const MCInst & Inst)448   virtual bool isIndirectCall(const MCInst &Inst) const {
449     llvm_unreachable("not implemented");
450     return false;
451   }
452 
isCall(const MCInst & Inst)453   virtual bool isCall(const MCInst &Inst) const {
454     return Analysis->isCall(Inst) || isTailCall(Inst);
455   }
456 
isReturn(const MCInst & Inst)457   virtual bool isReturn(const MCInst &Inst) const {
458     return Analysis->isReturn(Inst);
459   }
460 
isTerminator(const MCInst & Inst)461   virtual bool isTerminator(const MCInst &Inst) const {
462     return Analysis->isTerminator(Inst);
463   }
464 
isNoop(const MCInst & Inst)465   virtual bool isNoop(const MCInst &Inst) const {
466     llvm_unreachable("not implemented");
467     return false;
468   }
469 
isBreakpoint(const MCInst & Inst)470   virtual bool isBreakpoint(const MCInst &Inst) const {
471     llvm_unreachable("not implemented");
472     return false;
473   }
474 
isPrefix(const MCInst & Inst)475   virtual bool isPrefix(const MCInst &Inst) const {
476     llvm_unreachable("not implemented");
477     return false;
478   }
479 
isRep(const MCInst & Inst)480   virtual bool isRep(const MCInst &Inst) const {
481     llvm_unreachable("not implemented");
482     return false;
483   }
484 
deleteREPPrefix(MCInst & Inst)485   virtual bool deleteREPPrefix(MCInst &Inst) const {
486     llvm_unreachable("not implemented");
487     return false;
488   }
489 
isEHLabel(const MCInst & Inst)490   virtual bool isEHLabel(const MCInst &Inst) const {
491     return Inst.getOpcode() == TargetOpcode::EH_LABEL;
492   }
493 
isPop(const MCInst & Inst)494   virtual bool isPop(const MCInst &Inst) const {
495     llvm_unreachable("not implemented");
496     return false;
497   }
498 
499   /// Return true if the instruction is used to terminate an indirect branch.
isTerminateBranch(const MCInst & Inst)500   virtual bool isTerminateBranch(const MCInst &Inst) const {
501     llvm_unreachable("not implemented");
502     return false;
503   }
504 
505   /// Return the width, in bytes, of the memory access performed by \p Inst, if
506   /// this is a pop instruction. Return zero otherwise.
getPopSize(const MCInst & Inst)507   virtual int getPopSize(const MCInst &Inst) const {
508     llvm_unreachable("not implemented");
509     return 0;
510   }
511 
isPush(const MCInst & Inst)512   virtual bool isPush(const MCInst &Inst) const {
513     llvm_unreachable("not implemented");
514     return false;
515   }
516 
517   /// Return the width, in bytes, of the memory access performed by \p Inst, if
518   /// this is a push instruction. Return zero otherwise.
getPushSize(const MCInst & Inst)519   virtual int getPushSize(const MCInst &Inst) const {
520     llvm_unreachable("not implemented");
521     return 0;
522   }
523 
isSUB(const MCInst & Inst)524   virtual bool isSUB(const MCInst &Inst) const {
525     llvm_unreachable("not implemented");
526     return false;
527   }
528 
isLEA64r(const MCInst & Inst)529   virtual bool isLEA64r(const MCInst &Inst) const {
530     llvm_unreachable("not implemented");
531     return false;
532   }
533 
isLeave(const MCInst & Inst)534   virtual bool isLeave(const MCInst &Inst) const {
535     llvm_unreachable("not implemented");
536     return false;
537   }
538 
isADRP(const MCInst & Inst)539   virtual bool isADRP(const MCInst &Inst) const {
540     llvm_unreachable("not implemented");
541     return false;
542   }
543 
isADR(const MCInst & Inst)544   virtual bool isADR(const MCInst &Inst) const {
545     llvm_unreachable("not implemented");
546     return false;
547   }
548 
getADRReg(const MCInst & Inst,MCPhysReg & RegName)549   virtual void getADRReg(const MCInst &Inst, MCPhysReg &RegName) const {
550     llvm_unreachable("not implemented");
551   }
552 
isMoveMem2Reg(const MCInst & Inst)553   virtual bool isMoveMem2Reg(const MCInst &Inst) const {
554     llvm_unreachable("not implemented");
555     return false;
556   }
557 
isLoad(const MCInst & Inst)558   virtual bool isLoad(const MCInst &Inst) const {
559     llvm_unreachable("not implemented");
560     return false;
561   }
562 
isStore(const MCInst & Inst)563   virtual bool isStore(const MCInst &Inst) const {
564     llvm_unreachable("not implemented");
565     return false;
566   }
567 
isCleanRegXOR(const MCInst & Inst)568   virtual bool isCleanRegXOR(const MCInst &Inst) const {
569     llvm_unreachable("not implemented");
570     return false;
571   }
572 
isPacked(const MCInst & Inst)573   virtual bool isPacked(const MCInst &Inst) const {
574     llvm_unreachable("not implemented");
575     return false;
576   }
577 
578   /// If non-zero, this is used to fill the executable space with instructions
579   /// that will trap. Defaults to 0.
getTrapFillValue()580   virtual unsigned getTrapFillValue() const { return 0; }
581 
582   /// Interface and basic functionality of a MCInstMatcher. The idea is to make
583   /// it easy to match one or more MCInsts against a tree-like pattern and
584   /// extract the fragment operands. Example:
585   ///
586   ///   auto IndJmpMatcher =
587   ///       matchIndJmp(matchAdd(matchAnyOperand(), matchAnyOperand()));
588   ///   if (!IndJmpMatcher->match(...))
589   ///     return false;
590   ///
591   /// This matches an indirect jump whose target register is defined by an
592   /// add to form the target address. Matchers should also allow extraction
593   /// of operands, for example:
594   ///
595   ///   uint64_t Scale;
596   ///   auto IndJmpMatcher = BC.MIA->matchIndJmp(
597   ///       BC.MIA->matchAnyOperand(), BC.MIA->matchImm(Scale),
598   ///       BC.MIA->matchReg(), BC.MIA->matchAnyOperand());
599   ///   if (!IndJmpMatcher->match(...))
600   ///     return false;
601   ///
602   /// Here we are interesting in extracting the scale immediate in an indirect
603   /// jump fragment.
604   ///
605   struct MCInstMatcher {
606     MutableArrayRef<MCInst> InstrWindow;
607     MutableArrayRef<MCInst>::iterator CurInst;
~MCInstMatcherMCInstMatcher608     virtual ~MCInstMatcher() {}
609 
610     /// Returns true if the pattern is matched. Needs MCRegisterInfo and
611     /// MCInstrAnalysis for analysis. InstrWindow contains an array
612     /// where the last instruction is always the instruction to start matching
613     /// against a fragment, potentially matching more instructions before it.
614     /// If OpNum is greater than 0, we will not match against the last
615     /// instruction itself but against an operand of the last instruction given
616     /// by the index OpNum. If this operand is a register, we will immediately
617     /// look for a previous instruction defining this register and match against
618     /// it instead. This parent member function contains common bookkeeping
619     /// required to implement this behavior.
matchMCInstMatcher620     virtual bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIA,
621                        MutableArrayRef<MCInst> InInstrWindow, int OpNum) {
622       InstrWindow = InInstrWindow;
623       CurInst = InstrWindow.end();
624 
625       if (!next())
626         return false;
627 
628       if (OpNum < 0)
629         return true;
630 
631       if (static_cast<unsigned int>(OpNum) >=
632           MCPlus::getNumPrimeOperands(*CurInst))
633         return false;
634 
635       const MCOperand &Op = CurInst->getOperand(OpNum);
636       if (!Op.isReg())
637         return true;
638 
639       MCPhysReg Reg = Op.getReg();
640       while (next()) {
641         const MCInstrDesc &InstrDesc = MIA.Info->get(CurInst->getOpcode());
642         if (InstrDesc.hasDefOfPhysReg(*CurInst, Reg, MRI)) {
643           InstrWindow = InstrWindow.slice(0, CurInst - InstrWindow.begin() + 1);
644           return true;
645         }
646       }
647       return false;
648     }
649 
650     /// If successfully matched, calling this function will add an annotation
651     /// to all instructions that were matched. This is used to easily tag
652     /// instructions for deletion and implement match-and-replace operations.
annotateMCInstMatcher653     virtual void annotate(MCPlusBuilder &MIA, StringRef Annotation) {}
654 
655     /// Moves internal instruction iterator to the next instruction, walking
656     /// backwards for pattern matching (effectively the previous instruction in
657     /// regular order).
nextMCInstMatcher658     bool next() {
659       if (CurInst == InstrWindow.begin())
660         return false;
661       --CurInst;
662       return true;
663     }
664   };
665 
666   /// Matches any operand
667   struct AnyOperandMatcher : MCInstMatcher {
668     MCOperand &Op;
AnyOperandMatcherAnyOperandMatcher669     AnyOperandMatcher(MCOperand &Op) : Op(Op) {}
670 
matchAnyOperandMatcher671     bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIA,
672                MutableArrayRef<MCInst> InInstrWindow, int OpNum) override {
673       auto I = InInstrWindow.end();
674       if (I == InInstrWindow.begin())
675         return false;
676       --I;
677       if (OpNum < 0 ||
678           static_cast<unsigned int>(OpNum) >= MCPlus::getNumPrimeOperands(*I))
679         return false;
680       Op = I->getOperand(OpNum);
681       return true;
682     }
683   };
684 
685   /// Matches operands that are immediates
686   struct ImmMatcher : MCInstMatcher {
687     uint64_t &Imm;
ImmMatcherImmMatcher688     ImmMatcher(uint64_t &Imm) : Imm(Imm) {}
689 
matchImmMatcher690     bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIA,
691                MutableArrayRef<MCInst> InInstrWindow, int OpNum) override {
692       if (!MCInstMatcher::match(MRI, MIA, InInstrWindow, OpNum))
693         return false;
694 
695       if (OpNum < 0)
696         return false;
697       const MCOperand &Op = CurInst->getOperand(OpNum);
698       if (!Op.isImm())
699         return false;
700       Imm = Op.getImm();
701       return true;
702     }
703   };
704 
705   /// Matches operands that are MCSymbols
706   struct SymbolMatcher : MCInstMatcher {
707     const MCSymbol *&Sym;
SymbolMatcherSymbolMatcher708     SymbolMatcher(const MCSymbol *&Sym) : Sym(Sym) {}
709 
matchSymbolMatcher710     bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIA,
711                MutableArrayRef<MCInst> InInstrWindow, int OpNum) override {
712       if (!MCInstMatcher::match(MRI, MIA, InInstrWindow, OpNum))
713         return false;
714 
715       if (OpNum < 0)
716         return false;
717       Sym = MIA.getTargetSymbol(*CurInst, OpNum);
718       return Sym != nullptr;
719     }
720   };
721 
722   /// Matches operands that are registers
723   struct RegMatcher : MCInstMatcher {
724     MCPhysReg &Reg;
RegMatcherRegMatcher725     RegMatcher(MCPhysReg &Reg) : Reg(Reg) {}
726 
matchRegMatcher727     bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIA,
728                MutableArrayRef<MCInst> InInstrWindow, int OpNum) override {
729       auto I = InInstrWindow.end();
730       if (I == InInstrWindow.begin())
731         return false;
732       --I;
733       if (OpNum < 0 ||
734           static_cast<unsigned int>(OpNum) >= MCPlus::getNumPrimeOperands(*I))
735         return false;
736       const MCOperand &Op = I->getOperand(OpNum);
737       if (!Op.isReg())
738         return false;
739       Reg = Op.getReg();
740       return true;
741     }
742   };
743 
matchAnyOperand(MCOperand & Op)744   std::unique_ptr<MCInstMatcher> matchAnyOperand(MCOperand &Op) const {
745     return std::unique_ptr<MCInstMatcher>(new AnyOperandMatcher(Op));
746   }
747 
matchAnyOperand()748   std::unique_ptr<MCInstMatcher> matchAnyOperand() const {
749     static MCOperand Unused;
750     return std::unique_ptr<MCInstMatcher>(new AnyOperandMatcher(Unused));
751   }
752 
matchReg(MCPhysReg & Reg)753   std::unique_ptr<MCInstMatcher> matchReg(MCPhysReg &Reg) const {
754     return std::unique_ptr<MCInstMatcher>(new RegMatcher(Reg));
755   }
756 
matchReg()757   std::unique_ptr<MCInstMatcher> matchReg() const {
758     static MCPhysReg Unused;
759     return std::unique_ptr<MCInstMatcher>(new RegMatcher(Unused));
760   }
761 
matchImm(uint64_t & Imm)762   std::unique_ptr<MCInstMatcher> matchImm(uint64_t &Imm) const {
763     return std::unique_ptr<MCInstMatcher>(new ImmMatcher(Imm));
764   }
765 
matchImm()766   std::unique_ptr<MCInstMatcher> matchImm() const {
767     static uint64_t Unused;
768     return std::unique_ptr<MCInstMatcher>(new ImmMatcher(Unused));
769   }
770 
matchSymbol(const MCSymbol * & Sym)771   std::unique_ptr<MCInstMatcher> matchSymbol(const MCSymbol *&Sym) const {
772     return std::unique_ptr<MCInstMatcher>(new SymbolMatcher(Sym));
773   }
774 
matchSymbol()775   std::unique_ptr<MCInstMatcher> matchSymbol() const {
776     static const MCSymbol *Unused;
777     return std::unique_ptr<MCInstMatcher>(new SymbolMatcher(Unused));
778   }
779 
780   virtual std::unique_ptr<MCInstMatcher>
matchIndJmp(std::unique_ptr<MCInstMatcher> Target)781   matchIndJmp(std::unique_ptr<MCInstMatcher> Target) const {
782     llvm_unreachable("not implemented");
783     return nullptr;
784   }
785 
786   virtual std::unique_ptr<MCInstMatcher>
matchIndJmp(std::unique_ptr<MCInstMatcher> Base,std::unique_ptr<MCInstMatcher> Scale,std::unique_ptr<MCInstMatcher> Index,std::unique_ptr<MCInstMatcher> Offset)787   matchIndJmp(std::unique_ptr<MCInstMatcher> Base,
788               std::unique_ptr<MCInstMatcher> Scale,
789               std::unique_ptr<MCInstMatcher> Index,
790               std::unique_ptr<MCInstMatcher> Offset) const {
791     llvm_unreachable("not implemented");
792     return nullptr;
793   }
794 
795   virtual std::unique_ptr<MCInstMatcher>
matchAdd(std::unique_ptr<MCInstMatcher> A,std::unique_ptr<MCInstMatcher> B)796   matchAdd(std::unique_ptr<MCInstMatcher> A,
797            std::unique_ptr<MCInstMatcher> B) const {
798     llvm_unreachable("not implemented");
799     return nullptr;
800   }
801 
802   virtual std::unique_ptr<MCInstMatcher>
matchLoadAddr(std::unique_ptr<MCInstMatcher> Target)803   matchLoadAddr(std::unique_ptr<MCInstMatcher> Target) const {
804     llvm_unreachable("not implemented");
805     return nullptr;
806   }
807 
808   virtual std::unique_ptr<MCInstMatcher>
matchLoad(std::unique_ptr<MCInstMatcher> Base,std::unique_ptr<MCInstMatcher> Scale,std::unique_ptr<MCInstMatcher> Index,std::unique_ptr<MCInstMatcher> Offset)809   matchLoad(std::unique_ptr<MCInstMatcher> Base,
810             std::unique_ptr<MCInstMatcher> Scale,
811             std::unique_ptr<MCInstMatcher> Index,
812             std::unique_ptr<MCInstMatcher> Offset) const {
813     llvm_unreachable("not implemented");
814     return nullptr;
815   }
816 
817   /// \brief Given a branch instruction try to get the address the branch
818   /// targets. Return true on success, and the address in Target.
819   virtual bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
820                               uint64_t &Target) const;
821 
822   /// Return true if one of the operands of the \p Inst instruction uses
823   /// PC-relative addressing.
824   /// Note that PC-relative branches do not fall into this category.
hasPCRelOperand(const MCInst & Inst)825   virtual bool hasPCRelOperand(const MCInst &Inst) const {
826     llvm_unreachable("not implemented");
827     return false;
828   }
829 
830   /// Return a number of the operand representing a memory.
831   /// Return -1 if the instruction doesn't have an explicit memory field.
getMemoryOperandNo(const MCInst & Inst)832   virtual int getMemoryOperandNo(const MCInst &Inst) const {
833     llvm_unreachable("not implemented");
834     return -1;
835   }
836 
837   /// Return true if the instruction is encoded using EVEX (AVX-512).
hasEVEXEncoding(const MCInst & Inst)838   virtual bool hasEVEXEncoding(const MCInst &Inst) const {
839     llvm_unreachable("not implemented");
840     return false;
841   }
842 
843   /// Return true if a pair of instructions represented by \p Insts
844   /// could be fused into a single uop.
isMacroOpFusionPair(ArrayRef<MCInst> Insts)845   virtual bool isMacroOpFusionPair(ArrayRef<MCInst> Insts) const {
846     llvm_unreachable("not implemented");
847     return false;
848   }
849 
850   /// Given an instruction with (compound) memory operand, evaluate and return
851   /// the corresponding values. Note that the operand could be in any position,
852   /// but there is an assumption there's only one compound memory operand.
853   /// Return true upon success, return false if the instruction does not have
854   /// a memory operand.
855   ///
856   /// Since a Displacement field could be either an immediate or an expression,
857   /// the function sets either \p DispImm or \p DispExpr value.
858   virtual bool
859   evaluateX86MemoryOperand(const MCInst &Inst, unsigned *BaseRegNum,
860                            int64_t *ScaleImm, unsigned *IndexRegNum,
861                            int64_t *DispImm, unsigned *SegmentRegNum,
862                            const MCExpr **DispExpr = nullptr) const {
863     llvm_unreachable("not implemented");
864     return false;
865   }
866 
867   /// Given an instruction with memory addressing attempt to statically compute
868   /// the address being accessed. Return true on success, and the address in
869   /// \p Target.
870   ///
871   /// For RIP-relative addressing the caller is required to pass instruction
872   /// \p Address and \p Size.
873   virtual bool evaluateMemOperandTarget(const MCInst &Inst, uint64_t &Target,
874                                         uint64_t Address = 0,
875                                         uint64_t Size = 0) const {
876     llvm_unreachable("not implemented");
877     return false;
878   }
879 
880   /// Return operand iterator pointing to displacement in the compound memory
881   /// operand if such exists. Return Inst.end() otherwise.
getMemOperandDisp(MCInst & Inst)882   virtual MCInst::iterator getMemOperandDisp(MCInst &Inst) const {
883     llvm_unreachable("not implemented");
884     return Inst.end();
885   }
886 
887   /// Analyze \p Inst and return true if this instruction accesses \p Size
888   /// bytes of the stack frame at position \p StackOffset. \p IsLoad and
889   /// \p IsStore are set accordingly. If both are set, it means it is a
890   /// instruction that reads and updates the same memory location. \p Reg is set
891   /// to the source register in case of a store or destination register in case
892   /// of a load. If the store does not use a source register, \p SrcImm will
893   /// contain the source immediate and \p IsStoreFromReg will be set to false.
894   /// \p Simple is false if the instruction is not fully understood by
895   /// companion functions "replaceMemOperandWithImm" or
896   /// "replaceMemOperandWithReg".
isStackAccess(const MCInst & Inst,bool & IsLoad,bool & IsStore,bool & IsStoreFromReg,MCPhysReg & Reg,int32_t & SrcImm,uint16_t & StackPtrReg,int64_t & StackOffset,uint8_t & Size,bool & IsSimple,bool & IsIndexed)897   virtual bool isStackAccess(const MCInst &Inst, bool &IsLoad, bool &IsStore,
898                              bool &IsStoreFromReg, MCPhysReg &Reg,
899                              int32_t &SrcImm, uint16_t &StackPtrReg,
900                              int64_t &StackOffset, uint8_t &Size,
901                              bool &IsSimple, bool &IsIndexed) const {
902     llvm_unreachable("not implemented");
903     return false;
904   }
905 
906   /// Convert a stack accessing load/store instruction in \p Inst to a PUSH
907   /// or POP saving/restoring the source/dest reg in \p Inst. The original
908   /// stack offset in \p Inst is ignored.
changeToPushOrPop(MCInst & Inst)909   virtual void changeToPushOrPop(MCInst &Inst) const {
910     llvm_unreachable("not implemented");
911   }
912 
913   /// Identify stack adjustment instructions -- those that change the stack
914   /// pointer by adding or subtracting an immediate.
isStackAdjustment(const MCInst & Inst)915   virtual bool isStackAdjustment(const MCInst &Inst) const {
916     llvm_unreachable("not implemented");
917     return false;
918   }
919 
920   /// Use \p Input1 or Input2 as the current value for the input
921   /// register and put in \p Output the changes incurred by executing
922   /// \p Inst. Return false if it was not possible to perform the
923   /// evaluation. evaluateStackOffsetExpr is restricted to operations
924   /// that have associativity with addition. Its intended usage is for
925   /// evaluating stack offset changes. In these cases, expressions
926   /// appear in the form of (x + offset) OP constant, where x is an
927   /// unknown base (such as stack base) but offset and constant are
928   /// known. In these cases, \p Output represents the new stack offset
929   /// after executing \p Inst. Because we don't know x, we can't
930   /// evaluate operations such as multiply or AND/OR, e.g. (x +
931   /// offset) OP constant is not the same as x + (offset OP constant).
932   virtual bool
evaluateStackOffsetExpr(const MCInst & Inst,int64_t & Output,std::pair<MCPhysReg,int64_t> Input1,std::pair<MCPhysReg,int64_t> Input2)933   evaluateStackOffsetExpr(const MCInst &Inst, int64_t &Output,
934                           std::pair<MCPhysReg, int64_t> Input1,
935                           std::pair<MCPhysReg, int64_t> Input2) const {
936     llvm_unreachable("not implemented");
937     return false;
938   }
939 
isRegToRegMove(const MCInst & Inst,MCPhysReg & From,MCPhysReg & To)940   virtual bool isRegToRegMove(const MCInst &Inst, MCPhysReg &From,
941                               MCPhysReg &To) const {
942     llvm_unreachable("not implemented");
943     return false;
944   }
945 
getStackPointer()946   virtual MCPhysReg getStackPointer() const {
947     llvm_unreachable("not implemented");
948     return 0;
949   }
950 
getFramePointer()951   virtual MCPhysReg getFramePointer() const {
952     llvm_unreachable("not implemented");
953     return 0;
954   }
955 
getFlagsReg()956   virtual MCPhysReg getFlagsReg() const {
957     llvm_unreachable("not implemented");
958     return 0;
959   }
960 
961   /// Return true if \p Inst is a instruction that copies either the frame
962   /// pointer or the stack pointer to another general purpose register or
963   /// writes it to a memory location.
escapesVariable(const MCInst & Inst,bool HasFramePointer)964   virtual bool escapesVariable(const MCInst &Inst, bool HasFramePointer) const {
965     llvm_unreachable("not implemented");
966     return false;
967   }
968 
969   /// Discard operand \p OpNum replacing it by a new MCOperand that is a
970   /// MCExpr referencing \p Symbol + \p Addend.
971   virtual bool setOperandToSymbolRef(MCInst &Inst, int OpNum,
972                                      const MCSymbol *Symbol, int64_t Addend,
973                                      MCContext *Ctx, uint64_t RelType) const;
974 
975   /// Replace an immediate operand in the instruction \p Inst with a reference
976   /// of the passed \p Symbol plus \p Addend. If the instruction does not have
977   /// an immediate operand or has more than one - then return false. Otherwise
978   /// return true.
replaceImmWithSymbolRef(MCInst & Inst,const MCSymbol * Symbol,int64_t Addend,MCContext * Ctx,int64_t & Value,uint64_t RelType)979   virtual bool replaceImmWithSymbolRef(MCInst &Inst, const MCSymbol *Symbol,
980                                        int64_t Addend, MCContext *Ctx,
981                                        int64_t &Value, uint64_t RelType) const {
982     llvm_unreachable("not implemented");
983     return false;
984   }
985 
986   // Replace Register in Inst with Imm. Returns true if successful
replaceRegWithImm(MCInst & Inst,unsigned Register,int64_t Imm)987   virtual bool replaceRegWithImm(MCInst &Inst, unsigned Register,
988                                  int64_t Imm) const {
989     llvm_unreachable("not implemented");
990     return false;
991   }
992 
993   // Replace ToReplace in Inst with ReplaceWith. Returns true if successful
replaceRegWithReg(MCInst & Inst,unsigned ToReplace,unsigned ReplaceWith)994   virtual bool replaceRegWithReg(MCInst &Inst, unsigned ToReplace,
995                                  unsigned ReplaceWith) const {
996     llvm_unreachable("not implemented");
997     return false;
998   }
999 
1000   /// Add \p NewImm to the current immediate operand of \p Inst. If it is a
1001   /// memory accessing instruction, this immediate is the memory address
1002   /// displacement. Otherwise, the target operand is the first immediate
1003   /// operand found in \p Inst. Return false if no imm operand found.
addToImm(MCInst & Inst,int64_t & Amt,MCContext * Ctx)1004   virtual bool addToImm(MCInst &Inst, int64_t &Amt, MCContext *Ctx) const {
1005     llvm_unreachable("not implemented");
1006     return false;
1007   }
1008 
1009   /// Replace the compound memory operand of Inst with an immediate operand.
1010   /// The value of the immediate operand is computed by reading the \p
1011   /// ConstantData array starting from \p offset and assuming little-endianess.
1012   /// Return true on success. The given instruction is modified in place.
replaceMemOperandWithImm(MCInst & Inst,StringRef ConstantData,uint64_t Offset)1013   virtual bool replaceMemOperandWithImm(MCInst &Inst, StringRef ConstantData,
1014                                         uint64_t Offset) const {
1015     llvm_unreachable("not implemented");
1016     return false;
1017   }
1018 
1019   /// Same as replaceMemOperandWithImm, but for registers.
replaceMemOperandWithReg(MCInst & Inst,MCPhysReg RegNum)1020   virtual bool replaceMemOperandWithReg(MCInst &Inst, MCPhysReg RegNum) const {
1021     llvm_unreachable("not implemented");
1022     return false;
1023   }
1024 
1025   /// Return true if a move instruction moves a register to itself.
isRedundantMove(const MCInst & Inst)1026   virtual bool isRedundantMove(const MCInst &Inst) const {
1027     llvm_unreachable("not implemented");
1028     return false;
1029   }
1030 
1031   /// Return true if the instruction is a tail call.
1032   bool isTailCall(const MCInst &Inst) const;
1033 
1034   /// Return true if the instruction is a call with an exception handling info.
isInvoke(const MCInst & Inst)1035   virtual bool isInvoke(const MCInst &Inst) const {
1036     return isCall(Inst) && getEHInfo(Inst);
1037   }
1038 
1039   /// Return true if \p Inst is an instruction that potentially traps when
1040   /// working with addresses not aligned to the size of the operand.
requiresAlignedAddress(const MCInst & Inst)1041   virtual bool requiresAlignedAddress(const MCInst &Inst) const {
1042     llvm_unreachable("not implemented");
1043     return false;
1044   }
1045 
1046   /// Return handler and action info for invoke instruction if present.
1047   Optional<MCPlus::MCLandingPad> getEHInfo(const MCInst &Inst) const;
1048 
1049   /// Add handler and action info for call instruction.
1050   void addEHInfo(MCInst &Inst, const MCPlus::MCLandingPad &LP);
1051 
1052   /// Update exception-handling info for the invoke instruction \p Inst.
1053   /// Return true on success and false otherwise, e.g. if the instruction is
1054   /// not an invoke.
1055   bool updateEHInfo(MCInst &Inst, const MCPlus::MCLandingPad &LP);
1056 
1057   /// Return non-negative GNU_args_size associated with the instruction
1058   /// or -1 if there's no associated info.
1059   int64_t getGnuArgsSize(const MCInst &Inst) const;
1060 
1061   /// Add the value of GNU_args_size to Inst if it already has EH info.
1062   void addGnuArgsSize(MCInst &Inst, int64_t GnuArgsSize,
1063                       AllocatorIdTy AllocId = 0);
1064 
1065   /// Return jump table addressed by this instruction.
1066   uint64_t getJumpTable(const MCInst &Inst) const;
1067 
1068   /// Return index register for instruction that uses a jump table.
1069   uint16_t getJumpTableIndexReg(const MCInst &Inst) const;
1070 
1071   /// Set jump table addressed by this instruction.
1072   bool setJumpTable(MCInst &Inst, uint64_t Value, uint16_t IndexReg,
1073                     AllocatorIdTy AllocId = 0);
1074 
1075   /// Disassociate instruction with a jump table.
1076   bool unsetJumpTable(MCInst &Inst);
1077 
1078   /// Return destination of conditional tail call instruction if \p Inst is one.
1079   Optional<uint64_t> getConditionalTailCall(const MCInst &Inst) const;
1080 
1081   /// Mark the \p Instruction as a conditional tail call, and set its
1082   /// destination address if it is known. If \p Instruction was already marked,
1083   /// update its destination with \p Dest.
1084   bool setConditionalTailCall(MCInst &Inst, uint64_t Dest = 0);
1085 
1086   /// If \p Inst was marked as a conditional tail call convert it to a regular
1087   /// branch. Return true if the instruction was converted.
1088   bool unsetConditionalTailCall(MCInst &Inst);
1089 
1090   /// Return offset of \p Inst in the original function, if available.
1091   Optional<uint32_t> getOffset(const MCInst &Inst) const;
1092 
1093   /// Return the offset if the annotation is present, or \p Default otherwise.
1094   uint32_t getOffsetWithDefault(const MCInst &Inst, uint32_t Default) const;
1095 
1096   /// Set offset of \p Inst in the original function.
1097   bool setOffset(MCInst &Inst, uint32_t Offset, AllocatorIdTy AllocatorId = 0);
1098 
1099   /// Remove offset annotation.
1100   bool clearOffset(MCInst &Inst);
1101 
1102   /// Return MCSymbol that represents a target of this instruction at a given
1103   /// operand number \p OpNum. If there's no symbol associated with
1104   /// the operand - return nullptr.
1105   virtual const MCSymbol *getTargetSymbol(const MCInst &Inst,
1106                                           unsigned OpNum = 0) const {
1107     llvm_unreachable("not implemented");
1108     return nullptr;
1109   }
1110 
1111   /// Return MCSymbol extracted from a target expression
getTargetSymbol(const MCExpr * Expr)1112   virtual const MCSymbol *getTargetSymbol(const MCExpr *Expr) const {
1113     return &cast<const MCSymbolRefExpr>(Expr)->getSymbol();
1114   }
1115 
1116   /// Return addend that represents an offset from MCSymbol target
1117   /// of this instruction at a given operand number \p OpNum.
1118   /// If there's no symbol associated with  the operand - return 0
1119   virtual int64_t getTargetAddend(const MCInst &Inst,
1120                                   unsigned OpNum = 0) const {
1121     llvm_unreachable("not implemented");
1122     return 0;
1123   }
1124 
1125   /// Return MCSymbol addend extracted from a target expression
getTargetAddend(const MCExpr * Expr)1126   virtual int64_t getTargetAddend(const MCExpr *Expr) const {
1127     llvm_unreachable("not implemented");
1128     return 0;
1129   }
1130 
1131   /// Return MCSymbol/offset extracted from a target expression
1132   virtual std::pair<const MCSymbol *, uint64_t>
getTargetSymbolInfo(const MCExpr * Expr)1133   getTargetSymbolInfo(const MCExpr *Expr) const {
1134     if (auto *SymExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1135       return std::make_pair(&SymExpr->getSymbol(), 0);
1136     } else if (auto *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1137       const auto *SymExpr = dyn_cast<MCSymbolRefExpr>(BinExpr->getLHS());
1138       const auto *ConstExpr = dyn_cast<MCConstantExpr>(BinExpr->getRHS());
1139       if (BinExpr->getOpcode() == MCBinaryExpr::Add && SymExpr && ConstExpr)
1140         return std::make_pair(&SymExpr->getSymbol(), ConstExpr->getValue());
1141     }
1142     return std::make_pair(nullptr, 0);
1143   }
1144 
1145   /// Replace displacement in compound memory operand with given \p Operand.
replaceMemOperandDisp(MCInst & Inst,MCOperand Operand)1146   virtual bool replaceMemOperandDisp(MCInst &Inst, MCOperand Operand) const {
1147     llvm_unreachable("not implemented");
1148     return false;
1149   }
1150 
1151   /// Return the MCExpr used for absolute references in this target
getTargetExprFor(MCInst & Inst,const MCExpr * Expr,MCContext & Ctx,uint64_t RelType)1152   virtual const MCExpr *getTargetExprFor(MCInst &Inst, const MCExpr *Expr,
1153                                          MCContext &Ctx,
1154                                          uint64_t RelType) const {
1155     return Expr;
1156   }
1157 
1158   /// Return a BitVector marking all sub or super registers of \p Reg, including
1159   /// itself.
1160   virtual const BitVector &getAliases(MCPhysReg Reg,
1161                                       bool OnlySmaller = false) const;
1162 
1163   /// Initialize aliases tables.
1164   virtual void initAliases();
1165 
1166   /// Change \p Regs setting all registers used to pass parameters according
1167   /// to the host abi. Do nothing if not implemented.
getRegsUsedAsParams()1168   virtual BitVector getRegsUsedAsParams() const {
1169     llvm_unreachable("not implemented");
1170     return BitVector();
1171   }
1172 
1173   /// Change \p Regs setting all registers used as callee-saved according
1174   /// to the host abi. Do nothing if not implemented.
getCalleeSavedRegs(BitVector & Regs)1175   virtual void getCalleeSavedRegs(BitVector &Regs) const {
1176     llvm_unreachable("not implemented");
1177   }
1178 
1179   /// Get the default def_in and live_out registers for the function
1180   /// Currently only used for the Stoke optimzation
getDefaultDefIn(BitVector & Regs)1181   virtual void getDefaultDefIn(BitVector &Regs) const {
1182     llvm_unreachable("not implemented");
1183   }
1184 
1185   /// Similar to getDefaultDefIn
getDefaultLiveOut(BitVector & Regs)1186   virtual void getDefaultLiveOut(BitVector &Regs) const {
1187     llvm_unreachable("not implemented");
1188   }
1189 
1190   /// Change \p Regs with a bitmask with all general purpose regs
1191   virtual void getGPRegs(BitVector &Regs, bool IncludeAlias = true) const {
1192     llvm_unreachable("not implemented");
1193   }
1194 
1195   /// Change \p Regs with a bitmask with all general purpose regs that can be
1196   /// encoded without extra prefix bytes. For x86 only.
getClassicGPRegs(BitVector & Regs)1197   virtual void getClassicGPRegs(BitVector &Regs) const {
1198     llvm_unreachable("not implemented");
1199   }
1200 
1201   /// Set of Registers used by the Rep instruction
getRepRegs(BitVector & Regs)1202   virtual void getRepRegs(BitVector &Regs) const {
1203     llvm_unreachable("not implemented");
1204   }
1205 
1206   /// Return the register width in bytes (1, 2, 4 or 8)
1207   virtual uint8_t getRegSize(MCPhysReg Reg) const;
1208 
1209   /// For aliased registers, return an alias of \p Reg that has the width of
1210   /// \p Size bytes
getAliasSized(MCPhysReg Reg,uint8_t Size)1211   virtual MCPhysReg getAliasSized(MCPhysReg Reg, uint8_t Size) const {
1212     llvm_unreachable("not implemented");
1213     return 0;
1214   }
1215 
1216   /// For X86, return whether this register is an upper 8-bit register, such as
1217   /// AH, BH, etc.
isUpper8BitReg(MCPhysReg Reg)1218   virtual bool isUpper8BitReg(MCPhysReg Reg) const {
1219     llvm_unreachable("not implemented");
1220     return false;
1221   }
1222 
1223   /// For X86, return whether this instruction has special constraints that
1224   /// prevents it from encoding registers that require a REX prefix.
cannotUseREX(const MCInst & Inst)1225   virtual bool cannotUseREX(const MCInst &Inst) const {
1226     llvm_unreachable("not implemented");
1227     return false;
1228   }
1229 
1230   /// Modifies the set \p Regs by adding registers \p Inst may rewrite. Caller
1231   /// is responsible for passing a valid BitVector with the size equivalent to
1232   /// the number of registers in the target.
1233   /// Since this function is called many times during clobber analysis, it
1234   /// expects the caller to manage BitVector creation to avoid extra overhead.
1235   virtual void getClobberedRegs(const MCInst &Inst, BitVector &Regs) const;
1236 
1237   /// Set of all registers touched by this instruction, including implicit uses
1238   /// and defs.
1239   virtual void getTouchedRegs(const MCInst &Inst, BitVector &Regs) const;
1240 
1241   /// Set of all registers being written to by this instruction -- includes
1242   /// aliases but only if they are strictly smaller than the actual reg
1243   virtual void getWrittenRegs(const MCInst &Inst, BitVector &Regs) const;
1244 
1245   /// Set of all registers being read by this instruction -- includes aliases
1246   /// but only if they are strictly smaller than the actual reg
1247   virtual void getUsedRegs(const MCInst &Inst, BitVector &Regs) const;
1248 
1249   /// Set of all src registers -- includes aliases but
1250   /// only if they are strictly smaller than the actual reg
1251   virtual void getSrcRegs(const MCInst &Inst, BitVector &Regs) const;
1252 
1253   /// Return true if this instruction defines the specified physical
1254   /// register either explicitly or implicitly.
1255   virtual bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg) const;
1256 
1257   /// Return true if this instruction uses the specified physical
1258   /// register either explicitly or implicitly.
1259   virtual bool hasUseOfPhysReg(const MCInst &MI, unsigned Reg) const;
1260 
1261   /// Replace displacement in compound memory operand with given \p Label.
replaceMemOperandDisp(MCInst & Inst,const MCSymbol * Label,MCContext * Ctx)1262   bool replaceMemOperandDisp(MCInst &Inst, const MCSymbol *Label,
1263                              MCContext *Ctx) const {
1264     return replaceMemOperandDisp(
1265         Inst, MCOperand::createExpr(MCSymbolRefExpr::create(Label, *Ctx)));
1266   }
1267 
1268   /// Returns how many bits we have in this instruction to encode a PC-rel
1269   /// imm.
getPCRelEncodingSize(const MCInst & Inst)1270   virtual int getPCRelEncodingSize(const MCInst &Inst) const {
1271     llvm_unreachable("not implemented");
1272     return 0;
1273   }
1274 
1275   /// Replace instruction opcode to be a tail call instead of jump.
convertJmpToTailCall(MCInst & Inst)1276   virtual bool convertJmpToTailCall(MCInst &Inst) {
1277     llvm_unreachable("not implemented");
1278     return false;
1279   }
1280 
1281   /// Perform any additional actions to transform a (conditional) tail call
1282   /// into a (conditional) jump. Assume the target was already replaced with
1283   /// a local one, so the default is to do nothing more.
convertTailCallToJmp(MCInst & Inst)1284   virtual bool convertTailCallToJmp(MCInst &Inst) { return true; }
1285 
1286   /// Replace instruction opcode to be a regural call instead of tail call.
convertTailCallToCall(MCInst & Inst)1287   virtual bool convertTailCallToCall(MCInst &Inst) {
1288     llvm_unreachable("not implemented");
1289     return false;
1290   }
1291 
1292   /// Modify a direct call instruction \p Inst with an indirect call taking
1293   /// a destination from a memory location pointed by \p TargetLocation symbol.
convertCallToIndirectCall(MCInst & Inst,const MCSymbol * TargetLocation,MCContext * Ctx)1294   virtual bool convertCallToIndirectCall(MCInst &Inst,
1295                                          const MCSymbol *TargetLocation,
1296                                          MCContext *Ctx) {
1297     llvm_unreachable("not implemented");
1298     return false;
1299   }
1300 
1301   /// Morph an indirect call into a load where \p Reg holds the call target.
convertIndirectCallToLoad(MCInst & Inst,MCPhysReg Reg)1302   virtual void convertIndirectCallToLoad(MCInst &Inst, MCPhysReg Reg) {
1303     llvm_unreachable("not implemented");
1304   }
1305 
1306   /// Replace instruction with a shorter version that could be relaxed later
1307   /// if needed.
shortenInstruction(MCInst & Inst,const MCSubtargetInfo & STI)1308   virtual bool shortenInstruction(MCInst &Inst,
1309                                   const MCSubtargetInfo &STI) const {
1310     llvm_unreachable("not implemented");
1311     return false;
1312   }
1313 
1314   /// Convert a move instruction into a conditional move instruction, given a
1315   /// condition code.
1316   virtual bool
1317   convertMoveToConditionalMove(MCInst &Inst, unsigned CC,
1318                                bool AllowStackMemOp = false,
1319                                bool AllowBasePtrStackMemOp = false) const {
1320     llvm_unreachable("not implemented");
1321     return false;
1322   }
1323 
1324   /// Lower a tail call instruction \p Inst if required by target.
lowerTailCall(MCInst & Inst)1325   virtual bool lowerTailCall(MCInst &Inst) {
1326     llvm_unreachable("not implemented");
1327     return false;
1328   }
1329 
1330   /// Receives a list of MCInst of the basic block to analyze and interpret the
1331   /// terminators of this basic block. TBB must be initialized with the original
1332   /// fall-through for this BB.
analyzeBranch(InstructionIterator Begin,InstructionIterator End,const MCSymbol * & TBB,const MCSymbol * & FBB,MCInst * & CondBranch,MCInst * & UncondBranch)1333   virtual bool analyzeBranch(InstructionIterator Begin, InstructionIterator End,
1334                              const MCSymbol *&TBB, const MCSymbol *&FBB,
1335                              MCInst *&CondBranch, MCInst *&UncondBranch) const {
1336     llvm_unreachable("not implemented");
1337     return false;
1338   }
1339 
1340   /// Analyze \p Instruction to try and determine what type of indirect branch
1341   /// it is.  It is assumed that \p Instruction passes isIndirectBranch().
1342   /// \p BB is an array of instructions immediately preceding \p Instruction.
1343   /// If \p Instruction can be successfully analyzed, the output parameters
1344   /// will be set to the different components of the branch.  \p MemLocInstr
1345   /// is the instruction that loads up the indirect function pointer.  It may
1346   /// or may not be same as \p Instruction.
1347   virtual IndirectBranchType
analyzeIndirectBranch(MCInst & Instruction,InstructionIterator Begin,InstructionIterator End,const unsigned PtrSize,MCInst * & MemLocInstr,unsigned & BaseRegNum,unsigned & IndexRegNum,int64_t & DispValue,const MCExpr * & DispExpr,MCInst * & PCRelBaseOut)1348   analyzeIndirectBranch(MCInst &Instruction, InstructionIterator Begin,
1349                         InstructionIterator End, const unsigned PtrSize,
1350                         MCInst *&MemLocInstr, unsigned &BaseRegNum,
1351                         unsigned &IndexRegNum, int64_t &DispValue,
1352                         const MCExpr *&DispExpr, MCInst *&PCRelBaseOut) const {
1353     llvm_unreachable("not implemented");
1354     return IndirectBranchType::UNKNOWN;
1355   }
1356 
1357   /// Analyze branch \p Instruction in PLT section and try to determine
1358   /// associated got entry address.
analyzePLTEntry(MCInst & Instruction,InstructionIterator Begin,InstructionIterator End,uint64_t BeginPC)1359   virtual uint64_t analyzePLTEntry(MCInst &Instruction,
1360                                    InstructionIterator Begin,
1361                                    InstructionIterator End,
1362                                    uint64_t BeginPC) const {
1363     llvm_unreachable("not implemented");
1364     return 0;
1365   }
1366 
analyzeVirtualMethodCall(InstructionIterator Begin,InstructionIterator End,std::vector<MCInst * > & MethodFetchInsns,unsigned & VtableRegNum,unsigned & BaseRegNum,uint64_t & MethodOffset)1367   virtual bool analyzeVirtualMethodCall(InstructionIterator Begin,
1368                                         InstructionIterator End,
1369                                         std::vector<MCInst *> &MethodFetchInsns,
1370                                         unsigned &VtableRegNum,
1371                                         unsigned &BaseRegNum,
1372                                         uint64_t &MethodOffset) const {
1373     llvm_unreachable("not implemented");
1374     return false;
1375   }
1376 
1377   virtual void createLongJmp(InstructionListType &Seq, const MCSymbol *Target,
1378                              MCContext *Ctx, bool IsTailCall = false) {
1379     llvm_unreachable("not implemented");
1380   }
1381 
1382   virtual void createShortJmp(InstructionListType &Seq, const MCSymbol *Target,
1383                               MCContext *Ctx, bool IsTailCall = false) {
1384     llvm_unreachable("not implemented");
1385   }
1386 
1387   /// Return not 0 if the instruction CurInst, in combination with the recent
1388   /// history of disassembled instructions supplied by [Begin, End), is a linker
1389   /// generated veneer/stub that needs patching. This happens in AArch64 when
1390   /// the code is large and the linker needs to generate stubs, but it does
1391   /// not put any extra relocation information that could help us to easily
1392   /// extract the real target. This function identifies and extract the real
1393   /// target in Tgt. The instruction that loads the lower bits of the target
1394   /// is put in TgtLowBits, and its pair in TgtHiBits. If the instruction in
1395   /// TgtHiBits does not have an immediate operand, but an expression, then
1396   /// this expression is put in TgtHiSym and Tgt only contains the lower bits.
1397   /// Return value is a total number of instructions that were used to create
1398   /// a veneer.
matchLinkerVeneer(InstructionIterator Begin,InstructionIterator End,uint64_t Address,const MCInst & CurInst,MCInst * & TargetHiBits,MCInst * & TargetLowBits,uint64_t & Target)1399   virtual uint64_t matchLinkerVeneer(InstructionIterator Begin,
1400                                      InstructionIterator End, uint64_t Address,
1401                                      const MCInst &CurInst,
1402                                      MCInst *&TargetHiBits,
1403                                      MCInst *&TargetLowBits,
1404                                      uint64_t &Target) const {
1405     llvm_unreachable("not implemented");
1406   }
1407 
getShortJmpEncodingSize()1408   virtual int getShortJmpEncodingSize() const {
1409     llvm_unreachable("not implemented");
1410   }
1411 
getUncondBranchEncodingSize()1412   virtual int getUncondBranchEncodingSize() const {
1413     llvm_unreachable("not implemented");
1414     return 0;
1415   }
1416 
1417   /// Create a no-op instruction.
createNoop(MCInst & Inst)1418   virtual bool createNoop(MCInst &Inst) const {
1419     llvm_unreachable("not implemented");
1420     return false;
1421   }
1422 
1423   /// Create a return instruction.
createReturn(MCInst & Inst)1424   virtual bool createReturn(MCInst &Inst) const {
1425     llvm_unreachable("not implemented");
1426     return false;
1427   }
1428 
1429   /// Store \p Target absolute adddress to \p RegName
1430   virtual InstructionListType materializeAddress(const MCSymbol *Target,
1431                                                  MCContext *Ctx,
1432                                                  MCPhysReg RegName,
1433                                                  int64_t Addend = 0) const {
1434     llvm_unreachable("not implemented");
1435     return {};
1436   }
1437 
1438   /// Creates a new unconditional branch instruction in Inst and set its operand
1439   /// to TBB.
1440   ///
1441   /// Returns true on success.
createUncondBranch(MCInst & Inst,const MCSymbol * TBB,MCContext * Ctx)1442   virtual bool createUncondBranch(MCInst &Inst, const MCSymbol *TBB,
1443                                   MCContext *Ctx) const {
1444     llvm_unreachable("not implemented");
1445     return false;
1446   }
1447 
1448   /// Creates a new call instruction in Inst and sets its operand to
1449   /// Target.
1450   ///
1451   /// Returns true on success.
createCall(MCInst & Inst,const MCSymbol * Target,MCContext * Ctx)1452   virtual bool createCall(MCInst &Inst, const MCSymbol *Target,
1453                           MCContext *Ctx) {
1454     llvm_unreachable("not implemented");
1455     return false;
1456   }
1457 
1458   /// Creates a new tail call instruction in Inst and sets its operand to
1459   /// Target.
1460   ///
1461   /// Returns true on success.
createTailCall(MCInst & Inst,const MCSymbol * Target,MCContext * Ctx)1462   virtual bool createTailCall(MCInst &Inst, const MCSymbol *Target,
1463                               MCContext *Ctx) {
1464     llvm_unreachable("not implemented");
1465     return false;
1466   }
1467 
createLongTailCall(InstructionListType & Seq,const MCSymbol * Target,MCContext * Ctx)1468   virtual void createLongTailCall(InstructionListType &Seq,
1469                                   const MCSymbol *Target, MCContext *Ctx) {
1470     llvm_unreachable("not implemented");
1471   }
1472 
1473   /// Creates a trap instruction in Inst.
1474   ///
1475   /// Returns true on success.
createTrap(MCInst & Inst)1476   virtual bool createTrap(MCInst &Inst) const {
1477     llvm_unreachable("not implemented");
1478     return false;
1479   }
1480 
1481   /// Creates an instruction to bump the stack pointer just like a call.
1482   virtual bool createStackPointerIncrement(MCInst &Inst, int Size = 8,
1483                                            bool NoFlagsClobber = false) const {
1484     llvm_unreachable("not implemented");
1485     return false;
1486   }
1487 
1488   /// Creates an instruction to move the stack pointer just like a ret.
1489   virtual bool createStackPointerDecrement(MCInst &Inst, int Size = 8,
1490                                            bool NoFlagsClobber = false) const {
1491     llvm_unreachable("not implemented");
1492     return false;
1493   }
1494 
1495   /// Create a store instruction using \p StackReg as the base register
1496   /// and \p Offset as the displacement.
createSaveToStack(MCInst & Inst,const MCPhysReg & StackReg,int Offset,const MCPhysReg & SrcReg,int Size)1497   virtual bool createSaveToStack(MCInst &Inst, const MCPhysReg &StackReg,
1498                                  int Offset, const MCPhysReg &SrcReg,
1499                                  int Size) const {
1500     llvm_unreachable("not implemented");
1501     return false;
1502   }
1503 
createLoad(MCInst & Inst,const MCPhysReg & BaseReg,int64_t Scale,const MCPhysReg & IndexReg,int64_t Offset,const MCExpr * OffsetExpr,const MCPhysReg & AddrSegmentReg,const MCPhysReg & DstReg,int Size)1504   virtual bool createLoad(MCInst &Inst, const MCPhysReg &BaseReg, int64_t Scale,
1505                           const MCPhysReg &IndexReg, int64_t Offset,
1506                           const MCExpr *OffsetExpr,
1507                           const MCPhysReg &AddrSegmentReg,
1508                           const MCPhysReg &DstReg, int Size) const {
1509     llvm_unreachable("not implemented");
1510     return false;
1511   }
1512 
createLoadImmediate(MCInst & Inst,const MCPhysReg Dest,uint32_t Imm)1513   virtual void createLoadImmediate(MCInst &Inst, const MCPhysReg Dest,
1514                                    uint32_t Imm) const {
1515     llvm_unreachable("not implemented");
1516   }
1517 
1518   /// Create instruction to increment contents of target by 1
createIncMemory(MCInst & Inst,const MCSymbol * Target,MCContext * Ctx)1519   virtual bool createIncMemory(MCInst &Inst, const MCSymbol *Target,
1520                                MCContext *Ctx) const {
1521     llvm_unreachable("not implemented");
1522     return false;
1523   }
1524 
1525   /// Create a fragment of code (sequence of instructions) that load a 32-bit
1526   /// address from memory, zero-extends it to 64 and jump to it (indirect jump).
1527   virtual bool
createIJmp32Frag(SmallVectorImpl<MCInst> & Insts,const MCOperand & BaseReg,const MCOperand & Scale,const MCOperand & IndexReg,const MCOperand & Offset,const MCOperand & TmpReg)1528   createIJmp32Frag(SmallVectorImpl<MCInst> &Insts, const MCOperand &BaseReg,
1529                    const MCOperand &Scale, const MCOperand &IndexReg,
1530                    const MCOperand &Offset, const MCOperand &TmpReg) const {
1531     llvm_unreachable("not implemented");
1532     return false;
1533   }
1534 
1535   /// Create a load instruction using \p StackReg as the base register
1536   /// and \p Offset as the displacement.
createRestoreFromStack(MCInst & Inst,const MCPhysReg & StackReg,int Offset,const MCPhysReg & DstReg,int Size)1537   virtual bool createRestoreFromStack(MCInst &Inst, const MCPhysReg &StackReg,
1538                                       int Offset, const MCPhysReg &DstReg,
1539                                       int Size) const {
1540     llvm_unreachable("not implemented");
1541     return false;
1542   }
1543 
1544   /// Creates a call frame pseudo instruction. A single operand identifies which
1545   /// MCCFIInstruction this MCInst is referring to.
1546   ///
1547   /// Returns true on success.
createCFI(MCInst & Inst,int64_t Offset)1548   virtual bool createCFI(MCInst &Inst, int64_t Offset) const {
1549     Inst.clear();
1550     Inst.setOpcode(TargetOpcode::CFI_INSTRUCTION);
1551     Inst.addOperand(MCOperand::createImm(Offset));
1552     return true;
1553   }
1554 
1555   /// Create an inline version of memcpy(dest, src, 1).
createOneByteMemcpy()1556   virtual InstructionListType createOneByteMemcpy() const {
1557     llvm_unreachable("not implemented");
1558     return {};
1559   }
1560 
1561   /// Create a sequence of instructions to compare contents of a register
1562   /// \p RegNo to immediate \Imm and jump to \p Target if they are equal.
createCmpJE(MCPhysReg RegNo,int64_t Imm,const MCSymbol * Target,MCContext * Ctx)1563   virtual InstructionListType createCmpJE(MCPhysReg RegNo, int64_t Imm,
1564                                           const MCSymbol *Target,
1565                                           MCContext *Ctx) const {
1566     llvm_unreachable("not implemented");
1567     return {};
1568   }
1569 
1570   /// Creates inline memcpy instruction. If \p ReturnEnd is true, then return
1571   /// (dest + n) instead of dest.
createInlineMemcpy(bool ReturnEnd)1572   virtual InstructionListType createInlineMemcpy(bool ReturnEnd) const {
1573     llvm_unreachable("not implemented");
1574     return {};
1575   }
1576 
1577   /// Create a target-specific relocation out of the \p Fixup.
1578   /// Note that not every fixup could be converted into a relocation.
createRelocation(const MCFixup & Fixup,const MCAsmBackend & MAB)1579   virtual Optional<Relocation> createRelocation(const MCFixup &Fixup,
1580                                                 const MCAsmBackend &MAB) const {
1581     llvm_unreachable("not implemented");
1582     return Relocation();
1583   }
1584 
1585   /// Returns true if instruction is a call frame pseudo instruction.
isCFI(const MCInst & Inst)1586   virtual bool isCFI(const MCInst &Inst) const {
1587     return Inst.getOpcode() == TargetOpcode::CFI_INSTRUCTION;
1588   }
1589 
1590   /// Reverses the branch condition in Inst and update its taken target to TBB.
1591   ///
1592   /// Returns true on success.
reverseBranchCondition(MCInst & Inst,const MCSymbol * TBB,MCContext * Ctx)1593   virtual bool reverseBranchCondition(MCInst &Inst, const MCSymbol *TBB,
1594                                       MCContext *Ctx) const {
1595     llvm_unreachable("not implemented");
1596     return false;
1597   }
1598 
replaceBranchCondition(MCInst & Inst,const MCSymbol * TBB,MCContext * Ctx,unsigned CC)1599   virtual bool replaceBranchCondition(MCInst &Inst, const MCSymbol *TBB,
1600                                       MCContext *Ctx, unsigned CC) const {
1601     llvm_unreachable("not implemented");
1602     return false;
1603   }
1604 
getInvertedCondCode(unsigned CC)1605   virtual unsigned getInvertedCondCode(unsigned CC) const {
1606     llvm_unreachable("not implemented");
1607     return false;
1608   }
1609 
getCondCodesLogicalOr(unsigned CC1,unsigned CC2)1610   virtual unsigned getCondCodesLogicalOr(unsigned CC1, unsigned CC2) const {
1611     llvm_unreachable("not implemented");
1612     return false;
1613   }
1614 
isValidCondCode(unsigned CC)1615   virtual bool isValidCondCode(unsigned CC) const {
1616     llvm_unreachable("not implemented");
1617     return false;
1618   }
1619 
1620   /// Return the conditional code used in a conditional jump instruction.
1621   /// Returns invalid code if not conditional jump.
getCondCode(const MCInst & Inst)1622   virtual unsigned getCondCode(const MCInst &Inst) const {
1623     llvm_unreachable("not implemented");
1624     return false;
1625   }
1626 
1627   /// Return canonical branch opcode for a reversible branch opcode. For every
1628   /// opposite branch opcode pair Op <-> OpR this function returns one of the
1629   /// opcodes which is considered a canonical.
getCanonicalBranchCondCode(unsigned CC)1630   virtual unsigned getCanonicalBranchCondCode(unsigned CC) const {
1631     llvm_unreachable("not implemented");
1632     return false;
1633   }
1634 
1635   /// Sets the taken target of the branch instruction to Target.
1636   ///
1637   /// Returns true on success.
replaceBranchTarget(MCInst & Inst,const MCSymbol * TBB,MCContext * Ctx)1638   virtual bool replaceBranchTarget(MCInst &Inst, const MCSymbol *TBB,
1639                                    MCContext *Ctx) const {
1640     llvm_unreachable("not implemented");
1641     return false;
1642   }
1643 
createEHLabel(MCInst & Inst,const MCSymbol * Label,MCContext * Ctx)1644   virtual bool createEHLabel(MCInst &Inst, const MCSymbol *Label,
1645                              MCContext *Ctx) const {
1646     Inst.setOpcode(TargetOpcode::EH_LABEL);
1647     Inst.clear();
1648     Inst.addOperand(MCOperand::createExpr(
1649         MCSymbolRefExpr::create(Label, MCSymbolRefExpr::VK_None, *Ctx)));
1650     return true;
1651   }
1652 
1653   /// Return annotation index matching the \p Name.
getAnnotationIndex(StringRef Name)1654   Optional<unsigned> getAnnotationIndex(StringRef Name) const {
1655     auto AI = AnnotationNameIndexMap.find(Name);
1656     if (AI != AnnotationNameIndexMap.end())
1657       return AI->second;
1658     return NoneType();
1659   }
1660 
1661   /// Return annotation index matching the \p Name. Create a new index if the
1662   /// \p Name wasn't registered previously.
getOrCreateAnnotationIndex(StringRef Name)1663   unsigned getOrCreateAnnotationIndex(StringRef Name) {
1664     auto AI = AnnotationNameIndexMap.find(Name);
1665     if (AI != AnnotationNameIndexMap.end())
1666       return AI->second;
1667 
1668     const unsigned Index =
1669         AnnotationNameIndexMap.size() + MCPlus::MCAnnotation::kGeneric;
1670     AnnotationNameIndexMap.insert(std::make_pair(Name, Index));
1671     AnnotationNames.emplace_back(std::string(Name));
1672     return Index;
1673   }
1674 
1675   /// Store an annotation value on an MCInst.  This assumes the annotation
1676   /// is not already present.
1677   template <typename ValueType>
1678   const ValueType &addAnnotation(MCInst &Inst, unsigned Index,
1679                                  const ValueType &Val,
1680                                  AllocatorIdTy AllocatorId = 0) {
1681     assert(!hasAnnotation(Inst, Index));
1682     AnnotationAllocator &Allocator = getAnnotationAllocator(AllocatorId);
1683     auto *A = new (Allocator.ValueAllocator)
1684         MCPlus::MCSimpleAnnotation<ValueType>(Val);
1685 
1686     if (!std::is_trivial<ValueType>::value)
1687       Allocator.AnnotationPool.insert(A);
1688     setAnnotationOpValue(Inst, Index, reinterpret_cast<int64_t>(A),
1689                          AllocatorId);
1690     return A->getValue();
1691   }
1692 
1693   /// Store an annotation value on an MCInst.  This assumes the annotation
1694   /// is not already present.
1695   template <typename ValueType>
1696   const ValueType &addAnnotation(MCInst &Inst, StringRef Name,
1697                                  const ValueType &Val,
1698                                  AllocatorIdTy AllocatorId = 0) {
1699     return addAnnotation(Inst, getOrCreateAnnotationIndex(Name), Val,
1700                          AllocatorId);
1701   }
1702 
1703   /// Get an annotation as a specific value, but if the annotation does not
1704   /// exist, create a new annotation with the default constructor for that type.
1705   /// Return a non-const ref so caller can freely modify its contents
1706   /// afterwards.
1707   template <typename ValueType>
1708   ValueType &getOrCreateAnnotationAs(MCInst &Inst, unsigned Index,
1709                                      AllocatorIdTy AllocatorId = 0) {
1710     auto Val =
1711         tryGetAnnotationAs<ValueType>(const_cast<const MCInst &>(Inst), Index);
1712     if (!Val)
1713       Val = addAnnotation(Inst, Index, ValueType(), AllocatorId);
1714     return const_cast<ValueType &>(*Val);
1715   }
1716 
1717   /// Get an annotation as a specific value, but if the annotation does not
1718   /// exist, create a new annotation with the default constructor for that type.
1719   /// Return a non-const ref so caller can freely modify its contents
1720   /// afterwards.
1721   template <typename ValueType>
1722   ValueType &getOrCreateAnnotationAs(MCInst &Inst, StringRef Name,
1723                                      AllocatorIdTy AllocatorId = 0) {
1724     const unsigned Index = getOrCreateAnnotationIndex(Name);
1725     return getOrCreateAnnotationAs<ValueType>(Inst, Index, AllocatorId);
1726   }
1727 
1728   /// Get an annotation as a specific value. Assumes that the annotation exists.
1729   /// Use hasAnnotation() if the annotation may not exist.
1730   template <typename ValueType>
getAnnotationAs(const MCInst & Inst,unsigned Index)1731   ValueType &getAnnotationAs(const MCInst &Inst, unsigned Index) const {
1732     Optional<int64_t> Value = getAnnotationOpValue(Inst, Index);
1733     assert(Value && "annotation should exist");
1734     return reinterpret_cast<MCPlus::MCSimpleAnnotation<ValueType> *>(*Value)
1735         ->getValue();
1736   }
1737 
1738   /// Get an annotation as a specific value. Assumes that the annotation exists.
1739   /// Use hasAnnotation() if the annotation may not exist.
1740   template <typename ValueType>
getAnnotationAs(const MCInst & Inst,StringRef Name)1741   ValueType &getAnnotationAs(const MCInst &Inst, StringRef Name) const {
1742     const auto Index = getAnnotationIndex(Name);
1743     assert(Index && "annotation should exist");
1744     return getAnnotationAs<ValueType>(Inst, *Index);
1745   }
1746 
1747   /// Get an annotation as a specific value. If the annotation does not exist,
1748   /// return the \p DefaultValue.
1749   template <typename ValueType>
1750   const ValueType &
1751   getAnnotationWithDefault(const MCInst &Inst, unsigned Index,
1752                            const ValueType &DefaultValue = ValueType()) {
1753     if (!hasAnnotation(Inst, Index))
1754       return DefaultValue;
1755     return getAnnotationAs<ValueType>(Inst, Index);
1756   }
1757 
1758   /// Get an annotation as a specific value. If the annotation does not exist,
1759   /// return the \p DefaultValue.
1760   template <typename ValueType>
1761   const ValueType &
1762   getAnnotationWithDefault(const MCInst &Inst, StringRef Name,
1763                            const ValueType &DefaultValue = ValueType()) {
1764     const unsigned Index = getOrCreateAnnotationIndex(Name);
1765     return getAnnotationWithDefault<ValueType>(Inst, Index, DefaultValue);
1766   }
1767 
1768   /// Check if the specified annotation exists on this instruction.
1769   bool hasAnnotation(const MCInst &Inst, unsigned Index) const;
1770 
1771   /// Check if an annotation with a specified \p Name exists on \p Inst.
hasAnnotation(const MCInst & Inst,StringRef Name)1772   bool hasAnnotation(const MCInst &Inst, StringRef Name) const {
1773     const auto Index = getAnnotationIndex(Name);
1774     if (!Index)
1775       return false;
1776     return hasAnnotation(Inst, *Index);
1777   }
1778 
1779   /// Get an annotation as a specific value, but if the annotation does not
1780   /// exist, return errc::result_out_of_range.
1781   template <typename ValueType>
tryGetAnnotationAs(const MCInst & Inst,unsigned Index)1782   ErrorOr<const ValueType &> tryGetAnnotationAs(const MCInst &Inst,
1783                                                 unsigned Index) const {
1784     if (!hasAnnotation(Inst, Index))
1785       return make_error_code(std::errc::result_out_of_range);
1786     return getAnnotationAs<ValueType>(Inst, Index);
1787   }
1788 
1789   /// Get an annotation as a specific value, but if the annotation does not
1790   /// exist, return errc::result_out_of_range.
1791   template <typename ValueType>
tryGetAnnotationAs(const MCInst & Inst,StringRef Name)1792   ErrorOr<const ValueType &> tryGetAnnotationAs(const MCInst &Inst,
1793                                                 StringRef Name) const {
1794     const auto Index = getAnnotationIndex(Name);
1795     if (!Index)
1796       return make_error_code(std::errc::result_out_of_range);
1797     return tryGetAnnotationAs<ValueType>(Inst, *Index);
1798   }
1799 
1800   template <typename ValueType>
tryGetAnnotationAs(MCInst & Inst,unsigned Index)1801   ErrorOr<ValueType &> tryGetAnnotationAs(MCInst &Inst, unsigned Index) const {
1802     if (!hasAnnotation(Inst, Index))
1803       return make_error_code(std::errc::result_out_of_range);
1804     return const_cast<ValueType &>(getAnnotationAs<ValueType>(Inst, Index));
1805   }
1806 
1807   template <typename ValueType>
tryGetAnnotationAs(MCInst & Inst,StringRef Name)1808   ErrorOr<ValueType &> tryGetAnnotationAs(MCInst &Inst, StringRef Name) const {
1809     const auto Index = getAnnotationIndex(Name);
1810     if (!Index)
1811       return make_error_code(std::errc::result_out_of_range);
1812     return tryGetAnnotationAs<ValueType>(Inst, *Index);
1813   }
1814 
1815   /// Print each annotation attached to \p Inst.
1816   void printAnnotations(const MCInst &Inst, raw_ostream &OS) const;
1817 
1818   /// Remove annotation with a given \p Index.
1819   ///
1820   /// Return true if the annotation was removed, false if the annotation
1821   /// was not present.
1822   bool removeAnnotation(MCInst &Inst, unsigned Index);
1823 
1824   /// Remove annotation associated with \p Name.
1825   ///
1826   /// Return true if the annotation was removed, false if the annotation
1827   /// was not present.
removeAnnotation(MCInst & Inst,StringRef Name)1828   bool removeAnnotation(MCInst &Inst, StringRef Name) {
1829     const auto Index = getAnnotationIndex(Name);
1830     if (!Index)
1831       return false;
1832     return removeAnnotation(Inst, *Index);
1833   }
1834 
1835   /// Remove meta-data, but don't destroy it.
1836   void stripAnnotations(MCInst &Inst, bool KeepTC = false);
1837 
1838   virtual InstructionListType
createInstrumentedIndirectCall(const MCInst & CallInst,bool TailCall,MCSymbol * HandlerFuncAddr,int CallSiteID,MCContext * Ctx)1839   createInstrumentedIndirectCall(const MCInst &CallInst, bool TailCall,
1840                                  MCSymbol *HandlerFuncAddr, int CallSiteID,
1841                                  MCContext *Ctx) {
1842     llvm_unreachable("not implemented");
1843     return InstructionListType();
1844   }
1845 
createInstrumentedIndCallHandlerExitBB()1846   virtual InstructionListType createInstrumentedIndCallHandlerExitBB() const {
1847     llvm_unreachable("not implemented");
1848     return InstructionListType();
1849   }
1850 
1851   virtual InstructionListType
createInstrumentedIndTailCallHandlerExitBB()1852   createInstrumentedIndTailCallHandlerExitBB() const {
1853     llvm_unreachable("not implemented");
1854     return InstructionListType();
1855   }
1856 
1857   virtual InstructionListType
createInstrumentedIndCallHandlerEntryBB(const MCSymbol * InstrTrampoline,const MCSymbol * IndCallHandler,MCContext * Ctx)1858   createInstrumentedIndCallHandlerEntryBB(const MCSymbol *InstrTrampoline,
1859                                           const MCSymbol *IndCallHandler,
1860                                           MCContext *Ctx) {
1861     llvm_unreachable("not implemented");
1862     return InstructionListType();
1863   }
1864 
createNumCountersGetter(MCContext * Ctx)1865   virtual InstructionListType createNumCountersGetter(MCContext *Ctx) const {
1866     llvm_unreachable("not implemented");
1867     return {};
1868   }
1869 
createInstrLocationsGetter(MCContext * Ctx)1870   virtual InstructionListType createInstrLocationsGetter(MCContext *Ctx) const {
1871     llvm_unreachable("not implemented");
1872     return {};
1873   }
1874 
createInstrTablesGetter(MCContext * Ctx)1875   virtual InstructionListType createInstrTablesGetter(MCContext *Ctx) const {
1876     llvm_unreachable("not implemented");
1877     return {};
1878   }
1879 
createInstrNumFuncsGetter(MCContext * Ctx)1880   virtual InstructionListType createInstrNumFuncsGetter(MCContext *Ctx) const {
1881     llvm_unreachable("not implemented");
1882     return {};
1883   }
1884 
createSymbolTrampoline(const MCSymbol * TgtSym,MCContext * Ctx)1885   virtual InstructionListType createSymbolTrampoline(const MCSymbol *TgtSym,
1886                                                      MCContext *Ctx) const {
1887     llvm_unreachable("not implemented");
1888     return InstructionListType();
1889   }
1890 
createDummyReturnFunction(MCContext * Ctx)1891   virtual InstructionListType createDummyReturnFunction(MCContext *Ctx) const {
1892     llvm_unreachable("not implemented");
1893     return InstructionListType();
1894   }
1895 
1896   /// This method takes an indirect call instruction and splits it up into an
1897   /// equivalent set of instructions that use direct calls for target
1898   /// symbols/addresses that are contained in the Targets vector.  This is done
1899   /// by guarding each direct call with a compare instruction to verify that
1900   /// the target is correct.
1901   /// If the VtableAddrs vector is not empty, the call will have the extra
1902   /// load of the method pointer from the vtable eliminated.  When non-empty
1903   /// the VtableAddrs vector must be the same size as Targets and include the
1904   /// address of a vtable for each corresponding method call in Targets.  The
1905   /// MethodFetchInsns vector holds instructions that are used to load the
1906   /// correct method for the cold call case.
1907   ///
1908   /// The return value is a vector of code snippets (essentially basic blocks).
1909   /// There is a symbol associated with each snippet except for the first.
1910   /// If the original call is not a tail call, the last snippet will have an
1911   /// empty vector of instructions.  The label is meant to indicate the basic
1912   /// block where all previous snippets are joined, i.e. the instructions that
1913   /// would immediate follow the original call.
1914   using BlocksVectorTy =
1915       std::vector<std::pair<MCSymbol *, InstructionListType>>;
1916   struct MultiBlocksCode {
1917     BlocksVectorTy Blocks;
1918     std::vector<MCSymbol *> Successors;
1919   };
1920 
indirectCallPromotion(const MCInst & CallInst,const std::vector<std::pair<MCSymbol *,uint64_t>> & Targets,const std::vector<std::pair<MCSymbol *,uint64_t>> & VtableSyms,const std::vector<MCInst * > & MethodFetchInsns,const bool MinimizeCodeSize,MCContext * Ctx)1921   virtual BlocksVectorTy indirectCallPromotion(
1922       const MCInst &CallInst,
1923       const std::vector<std::pair<MCSymbol *, uint64_t>> &Targets,
1924       const std::vector<std::pair<MCSymbol *, uint64_t>> &VtableSyms,
1925       const std::vector<MCInst *> &MethodFetchInsns,
1926       const bool MinimizeCodeSize, MCContext *Ctx) {
1927     llvm_unreachable("not implemented");
1928     return BlocksVectorTy();
1929   }
1930 
jumpTablePromotion(const MCInst & IJmpInst,const std::vector<std::pair<MCSymbol *,uint64_t>> & Targets,const std::vector<MCInst * > & TargetFetchInsns,MCContext * Ctx)1931   virtual BlocksVectorTy jumpTablePromotion(
1932       const MCInst &IJmpInst,
1933       const std::vector<std::pair<MCSymbol *, uint64_t>> &Targets,
1934       const std::vector<MCInst *> &TargetFetchInsns, MCContext *Ctx) const {
1935     llvm_unreachable("not implemented");
1936     return BlocksVectorTy();
1937   }
1938 
1939   // AliasMap caches a mapping of registers to the set of registers that
1940   // alias (are sub or superregs of itself, including itself).
1941   std::vector<BitVector> AliasMap;
1942   std::vector<BitVector> SmallerAliasMap;
1943 };
1944 
1945 MCPlusBuilder *createX86MCPlusBuilder(const MCInstrAnalysis *,
1946                                       const MCInstrInfo *,
1947                                       const MCRegisterInfo *);
1948 
1949 MCPlusBuilder *createAArch64MCPlusBuilder(const MCInstrAnalysis *,
1950                                           const MCInstrInfo *,
1951                                           const MCRegisterInfo *);
1952 
1953 } // namespace bolt
1954 } // namespace llvm
1955 
1956 #endif
1957