xref: /aosp_15_r20/external/llvm/lib/Target/ARM/ARMAsmPrinter.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
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 GAS-format ARM assembly language.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include "ARMAsmPrinter.h"
16*9880d681SAndroid Build Coastguard Worker #include "ARM.h"
17*9880d681SAndroid Build Coastguard Worker #include "ARMConstantPoolValue.h"
18*9880d681SAndroid Build Coastguard Worker #include "ARMMachineFunctionInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "ARMTargetMachine.h"
20*9880d681SAndroid Build Coastguard Worker #include "ARMTargetObjectFile.h"
21*9880d681SAndroid Build Coastguard Worker #include "InstPrinter/ARMInstPrinter.h"
22*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/ARMAddressingModes.h"
23*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/ARMMCExpr.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SetVector.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallString.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineJumpTableInfo.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineModuleInfoImpls.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DebugInfo.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Mangler.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Type.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAssembler.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCELFStreamer.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstBuilder.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCObjectStreamer.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSectionMachO.h"
43*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h"
44*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h"
45*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ARMBuildAttributes.h"
46*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/COFF.h"
47*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
48*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ELF.h"
49*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
50*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetParser.h"
51*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
52*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
53*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
54*9880d681SAndroid Build Coastguard Worker #include <cctype>
55*9880d681SAndroid Build Coastguard Worker using namespace llvm;
56*9880d681SAndroid Build Coastguard Worker 
57*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "asm-printer"
58*9880d681SAndroid Build Coastguard Worker 
ARMAsmPrinter(TargetMachine & TM,std::unique_ptr<MCStreamer> Streamer)59*9880d681SAndroid Build Coastguard Worker ARMAsmPrinter::ARMAsmPrinter(TargetMachine &TM,
60*9880d681SAndroid Build Coastguard Worker                              std::unique_ptr<MCStreamer> Streamer)
61*9880d681SAndroid Build Coastguard Worker     : AsmPrinter(TM, std::move(Streamer)), AFI(nullptr), MCP(nullptr),
62*9880d681SAndroid Build Coastguard Worker       InConstantPool(false), OptimizationGoals(-1) {}
63*9880d681SAndroid Build Coastguard Worker 
EmitFunctionBodyEnd()64*9880d681SAndroid Build Coastguard Worker void ARMAsmPrinter::EmitFunctionBodyEnd() {
65*9880d681SAndroid Build Coastguard Worker   // Make sure to terminate any constant pools that were at the end
66*9880d681SAndroid Build Coastguard Worker   // of the function.
67*9880d681SAndroid Build Coastguard Worker   if (!InConstantPool)
68*9880d681SAndroid Build Coastguard Worker     return;
69*9880d681SAndroid Build Coastguard Worker   InConstantPool = false;
70*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
71*9880d681SAndroid Build Coastguard Worker }
72*9880d681SAndroid Build Coastguard Worker 
EmitFunctionEntryLabel()73*9880d681SAndroid Build Coastguard Worker void ARMAsmPrinter::EmitFunctionEntryLabel() {
74*9880d681SAndroid Build Coastguard Worker   if (AFI->isThumbFunction()) {
75*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitAssemblerFlag(MCAF_Code16);
76*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitThumbFunc(CurrentFnSym);
77*9880d681SAndroid Build Coastguard Worker   }
78*9880d681SAndroid Build Coastguard Worker 
79*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitLabel(CurrentFnSym);
80*9880d681SAndroid Build Coastguard Worker }
81*9880d681SAndroid Build Coastguard Worker 
EmitXXStructor(const DataLayout & DL,const Constant * CV)82*9880d681SAndroid Build Coastguard Worker void ARMAsmPrinter::EmitXXStructor(const DataLayout &DL, const Constant *CV) {
83*9880d681SAndroid Build Coastguard Worker   uint64_t Size = getDataLayout().getTypeAllocSize(CV->getType());
84*9880d681SAndroid Build Coastguard Worker   assert(Size && "C++ constructor pointer had zero size!");
85*9880d681SAndroid Build Coastguard Worker 
86*9880d681SAndroid Build Coastguard Worker   const GlobalValue *GV = dyn_cast<GlobalValue>(CV->stripPointerCasts());
87*9880d681SAndroid Build Coastguard Worker   assert(GV && "C++ constructor pointer was not a GlobalValue!");
88*9880d681SAndroid Build Coastguard Worker 
89*9880d681SAndroid Build Coastguard Worker   const MCExpr *E = MCSymbolRefExpr::create(GetARMGVSymbol(GV,
90*9880d681SAndroid Build Coastguard Worker                                                            ARMII::MO_NO_FLAG),
91*9880d681SAndroid Build Coastguard Worker                                             (Subtarget->isTargetELF()
92*9880d681SAndroid Build Coastguard Worker                                              ? MCSymbolRefExpr::VK_ARM_TARGET1
93*9880d681SAndroid Build Coastguard Worker                                              : MCSymbolRefExpr::VK_None),
94*9880d681SAndroid Build Coastguard Worker                                             OutContext);
95*9880d681SAndroid Build Coastguard Worker 
96*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitValue(E, Size);
97*9880d681SAndroid Build Coastguard Worker }
98*9880d681SAndroid Build Coastguard Worker 
99*9880d681SAndroid Build Coastguard Worker /// runOnMachineFunction - This uses the EmitInstruction()
100*9880d681SAndroid Build Coastguard Worker /// method to print assembly for each instruction.
101*9880d681SAndroid Build Coastguard Worker ///
runOnMachineFunction(MachineFunction & MF)102*9880d681SAndroid Build Coastguard Worker bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
103*9880d681SAndroid Build Coastguard Worker   AFI = MF.getInfo<ARMFunctionInfo>();
104*9880d681SAndroid Build Coastguard Worker   MCP = MF.getConstantPool();
105*9880d681SAndroid Build Coastguard Worker   Subtarget = &MF.getSubtarget<ARMSubtarget>();
106*9880d681SAndroid Build Coastguard Worker 
107*9880d681SAndroid Build Coastguard Worker   SetupMachineFunction(MF);
108*9880d681SAndroid Build Coastguard Worker   const Function* F = MF.getFunction();
109*9880d681SAndroid Build Coastguard Worker   const TargetMachine& TM = MF.getTarget();
110*9880d681SAndroid Build Coastguard Worker 
111*9880d681SAndroid Build Coastguard Worker   // Calculate this function's optimization goal.
112*9880d681SAndroid Build Coastguard Worker   unsigned OptimizationGoal;
113*9880d681SAndroid Build Coastguard Worker   if (F->hasFnAttribute(Attribute::OptimizeNone))
114*9880d681SAndroid Build Coastguard Worker     // For best debugging illusion, speed and small size sacrificed
115*9880d681SAndroid Build Coastguard Worker     OptimizationGoal = 6;
116*9880d681SAndroid Build Coastguard Worker   else if (F->optForMinSize())
117*9880d681SAndroid Build Coastguard Worker     // Aggressively for small size, speed and debug illusion sacrificed
118*9880d681SAndroid Build Coastguard Worker     OptimizationGoal = 4;
119*9880d681SAndroid Build Coastguard Worker   else if (F->optForSize())
120*9880d681SAndroid Build Coastguard Worker     // For small size, but speed and debugging illusion preserved
121*9880d681SAndroid Build Coastguard Worker     OptimizationGoal = 3;
122*9880d681SAndroid Build Coastguard Worker   else if (TM.getOptLevel() == CodeGenOpt::Aggressive)
123*9880d681SAndroid Build Coastguard Worker     // Aggressively for speed, small size and debug illusion sacrificed
124*9880d681SAndroid Build Coastguard Worker     OptimizationGoal = 2;
125*9880d681SAndroid Build Coastguard Worker   else if (TM.getOptLevel() > CodeGenOpt::None)
126*9880d681SAndroid Build Coastguard Worker     // For speed, but small size and good debug illusion preserved
127*9880d681SAndroid Build Coastguard Worker     OptimizationGoal = 1;
128*9880d681SAndroid Build Coastguard Worker   else // TM.getOptLevel() == CodeGenOpt::None
129*9880d681SAndroid Build Coastguard Worker     // For good debugging, but speed and small size preserved
130*9880d681SAndroid Build Coastguard Worker     OptimizationGoal = 5;
131*9880d681SAndroid Build Coastguard Worker 
132*9880d681SAndroid Build Coastguard Worker   // Combine a new optimization goal with existing ones.
133*9880d681SAndroid Build Coastguard Worker   if (OptimizationGoals == -1) // uninitialized goals
134*9880d681SAndroid Build Coastguard Worker     OptimizationGoals = OptimizationGoal;
135*9880d681SAndroid Build Coastguard Worker   else if (OptimizationGoals != (int)OptimizationGoal) // conflicting goals
136*9880d681SAndroid Build Coastguard Worker     OptimizationGoals = 0;
137*9880d681SAndroid Build Coastguard Worker 
138*9880d681SAndroid Build Coastguard Worker   if (Subtarget->isTargetCOFF()) {
139*9880d681SAndroid Build Coastguard Worker     bool Internal = F->hasInternalLinkage();
140*9880d681SAndroid Build Coastguard Worker     COFF::SymbolStorageClass Scl = Internal ? COFF::IMAGE_SYM_CLASS_STATIC
141*9880d681SAndroid Build Coastguard Worker                                             : COFF::IMAGE_SYM_CLASS_EXTERNAL;
142*9880d681SAndroid Build Coastguard Worker     int Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT;
143*9880d681SAndroid Build Coastguard Worker 
144*9880d681SAndroid Build Coastguard Worker     OutStreamer->BeginCOFFSymbolDef(CurrentFnSym);
145*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitCOFFSymbolStorageClass(Scl);
146*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitCOFFSymbolType(Type);
147*9880d681SAndroid Build Coastguard Worker     OutStreamer->EndCOFFSymbolDef();
148*9880d681SAndroid Build Coastguard Worker   }
149*9880d681SAndroid Build Coastguard Worker 
150*9880d681SAndroid Build Coastguard Worker   // Emit the rest of the function body.
151*9880d681SAndroid Build Coastguard Worker   EmitFunctionBody();
152*9880d681SAndroid Build Coastguard Worker 
153*9880d681SAndroid Build Coastguard Worker   // If we need V4T thumb mode Register Indirect Jump pads, emit them.
154*9880d681SAndroid Build Coastguard Worker   // These are created per function, rather than per TU, since it's
155*9880d681SAndroid Build Coastguard Worker   // relatively easy to exceed the thumb branch range within a TU.
156*9880d681SAndroid Build Coastguard Worker   if (! ThumbIndirectPads.empty()) {
157*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitAssemblerFlag(MCAF_Code16);
158*9880d681SAndroid Build Coastguard Worker     EmitAlignment(1);
159*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = ThumbIndirectPads.size(); i < e; i++) {
160*9880d681SAndroid Build Coastguard Worker       OutStreamer->EmitLabel(ThumbIndirectPads[i].second);
161*9880d681SAndroid Build Coastguard Worker       EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tBX)
162*9880d681SAndroid Build Coastguard Worker         .addReg(ThumbIndirectPads[i].first)
163*9880d681SAndroid Build Coastguard Worker         // Add predicate operands.
164*9880d681SAndroid Build Coastguard Worker         .addImm(ARMCC::AL)
165*9880d681SAndroid Build Coastguard Worker         .addReg(0));
166*9880d681SAndroid Build Coastguard Worker     }
167*9880d681SAndroid Build Coastguard Worker     ThumbIndirectPads.clear();
168*9880d681SAndroid Build Coastguard Worker   }
169*9880d681SAndroid Build Coastguard Worker 
170*9880d681SAndroid Build Coastguard Worker   // We didn't modify anything.
171*9880d681SAndroid Build Coastguard Worker   return false;
172*9880d681SAndroid Build Coastguard Worker }
173*9880d681SAndroid Build Coastguard Worker 
printOperand(const MachineInstr * MI,int OpNum,raw_ostream & O)174*9880d681SAndroid Build Coastguard Worker void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
175*9880d681SAndroid Build Coastguard Worker                                  raw_ostream &O) {
176*9880d681SAndroid Build Coastguard Worker   const MachineOperand &MO = MI->getOperand(OpNum);
177*9880d681SAndroid Build Coastguard Worker   unsigned TF = MO.getTargetFlags();
178*9880d681SAndroid Build Coastguard Worker 
179*9880d681SAndroid Build Coastguard Worker   switch (MO.getType()) {
180*9880d681SAndroid Build Coastguard Worker   default: 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     if(ARM::GPRPairRegClass.contains(Reg)) {
186*9880d681SAndroid Build Coastguard Worker       const MachineFunction &MF = *MI->getParent()->getParent();
187*9880d681SAndroid Build Coastguard Worker       const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
188*9880d681SAndroid Build Coastguard Worker       Reg = TRI->getSubReg(Reg, ARM::gsub_0);
189*9880d681SAndroid Build Coastguard Worker     }
190*9880d681SAndroid Build Coastguard Worker     O << ARMInstPrinter::getRegisterName(Reg);
191*9880d681SAndroid Build Coastguard Worker     break;
192*9880d681SAndroid Build Coastguard Worker   }
193*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_Immediate: {
194*9880d681SAndroid Build Coastguard Worker     int64_t Imm = MO.getImm();
195*9880d681SAndroid Build Coastguard Worker     O << '#';
196*9880d681SAndroid Build Coastguard Worker     if (TF == ARMII::MO_LO16)
197*9880d681SAndroid Build Coastguard Worker       O << ":lower16:";
198*9880d681SAndroid Build Coastguard Worker     else if (TF == ARMII::MO_HI16)
199*9880d681SAndroid Build Coastguard Worker       O << ":upper16:";
200*9880d681SAndroid Build Coastguard Worker     O << Imm;
201*9880d681SAndroid Build Coastguard Worker     break;
202*9880d681SAndroid Build Coastguard Worker   }
203*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_MachineBasicBlock:
204*9880d681SAndroid Build Coastguard Worker     MO.getMBB()->getSymbol()->print(O, MAI);
205*9880d681SAndroid Build Coastguard Worker     return;
206*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_GlobalAddress: {
207*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GV = MO.getGlobal();
208*9880d681SAndroid Build Coastguard Worker     if (TF & ARMII::MO_LO16)
209*9880d681SAndroid Build Coastguard Worker       O << ":lower16:";
210*9880d681SAndroid Build Coastguard Worker     else if (TF & ARMII::MO_HI16)
211*9880d681SAndroid Build Coastguard Worker       O << ":upper16:";
212*9880d681SAndroid Build Coastguard Worker     GetARMGVSymbol(GV, TF)->print(O, MAI);
213*9880d681SAndroid Build Coastguard Worker 
214*9880d681SAndroid Build Coastguard Worker     printOffset(MO.getOffset(), O);
215*9880d681SAndroid Build Coastguard Worker     break;
216*9880d681SAndroid Build Coastguard Worker   }
217*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_ConstantPoolIndex:
218*9880d681SAndroid Build Coastguard Worker     GetCPISymbol(MO.getIndex())->print(O, MAI);
219*9880d681SAndroid Build Coastguard Worker     break;
220*9880d681SAndroid Build Coastguard Worker   }
221*9880d681SAndroid Build Coastguard Worker }
222*9880d681SAndroid Build Coastguard Worker 
223*9880d681SAndroid Build Coastguard Worker //===--------------------------------------------------------------------===//
224*9880d681SAndroid Build Coastguard Worker 
225*9880d681SAndroid Build Coastguard Worker MCSymbol *ARMAsmPrinter::
GetARMJTIPICJumpTableLabel(unsigned uid) const226*9880d681SAndroid Build Coastguard Worker GetARMJTIPICJumpTableLabel(unsigned uid) const {
227*9880d681SAndroid Build Coastguard Worker   const DataLayout &DL = getDataLayout();
228*9880d681SAndroid Build Coastguard Worker   SmallString<60> Name;
229*9880d681SAndroid Build Coastguard Worker   raw_svector_ostream(Name) << DL.getPrivateGlobalPrefix() << "JTI"
230*9880d681SAndroid Build Coastguard Worker                             << getFunctionNumber() << '_' << uid;
231*9880d681SAndroid Build Coastguard Worker   return OutContext.getOrCreateSymbol(Name);
232*9880d681SAndroid Build Coastguard Worker }
233*9880d681SAndroid Build Coastguard Worker 
PrintAsmOperand(const MachineInstr * MI,unsigned OpNum,unsigned AsmVariant,const char * ExtraCode,raw_ostream & O)234*9880d681SAndroid Build Coastguard Worker bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
235*9880d681SAndroid Build Coastguard Worker                                     unsigned AsmVariant, const char *ExtraCode,
236*9880d681SAndroid Build Coastguard Worker                                     raw_ostream &O) {
237*9880d681SAndroid Build Coastguard Worker   // Does this asm operand have a single letter operand modifier?
238*9880d681SAndroid Build Coastguard Worker   if (ExtraCode && ExtraCode[0]) {
239*9880d681SAndroid Build Coastguard Worker     if (ExtraCode[1] != 0) return true; // Unknown modifier.
240*9880d681SAndroid Build Coastguard Worker 
241*9880d681SAndroid Build Coastguard Worker     switch (ExtraCode[0]) {
242*9880d681SAndroid Build Coastguard Worker     default:
243*9880d681SAndroid Build Coastguard Worker       // See if this is a generic print operand
244*9880d681SAndroid Build Coastguard Worker       return AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O);
245*9880d681SAndroid Build Coastguard Worker     case 'a': // Print as a memory address.
246*9880d681SAndroid Build Coastguard Worker       if (MI->getOperand(OpNum).isReg()) {
247*9880d681SAndroid Build Coastguard Worker         O << "["
248*9880d681SAndroid Build Coastguard Worker           << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg())
249*9880d681SAndroid Build Coastguard Worker           << "]";
250*9880d681SAndroid Build Coastguard Worker         return false;
251*9880d681SAndroid Build Coastguard Worker       }
252*9880d681SAndroid Build Coastguard Worker       // Fallthrough
253*9880d681SAndroid Build Coastguard Worker     case 'c': // Don't print "#" before an immediate operand.
254*9880d681SAndroid Build Coastguard Worker       if (!MI->getOperand(OpNum).isImm())
255*9880d681SAndroid Build Coastguard Worker         return true;
256*9880d681SAndroid Build Coastguard Worker       O << MI->getOperand(OpNum).getImm();
257*9880d681SAndroid Build Coastguard Worker       return false;
258*9880d681SAndroid Build Coastguard Worker     case 'P': // Print a VFP double precision register.
259*9880d681SAndroid Build Coastguard Worker     case 'q': // Print a NEON quad precision register.
260*9880d681SAndroid Build Coastguard Worker       printOperand(MI, OpNum, O);
261*9880d681SAndroid Build Coastguard Worker       return false;
262*9880d681SAndroid Build Coastguard Worker     case 'y': // Print a VFP single precision register as indexed double.
263*9880d681SAndroid Build Coastguard Worker       if (MI->getOperand(OpNum).isReg()) {
264*9880d681SAndroid Build Coastguard Worker         unsigned Reg = MI->getOperand(OpNum).getReg();
265*9880d681SAndroid Build Coastguard Worker         const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
266*9880d681SAndroid Build Coastguard Worker         // Find the 'd' register that has this 's' register as a sub-register,
267*9880d681SAndroid Build Coastguard Worker         // and determine the lane number.
268*9880d681SAndroid Build Coastguard Worker         for (MCSuperRegIterator SR(Reg, TRI); SR.isValid(); ++SR) {
269*9880d681SAndroid Build Coastguard Worker           if (!ARM::DPRRegClass.contains(*SR))
270*9880d681SAndroid Build Coastguard Worker             continue;
271*9880d681SAndroid Build Coastguard Worker           bool Lane0 = TRI->getSubReg(*SR, ARM::ssub_0) == Reg;
272*9880d681SAndroid Build Coastguard Worker           O << ARMInstPrinter::getRegisterName(*SR) << (Lane0 ? "[0]" : "[1]");
273*9880d681SAndroid Build Coastguard Worker           return false;
274*9880d681SAndroid Build Coastguard Worker         }
275*9880d681SAndroid Build Coastguard Worker       }
276*9880d681SAndroid Build Coastguard Worker       return true;
277*9880d681SAndroid Build Coastguard Worker     case 'B': // Bitwise inverse of integer or symbol without a preceding #.
278*9880d681SAndroid Build Coastguard Worker       if (!MI->getOperand(OpNum).isImm())
279*9880d681SAndroid Build Coastguard Worker         return true;
280*9880d681SAndroid Build Coastguard Worker       O << ~(MI->getOperand(OpNum).getImm());
281*9880d681SAndroid Build Coastguard Worker       return false;
282*9880d681SAndroid Build Coastguard Worker     case 'L': // The low 16 bits of an immediate constant.
283*9880d681SAndroid Build Coastguard Worker       if (!MI->getOperand(OpNum).isImm())
284*9880d681SAndroid Build Coastguard Worker         return true;
285*9880d681SAndroid Build Coastguard Worker       O << (MI->getOperand(OpNum).getImm() & 0xffff);
286*9880d681SAndroid Build Coastguard Worker       return false;
287*9880d681SAndroid Build Coastguard Worker     case 'M': { // A register range suitable for LDM/STM.
288*9880d681SAndroid Build Coastguard Worker       if (!MI->getOperand(OpNum).isReg())
289*9880d681SAndroid Build Coastguard Worker         return true;
290*9880d681SAndroid Build Coastguard Worker       const MachineOperand &MO = MI->getOperand(OpNum);
291*9880d681SAndroid Build Coastguard Worker       unsigned RegBegin = MO.getReg();
292*9880d681SAndroid Build Coastguard Worker       // This takes advantage of the 2 operand-ness of ldm/stm and that we've
293*9880d681SAndroid Build Coastguard Worker       // already got the operands in registers that are operands to the
294*9880d681SAndroid Build Coastguard Worker       // inline asm statement.
295*9880d681SAndroid Build Coastguard Worker       O << "{";
296*9880d681SAndroid Build Coastguard Worker       if (ARM::GPRPairRegClass.contains(RegBegin)) {
297*9880d681SAndroid Build Coastguard Worker         const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
298*9880d681SAndroid Build Coastguard Worker         unsigned Reg0 = TRI->getSubReg(RegBegin, ARM::gsub_0);
299*9880d681SAndroid Build Coastguard Worker         O << ARMInstPrinter::getRegisterName(Reg0) << ", ";
300*9880d681SAndroid Build Coastguard Worker         RegBegin = TRI->getSubReg(RegBegin, ARM::gsub_1);
301*9880d681SAndroid Build Coastguard Worker       }
302*9880d681SAndroid Build Coastguard Worker       O << ARMInstPrinter::getRegisterName(RegBegin);
303*9880d681SAndroid Build Coastguard Worker 
304*9880d681SAndroid Build Coastguard Worker       // FIXME: The register allocator not only may not have given us the
305*9880d681SAndroid Build Coastguard Worker       // registers in sequence, but may not be in ascending registers. This
306*9880d681SAndroid Build Coastguard Worker       // will require changes in the register allocator that'll need to be
307*9880d681SAndroid Build Coastguard Worker       // propagated down here if the operands change.
308*9880d681SAndroid Build Coastguard Worker       unsigned RegOps = OpNum + 1;
309*9880d681SAndroid Build Coastguard Worker       while (MI->getOperand(RegOps).isReg()) {
310*9880d681SAndroid Build Coastguard Worker         O << ", "
311*9880d681SAndroid Build Coastguard Worker           << ARMInstPrinter::getRegisterName(MI->getOperand(RegOps).getReg());
312*9880d681SAndroid Build Coastguard Worker         RegOps++;
313*9880d681SAndroid Build Coastguard Worker       }
314*9880d681SAndroid Build Coastguard Worker 
315*9880d681SAndroid Build Coastguard Worker       O << "}";
316*9880d681SAndroid Build Coastguard Worker 
317*9880d681SAndroid Build Coastguard Worker       return false;
318*9880d681SAndroid Build Coastguard Worker     }
319*9880d681SAndroid Build Coastguard Worker     case 'R': // The most significant register of a pair.
320*9880d681SAndroid Build Coastguard Worker     case 'Q': { // The least significant register of a pair.
321*9880d681SAndroid Build Coastguard Worker       if (OpNum == 0)
322*9880d681SAndroid Build Coastguard Worker         return true;
323*9880d681SAndroid Build Coastguard Worker       const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
324*9880d681SAndroid Build Coastguard Worker       if (!FlagsOP.isImm())
325*9880d681SAndroid Build Coastguard Worker         return true;
326*9880d681SAndroid Build Coastguard Worker       unsigned Flags = FlagsOP.getImm();
327*9880d681SAndroid Build Coastguard Worker 
328*9880d681SAndroid Build Coastguard Worker       // This operand may not be the one that actually provides the register. If
329*9880d681SAndroid Build Coastguard Worker       // it's tied to a previous one then we should refer instead to that one
330*9880d681SAndroid Build Coastguard Worker       // for registers and their classes.
331*9880d681SAndroid Build Coastguard Worker       unsigned TiedIdx;
332*9880d681SAndroid Build Coastguard Worker       if (InlineAsm::isUseOperandTiedToDef(Flags, TiedIdx)) {
333*9880d681SAndroid Build Coastguard Worker         for (OpNum = InlineAsm::MIOp_FirstOperand; TiedIdx; --TiedIdx) {
334*9880d681SAndroid Build Coastguard Worker           unsigned OpFlags = MI->getOperand(OpNum).getImm();
335*9880d681SAndroid Build Coastguard Worker           OpNum += InlineAsm::getNumOperandRegisters(OpFlags) + 1;
336*9880d681SAndroid Build Coastguard Worker         }
337*9880d681SAndroid Build Coastguard Worker         Flags = MI->getOperand(OpNum).getImm();
338*9880d681SAndroid Build Coastguard Worker 
339*9880d681SAndroid Build Coastguard Worker         // Later code expects OpNum to be pointing at the register rather than
340*9880d681SAndroid Build Coastguard Worker         // the flags.
341*9880d681SAndroid Build Coastguard Worker         OpNum += 1;
342*9880d681SAndroid Build Coastguard Worker       }
343*9880d681SAndroid Build Coastguard Worker 
344*9880d681SAndroid Build Coastguard Worker       unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
345*9880d681SAndroid Build Coastguard Worker       unsigned RC;
346*9880d681SAndroid Build Coastguard Worker       InlineAsm::hasRegClassConstraint(Flags, RC);
347*9880d681SAndroid Build Coastguard Worker       if (RC == ARM::GPRPairRegClassID) {
348*9880d681SAndroid Build Coastguard Worker         if (NumVals != 1)
349*9880d681SAndroid Build Coastguard Worker           return true;
350*9880d681SAndroid Build Coastguard Worker         const MachineOperand &MO = MI->getOperand(OpNum);
351*9880d681SAndroid Build Coastguard Worker         if (!MO.isReg())
352*9880d681SAndroid Build Coastguard Worker           return true;
353*9880d681SAndroid Build Coastguard Worker         const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
354*9880d681SAndroid Build Coastguard Worker         unsigned Reg = TRI->getSubReg(MO.getReg(), ExtraCode[0] == 'Q' ?
355*9880d681SAndroid Build Coastguard Worker             ARM::gsub_0 : ARM::gsub_1);
356*9880d681SAndroid Build Coastguard Worker         O << ARMInstPrinter::getRegisterName(Reg);
357*9880d681SAndroid Build Coastguard Worker         return false;
358*9880d681SAndroid Build Coastguard Worker       }
359*9880d681SAndroid Build Coastguard Worker       if (NumVals != 2)
360*9880d681SAndroid Build Coastguard Worker         return true;
361*9880d681SAndroid Build Coastguard Worker       unsigned RegOp = ExtraCode[0] == 'Q' ? OpNum : OpNum + 1;
362*9880d681SAndroid Build Coastguard Worker       if (RegOp >= MI->getNumOperands())
363*9880d681SAndroid Build Coastguard Worker         return true;
364*9880d681SAndroid Build Coastguard Worker       const MachineOperand &MO = MI->getOperand(RegOp);
365*9880d681SAndroid Build Coastguard Worker       if (!MO.isReg())
366*9880d681SAndroid Build Coastguard Worker         return true;
367*9880d681SAndroid Build Coastguard Worker       unsigned Reg = MO.getReg();
368*9880d681SAndroid Build Coastguard Worker       O << ARMInstPrinter::getRegisterName(Reg);
369*9880d681SAndroid Build Coastguard Worker       return false;
370*9880d681SAndroid Build Coastguard Worker     }
371*9880d681SAndroid Build Coastguard Worker 
372*9880d681SAndroid Build Coastguard Worker     case 'e': // The low doubleword register of a NEON quad register.
373*9880d681SAndroid Build Coastguard Worker     case 'f': { // The high doubleword register of a NEON quad register.
374*9880d681SAndroid Build Coastguard Worker       if (!MI->getOperand(OpNum).isReg())
375*9880d681SAndroid Build Coastguard Worker         return true;
376*9880d681SAndroid Build Coastguard Worker       unsigned Reg = MI->getOperand(OpNum).getReg();
377*9880d681SAndroid Build Coastguard Worker       if (!ARM::QPRRegClass.contains(Reg))
378*9880d681SAndroid Build Coastguard Worker         return true;
379*9880d681SAndroid Build Coastguard Worker       const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
380*9880d681SAndroid Build Coastguard Worker       unsigned SubReg = TRI->getSubReg(Reg, ExtraCode[0] == 'e' ?
381*9880d681SAndroid Build Coastguard Worker                                        ARM::dsub_0 : ARM::dsub_1);
382*9880d681SAndroid Build Coastguard Worker       O << ARMInstPrinter::getRegisterName(SubReg);
383*9880d681SAndroid Build Coastguard Worker       return false;
384*9880d681SAndroid Build Coastguard Worker     }
385*9880d681SAndroid Build Coastguard Worker 
386*9880d681SAndroid Build Coastguard Worker     // This modifier is not yet supported.
387*9880d681SAndroid Build Coastguard Worker     case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1.
388*9880d681SAndroid Build Coastguard Worker       return true;
389*9880d681SAndroid Build Coastguard Worker     case 'H': { // The highest-numbered register of a pair.
390*9880d681SAndroid Build Coastguard Worker       const MachineOperand &MO = MI->getOperand(OpNum);
391*9880d681SAndroid Build Coastguard Worker       if (!MO.isReg())
392*9880d681SAndroid Build Coastguard Worker         return true;
393*9880d681SAndroid Build Coastguard Worker       const MachineFunction &MF = *MI->getParent()->getParent();
394*9880d681SAndroid Build Coastguard Worker       const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
395*9880d681SAndroid Build Coastguard Worker       unsigned Reg = MO.getReg();
396*9880d681SAndroid Build Coastguard Worker       if(!ARM::GPRPairRegClass.contains(Reg))
397*9880d681SAndroid Build Coastguard Worker         return false;
398*9880d681SAndroid Build Coastguard Worker       Reg = TRI->getSubReg(Reg, ARM::gsub_1);
399*9880d681SAndroid Build Coastguard Worker       O << ARMInstPrinter::getRegisterName(Reg);
400*9880d681SAndroid Build Coastguard Worker       return false;
401*9880d681SAndroid Build Coastguard Worker     }
402*9880d681SAndroid Build Coastguard Worker     }
403*9880d681SAndroid Build Coastguard Worker   }
404*9880d681SAndroid Build Coastguard Worker 
405*9880d681SAndroid Build Coastguard Worker   printOperand(MI, OpNum, O);
406*9880d681SAndroid Build Coastguard Worker   return false;
407*9880d681SAndroid Build Coastguard Worker }
408*9880d681SAndroid Build Coastguard Worker 
PrintAsmMemoryOperand(const MachineInstr * MI,unsigned OpNum,unsigned AsmVariant,const char * ExtraCode,raw_ostream & O)409*9880d681SAndroid Build Coastguard Worker bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
410*9880d681SAndroid Build Coastguard Worker                                           unsigned OpNum, unsigned AsmVariant,
411*9880d681SAndroid Build Coastguard Worker                                           const char *ExtraCode,
412*9880d681SAndroid Build Coastguard Worker                                           raw_ostream &O) {
413*9880d681SAndroid Build Coastguard Worker   // Does this asm operand have a single letter operand modifier?
414*9880d681SAndroid Build Coastguard Worker   if (ExtraCode && ExtraCode[0]) {
415*9880d681SAndroid Build Coastguard Worker     if (ExtraCode[1] != 0) return true; // Unknown modifier.
416*9880d681SAndroid Build Coastguard Worker 
417*9880d681SAndroid Build Coastguard Worker     switch (ExtraCode[0]) {
418*9880d681SAndroid Build Coastguard Worker       case 'A': // A memory operand for a VLD1/VST1 instruction.
419*9880d681SAndroid Build Coastguard Worker       default: return true;  // Unknown modifier.
420*9880d681SAndroid Build Coastguard Worker       case 'm': // The base register of a memory operand.
421*9880d681SAndroid Build Coastguard Worker         if (!MI->getOperand(OpNum).isReg())
422*9880d681SAndroid Build Coastguard Worker           return true;
423*9880d681SAndroid Build Coastguard Worker         O << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg());
424*9880d681SAndroid Build Coastguard Worker         return false;
425*9880d681SAndroid Build Coastguard Worker     }
426*9880d681SAndroid Build Coastguard Worker   }
427*9880d681SAndroid Build Coastguard Worker 
428*9880d681SAndroid Build Coastguard Worker   const MachineOperand &MO = MI->getOperand(OpNum);
429*9880d681SAndroid Build Coastguard Worker   assert(MO.isReg() && "unexpected inline asm memory operand");
430*9880d681SAndroid Build Coastguard Worker   O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
431*9880d681SAndroid Build Coastguard Worker   return false;
432*9880d681SAndroid Build Coastguard Worker }
433*9880d681SAndroid Build Coastguard Worker 
isThumb(const MCSubtargetInfo & STI)434*9880d681SAndroid Build Coastguard Worker static bool isThumb(const MCSubtargetInfo& STI) {
435*9880d681SAndroid Build Coastguard Worker   return STI.getFeatureBits()[ARM::ModeThumb];
436*9880d681SAndroid Build Coastguard Worker }
437*9880d681SAndroid Build Coastguard Worker 
emitInlineAsmEnd(const MCSubtargetInfo & StartInfo,const MCSubtargetInfo * EndInfo) const438*9880d681SAndroid Build Coastguard Worker void ARMAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
439*9880d681SAndroid Build Coastguard Worker                                      const MCSubtargetInfo *EndInfo) const {
440*9880d681SAndroid Build Coastguard Worker   // If either end mode is unknown (EndInfo == NULL) or different than
441*9880d681SAndroid Build Coastguard Worker   // the start mode, then restore the start mode.
442*9880d681SAndroid Build Coastguard Worker   const bool WasThumb = isThumb(StartInfo);
443*9880d681SAndroid Build Coastguard Worker   if (!EndInfo || WasThumb != isThumb(*EndInfo)) {
444*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitAssemblerFlag(WasThumb ? MCAF_Code16 : MCAF_Code32);
445*9880d681SAndroid Build Coastguard Worker   }
446*9880d681SAndroid Build Coastguard Worker }
447*9880d681SAndroid Build Coastguard Worker 
EmitStartOfAsmFile(Module & M)448*9880d681SAndroid Build Coastguard Worker void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
449*9880d681SAndroid Build Coastguard Worker   const Triple &TT = TM.getTargetTriple();
450*9880d681SAndroid Build Coastguard Worker   // Use unified assembler syntax.
451*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitAssemblerFlag(MCAF_SyntaxUnified);
452*9880d681SAndroid Build Coastguard Worker 
453*9880d681SAndroid Build Coastguard Worker   // Emit ARM Build Attributes
454*9880d681SAndroid Build Coastguard Worker   if (TT.isOSBinFormatELF())
455*9880d681SAndroid Build Coastguard Worker     emitAttributes();
456*9880d681SAndroid Build Coastguard Worker 
457*9880d681SAndroid Build Coastguard Worker   // Use the triple's architecture and subarchitecture to determine
458*9880d681SAndroid Build Coastguard Worker   // if we're thumb for the purposes of the top level code16 assembler
459*9880d681SAndroid Build Coastguard Worker   // flag.
460*9880d681SAndroid Build Coastguard Worker   bool isThumb = TT.getArch() == Triple::thumb ||
461*9880d681SAndroid Build Coastguard Worker                  TT.getArch() == Triple::thumbeb ||
462*9880d681SAndroid Build Coastguard Worker                  TT.getSubArch() == Triple::ARMSubArch_v7m ||
463*9880d681SAndroid Build Coastguard Worker                  TT.getSubArch() == Triple::ARMSubArch_v6m;
464*9880d681SAndroid Build Coastguard Worker   if (!M.getModuleInlineAsm().empty() && isThumb)
465*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitAssemblerFlag(MCAF_Code16);
466*9880d681SAndroid Build Coastguard Worker }
467*9880d681SAndroid Build Coastguard Worker 
468*9880d681SAndroid Build Coastguard Worker static void
emitNonLazySymbolPointer(MCStreamer & OutStreamer,MCSymbol * StubLabel,MachineModuleInfoImpl::StubValueTy & MCSym)469*9880d681SAndroid Build Coastguard Worker emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel,
470*9880d681SAndroid Build Coastguard Worker                          MachineModuleInfoImpl::StubValueTy &MCSym) {
471*9880d681SAndroid Build Coastguard Worker   // L_foo$stub:
472*9880d681SAndroid Build Coastguard Worker   OutStreamer.EmitLabel(StubLabel);
473*9880d681SAndroid Build Coastguard Worker   //   .indirect_symbol _foo
474*9880d681SAndroid Build Coastguard Worker   OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
475*9880d681SAndroid Build Coastguard Worker 
476*9880d681SAndroid Build Coastguard Worker   if (MCSym.getInt())
477*9880d681SAndroid Build Coastguard Worker     // External to current translation unit.
478*9880d681SAndroid Build Coastguard Worker     OutStreamer.EmitIntValue(0, 4/*size*/);
479*9880d681SAndroid Build Coastguard Worker   else
480*9880d681SAndroid Build Coastguard Worker     // Internal to current translation unit.
481*9880d681SAndroid Build Coastguard Worker     //
482*9880d681SAndroid Build Coastguard Worker     // When we place the LSDA into the TEXT section, the type info
483*9880d681SAndroid Build Coastguard Worker     // pointers need to be indirect and pc-rel. We accomplish this by
484*9880d681SAndroid Build Coastguard Worker     // using NLPs; however, sometimes the types are local to the file.
485*9880d681SAndroid Build Coastguard Worker     // We need to fill in the value for the NLP in those cases.
486*9880d681SAndroid Build Coastguard Worker     OutStreamer.EmitValue(
487*9880d681SAndroid Build Coastguard Worker         MCSymbolRefExpr::create(MCSym.getPointer(), OutStreamer.getContext()),
488*9880d681SAndroid Build Coastguard Worker         4 /*size*/);
489*9880d681SAndroid Build Coastguard Worker }
490*9880d681SAndroid Build Coastguard Worker 
491*9880d681SAndroid Build Coastguard Worker 
EmitEndOfAsmFile(Module & M)492*9880d681SAndroid Build Coastguard Worker void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
493*9880d681SAndroid Build Coastguard Worker   const Triple &TT = TM.getTargetTriple();
494*9880d681SAndroid Build Coastguard Worker   if (TT.isOSBinFormatMachO()) {
495*9880d681SAndroid Build Coastguard Worker     // All darwin targets use mach-o.
496*9880d681SAndroid Build Coastguard Worker     const TargetLoweringObjectFileMachO &TLOFMacho =
497*9880d681SAndroid Build Coastguard Worker       static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
498*9880d681SAndroid Build Coastguard Worker     MachineModuleInfoMachO &MMIMacho =
499*9880d681SAndroid Build Coastguard Worker       MMI->getObjFileInfo<MachineModuleInfoMachO>();
500*9880d681SAndroid Build Coastguard Worker 
501*9880d681SAndroid Build Coastguard Worker     // Output non-lazy-pointers for external and common global variables.
502*9880d681SAndroid Build Coastguard Worker     MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
503*9880d681SAndroid Build Coastguard Worker 
504*9880d681SAndroid Build Coastguard Worker     if (!Stubs.empty()) {
505*9880d681SAndroid Build Coastguard Worker       // Switch with ".non_lazy_symbol_pointer" directive.
506*9880d681SAndroid Build Coastguard Worker       OutStreamer->SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
507*9880d681SAndroid Build Coastguard Worker       EmitAlignment(2);
508*9880d681SAndroid Build Coastguard Worker 
509*9880d681SAndroid Build Coastguard Worker       for (auto &Stub : Stubs)
510*9880d681SAndroid Build Coastguard Worker         emitNonLazySymbolPointer(*OutStreamer, Stub.first, Stub.second);
511*9880d681SAndroid Build Coastguard Worker 
512*9880d681SAndroid Build Coastguard Worker       Stubs.clear();
513*9880d681SAndroid Build Coastguard Worker       OutStreamer->AddBlankLine();
514*9880d681SAndroid Build Coastguard Worker     }
515*9880d681SAndroid Build Coastguard Worker 
516*9880d681SAndroid Build Coastguard Worker     Stubs = MMIMacho.GetThreadLocalGVStubList();
517*9880d681SAndroid Build Coastguard Worker     if (!Stubs.empty()) {
518*9880d681SAndroid Build Coastguard Worker       // Switch with ".non_lazy_symbol_pointer" directive.
519*9880d681SAndroid Build Coastguard Worker       OutStreamer->SwitchSection(TLOFMacho.getThreadLocalPointerSection());
520*9880d681SAndroid Build Coastguard Worker       EmitAlignment(2);
521*9880d681SAndroid Build Coastguard Worker 
522*9880d681SAndroid Build Coastguard Worker       for (auto &Stub : Stubs)
523*9880d681SAndroid Build Coastguard Worker         emitNonLazySymbolPointer(*OutStreamer, Stub.first, Stub.second);
524*9880d681SAndroid Build Coastguard Worker 
525*9880d681SAndroid Build Coastguard Worker       Stubs.clear();
526*9880d681SAndroid Build Coastguard Worker       OutStreamer->AddBlankLine();
527*9880d681SAndroid Build Coastguard Worker     }
528*9880d681SAndroid Build Coastguard Worker 
529*9880d681SAndroid Build Coastguard Worker     // Funny Darwin hack: This flag tells the linker that no global symbols
530*9880d681SAndroid Build Coastguard Worker     // contain code that falls through to other global symbols (e.g. the obvious
531*9880d681SAndroid Build Coastguard Worker     // implementation of multiple entry points).  If this doesn't occur, the
532*9880d681SAndroid Build Coastguard Worker     // linker can safely perform dead code stripping.  Since LLVM never
533*9880d681SAndroid Build Coastguard Worker     // generates code that does this, it is always safe to set.
534*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
535*9880d681SAndroid Build Coastguard Worker   }
536*9880d681SAndroid Build Coastguard Worker 
537*9880d681SAndroid Build Coastguard Worker   if (TT.isOSBinFormatCOFF()) {
538*9880d681SAndroid Build Coastguard Worker     const auto &TLOF =
539*9880d681SAndroid Build Coastguard Worker         static_cast<const TargetLoweringObjectFileCOFF &>(getObjFileLowering());
540*9880d681SAndroid Build Coastguard Worker 
541*9880d681SAndroid Build Coastguard Worker     std::string Flags;
542*9880d681SAndroid Build Coastguard Worker     raw_string_ostream OS(Flags);
543*9880d681SAndroid Build Coastguard Worker 
544*9880d681SAndroid Build Coastguard Worker     for (const auto &Function : M)
545*9880d681SAndroid Build Coastguard Worker       TLOF.emitLinkerFlagsForGlobal(OS, &Function, *Mang);
546*9880d681SAndroid Build Coastguard Worker     for (const auto &Global : M.globals())
547*9880d681SAndroid Build Coastguard Worker       TLOF.emitLinkerFlagsForGlobal(OS, &Global, *Mang);
548*9880d681SAndroid Build Coastguard Worker     for (const auto &Alias : M.aliases())
549*9880d681SAndroid Build Coastguard Worker       TLOF.emitLinkerFlagsForGlobal(OS, &Alias, *Mang);
550*9880d681SAndroid Build Coastguard Worker 
551*9880d681SAndroid Build Coastguard Worker     OS.flush();
552*9880d681SAndroid Build Coastguard Worker 
553*9880d681SAndroid Build Coastguard Worker     // Output collected flags
554*9880d681SAndroid Build Coastguard Worker     if (!Flags.empty()) {
555*9880d681SAndroid Build Coastguard Worker       OutStreamer->SwitchSection(TLOF.getDrectveSection());
556*9880d681SAndroid Build Coastguard Worker       OutStreamer->EmitBytes(Flags);
557*9880d681SAndroid Build Coastguard Worker     }
558*9880d681SAndroid Build Coastguard Worker   }
559*9880d681SAndroid Build Coastguard Worker 
560*9880d681SAndroid Build Coastguard Worker   // The last attribute to be emitted is ABI_optimization_goals
561*9880d681SAndroid Build Coastguard Worker   MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
562*9880d681SAndroid Build Coastguard Worker   ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
563*9880d681SAndroid Build Coastguard Worker 
564*9880d681SAndroid Build Coastguard Worker   if (OptimizationGoals > 0 &&
565*9880d681SAndroid Build Coastguard Worker       (Subtarget->isTargetAEABI() || Subtarget->isTargetGNUAEABI() ||
566*9880d681SAndroid Build Coastguard Worker        Subtarget->isTargetMuslAEABI()))
567*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::ABI_optimization_goals, OptimizationGoals);
568*9880d681SAndroid Build Coastguard Worker   OptimizationGoals = -1;
569*9880d681SAndroid Build Coastguard Worker 
570*9880d681SAndroid Build Coastguard Worker   ATS.finishAttributeSection();
571*9880d681SAndroid Build Coastguard Worker }
572*9880d681SAndroid Build Coastguard Worker 
isV8M(const ARMSubtarget * Subtarget)573*9880d681SAndroid Build Coastguard Worker static bool isV8M(const ARMSubtarget *Subtarget) {
574*9880d681SAndroid Build Coastguard Worker   // Note that v8M Baseline is a subset of v6T2!
575*9880d681SAndroid Build Coastguard Worker   return (Subtarget->hasV8MBaselineOps() && !Subtarget->hasV6T2Ops()) ||
576*9880d681SAndroid Build Coastguard Worker          Subtarget->hasV8MMainlineOps();
577*9880d681SAndroid Build Coastguard Worker }
578*9880d681SAndroid Build Coastguard Worker 
579*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
580*9880d681SAndroid Build Coastguard Worker // Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile()
581*9880d681SAndroid Build Coastguard Worker // FIXME:
582*9880d681SAndroid Build Coastguard Worker // The following seem like one-off assembler flags, but they actually need
583*9880d681SAndroid Build Coastguard Worker // to appear in the .ARM.attributes section in ELF.
584*9880d681SAndroid Build Coastguard Worker // Instead of subclassing the MCELFStreamer, we do the work here.
585*9880d681SAndroid Build Coastguard Worker 
getArchForCPU(StringRef CPU,const ARMSubtarget * Subtarget)586*9880d681SAndroid Build Coastguard Worker static ARMBuildAttrs::CPUArch getArchForCPU(StringRef CPU,
587*9880d681SAndroid Build Coastguard Worker                                             const ARMSubtarget *Subtarget) {
588*9880d681SAndroid Build Coastguard Worker   if (CPU == "xscale")
589*9880d681SAndroid Build Coastguard Worker     return ARMBuildAttrs::v5TEJ;
590*9880d681SAndroid Build Coastguard Worker 
591*9880d681SAndroid Build Coastguard Worker   if (Subtarget->hasV8Ops())
592*9880d681SAndroid Build Coastguard Worker     return ARMBuildAttrs::v8_A;
593*9880d681SAndroid Build Coastguard Worker   else if (Subtarget->hasV8MMainlineOps())
594*9880d681SAndroid Build Coastguard Worker     return ARMBuildAttrs::v8_M_Main;
595*9880d681SAndroid Build Coastguard Worker   else if (Subtarget->hasV7Ops()) {
596*9880d681SAndroid Build Coastguard Worker     if (Subtarget->isMClass() && Subtarget->hasDSP())
597*9880d681SAndroid Build Coastguard Worker       return ARMBuildAttrs::v7E_M;
598*9880d681SAndroid Build Coastguard Worker     return ARMBuildAttrs::v7;
599*9880d681SAndroid Build Coastguard Worker   } else if (Subtarget->hasV6T2Ops())
600*9880d681SAndroid Build Coastguard Worker     return ARMBuildAttrs::v6T2;
601*9880d681SAndroid Build Coastguard Worker   else if (Subtarget->hasV8MBaselineOps())
602*9880d681SAndroid Build Coastguard Worker     return ARMBuildAttrs::v8_M_Base;
603*9880d681SAndroid Build Coastguard Worker   else if (Subtarget->hasV6MOps())
604*9880d681SAndroid Build Coastguard Worker     return ARMBuildAttrs::v6S_M;
605*9880d681SAndroid Build Coastguard Worker   else if (Subtarget->hasV6Ops())
606*9880d681SAndroid Build Coastguard Worker     return ARMBuildAttrs::v6;
607*9880d681SAndroid Build Coastguard Worker   else if (Subtarget->hasV5TEOps())
608*9880d681SAndroid Build Coastguard Worker     return ARMBuildAttrs::v5TE;
609*9880d681SAndroid Build Coastguard Worker   else if (Subtarget->hasV5TOps())
610*9880d681SAndroid Build Coastguard Worker     return ARMBuildAttrs::v5T;
611*9880d681SAndroid Build Coastguard Worker   else if (Subtarget->hasV4TOps())
612*9880d681SAndroid Build Coastguard Worker     return ARMBuildAttrs::v4T;
613*9880d681SAndroid Build Coastguard Worker   else
614*9880d681SAndroid Build Coastguard Worker     return ARMBuildAttrs::v4;
615*9880d681SAndroid Build Coastguard Worker }
616*9880d681SAndroid Build Coastguard Worker 
emitAttributes()617*9880d681SAndroid Build Coastguard Worker void ARMAsmPrinter::emitAttributes() {
618*9880d681SAndroid Build Coastguard Worker   MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
619*9880d681SAndroid Build Coastguard Worker   ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
620*9880d681SAndroid Build Coastguard Worker 
621*9880d681SAndroid Build Coastguard Worker   ATS.emitTextAttribute(ARMBuildAttrs::conformance, "2.09");
622*9880d681SAndroid Build Coastguard Worker 
623*9880d681SAndroid Build Coastguard Worker   ATS.switchVendor("aeabi");
624*9880d681SAndroid Build Coastguard Worker 
625*9880d681SAndroid Build Coastguard Worker   // Compute ARM ELF Attributes based on the default subtarget that
626*9880d681SAndroid Build Coastguard Worker   // we'd have constructed. The existing ARM behavior isn't LTO clean
627*9880d681SAndroid Build Coastguard Worker   // anyhow.
628*9880d681SAndroid Build Coastguard Worker   // FIXME: For ifunc related functions we could iterate over and look
629*9880d681SAndroid Build Coastguard Worker   // for a feature string that doesn't match the default one.
630*9880d681SAndroid Build Coastguard Worker   const Triple &TT = TM.getTargetTriple();
631*9880d681SAndroid Build Coastguard Worker   StringRef CPU = TM.getTargetCPU();
632*9880d681SAndroid Build Coastguard Worker   StringRef FS = TM.getTargetFeatureString();
633*9880d681SAndroid Build Coastguard Worker   std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
634*9880d681SAndroid Build Coastguard Worker   if (!FS.empty()) {
635*9880d681SAndroid Build Coastguard Worker     if (!ArchFS.empty())
636*9880d681SAndroid Build Coastguard Worker       ArchFS = (Twine(ArchFS) + "," + FS).str();
637*9880d681SAndroid Build Coastguard Worker     else
638*9880d681SAndroid Build Coastguard Worker       ArchFS = FS;
639*9880d681SAndroid Build Coastguard Worker   }
640*9880d681SAndroid Build Coastguard Worker   const ARMBaseTargetMachine &ATM =
641*9880d681SAndroid Build Coastguard Worker       static_cast<const ARMBaseTargetMachine &>(TM);
642*9880d681SAndroid Build Coastguard Worker   const ARMSubtarget STI(TT, CPU, ArchFS, ATM, ATM.isLittleEndian());
643*9880d681SAndroid Build Coastguard Worker 
644*9880d681SAndroid Build Coastguard Worker   const std::string &CPUString = STI.getCPUString();
645*9880d681SAndroid Build Coastguard Worker 
646*9880d681SAndroid Build Coastguard Worker   if (!StringRef(CPUString).startswith("generic")) {
647*9880d681SAndroid Build Coastguard Worker     // FIXME: remove krait check when GNU tools support krait cpu
648*9880d681SAndroid Build Coastguard Worker     if (STI.isKrait()) {
649*9880d681SAndroid Build Coastguard Worker       ATS.emitTextAttribute(ARMBuildAttrs::CPU_name, "cortex-a9");
650*9880d681SAndroid Build Coastguard Worker       // We consider krait as a "cortex-a9" + hwdiv CPU
651*9880d681SAndroid Build Coastguard Worker       // Enable hwdiv through ".arch_extension idiv"
652*9880d681SAndroid Build Coastguard Worker       if (STI.hasDivide() || STI.hasDivideInARMMode())
653*9880d681SAndroid Build Coastguard Worker         ATS.emitArchExtension(ARM::AEK_HWDIV | ARM::AEK_HWDIVARM);
654*9880d681SAndroid Build Coastguard Worker     } else
655*9880d681SAndroid Build Coastguard Worker       ATS.emitTextAttribute(ARMBuildAttrs::CPU_name, CPUString);
656*9880d681SAndroid Build Coastguard Worker   }
657*9880d681SAndroid Build Coastguard Worker 
658*9880d681SAndroid Build Coastguard Worker   ATS.emitAttribute(ARMBuildAttrs::CPU_arch, getArchForCPU(CPUString, &STI));
659*9880d681SAndroid Build Coastguard Worker 
660*9880d681SAndroid Build Coastguard Worker   // Tag_CPU_arch_profile must have the default value of 0 when "Architecture
661*9880d681SAndroid Build Coastguard Worker   // profile is not applicable (e.g. pre v7, or cross-profile code)".
662*9880d681SAndroid Build Coastguard Worker   if (STI.hasV7Ops() || isV8M(&STI)) {
663*9880d681SAndroid Build Coastguard Worker     if (STI.isAClass()) {
664*9880d681SAndroid Build Coastguard Worker       ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,
665*9880d681SAndroid Build Coastguard Worker                         ARMBuildAttrs::ApplicationProfile);
666*9880d681SAndroid Build Coastguard Worker     } else if (STI.isRClass()) {
667*9880d681SAndroid Build Coastguard Worker       ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,
668*9880d681SAndroid Build Coastguard Worker                         ARMBuildAttrs::RealTimeProfile);
669*9880d681SAndroid Build Coastguard Worker     } else if (STI.isMClass()) {
670*9880d681SAndroid Build Coastguard Worker       ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,
671*9880d681SAndroid Build Coastguard Worker                         ARMBuildAttrs::MicroControllerProfile);
672*9880d681SAndroid Build Coastguard Worker     }
673*9880d681SAndroid Build Coastguard Worker   }
674*9880d681SAndroid Build Coastguard Worker 
675*9880d681SAndroid Build Coastguard Worker   ATS.emitAttribute(ARMBuildAttrs::ARM_ISA_use,
676*9880d681SAndroid Build Coastguard Worker                     STI.hasARMOps() ? ARMBuildAttrs::Allowed
677*9880d681SAndroid Build Coastguard Worker                                     : ARMBuildAttrs::Not_Allowed);
678*9880d681SAndroid Build Coastguard Worker   if (isV8M(&STI)) {
679*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use,
680*9880d681SAndroid Build Coastguard Worker                       ARMBuildAttrs::AllowThumbDerived);
681*9880d681SAndroid Build Coastguard Worker   } else if (STI.isThumb1Only()) {
682*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use, ARMBuildAttrs::Allowed);
683*9880d681SAndroid Build Coastguard Worker   } else if (STI.hasThumb2()) {
684*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use,
685*9880d681SAndroid Build Coastguard Worker                       ARMBuildAttrs::AllowThumb32);
686*9880d681SAndroid Build Coastguard Worker   }
687*9880d681SAndroid Build Coastguard Worker 
688*9880d681SAndroid Build Coastguard Worker   if (STI.hasNEON()) {
689*9880d681SAndroid Build Coastguard Worker     /* NEON is not exactly a VFP architecture, but GAS emit one of
690*9880d681SAndroid Build Coastguard Worker      * neon/neon-fp-armv8/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */
691*9880d681SAndroid Build Coastguard Worker     if (STI.hasFPARMv8()) {
692*9880d681SAndroid Build Coastguard Worker       if (STI.hasCrypto())
693*9880d681SAndroid Build Coastguard Worker         ATS.emitFPU(ARM::FK_CRYPTO_NEON_FP_ARMV8);
694*9880d681SAndroid Build Coastguard Worker       else
695*9880d681SAndroid Build Coastguard Worker         ATS.emitFPU(ARM::FK_NEON_FP_ARMV8);
696*9880d681SAndroid Build Coastguard Worker     } else if (STI.hasVFP4())
697*9880d681SAndroid Build Coastguard Worker       ATS.emitFPU(ARM::FK_NEON_VFPV4);
698*9880d681SAndroid Build Coastguard Worker     else
699*9880d681SAndroid Build Coastguard Worker       ATS.emitFPU(STI.hasFP16() ? ARM::FK_NEON_FP16 : ARM::FK_NEON);
700*9880d681SAndroid Build Coastguard Worker     // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture
701*9880d681SAndroid Build Coastguard Worker     if (STI.hasV8Ops())
702*9880d681SAndroid Build Coastguard Worker       ATS.emitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
703*9880d681SAndroid Build Coastguard Worker                         STI.hasV8_1aOps() ? ARMBuildAttrs::AllowNeonARMv8_1a:
704*9880d681SAndroid Build Coastguard Worker                                             ARMBuildAttrs::AllowNeonARMv8);
705*9880d681SAndroid Build Coastguard Worker   } else {
706*9880d681SAndroid Build Coastguard Worker     if (STI.hasFPARMv8())
707*9880d681SAndroid Build Coastguard Worker       // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one
708*9880d681SAndroid Build Coastguard Worker       // FPU, but there are two different names for it depending on the CPU.
709*9880d681SAndroid Build Coastguard Worker       ATS.emitFPU(STI.hasD16()
710*9880d681SAndroid Build Coastguard Worker                   ? (STI.isFPOnlySP() ? ARM::FK_FPV5_SP_D16 : ARM::FK_FPV5_D16)
711*9880d681SAndroid Build Coastguard Worker                   : ARM::FK_FP_ARMV8);
712*9880d681SAndroid Build Coastguard Worker     else if (STI.hasVFP4())
713*9880d681SAndroid Build Coastguard Worker       ATS.emitFPU(STI.hasD16()
714*9880d681SAndroid Build Coastguard Worker                   ? (STI.isFPOnlySP() ? ARM::FK_FPV4_SP_D16 : ARM::FK_VFPV4_D16)
715*9880d681SAndroid Build Coastguard Worker                   : ARM::FK_VFPV4);
716*9880d681SAndroid Build Coastguard Worker     else if (STI.hasVFP3())
717*9880d681SAndroid Build Coastguard Worker       ATS.emitFPU(STI.hasD16()
718*9880d681SAndroid Build Coastguard Worker                   // +d16
719*9880d681SAndroid Build Coastguard Worker                   ? (STI.isFPOnlySP()
720*9880d681SAndroid Build Coastguard Worker                      ? (STI.hasFP16() ? ARM::FK_VFPV3XD_FP16 : ARM::FK_VFPV3XD)
721*9880d681SAndroid Build Coastguard Worker                      : (STI.hasFP16() ? ARM::FK_VFPV3_D16_FP16 : ARM::FK_VFPV3_D16))
722*9880d681SAndroid Build Coastguard Worker                   // -d16
723*9880d681SAndroid Build Coastguard Worker                   : (STI.hasFP16() ? ARM::FK_VFPV3_FP16 : ARM::FK_VFPV3));
724*9880d681SAndroid Build Coastguard Worker     else if (STI.hasVFP2())
725*9880d681SAndroid Build Coastguard Worker       ATS.emitFPU(ARM::FK_VFPV2);
726*9880d681SAndroid Build Coastguard Worker   }
727*9880d681SAndroid Build Coastguard Worker 
728*9880d681SAndroid Build Coastguard Worker   if (isPositionIndependent()) {
729*9880d681SAndroid Build Coastguard Worker     // PIC specific attributes.
730*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_RW_data,
731*9880d681SAndroid Build Coastguard Worker                       ARMBuildAttrs::AddressRWPCRel);
732*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_RO_data,
733*9880d681SAndroid Build Coastguard Worker                       ARMBuildAttrs::AddressROPCRel);
734*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_GOT_use,
735*9880d681SAndroid Build Coastguard Worker                       ARMBuildAttrs::AddressGOT);
736*9880d681SAndroid Build Coastguard Worker   } else {
737*9880d681SAndroid Build Coastguard Worker     // Allow direct addressing of imported data for all other relocation models.
738*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_GOT_use,
739*9880d681SAndroid Build Coastguard Worker                       ARMBuildAttrs::AddressDirect);
740*9880d681SAndroid Build Coastguard Worker   }
741*9880d681SAndroid Build Coastguard Worker 
742*9880d681SAndroid Build Coastguard Worker   // Signal various FP modes.
743*9880d681SAndroid Build Coastguard Worker   if (!TM.Options.UnsafeFPMath) {
744*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
745*9880d681SAndroid Build Coastguard Worker                       ARMBuildAttrs::IEEEDenormals);
746*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions, ARMBuildAttrs::Allowed);
747*9880d681SAndroid Build Coastguard Worker 
748*9880d681SAndroid Build Coastguard Worker     // If the user has permitted this code to choose the IEEE 754
749*9880d681SAndroid Build Coastguard Worker     // rounding at run-time, emit the rounding attribute.
750*9880d681SAndroid Build Coastguard Worker     if (TM.Options.HonorSignDependentRoundingFPMathOption)
751*9880d681SAndroid Build Coastguard Worker       ATS.emitAttribute(ARMBuildAttrs::ABI_FP_rounding, ARMBuildAttrs::Allowed);
752*9880d681SAndroid Build Coastguard Worker   } else {
753*9880d681SAndroid Build Coastguard Worker     if (!STI.hasVFP2()) {
754*9880d681SAndroid Build Coastguard Worker       // When the target doesn't have an FPU (by design or
755*9880d681SAndroid Build Coastguard Worker       // intention), the assumptions made on the software support
756*9880d681SAndroid Build Coastguard Worker       // mirror that of the equivalent hardware support *if it
757*9880d681SAndroid Build Coastguard Worker       // existed*. For v7 and better we indicate that denormals are
758*9880d681SAndroid Build Coastguard Worker       // flushed preserving sign, and for V6 we indicate that
759*9880d681SAndroid Build Coastguard Worker       // denormals are flushed to positive zero.
760*9880d681SAndroid Build Coastguard Worker       if (STI.hasV7Ops())
761*9880d681SAndroid Build Coastguard Worker         ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
762*9880d681SAndroid Build Coastguard Worker                           ARMBuildAttrs::PreserveFPSign);
763*9880d681SAndroid Build Coastguard Worker     } else if (STI.hasVFP3()) {
764*9880d681SAndroid Build Coastguard Worker       // In VFPv4, VFPv4U, VFPv3, or VFPv3U, it is preserved. That is,
765*9880d681SAndroid Build Coastguard Worker       // the sign bit of the zero matches the sign bit of the input or
766*9880d681SAndroid Build Coastguard Worker       // result that is being flushed to zero.
767*9880d681SAndroid Build Coastguard Worker       ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
768*9880d681SAndroid Build Coastguard Worker                         ARMBuildAttrs::PreserveFPSign);
769*9880d681SAndroid Build Coastguard Worker     }
770*9880d681SAndroid Build Coastguard Worker     // For VFPv2 implementations it is implementation defined as
771*9880d681SAndroid Build Coastguard Worker     // to whether denormals are flushed to positive zero or to
772*9880d681SAndroid Build Coastguard Worker     // whatever the sign of zero is (ARM v7AR ARM 2.7.5). Historically
773*9880d681SAndroid Build Coastguard Worker     // LLVM has chosen to flush this to positive zero (most likely for
774*9880d681SAndroid Build Coastguard Worker     // GCC compatibility), so that's the chosen value here (the
775*9880d681SAndroid Build Coastguard Worker     // absence of its emission implies zero).
776*9880d681SAndroid Build Coastguard Worker   }
777*9880d681SAndroid Build Coastguard Worker 
778*9880d681SAndroid Build Coastguard Worker   // TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath is the
779*9880d681SAndroid Build Coastguard Worker   // equivalent of GCC's -ffinite-math-only flag.
780*9880d681SAndroid Build Coastguard Worker   if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath)
781*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model,
782*9880d681SAndroid Build Coastguard Worker                       ARMBuildAttrs::Allowed);
783*9880d681SAndroid Build Coastguard Worker   else
784*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model,
785*9880d681SAndroid Build Coastguard Worker                       ARMBuildAttrs::AllowIEE754);
786*9880d681SAndroid Build Coastguard Worker 
787*9880d681SAndroid Build Coastguard Worker   if (STI.allowsUnalignedMem())
788*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::CPU_unaligned_access,
789*9880d681SAndroid Build Coastguard Worker                       ARMBuildAttrs::Allowed);
790*9880d681SAndroid Build Coastguard Worker   else
791*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::CPU_unaligned_access,
792*9880d681SAndroid Build Coastguard Worker                       ARMBuildAttrs::Not_Allowed);
793*9880d681SAndroid Build Coastguard Worker 
794*9880d681SAndroid Build Coastguard Worker   // FIXME: add more flags to ARMBuildAttributes.h
795*9880d681SAndroid Build Coastguard Worker   // 8-bytes alignment stuff.
796*9880d681SAndroid Build Coastguard Worker   ATS.emitAttribute(ARMBuildAttrs::ABI_align_needed, 1);
797*9880d681SAndroid Build Coastguard Worker   ATS.emitAttribute(ARMBuildAttrs::ABI_align_preserved, 1);
798*9880d681SAndroid Build Coastguard Worker 
799*9880d681SAndroid Build Coastguard Worker   // ABI_HardFP_use attribute to indicate single precision FP.
800*9880d681SAndroid Build Coastguard Worker   if (STI.isFPOnlySP())
801*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::ABI_HardFP_use,
802*9880d681SAndroid Build Coastguard Worker                       ARMBuildAttrs::HardFPSinglePrecision);
803*9880d681SAndroid Build Coastguard Worker 
804*9880d681SAndroid Build Coastguard Worker   // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
805*9880d681SAndroid Build Coastguard Worker   if (STI.isAAPCS_ABI() && TM.Options.FloatABIType == FloatABI::Hard)
806*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::ABI_VFP_args, ARMBuildAttrs::HardFPAAPCS);
807*9880d681SAndroid Build Coastguard Worker 
808*9880d681SAndroid Build Coastguard Worker   // FIXME: Should we signal R9 usage?
809*9880d681SAndroid Build Coastguard Worker 
810*9880d681SAndroid Build Coastguard Worker   if (STI.hasFP16())
811*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP);
812*9880d681SAndroid Build Coastguard Worker 
813*9880d681SAndroid Build Coastguard Worker   // FIXME: To support emitting this build attribute as GCC does, the
814*9880d681SAndroid Build Coastguard Worker   // -mfp16-format option and associated plumbing must be
815*9880d681SAndroid Build Coastguard Worker   // supported. For now the __fp16 type is exposed by default, so this
816*9880d681SAndroid Build Coastguard Worker   // attribute should be emitted with value 1.
817*9880d681SAndroid Build Coastguard Worker   ATS.emitAttribute(ARMBuildAttrs::ABI_FP_16bit_format,
818*9880d681SAndroid Build Coastguard Worker                     ARMBuildAttrs::FP16FormatIEEE);
819*9880d681SAndroid Build Coastguard Worker 
820*9880d681SAndroid Build Coastguard Worker   if (STI.hasMPExtension())
821*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::MPextension_use, ARMBuildAttrs::AllowMP);
822*9880d681SAndroid Build Coastguard Worker 
823*9880d681SAndroid Build Coastguard Worker   // Hardware divide in ARM mode is part of base arch, starting from ARMv8.
824*9880d681SAndroid Build Coastguard Worker   // If only Thumb hwdiv is present, it must also be in base arch (ARMv7-R/M).
825*9880d681SAndroid Build Coastguard Worker   // It is not possible to produce DisallowDIV: if hwdiv is present in the base
826*9880d681SAndroid Build Coastguard Worker   // arch, supplying -hwdiv downgrades the effective arch, via ClearImpliedBits.
827*9880d681SAndroid Build Coastguard Worker   // AllowDIVExt is only emitted if hwdiv isn't available in the base arch;
828*9880d681SAndroid Build Coastguard Worker   // otherwise, the default value (AllowDIVIfExists) applies.
829*9880d681SAndroid Build Coastguard Worker   if (STI.hasDivideInARMMode() && !STI.hasV8Ops())
830*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::DIV_use, ARMBuildAttrs::AllowDIVExt);
831*9880d681SAndroid Build Coastguard Worker 
832*9880d681SAndroid Build Coastguard Worker   if (STI.hasDSP() && isV8M(&STI))
833*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::DSP_extension, ARMBuildAttrs::Allowed);
834*9880d681SAndroid Build Coastguard Worker 
835*9880d681SAndroid Build Coastguard Worker   if (MMI) {
836*9880d681SAndroid Build Coastguard Worker     if (const Module *SourceModule = MMI->getModule()) {
837*9880d681SAndroid Build Coastguard Worker       // ABI_PCS_wchar_t to indicate wchar_t width
838*9880d681SAndroid Build Coastguard Worker       // FIXME: There is no way to emit value 0 (wchar_t prohibited).
839*9880d681SAndroid Build Coastguard Worker       if (auto WCharWidthValue = mdconst::extract_or_null<ConstantInt>(
840*9880d681SAndroid Build Coastguard Worker               SourceModule->getModuleFlag("wchar_size"))) {
841*9880d681SAndroid Build Coastguard Worker         int WCharWidth = WCharWidthValue->getZExtValue();
842*9880d681SAndroid Build Coastguard Worker         assert((WCharWidth == 2 || WCharWidth == 4) &&
843*9880d681SAndroid Build Coastguard Worker                "wchar_t width must be 2 or 4 bytes");
844*9880d681SAndroid Build Coastguard Worker         ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_wchar_t, WCharWidth);
845*9880d681SAndroid Build Coastguard Worker       }
846*9880d681SAndroid Build Coastguard Worker 
847*9880d681SAndroid Build Coastguard Worker       // ABI_enum_size to indicate enum width
848*9880d681SAndroid Build Coastguard Worker       // FIXME: There is no way to emit value 0 (enums prohibited) or value 3
849*9880d681SAndroid Build Coastguard Worker       //        (all enums contain a value needing 32 bits to encode).
850*9880d681SAndroid Build Coastguard Worker       if (auto EnumWidthValue = mdconst::extract_or_null<ConstantInt>(
851*9880d681SAndroid Build Coastguard Worker               SourceModule->getModuleFlag("min_enum_size"))) {
852*9880d681SAndroid Build Coastguard Worker         int EnumWidth = EnumWidthValue->getZExtValue();
853*9880d681SAndroid Build Coastguard Worker         assert((EnumWidth == 1 || EnumWidth == 4) &&
854*9880d681SAndroid Build Coastguard Worker                "Minimum enum width must be 1 or 4 bytes");
855*9880d681SAndroid Build Coastguard Worker         int EnumBuildAttr = EnumWidth == 1 ? 1 : 2;
856*9880d681SAndroid Build Coastguard Worker         ATS.emitAttribute(ARMBuildAttrs::ABI_enum_size, EnumBuildAttr);
857*9880d681SAndroid Build Coastguard Worker       }
858*9880d681SAndroid Build Coastguard Worker     }
859*9880d681SAndroid Build Coastguard Worker   }
860*9880d681SAndroid Build Coastguard Worker 
861*9880d681SAndroid Build Coastguard Worker   // TODO: We currently only support either reserving the register, or treating
862*9880d681SAndroid Build Coastguard Worker   // it as another callee-saved register, but not as SB or a TLS pointer; It
863*9880d681SAndroid Build Coastguard Worker   // would instead be nicer to push this from the frontend as metadata, as we do
864*9880d681SAndroid Build Coastguard Worker   // for the wchar and enum size tags
865*9880d681SAndroid Build Coastguard Worker   if (STI.isR9Reserved())
866*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use, ARMBuildAttrs::R9Reserved);
867*9880d681SAndroid Build Coastguard Worker   else
868*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use, ARMBuildAttrs::R9IsGPR);
869*9880d681SAndroid Build Coastguard Worker 
870*9880d681SAndroid Build Coastguard Worker   if (STI.hasTrustZone() && STI.hasVirtualization())
871*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::Virtualization_use,
872*9880d681SAndroid Build Coastguard Worker                       ARMBuildAttrs::AllowTZVirtualization);
873*9880d681SAndroid Build Coastguard Worker   else if (STI.hasTrustZone())
874*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::Virtualization_use,
875*9880d681SAndroid Build Coastguard Worker                       ARMBuildAttrs::AllowTZ);
876*9880d681SAndroid Build Coastguard Worker   else if (STI.hasVirtualization())
877*9880d681SAndroid Build Coastguard Worker     ATS.emitAttribute(ARMBuildAttrs::Virtualization_use,
878*9880d681SAndroid Build Coastguard Worker                       ARMBuildAttrs::AllowVirtualization);
879*9880d681SAndroid Build Coastguard Worker }
880*9880d681SAndroid Build Coastguard Worker 
881*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
882*9880d681SAndroid Build Coastguard Worker 
getPICLabel(const char * Prefix,unsigned FunctionNumber,unsigned LabelId,MCContext & Ctx)883*9880d681SAndroid Build Coastguard Worker static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
884*9880d681SAndroid Build Coastguard Worker                              unsigned LabelId, MCContext &Ctx) {
885*9880d681SAndroid Build Coastguard Worker 
886*9880d681SAndroid Build Coastguard Worker   MCSymbol *Label = Ctx.getOrCreateSymbol(Twine(Prefix)
887*9880d681SAndroid Build Coastguard Worker                        + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
888*9880d681SAndroid Build Coastguard Worker   return Label;
889*9880d681SAndroid Build Coastguard Worker }
890*9880d681SAndroid Build Coastguard Worker 
891*9880d681SAndroid Build Coastguard Worker static MCSymbolRefExpr::VariantKind
getModifierVariantKind(ARMCP::ARMCPModifier Modifier)892*9880d681SAndroid Build Coastguard Worker getModifierVariantKind(ARMCP::ARMCPModifier Modifier) {
893*9880d681SAndroid Build Coastguard Worker   switch (Modifier) {
894*9880d681SAndroid Build Coastguard Worker   case ARMCP::no_modifier:
895*9880d681SAndroid Build Coastguard Worker     return MCSymbolRefExpr::VK_None;
896*9880d681SAndroid Build Coastguard Worker   case ARMCP::TLSGD:
897*9880d681SAndroid Build Coastguard Worker     return MCSymbolRefExpr::VK_TLSGD;
898*9880d681SAndroid Build Coastguard Worker   case ARMCP::TPOFF:
899*9880d681SAndroid Build Coastguard Worker     return MCSymbolRefExpr::VK_TPOFF;
900*9880d681SAndroid Build Coastguard Worker   case ARMCP::GOTTPOFF:
901*9880d681SAndroid Build Coastguard Worker     return MCSymbolRefExpr::VK_GOTTPOFF;
902*9880d681SAndroid Build Coastguard Worker   case ARMCP::GOT_PREL:
903*9880d681SAndroid Build Coastguard Worker     return MCSymbolRefExpr::VK_ARM_GOT_PREL;
904*9880d681SAndroid Build Coastguard Worker   case ARMCP::SECREL:
905*9880d681SAndroid Build Coastguard Worker     return MCSymbolRefExpr::VK_SECREL;
906*9880d681SAndroid Build Coastguard Worker   }
907*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Invalid ARMCPModifier!");
908*9880d681SAndroid Build Coastguard Worker }
909*9880d681SAndroid Build Coastguard Worker 
GetARMGVSymbol(const GlobalValue * GV,unsigned char TargetFlags)910*9880d681SAndroid Build Coastguard Worker MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV,
911*9880d681SAndroid Build Coastguard Worker                                         unsigned char TargetFlags) {
912*9880d681SAndroid Build Coastguard Worker   if (Subtarget->isTargetMachO()) {
913*9880d681SAndroid Build Coastguard Worker     bool IsIndirect =
914*9880d681SAndroid Build Coastguard Worker         (TargetFlags & ARMII::MO_NONLAZY) && Subtarget->isGVIndirectSymbol(GV);
915*9880d681SAndroid Build Coastguard Worker 
916*9880d681SAndroid Build Coastguard Worker     if (!IsIndirect)
917*9880d681SAndroid Build Coastguard Worker       return getSymbol(GV);
918*9880d681SAndroid Build Coastguard Worker 
919*9880d681SAndroid Build Coastguard Worker     // FIXME: Remove this when Darwin transition to @GOT like syntax.
920*9880d681SAndroid Build Coastguard Worker     MCSymbol *MCSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
921*9880d681SAndroid Build Coastguard Worker     MachineModuleInfoMachO &MMIMachO =
922*9880d681SAndroid Build Coastguard Worker       MMI->getObjFileInfo<MachineModuleInfoMachO>();
923*9880d681SAndroid Build Coastguard Worker     MachineModuleInfoImpl::StubValueTy &StubSym =
924*9880d681SAndroid Build Coastguard Worker         GV->isThreadLocal() ? MMIMachO.getThreadLocalGVStubEntry(MCSym)
925*9880d681SAndroid Build Coastguard Worker                             : MMIMachO.getGVStubEntry(MCSym);
926*9880d681SAndroid Build Coastguard Worker 
927*9880d681SAndroid Build Coastguard Worker     if (!StubSym.getPointer())
928*9880d681SAndroid Build Coastguard Worker       StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV),
929*9880d681SAndroid Build Coastguard Worker                                                    !GV->hasInternalLinkage());
930*9880d681SAndroid Build Coastguard Worker     return MCSym;
931*9880d681SAndroid Build Coastguard Worker   } else if (Subtarget->isTargetCOFF()) {
932*9880d681SAndroid Build Coastguard Worker     assert(Subtarget->isTargetWindows() &&
933*9880d681SAndroid Build Coastguard Worker            "Windows is the only supported COFF target");
934*9880d681SAndroid Build Coastguard Worker 
935*9880d681SAndroid Build Coastguard Worker     bool IsIndirect = (TargetFlags & ARMII::MO_DLLIMPORT);
936*9880d681SAndroid Build Coastguard Worker     if (!IsIndirect)
937*9880d681SAndroid Build Coastguard Worker       return getSymbol(GV);
938*9880d681SAndroid Build Coastguard Worker 
939*9880d681SAndroid Build Coastguard Worker     SmallString<128> Name;
940*9880d681SAndroid Build Coastguard Worker     Name = "__imp_";
941*9880d681SAndroid Build Coastguard Worker     getNameWithPrefix(Name, GV);
942*9880d681SAndroid Build Coastguard Worker 
943*9880d681SAndroid Build Coastguard Worker     return OutContext.getOrCreateSymbol(Name);
944*9880d681SAndroid Build Coastguard Worker   } else if (Subtarget->isTargetELF()) {
945*9880d681SAndroid Build Coastguard Worker     return getSymbol(GV);
946*9880d681SAndroid Build Coastguard Worker   }
947*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("unexpected target");
948*9880d681SAndroid Build Coastguard Worker }
949*9880d681SAndroid Build Coastguard Worker 
950*9880d681SAndroid Build Coastguard Worker void ARMAsmPrinter::
EmitMachineConstantPoolValue(MachineConstantPoolValue * MCPV)951*9880d681SAndroid Build Coastguard Worker EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
952*9880d681SAndroid Build Coastguard Worker   const DataLayout &DL = getDataLayout();
953*9880d681SAndroid Build Coastguard Worker   int Size = DL.getTypeAllocSize(MCPV->getType());
954*9880d681SAndroid Build Coastguard Worker 
955*9880d681SAndroid Build Coastguard Worker   ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
956*9880d681SAndroid Build Coastguard Worker 
957*9880d681SAndroid Build Coastguard Worker   MCSymbol *MCSym;
958*9880d681SAndroid Build Coastguard Worker   if (ACPV->isLSDA()) {
959*9880d681SAndroid Build Coastguard Worker     MCSym = getCurExceptionSym();
960*9880d681SAndroid Build Coastguard Worker   } else if (ACPV->isBlockAddress()) {
961*9880d681SAndroid Build Coastguard Worker     const BlockAddress *BA =
962*9880d681SAndroid Build Coastguard Worker       cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress();
963*9880d681SAndroid Build Coastguard Worker     MCSym = GetBlockAddressSymbol(BA);
964*9880d681SAndroid Build Coastguard Worker   } else if (ACPV->isGlobalValue()) {
965*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV();
966*9880d681SAndroid Build Coastguard Worker 
967*9880d681SAndroid Build Coastguard Worker     // On Darwin, const-pool entries may get the "FOO$non_lazy_ptr" mangling, so
968*9880d681SAndroid Build Coastguard Worker     // flag the global as MO_NONLAZY.
969*9880d681SAndroid Build Coastguard Worker     unsigned char TF = Subtarget->isTargetMachO() ? ARMII::MO_NONLAZY : 0;
970*9880d681SAndroid Build Coastguard Worker     MCSym = GetARMGVSymbol(GV, TF);
971*9880d681SAndroid Build Coastguard Worker   } else if (ACPV->isMachineBasicBlock()) {
972*9880d681SAndroid Build Coastguard Worker     const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB();
973*9880d681SAndroid Build Coastguard Worker     MCSym = MBB->getSymbol();
974*9880d681SAndroid Build Coastguard Worker   } else {
975*9880d681SAndroid Build Coastguard Worker     assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
976*9880d681SAndroid Build Coastguard Worker     const char *Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol();
977*9880d681SAndroid Build Coastguard Worker     MCSym = GetExternalSymbolSymbol(Sym);
978*9880d681SAndroid Build Coastguard Worker   }
979*9880d681SAndroid Build Coastguard Worker 
980*9880d681SAndroid Build Coastguard Worker   // Create an MCSymbol for the reference.
981*9880d681SAndroid Build Coastguard Worker   const MCExpr *Expr =
982*9880d681SAndroid Build Coastguard Worker     MCSymbolRefExpr::create(MCSym, getModifierVariantKind(ACPV->getModifier()),
983*9880d681SAndroid Build Coastguard Worker                             OutContext);
984*9880d681SAndroid Build Coastguard Worker 
985*9880d681SAndroid Build Coastguard Worker   if (ACPV->getPCAdjustment()) {
986*9880d681SAndroid Build Coastguard Worker     MCSymbol *PCLabel =
987*9880d681SAndroid Build Coastguard Worker         getPICLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(),
988*9880d681SAndroid Build Coastguard Worker                     ACPV->getLabelId(), OutContext);
989*9880d681SAndroid Build Coastguard Worker     const MCExpr *PCRelExpr = MCSymbolRefExpr::create(PCLabel, OutContext);
990*9880d681SAndroid Build Coastguard Worker     PCRelExpr =
991*9880d681SAndroid Build Coastguard Worker       MCBinaryExpr::createAdd(PCRelExpr,
992*9880d681SAndroid Build Coastguard Worker                               MCConstantExpr::create(ACPV->getPCAdjustment(),
993*9880d681SAndroid Build Coastguard Worker                                                      OutContext),
994*9880d681SAndroid Build Coastguard Worker                               OutContext);
995*9880d681SAndroid Build Coastguard Worker     if (ACPV->mustAddCurrentAddress()) {
996*9880d681SAndroid Build Coastguard Worker       // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
997*9880d681SAndroid Build Coastguard Worker       // label, so just emit a local label end reference that instead.
998*9880d681SAndroid Build Coastguard Worker       MCSymbol *DotSym = OutContext.createTempSymbol();
999*9880d681SAndroid Build Coastguard Worker       OutStreamer->EmitLabel(DotSym);
1000*9880d681SAndroid Build Coastguard Worker       const MCExpr *DotExpr = MCSymbolRefExpr::create(DotSym, OutContext);
1001*9880d681SAndroid Build Coastguard Worker       PCRelExpr = MCBinaryExpr::createSub(PCRelExpr, DotExpr, OutContext);
1002*9880d681SAndroid Build Coastguard Worker     }
1003*9880d681SAndroid Build Coastguard Worker     Expr = MCBinaryExpr::createSub(Expr, PCRelExpr, OutContext);
1004*9880d681SAndroid Build Coastguard Worker   }
1005*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitValue(Expr, Size);
1006*9880d681SAndroid Build Coastguard Worker }
1007*9880d681SAndroid Build Coastguard Worker 
EmitJumpTableAddrs(const MachineInstr * MI)1008*9880d681SAndroid Build Coastguard Worker void ARMAsmPrinter::EmitJumpTableAddrs(const MachineInstr *MI) {
1009*9880d681SAndroid Build Coastguard Worker   const MachineOperand &MO1 = MI->getOperand(1);
1010*9880d681SAndroid Build Coastguard Worker   unsigned JTI = MO1.getIndex();
1011*9880d681SAndroid Build Coastguard Worker 
1012*9880d681SAndroid Build Coastguard Worker   // Make sure the Thumb jump table is 4-byte aligned. This will be a nop for
1013*9880d681SAndroid Build Coastguard Worker   // ARM mode tables.
1014*9880d681SAndroid Build Coastguard Worker   EmitAlignment(2);
1015*9880d681SAndroid Build Coastguard Worker 
1016*9880d681SAndroid Build Coastguard Worker   // Emit a label for the jump table.
1017*9880d681SAndroid Build Coastguard Worker   MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);
1018*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitLabel(JTISymbol);
1019*9880d681SAndroid Build Coastguard Worker 
1020*9880d681SAndroid Build Coastguard Worker   // Mark the jump table as data-in-code.
1021*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitDataRegion(MCDR_DataRegionJT32);
1022*9880d681SAndroid Build Coastguard Worker 
1023*9880d681SAndroid Build Coastguard Worker   // Emit each entry of the table.
1024*9880d681SAndroid Build Coastguard Worker   const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1025*9880d681SAndroid Build Coastguard Worker   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1026*9880d681SAndroid Build Coastguard Worker   const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1027*9880d681SAndroid Build Coastguard Worker 
1028*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
1029*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *MBB = JTBBs[i];
1030*9880d681SAndroid Build Coastguard Worker     // Construct an MCExpr for the entry. We want a value of the form:
1031*9880d681SAndroid Build Coastguard Worker     // (BasicBlockAddr - TableBeginAddr)
1032*9880d681SAndroid Build Coastguard Worker     //
1033*9880d681SAndroid Build Coastguard Worker     // For example, a table with entries jumping to basic blocks BB0 and BB1
1034*9880d681SAndroid Build Coastguard Worker     // would look like:
1035*9880d681SAndroid Build Coastguard Worker     // LJTI_0_0:
1036*9880d681SAndroid Build Coastguard Worker     //    .word (LBB0 - LJTI_0_0)
1037*9880d681SAndroid Build Coastguard Worker     //    .word (LBB1 - LJTI_0_0)
1038*9880d681SAndroid Build Coastguard Worker     const MCExpr *Expr = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext);
1039*9880d681SAndroid Build Coastguard Worker 
1040*9880d681SAndroid Build Coastguard Worker     if (isPositionIndependent())
1041*9880d681SAndroid Build Coastguard Worker       Expr = MCBinaryExpr::createSub(Expr, MCSymbolRefExpr::create(JTISymbol,
1042*9880d681SAndroid Build Coastguard Worker                                                                    OutContext),
1043*9880d681SAndroid Build Coastguard Worker                                      OutContext);
1044*9880d681SAndroid Build Coastguard Worker     // If we're generating a table of Thumb addresses in static relocation
1045*9880d681SAndroid Build Coastguard Worker     // model, we need to add one to keep interworking correctly.
1046*9880d681SAndroid Build Coastguard Worker     else if (AFI->isThumbFunction())
1047*9880d681SAndroid Build Coastguard Worker       Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(1,OutContext),
1048*9880d681SAndroid Build Coastguard Worker                                      OutContext);
1049*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitValue(Expr, 4);
1050*9880d681SAndroid Build Coastguard Worker   }
1051*9880d681SAndroid Build Coastguard Worker   // Mark the end of jump table data-in-code region.
1052*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
1053*9880d681SAndroid Build Coastguard Worker }
1054*9880d681SAndroid Build Coastguard Worker 
EmitJumpTableInsts(const MachineInstr * MI)1055*9880d681SAndroid Build Coastguard Worker void ARMAsmPrinter::EmitJumpTableInsts(const MachineInstr *MI) {
1056*9880d681SAndroid Build Coastguard Worker   const MachineOperand &MO1 = MI->getOperand(1);
1057*9880d681SAndroid Build Coastguard Worker   unsigned JTI = MO1.getIndex();
1058*9880d681SAndroid Build Coastguard Worker 
1059*9880d681SAndroid Build Coastguard Worker   MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);
1060*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitLabel(JTISymbol);
1061*9880d681SAndroid Build Coastguard Worker 
1062*9880d681SAndroid Build Coastguard Worker   // Emit each entry of the table.
1063*9880d681SAndroid Build Coastguard Worker   const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1064*9880d681SAndroid Build Coastguard Worker   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1065*9880d681SAndroid Build Coastguard Worker   const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1066*9880d681SAndroid Build Coastguard Worker 
1067*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
1068*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *MBB = JTBBs[i];
1069*9880d681SAndroid Build Coastguard Worker     const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::create(MBB->getSymbol(),
1070*9880d681SAndroid Build Coastguard Worker                                                           OutContext);
1071*9880d681SAndroid Build Coastguard Worker     // If this isn't a TBB or TBH, the entries are direct branch instructions.
1072*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2B)
1073*9880d681SAndroid Build Coastguard Worker         .addExpr(MBBSymbolExpr)
1074*9880d681SAndroid Build Coastguard Worker         .addImm(ARMCC::AL)
1075*9880d681SAndroid Build Coastguard Worker         .addReg(0));
1076*9880d681SAndroid Build Coastguard Worker   }
1077*9880d681SAndroid Build Coastguard Worker }
1078*9880d681SAndroid Build Coastguard Worker 
EmitJumpTableTBInst(const MachineInstr * MI,unsigned OffsetWidth)1079*9880d681SAndroid Build Coastguard Worker void ARMAsmPrinter::EmitJumpTableTBInst(const MachineInstr *MI,
1080*9880d681SAndroid Build Coastguard Worker                                         unsigned OffsetWidth) {
1081*9880d681SAndroid Build Coastguard Worker   assert((OffsetWidth == 1 || OffsetWidth == 2) && "invalid tbb/tbh width");
1082*9880d681SAndroid Build Coastguard Worker   const MachineOperand &MO1 = MI->getOperand(1);
1083*9880d681SAndroid Build Coastguard Worker   unsigned JTI = MO1.getIndex();
1084*9880d681SAndroid Build Coastguard Worker 
1085*9880d681SAndroid Build Coastguard Worker   MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);
1086*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitLabel(JTISymbol);
1087*9880d681SAndroid Build Coastguard Worker 
1088*9880d681SAndroid Build Coastguard Worker   // Emit each entry of the table.
1089*9880d681SAndroid Build Coastguard Worker   const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1090*9880d681SAndroid Build Coastguard Worker   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1091*9880d681SAndroid Build Coastguard Worker   const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1092*9880d681SAndroid Build Coastguard Worker 
1093*9880d681SAndroid Build Coastguard Worker   // Mark the jump table as data-in-code.
1094*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitDataRegion(OffsetWidth == 1 ? MCDR_DataRegionJT8
1095*9880d681SAndroid Build Coastguard Worker                                                : MCDR_DataRegionJT16);
1096*9880d681SAndroid Build Coastguard Worker 
1097*9880d681SAndroid Build Coastguard Worker   for (auto MBB : JTBBs) {
1098*9880d681SAndroid Build Coastguard Worker     const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::create(MBB->getSymbol(),
1099*9880d681SAndroid Build Coastguard Worker                                                           OutContext);
1100*9880d681SAndroid Build Coastguard Worker     // Otherwise it's an offset from the dispatch instruction. Construct an
1101*9880d681SAndroid Build Coastguard Worker     // MCExpr for the entry. We want a value of the form:
1102*9880d681SAndroid Build Coastguard Worker     // (BasicBlockAddr - TBBInstAddr + 4) / 2
1103*9880d681SAndroid Build Coastguard Worker     //
1104*9880d681SAndroid Build Coastguard Worker     // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
1105*9880d681SAndroid Build Coastguard Worker     // would look like:
1106*9880d681SAndroid Build Coastguard Worker     // LJTI_0_0:
1107*9880d681SAndroid Build Coastguard Worker     //    .byte (LBB0 - (LCPI0_0 + 4)) / 2
1108*9880d681SAndroid Build Coastguard Worker     //    .byte (LBB1 - (LCPI0_0 + 4)) / 2
1109*9880d681SAndroid Build Coastguard Worker     // where LCPI0_0 is a label defined just before the TBB instruction using
1110*9880d681SAndroid Build Coastguard Worker     // this table.
1111*9880d681SAndroid Build Coastguard Worker     MCSymbol *TBInstPC = GetCPISymbol(MI->getOperand(0).getImm());
1112*9880d681SAndroid Build Coastguard Worker     const MCExpr *Expr = MCBinaryExpr::createAdd(
1113*9880d681SAndroid Build Coastguard Worker         MCSymbolRefExpr::create(TBInstPC, OutContext),
1114*9880d681SAndroid Build Coastguard Worker         MCConstantExpr::create(4, OutContext), OutContext);
1115*9880d681SAndroid Build Coastguard Worker     Expr = MCBinaryExpr::createSub(MBBSymbolExpr, Expr, OutContext);
1116*9880d681SAndroid Build Coastguard Worker     Expr = MCBinaryExpr::createDiv(Expr, MCConstantExpr::create(2, OutContext),
1117*9880d681SAndroid Build Coastguard Worker                                    OutContext);
1118*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitValue(Expr, OffsetWidth);
1119*9880d681SAndroid Build Coastguard Worker   }
1120*9880d681SAndroid Build Coastguard Worker   // Mark the end of jump table data-in-code region. 32-bit offsets use
1121*9880d681SAndroid Build Coastguard Worker   // actual branch instructions here, so we don't mark those as a data-region
1122*9880d681SAndroid Build Coastguard Worker   // at all.
1123*9880d681SAndroid Build Coastguard Worker   OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
1124*9880d681SAndroid Build Coastguard Worker 
1125*9880d681SAndroid Build Coastguard Worker   // Make sure the next instruction is 2-byte aligned.
1126*9880d681SAndroid Build Coastguard Worker   EmitAlignment(1);
1127*9880d681SAndroid Build Coastguard Worker }
1128*9880d681SAndroid Build Coastguard Worker 
EmitUnwindingInstruction(const MachineInstr * MI)1129*9880d681SAndroid Build Coastguard Worker void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
1130*9880d681SAndroid Build Coastguard Worker   assert(MI->getFlag(MachineInstr::FrameSetup) &&
1131*9880d681SAndroid Build Coastguard Worker       "Only instruction which are involved into frame setup code are allowed");
1132*9880d681SAndroid Build Coastguard Worker 
1133*9880d681SAndroid Build Coastguard Worker   MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
1134*9880d681SAndroid Build Coastguard Worker   ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1135*9880d681SAndroid Build Coastguard Worker   const MachineFunction &MF = *MI->getParent()->getParent();
1136*9880d681SAndroid Build Coastguard Worker   const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
1137*9880d681SAndroid Build Coastguard Worker   const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>();
1138*9880d681SAndroid Build Coastguard Worker 
1139*9880d681SAndroid Build Coastguard Worker   unsigned FramePtr = RegInfo->getFrameRegister(MF);
1140*9880d681SAndroid Build Coastguard Worker   unsigned Opc = MI->getOpcode();
1141*9880d681SAndroid Build Coastguard Worker   unsigned SrcReg, DstReg;
1142*9880d681SAndroid Build Coastguard Worker 
1143*9880d681SAndroid Build Coastguard Worker   if (Opc == ARM::tPUSH || Opc == ARM::tLDRpci) {
1144*9880d681SAndroid Build Coastguard Worker     // Two special cases:
1145*9880d681SAndroid Build Coastguard Worker     // 1) tPUSH does not have src/dst regs.
1146*9880d681SAndroid Build Coastguard Worker     // 2) for Thumb1 code we sometimes materialize the constant via constpool
1147*9880d681SAndroid Build Coastguard Worker     // load. Yes, this is pretty fragile, but for now I don't see better
1148*9880d681SAndroid Build Coastguard Worker     // way... :(
1149*9880d681SAndroid Build Coastguard Worker     SrcReg = DstReg = ARM::SP;
1150*9880d681SAndroid Build Coastguard Worker   } else {
1151*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(1).getReg();
1152*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
1153*9880d681SAndroid Build Coastguard Worker   }
1154*9880d681SAndroid Build Coastguard Worker 
1155*9880d681SAndroid Build Coastguard Worker   // Try to figure out the unwinding opcode out of src / dst regs.
1156*9880d681SAndroid Build Coastguard Worker   if (MI->mayStore()) {
1157*9880d681SAndroid Build Coastguard Worker     // Register saves.
1158*9880d681SAndroid Build Coastguard Worker     assert(DstReg == ARM::SP &&
1159*9880d681SAndroid Build Coastguard Worker            "Only stack pointer as a destination reg is supported");
1160*9880d681SAndroid Build Coastguard Worker 
1161*9880d681SAndroid Build Coastguard Worker     SmallVector<unsigned, 4> RegList;
1162*9880d681SAndroid Build Coastguard Worker     // Skip src & dst reg, and pred ops.
1163*9880d681SAndroid Build Coastguard Worker     unsigned StartOp = 2 + 2;
1164*9880d681SAndroid Build Coastguard Worker     // Use all the operands.
1165*9880d681SAndroid Build Coastguard Worker     unsigned NumOffset = 0;
1166*9880d681SAndroid Build Coastguard Worker 
1167*9880d681SAndroid Build Coastguard Worker     switch (Opc) {
1168*9880d681SAndroid Build Coastguard Worker     default:
1169*9880d681SAndroid Build Coastguard Worker       MI->dump();
1170*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Unsupported opcode for unwinding information");
1171*9880d681SAndroid Build Coastguard Worker     case ARM::tPUSH:
1172*9880d681SAndroid Build Coastguard Worker       // Special case here: no src & dst reg, but two extra imp ops.
1173*9880d681SAndroid Build Coastguard Worker       StartOp = 2; NumOffset = 2;
1174*9880d681SAndroid Build Coastguard Worker     case ARM::STMDB_UPD:
1175*9880d681SAndroid Build Coastguard Worker     case ARM::t2STMDB_UPD:
1176*9880d681SAndroid Build Coastguard Worker     case ARM::VSTMDDB_UPD:
1177*9880d681SAndroid Build Coastguard Worker       assert(SrcReg == ARM::SP &&
1178*9880d681SAndroid Build Coastguard Worker              "Only stack pointer as a source reg is supported");
1179*9880d681SAndroid Build Coastguard Worker       for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset;
1180*9880d681SAndroid Build Coastguard Worker            i != NumOps; ++i) {
1181*9880d681SAndroid Build Coastguard Worker         const MachineOperand &MO = MI->getOperand(i);
1182*9880d681SAndroid Build Coastguard Worker         // Actually, there should never be any impdef stuff here. Skip it
1183*9880d681SAndroid Build Coastguard Worker         // temporary to workaround PR11902.
1184*9880d681SAndroid Build Coastguard Worker         if (MO.isImplicit())
1185*9880d681SAndroid Build Coastguard Worker           continue;
1186*9880d681SAndroid Build Coastguard Worker         RegList.push_back(MO.getReg());
1187*9880d681SAndroid Build Coastguard Worker       }
1188*9880d681SAndroid Build Coastguard Worker       break;
1189*9880d681SAndroid Build Coastguard Worker     case ARM::STR_PRE_IMM:
1190*9880d681SAndroid Build Coastguard Worker     case ARM::STR_PRE_REG:
1191*9880d681SAndroid Build Coastguard Worker     case ARM::t2STR_PRE:
1192*9880d681SAndroid Build Coastguard Worker       assert(MI->getOperand(2).getReg() == ARM::SP &&
1193*9880d681SAndroid Build Coastguard Worker              "Only stack pointer as a source reg is supported");
1194*9880d681SAndroid Build Coastguard Worker       RegList.push_back(SrcReg);
1195*9880d681SAndroid Build Coastguard Worker       break;
1196*9880d681SAndroid Build Coastguard Worker     }
1197*9880d681SAndroid Build Coastguard Worker     if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
1198*9880d681SAndroid Build Coastguard Worker       ATS.emitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);
1199*9880d681SAndroid Build Coastguard Worker   } else {
1200*9880d681SAndroid Build Coastguard Worker     // Changes of stack / frame pointer.
1201*9880d681SAndroid Build Coastguard Worker     if (SrcReg == ARM::SP) {
1202*9880d681SAndroid Build Coastguard Worker       int64_t Offset = 0;
1203*9880d681SAndroid Build Coastguard Worker       switch (Opc) {
1204*9880d681SAndroid Build Coastguard Worker       default:
1205*9880d681SAndroid Build Coastguard Worker         MI->dump();
1206*9880d681SAndroid Build Coastguard Worker         llvm_unreachable("Unsupported opcode for unwinding information");
1207*9880d681SAndroid Build Coastguard Worker       case ARM::MOVr:
1208*9880d681SAndroid Build Coastguard Worker       case ARM::tMOVr:
1209*9880d681SAndroid Build Coastguard Worker         Offset = 0;
1210*9880d681SAndroid Build Coastguard Worker         break;
1211*9880d681SAndroid Build Coastguard Worker       case ARM::ADDri:
1212*9880d681SAndroid Build Coastguard Worker       case ARM::t2ADDri:
1213*9880d681SAndroid Build Coastguard Worker         Offset = -MI->getOperand(2).getImm();
1214*9880d681SAndroid Build Coastguard Worker         break;
1215*9880d681SAndroid Build Coastguard Worker       case ARM::SUBri:
1216*9880d681SAndroid Build Coastguard Worker       case ARM::t2SUBri:
1217*9880d681SAndroid Build Coastguard Worker         Offset = MI->getOperand(2).getImm();
1218*9880d681SAndroid Build Coastguard Worker         break;
1219*9880d681SAndroid Build Coastguard Worker       case ARM::tSUBspi:
1220*9880d681SAndroid Build Coastguard Worker         Offset = MI->getOperand(2).getImm()*4;
1221*9880d681SAndroid Build Coastguard Worker         break;
1222*9880d681SAndroid Build Coastguard Worker       case ARM::tADDspi:
1223*9880d681SAndroid Build Coastguard Worker       case ARM::tADDrSPi:
1224*9880d681SAndroid Build Coastguard Worker         Offset = -MI->getOperand(2).getImm()*4;
1225*9880d681SAndroid Build Coastguard Worker         break;
1226*9880d681SAndroid Build Coastguard Worker       case ARM::tLDRpci: {
1227*9880d681SAndroid Build Coastguard Worker         // Grab the constpool index and check, whether it corresponds to
1228*9880d681SAndroid Build Coastguard Worker         // original or cloned constpool entry.
1229*9880d681SAndroid Build Coastguard Worker         unsigned CPI = MI->getOperand(1).getIndex();
1230*9880d681SAndroid Build Coastguard Worker         const MachineConstantPool *MCP = MF.getConstantPool();
1231*9880d681SAndroid Build Coastguard Worker         if (CPI >= MCP->getConstants().size())
1232*9880d681SAndroid Build Coastguard Worker           CPI = AFI.getOriginalCPIdx(CPI);
1233*9880d681SAndroid Build Coastguard Worker         assert(CPI != -1U && "Invalid constpool index");
1234*9880d681SAndroid Build Coastguard Worker 
1235*9880d681SAndroid Build Coastguard Worker         // Derive the actual offset.
1236*9880d681SAndroid Build Coastguard Worker         const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI];
1237*9880d681SAndroid Build Coastguard Worker         assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry");
1238*9880d681SAndroid Build Coastguard Worker         // FIXME: Check for user, it should be "add" instruction!
1239*9880d681SAndroid Build Coastguard Worker         Offset = -cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue();
1240*9880d681SAndroid Build Coastguard Worker         break;
1241*9880d681SAndroid Build Coastguard Worker       }
1242*9880d681SAndroid Build Coastguard Worker       }
1243*9880d681SAndroid Build Coastguard Worker 
1244*9880d681SAndroid Build Coastguard Worker       if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM) {
1245*9880d681SAndroid Build Coastguard Worker         if (DstReg == FramePtr && FramePtr != ARM::SP)
1246*9880d681SAndroid Build Coastguard Worker           // Set-up of the frame pointer. Positive values correspond to "add"
1247*9880d681SAndroid Build Coastguard Worker           // instruction.
1248*9880d681SAndroid Build Coastguard Worker           ATS.emitSetFP(FramePtr, ARM::SP, -Offset);
1249*9880d681SAndroid Build Coastguard Worker         else if (DstReg == ARM::SP) {
1250*9880d681SAndroid Build Coastguard Worker           // Change of SP by an offset. Positive values correspond to "sub"
1251*9880d681SAndroid Build Coastguard Worker           // instruction.
1252*9880d681SAndroid Build Coastguard Worker           ATS.emitPad(Offset);
1253*9880d681SAndroid Build Coastguard Worker         } else {
1254*9880d681SAndroid Build Coastguard Worker           // Move of SP to a register.  Positive values correspond to an "add"
1255*9880d681SAndroid Build Coastguard Worker           // instruction.
1256*9880d681SAndroid Build Coastguard Worker           ATS.emitMovSP(DstReg, -Offset);
1257*9880d681SAndroid Build Coastguard Worker         }
1258*9880d681SAndroid Build Coastguard Worker       }
1259*9880d681SAndroid Build Coastguard Worker     } else if (DstReg == ARM::SP) {
1260*9880d681SAndroid Build Coastguard Worker       MI->dump();
1261*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Unsupported opcode for unwinding information");
1262*9880d681SAndroid Build Coastguard Worker     }
1263*9880d681SAndroid Build Coastguard Worker     else {
1264*9880d681SAndroid Build Coastguard Worker       MI->dump();
1265*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Unsupported opcode for unwinding information");
1266*9880d681SAndroid Build Coastguard Worker     }
1267*9880d681SAndroid Build Coastguard Worker   }
1268*9880d681SAndroid Build Coastguard Worker }
1269*9880d681SAndroid Build Coastguard Worker 
1270*9880d681SAndroid Build Coastguard Worker // Simple pseudo-instructions have their lowering (with expansion to real
1271*9880d681SAndroid Build Coastguard Worker // instructions) auto-generated.
1272*9880d681SAndroid Build Coastguard Worker #include "ARMGenMCPseudoLowering.inc"
1273*9880d681SAndroid Build Coastguard Worker 
EmitInstruction(const MachineInstr * MI)1274*9880d681SAndroid Build Coastguard Worker void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
1275*9880d681SAndroid Build Coastguard Worker   const DataLayout &DL = getDataLayout();
1276*9880d681SAndroid Build Coastguard Worker   MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
1277*9880d681SAndroid Build Coastguard Worker   ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1278*9880d681SAndroid Build Coastguard Worker 
1279*9880d681SAndroid Build Coastguard Worker   // If we just ended a constant pool, mark it as such.
1280*9880d681SAndroid Build Coastguard Worker   if (InConstantPool && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) {
1281*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
1282*9880d681SAndroid Build Coastguard Worker     InConstantPool = false;
1283*9880d681SAndroid Build Coastguard Worker   }
1284*9880d681SAndroid Build Coastguard Worker 
1285*9880d681SAndroid Build Coastguard Worker   // Emit unwinding stuff for frame-related instructions
1286*9880d681SAndroid Build Coastguard Worker   if (Subtarget->isTargetEHABICompatible() &&
1287*9880d681SAndroid Build Coastguard Worker        MI->getFlag(MachineInstr::FrameSetup))
1288*9880d681SAndroid Build Coastguard Worker     EmitUnwindingInstruction(MI);
1289*9880d681SAndroid Build Coastguard Worker 
1290*9880d681SAndroid Build Coastguard Worker   // Do any auto-generated pseudo lowerings.
1291*9880d681SAndroid Build Coastguard Worker   if (emitPseudoExpansionLowering(*OutStreamer, MI))
1292*9880d681SAndroid Build Coastguard Worker     return;
1293*9880d681SAndroid Build Coastguard Worker 
1294*9880d681SAndroid Build Coastguard Worker   assert(!convertAddSubFlagsOpcode(MI->getOpcode()) &&
1295*9880d681SAndroid Build Coastguard Worker          "Pseudo flag setting opcode should be expanded early");
1296*9880d681SAndroid Build Coastguard Worker 
1297*9880d681SAndroid Build Coastguard Worker   // Check for manual lowerings.
1298*9880d681SAndroid Build Coastguard Worker   unsigned Opc = MI->getOpcode();
1299*9880d681SAndroid Build Coastguard Worker   switch (Opc) {
1300*9880d681SAndroid Build Coastguard Worker   case ARM::t2MOVi32imm: llvm_unreachable("Should be lowered by thumb2it pass");
1301*9880d681SAndroid Build Coastguard Worker   case ARM::DBG_VALUE: llvm_unreachable("Should be handled by generic printing");
1302*9880d681SAndroid Build Coastguard Worker   case ARM::LEApcrel:
1303*9880d681SAndroid Build Coastguard Worker   case ARM::tLEApcrel:
1304*9880d681SAndroid Build Coastguard Worker   case ARM::t2LEApcrel: {
1305*9880d681SAndroid Build Coastguard Worker     // FIXME: Need to also handle globals and externals
1306*9880d681SAndroid Build Coastguard Worker     MCSymbol *CPISymbol = GetCPISymbol(MI->getOperand(1).getIndex());
1307*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(MI->getOpcode() ==
1308*9880d681SAndroid Build Coastguard Worker                                                ARM::t2LEApcrel ? ARM::t2ADR
1309*9880d681SAndroid Build Coastguard Worker                   : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR
1310*9880d681SAndroid Build Coastguard Worker                      : ARM::ADR))
1311*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(0).getReg())
1312*9880d681SAndroid Build Coastguard Worker       .addExpr(MCSymbolRefExpr::create(CPISymbol, OutContext))
1313*9880d681SAndroid Build Coastguard Worker       // Add predicate operands.
1314*9880d681SAndroid Build Coastguard Worker       .addImm(MI->getOperand(2).getImm())
1315*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(3).getReg()));
1316*9880d681SAndroid Build Coastguard Worker     return;
1317*9880d681SAndroid Build Coastguard Worker   }
1318*9880d681SAndroid Build Coastguard Worker   case ARM::LEApcrelJT:
1319*9880d681SAndroid Build Coastguard Worker   case ARM::tLEApcrelJT:
1320*9880d681SAndroid Build Coastguard Worker   case ARM::t2LEApcrelJT: {
1321*9880d681SAndroid Build Coastguard Worker     MCSymbol *JTIPICSymbol =
1322*9880d681SAndroid Build Coastguard Worker       GetARMJTIPICJumpTableLabel(MI->getOperand(1).getIndex());
1323*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(MI->getOpcode() ==
1324*9880d681SAndroid Build Coastguard Worker                                                ARM::t2LEApcrelJT ? ARM::t2ADR
1325*9880d681SAndroid Build Coastguard Worker                   : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR
1326*9880d681SAndroid Build Coastguard Worker                      : ARM::ADR))
1327*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(0).getReg())
1328*9880d681SAndroid Build Coastguard Worker       .addExpr(MCSymbolRefExpr::create(JTIPICSymbol, OutContext))
1329*9880d681SAndroid Build Coastguard Worker       // Add predicate operands.
1330*9880d681SAndroid Build Coastguard Worker       .addImm(MI->getOperand(2).getImm())
1331*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(3).getReg()));
1332*9880d681SAndroid Build Coastguard Worker     return;
1333*9880d681SAndroid Build Coastguard Worker   }
1334*9880d681SAndroid Build Coastguard Worker   // Darwin call instructions are just normal call instructions with different
1335*9880d681SAndroid Build Coastguard Worker   // clobber semantics (they clobber R9).
1336*9880d681SAndroid Build Coastguard Worker   case ARM::BX_CALL: {
1337*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVr)
1338*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::LR)
1339*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::PC)
1340*9880d681SAndroid Build Coastguard Worker       // Add predicate operands.
1341*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1342*9880d681SAndroid Build Coastguard Worker       .addReg(0)
1343*9880d681SAndroid Build Coastguard Worker       // Add 's' bit operand (always reg0 for this)
1344*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1345*9880d681SAndroid Build Coastguard Worker 
1346*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::BX)
1347*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(0).getReg()));
1348*9880d681SAndroid Build Coastguard Worker     return;
1349*9880d681SAndroid Build Coastguard Worker   }
1350*9880d681SAndroid Build Coastguard Worker   case ARM::tBX_CALL: {
1351*9880d681SAndroid Build Coastguard Worker     if (Subtarget->hasV5TOps())
1352*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Expected BLX to be selected for v5t+");
1353*9880d681SAndroid Build Coastguard Worker 
1354*9880d681SAndroid Build Coastguard Worker     // On ARM v4t, when doing a call from thumb mode, we need to ensure
1355*9880d681SAndroid Build Coastguard Worker     // that the saved lr has its LSB set correctly (the arch doesn't
1356*9880d681SAndroid Build Coastguard Worker     // have blx).
1357*9880d681SAndroid Build Coastguard Worker     // So here we generate a bl to a small jump pad that does bx rN.
1358*9880d681SAndroid Build Coastguard Worker     // The jump pads are emitted after the function body.
1359*9880d681SAndroid Build Coastguard Worker 
1360*9880d681SAndroid Build Coastguard Worker     unsigned TReg = MI->getOperand(0).getReg();
1361*9880d681SAndroid Build Coastguard Worker     MCSymbol *TRegSym = nullptr;
1362*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = ThumbIndirectPads.size(); i < e; i++) {
1363*9880d681SAndroid Build Coastguard Worker       if (ThumbIndirectPads[i].first == TReg) {
1364*9880d681SAndroid Build Coastguard Worker         TRegSym = ThumbIndirectPads[i].second;
1365*9880d681SAndroid Build Coastguard Worker         break;
1366*9880d681SAndroid Build Coastguard Worker       }
1367*9880d681SAndroid Build Coastguard Worker     }
1368*9880d681SAndroid Build Coastguard Worker 
1369*9880d681SAndroid Build Coastguard Worker     if (!TRegSym) {
1370*9880d681SAndroid Build Coastguard Worker       TRegSym = OutContext.createTempSymbol();
1371*9880d681SAndroid Build Coastguard Worker       ThumbIndirectPads.push_back(std::make_pair(TReg, TRegSym));
1372*9880d681SAndroid Build Coastguard Worker     }
1373*9880d681SAndroid Build Coastguard Worker 
1374*9880d681SAndroid Build Coastguard Worker     // Create a link-saving branch to the Reg Indirect Jump Pad.
1375*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tBL)
1376*9880d681SAndroid Build Coastguard Worker         // Predicate comes first here.
1377*9880d681SAndroid Build Coastguard Worker         .addImm(ARMCC::AL).addReg(0)
1378*9880d681SAndroid Build Coastguard Worker         .addExpr(MCSymbolRefExpr::create(TRegSym, OutContext)));
1379*9880d681SAndroid Build Coastguard Worker     return;
1380*9880d681SAndroid Build Coastguard Worker   }
1381*9880d681SAndroid Build Coastguard Worker   case ARM::BMOVPCRX_CALL: {
1382*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVr)
1383*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::LR)
1384*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::PC)
1385*9880d681SAndroid Build Coastguard Worker       // Add predicate operands.
1386*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1387*9880d681SAndroid Build Coastguard Worker       .addReg(0)
1388*9880d681SAndroid Build Coastguard Worker       // Add 's' bit operand (always reg0 for this)
1389*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1390*9880d681SAndroid Build Coastguard Worker 
1391*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVr)
1392*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::PC)
1393*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(0).getReg())
1394*9880d681SAndroid Build Coastguard Worker       // Add predicate operands.
1395*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1396*9880d681SAndroid Build Coastguard Worker       .addReg(0)
1397*9880d681SAndroid Build Coastguard Worker       // Add 's' bit operand (always reg0 for this)
1398*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1399*9880d681SAndroid Build Coastguard Worker     return;
1400*9880d681SAndroid Build Coastguard Worker   }
1401*9880d681SAndroid Build Coastguard Worker   case ARM::BMOVPCB_CALL: {
1402*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVr)
1403*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::LR)
1404*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::PC)
1405*9880d681SAndroid Build Coastguard Worker       // Add predicate operands.
1406*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1407*9880d681SAndroid Build Coastguard Worker       .addReg(0)
1408*9880d681SAndroid Build Coastguard Worker       // Add 's' bit operand (always reg0 for this)
1409*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1410*9880d681SAndroid Build Coastguard Worker 
1411*9880d681SAndroid Build Coastguard Worker     const MachineOperand &Op = MI->getOperand(0);
1412*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GV = Op.getGlobal();
1413*9880d681SAndroid Build Coastguard Worker     const unsigned TF = Op.getTargetFlags();
1414*9880d681SAndroid Build Coastguard Worker     MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1415*9880d681SAndroid Build Coastguard Worker     const MCExpr *GVSymExpr = MCSymbolRefExpr::create(GVSym, OutContext);
1416*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::Bcc)
1417*9880d681SAndroid Build Coastguard Worker       .addExpr(GVSymExpr)
1418*9880d681SAndroid Build Coastguard Worker       // Add predicate operands.
1419*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1420*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1421*9880d681SAndroid Build Coastguard Worker     return;
1422*9880d681SAndroid Build Coastguard Worker   }
1423*9880d681SAndroid Build Coastguard Worker   case ARM::MOVi16_ga_pcrel:
1424*9880d681SAndroid Build Coastguard Worker   case ARM::t2MOVi16_ga_pcrel: {
1425*9880d681SAndroid Build Coastguard Worker     MCInst TmpInst;
1426*9880d681SAndroid Build Coastguard Worker     TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16);
1427*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1428*9880d681SAndroid Build Coastguard Worker 
1429*9880d681SAndroid Build Coastguard Worker     unsigned TF = MI->getOperand(1).getTargetFlags();
1430*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GV = MI->getOperand(1).getGlobal();
1431*9880d681SAndroid Build Coastguard Worker     MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1432*9880d681SAndroid Build Coastguard Worker     const MCExpr *GVSymExpr = MCSymbolRefExpr::create(GVSym, OutContext);
1433*9880d681SAndroid Build Coastguard Worker 
1434*9880d681SAndroid Build Coastguard Worker     MCSymbol *LabelSym =
1435*9880d681SAndroid Build Coastguard Worker         getPICLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(),
1436*9880d681SAndroid Build Coastguard Worker                     MI->getOperand(2).getImm(), OutContext);
1437*9880d681SAndroid Build Coastguard Worker     const MCExpr *LabelSymExpr= MCSymbolRefExpr::create(LabelSym, OutContext);
1438*9880d681SAndroid Build Coastguard Worker     unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;
1439*9880d681SAndroid Build Coastguard Worker     const MCExpr *PCRelExpr =
1440*9880d681SAndroid Build Coastguard Worker       ARMMCExpr::createLower16(MCBinaryExpr::createSub(GVSymExpr,
1441*9880d681SAndroid Build Coastguard Worker                                       MCBinaryExpr::createAdd(LabelSymExpr,
1442*9880d681SAndroid Build Coastguard Worker                                       MCConstantExpr::create(PCAdj, OutContext),
1443*9880d681SAndroid Build Coastguard Worker                                       OutContext), OutContext), OutContext);
1444*9880d681SAndroid Build Coastguard Worker       TmpInst.addOperand(MCOperand::createExpr(PCRelExpr));
1445*9880d681SAndroid Build Coastguard Worker 
1446*9880d681SAndroid Build Coastguard Worker     // Add predicate operands.
1447*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createImm(ARMCC::AL));
1448*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createReg(0));
1449*9880d681SAndroid Build Coastguard Worker     // Add 's' bit operand (always reg0 for this)
1450*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createReg(0));
1451*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, TmpInst);
1452*9880d681SAndroid Build Coastguard Worker     return;
1453*9880d681SAndroid Build Coastguard Worker   }
1454*9880d681SAndroid Build Coastguard Worker   case ARM::MOVTi16_ga_pcrel:
1455*9880d681SAndroid Build Coastguard Worker   case ARM::t2MOVTi16_ga_pcrel: {
1456*9880d681SAndroid Build Coastguard Worker     MCInst TmpInst;
1457*9880d681SAndroid Build Coastguard Worker     TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel
1458*9880d681SAndroid Build Coastguard Worker                       ? ARM::MOVTi16 : ARM::t2MOVTi16);
1459*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1460*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createReg(MI->getOperand(1).getReg()));
1461*9880d681SAndroid Build Coastguard Worker 
1462*9880d681SAndroid Build Coastguard Worker     unsigned TF = MI->getOperand(2).getTargetFlags();
1463*9880d681SAndroid Build Coastguard Worker     const GlobalValue *GV = MI->getOperand(2).getGlobal();
1464*9880d681SAndroid Build Coastguard Worker     MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1465*9880d681SAndroid Build Coastguard Worker     const MCExpr *GVSymExpr = MCSymbolRefExpr::create(GVSym, OutContext);
1466*9880d681SAndroid Build Coastguard Worker 
1467*9880d681SAndroid Build Coastguard Worker     MCSymbol *LabelSym =
1468*9880d681SAndroid Build Coastguard Worker         getPICLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(),
1469*9880d681SAndroid Build Coastguard Worker                     MI->getOperand(3).getImm(), OutContext);
1470*9880d681SAndroid Build Coastguard Worker     const MCExpr *LabelSymExpr= MCSymbolRefExpr::create(LabelSym, OutContext);
1471*9880d681SAndroid Build Coastguard Worker     unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;
1472*9880d681SAndroid Build Coastguard Worker     const MCExpr *PCRelExpr =
1473*9880d681SAndroid Build Coastguard Worker         ARMMCExpr::createUpper16(MCBinaryExpr::createSub(GVSymExpr,
1474*9880d681SAndroid Build Coastguard Worker                                    MCBinaryExpr::createAdd(LabelSymExpr,
1475*9880d681SAndroid Build Coastguard Worker                                       MCConstantExpr::create(PCAdj, OutContext),
1476*9880d681SAndroid Build Coastguard Worker                                           OutContext), OutContext), OutContext);
1477*9880d681SAndroid Build Coastguard Worker       TmpInst.addOperand(MCOperand::createExpr(PCRelExpr));
1478*9880d681SAndroid Build Coastguard Worker     // Add predicate operands.
1479*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createImm(ARMCC::AL));
1480*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createReg(0));
1481*9880d681SAndroid Build Coastguard Worker     // Add 's' bit operand (always reg0 for this)
1482*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createReg(0));
1483*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, TmpInst);
1484*9880d681SAndroid Build Coastguard Worker     return;
1485*9880d681SAndroid Build Coastguard Worker   }
1486*9880d681SAndroid Build Coastguard Worker   case ARM::tPICADD: {
1487*9880d681SAndroid Build Coastguard Worker     // This is a pseudo op for a label + instruction sequence, which looks like:
1488*9880d681SAndroid Build Coastguard Worker     // LPC0:
1489*9880d681SAndroid Build Coastguard Worker     //     add r0, pc
1490*9880d681SAndroid Build Coastguard Worker     // This adds the address of LPC0 to r0.
1491*9880d681SAndroid Build Coastguard Worker 
1492*9880d681SAndroid Build Coastguard Worker     // Emit the label.
1493*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitLabel(getPICLabel(DL.getPrivateGlobalPrefix(),
1494*9880d681SAndroid Build Coastguard Worker                                        getFunctionNumber(),
1495*9880d681SAndroid Build Coastguard Worker                                        MI->getOperand(2).getImm(), OutContext));
1496*9880d681SAndroid Build Coastguard Worker 
1497*9880d681SAndroid Build Coastguard Worker     // Form and emit the add.
1498*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tADDhirr)
1499*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(0).getReg())
1500*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(0).getReg())
1501*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::PC)
1502*9880d681SAndroid Build Coastguard Worker       // Add predicate operands.
1503*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1504*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1505*9880d681SAndroid Build Coastguard Worker     return;
1506*9880d681SAndroid Build Coastguard Worker   }
1507*9880d681SAndroid Build Coastguard Worker   case ARM::PICADD: {
1508*9880d681SAndroid Build Coastguard Worker     // This is a pseudo op for a label + instruction sequence, which looks like:
1509*9880d681SAndroid Build Coastguard Worker     // LPC0:
1510*9880d681SAndroid Build Coastguard Worker     //     add r0, pc, r0
1511*9880d681SAndroid Build Coastguard Worker     // This adds the address of LPC0 to r0.
1512*9880d681SAndroid Build Coastguard Worker 
1513*9880d681SAndroid Build Coastguard Worker     // Emit the label.
1514*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitLabel(getPICLabel(DL.getPrivateGlobalPrefix(),
1515*9880d681SAndroid Build Coastguard Worker                                        getFunctionNumber(),
1516*9880d681SAndroid Build Coastguard Worker                                        MI->getOperand(2).getImm(), OutContext));
1517*9880d681SAndroid Build Coastguard Worker 
1518*9880d681SAndroid Build Coastguard Worker     // Form and emit the add.
1519*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::ADDrr)
1520*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(0).getReg())
1521*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::PC)
1522*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(1).getReg())
1523*9880d681SAndroid Build Coastguard Worker       // Add predicate operands.
1524*9880d681SAndroid Build Coastguard Worker       .addImm(MI->getOperand(3).getImm())
1525*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(4).getReg())
1526*9880d681SAndroid Build Coastguard Worker       // Add 's' bit operand (always reg0 for this)
1527*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1528*9880d681SAndroid Build Coastguard Worker     return;
1529*9880d681SAndroid Build Coastguard Worker   }
1530*9880d681SAndroid Build Coastguard Worker   case ARM::PICSTR:
1531*9880d681SAndroid Build Coastguard Worker   case ARM::PICSTRB:
1532*9880d681SAndroid Build Coastguard Worker   case ARM::PICSTRH:
1533*9880d681SAndroid Build Coastguard Worker   case ARM::PICLDR:
1534*9880d681SAndroid Build Coastguard Worker   case ARM::PICLDRB:
1535*9880d681SAndroid Build Coastguard Worker   case ARM::PICLDRH:
1536*9880d681SAndroid Build Coastguard Worker   case ARM::PICLDRSB:
1537*9880d681SAndroid Build Coastguard Worker   case ARM::PICLDRSH: {
1538*9880d681SAndroid Build Coastguard Worker     // This is a pseudo op for a label + instruction sequence, which looks like:
1539*9880d681SAndroid Build Coastguard Worker     // LPC0:
1540*9880d681SAndroid Build Coastguard Worker     //     OP r0, [pc, r0]
1541*9880d681SAndroid Build Coastguard Worker     // The LCP0 label is referenced by a constant pool entry in order to get
1542*9880d681SAndroid Build Coastguard Worker     // a PC-relative address at the ldr instruction.
1543*9880d681SAndroid Build Coastguard Worker 
1544*9880d681SAndroid Build Coastguard Worker     // Emit the label.
1545*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitLabel(getPICLabel(DL.getPrivateGlobalPrefix(),
1546*9880d681SAndroid Build Coastguard Worker                                        getFunctionNumber(),
1547*9880d681SAndroid Build Coastguard Worker                                        MI->getOperand(2).getImm(), OutContext));
1548*9880d681SAndroid Build Coastguard Worker 
1549*9880d681SAndroid Build Coastguard Worker     // Form and emit the load
1550*9880d681SAndroid Build Coastguard Worker     unsigned Opcode;
1551*9880d681SAndroid Build Coastguard Worker     switch (MI->getOpcode()) {
1552*9880d681SAndroid Build Coastguard Worker     default:
1553*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Unexpected opcode!");
1554*9880d681SAndroid Build Coastguard Worker     case ARM::PICSTR:   Opcode = ARM::STRrs; break;
1555*9880d681SAndroid Build Coastguard Worker     case ARM::PICSTRB:  Opcode = ARM::STRBrs; break;
1556*9880d681SAndroid Build Coastguard Worker     case ARM::PICSTRH:  Opcode = ARM::STRH; break;
1557*9880d681SAndroid Build Coastguard Worker     case ARM::PICLDR:   Opcode = ARM::LDRrs; break;
1558*9880d681SAndroid Build Coastguard Worker     case ARM::PICLDRB:  Opcode = ARM::LDRBrs; break;
1559*9880d681SAndroid Build Coastguard Worker     case ARM::PICLDRH:  Opcode = ARM::LDRH; break;
1560*9880d681SAndroid Build Coastguard Worker     case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
1561*9880d681SAndroid Build Coastguard Worker     case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
1562*9880d681SAndroid Build Coastguard Worker     }
1563*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(Opcode)
1564*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(0).getReg())
1565*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::PC)
1566*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(1).getReg())
1567*9880d681SAndroid Build Coastguard Worker       .addImm(0)
1568*9880d681SAndroid Build Coastguard Worker       // Add predicate operands.
1569*9880d681SAndroid Build Coastguard Worker       .addImm(MI->getOperand(3).getImm())
1570*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(4).getReg()));
1571*9880d681SAndroid Build Coastguard Worker 
1572*9880d681SAndroid Build Coastguard Worker     return;
1573*9880d681SAndroid Build Coastguard Worker   }
1574*9880d681SAndroid Build Coastguard Worker   case ARM::CONSTPOOL_ENTRY: {
1575*9880d681SAndroid Build Coastguard Worker     /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1576*9880d681SAndroid Build Coastguard Worker     /// in the function.  The first operand is the ID# for this instruction, the
1577*9880d681SAndroid Build Coastguard Worker     /// second is the index into the MachineConstantPool that this is, the third
1578*9880d681SAndroid Build Coastguard Worker     /// is the size in bytes of this constant pool entry.
1579*9880d681SAndroid Build Coastguard Worker     /// The required alignment is specified on the basic block holding this MI.
1580*9880d681SAndroid Build Coastguard Worker     unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1581*9880d681SAndroid Build Coastguard Worker     unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
1582*9880d681SAndroid Build Coastguard Worker 
1583*9880d681SAndroid Build Coastguard Worker     // If this is the first entry of the pool, mark it.
1584*9880d681SAndroid Build Coastguard Worker     if (!InConstantPool) {
1585*9880d681SAndroid Build Coastguard Worker       OutStreamer->EmitDataRegion(MCDR_DataRegion);
1586*9880d681SAndroid Build Coastguard Worker       InConstantPool = true;
1587*9880d681SAndroid Build Coastguard Worker     }
1588*9880d681SAndroid Build Coastguard Worker 
1589*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitLabel(GetCPISymbol(LabelId));
1590*9880d681SAndroid Build Coastguard Worker 
1591*9880d681SAndroid Build Coastguard Worker     const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1592*9880d681SAndroid Build Coastguard Worker     if (MCPE.isMachineConstantPoolEntry())
1593*9880d681SAndroid Build Coastguard Worker       EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
1594*9880d681SAndroid Build Coastguard Worker     else
1595*9880d681SAndroid Build Coastguard Worker       EmitGlobalConstant(DL, MCPE.Val.ConstVal);
1596*9880d681SAndroid Build Coastguard Worker     return;
1597*9880d681SAndroid Build Coastguard Worker   }
1598*9880d681SAndroid Build Coastguard Worker   case ARM::JUMPTABLE_ADDRS:
1599*9880d681SAndroid Build Coastguard Worker     EmitJumpTableAddrs(MI);
1600*9880d681SAndroid Build Coastguard Worker     return;
1601*9880d681SAndroid Build Coastguard Worker   case ARM::JUMPTABLE_INSTS:
1602*9880d681SAndroid Build Coastguard Worker     EmitJumpTableInsts(MI);
1603*9880d681SAndroid Build Coastguard Worker     return;
1604*9880d681SAndroid Build Coastguard Worker   case ARM::JUMPTABLE_TBB:
1605*9880d681SAndroid Build Coastguard Worker   case ARM::JUMPTABLE_TBH:
1606*9880d681SAndroid Build Coastguard Worker     EmitJumpTableTBInst(MI, MI->getOpcode() == ARM::JUMPTABLE_TBB ? 1 : 2);
1607*9880d681SAndroid Build Coastguard Worker     return;
1608*9880d681SAndroid Build Coastguard Worker   case ARM::t2BR_JT: {
1609*9880d681SAndroid Build Coastguard Worker     // Lower and emit the instruction itself, then the jump table following it.
1610*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVr)
1611*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::PC)
1612*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(0).getReg())
1613*9880d681SAndroid Build Coastguard Worker       // Add predicate operands.
1614*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1615*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1616*9880d681SAndroid Build Coastguard Worker     return;
1617*9880d681SAndroid Build Coastguard Worker   }
1618*9880d681SAndroid Build Coastguard Worker   case ARM::t2TBB_JT:
1619*9880d681SAndroid Build Coastguard Worker   case ARM::t2TBH_JT: {
1620*9880d681SAndroid Build Coastguard Worker     unsigned Opc = MI->getOpcode() == ARM::t2TBB_JT ? ARM::t2TBB : ARM::t2TBH;
1621*9880d681SAndroid Build Coastguard Worker     // Lower and emit the PC label, then the instruction itself.
1622*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitLabel(GetCPISymbol(MI->getOperand(3).getImm()));
1623*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(Opc)
1624*9880d681SAndroid Build Coastguard Worker                                      .addReg(MI->getOperand(0).getReg())
1625*9880d681SAndroid Build Coastguard Worker                                      .addReg(MI->getOperand(1).getReg())
1626*9880d681SAndroid Build Coastguard Worker                                      // Add predicate operands.
1627*9880d681SAndroid Build Coastguard Worker                                      .addImm(ARMCC::AL)
1628*9880d681SAndroid Build Coastguard Worker                                      .addReg(0));
1629*9880d681SAndroid Build Coastguard Worker     return;
1630*9880d681SAndroid Build Coastguard Worker   }
1631*9880d681SAndroid Build Coastguard Worker   case ARM::tBR_JTr:
1632*9880d681SAndroid Build Coastguard Worker   case ARM::BR_JTr: {
1633*9880d681SAndroid Build Coastguard Worker     // Lower and emit the instruction itself, then the jump table following it.
1634*9880d681SAndroid Build Coastguard Worker     // mov pc, target
1635*9880d681SAndroid Build Coastguard Worker     MCInst TmpInst;
1636*9880d681SAndroid Build Coastguard Worker     unsigned Opc = MI->getOpcode() == ARM::BR_JTr ?
1637*9880d681SAndroid Build Coastguard Worker       ARM::MOVr : ARM::tMOVr;
1638*9880d681SAndroid Build Coastguard Worker     TmpInst.setOpcode(Opc);
1639*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createReg(ARM::PC));
1640*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1641*9880d681SAndroid Build Coastguard Worker     // Add predicate operands.
1642*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createImm(ARMCC::AL));
1643*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createReg(0));
1644*9880d681SAndroid Build Coastguard Worker     // Add 's' bit operand (always reg0 for this)
1645*9880d681SAndroid Build Coastguard Worker     if (Opc == ARM::MOVr)
1646*9880d681SAndroid Build Coastguard Worker       TmpInst.addOperand(MCOperand::createReg(0));
1647*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, TmpInst);
1648*9880d681SAndroid Build Coastguard Worker     return;
1649*9880d681SAndroid Build Coastguard Worker   }
1650*9880d681SAndroid Build Coastguard Worker   case ARM::BR_JTm: {
1651*9880d681SAndroid Build Coastguard Worker     // Lower and emit the instruction itself, then the jump table following it.
1652*9880d681SAndroid Build Coastguard Worker     // ldr pc, target
1653*9880d681SAndroid Build Coastguard Worker     MCInst TmpInst;
1654*9880d681SAndroid Build Coastguard Worker     if (MI->getOperand(1).getReg() == 0) {
1655*9880d681SAndroid Build Coastguard Worker       // literal offset
1656*9880d681SAndroid Build Coastguard Worker       TmpInst.setOpcode(ARM::LDRi12);
1657*9880d681SAndroid Build Coastguard Worker       TmpInst.addOperand(MCOperand::createReg(ARM::PC));
1658*9880d681SAndroid Build Coastguard Worker       TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1659*9880d681SAndroid Build Coastguard Worker       TmpInst.addOperand(MCOperand::createImm(MI->getOperand(2).getImm()));
1660*9880d681SAndroid Build Coastguard Worker     } else {
1661*9880d681SAndroid Build Coastguard Worker       TmpInst.setOpcode(ARM::LDRrs);
1662*9880d681SAndroid Build Coastguard Worker       TmpInst.addOperand(MCOperand::createReg(ARM::PC));
1663*9880d681SAndroid Build Coastguard Worker       TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1664*9880d681SAndroid Build Coastguard Worker       TmpInst.addOperand(MCOperand::createReg(MI->getOperand(1).getReg()));
1665*9880d681SAndroid Build Coastguard Worker       TmpInst.addOperand(MCOperand::createImm(0));
1666*9880d681SAndroid Build Coastguard Worker     }
1667*9880d681SAndroid Build Coastguard Worker     // Add predicate operands.
1668*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createImm(ARMCC::AL));
1669*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createReg(0));
1670*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, TmpInst);
1671*9880d681SAndroid Build Coastguard Worker     return;
1672*9880d681SAndroid Build Coastguard Worker   }
1673*9880d681SAndroid Build Coastguard Worker   case ARM::BR_JTadd: {
1674*9880d681SAndroid Build Coastguard Worker     // Lower and emit the instruction itself, then the jump table following it.
1675*9880d681SAndroid Build Coastguard Worker     // add pc, target, idx
1676*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::ADDrr)
1677*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::PC)
1678*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(0).getReg())
1679*9880d681SAndroid Build Coastguard Worker       .addReg(MI->getOperand(1).getReg())
1680*9880d681SAndroid Build Coastguard Worker       // Add predicate operands.
1681*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1682*9880d681SAndroid Build Coastguard Worker       .addReg(0)
1683*9880d681SAndroid Build Coastguard Worker       // Add 's' bit operand (always reg0 for this)
1684*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1685*9880d681SAndroid Build Coastguard Worker     return;
1686*9880d681SAndroid Build Coastguard Worker   }
1687*9880d681SAndroid Build Coastguard Worker   case ARM::SPACE:
1688*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitZeros(MI->getOperand(1).getImm());
1689*9880d681SAndroid Build Coastguard Worker     return;
1690*9880d681SAndroid Build Coastguard Worker   case ARM::TRAP: {
1691*9880d681SAndroid Build Coastguard Worker     // Non-Darwin binutils don't yet support the "trap" mnemonic.
1692*9880d681SAndroid Build Coastguard Worker     // FIXME: Remove this special case when they do.
1693*9880d681SAndroid Build Coastguard Worker     if (!Subtarget->isTargetMachO()) {
1694*9880d681SAndroid Build Coastguard Worker       uint32_t Val = 0xe7ffdefeUL;
1695*9880d681SAndroid Build Coastguard Worker       OutStreamer->AddComment("trap");
1696*9880d681SAndroid Build Coastguard Worker       ATS.emitInst(Val);
1697*9880d681SAndroid Build Coastguard Worker       return;
1698*9880d681SAndroid Build Coastguard Worker     }
1699*9880d681SAndroid Build Coastguard Worker     break;
1700*9880d681SAndroid Build Coastguard Worker   }
1701*9880d681SAndroid Build Coastguard Worker   case ARM::TRAPNaCl: {
1702*9880d681SAndroid Build Coastguard Worker     uint32_t Val = 0xe7fedef0UL;
1703*9880d681SAndroid Build Coastguard Worker     OutStreamer->AddComment("trap");
1704*9880d681SAndroid Build Coastguard Worker     ATS.emitInst(Val);
1705*9880d681SAndroid Build Coastguard Worker     return;
1706*9880d681SAndroid Build Coastguard Worker   }
1707*9880d681SAndroid Build Coastguard Worker   case ARM::tTRAP: {
1708*9880d681SAndroid Build Coastguard Worker     // Non-Darwin binutils don't yet support the "trap" mnemonic.
1709*9880d681SAndroid Build Coastguard Worker     // FIXME: Remove this special case when they do.
1710*9880d681SAndroid Build Coastguard Worker     if (!Subtarget->isTargetMachO()) {
1711*9880d681SAndroid Build Coastguard Worker       uint16_t Val = 0xdefe;
1712*9880d681SAndroid Build Coastguard Worker       OutStreamer->AddComment("trap");
1713*9880d681SAndroid Build Coastguard Worker       ATS.emitInst(Val, 'n');
1714*9880d681SAndroid Build Coastguard Worker       return;
1715*9880d681SAndroid Build Coastguard Worker     }
1716*9880d681SAndroid Build Coastguard Worker     break;
1717*9880d681SAndroid Build Coastguard Worker   }
1718*9880d681SAndroid Build Coastguard Worker   case ARM::t2Int_eh_sjlj_setjmp:
1719*9880d681SAndroid Build Coastguard Worker   case ARM::t2Int_eh_sjlj_setjmp_nofp:
1720*9880d681SAndroid Build Coastguard Worker   case ARM::tInt_eh_sjlj_setjmp: {
1721*9880d681SAndroid Build Coastguard Worker     // Two incoming args: GPR:$src, GPR:$val
1722*9880d681SAndroid Build Coastguard Worker     // mov $val, pc
1723*9880d681SAndroid Build Coastguard Worker     // adds $val, #7
1724*9880d681SAndroid Build Coastguard Worker     // str $val, [$src, #4]
1725*9880d681SAndroid Build Coastguard Worker     // movs r0, #0
1726*9880d681SAndroid Build Coastguard Worker     // b LSJLJEH
1727*9880d681SAndroid Build Coastguard Worker     // movs r0, #1
1728*9880d681SAndroid Build Coastguard Worker     // LSJLJEH:
1729*9880d681SAndroid Build Coastguard Worker     unsigned SrcReg = MI->getOperand(0).getReg();
1730*9880d681SAndroid Build Coastguard Worker     unsigned ValReg = MI->getOperand(1).getReg();
1731*9880d681SAndroid Build Coastguard Worker     MCSymbol *Label = OutContext.createTempSymbol("SJLJEH", false, true);
1732*9880d681SAndroid Build Coastguard Worker     OutStreamer->AddComment("eh_setjmp begin");
1733*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVr)
1734*9880d681SAndroid Build Coastguard Worker       .addReg(ValReg)
1735*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::PC)
1736*9880d681SAndroid Build Coastguard Worker       // Predicate.
1737*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1738*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1739*9880d681SAndroid Build Coastguard Worker 
1740*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tADDi3)
1741*9880d681SAndroid Build Coastguard Worker       .addReg(ValReg)
1742*9880d681SAndroid Build Coastguard Worker       // 's' bit operand
1743*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::CPSR)
1744*9880d681SAndroid Build Coastguard Worker       .addReg(ValReg)
1745*9880d681SAndroid Build Coastguard Worker       .addImm(7)
1746*9880d681SAndroid Build Coastguard Worker       // Predicate.
1747*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1748*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1749*9880d681SAndroid Build Coastguard Worker 
1750*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tSTRi)
1751*9880d681SAndroid Build Coastguard Worker       .addReg(ValReg)
1752*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg)
1753*9880d681SAndroid Build Coastguard Worker       // The offset immediate is #4. The operand value is scaled by 4 for the
1754*9880d681SAndroid Build Coastguard Worker       // tSTR instruction.
1755*9880d681SAndroid Build Coastguard Worker       .addImm(1)
1756*9880d681SAndroid Build Coastguard Worker       // Predicate.
1757*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1758*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1759*9880d681SAndroid Build Coastguard Worker 
1760*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVi8)
1761*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::R0)
1762*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::CPSR)
1763*9880d681SAndroid Build Coastguard Worker       .addImm(0)
1764*9880d681SAndroid Build Coastguard Worker       // Predicate.
1765*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1766*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1767*9880d681SAndroid Build Coastguard Worker 
1768*9880d681SAndroid Build Coastguard Worker     const MCExpr *SymbolExpr = MCSymbolRefExpr::create(Label, OutContext);
1769*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tB)
1770*9880d681SAndroid Build Coastguard Worker       .addExpr(SymbolExpr)
1771*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1772*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1773*9880d681SAndroid Build Coastguard Worker 
1774*9880d681SAndroid Build Coastguard Worker     OutStreamer->AddComment("eh_setjmp end");
1775*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVi8)
1776*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::R0)
1777*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::CPSR)
1778*9880d681SAndroid Build Coastguard Worker       .addImm(1)
1779*9880d681SAndroid Build Coastguard Worker       // Predicate.
1780*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1781*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1782*9880d681SAndroid Build Coastguard Worker 
1783*9880d681SAndroid Build Coastguard Worker     OutStreamer->EmitLabel(Label);
1784*9880d681SAndroid Build Coastguard Worker     return;
1785*9880d681SAndroid Build Coastguard Worker   }
1786*9880d681SAndroid Build Coastguard Worker 
1787*9880d681SAndroid Build Coastguard Worker   case ARM::Int_eh_sjlj_setjmp_nofp:
1788*9880d681SAndroid Build Coastguard Worker   case ARM::Int_eh_sjlj_setjmp: {
1789*9880d681SAndroid Build Coastguard Worker     // Two incoming args: GPR:$src, GPR:$val
1790*9880d681SAndroid Build Coastguard Worker     // add $val, pc, #8
1791*9880d681SAndroid Build Coastguard Worker     // str $val, [$src, #+4]
1792*9880d681SAndroid Build Coastguard Worker     // mov r0, #0
1793*9880d681SAndroid Build Coastguard Worker     // add pc, pc, #0
1794*9880d681SAndroid Build Coastguard Worker     // mov r0, #1
1795*9880d681SAndroid Build Coastguard Worker     unsigned SrcReg = MI->getOperand(0).getReg();
1796*9880d681SAndroid Build Coastguard Worker     unsigned ValReg = MI->getOperand(1).getReg();
1797*9880d681SAndroid Build Coastguard Worker 
1798*9880d681SAndroid Build Coastguard Worker     OutStreamer->AddComment("eh_setjmp begin");
1799*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::ADDri)
1800*9880d681SAndroid Build Coastguard Worker       .addReg(ValReg)
1801*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::PC)
1802*9880d681SAndroid Build Coastguard Worker       .addImm(8)
1803*9880d681SAndroid Build Coastguard Worker       // Predicate.
1804*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1805*9880d681SAndroid Build Coastguard Worker       .addReg(0)
1806*9880d681SAndroid Build Coastguard Worker       // 's' bit operand (always reg0 for this).
1807*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1808*9880d681SAndroid Build Coastguard Worker 
1809*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::STRi12)
1810*9880d681SAndroid Build Coastguard Worker       .addReg(ValReg)
1811*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg)
1812*9880d681SAndroid Build Coastguard Worker       .addImm(4)
1813*9880d681SAndroid Build Coastguard Worker       // Predicate.
1814*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1815*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1816*9880d681SAndroid Build Coastguard Worker 
1817*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVi)
1818*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::R0)
1819*9880d681SAndroid Build Coastguard Worker       .addImm(0)
1820*9880d681SAndroid Build Coastguard Worker       // Predicate.
1821*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1822*9880d681SAndroid Build Coastguard Worker       .addReg(0)
1823*9880d681SAndroid Build Coastguard Worker       // 's' bit operand (always reg0 for this).
1824*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1825*9880d681SAndroid Build Coastguard Worker 
1826*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::ADDri)
1827*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::PC)
1828*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::PC)
1829*9880d681SAndroid Build Coastguard Worker       .addImm(0)
1830*9880d681SAndroid Build Coastguard Worker       // Predicate.
1831*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1832*9880d681SAndroid Build Coastguard Worker       .addReg(0)
1833*9880d681SAndroid Build Coastguard Worker       // 's' bit operand (always reg0 for this).
1834*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1835*9880d681SAndroid Build Coastguard Worker 
1836*9880d681SAndroid Build Coastguard Worker     OutStreamer->AddComment("eh_setjmp end");
1837*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::MOVi)
1838*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::R0)
1839*9880d681SAndroid Build Coastguard Worker       .addImm(1)
1840*9880d681SAndroid Build Coastguard Worker       // Predicate.
1841*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1842*9880d681SAndroid Build Coastguard Worker       .addReg(0)
1843*9880d681SAndroid Build Coastguard Worker       // 's' bit operand (always reg0 for this).
1844*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1845*9880d681SAndroid Build Coastguard Worker     return;
1846*9880d681SAndroid Build Coastguard Worker   }
1847*9880d681SAndroid Build Coastguard Worker   case ARM::Int_eh_sjlj_longjmp: {
1848*9880d681SAndroid Build Coastguard Worker     // ldr sp, [$src, #8]
1849*9880d681SAndroid Build Coastguard Worker     // ldr $scratch, [$src, #4]
1850*9880d681SAndroid Build Coastguard Worker     // ldr r7, [$src]
1851*9880d681SAndroid Build Coastguard Worker     // bx $scratch
1852*9880d681SAndroid Build Coastguard Worker     unsigned SrcReg = MI->getOperand(0).getReg();
1853*9880d681SAndroid Build Coastguard Worker     unsigned ScratchReg = MI->getOperand(1).getReg();
1854*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::LDRi12)
1855*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::SP)
1856*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg)
1857*9880d681SAndroid Build Coastguard Worker       .addImm(8)
1858*9880d681SAndroid Build Coastguard Worker       // Predicate.
1859*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1860*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1861*9880d681SAndroid Build Coastguard Worker 
1862*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::LDRi12)
1863*9880d681SAndroid Build Coastguard Worker       .addReg(ScratchReg)
1864*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg)
1865*9880d681SAndroid Build Coastguard Worker       .addImm(4)
1866*9880d681SAndroid Build Coastguard Worker       // Predicate.
1867*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1868*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1869*9880d681SAndroid Build Coastguard Worker 
1870*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::LDRi12)
1871*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::R7)
1872*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg)
1873*9880d681SAndroid Build Coastguard Worker       .addImm(0)
1874*9880d681SAndroid Build Coastguard Worker       // Predicate.
1875*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1876*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1877*9880d681SAndroid Build Coastguard Worker 
1878*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::BX)
1879*9880d681SAndroid Build Coastguard Worker       .addReg(ScratchReg)
1880*9880d681SAndroid Build Coastguard Worker       // Predicate.
1881*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1882*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1883*9880d681SAndroid Build Coastguard Worker     return;
1884*9880d681SAndroid Build Coastguard Worker   }
1885*9880d681SAndroid Build Coastguard Worker   case ARM::tInt_eh_sjlj_longjmp: {
1886*9880d681SAndroid Build Coastguard Worker     // ldr $scratch, [$src, #8]
1887*9880d681SAndroid Build Coastguard Worker     // mov sp, $scratch
1888*9880d681SAndroid Build Coastguard Worker     // ldr $scratch, [$src, #4]
1889*9880d681SAndroid Build Coastguard Worker     // ldr r7, [$src]
1890*9880d681SAndroid Build Coastguard Worker     // bx $scratch
1891*9880d681SAndroid Build Coastguard Worker     unsigned SrcReg = MI->getOperand(0).getReg();
1892*9880d681SAndroid Build Coastguard Worker     unsigned ScratchReg = MI->getOperand(1).getReg();
1893*9880d681SAndroid Build Coastguard Worker 
1894*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLDRi)
1895*9880d681SAndroid Build Coastguard Worker       .addReg(ScratchReg)
1896*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg)
1897*9880d681SAndroid Build Coastguard Worker       // The offset immediate is #8. The operand value is scaled by 4 for the
1898*9880d681SAndroid Build Coastguard Worker       // tLDR instruction.
1899*9880d681SAndroid Build Coastguard Worker       .addImm(2)
1900*9880d681SAndroid Build Coastguard Worker       // Predicate.
1901*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1902*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1903*9880d681SAndroid Build Coastguard Worker 
1904*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVr)
1905*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::SP)
1906*9880d681SAndroid Build Coastguard Worker       .addReg(ScratchReg)
1907*9880d681SAndroid Build Coastguard Worker       // Predicate.
1908*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1909*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1910*9880d681SAndroid Build Coastguard Worker 
1911*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLDRi)
1912*9880d681SAndroid Build Coastguard Worker       .addReg(ScratchReg)
1913*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg)
1914*9880d681SAndroid Build Coastguard Worker       .addImm(1)
1915*9880d681SAndroid Build Coastguard Worker       // Predicate.
1916*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1917*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1918*9880d681SAndroid Build Coastguard Worker 
1919*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLDRi)
1920*9880d681SAndroid Build Coastguard Worker       .addReg(ARM::R7)
1921*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg)
1922*9880d681SAndroid Build Coastguard Worker       .addImm(0)
1923*9880d681SAndroid Build Coastguard Worker       // Predicate.
1924*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1925*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1926*9880d681SAndroid Build Coastguard Worker 
1927*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tBX)
1928*9880d681SAndroid Build Coastguard Worker       .addReg(ScratchReg)
1929*9880d681SAndroid Build Coastguard Worker       // Predicate.
1930*9880d681SAndroid Build Coastguard Worker       .addImm(ARMCC::AL)
1931*9880d681SAndroid Build Coastguard Worker       .addReg(0));
1932*9880d681SAndroid Build Coastguard Worker     return;
1933*9880d681SAndroid Build Coastguard Worker   }
1934*9880d681SAndroid Build Coastguard Worker   case ARM::tInt_WIN_eh_sjlj_longjmp: {
1935*9880d681SAndroid Build Coastguard Worker     // ldr.w r11, [$src, #0]
1936*9880d681SAndroid Build Coastguard Worker     // ldr.w  sp, [$src, #8]
1937*9880d681SAndroid Build Coastguard Worker     // ldr.w  pc, [$src, #4]
1938*9880d681SAndroid Build Coastguard Worker 
1939*9880d681SAndroid Build Coastguard Worker     unsigned SrcReg = MI->getOperand(0).getReg();
1940*9880d681SAndroid Build Coastguard Worker 
1941*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2LDRi12)
1942*9880d681SAndroid Build Coastguard Worker                                      .addReg(ARM::R11)
1943*9880d681SAndroid Build Coastguard Worker                                      .addReg(SrcReg)
1944*9880d681SAndroid Build Coastguard Worker                                      .addImm(0)
1945*9880d681SAndroid Build Coastguard Worker                                      // Predicate
1946*9880d681SAndroid Build Coastguard Worker                                      .addImm(ARMCC::AL)
1947*9880d681SAndroid Build Coastguard Worker                                      .addReg(0));
1948*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2LDRi12)
1949*9880d681SAndroid Build Coastguard Worker                                      .addReg(ARM::SP)
1950*9880d681SAndroid Build Coastguard Worker                                      .addReg(SrcReg)
1951*9880d681SAndroid Build Coastguard Worker                                      .addImm(8)
1952*9880d681SAndroid Build Coastguard Worker                                      // Predicate
1953*9880d681SAndroid Build Coastguard Worker                                      .addImm(ARMCC::AL)
1954*9880d681SAndroid Build Coastguard Worker                                      .addReg(0));
1955*9880d681SAndroid Build Coastguard Worker     EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2LDRi12)
1956*9880d681SAndroid Build Coastguard Worker                                      .addReg(ARM::PC)
1957*9880d681SAndroid Build Coastguard Worker                                      .addReg(SrcReg)
1958*9880d681SAndroid Build Coastguard Worker                                      .addImm(4)
1959*9880d681SAndroid Build Coastguard Worker                                      // Predicate
1960*9880d681SAndroid Build Coastguard Worker                                      .addImm(ARMCC::AL)
1961*9880d681SAndroid Build Coastguard Worker                                      .addReg(0));
1962*9880d681SAndroid Build Coastguard Worker     return;
1963*9880d681SAndroid Build Coastguard Worker   }
1964*9880d681SAndroid Build Coastguard Worker   }
1965*9880d681SAndroid Build Coastguard Worker 
1966*9880d681SAndroid Build Coastguard Worker   MCInst TmpInst;
1967*9880d681SAndroid Build Coastguard Worker   LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
1968*9880d681SAndroid Build Coastguard Worker 
1969*9880d681SAndroid Build Coastguard Worker   EmitToStreamer(*OutStreamer, TmpInst);
1970*9880d681SAndroid Build Coastguard Worker }
1971*9880d681SAndroid Build Coastguard Worker 
1972*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1973*9880d681SAndroid Build Coastguard Worker // Target Registry Stuff
1974*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1975*9880d681SAndroid Build Coastguard Worker 
1976*9880d681SAndroid Build Coastguard Worker // Force static initialization.
LLVMInitializeARMAsmPrinter()1977*9880d681SAndroid Build Coastguard Worker extern "C" void LLVMInitializeARMAsmPrinter() {
1978*9880d681SAndroid Build Coastguard Worker   RegisterAsmPrinter<ARMAsmPrinter> X(TheARMLETarget);
1979*9880d681SAndroid Build Coastguard Worker   RegisterAsmPrinter<ARMAsmPrinter> Y(TheARMBETarget);
1980*9880d681SAndroid Build Coastguard Worker   RegisterAsmPrinter<ARMAsmPrinter> A(TheThumbLETarget);
1981*9880d681SAndroid Build Coastguard Worker   RegisterAsmPrinter<ARMAsmPrinter> B(TheThumbBETarget);
1982*9880d681SAndroid Build Coastguard Worker }
1983