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