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