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