xref: /aosp_15_r20/external/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- AArch64AsmPrinter.cpp - AArch64 LLVM assembly writer --------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains a printer that converts from our internal representation
11*9880d681SAndroid Build Coastguard Worker // of machine-dependent LLVM code to the AArch64 assembly language.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/AArch64AddressingModes.h"
16*9880d681SAndroid Build Coastguard Worker #include "AArch64.h"
17*9880d681SAndroid Build Coastguard Worker #include "AArch64MCInstLower.h"
18*9880d681SAndroid Build Coastguard Worker #include "AArch64MachineFunctionInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "AArch64RegisterInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "AArch64Subtarget.h"
21*9880d681SAndroid Build Coastguard Worker #include "InstPrinter/AArch64InstPrinter.h"
22*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/AArch64MCExpr.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallString.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringSwitch.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Twine.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/AsmPrinter.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstr.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineModuleInfoImpls.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/StackMaps.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DebugInfo.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstBuilder.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCLinkerOptimizationHint.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
43*9880d681SAndroid Build Coastguard Worker using namespace llvm;
44*9880d681SAndroid Build Coastguard Worker 
45*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "asm-printer"
46*9880d681SAndroid Build Coastguard Worker 
47*9880d681SAndroid Build Coastguard Worker namespace {
48*9880d681SAndroid Build Coastguard Worker 
49*9880d681SAndroid Build Coastguard Worker class AArch64AsmPrinter : public AsmPrinter {
50*9880d681SAndroid Build Coastguard Worker   AArch64MCInstLower MCInstLowering;
51*9880d681SAndroid Build Coastguard Worker   StackMaps SM;
52*9880d681SAndroid Build Coastguard Worker   const AArch64Subtarget *STI;
53*9880d681SAndroid Build Coastguard Worker 
54*9880d681SAndroid Build Coastguard Worker public:
AArch64AsmPrinter(TargetMachine & TM,std::unique_ptr<MCStreamer> Streamer)55*9880d681SAndroid Build Coastguard Worker   AArch64AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
56*9880d681SAndroid Build Coastguard Worker       : AsmPrinter(TM, std::move(Streamer)), MCInstLowering(OutContext, *this),
57*9880d681SAndroid Build Coastguard Worker         SM(*this), AArch64FI(nullptr) {}
58*9880d681SAndroid Build Coastguard Worker 
getPassName() const59*9880d681SAndroid Build Coastguard Worker   const char *getPassName() const override {
60*9880d681SAndroid Build Coastguard Worker     return "AArch64 Assembly Printer";
61*9880d681SAndroid Build Coastguard Worker   }
62*9880d681SAndroid Build Coastguard Worker 
63*9880d681SAndroid Build Coastguard Worker   /// \brief Wrapper for MCInstLowering.lowerOperand() for the
64*9880d681SAndroid Build Coastguard Worker   /// tblgen'erated pseudo lowering.
lowerOperand(const MachineOperand & MO,MCOperand & MCOp) const65*9880d681SAndroid Build Coastguard Worker   bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const {
66*9880d681SAndroid Build Coastguard Worker     return MCInstLowering.lowerOperand(MO, MCOp);
67*9880d681SAndroid Build Coastguard Worker   }
68*9880d681SAndroid Build Coastguard Worker 
69*9880d681SAndroid Build Coastguard Worker   void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
70*9880d681SAndroid Build Coastguard Worker                      const MachineInstr &MI);
71*9880d681SAndroid Build Coastguard Worker   void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
72*9880d681SAndroid Build Coastguard Worker                        const MachineInstr &MI);
73*9880d681SAndroid Build Coastguard Worker   /// \brief tblgen'erated driver function for lowering simple MI->MC
74*9880d681SAndroid Build Coastguard Worker   /// pseudo instructions.
75*9880d681SAndroid Build Coastguard Worker   bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
76*9880d681SAndroid Build Coastguard Worker                                    const MachineInstr *MI);
77*9880d681SAndroid Build Coastguard Worker 
78*9880d681SAndroid Build Coastguard Worker   void EmitInstruction(const MachineInstr *MI) override;
79*9880d681SAndroid Build Coastguard Worker 
getAnalysisUsage(AnalysisUsage & AU) const80*9880d681SAndroid Build Coastguard Worker   void getAnalysisUsage(AnalysisUsage &AU) const override {
81*9880d681SAndroid Build Coastguard Worker     AsmPrinter::getAnalysisUsage(AU);
82*9880d681SAndroid Build Coastguard Worker     AU.setPreservesAll();
83*9880d681SAndroid Build Coastguard Worker   }
84*9880d681SAndroid Build Coastguard Worker 
runOnMachineFunction(MachineFunction & F)85*9880d681SAndroid Build Coastguard Worker   bool runOnMachineFunction(MachineFunction &F) override {
86*9880d681SAndroid Build Coastguard Worker     AArch64FI = F.getInfo<AArch64FunctionInfo>();
87*9880d681SAndroid Build Coastguard Worker     STI = static_cast<const AArch64Subtarget*>(&F.getSubtarget());
88*9880d681SAndroid Build Coastguard Worker     return AsmPrinter::runOnMachineFunction(F);
89*9880d681SAndroid Build Coastguard Worker   }
90*9880d681SAndroid Build Coastguard Worker 
91*9880d681SAndroid Build Coastguard Worker private:
92*9880d681SAndroid Build Coastguard Worker   void printOperand(const MachineInstr *MI, unsigned OpNum, raw_ostream &O);
93*9880d681SAndroid Build Coastguard Worker   bool printAsmMRegister(const MachineOperand &MO, char Mode, raw_ostream &O);
94*9880d681SAndroid Build Coastguard Worker   bool printAsmRegInClass(const MachineOperand &MO,
95*9880d681SAndroid Build Coastguard Worker                           const TargetRegisterClass *RC, bool isVector,
96*9880d681SAndroid Build Coastguard Worker                           raw_ostream &O);
97*9880d681SAndroid Build Coastguard Worker 
98*9880d681SAndroid Build Coastguard Worker   bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
99*9880d681SAndroid Build Coastguard Worker                        unsigned AsmVariant, const char *ExtraCode,
100*9880d681SAndroid Build Coastguard Worker                        raw_ostream &O) override;
101*9880d681SAndroid Build Coastguard Worker   bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
102*9880d681SAndroid Build Coastguard Worker                              unsigned AsmVariant, const char *ExtraCode,
103*9880d681SAndroid Build Coastguard Worker                              raw_ostream &O) override;
104*9880d681SAndroid Build Coastguard Worker 
105*9880d681SAndroid Build Coastguard Worker   void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
106*9880d681SAndroid Build Coastguard Worker 
107*9880d681SAndroid Build Coastguard Worker   void EmitFunctionBodyEnd() override;
108*9880d681SAndroid Build Coastguard Worker 
109*9880d681SAndroid Build Coastguard Worker   MCSymbol *GetCPISymbol(unsigned CPID) const override;
110*9880d681SAndroid Build Coastguard Worker   void EmitEndOfAsmFile(Module &M) override;
111*9880d681SAndroid Build Coastguard Worker   AArch64FunctionInfo *AArch64FI;
112*9880d681SAndroid Build Coastguard Worker 
113*9880d681SAndroid Build Coastguard Worker   /// \brief Emit the LOHs contained in AArch64FI.
114*9880d681SAndroid Build Coastguard Worker   void EmitLOHs();
115*9880d681SAndroid Build Coastguard Worker 
116*9880d681SAndroid Build Coastguard Worker   /// Emit instruction to set float register to zero.
117*9880d681SAndroid Build Coastguard Worker   void EmitFMov0(const MachineInstr &MI);
118*9880d681SAndroid Build Coastguard Worker 
119*9880d681SAndroid Build Coastguard Worker   typedef std::map<const MachineInstr *, MCSymbol *> MInstToMCSymbol;
120*9880d681SAndroid Build Coastguard Worker   MInstToMCSymbol LOHInstToLabel;
121*9880d681SAndroid Build Coastguard Worker };
122*9880d681SAndroid Build Coastguard Worker 
123*9880d681SAndroid Build Coastguard Worker } // end of anonymous namespace
124*9880d681SAndroid Build Coastguard Worker 
125*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
126*9880d681SAndroid Build Coastguard Worker 
EmitEndOfAsmFile(Module & M)127*9880d681SAndroid Build Coastguard Worker void AArch64AsmPrinter::EmitEndOfAsmFile(Module &M) {
128*9880d681SAndroid Build Coastguard Worker   const Triple &TT = TM.getTargetTriple();
129*9880d681SAndroid Build Coastguard Worker   if (TT.isOSBinFormatMachO()) {
130*9880d681SAndroid Build Coastguard Worker     // Funny Darwin hack: This flag tells the linker that no global symbols
131*9880d681SAndroid Build Coastguard Worker     // contain code that falls through to other global symbols (e.g. the obvious
132*9880d681SAndroid Build Coastguard Worker     // implementation of multiple entry points).  If this doesn't occur, the
133*9880d681SAndroid Build Coastguard Worker     // linker can safely perform dead code stripping.  Since LLVM never
134*9880d681SAndroid Build Coastguard Worker     // generates code that does this, it is always safe to set.
135*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
136*9880d681SAndroid Build Coastguard Worker     SM.serializeToStackMapSection();
137*9880d681SAndroid Build Coastguard Worker   }
138*9880d681SAndroid Build Coastguard Worker }
139*9880d681SAndroid Build Coastguard Worker 
EmitLOHs()140*9880d681SAndroid Build Coastguard Worker void AArch64AsmPrinter::EmitLOHs() {
141*9880d681SAndroid Build Coastguard Worker   SmallVector<MCSymbol *, 3> MCArgs;
142*9880d681SAndroid Build Coastguard Worker 
143*9880d681SAndroid Build Coastguard Worker   for (const auto &D : AArch64FI->getLOHContainer()) {
144*9880d681SAndroid Build Coastguard Worker     for (const MachineInstr *MI : D.getArgs()) {
145*9880d681SAndroid Build Coastguard Worker       MInstToMCSymbol::iterator LabelIt = LOHInstToLabel.find(MI);
146*9880d681SAndroid Build Coastguard Worker       assert(LabelIt != LOHInstToLabel.end() &&
147*9880d681SAndroid Build Coastguard Worker              "Label hasn't been inserted for LOH related instruction");
148*9880d681SAndroid Build Coastguard Worker       MCArgs.push_back(LabelIt->second);
149*9880d681SAndroid Build Coastguard Worker     }
150*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitLOHDirective(D.getKind(), MCArgs);
151*9880d681SAndroid Build Coastguard Worker     MCArgs.clear();
152*9880d681SAndroid Build Coastguard Worker   }
153*9880d681SAndroid Build Coastguard Worker }
154*9880d681SAndroid Build Coastguard Worker 
EmitFunctionBodyEnd()155*9880d681SAndroid Build Coastguard Worker void AArch64AsmPrinter::EmitFunctionBodyEnd() {
156*9880d681SAndroid Build Coastguard Worker   if (!AArch64FI->getLOHRelated().empty())
157*9880d681SAndroid Build Coastguard Worker     EmitLOHs();
158*9880d681SAndroid Build Coastguard Worker }
159*9880d681SAndroid Build Coastguard Worker 
160*9880d681SAndroid Build Coastguard Worker /// GetCPISymbol - Return the symbol for the specified constant pool entry.
GetCPISymbol(unsigned CPID) const161*9880d681SAndroid Build Coastguard Worker MCSymbol *AArch64AsmPrinter::GetCPISymbol(unsigned CPID) const {
162*9880d681SAndroid Build Coastguard Worker   // Darwin uses a linker-private symbol name for constant-pools (to
163*9880d681SAndroid Build Coastguard Worker   // avoid addends on the relocation?), ELF has no such concept and
164*9880d681SAndroid Build Coastguard Worker   // uses a normal private symbol.
165*9880d681SAndroid Build Coastguard Worker   if (getDataLayout().getLinkerPrivateGlobalPrefix()[0])
166*9880d681SAndroid Build Coastguard Worker     return OutContext.getOrCreateSymbol(
167*9880d681SAndroid Build Coastguard Worker         Twine(getDataLayout().getLinkerPrivateGlobalPrefix()) + "CPI" +
168*9880d681SAndroid Build Coastguard Worker         Twine(getFunctionNumber()) + "_" + Twine(CPID));
169*9880d681SAndroid Build Coastguard Worker 
170*9880d681SAndroid Build Coastguard Worker   return OutContext.getOrCreateSymbol(
171*9880d681SAndroid Build Coastguard Worker       Twine(getDataLayout().getPrivateGlobalPrefix()) + "CPI" +
172*9880d681SAndroid Build Coastguard Worker       Twine(getFunctionNumber()) + "_" + Twine(CPID));
173*9880d681SAndroid Build Coastguard Worker }
174*9880d681SAndroid Build Coastguard Worker 
printOperand(const MachineInstr * MI,unsigned OpNum,raw_ostream & O)175*9880d681SAndroid Build Coastguard Worker void AArch64AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNum,
176*9880d681SAndroid Build Coastguard Worker                                      raw_ostream &O) {
177*9880d681SAndroid Build Coastguard Worker   const MachineOperand &MO = MI->getOperand(OpNum);
178*9880d681SAndroid Build Coastguard Worker   switch (MO.getType()) {
179*9880d681SAndroid Build Coastguard Worker   default:
180*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("<unknown operand type>");
181*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_Register: {
182*9880d681SAndroid Build Coastguard Worker     unsigned Reg = MO.getReg();
183*9880d681SAndroid Build Coastguard Worker     assert(TargetRegisterInfo::isPhysicalRegister(Reg));
184*9880d681SAndroid Build Coastguard Worker     assert(!MO.getSubReg() && "Subregs should be eliminated!");
185*9880d681SAndroid Build Coastguard Worker     O << AArch64InstPrinter::getRegisterName(Reg);
186*9880d681SAndroid Build Coastguard Worker     break;
187*9880d681SAndroid Build Coastguard Worker   }
188*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_Immediate: {
189*9880d681SAndroid Build Coastguard Worker     int64_t Imm = MO.getImm();
190*9880d681SAndroid Build Coastguard Worker     O << '#' << Imm;
191*9880d681SAndroid Build Coastguard Worker     break;
192*9880d681SAndroid Build Coastguard Worker   }
193*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_GlobalAddress: {
194*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GV = MO.getGlobal();
195*9880d681SAndroid Build Coastguard Worker     MCSymbol *Sym = getSymbol(GV);
196*9880d681SAndroid Build Coastguard Worker 
197*9880d681SAndroid Build Coastguard Worker     // FIXME: Can we get anything other than a plain symbol here?
198*9880d681SAndroid Build Coastguard Worker     assert(!MO.getTargetFlags() && "Unknown operand target flag!");
199*9880d681SAndroid Build Coastguard Worker 
200*9880d681SAndroid Build Coastguard Worker     Sym->print(O, MAI);
201*9880d681SAndroid Build Coastguard Worker     printOffset(MO.getOffset(), O);
202*9880d681SAndroid Build Coastguard Worker     break;
203*9880d681SAndroid Build Coastguard Worker   }
204*9880d681SAndroid Build Coastguard Worker   }
205*9880d681SAndroid Build Coastguard Worker }
206*9880d681SAndroid Build Coastguard Worker 
printAsmMRegister(const MachineOperand & MO,char Mode,raw_ostream & O)207*9880d681SAndroid Build Coastguard Worker bool AArch64AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode,
208*9880d681SAndroid Build Coastguard Worker                                           raw_ostream &O) {
209*9880d681SAndroid Build Coastguard Worker   unsigned Reg = MO.getReg();
210*9880d681SAndroid Build Coastguard Worker   switch (Mode) {
211*9880d681SAndroid Build Coastguard Worker   default:
212*9880d681SAndroid Build Coastguard Worker     return true; // Unknown mode.
213*9880d681SAndroid Build Coastguard Worker   case 'w':
214*9880d681SAndroid Build Coastguard Worker     Reg = getWRegFromXReg(Reg);
215*9880d681SAndroid Build Coastguard Worker     break;
216*9880d681SAndroid Build Coastguard Worker   case 'x':
217*9880d681SAndroid Build Coastguard Worker     Reg = getXRegFromWReg(Reg);
218*9880d681SAndroid Build Coastguard Worker     break;
219*9880d681SAndroid Build Coastguard Worker   }
220*9880d681SAndroid Build Coastguard Worker 
221*9880d681SAndroid Build Coastguard Worker   O << AArch64InstPrinter::getRegisterName(Reg);
222*9880d681SAndroid Build Coastguard Worker   return false;
223*9880d681SAndroid Build Coastguard Worker }
224*9880d681SAndroid Build Coastguard Worker 
225*9880d681SAndroid Build Coastguard Worker // Prints the register in MO using class RC using the offset in the
226*9880d681SAndroid Build Coastguard Worker // new register class. This should not be used for cross class
227*9880d681SAndroid Build Coastguard Worker // printing.
printAsmRegInClass(const MachineOperand & MO,const TargetRegisterClass * RC,bool isVector,raw_ostream & O)228*9880d681SAndroid Build Coastguard Worker bool AArch64AsmPrinter::printAsmRegInClass(const MachineOperand &MO,
229*9880d681SAndroid Build Coastguard Worker                                            const TargetRegisterClass *RC,
230*9880d681SAndroid Build Coastguard Worker                                            bool isVector, raw_ostream &O) {
231*9880d681SAndroid Build Coastguard Worker   assert(MO.isReg() && "Should only get here with a register!");
232*9880d681SAndroid Build Coastguard Worker   const TargetRegisterInfo *RI = STI->getRegisterInfo();
233*9880d681SAndroid Build Coastguard Worker   unsigned Reg = MO.getReg();
234*9880d681SAndroid Build Coastguard Worker   unsigned RegToPrint = RC->getRegister(RI->getEncodingValue(Reg));
235*9880d681SAndroid Build Coastguard Worker   assert(RI->regsOverlap(RegToPrint, Reg));
236*9880d681SAndroid Build Coastguard Worker   O << AArch64InstPrinter::getRegisterName(
237*9880d681SAndroid Build Coastguard Worker            RegToPrint, isVector ? AArch64::vreg : AArch64::NoRegAltName);
238*9880d681SAndroid Build Coastguard Worker   return false;
239*9880d681SAndroid Build Coastguard Worker }
240*9880d681SAndroid Build Coastguard Worker 
PrintAsmOperand(const MachineInstr * MI,unsigned OpNum,unsigned AsmVariant,const char * ExtraCode,raw_ostream & O)241*9880d681SAndroid Build Coastguard Worker bool AArch64AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
242*9880d681SAndroid Build Coastguard Worker                                         unsigned AsmVariant,
243*9880d681SAndroid Build Coastguard Worker                                         const char *ExtraCode, raw_ostream &O) {
244*9880d681SAndroid Build Coastguard Worker   const MachineOperand &MO = MI->getOperand(OpNum);
245*9880d681SAndroid Build Coastguard Worker 
246*9880d681SAndroid Build Coastguard Worker   // First try the generic code, which knows about modifiers like 'c' and 'n'.
247*9880d681SAndroid Build Coastguard Worker   if (!AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O))
248*9880d681SAndroid Build Coastguard Worker     return false;
249*9880d681SAndroid Build Coastguard Worker 
250*9880d681SAndroid Build Coastguard Worker   // Does this asm operand have a single letter operand modifier?
251*9880d681SAndroid Build Coastguard Worker   if (ExtraCode && ExtraCode[0]) {
252*9880d681SAndroid Build Coastguard Worker     if (ExtraCode[1] != 0)
253*9880d681SAndroid Build Coastguard Worker       return true; // Unknown modifier.
254*9880d681SAndroid Build Coastguard Worker 
255*9880d681SAndroid Build Coastguard Worker     switch (ExtraCode[0]) {
256*9880d681SAndroid Build Coastguard Worker     default:
257*9880d681SAndroid Build Coastguard Worker       return true; // Unknown modifier.
258*9880d681SAndroid Build Coastguard Worker     case 'w':      // Print W register
259*9880d681SAndroid Build Coastguard Worker     case 'x':      // Print X register
260*9880d681SAndroid Build Coastguard Worker       if (MO.isReg())
261*9880d681SAndroid Build Coastguard Worker         return printAsmMRegister(MO, ExtraCode[0], O);
262*9880d681SAndroid Build Coastguard Worker       if (MO.isImm() && MO.getImm() == 0) {
263*9880d681SAndroid Build Coastguard Worker         unsigned Reg = ExtraCode[0] == 'w' ? AArch64::WZR : AArch64::XZR;
264*9880d681SAndroid Build Coastguard Worker         O << AArch64InstPrinter::getRegisterName(Reg);
265*9880d681SAndroid Build Coastguard Worker         return false;
266*9880d681SAndroid Build Coastguard Worker       }
267*9880d681SAndroid Build Coastguard Worker       printOperand(MI, OpNum, O);
268*9880d681SAndroid Build Coastguard Worker       return false;
269*9880d681SAndroid Build Coastguard Worker     case 'b': // Print B register.
270*9880d681SAndroid Build Coastguard Worker     case 'h': // Print H register.
271*9880d681SAndroid Build Coastguard Worker     case 's': // Print S register.
272*9880d681SAndroid Build Coastguard Worker     case 'd': // Print D register.
273*9880d681SAndroid Build Coastguard Worker     case 'q': // Print Q register.
274*9880d681SAndroid Build Coastguard Worker       if (MO.isReg()) {
275*9880d681SAndroid Build Coastguard Worker         const TargetRegisterClass *RC;
276*9880d681SAndroid Build Coastguard Worker         switch (ExtraCode[0]) {
277*9880d681SAndroid Build Coastguard Worker         case 'b':
278*9880d681SAndroid Build Coastguard Worker           RC = &AArch64::FPR8RegClass;
279*9880d681SAndroid Build Coastguard Worker           break;
280*9880d681SAndroid Build Coastguard Worker         case 'h':
281*9880d681SAndroid Build Coastguard Worker           RC = &AArch64::FPR16RegClass;
282*9880d681SAndroid Build Coastguard Worker           break;
283*9880d681SAndroid Build Coastguard Worker         case 's':
284*9880d681SAndroid Build Coastguard Worker           RC = &AArch64::FPR32RegClass;
285*9880d681SAndroid Build Coastguard Worker           break;
286*9880d681SAndroid Build Coastguard Worker         case 'd':
287*9880d681SAndroid Build Coastguard Worker           RC = &AArch64::FPR64RegClass;
288*9880d681SAndroid Build Coastguard Worker           break;
289*9880d681SAndroid Build Coastguard Worker         case 'q':
290*9880d681SAndroid Build Coastguard Worker           RC = &AArch64::FPR128RegClass;
291*9880d681SAndroid Build Coastguard Worker           break;
292*9880d681SAndroid Build Coastguard Worker         default:
293*9880d681SAndroid Build Coastguard Worker           return true;
294*9880d681SAndroid Build Coastguard Worker         }
295*9880d681SAndroid Build Coastguard Worker         return printAsmRegInClass(MO, RC, false /* vector */, O);
296*9880d681SAndroid Build Coastguard Worker       }
297*9880d681SAndroid Build Coastguard Worker       printOperand(MI, OpNum, O);
298*9880d681SAndroid Build Coastguard Worker       return false;
299*9880d681SAndroid Build Coastguard Worker     }
300*9880d681SAndroid Build Coastguard Worker   }
301*9880d681SAndroid Build Coastguard Worker 
302*9880d681SAndroid Build Coastguard Worker   // According to ARM, we should emit x and v registers unless we have a
303*9880d681SAndroid Build Coastguard Worker   // modifier.
304*9880d681SAndroid Build Coastguard Worker   if (MO.isReg()) {
305*9880d681SAndroid Build Coastguard Worker     unsigned Reg = MO.getReg();
306*9880d681SAndroid Build Coastguard Worker 
307*9880d681SAndroid Build Coastguard Worker     // If this is a w or x register, print an x register.
308*9880d681SAndroid Build Coastguard Worker     if (AArch64::GPR32allRegClass.contains(Reg) ||
309*9880d681SAndroid Build Coastguard Worker         AArch64::GPR64allRegClass.contains(Reg))
310*9880d681SAndroid Build Coastguard Worker       return printAsmMRegister(MO, 'x', O);
311*9880d681SAndroid Build Coastguard Worker 
312*9880d681SAndroid Build Coastguard Worker     // If this is a b, h, s, d, or q register, print it as a v register.
313*9880d681SAndroid Build Coastguard Worker     return printAsmRegInClass(MO, &AArch64::FPR128RegClass, true /* vector */,
314*9880d681SAndroid Build Coastguard Worker                               O);
315*9880d681SAndroid Build Coastguard Worker   }
316*9880d681SAndroid Build Coastguard Worker 
317*9880d681SAndroid Build Coastguard Worker   printOperand(MI, OpNum, O);
318*9880d681SAndroid Build Coastguard Worker   return false;
319*9880d681SAndroid Build Coastguard Worker }
320*9880d681SAndroid Build Coastguard Worker 
PrintAsmMemoryOperand(const MachineInstr * MI,unsigned OpNum,unsigned AsmVariant,const char * ExtraCode,raw_ostream & O)321*9880d681SAndroid Build Coastguard Worker bool AArch64AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
322*9880d681SAndroid Build Coastguard Worker                                               unsigned OpNum,
323*9880d681SAndroid Build Coastguard Worker                                               unsigned AsmVariant,
324*9880d681SAndroid Build Coastguard Worker                                               const char *ExtraCode,
325*9880d681SAndroid Build Coastguard Worker                                               raw_ostream &O) {
326*9880d681SAndroid Build Coastguard Worker   if (ExtraCode && ExtraCode[0])
327*9880d681SAndroid Build Coastguard Worker     return true; // Unknown modifier.
328*9880d681SAndroid Build Coastguard Worker 
329*9880d681SAndroid Build Coastguard Worker   const MachineOperand &MO = MI->getOperand(OpNum);
330*9880d681SAndroid Build Coastguard Worker   assert(MO.isReg() && "unexpected inline asm memory operand");
331*9880d681SAndroid Build Coastguard Worker   O << "[" << AArch64InstPrinter::getRegisterName(MO.getReg()) << "]";
332*9880d681SAndroid Build Coastguard Worker   return false;
333*9880d681SAndroid Build Coastguard Worker }
334*9880d681SAndroid Build Coastguard Worker 
PrintDebugValueComment(const MachineInstr * MI,raw_ostream & OS)335*9880d681SAndroid Build Coastguard Worker void AArch64AsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
336*9880d681SAndroid Build Coastguard Worker                                                raw_ostream &OS) {
337*9880d681SAndroid Build Coastguard Worker   unsigned NOps = MI->getNumOperands();
338*9880d681SAndroid Build Coastguard Worker   assert(NOps == 4);
339*9880d681SAndroid Build Coastguard Worker   OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
340*9880d681SAndroid Build Coastguard Worker   // cast away const; DIetc do not take const operands for some reason.
341*9880d681SAndroid Build Coastguard Worker   OS << cast<DILocalVariable>(MI->getOperand(NOps - 2).getMetadata())
342*9880d681SAndroid Build Coastguard Worker             ->getName();
343*9880d681SAndroid Build Coastguard Worker   OS << " <- ";
344*9880d681SAndroid Build Coastguard Worker   // Frame address.  Currently handles register +- offset only.
345*9880d681SAndroid Build Coastguard Worker   assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
346*9880d681SAndroid Build Coastguard Worker   OS << '[';
347*9880d681SAndroid Build Coastguard Worker   printOperand(MI, 0, OS);
348*9880d681SAndroid Build Coastguard Worker   OS << '+';
349*9880d681SAndroid Build Coastguard Worker   printOperand(MI, 1, OS);
350*9880d681SAndroid Build Coastguard Worker   OS << ']';
351*9880d681SAndroid Build Coastguard Worker   OS << "+";
352*9880d681SAndroid Build Coastguard Worker   printOperand(MI, NOps - 2, OS);
353*9880d681SAndroid Build Coastguard Worker }
354*9880d681SAndroid Build Coastguard Worker 
LowerSTACKMAP(MCStreamer & OutStreamer,StackMaps & SM,const MachineInstr & MI)355*9880d681SAndroid Build Coastguard Worker void AArch64AsmPrinter::LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
356*9880d681SAndroid Build Coastguard Worker                                       const MachineInstr &MI) {
357*9880d681SAndroid Build Coastguard Worker   unsigned NumNOPBytes = MI.getOperand(1).getImm();
358*9880d681SAndroid Build Coastguard Worker 
359*9880d681SAndroid Build Coastguard Worker   SM.recordStackMap(MI);
360*9880d681SAndroid Build Coastguard Worker   assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
361*9880d681SAndroid Build Coastguard Worker 
362*9880d681SAndroid Build Coastguard Worker   // Scan ahead to trim the shadow.
363*9880d681SAndroid Build Coastguard Worker   const MachineBasicBlock &MBB = *MI.getParent();
364*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::const_iterator MII(MI);
365*9880d681SAndroid Build Coastguard Worker   ++MII;
366*9880d681SAndroid Build Coastguard Worker   while (NumNOPBytes > 0) {
367*9880d681SAndroid Build Coastguard Worker     if (MII == MBB.end() || MII->isCall() ||
368*9880d681SAndroid Build Coastguard Worker         MII->getOpcode() == AArch64::DBG_VALUE ||
369*9880d681SAndroid Build Coastguard Worker         MII->getOpcode() == TargetOpcode::PATCHPOINT ||
370*9880d681SAndroid Build Coastguard Worker         MII->getOpcode() == TargetOpcode::STACKMAP)
371*9880d681SAndroid Build Coastguard Worker       break;
372*9880d681SAndroid Build Coastguard Worker     ++MII;
373*9880d681SAndroid Build Coastguard Worker     NumNOPBytes -= 4;
374*9880d681SAndroid Build Coastguard Worker   }
375*9880d681SAndroid Build Coastguard Worker 
376*9880d681SAndroid Build Coastguard Worker   // Emit nops.
377*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i < NumNOPBytes; i += 4)
378*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
379*9880d681SAndroid Build Coastguard Worker }
380*9880d681SAndroid Build Coastguard Worker 
381*9880d681SAndroid Build Coastguard Worker // Lower a patchpoint of the form:
382*9880d681SAndroid Build Coastguard Worker // [<def>], <id>, <numBytes>, <target>, <numArgs>
LowerPATCHPOINT(MCStreamer & OutStreamer,StackMaps & SM,const MachineInstr & MI)383*9880d681SAndroid Build Coastguard Worker void AArch64AsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
384*9880d681SAndroid Build Coastguard Worker                                         const MachineInstr &MI) {
385*9880d681SAndroid Build Coastguard Worker   SM.recordPatchPoint(MI);
386*9880d681SAndroid Build Coastguard Worker 
387*9880d681SAndroid Build Coastguard Worker   PatchPointOpers Opers(&MI);
388*9880d681SAndroid Build Coastguard Worker 
389*9880d681SAndroid Build Coastguard Worker   int64_t CallTarget = Opers.getMetaOper(PatchPointOpers::TargetPos).getImm();
390*9880d681SAndroid Build Coastguard Worker   unsigned EncodedBytes = 0;
391*9880d681SAndroid Build Coastguard Worker   if (CallTarget) {
392*9880d681SAndroid Build Coastguard Worker     assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
393*9880d681SAndroid Build Coastguard Worker            "High 16 bits of call target should be zero.");
394*9880d681SAndroid Build Coastguard Worker     unsigned ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
395*9880d681SAndroid Build Coastguard Worker     EncodedBytes = 16;
396*9880d681SAndroid Build Coastguard Worker     // Materialize the jump address:
397*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::MOVZXi)
398*9880d681SAndroid Build Coastguard Worker                                     .addReg(ScratchReg)
399*9880d681SAndroid Build Coastguard Worker                                     .addImm((CallTarget >> 32) & 0xFFFF)
400*9880d681SAndroid Build Coastguard Worker                                     .addImm(32));
401*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::MOVKXi)
402*9880d681SAndroid Build Coastguard Worker                                     .addReg(ScratchReg)
403*9880d681SAndroid Build Coastguard Worker                                     .addReg(ScratchReg)
404*9880d681SAndroid Build Coastguard Worker                                     .addImm((CallTarget >> 16) & 0xFFFF)
405*9880d681SAndroid Build Coastguard Worker                                     .addImm(16));
406*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::MOVKXi)
407*9880d681SAndroid Build Coastguard Worker                                     .addReg(ScratchReg)
408*9880d681SAndroid Build Coastguard Worker                                     .addReg(ScratchReg)
409*9880d681SAndroid Build Coastguard Worker                                     .addImm(CallTarget & 0xFFFF)
410*9880d681SAndroid Build Coastguard Worker                                     .addImm(0));
411*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::BLR).addReg(ScratchReg));
412*9880d681SAndroid Build Coastguard Worker   }
413*9880d681SAndroid Build Coastguard Worker   // Emit padding.
414*9880d681SAndroid Build Coastguard Worker   unsigned NumBytes = Opers.getMetaOper(PatchPointOpers::NBytesPos).getImm();
415*9880d681SAndroid Build Coastguard Worker   assert(NumBytes >= EncodedBytes &&
416*9880d681SAndroid Build Coastguard Worker          "Patchpoint can't request size less than the length of a call.");
417*9880d681SAndroid Build Coastguard Worker   assert((NumBytes - EncodedBytes) % 4 == 0 &&
418*9880d681SAndroid Build Coastguard Worker          "Invalid number of NOP bytes requested!");
419*9880d681SAndroid Build Coastguard Worker   for (unsigned i = EncodedBytes; i < NumBytes; i += 4)
420*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
421*9880d681SAndroid Build Coastguard Worker }
422*9880d681SAndroid Build Coastguard Worker 
EmitFMov0(const MachineInstr & MI)423*9880d681SAndroid Build Coastguard Worker void AArch64AsmPrinter::EmitFMov0(const MachineInstr &MI) {
424*9880d681SAndroid Build Coastguard Worker   unsigned DestReg = MI.getOperand(0).getReg();
425*9880d681SAndroid Build Coastguard Worker   if (STI->hasZeroCycleZeroing()) {
426*9880d681SAndroid Build Coastguard Worker     // Convert S/D register to corresponding Q register
427*9880d681SAndroid Build Coastguard Worker     if (AArch64::S0 <= DestReg && DestReg <= AArch64::S31) {
428*9880d681SAndroid Build Coastguard Worker       DestReg = AArch64::Q0 + (DestReg - AArch64::S0);
429*9880d681SAndroid Build Coastguard Worker     } else {
430*9880d681SAndroid Build Coastguard Worker       assert(AArch64::D0 <= DestReg && DestReg <= AArch64::D31);
431*9880d681SAndroid Build Coastguard Worker       DestReg = AArch64::Q0 + (DestReg - AArch64::D0);
432*9880d681SAndroid Build Coastguard Worker     }
433*9880d681SAndroid Build Coastguard Worker     MCInst MOVI;
434*9880d681SAndroid Build Coastguard Worker     MOVI.setOpcode(AArch64::MOVIv2d_ns);
435*9880d681SAndroid Build Coastguard Worker     MOVI.addOperand(MCOperand::createReg(DestReg));
436*9880d681SAndroid Build Coastguard Worker     MOVI.addOperand(MCOperand::createImm(0));
437*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MOVI);
438*9880d681SAndroid Build Coastguard Worker   } else {
439*9880d681SAndroid Build Coastguard Worker     MCInst FMov;
440*9880d681SAndroid Build Coastguard Worker     switch (MI.getOpcode()) {
441*9880d681SAndroid Build Coastguard Worker     default: llvm_unreachable("Unexpected opcode");
442*9880d681SAndroid Build Coastguard Worker     case AArch64::FMOVS0:
443*9880d681SAndroid Build Coastguard Worker       FMov.setOpcode(AArch64::FMOVWSr);
444*9880d681SAndroid Build Coastguard Worker       FMov.addOperand(MCOperand::createReg(DestReg));
445*9880d681SAndroid Build Coastguard Worker       FMov.addOperand(MCOperand::createReg(AArch64::WZR));
446*9880d681SAndroid Build Coastguard Worker       break;
447*9880d681SAndroid Build Coastguard Worker     case AArch64::FMOVD0:
448*9880d681SAndroid Build Coastguard Worker       FMov.setOpcode(AArch64::FMOVXDr);
449*9880d681SAndroid Build Coastguard Worker       FMov.addOperand(MCOperand::createReg(DestReg));
450*9880d681SAndroid Build Coastguard Worker       FMov.addOperand(MCOperand::createReg(AArch64::XZR));
451*9880d681SAndroid Build Coastguard Worker       break;
452*9880d681SAndroid Build Coastguard Worker     }
453*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, FMov);
454*9880d681SAndroid Build Coastguard Worker   }
455*9880d681SAndroid Build Coastguard Worker }
456*9880d681SAndroid Build Coastguard Worker 
457*9880d681SAndroid Build Coastguard Worker // Simple pseudo-instructions have their lowering (with expansion to real
458*9880d681SAndroid Build Coastguard Worker // instructions) auto-generated.
459*9880d681SAndroid Build Coastguard Worker #include "AArch64GenMCPseudoLowering.inc"
460*9880d681SAndroid Build Coastguard Worker 
EmitInstruction(const MachineInstr * MI)461*9880d681SAndroid Build Coastguard Worker void AArch64AsmPrinter::EmitInstruction(const MachineInstr *MI) {
462*9880d681SAndroid Build Coastguard Worker   // Do any auto-generated pseudo lowerings.
463*9880d681SAndroid Build Coastguard Worker   if (emitPseudoExpansionLowering(*OutStreamer, MI))
464*9880d681SAndroid Build Coastguard Worker     return;
465*9880d681SAndroid Build Coastguard Worker 
466*9880d681SAndroid Build Coastguard Worker   if (AArch64FI->getLOHRelated().count(MI)) {
467*9880d681SAndroid Build Coastguard Worker     // Generate a label for LOH related instruction
468*9880d681SAndroid Build Coastguard Worker     MCSymbol *LOHLabel = createTempSymbol("loh");
469*9880d681SAndroid Build Coastguard Worker     // Associate the instruction with the label
470*9880d681SAndroid Build Coastguard Worker     LOHInstToLabel[MI] = LOHLabel;
471*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitLabel(LOHLabel);
472*9880d681SAndroid Build Coastguard Worker   }
473*9880d681SAndroid Build Coastguard Worker 
474*9880d681SAndroid Build Coastguard Worker   // Do any manual lowerings.
475*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
476*9880d681SAndroid Build Coastguard Worker   default:
477*9880d681SAndroid Build Coastguard Worker     break;
478*9880d681SAndroid Build Coastguard Worker   case AArch64::DBG_VALUE: {
479*9880d681SAndroid Build Coastguard Worker     if (isVerbose() && OutStreamer->hasRawTextSupport()) {
480*9880d681SAndroid Build Coastguard Worker       SmallString<128> TmpStr;
481*9880d681SAndroid Build Coastguard Worker       raw_svector_ostream OS(TmpStr);
482*9880d681SAndroid Build Coastguard Worker       PrintDebugValueComment(MI, OS);
483*9880d681SAndroid Build Coastguard Worker       OutStreamer->EmitRawText(StringRef(OS.str()));
484*9880d681SAndroid Build Coastguard Worker     }
485*9880d681SAndroid Build Coastguard Worker     return;
486*9880d681SAndroid Build Coastguard Worker   }
487*9880d681SAndroid Build Coastguard Worker 
488*9880d681SAndroid Build Coastguard Worker   // Tail calls use pseudo instructions so they have the proper code-gen
489*9880d681SAndroid Build Coastguard Worker   // attributes (isCall, isReturn, etc.). We lower them to the real
490*9880d681SAndroid Build Coastguard Worker   // instruction here.
491*9880d681SAndroid Build Coastguard Worker   case AArch64::TCRETURNri: {
492*9880d681SAndroid Build Coastguard Worker     MCInst TmpInst;
493*9880d681SAndroid Build Coastguard Worker     TmpInst.setOpcode(AArch64::BR);
494*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
495*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, TmpInst);
496*9880d681SAndroid Build Coastguard Worker     return;
497*9880d681SAndroid Build Coastguard Worker   }
498*9880d681SAndroid Build Coastguard Worker   case AArch64::TCRETURNdi: {
499*9880d681SAndroid Build Coastguard Worker     MCOperand Dest;
500*9880d681SAndroid Build Coastguard Worker     MCInstLowering.lowerOperand(MI->getOperand(0), Dest);
501*9880d681SAndroid Build Coastguard Worker     MCInst TmpInst;
502*9880d681SAndroid Build Coastguard Worker     TmpInst.setOpcode(AArch64::B);
503*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(Dest);
504*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, TmpInst);
505*9880d681SAndroid Build Coastguard Worker     return;
506*9880d681SAndroid Build Coastguard Worker   }
507*9880d681SAndroid Build Coastguard Worker   case AArch64::TLSDESC_CALLSEQ: {
508*9880d681SAndroid Build Coastguard Worker     /// lower this to:
509*9880d681SAndroid Build Coastguard Worker     ///    adrp  x0, :tlsdesc:var
510*9880d681SAndroid Build Coastguard Worker     ///    ldr   x1, [x0, #:tlsdesc_lo12:var]
511*9880d681SAndroid Build Coastguard Worker     ///    add   x0, x0, #:tlsdesc_lo12:var
512*9880d681SAndroid Build Coastguard Worker     ///    .tlsdesccall var
513*9880d681SAndroid Build Coastguard Worker     ///    blr   x1
514*9880d681SAndroid Build Coastguard Worker     ///    (TPIDR_EL0 offset now in x0)
515*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO_Sym = MI->getOperand(0);
516*9880d681SAndroid Build Coastguard Worker     MachineOperand MO_TLSDESC_LO12(MO_Sym), MO_TLSDESC(MO_Sym);
517*9880d681SAndroid Build Coastguard Worker     MCOperand Sym, SymTLSDescLo12, SymTLSDesc;
518*9880d681SAndroid Build Coastguard Worker     MO_TLSDESC_LO12.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGEOFF |
519*9880d681SAndroid Build Coastguard Worker                                    AArch64II::MO_NC);
520*9880d681SAndroid Build Coastguard Worker     MO_TLSDESC.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGE);
521*9880d681SAndroid Build Coastguard Worker     MCInstLowering.lowerOperand(MO_Sym, Sym);
522*9880d681SAndroid Build Coastguard Worker     MCInstLowering.lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
523*9880d681SAndroid Build Coastguard Worker     MCInstLowering.lowerOperand(MO_TLSDESC, SymTLSDesc);
524*9880d681SAndroid Build Coastguard Worker 
525*9880d681SAndroid Build Coastguard Worker     MCInst Adrp;
526*9880d681SAndroid Build Coastguard Worker     Adrp.setOpcode(AArch64::ADRP);
527*9880d681SAndroid Build Coastguard Worker     Adrp.addOperand(MCOperand::createReg(AArch64::X0));
528*9880d681SAndroid Build Coastguard Worker     Adrp.addOperand(SymTLSDesc);
529*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, Adrp);
530*9880d681SAndroid Build Coastguard Worker 
531*9880d681SAndroid Build Coastguard Worker     MCInst Ldr;
532*9880d681SAndroid Build Coastguard Worker     Ldr.setOpcode(AArch64::LDRXui);
533*9880d681SAndroid Build Coastguard Worker     Ldr.addOperand(MCOperand::createReg(AArch64::X1));
534*9880d681SAndroid Build Coastguard Worker     Ldr.addOperand(MCOperand::createReg(AArch64::X0));
535*9880d681SAndroid Build Coastguard Worker     Ldr.addOperand(SymTLSDescLo12);
536*9880d681SAndroid Build Coastguard Worker     Ldr.addOperand(MCOperand::createImm(0));
537*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, Ldr);
538*9880d681SAndroid Build Coastguard Worker 
539*9880d681SAndroid Build Coastguard Worker     MCInst Add;
540*9880d681SAndroid Build Coastguard Worker     Add.setOpcode(AArch64::ADDXri);
541*9880d681SAndroid Build Coastguard Worker     Add.addOperand(MCOperand::createReg(AArch64::X0));
542*9880d681SAndroid Build Coastguard Worker     Add.addOperand(MCOperand::createReg(AArch64::X0));
543*9880d681SAndroid Build Coastguard Worker     Add.addOperand(SymTLSDescLo12);
544*9880d681SAndroid Build Coastguard Worker     Add.addOperand(MCOperand::createImm(AArch64_AM::getShiftValue(0)));
545*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, Add);
546*9880d681SAndroid Build Coastguard Worker 
547*9880d681SAndroid Build Coastguard Worker     // Emit a relocation-annotation. This expands to no code, but requests
548*9880d681SAndroid Build Coastguard Worker     // the following instruction gets an R_AARCH64_TLSDESC_CALL.
549*9880d681SAndroid Build Coastguard Worker     MCInst TLSDescCall;
550*9880d681SAndroid Build Coastguard Worker     TLSDescCall.setOpcode(AArch64::TLSDESCCALL);
551*9880d681SAndroid Build Coastguard Worker     TLSDescCall.addOperand(Sym);
552*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, TLSDescCall);
553*9880d681SAndroid Build Coastguard Worker 
554*9880d681SAndroid Build Coastguard Worker     MCInst Blr;
555*9880d681SAndroid Build Coastguard Worker     Blr.setOpcode(AArch64::BLR);
556*9880d681SAndroid Build Coastguard Worker     Blr.addOperand(MCOperand::createReg(AArch64::X1));
557*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, Blr);
558*9880d681SAndroid Build Coastguard Worker 
559*9880d681SAndroid Build Coastguard Worker     return;
560*9880d681SAndroid Build Coastguard Worker   }
561*9880d681SAndroid Build Coastguard Worker 
562*9880d681SAndroid Build Coastguard Worker   case AArch64::FMOVS0:
563*9880d681SAndroid Build Coastguard Worker   case AArch64::FMOVD0:
564*9880d681SAndroid Build Coastguard Worker     EmitFMov0(*MI);
565*9880d681SAndroid Build Coastguard Worker     return;
566*9880d681SAndroid Build Coastguard Worker 
567*9880d681SAndroid Build Coastguard Worker   case TargetOpcode::STACKMAP:
568*9880d681SAndroid Build Coastguard Worker     return LowerSTACKMAP(*OutStreamer, SM, *MI);
569*9880d681SAndroid Build Coastguard Worker 
570*9880d681SAndroid Build Coastguard Worker   case TargetOpcode::PATCHPOINT:
571*9880d681SAndroid Build Coastguard Worker     return LowerPATCHPOINT(*OutStreamer, SM, *MI);
572*9880d681SAndroid Build Coastguard Worker   }
573*9880d681SAndroid Build Coastguard Worker 
574*9880d681SAndroid Build Coastguard Worker   // Finally, do the automated lowerings for everything else.
575*9880d681SAndroid Build Coastguard Worker   MCInst TmpInst;
576*9880d681SAndroid Build Coastguard Worker   MCInstLowering.Lower(MI, TmpInst);
577*9880d681SAndroid Build Coastguard Worker   EmitToStreamer(*OutStreamer, TmpInst);
578*9880d681SAndroid Build Coastguard Worker }
579*9880d681SAndroid Build Coastguard Worker 
580*9880d681SAndroid Build Coastguard Worker // Force static initialization.
LLVMInitializeAArch64AsmPrinter()581*9880d681SAndroid Build Coastguard Worker extern "C" void LLVMInitializeAArch64AsmPrinter() {
582*9880d681SAndroid Build Coastguard Worker   RegisterAsmPrinter<AArch64AsmPrinter> X(TheAArch64leTarget);
583*9880d681SAndroid Build Coastguard Worker   RegisterAsmPrinter<AArch64AsmPrinter> Y(TheAArch64beTarget);
584*9880d681SAndroid Build Coastguard Worker   RegisterAsmPrinter<AArch64AsmPrinter> Z(TheARM64Target);
585*9880d681SAndroid Build Coastguard Worker }
586