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