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