xref: /openbsd-src/gnu/llvm/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //==-- AArch64MCInstLower.cpp - Convert AArch64 MachineInstr to an MCInst --==//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file contains code to lower AArch64 MachineInstrs to their corresponding
1009467b48Spatrick // MCInst records.
1109467b48Spatrick //
1209467b48Spatrick //===----------------------------------------------------------------------===//
1309467b48Spatrick 
1409467b48Spatrick #include "AArch64MCInstLower.h"
1509467b48Spatrick #include "MCTargetDesc/AArch64MCExpr.h"
1609467b48Spatrick #include "Utils/AArch64BaseInfo.h"
1709467b48Spatrick #include "llvm/CodeGen/AsmPrinter.h"
1809467b48Spatrick #include "llvm/CodeGen/MachineBasicBlock.h"
1909467b48Spatrick #include "llvm/CodeGen/MachineInstr.h"
2009467b48Spatrick #include "llvm/CodeGen/MachineModuleInfoImpls.h"
2109467b48Spatrick #include "llvm/IR/Mangler.h"
2209467b48Spatrick #include "llvm/MC/MCContext.h"
2309467b48Spatrick #include "llvm/MC/MCExpr.h"
2409467b48Spatrick #include "llvm/MC/MCInst.h"
25*d415bd75Srobert #include "llvm/MC/MCStreamer.h"
2609467b48Spatrick #include "llvm/Support/CodeGen.h"
2709467b48Spatrick #include "llvm/Support/CommandLine.h"
2809467b48Spatrick #include "llvm/Target/TargetLoweringObjectFile.h"
2909467b48Spatrick #include "llvm/Target/TargetMachine.h"
3009467b48Spatrick using namespace llvm;
3109467b48Spatrick 
3209467b48Spatrick extern cl::opt<bool> EnableAArch64ELFLocalDynamicTLSGeneration;
3309467b48Spatrick 
AArch64MCInstLower(MCContext & ctx,AsmPrinter & printer)3409467b48Spatrick AArch64MCInstLower::AArch64MCInstLower(MCContext &ctx, AsmPrinter &printer)
3509467b48Spatrick     : Ctx(ctx), Printer(printer) {}
3609467b48Spatrick 
3709467b48Spatrick MCSymbol *
GetGlobalAddressSymbol(const MachineOperand & MO) const3809467b48Spatrick AArch64MCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
3909467b48Spatrick   const GlobalValue *GV = MO.getGlobal();
4009467b48Spatrick   unsigned TargetFlags = MO.getTargetFlags();
4109467b48Spatrick   const Triple &TheTriple = Printer.TM.getTargetTriple();
4209467b48Spatrick   if (!TheTriple.isOSBinFormatCOFF())
4373471bf0Spatrick     return Printer.getSymbolPreferLocal(*GV);
4409467b48Spatrick 
4509467b48Spatrick   assert(TheTriple.isOSWindows() &&
4609467b48Spatrick          "Windows is the only supported COFF target");
4709467b48Spatrick 
48*d415bd75Srobert   bool IsIndirect =
49*d415bd75Srobert       (TargetFlags & (AArch64II::MO_DLLIMPORT | AArch64II::MO_DLLIMPORTAUX |
50*d415bd75Srobert                       AArch64II::MO_COFFSTUB));
5109467b48Spatrick   if (!IsIndirect)
5209467b48Spatrick     return Printer.getSymbol(GV);
5309467b48Spatrick 
5409467b48Spatrick   SmallString<128> Name;
55*d415bd75Srobert 
56*d415bd75Srobert   if (TargetFlags & AArch64II::MO_DLLIMPORTAUX) {
57*d415bd75Srobert     // __imp_aux is specific to arm64EC; it represents the actual address of
58*d415bd75Srobert     // an imported function without any thunks.
59*d415bd75Srobert     //
60*d415bd75Srobert     // If we see a reference to an "aux" symbol, also emit a reference to the
61*d415bd75Srobert     // corresponding non-aux symbol.  Otherwise, the Microsoft linker behaves
62*d415bd75Srobert     // strangely when linking against x64 import libararies.
63*d415bd75Srobert     //
64*d415bd75Srobert     // emitSymbolAttribute() doesn't have any real effect here; it just
65*d415bd75Srobert     // ensures the symbol name appears in the assembly without any
66*d415bd75Srobert     // side-effects. It might make sense to design a cleaner way to express
67*d415bd75Srobert     // this.
6809467b48Spatrick     Name = "__imp_";
69*d415bd75Srobert     Printer.TM.getNameWithPrefix(Name, GV,
70*d415bd75Srobert                                  Printer.getObjFileLowering().getMangler());
71*d415bd75Srobert     MCSymbol *ExtraSym = Ctx.getOrCreateSymbol(Name);
72*d415bd75Srobert     Printer.OutStreamer->emitSymbolAttribute(ExtraSym, MCSA_Global);
73*d415bd75Srobert 
74*d415bd75Srobert     Name = "__imp_aux_";
75*d415bd75Srobert   } else if (TargetFlags & AArch64II::MO_DLLIMPORT) {
76*d415bd75Srobert     Name = "__imp_";
77*d415bd75Srobert   } else if (TargetFlags & AArch64II::MO_COFFSTUB) {
7809467b48Spatrick     Name = ".refptr.";
79*d415bd75Srobert   }
8009467b48Spatrick   Printer.TM.getNameWithPrefix(Name, GV,
8109467b48Spatrick                                Printer.getObjFileLowering().getMangler());
8209467b48Spatrick 
8309467b48Spatrick   MCSymbol *MCSym = Ctx.getOrCreateSymbol(Name);
8409467b48Spatrick 
8509467b48Spatrick   if (TargetFlags & AArch64II::MO_COFFSTUB) {
8609467b48Spatrick     MachineModuleInfoCOFF &MMICOFF =
8709467b48Spatrick         Printer.MMI->getObjFileInfo<MachineModuleInfoCOFF>();
8809467b48Spatrick     MachineModuleInfoImpl::StubValueTy &StubSym =
8909467b48Spatrick         MMICOFF.getGVStubEntry(MCSym);
9009467b48Spatrick 
9109467b48Spatrick     if (!StubSym.getPointer())
9209467b48Spatrick       StubSym = MachineModuleInfoImpl::StubValueTy(Printer.getSymbol(GV), true);
9309467b48Spatrick   }
9409467b48Spatrick 
9509467b48Spatrick   return MCSym;
9609467b48Spatrick }
9709467b48Spatrick 
9809467b48Spatrick MCSymbol *
GetExternalSymbolSymbol(const MachineOperand & MO) const9909467b48Spatrick AArch64MCInstLower::GetExternalSymbolSymbol(const MachineOperand &MO) const {
10009467b48Spatrick   return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
10109467b48Spatrick }
10209467b48Spatrick 
lowerSymbolOperandDarwin(const MachineOperand & MO,MCSymbol * Sym) const10309467b48Spatrick MCOperand AArch64MCInstLower::lowerSymbolOperandDarwin(const MachineOperand &MO,
10409467b48Spatrick                                                        MCSymbol *Sym) const {
10509467b48Spatrick   // FIXME: We would like an efficient form for this, so we don't have to do a
10609467b48Spatrick   // lot of extra uniquing.
10709467b48Spatrick   MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
10809467b48Spatrick   if ((MO.getTargetFlags() & AArch64II::MO_GOT) != 0) {
10909467b48Spatrick     if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
11009467b48Spatrick       RefKind = MCSymbolRefExpr::VK_GOTPAGE;
11109467b48Spatrick     else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
11209467b48Spatrick              AArch64II::MO_PAGEOFF)
11309467b48Spatrick       RefKind = MCSymbolRefExpr::VK_GOTPAGEOFF;
11409467b48Spatrick     else
11509467b48Spatrick       llvm_unreachable("Unexpected target flags with MO_GOT on GV operand");
11609467b48Spatrick   } else if ((MO.getTargetFlags() & AArch64II::MO_TLS) != 0) {
11709467b48Spatrick     if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
11809467b48Spatrick       RefKind = MCSymbolRefExpr::VK_TLVPPAGE;
11909467b48Spatrick     else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
12009467b48Spatrick              AArch64II::MO_PAGEOFF)
12109467b48Spatrick       RefKind = MCSymbolRefExpr::VK_TLVPPAGEOFF;
12209467b48Spatrick     else
12309467b48Spatrick       llvm_unreachable("Unexpected target flags with MO_TLS on GV operand");
12409467b48Spatrick   } else {
12509467b48Spatrick     if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
12609467b48Spatrick       RefKind = MCSymbolRefExpr::VK_PAGE;
12709467b48Spatrick     else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
12809467b48Spatrick              AArch64II::MO_PAGEOFF)
12909467b48Spatrick       RefKind = MCSymbolRefExpr::VK_PAGEOFF;
13009467b48Spatrick   }
13109467b48Spatrick   const MCExpr *Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
13209467b48Spatrick   if (!MO.isJTI() && MO.getOffset())
13309467b48Spatrick     Expr = MCBinaryExpr::createAdd(
13409467b48Spatrick         Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
13509467b48Spatrick   return MCOperand::createExpr(Expr);
13609467b48Spatrick }
13709467b48Spatrick 
lowerSymbolOperandELF(const MachineOperand & MO,MCSymbol * Sym) const13809467b48Spatrick MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO,
13909467b48Spatrick                                                     MCSymbol *Sym) const {
14009467b48Spatrick   uint32_t RefFlags = 0;
14109467b48Spatrick 
14209467b48Spatrick   if (MO.getTargetFlags() & AArch64II::MO_GOT)
14309467b48Spatrick     RefFlags |= AArch64MCExpr::VK_GOT;
14409467b48Spatrick   else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
14509467b48Spatrick     TLSModel::Model Model;
14609467b48Spatrick     if (MO.isGlobal()) {
14709467b48Spatrick       const GlobalValue *GV = MO.getGlobal();
14809467b48Spatrick       Model = Printer.TM.getTLSModel(GV);
14909467b48Spatrick       if (!EnableAArch64ELFLocalDynamicTLSGeneration &&
15009467b48Spatrick           Model == TLSModel::LocalDynamic)
15109467b48Spatrick         Model = TLSModel::GeneralDynamic;
15209467b48Spatrick 
15309467b48Spatrick     } else {
15409467b48Spatrick       assert(MO.isSymbol() &&
15509467b48Spatrick              StringRef(MO.getSymbolName()) == "_TLS_MODULE_BASE_" &&
15609467b48Spatrick              "unexpected external TLS symbol");
15709467b48Spatrick       // The general dynamic access sequence is used to get the
15809467b48Spatrick       // address of _TLS_MODULE_BASE_.
15909467b48Spatrick       Model = TLSModel::GeneralDynamic;
16009467b48Spatrick     }
16109467b48Spatrick     switch (Model) {
16209467b48Spatrick     case TLSModel::InitialExec:
16309467b48Spatrick       RefFlags |= AArch64MCExpr::VK_GOTTPREL;
16409467b48Spatrick       break;
16509467b48Spatrick     case TLSModel::LocalExec:
16609467b48Spatrick       RefFlags |= AArch64MCExpr::VK_TPREL;
16709467b48Spatrick       break;
16809467b48Spatrick     case TLSModel::LocalDynamic:
16909467b48Spatrick       RefFlags |= AArch64MCExpr::VK_DTPREL;
17009467b48Spatrick       break;
17109467b48Spatrick     case TLSModel::GeneralDynamic:
17209467b48Spatrick       RefFlags |= AArch64MCExpr::VK_TLSDESC;
17309467b48Spatrick       break;
17409467b48Spatrick     }
17509467b48Spatrick   } else if (MO.getTargetFlags() & AArch64II::MO_PREL) {
17609467b48Spatrick     RefFlags |= AArch64MCExpr::VK_PREL;
17709467b48Spatrick   } else {
17809467b48Spatrick     // No modifier means this is a generic reference, classified as absolute for
17909467b48Spatrick     // the cases where it matters (:abs_g0: etc).
18009467b48Spatrick     RefFlags |= AArch64MCExpr::VK_ABS;
18109467b48Spatrick   }
18209467b48Spatrick 
18309467b48Spatrick   if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
18409467b48Spatrick     RefFlags |= AArch64MCExpr::VK_PAGE;
18509467b48Spatrick   else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
18609467b48Spatrick            AArch64II::MO_PAGEOFF)
18709467b48Spatrick     RefFlags |= AArch64MCExpr::VK_PAGEOFF;
18809467b48Spatrick   else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G3)
18909467b48Spatrick     RefFlags |= AArch64MCExpr::VK_G3;
19009467b48Spatrick   else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G2)
19109467b48Spatrick     RefFlags |= AArch64MCExpr::VK_G2;
19209467b48Spatrick   else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G1)
19309467b48Spatrick     RefFlags |= AArch64MCExpr::VK_G1;
19409467b48Spatrick   else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G0)
19509467b48Spatrick     RefFlags |= AArch64MCExpr::VK_G0;
19609467b48Spatrick   else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_HI12)
19709467b48Spatrick     RefFlags |= AArch64MCExpr::VK_HI12;
19809467b48Spatrick 
19909467b48Spatrick   if (MO.getTargetFlags() & AArch64II::MO_NC)
20009467b48Spatrick     RefFlags |= AArch64MCExpr::VK_NC;
20109467b48Spatrick 
20209467b48Spatrick   const MCExpr *Expr =
20309467b48Spatrick       MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx);
20409467b48Spatrick   if (!MO.isJTI() && MO.getOffset())
20509467b48Spatrick     Expr = MCBinaryExpr::createAdd(
20609467b48Spatrick         Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
20709467b48Spatrick 
20809467b48Spatrick   AArch64MCExpr::VariantKind RefKind;
20909467b48Spatrick   RefKind = static_cast<AArch64MCExpr::VariantKind>(RefFlags);
21009467b48Spatrick   Expr = AArch64MCExpr::create(Expr, RefKind, Ctx);
21109467b48Spatrick 
21209467b48Spatrick   return MCOperand::createExpr(Expr);
21309467b48Spatrick }
21409467b48Spatrick 
lowerSymbolOperandCOFF(const MachineOperand & MO,MCSymbol * Sym) const21509467b48Spatrick MCOperand AArch64MCInstLower::lowerSymbolOperandCOFF(const MachineOperand &MO,
21609467b48Spatrick                                                      MCSymbol *Sym) const {
21709467b48Spatrick   uint32_t RefFlags = 0;
21809467b48Spatrick 
21909467b48Spatrick   if (MO.getTargetFlags() & AArch64II::MO_TLS) {
22009467b48Spatrick     if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGEOFF)
22109467b48Spatrick       RefFlags |= AArch64MCExpr::VK_SECREL_LO12;
22209467b48Spatrick     else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
22309467b48Spatrick              AArch64II::MO_HI12)
22409467b48Spatrick       RefFlags |= AArch64MCExpr::VK_SECREL_HI12;
22509467b48Spatrick 
22609467b48Spatrick   } else if (MO.getTargetFlags() & AArch64II::MO_S) {
22709467b48Spatrick     RefFlags |= AArch64MCExpr::VK_SABS;
22809467b48Spatrick   } else {
22909467b48Spatrick     RefFlags |= AArch64MCExpr::VK_ABS;
23073471bf0Spatrick 
23173471bf0Spatrick     if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
23273471bf0Spatrick       RefFlags |= AArch64MCExpr::VK_PAGE;
23373471bf0Spatrick     else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
23473471bf0Spatrick              AArch64II::MO_PAGEOFF)
23573471bf0Spatrick       RefFlags |= AArch64MCExpr::VK_PAGEOFF | AArch64MCExpr::VK_NC;
23609467b48Spatrick   }
23709467b48Spatrick 
23809467b48Spatrick   if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G3)
23909467b48Spatrick     RefFlags |= AArch64MCExpr::VK_G3;
24009467b48Spatrick   else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G2)
24109467b48Spatrick     RefFlags |= AArch64MCExpr::VK_G2;
24209467b48Spatrick   else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G1)
24309467b48Spatrick     RefFlags |= AArch64MCExpr::VK_G1;
24409467b48Spatrick   else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G0)
24509467b48Spatrick     RefFlags |= AArch64MCExpr::VK_G0;
24609467b48Spatrick 
24709467b48Spatrick   // FIXME: Currently we only set VK_NC for MO_G3/MO_G2/MO_G1/MO_G0. This is
24809467b48Spatrick   // because setting VK_NC for others would mean setting their respective
24909467b48Spatrick   // RefFlags correctly.  We should do this in a separate patch.
25009467b48Spatrick   if (MO.getTargetFlags() & AArch64II::MO_NC) {
25109467b48Spatrick     auto MOFrag = (MO.getTargetFlags() & AArch64II::MO_FRAGMENT);
25209467b48Spatrick     if (MOFrag == AArch64II::MO_G3 || MOFrag == AArch64II::MO_G2 ||
25309467b48Spatrick         MOFrag == AArch64II::MO_G1 || MOFrag == AArch64II::MO_G0)
25409467b48Spatrick       RefFlags |= AArch64MCExpr::VK_NC;
25509467b48Spatrick   }
25609467b48Spatrick 
25709467b48Spatrick   const MCExpr *Expr =
25809467b48Spatrick       MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx);
25909467b48Spatrick   if (!MO.isJTI() && MO.getOffset())
26009467b48Spatrick     Expr = MCBinaryExpr::createAdd(
26109467b48Spatrick         Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
26209467b48Spatrick 
26309467b48Spatrick   auto RefKind = static_cast<AArch64MCExpr::VariantKind>(RefFlags);
26409467b48Spatrick   assert(RefKind != AArch64MCExpr::VK_INVALID &&
26509467b48Spatrick          "Invalid relocation requested");
26609467b48Spatrick   Expr = AArch64MCExpr::create(Expr, RefKind, Ctx);
26709467b48Spatrick 
26809467b48Spatrick   return MCOperand::createExpr(Expr);
26909467b48Spatrick }
27009467b48Spatrick 
LowerSymbolOperand(const MachineOperand & MO,MCSymbol * Sym) const27109467b48Spatrick MCOperand AArch64MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
27209467b48Spatrick                                                  MCSymbol *Sym) const {
27309467b48Spatrick   if (Printer.TM.getTargetTriple().isOSDarwin())
27409467b48Spatrick     return lowerSymbolOperandDarwin(MO, Sym);
27509467b48Spatrick   if (Printer.TM.getTargetTriple().isOSBinFormatCOFF())
27609467b48Spatrick     return lowerSymbolOperandCOFF(MO, Sym);
27709467b48Spatrick 
27809467b48Spatrick   assert(Printer.TM.getTargetTriple().isOSBinFormatELF() && "Invalid target");
27909467b48Spatrick   return lowerSymbolOperandELF(MO, Sym);
28009467b48Spatrick }
28109467b48Spatrick 
lowerOperand(const MachineOperand & MO,MCOperand & MCOp) const28209467b48Spatrick bool AArch64MCInstLower::lowerOperand(const MachineOperand &MO,
28309467b48Spatrick                                       MCOperand &MCOp) const {
28409467b48Spatrick   switch (MO.getType()) {
28509467b48Spatrick   default:
28609467b48Spatrick     llvm_unreachable("unknown operand type");
28709467b48Spatrick   case MachineOperand::MO_Register:
28809467b48Spatrick     // Ignore all implicit register operands.
28909467b48Spatrick     if (MO.isImplicit())
29009467b48Spatrick       return false;
29109467b48Spatrick     MCOp = MCOperand::createReg(MO.getReg());
29209467b48Spatrick     break;
29309467b48Spatrick   case MachineOperand::MO_RegisterMask:
29409467b48Spatrick     // Regmasks are like implicit defs.
29509467b48Spatrick     return false;
29609467b48Spatrick   case MachineOperand::MO_Immediate:
29709467b48Spatrick     MCOp = MCOperand::createImm(MO.getImm());
29809467b48Spatrick     break;
29909467b48Spatrick   case MachineOperand::MO_MachineBasicBlock:
30009467b48Spatrick     MCOp = MCOperand::createExpr(
30109467b48Spatrick         MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx));
30209467b48Spatrick     break;
30309467b48Spatrick   case MachineOperand::MO_GlobalAddress:
30409467b48Spatrick     MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
30509467b48Spatrick     break;
30609467b48Spatrick   case MachineOperand::MO_ExternalSymbol:
30709467b48Spatrick     MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
30809467b48Spatrick     break;
30909467b48Spatrick   case MachineOperand::MO_MCSymbol:
31009467b48Spatrick     MCOp = LowerSymbolOperand(MO, MO.getMCSymbol());
31109467b48Spatrick     break;
31209467b48Spatrick   case MachineOperand::MO_JumpTableIndex:
31309467b48Spatrick     MCOp = LowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex()));
31409467b48Spatrick     break;
31509467b48Spatrick   case MachineOperand::MO_ConstantPoolIndex:
31609467b48Spatrick     MCOp = LowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex()));
31709467b48Spatrick     break;
31809467b48Spatrick   case MachineOperand::MO_BlockAddress:
31909467b48Spatrick     MCOp = LowerSymbolOperand(
32009467b48Spatrick         MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress()));
32109467b48Spatrick     break;
32209467b48Spatrick   }
32309467b48Spatrick   return true;
32409467b48Spatrick }
32509467b48Spatrick 
Lower(const MachineInstr * MI,MCInst & OutMI) const32609467b48Spatrick void AArch64MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
32709467b48Spatrick   OutMI.setOpcode(MI->getOpcode());
32809467b48Spatrick 
32909467b48Spatrick   for (const MachineOperand &MO : MI->operands()) {
33009467b48Spatrick     MCOperand MCOp;
33109467b48Spatrick     if (lowerOperand(MO, MCOp))
33209467b48Spatrick       OutMI.addOperand(MCOp);
33309467b48Spatrick   }
33409467b48Spatrick 
33509467b48Spatrick   switch (OutMI.getOpcode()) {
33609467b48Spatrick   case AArch64::CATCHRET:
33709467b48Spatrick     OutMI = MCInst();
33809467b48Spatrick     OutMI.setOpcode(AArch64::RET);
33909467b48Spatrick     OutMI.addOperand(MCOperand::createReg(AArch64::LR));
34009467b48Spatrick     break;
34109467b48Spatrick   case AArch64::CLEANUPRET:
34209467b48Spatrick     OutMI = MCInst();
34309467b48Spatrick     OutMI.setOpcode(AArch64::RET);
34409467b48Spatrick     OutMI.addOperand(MCOperand::createReg(AArch64::LR));
34509467b48Spatrick     break;
34609467b48Spatrick   }
34709467b48Spatrick }
348