1 //===- bolt/Target/AArch64/AArch64MCPlusBuilder.cpp -----------------------===//
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 provides AArch64-specific MCPlus builder.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "MCTargetDesc/AArch64AddressingModes.h"
14 #include "MCTargetDesc/AArch64MCExpr.h"
15 #include "MCTargetDesc/AArch64MCTargetDesc.h"
16 #include "Utils/AArch64BaseInfo.h"
17 #include "bolt/Core/MCPlusBuilder.h"
18 #include "llvm/BinaryFormat/ELF.h"
19 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/MC/MCRegisterInfo.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Support/ErrorHandling.h"
23 
24 #define DEBUG_TYPE "mcplus"
25 
26 using namespace llvm;
27 using namespace bolt;
28 
29 namespace {
30 
31 class AArch64MCPlusBuilder : public MCPlusBuilder {
32 public:
33   AArch64MCPlusBuilder(const MCInstrAnalysis *Analysis, const MCInstrInfo *Info,
34                        const MCRegisterInfo *RegInfo)
35       : MCPlusBuilder(Analysis, Info, RegInfo) {}
36 
37   bool equals(const MCTargetExpr &A, const MCTargetExpr &B,
38               CompFuncTy Comp) const override {
39     const auto &AArch64ExprA = cast<AArch64MCExpr>(A);
40     const auto &AArch64ExprB = cast<AArch64MCExpr>(B);
41     if (AArch64ExprA.getKind() != AArch64ExprB.getKind())
42       return false;
43 
44     return MCPlusBuilder::equals(*AArch64ExprA.getSubExpr(),
45                                  *AArch64ExprB.getSubExpr(), Comp);
46   }
47 
48   bool hasEVEXEncoding(const MCInst &) const override { return false; }
49 
50   bool isMacroOpFusionPair(ArrayRef<MCInst> Insts) const override {
51     return false;
52   }
53 
54   bool shortenInstruction(MCInst &, const MCSubtargetInfo &) const override {
55     return false;
56   }
57 
58   bool isADRP(const MCInst &Inst) const override {
59     return Inst.getOpcode() == AArch64::ADRP;
60   }
61 
62   bool isADR(const MCInst &Inst) const override {
63     return Inst.getOpcode() == AArch64::ADR;
64   }
65 
66   void getADRReg(const MCInst &Inst, MCPhysReg &RegName) const override {
67     assert((isADR(Inst) || isADRP(Inst)) && "Not an ADR instruction");
68     assert(MCPlus::getNumPrimeOperands(Inst) != 0 &&
69            "No operands for ADR instruction");
70     assert(Inst.getOperand(0).isReg() &&
71            "Unexpected operand in ADR instruction");
72     RegName = Inst.getOperand(0).getReg();
73   }
74 
75   bool isTB(const MCInst &Inst) const {
76     return (Inst.getOpcode() == AArch64::TBNZW ||
77             Inst.getOpcode() == AArch64::TBNZX ||
78             Inst.getOpcode() == AArch64::TBZW ||
79             Inst.getOpcode() == AArch64::TBZX);
80   }
81 
82   bool isCB(const MCInst &Inst) const {
83     return (Inst.getOpcode() == AArch64::CBNZW ||
84             Inst.getOpcode() == AArch64::CBNZX ||
85             Inst.getOpcode() == AArch64::CBZW ||
86             Inst.getOpcode() == AArch64::CBZX);
87   }
88 
89   bool isMOVW(const MCInst &Inst) const {
90     return (Inst.getOpcode() == AArch64::MOVKWi ||
91             Inst.getOpcode() == AArch64::MOVKXi ||
92             Inst.getOpcode() == AArch64::MOVNWi ||
93             Inst.getOpcode() == AArch64::MOVNXi ||
94             Inst.getOpcode() == AArch64::MOVZXi ||
95             Inst.getOpcode() == AArch64::MOVZWi);
96   }
97 
98   bool isADD(const MCInst &Inst) const {
99     return (Inst.getOpcode() == AArch64::ADDSWri ||
100             Inst.getOpcode() == AArch64::ADDSWrr ||
101             Inst.getOpcode() == AArch64::ADDSWrs ||
102             Inst.getOpcode() == AArch64::ADDSWrx ||
103             Inst.getOpcode() == AArch64::ADDSXri ||
104             Inst.getOpcode() == AArch64::ADDSXrr ||
105             Inst.getOpcode() == AArch64::ADDSXrs ||
106             Inst.getOpcode() == AArch64::ADDSXrx ||
107             Inst.getOpcode() == AArch64::ADDSXrx64 ||
108             Inst.getOpcode() == AArch64::ADDWri ||
109             Inst.getOpcode() == AArch64::ADDWrr ||
110             Inst.getOpcode() == AArch64::ADDWrs ||
111             Inst.getOpcode() == AArch64::ADDWrx ||
112             Inst.getOpcode() == AArch64::ADDXri ||
113             Inst.getOpcode() == AArch64::ADDXrr ||
114             Inst.getOpcode() == AArch64::ADDXrs ||
115             Inst.getOpcode() == AArch64::ADDXrx ||
116             Inst.getOpcode() == AArch64::ADDXrx64);
117   }
118 
119   bool isLDRB(const MCInst &Inst) const {
120     return (Inst.getOpcode() == AArch64::LDRBBpost ||
121             Inst.getOpcode() == AArch64::LDRBBpre ||
122             Inst.getOpcode() == AArch64::LDRBBroW ||
123             Inst.getOpcode() == AArch64::LDRBBroX ||
124             Inst.getOpcode() == AArch64::LDRBBui ||
125             Inst.getOpcode() == AArch64::LDRSBWpost ||
126             Inst.getOpcode() == AArch64::LDRSBWpre ||
127             Inst.getOpcode() == AArch64::LDRSBWroW ||
128             Inst.getOpcode() == AArch64::LDRSBWroX ||
129             Inst.getOpcode() == AArch64::LDRSBWui ||
130             Inst.getOpcode() == AArch64::LDRSBXpost ||
131             Inst.getOpcode() == AArch64::LDRSBXpre ||
132             Inst.getOpcode() == AArch64::LDRSBXroW ||
133             Inst.getOpcode() == AArch64::LDRSBXroX ||
134             Inst.getOpcode() == AArch64::LDRSBXui);
135   }
136 
137   bool isLDRH(const MCInst &Inst) const {
138     return (Inst.getOpcode() == AArch64::LDRHHpost ||
139             Inst.getOpcode() == AArch64::LDRHHpre ||
140             Inst.getOpcode() == AArch64::LDRHHroW ||
141             Inst.getOpcode() == AArch64::LDRHHroX ||
142             Inst.getOpcode() == AArch64::LDRHHui ||
143             Inst.getOpcode() == AArch64::LDRSHWpost ||
144             Inst.getOpcode() == AArch64::LDRSHWpre ||
145             Inst.getOpcode() == AArch64::LDRSHWroW ||
146             Inst.getOpcode() == AArch64::LDRSHWroX ||
147             Inst.getOpcode() == AArch64::LDRSHWui ||
148             Inst.getOpcode() == AArch64::LDRSHXpost ||
149             Inst.getOpcode() == AArch64::LDRSHXpre ||
150             Inst.getOpcode() == AArch64::LDRSHXroW ||
151             Inst.getOpcode() == AArch64::LDRSHXroX ||
152             Inst.getOpcode() == AArch64::LDRSHXui);
153   }
154 
155   bool isLDRW(const MCInst &Inst) const {
156     return (Inst.getOpcode() == AArch64::LDRWpost ||
157             Inst.getOpcode() == AArch64::LDRWpre ||
158             Inst.getOpcode() == AArch64::LDRWroW ||
159             Inst.getOpcode() == AArch64::LDRWroX ||
160             Inst.getOpcode() == AArch64::LDRWui);
161   }
162 
163   bool isLDRX(const MCInst &Inst) const {
164     return (Inst.getOpcode() == AArch64::LDRXpost ||
165             Inst.getOpcode() == AArch64::LDRXpre ||
166             Inst.getOpcode() == AArch64::LDRXroW ||
167             Inst.getOpcode() == AArch64::LDRXroX ||
168             Inst.getOpcode() == AArch64::LDRXui);
169   }
170 
171   bool isLoad(const MCInst &Inst) const override {
172     return isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) || isLDRX(Inst);
173   }
174 
175   bool isLoadFromStack(const MCInst &Inst) const {
176     if (!isLoad(Inst))
177       return false;
178     const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
179     unsigned NumDefs = InstInfo.getNumDefs();
180     for (unsigned I = NumDefs, E = InstInfo.getNumOperands(); I < E; ++I) {
181       const MCOperand &Operand = Inst.getOperand(I);
182       if (!Operand.isReg())
183         continue;
184       unsigned Reg = Operand.getReg();
185       if (Reg == AArch64::SP || Reg == AArch64::WSP || Reg == AArch64::FP ||
186           Reg == AArch64::W29)
187         return true;
188     }
189     return false;
190   }
191 
192   bool isRegToRegMove(const MCInst &Inst, MCPhysReg &From,
193                       MCPhysReg &To) const override {
194     if (Inst.getOpcode() != AArch64::ORRXrs)
195       return false;
196     if (Inst.getOperand(1).getReg() != AArch64::XZR)
197       return false;
198     if (Inst.getOperand(3).getImm() != 0)
199       return false;
200     From = Inst.getOperand(2).getReg();
201     To = Inst.getOperand(0).getReg();
202     return true;
203   }
204 
205   bool isIndirectCall(const MCInst &Inst) const override {
206     return Inst.getOpcode() == AArch64::BLR;
207   }
208 
209   bool hasPCRelOperand(const MCInst &Inst) const override {
210     // ADRP is blacklisted and is an exception. Even though it has a
211     // PC-relative operand, this operand is not a complete symbol reference
212     // and BOLT shouldn't try to process it in isolation.
213     if (isADRP(Inst))
214       return false;
215 
216     if (isADR(Inst))
217       return true;
218 
219     // Look for literal addressing mode (see C1-143 ARM DDI 0487B.a)
220     const MCInstrDesc &MCII = Info->get(Inst.getOpcode());
221     for (unsigned I = 0, E = MCII.getNumOperands(); I != E; ++I)
222       if (MCII.OpInfo[I].OperandType == MCOI::OPERAND_PCREL)
223         return true;
224 
225     return false;
226   }
227 
228   bool evaluateADR(const MCInst &Inst, int64_t &Imm,
229                    const MCExpr **DispExpr) const {
230     assert((isADR(Inst) || isADRP(Inst)) && "Not an ADR instruction");
231 
232     const MCOperand &Label = Inst.getOperand(1);
233     if (!Label.isImm()) {
234       assert(Label.isExpr() && "Unexpected ADR operand");
235       assert(DispExpr && "DispExpr must be set");
236       *DispExpr = Label.getExpr();
237       return false;
238     }
239 
240     if (Inst.getOpcode() == AArch64::ADR) {
241       Imm = Label.getImm();
242       return true;
243     }
244     Imm = Label.getImm() << 12;
245     return true;
246   }
247 
248   bool evaluateAArch64MemoryOperand(const MCInst &Inst, int64_t &DispImm,
249                                     const MCExpr **DispExpr = nullptr) const {
250     if (isADR(Inst) || isADRP(Inst))
251       return evaluateADR(Inst, DispImm, DispExpr);
252 
253     // Literal addressing mode
254     const MCInstrDesc &MCII = Info->get(Inst.getOpcode());
255     for (unsigned I = 0, E = MCII.getNumOperands(); I != E; ++I) {
256       if (MCII.OpInfo[I].OperandType != MCOI::OPERAND_PCREL)
257         continue;
258 
259       if (!Inst.getOperand(I).isImm()) {
260         assert(Inst.getOperand(I).isExpr() && "Unexpected PCREL operand");
261         assert(DispExpr && "DispExpr must be set");
262         *DispExpr = Inst.getOperand(I).getExpr();
263         return true;
264       }
265 
266       DispImm = Inst.getOperand(I).getImm() << 2;
267       return true;
268     }
269     return false;
270   }
271 
272   bool evaluateMemOperandTarget(const MCInst &Inst, uint64_t &Target,
273                                 uint64_t Address,
274                                 uint64_t Size) const override {
275     int64_t DispValue;
276     const MCExpr *DispExpr = nullptr;
277     if (!evaluateAArch64MemoryOperand(Inst, DispValue, &DispExpr))
278       return false;
279 
280     // Make sure it's a well-formed addressing we can statically evaluate.
281     if (DispExpr)
282       return false;
283 
284     Target = DispValue;
285     if (Inst.getOpcode() == AArch64::ADRP)
286       Target += Address & ~0xFFFULL;
287     else
288       Target += Address;
289     return true;
290   }
291 
292   bool replaceMemOperandDisp(MCInst &Inst, MCOperand Operand) const override {
293     MCInst::iterator OI = Inst.begin();
294     if (isADR(Inst) || isADRP(Inst)) {
295       assert(MCPlus::getNumPrimeOperands(Inst) >= 2 &&
296              "Unexpected number of operands");
297       ++OI;
298     } else {
299       const MCInstrDesc &MCII = Info->get(Inst.getOpcode());
300       for (unsigned I = 0, E = MCII.getNumOperands(); I != E; ++I) {
301         if (MCII.OpInfo[I].OperandType == MCOI::OPERAND_PCREL)
302           break;
303         ++OI;
304       }
305       assert(OI != Inst.end() && "Literal operand not found");
306     }
307     *OI = Operand;
308     return true;
309   }
310 
311   const MCExpr *getTargetExprFor(MCInst &Inst, const MCExpr *Expr,
312                                  MCContext &Ctx,
313                                  uint64_t RelType) const override {
314 
315     if (isADR(Inst) || RelType == ELF::R_AARCH64_ADR_PREL_LO21 ||
316         RelType == ELF::R_AARCH64_TLSDESC_ADR_PREL21) {
317       return AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS, Ctx);
318     } else if (isADRP(Inst) || RelType == ELF::R_AARCH64_ADR_PREL_PG_HI21 ||
319                RelType == ELF::R_AARCH64_ADR_PREL_PG_HI21_NC ||
320                RelType == ELF::R_AARCH64_TLSDESC_ADR_PAGE21 ||
321                RelType == ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 ||
322                RelType == ELF::R_AARCH64_ADR_GOT_PAGE) {
323       // Never emit a GOT reloc, we handled this in
324       // RewriteInstance::readRelocations().
325       return AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_PAGE, Ctx);
326     } else {
327       switch (RelType) {
328       case ELF::R_AARCH64_ADD_ABS_LO12_NC:
329       case ELF::R_AARCH64_LD64_GOT_LO12_NC:
330       case ELF::R_AARCH64_LDST8_ABS_LO12_NC:
331       case ELF::R_AARCH64_LDST16_ABS_LO12_NC:
332       case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
333       case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
334       case ELF::R_AARCH64_LDST128_ABS_LO12_NC:
335       case ELF::R_AARCH64_TLSDESC_ADD_LO12:
336       case ELF::R_AARCH64_TLSDESC_LD64_LO12:
337       case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
338       case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
339         return AArch64MCExpr::create(Expr, AArch64MCExpr::VK_LO12, Ctx);
340       case ELF::R_AARCH64_MOVW_UABS_G3:
341         return AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_G3, Ctx);
342       case ELF::R_AARCH64_MOVW_UABS_G2:
343       case ELF::R_AARCH64_MOVW_UABS_G2_NC:
344         return AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_G2_NC, Ctx);
345       case ELF::R_AARCH64_MOVW_UABS_G1:
346       case ELF::R_AARCH64_MOVW_UABS_G1_NC:
347         return AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_G1_NC, Ctx);
348       case ELF::R_AARCH64_MOVW_UABS_G0:
349       case ELF::R_AARCH64_MOVW_UABS_G0_NC:
350         return AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_G0_NC, Ctx);
351       default:
352         break;
353       }
354     }
355     return Expr;
356   }
357 
358   bool getSymbolRefOperandNum(const MCInst &Inst, unsigned &OpNum) const {
359     if (OpNum >= MCPlus::getNumPrimeOperands(Inst))
360       return false;
361 
362     // Auto-select correct operand number
363     if (OpNum == 0) {
364       if (isConditionalBranch(Inst) || isADR(Inst) || isADRP(Inst))
365         OpNum = 1;
366       if (isTB(Inst))
367         OpNum = 2;
368       if (isMOVW(Inst))
369         OpNum = 1;
370     }
371 
372     return true;
373   }
374 
375   const MCSymbol *getTargetSymbol(const MCExpr *Expr) const override {
376     auto *AArchExpr = dyn_cast<AArch64MCExpr>(Expr);
377     if (AArchExpr && AArchExpr->getSubExpr())
378       return getTargetSymbol(AArchExpr->getSubExpr());
379 
380     auto *BinExpr = dyn_cast<MCBinaryExpr>(Expr);
381     if (BinExpr)
382       return getTargetSymbol(BinExpr->getLHS());
383 
384     auto *SymExpr = dyn_cast<MCSymbolRefExpr>(Expr);
385     if (SymExpr && SymExpr->getKind() == MCSymbolRefExpr::VK_None)
386       return &SymExpr->getSymbol();
387 
388     return nullptr;
389   }
390 
391   const MCSymbol *getTargetSymbol(const MCInst &Inst,
392                                   unsigned OpNum = 0) const override {
393     if (!getSymbolRefOperandNum(Inst, OpNum))
394       return nullptr;
395 
396     const MCOperand &Op = Inst.getOperand(OpNum);
397     if (!Op.isExpr())
398       return nullptr;
399 
400     return getTargetSymbol(Op.getExpr());
401   }
402 
403   int64_t getTargetAddend(const MCExpr *Expr) const override {
404     auto *AArchExpr = dyn_cast<AArch64MCExpr>(Expr);
405     if (AArchExpr && AArchExpr->getSubExpr())
406       return getTargetAddend(AArchExpr->getSubExpr());
407 
408     auto *BinExpr = dyn_cast<MCBinaryExpr>(Expr);
409     if (BinExpr && BinExpr->getOpcode() == MCBinaryExpr::Add)
410       return getTargetAddend(BinExpr->getRHS());
411 
412     auto *ConstExpr = dyn_cast<MCConstantExpr>(Expr);
413     if (ConstExpr)
414       return ConstExpr->getValue();
415 
416     return 0;
417   }
418 
419   int64_t getTargetAddend(const MCInst &Inst,
420                           unsigned OpNum = 0) const override {
421     if (!getSymbolRefOperandNum(Inst, OpNum))
422       return 0;
423 
424     const MCOperand &Op = Inst.getOperand(OpNum);
425     if (!Op.isExpr())
426       return 0;
427 
428     return getTargetAddend(Op.getExpr());
429   }
430 
431   bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
432                       uint64_t &Target) const override {
433     size_t OpNum = 0;
434 
435     if (isConditionalBranch(Inst)) {
436       assert(MCPlus::getNumPrimeOperands(Inst) >= 2 &&
437              "Invalid number of operands");
438       OpNum = 1;
439     }
440 
441     if (isTB(Inst)) {
442       assert(MCPlus::getNumPrimeOperands(Inst) >= 3 &&
443              "Invalid number of operands");
444       OpNum = 2;
445     }
446 
447     if (Info->get(Inst.getOpcode()).OpInfo[OpNum].OperandType !=
448         MCOI::OPERAND_PCREL) {
449       assert((isIndirectBranch(Inst) || isIndirectCall(Inst)) &&
450              "FAILED evaluateBranch");
451       return false;
452     }
453 
454     int64_t Imm = Inst.getOperand(OpNum).getImm() << 2;
455     Target = Addr + Imm;
456     return true;
457   }
458 
459   bool replaceBranchTarget(MCInst &Inst, const MCSymbol *TBB,
460                            MCContext *Ctx) const override {
461     assert((isCall(Inst) || isBranch(Inst)) && !isIndirectBranch(Inst) &&
462            "Invalid instruction");
463     assert(MCPlus::getNumPrimeOperands(Inst) >= 1 &&
464            "Invalid number of operands");
465     MCInst::iterator OI = Inst.begin();
466 
467     if (isConditionalBranch(Inst)) {
468       assert(MCPlus::getNumPrimeOperands(Inst) >= 2 &&
469              "Invalid number of operands");
470       ++OI;
471     }
472 
473     if (isTB(Inst)) {
474       assert(MCPlus::getNumPrimeOperands(Inst) >= 3 &&
475              "Invalid number of operands");
476       OI = Inst.begin() + 2;
477     }
478 
479     *OI = MCOperand::createExpr(
480         MCSymbolRefExpr::create(TBB, MCSymbolRefExpr::VK_None, *Ctx));
481     return true;
482   }
483 
484   /// Matches indirect branch patterns in AArch64 related to a jump table (JT),
485   /// helping us to build the complete CFG. A typical indirect branch to
486   /// a jump table entry in AArch64 looks like the following:
487   ///
488   ///   adrp    x1, #-7585792           # Get JT Page location
489   ///   add     x1, x1, #692            # Complement with JT Page offset
490   ///   ldrh    w0, [x1, w0, uxtw #1]   # Loads JT entry
491   ///   adr     x1, #12                 # Get PC + 12 (end of this BB) used next
492   ///   add     x0, x1, w0, sxth #2     # Finish building branch target
493   ///                                   # (entries in JT are relative to the end
494   ///                                   #  of this BB)
495   ///   br      x0                      # Indirect jump instruction
496   ///
497   bool analyzeIndirectBranchFragment(
498       const MCInst &Inst,
499       DenseMap<const MCInst *, SmallVector<MCInst *, 4>> &UDChain,
500       const MCExpr *&JumpTable, int64_t &Offset, int64_t &ScaleValue,
501       MCInst *&PCRelBase) const {
502     // Expect AArch64 BR
503     assert(Inst.getOpcode() == AArch64::BR && "Unexpected opcode");
504 
505     // Match the indirect branch pattern for aarch64
506     SmallVector<MCInst *, 4> &UsesRoot = UDChain[&Inst];
507     if (UsesRoot.size() == 0 || UsesRoot[0] == nullptr)
508       return false;
509 
510     const MCInst *DefAdd = UsesRoot[0];
511 
512     // Now we match an ADD
513     if (!isADD(*DefAdd)) {
514       // If the address is not broken up in two parts, this is not branching
515       // according to a jump table entry. Fail.
516       return false;
517     }
518     if (DefAdd->getOpcode() == AArch64::ADDXri) {
519       // This can happen when there is no offset, but a direct jump that was
520       // transformed into an indirect one  (indirect tail call) :
521       //   ADRP   x2, Perl_re_compiler
522       //   ADD    x2, x2, :lo12:Perl_re_compiler
523       //   BR     x2
524       return false;
525     }
526     if (DefAdd->getOpcode() == AArch64::ADDXrs) {
527       // Covers the less common pattern where JT entries are relative to
528       // the JT itself (like x86). Seems less efficient since we can't
529       // assume the JT is aligned at 4B boundary and thus drop 2 bits from
530       // JT values.
531       // cde264:
532       //    adrp    x12, #21544960  ; 216a000
533       //    add     x12, x12, #1696 ; 216a6a0  (JT object in .rodata)
534       //    ldrsw   x8, [x12, x8, lsl #2]   --> loads e.g. 0xfeb73bd8
535       //  * add     x8, x8, x12   --> = cde278, next block
536       //    br      x8
537       // cde278:
538       //
539       // Parsed as ADDXrs reg:x8 reg:x8 reg:x12 imm:0
540       return false;
541     }
542     assert(DefAdd->getOpcode() == AArch64::ADDXrx &&
543            "Failed to match indirect branch!");
544 
545     // Validate ADD operands
546     int64_t OperandExtension = DefAdd->getOperand(3).getImm();
547     unsigned ShiftVal = AArch64_AM::getArithShiftValue(OperandExtension);
548     AArch64_AM::ShiftExtendType ExtendType =
549         AArch64_AM::getArithExtendType(OperandExtension);
550     if (ShiftVal != 2)
551       llvm_unreachable("Failed to match indirect branch! (fragment 2)");
552 
553     if (ExtendType == AArch64_AM::SXTB)
554       ScaleValue = 1LL;
555     else if (ExtendType == AArch64_AM::SXTH)
556       ScaleValue = 2LL;
557     else if (ExtendType == AArch64_AM::SXTW)
558       ScaleValue = 4LL;
559     else
560       llvm_unreachable("Failed to match indirect branch! (fragment 3)");
561 
562     // Match an ADR to load base address to be used when addressing JT targets
563     SmallVector<MCInst *, 4> &UsesAdd = UDChain[DefAdd];
564     if (UsesAdd.size() <= 1 || UsesAdd[1] == nullptr || UsesAdd[2] == nullptr) {
565       // This happens when we don't have enough context about this jump table
566       // because the jumping code sequence was split in multiple basic blocks.
567       // This was observed in the wild in HHVM code (dispatchImpl).
568       return false;
569     }
570     MCInst *DefBaseAddr = UsesAdd[1];
571     assert(DefBaseAddr->getOpcode() == AArch64::ADR &&
572            "Failed to match indirect branch pattern! (fragment 3)");
573 
574     PCRelBase = DefBaseAddr;
575     // Match LOAD to load the jump table (relative) target
576     const MCInst *DefLoad = UsesAdd[2];
577     assert(isLoad(*DefLoad) &&
578            "Failed to match indirect branch load pattern! (1)");
579     assert((ScaleValue != 1LL || isLDRB(*DefLoad)) &&
580            "Failed to match indirect branch load pattern! (2)");
581     assert((ScaleValue != 2LL || isLDRH(*DefLoad)) &&
582            "Failed to match indirect branch load pattern! (3)");
583 
584     // Match ADD that calculates the JumpTable Base Address (not the offset)
585     SmallVector<MCInst *, 4> &UsesLoad = UDChain[DefLoad];
586     const MCInst *DefJTBaseAdd = UsesLoad[1];
587     MCPhysReg From, To;
588     if (DefJTBaseAdd == nullptr || isLoadFromStack(*DefJTBaseAdd) ||
589         isRegToRegMove(*DefJTBaseAdd, From, To)) {
590       // Sometimes base address may have been defined in another basic block
591       // (hoisted). Return with no jump table info.
592       JumpTable = nullptr;
593       return true;
594     }
595 
596     assert(DefJTBaseAdd->getOpcode() == AArch64::ADDXri &&
597            "Failed to match jump table base address pattern! (1)");
598 
599     if (DefJTBaseAdd->getOperand(2).isImm())
600       Offset = DefJTBaseAdd->getOperand(2).getImm();
601     SmallVector<MCInst *, 4> &UsesJTBaseAdd = UDChain[DefJTBaseAdd];
602     const MCInst *DefJTBasePage = UsesJTBaseAdd[1];
603     if (DefJTBasePage == nullptr || isLoadFromStack(*DefJTBasePage)) {
604       JumpTable = nullptr;
605       return true;
606     }
607     assert(DefJTBasePage->getOpcode() == AArch64::ADRP &&
608            "Failed to match jump table base page pattern! (2)");
609     if (DefJTBasePage->getOperand(1).isExpr())
610       JumpTable = DefJTBasePage->getOperand(1).getExpr();
611     return true;
612   }
613 
614   DenseMap<const MCInst *, SmallVector<MCInst *, 4>>
615   computeLocalUDChain(const MCInst *CurInstr, InstructionIterator Begin,
616                       InstructionIterator End) const {
617     DenseMap<int, MCInst *> RegAliasTable;
618     DenseMap<const MCInst *, SmallVector<MCInst *, 4>> Uses;
619 
620     auto addInstrOperands = [&](const MCInst &Instr) {
621       // Update Uses table
622       for (unsigned OpNum = 0, OpEnd = MCPlus::getNumPrimeOperands(Instr);
623            OpNum != OpEnd; ++OpNum) {
624         if (!Instr.getOperand(OpNum).isReg())
625           continue;
626         unsigned Reg = Instr.getOperand(OpNum).getReg();
627         MCInst *AliasInst = RegAliasTable[Reg];
628         Uses[&Instr].push_back(AliasInst);
629         LLVM_DEBUG({
630           dbgs() << "Adding reg operand " << Reg << " refs ";
631           if (AliasInst != nullptr)
632             AliasInst->dump();
633           else
634             dbgs() << "\n";
635         });
636       }
637     };
638 
639     LLVM_DEBUG(dbgs() << "computeLocalUDChain\n");
640     bool TerminatorSeen = false;
641     for (auto II = Begin; II != End; ++II) {
642       MCInst &Instr = *II;
643       // Ignore nops and CFIs
644       if (isPseudo(Instr) || isNoop(Instr))
645         continue;
646       if (TerminatorSeen) {
647         RegAliasTable.clear();
648         Uses.clear();
649       }
650 
651       LLVM_DEBUG(dbgs() << "Now updating for:\n ");
652       LLVM_DEBUG(Instr.dump());
653       addInstrOperands(Instr);
654 
655       BitVector Regs = BitVector(RegInfo->getNumRegs(), false);
656       getWrittenRegs(Instr, Regs);
657 
658       // Update register definitions after this point
659       int Idx = Regs.find_first();
660       while (Idx != -1) {
661         RegAliasTable[Idx] = &Instr;
662         LLVM_DEBUG(dbgs() << "Setting reg " << Idx
663                           << " def to current instr.\n");
664         Idx = Regs.find_next(Idx);
665       }
666 
667       TerminatorSeen = isTerminator(Instr);
668     }
669 
670     // Process the last instruction, which is not currently added into the
671     // instruction stream
672     if (CurInstr)
673       addInstrOperands(*CurInstr);
674 
675     return Uses;
676   }
677 
678   IndirectBranchType analyzeIndirectBranch(
679       MCInst &Instruction, InstructionIterator Begin, InstructionIterator End,
680       const unsigned PtrSize, MCInst *&MemLocInstrOut, unsigned &BaseRegNumOut,
681       unsigned &IndexRegNumOut, int64_t &DispValueOut,
682       const MCExpr *&DispExprOut, MCInst *&PCRelBaseOut) const override {
683     MemLocInstrOut = nullptr;
684     BaseRegNumOut = AArch64::NoRegister;
685     IndexRegNumOut = AArch64::NoRegister;
686     DispValueOut = 0;
687     DispExprOut = nullptr;
688 
689     // An instruction referencing memory used by jump instruction (directly or
690     // via register). This location could be an array of function pointers
691     // in case of indirect tail call, or a jump table.
692     MCInst *MemLocInstr = nullptr;
693 
694     // Analyze the memory location.
695     int64_t ScaleValue, DispValue;
696     const MCExpr *DispExpr;
697 
698     DenseMap<const MCInst *, SmallVector<llvm::MCInst *, 4>> UDChain =
699         computeLocalUDChain(&Instruction, Begin, End);
700     MCInst *PCRelBase;
701     if (!analyzeIndirectBranchFragment(Instruction, UDChain, DispExpr,
702                                        DispValue, ScaleValue, PCRelBase))
703       return IndirectBranchType::UNKNOWN;
704 
705     MemLocInstrOut = MemLocInstr;
706     DispValueOut = DispValue;
707     DispExprOut = DispExpr;
708     PCRelBaseOut = PCRelBase;
709     return IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE;
710   }
711 
712   ///  Matches PLT entry pattern and returns the associated GOT entry address.
713   ///  Typical PLT entry looks like the following:
714   ///
715   ///    adrp    x16, 230000
716   ///    ldr     x17, [x16, #3040]
717   ///    add     x16, x16, #0xbe0
718   ///    br      x17
719   ///
720   uint64_t analyzePLTEntry(MCInst &Instruction, InstructionIterator Begin,
721                            InstructionIterator End,
722                            uint64_t BeginPC) const override {
723     // Check branch instruction
724     MCInst *Branch = &Instruction;
725     assert(Branch->getOpcode() == AArch64::BR && "Unexpected opcode");
726 
727     DenseMap<const MCInst *, SmallVector<llvm::MCInst *, 4>> UDChain =
728         computeLocalUDChain(Branch, Begin, End);
729 
730     // Match ldr instruction
731     SmallVector<MCInst *, 4> &BranchUses = UDChain[Branch];
732     if (BranchUses.size() < 1 || BranchUses[0] == nullptr)
733       return 0;
734 
735     // Check ldr instruction
736     const MCInst *Ldr = BranchUses[0];
737     if (Ldr->getOpcode() != AArch64::LDRXui)
738       return 0;
739 
740     // Get ldr value
741     const unsigned ScaleLdr = 8; // LDRX operates on 8 bytes segments
742     assert(Ldr->getOperand(2).isImm() && "Unexpected ldr operand");
743     const uint64_t Offset = Ldr->getOperand(2).getImm() * ScaleLdr;
744 
745     // Match adrp instruction
746     SmallVector<MCInst *, 4> &LdrUses = UDChain[Ldr];
747     if (LdrUses.size() < 2 || LdrUses[1] == nullptr)
748       return 0;
749 
750     // Check adrp instruction
751     MCInst *Adrp = LdrUses[1];
752     if (Adrp->getOpcode() != AArch64::ADRP)
753       return 0;
754 
755     // Get adrp instruction PC
756     const unsigned InstSize = 4;
757     uint64_t AdrpPC = BeginPC;
758     for (InstructionIterator It = Begin; It != End; ++It) {
759       if (&(*It) == Adrp)
760         break;
761       AdrpPC += InstSize;
762     }
763 
764     // Get adrp value
765     uint64_t Base;
766     assert(Adrp->getOperand(1).isImm() && "Unexpected adrp operand");
767     bool Ret = evaluateMemOperandTarget(*Adrp, Base, AdrpPC, InstSize);
768     assert(Ret && "Failed to evaluate adrp");
769 
770     return Base + Offset;
771   }
772 
773   unsigned getInvertedBranchOpcode(unsigned Opcode) const {
774     switch (Opcode) {
775     default:
776       llvm_unreachable("Failed to invert branch opcode");
777       return Opcode;
778     case AArch64::TBZW:     return AArch64::TBNZW;
779     case AArch64::TBZX:     return AArch64::TBNZX;
780     case AArch64::TBNZW:    return AArch64::TBZW;
781     case AArch64::TBNZX:    return AArch64::TBZX;
782     case AArch64::CBZW:     return AArch64::CBNZW;
783     case AArch64::CBZX:     return AArch64::CBNZX;
784     case AArch64::CBNZW:    return AArch64::CBZW;
785     case AArch64::CBNZX:    return AArch64::CBZX;
786     }
787   }
788 
789   unsigned getCondCode(const MCInst &Inst) const override {
790     // AArch64 does not use conditional codes, so we just return the opcode
791     // of the conditional branch here.
792     return Inst.getOpcode();
793   }
794 
795   unsigned getCanonicalBranchCondCode(unsigned Opcode) const override {
796     switch (Opcode) {
797     default:
798       return Opcode;
799     case AArch64::TBNZW:    return AArch64::TBZW;
800     case AArch64::TBNZX:    return AArch64::TBZX;
801     case AArch64::CBNZW:    return AArch64::CBZW;
802     case AArch64::CBNZX:    return AArch64::CBZX;
803     }
804   }
805 
806   bool reverseBranchCondition(MCInst &Inst, const MCSymbol *TBB,
807                               MCContext *Ctx) const override {
808     if (isTB(Inst) || isCB(Inst)) {
809       Inst.setOpcode(getInvertedBranchOpcode(Inst.getOpcode()));
810       assert(Inst.getOpcode() != 0 && "Invalid branch instruction");
811     } else if (Inst.getOpcode() == AArch64::Bcc) {
812       Inst.getOperand(0).setImm(AArch64CC::getInvertedCondCode(
813           static_cast<AArch64CC::CondCode>(Inst.getOperand(0).getImm())));
814       assert(Inst.getOperand(0).getImm() != AArch64CC::AL &&
815              Inst.getOperand(0).getImm() != AArch64CC::NV &&
816              "Can't reverse ALWAYS cond code");
817     } else {
818       LLVM_DEBUG(Inst.dump());
819       llvm_unreachable("Unrecognized branch instruction");
820     }
821     return replaceBranchTarget(Inst, TBB, Ctx);
822   }
823 
824   int getPCRelEncodingSize(const MCInst &Inst) const override {
825     switch (Inst.getOpcode()) {
826     default:
827       llvm_unreachable("Failed to get pcrel encoding size");
828       return 0;
829     case AArch64::TBZW:     return 16;
830     case AArch64::TBZX:     return 16;
831     case AArch64::TBNZW:    return 16;
832     case AArch64::TBNZX:    return 16;
833     case AArch64::CBZW:     return 21;
834     case AArch64::CBZX:     return 21;
835     case AArch64::CBNZW:    return 21;
836     case AArch64::CBNZX:    return 21;
837     case AArch64::B:        return 28;
838     case AArch64::BL:       return 28;
839     case AArch64::Bcc:      return 21;
840     }
841   }
842 
843   int getShortJmpEncodingSize() const override { return 33; }
844 
845   int getUncondBranchEncodingSize() const override { return 28; }
846 
847   bool createTailCall(MCInst &Inst, const MCSymbol *Target,
848                       MCContext *Ctx) override {
849     Inst.setOpcode(AArch64::B);
850     Inst.addOperand(MCOperand::createExpr(getTargetExprFor(
851         Inst, MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx),
852         *Ctx, 0)));
853     setTailCall(Inst);
854     return true;
855   }
856 
857   void createLongTailCall(InstructionListType &Seq, const MCSymbol *Target,
858                           MCContext *Ctx) override {
859     createShortJmp(Seq, Target, Ctx, /*IsTailCall*/ true);
860   }
861 
862   bool createTrap(MCInst &Inst) const override {
863     Inst.clear();
864     Inst.setOpcode(AArch64::BRK);
865     Inst.addOperand(MCOperand::createImm(1));
866     return true;
867   }
868 
869   bool convertJmpToTailCall(MCInst &Inst) override {
870     setTailCall(Inst);
871     return true;
872   }
873 
874   bool convertTailCallToJmp(MCInst &Inst) override {
875     removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
876     clearOffset(Inst);
877     if (getConditionalTailCall(Inst))
878       unsetConditionalTailCall(Inst);
879     return true;
880   }
881 
882   bool lowerTailCall(MCInst &Inst) override {
883     removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
884     if (getConditionalTailCall(Inst))
885       unsetConditionalTailCall(Inst);
886     return true;
887   }
888 
889   bool isNoop(const MCInst &Inst) const override {
890     return Inst.getOpcode() == AArch64::HINT &&
891            Inst.getOperand(0).getImm() == 0;
892   }
893 
894   bool createNoop(MCInst &Inst) const override {
895     Inst.setOpcode(AArch64::HINT);
896     Inst.clear();
897     Inst.addOperand(MCOperand::createImm(0));
898     return true;
899   }
900 
901   bool isStore(const MCInst &Inst) const override { return false; }
902 
903   bool analyzeBranch(InstructionIterator Begin, InstructionIterator End,
904                      const MCSymbol *&TBB, const MCSymbol *&FBB,
905                      MCInst *&CondBranch,
906                      MCInst *&UncondBranch) const override {
907     auto I = End;
908 
909     while (I != Begin) {
910       --I;
911 
912       // Ignore nops and CFIs
913       if (isPseudo(*I) || isNoop(*I))
914         continue;
915 
916       // Stop when we find the first non-terminator
917       if (!isTerminator(*I) || isTailCall(*I) || !isBranch(*I))
918         break;
919 
920       // Handle unconditional branches.
921       if (isUnconditionalBranch(*I)) {
922         // If any code was seen after this unconditional branch, we've seen
923         // unreachable code. Ignore them.
924         CondBranch = nullptr;
925         UncondBranch = &*I;
926         const MCSymbol *Sym = getTargetSymbol(*I);
927         assert(Sym != nullptr &&
928                "Couldn't extract BB symbol from jump operand");
929         TBB = Sym;
930         continue;
931       }
932 
933       // Handle conditional branches and ignore indirect branches
934       if (isIndirectBranch(*I))
935         return false;
936 
937       if (CondBranch == nullptr) {
938         const MCSymbol *TargetBB = getTargetSymbol(*I);
939         if (TargetBB == nullptr) {
940           // Unrecognized branch target
941           return false;
942         }
943         FBB = TBB;
944         TBB = TargetBB;
945         CondBranch = &*I;
946         continue;
947       }
948 
949       llvm_unreachable("multiple conditional branches in one BB");
950     }
951     return true;
952   }
953 
954   void createLongJmp(InstructionListType &Seq, const MCSymbol *Target,
955                      MCContext *Ctx, bool IsTailCall) override {
956     // ip0 (r16) is reserved to the linker (refer to 5.3.1.1 of "Procedure Call
957     //   Standard for the ARM 64-bit Architecture (AArch64)".
958     // The sequence of instructions we create here is the following:
959     //  movz ip0, #:abs_g3:<addr>
960     //  movk ip0, #:abs_g2_nc:<addr>
961     //  movk ip0, #:abs_g1_nc:<addr>
962     //  movk ip0, #:abs_g0_nc:<addr>
963     //  br ip0
964     MCInst Inst;
965     Inst.setOpcode(AArch64::MOVZXi);
966     Inst.addOperand(MCOperand::createReg(AArch64::X16));
967     Inst.addOperand(MCOperand::createExpr(AArch64MCExpr::create(
968         MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx),
969         AArch64MCExpr::VK_ABS_G3, *Ctx)));
970     Inst.addOperand(MCOperand::createImm(0x30));
971     Seq.emplace_back(Inst);
972 
973     Inst.clear();
974     Inst.setOpcode(AArch64::MOVKXi);
975     Inst.addOperand(MCOperand::createReg(AArch64::X16));
976     Inst.addOperand(MCOperand::createReg(AArch64::X16));
977     Inst.addOperand(MCOperand::createExpr(AArch64MCExpr::create(
978         MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx),
979         AArch64MCExpr::VK_ABS_G2_NC, *Ctx)));
980     Inst.addOperand(MCOperand::createImm(0x20));
981     Seq.emplace_back(Inst);
982 
983     Inst.clear();
984     Inst.setOpcode(AArch64::MOVKXi);
985     Inst.addOperand(MCOperand::createReg(AArch64::X16));
986     Inst.addOperand(MCOperand::createReg(AArch64::X16));
987     Inst.addOperand(MCOperand::createExpr(AArch64MCExpr::create(
988         MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx),
989         AArch64MCExpr::VK_ABS_G1_NC, *Ctx)));
990     Inst.addOperand(MCOperand::createImm(0x10));
991     Seq.emplace_back(Inst);
992 
993     Inst.clear();
994     Inst.setOpcode(AArch64::MOVKXi);
995     Inst.addOperand(MCOperand::createReg(AArch64::X16));
996     Inst.addOperand(MCOperand::createReg(AArch64::X16));
997     Inst.addOperand(MCOperand::createExpr(AArch64MCExpr::create(
998         MCSymbolRefExpr::create(Target, MCSymbolRefExpr::VK_None, *Ctx),
999         AArch64MCExpr::VK_ABS_G0_NC, *Ctx)));
1000     Inst.addOperand(MCOperand::createImm(0));
1001     Seq.emplace_back(Inst);
1002 
1003     Inst.clear();
1004     Inst.setOpcode(AArch64::BR);
1005     Inst.addOperand(MCOperand::createReg(AArch64::X16));
1006     if (IsTailCall)
1007       setTailCall(Inst);
1008     Seq.emplace_back(Inst);
1009   }
1010 
1011   void createShortJmp(InstructionListType &Seq, const MCSymbol *Target,
1012                       MCContext *Ctx, bool IsTailCall) override {
1013     // ip0 (r16) is reserved to the linker (refer to 5.3.1.1 of "Procedure Call
1014     //   Standard for the ARM 64-bit Architecture (AArch64)".
1015     // The sequence of instructions we create here is the following:
1016     //  adrp ip0, imm
1017     //  add ip0, ip0, imm
1018     //  br ip0
1019     MCPhysReg Reg = AArch64::X16;
1020     InstructionListType Insts = materializeAddress(Target, Ctx, Reg);
1021     Insts.emplace_back();
1022     MCInst &Inst = Insts.back();
1023     Inst.clear();
1024     Inst.setOpcode(AArch64::BR);
1025     Inst.addOperand(MCOperand::createReg(Reg));
1026     if (IsTailCall)
1027       setTailCall(Inst);
1028     Seq.swap(Insts);
1029   }
1030 
1031   /// Matching pattern here is
1032   ///
1033   ///    ADRP  x16, imm
1034   ///    ADD   x16, x16, imm
1035   ///    BR    x16
1036   ///
1037   bool matchLinkerVeneer(InstructionIterator Begin, InstructionIterator End,
1038                          uint64_t Address, const MCInst &CurInst,
1039                          MCInst *&TargetHiBits, MCInst *&TargetLowBits,
1040                          uint64_t &Target) const override {
1041     if (CurInst.getOpcode() != AArch64::BR || !CurInst.getOperand(0).isReg() ||
1042         CurInst.getOperand(0).getReg() != AArch64::X16)
1043       return false;
1044 
1045     auto I = End;
1046     if (I == Begin)
1047       return false;
1048 
1049     --I;
1050     Address -= 4;
1051     if (I == Begin || I->getOpcode() != AArch64::ADDXri ||
1052         MCPlus::getNumPrimeOperands(*I) < 3 || !I->getOperand(0).isReg() ||
1053         !I->getOperand(1).isReg() ||
1054         I->getOperand(0).getReg() != AArch64::X16 ||
1055         I->getOperand(1).getReg() != AArch64::X16 || !I->getOperand(2).isImm())
1056       return false;
1057     TargetLowBits = &*I;
1058     uint64_t Addr = I->getOperand(2).getImm() & 0xFFF;
1059 
1060     --I;
1061     Address -= 4;
1062     if (I->getOpcode() != AArch64::ADRP ||
1063         MCPlus::getNumPrimeOperands(*I) < 2 || !I->getOperand(0).isReg() ||
1064         !I->getOperand(1).isImm() || I->getOperand(0).getReg() != AArch64::X16)
1065       return false;
1066     TargetHiBits = &*I;
1067     Addr |= (Address + ((int64_t)I->getOperand(1).getImm() << 12)) &
1068             0xFFFFFFFFFFFFF000ULL;
1069     Target = Addr;
1070     return true;
1071   }
1072 
1073   bool replaceImmWithSymbolRef(MCInst &Inst, const MCSymbol *Symbol,
1074                                int64_t Addend, MCContext *Ctx, int64_t &Value,
1075                                uint64_t RelType) const override {
1076     unsigned ImmOpNo = -1U;
1077     for (unsigned Index = 0; Index < MCPlus::getNumPrimeOperands(Inst);
1078          ++Index) {
1079       if (Inst.getOperand(Index).isImm()) {
1080         ImmOpNo = Index;
1081         break;
1082       }
1083     }
1084     if (ImmOpNo == -1U)
1085       return false;
1086 
1087     Value = Inst.getOperand(ImmOpNo).getImm();
1088 
1089     setOperandToSymbolRef(Inst, ImmOpNo, Symbol, Addend, Ctx, RelType);
1090 
1091     return true;
1092   }
1093 
1094   bool createUncondBranch(MCInst &Inst, const MCSymbol *TBB,
1095                           MCContext *Ctx) const override {
1096     Inst.setOpcode(AArch64::B);
1097     Inst.clear();
1098     Inst.addOperand(MCOperand::createExpr(getTargetExprFor(
1099         Inst, MCSymbolRefExpr::create(TBB, MCSymbolRefExpr::VK_None, *Ctx),
1100         *Ctx, 0)));
1101     return true;
1102   }
1103 
1104   bool isMoveMem2Reg(const MCInst &Inst) const override { return false; }
1105 
1106   bool isLeave(const MCInst &Inst) const override { return false; }
1107 
1108   bool isPop(const MCInst &Inst) const override { return false; }
1109 
1110   bool isPrefix(const MCInst &Inst) const override { return false; }
1111 
1112   bool deleteREPPrefix(MCInst &Inst) const override { return false; }
1113 
1114   bool createReturn(MCInst &Inst) const override {
1115     Inst.setOpcode(AArch64::RET);
1116     Inst.clear();
1117     Inst.addOperand(MCOperand::createReg(AArch64::LR));
1118     return true;
1119   }
1120 
1121   InstructionListType materializeAddress(const MCSymbol *Target, MCContext *Ctx,
1122                                          MCPhysReg RegName,
1123                                          int64_t Addend = 0) const override {
1124     // Get page-aligned address and add page offset
1125     InstructionListType Insts(2);
1126     Insts[0].setOpcode(AArch64::ADRP);
1127     Insts[0].clear();
1128     Insts[0].addOperand(MCOperand::createReg(RegName));
1129     Insts[0].addOperand(MCOperand::createImm(0));
1130     setOperandToSymbolRef(Insts[0], /* OpNum */ 1, Target, Addend, Ctx,
1131                           ELF::R_AARCH64_NONE);
1132     Insts[1].setOpcode(AArch64::ADDXri);
1133     Insts[1].clear();
1134     Insts[1].addOperand(MCOperand::createReg(RegName));
1135     Insts[1].addOperand(MCOperand::createReg(RegName));
1136     Insts[1].addOperand(MCOperand::createImm(0));
1137     Insts[1].addOperand(MCOperand::createImm(0));
1138     setOperandToSymbolRef(Insts[1], /* OpNum */ 2, Target, Addend, Ctx,
1139                           ELF::R_AARCH64_ADD_ABS_LO12_NC);
1140     return Insts;
1141   }
1142 };
1143 
1144 } // end anonymous namespace
1145 
1146 namespace llvm {
1147 namespace bolt {
1148 
1149 MCPlusBuilder *createAArch64MCPlusBuilder(const MCInstrAnalysis *Analysis,
1150                                           const MCInstrInfo *Info,
1151                                           const MCRegisterInfo *RegInfo) {
1152   return new AArch64MCPlusBuilder(Analysis, Info, RegInfo);
1153 }
1154 
1155 } // namespace bolt
1156 } // namespace llvm
1157