LLVM 22.0.0git
ARMAsmPrinter.cpp
Go to the documentation of this file.
1//===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains a printer that converts from our internal representation
10// of machine-dependent LLVM code to GAS-format ARM assembly language.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ARMAsmPrinter.h"
15#include "ARM.h"
18#include "ARMTargetMachine.h"
19#include "ARMTargetObjectFile.h"
27#include "llvm/IR/Constants.h"
28#include "llvm/IR/DataLayout.h"
29#include "llvm/IR/Mangler.h"
30#include "llvm/IR/Module.h"
31#include "llvm/IR/Type.h"
32#include "llvm/MC/MCAsmInfo.h"
33#include "llvm/MC/MCAssembler.h"
34#include "llvm/MC/MCContext.h"
36#include "llvm/MC/MCInst.h"
39#include "llvm/MC/MCStreamer.h"
40#include "llvm/MC/MCSymbol.h"
44#include "llvm/Support/Debug.h"
48using namespace llvm;
49
50#define DEBUG_TYPE "asm-printer"
51
53 std::unique_ptr<MCStreamer> Streamer)
54 : AsmPrinter(TM, std::move(Streamer), ID), Subtarget(nullptr), AFI(nullptr),
55 MCP(nullptr), InConstantPool(false), OptimizationGoals(-1) {}
56
58 return static_cast<const ARMBaseTargetMachine &>(TM);
59}
60
62 // Make sure to terminate any constant pools that were at the end
63 // of the function.
64 if (!InConstantPool)
65 return;
66 InConstantPool = false;
67 OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
68}
69
71 auto &TS =
72 static_cast<ARMTargetStreamer &>(*OutStreamer->getTargetStreamer());
73 if (AFI->isThumbFunction()) {
74 TS.emitCode16();
75 TS.emitThumbFunc(CurrentFnSym);
76 } else {
77 TS.emitCode32();
78 }
79
80 // Emit symbol for CMSE non-secure entry point
81 if (AFI->isCmseNSEntryFunction()) {
82 MCSymbol *S =
83 OutContext.getOrCreateSymbol("__acle_se_" + CurrentFnSym->getName());
84 emitLinkage(&MF->getFunction(), S);
85 OutStreamer->emitSymbolAttribute(S, MCSA_ELF_TypeFunction);
86 OutStreamer->emitLabel(S);
87 }
89}
90
93 assert(Size && "C++ constructor pointer had zero size!");
94
96 assert(GV && "C++ constructor pointer was not a GlobalValue!");
97
99 GetARMGVSymbol(GV, ARMII::MO_NO_FLAG),
100 (Subtarget->isTargetELF() ? ARM::S_TARGET1 : ARM::S_None), OutContext);
101
102 OutStreamer->emitValue(E, Size);
103}
104
106 if (PromotedGlobals.count(GV))
107 // The global was promoted into a constant pool. It should not be emitted.
108 return;
110}
111
112/// runOnMachineFunction - This uses the emitInstruction()
113/// method to print assembly for each instruction.
114///
116 AFI = MF.getInfo<ARMFunctionInfo>();
117 MCP = MF.getConstantPool();
118 Subtarget = &MF.getSubtarget<ARMSubtarget>();
119
121 const Function &F = MF.getFunction();
122 const TargetMachine& TM = MF.getTarget();
123
124 // Collect all globals that had their storage promoted to a constant pool.
125 // Functions are emitted before variables, so this accumulates promoted
126 // globals from all functions in PromotedGlobals.
127 PromotedGlobals.insert_range(AFI->getGlobalsPromotedToConstantPool());
128
129 // Calculate this function's optimization goal.
130 unsigned OptimizationGoal;
131 if (F.hasOptNone())
132 // For best debugging illusion, speed and small size sacrificed
133 OptimizationGoal = 6;
134 else if (F.hasMinSize())
135 // Aggressively for small size, speed and debug illusion sacrificed
136 OptimizationGoal = 4;
137 else if (F.hasOptSize())
138 // For small size, but speed and debugging illusion preserved
139 OptimizationGoal = 3;
140 else if (TM.getOptLevel() == CodeGenOptLevel::Aggressive)
141 // Aggressively for speed, small size and debug illusion sacrificed
142 OptimizationGoal = 2;
143 else if (TM.getOptLevel() > CodeGenOptLevel::None)
144 // For speed, but small size and good debug illusion preserved
145 OptimizationGoal = 1;
146 else // TM.getOptLevel() == CodeGenOptLevel::None
147 // For good debugging, but speed and small size preserved
148 OptimizationGoal = 5;
149
150 // Combine a new optimization goal with existing ones.
151 if (OptimizationGoals == -1) // uninitialized goals
152 OptimizationGoals = OptimizationGoal;
153 else if (OptimizationGoals != (int)OptimizationGoal) // conflicting goals
154 OptimizationGoals = 0;
155
156 if (Subtarget->isTargetCOFF()) {
157 bool Local = F.hasLocalLinkage();
161
162 OutStreamer->beginCOFFSymbolDef(CurrentFnSym);
163 OutStreamer->emitCOFFSymbolStorageClass(Scl);
164 OutStreamer->emitCOFFSymbolType(Type);
165 OutStreamer->endCOFFSymbolDef();
166 }
167
168 // Emit the rest of the function body.
170
171 // Emit the XRay table for this function.
173
174 // If we need V4T thumb mode Register Indirect Jump pads, emit them.
175 // These are created per function, rather than per TU, since it's
176 // relatively easy to exceed the thumb branch range within a TU.
177 if (! ThumbIndirectPads.empty()) {
178 auto &TS =
179 static_cast<ARMTargetStreamer &>(*OutStreamer->getTargetStreamer());
180 TS.emitCode16();
182 for (std::pair<unsigned, MCSymbol *> &TIP : ThumbIndirectPads) {
183 OutStreamer->emitLabel(TIP.second);
185 .addReg(TIP.first)
186 // Add predicate operands.
188 .addReg(0));
189 }
190 ThumbIndirectPads.clear();
191 }
192
193 // We didn't modify anything.
194 return false;
195}
196
198 raw_ostream &O) {
199 assert(MO.isGlobal() && "caller should check MO.isGlobal");
200 unsigned TF = MO.getTargetFlags();
201 if (TF & ARMII::MO_LO16)
202 O << ":lower16:";
203 else if (TF & ARMII::MO_HI16)
204 O << ":upper16:";
205 else if (TF & ARMII::MO_LO_0_7)
206 O << ":lower0_7:";
207 else if (TF & ARMII::MO_LO_8_15)
208 O << ":lower8_15:";
209 else if (TF & ARMII::MO_HI_0_7)
210 O << ":upper0_7:";
211 else if (TF & ARMII::MO_HI_8_15)
212 O << ":upper8_15:";
213
214 GetARMGVSymbol(MO.getGlobal(), TF)->print(O, MAI);
215 printOffset(MO.getOffset(), O);
216}
217
219 raw_ostream &O) {
220 const MachineOperand &MO = MI->getOperand(OpNum);
221
222 switch (MO.getType()) {
223 default: llvm_unreachable("<unknown operand type>");
225 Register Reg = MO.getReg();
226 assert(Reg.isPhysical());
227 assert(!MO.getSubReg() && "Subregs should be eliminated!");
228 if(ARM::GPRPairRegClass.contains(Reg)) {
229 const MachineFunction &MF = *MI->getParent()->getParent();
230 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
231 Reg = TRI->getSubReg(Reg, ARM::gsub_0);
232 }
234 break;
235 }
237 O << '#';
238 unsigned TF = MO.getTargetFlags();
239 if (TF == ARMII::MO_LO16)
240 O << ":lower16:";
241 else if (TF == ARMII::MO_HI16)
242 O << ":upper16:";
243 else if (TF == ARMII::MO_LO_0_7)
244 O << ":lower0_7:";
245 else if (TF == ARMII::MO_LO_8_15)
246 O << ":lower8_15:";
247 else if (TF == ARMII::MO_HI_0_7)
248 O << ":upper0_7:";
249 else if (TF == ARMII::MO_HI_8_15)
250 O << ":upper8_15:";
251 O << MO.getImm();
252 break;
253 }
255 MO.getMBB()->getSymbol()->print(O, MAI);
256 return;
258 PrintSymbolOperand(MO, O);
259 break;
260 }
262 if (Subtarget->genExecuteOnly())
263 llvm_unreachable("execute-only should not generate constant pools");
264 GetCPISymbol(MO.getIndex())->print(O, MAI);
265 break;
266 }
267}
268
270 // The AsmPrinter::GetCPISymbol superclass method tries to use CPID as
271 // indexes in MachineConstantPool, which isn't in sync with indexes used here.
272 const DataLayout &DL = getDataLayout();
273 return OutContext.getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +
274 "CPI" + Twine(getFunctionNumber()) + "_" +
275 Twine(CPID));
276}
277
278//===--------------------------------------------------------------------===//
279
280MCSymbol *ARMAsmPrinter::
281GetARMJTIPICJumpTableLabel(unsigned uid) const {
282 const DataLayout &DL = getDataLayout();
283 SmallString<60> Name;
284 raw_svector_ostream(Name) << DL.getPrivateGlobalPrefix() << "JTI"
285 << getFunctionNumber() << '_' << uid;
286 return OutContext.getOrCreateSymbol(Name);
287}
288
290 const char *ExtraCode, raw_ostream &O) {
291 // Does this asm operand have a single letter operand modifier?
292 if (ExtraCode && ExtraCode[0]) {
293 if (ExtraCode[1] != 0) return true; // Unknown modifier.
294
295 switch (ExtraCode[0]) {
296 default:
297 // See if this is a generic print operand
298 return AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O);
299 case 'P': // Print a VFP double precision register.
300 case 'q': // Print a NEON quad precision register.
301 printOperand(MI, OpNum, O);
302 return false;
303 case 'y': // Print a VFP single precision register as indexed double.
304 if (MI->getOperand(OpNum).isReg()) {
305 MCRegister Reg = MI->getOperand(OpNum).getReg().asMCReg();
306 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
307 // Find the 'd' register that has this 's' register as a sub-register,
308 // and determine the lane number.
309 for (MCPhysReg SR : TRI->superregs(Reg)) {
310 if (!ARM::DPRRegClass.contains(SR))
311 continue;
312 bool Lane0 = TRI->getSubReg(SR, ARM::ssub_0) == Reg;
313 O << ARMInstPrinter::getRegisterName(SR) << (Lane0 ? "[0]" : "[1]");
314 return false;
315 }
316 }
317 return true;
318 case 'B': // Bitwise inverse of integer or symbol without a preceding #.
319 if (!MI->getOperand(OpNum).isImm())
320 return true;
321 O << ~(MI->getOperand(OpNum).getImm());
322 return false;
323 case 'L': // The low 16 bits of an immediate constant.
324 if (!MI->getOperand(OpNum).isImm())
325 return true;
326 O << (MI->getOperand(OpNum).getImm() & 0xffff);
327 return false;
328 case 'M': { // A register range suitable for LDM/STM.
329 if (!MI->getOperand(OpNum).isReg())
330 return true;
331 const MachineOperand &MO = MI->getOperand(OpNum);
332 Register RegBegin = MO.getReg();
333 // This takes advantage of the 2 operand-ness of ldm/stm and that we've
334 // already got the operands in registers that are operands to the
335 // inline asm statement.
336 O << "{";
337 if (ARM::GPRPairRegClass.contains(RegBegin)) {
338 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
339 Register Reg0 = TRI->getSubReg(RegBegin, ARM::gsub_0);
340 O << ARMInstPrinter::getRegisterName(Reg0) << ", ";
341 RegBegin = TRI->getSubReg(RegBegin, ARM::gsub_1);
342 }
343 O << ARMInstPrinter::getRegisterName(RegBegin);
344
345 // FIXME: The register allocator not only may not have given us the
346 // registers in sequence, but may not be in ascending registers. This
347 // will require changes in the register allocator that'll need to be
348 // propagated down here if the operands change.
349 unsigned RegOps = OpNum + 1;
350 while (MI->getOperand(RegOps).isReg()) {
351 O << ", "
352 << ARMInstPrinter::getRegisterName(MI->getOperand(RegOps).getReg());
353 RegOps++;
354 }
355
356 O << "}";
357
358 return false;
359 }
360 case 'R': // The most significant register of a pair.
361 case 'Q': { // The least significant register of a pair.
362 if (OpNum == 0)
363 return true;
364 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
365 if (!FlagsOP.isImm())
366 return true;
367 InlineAsm::Flag F(FlagsOP.getImm());
368
369 // This operand may not be the one that actually provides the register. If
370 // it's tied to a previous one then we should refer instead to that one
371 // for registers and their classes.
372 unsigned TiedIdx;
373 if (F.isUseOperandTiedToDef(TiedIdx)) {
374 for (OpNum = InlineAsm::MIOp_FirstOperand; TiedIdx; --TiedIdx) {
375 unsigned OpFlags = MI->getOperand(OpNum).getImm();
376 const InlineAsm::Flag F(OpFlags);
377 OpNum += F.getNumOperandRegisters() + 1;
378 }
379 F = InlineAsm::Flag(MI->getOperand(OpNum).getImm());
380
381 // Later code expects OpNum to be pointing at the register rather than
382 // the flags.
383 OpNum += 1;
384 }
385
386 const unsigned NumVals = F.getNumOperandRegisters();
387 unsigned RC;
388 bool FirstHalf;
389 const ARMBaseTargetMachine &ATM =
390 static_cast<const ARMBaseTargetMachine &>(TM);
391
392 // 'Q' should correspond to the low order register and 'R' to the high
393 // order register. Whether this corresponds to the upper or lower half
394 // depends on the endianess mode.
395 if (ExtraCode[0] == 'Q')
396 FirstHalf = ATM.isLittleEndian();
397 else
398 // ExtraCode[0] == 'R'.
399 FirstHalf = !ATM.isLittleEndian();
400 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
401 if (F.hasRegClassConstraint(RC) &&
402 ARM::GPRPairRegClass.hasSubClassEq(TRI->getRegClass(RC))) {
403 if (NumVals != 1)
404 return true;
405 const MachineOperand &MO = MI->getOperand(OpNum);
406 if (!MO.isReg())
407 return true;
408 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
409 Register Reg =
410 TRI->getSubReg(MO.getReg(), FirstHalf ? ARM::gsub_0 : ARM::gsub_1);
412 return false;
413 }
414 if (NumVals != 2)
415 return true;
416 unsigned RegOp = FirstHalf ? OpNum : OpNum + 1;
417 if (RegOp >= MI->getNumOperands())
418 return true;
419 const MachineOperand &MO = MI->getOperand(RegOp);
420 if (!MO.isReg())
421 return true;
422 Register Reg = MO.getReg();
424 return false;
425 }
426
427 case 'e': // The low doubleword register of a NEON quad register.
428 case 'f': { // The high doubleword register of a NEON quad register.
429 if (!MI->getOperand(OpNum).isReg())
430 return true;
431 Register Reg = MI->getOperand(OpNum).getReg();
432 if (!ARM::QPRRegClass.contains(Reg))
433 return true;
434 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
436 TRI->getSubReg(Reg, ExtraCode[0] == 'e' ? ARM::dsub_0 : ARM::dsub_1);
438 return false;
439 }
440
441 // This modifier is not yet supported.
442 case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1.
443 return true;
444 case 'H': { // The highest-numbered register of a pair.
445 const MachineOperand &MO = MI->getOperand(OpNum);
446 if (!MO.isReg())
447 return true;
448 const MachineFunction &MF = *MI->getParent()->getParent();
449 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
450 Register Reg = MO.getReg();
451 if(!ARM::GPRPairRegClass.contains(Reg))
452 return false;
453 Reg = TRI->getSubReg(Reg, ARM::gsub_1);
455 return false;
456 }
457 }
458 }
459
460 printOperand(MI, OpNum, O);
461 return false;
462}
463
465 unsigned OpNum, const char *ExtraCode,
466 raw_ostream &O) {
467 // Does this asm operand have a single letter operand modifier?
468 if (ExtraCode && ExtraCode[0]) {
469 if (ExtraCode[1] != 0) return true; // Unknown modifier.
470
471 switch (ExtraCode[0]) {
472 case 'A': // A memory operand for a VLD1/VST1 instruction.
473 default: return true; // Unknown modifier.
474 case 'm': // The base register of a memory operand.
475 if (!MI->getOperand(OpNum).isReg())
476 return true;
477 O << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg());
478 return false;
479 }
480 }
481
482 const MachineOperand &MO = MI->getOperand(OpNum);
483 assert(MO.isReg() && "unexpected inline asm memory operand");
484 O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
485 return false;
486}
487
488static bool isThumb(const MCSubtargetInfo& STI) {
489 return STI.hasFeature(ARM::ModeThumb);
490}
491
493 const MCSubtargetInfo *EndInfo) const {
494 // If either end mode is unknown (EndInfo == NULL) or different than
495 // the start mode, then restore the start mode.
496 const bool WasThumb = isThumb(StartInfo);
497 if (!EndInfo || WasThumb != isThumb(*EndInfo)) {
498 auto &TS =
499 static_cast<ARMTargetStreamer &>(*OutStreamer->getTargetStreamer());
500 if (WasThumb)
501 TS.emitCode16();
502 else
503 TS.emitCode32();
504 }
505}
506
508 const Triple &TT = TM.getTargetTriple();
509 auto &TS =
510 static_cast<ARMTargetStreamer &>(*OutStreamer->getTargetStreamer());
511 // Use unified assembler syntax.
513
514 // Emit ARM Build Attributes
515 if (TT.isOSBinFormatELF())
516 emitAttributes();
517
518 // Use the triple's architecture and subarchitecture to determine
519 // if we're thumb for the purposes of the top level code16 state.
520 if (!M.getModuleInlineAsm().empty() && TT.isThumb())
521 TS.emitCode16();
522}
523
524static void
527 // L_foo$stub:
528 OutStreamer.emitLabel(StubLabel);
529 // .indirect_symbol _foo
531
532 if (MCSym.getInt())
533 // External to current translation unit.
534 OutStreamer.emitIntValue(0, 4/*size*/);
535 else
536 // Internal to current translation unit.
537 //
538 // When we place the LSDA into the TEXT section, the type info
539 // pointers need to be indirect and pc-rel. We accomplish this by
540 // using NLPs; however, sometimes the types are local to the file.
541 // We need to fill in the value for the NLP in those cases.
542 OutStreamer.emitValue(
543 MCSymbolRefExpr::create(MCSym.getPointer(), OutStreamer.getContext()),
544 4 /*size*/);
545}
546
547
549 const Triple &TT = TM.getTargetTriple();
550 if (TT.isOSBinFormatMachO()) {
551 // All darwin targets use mach-o.
552 const TargetLoweringObjectFileMachO &TLOFMacho =
554 MachineModuleInfoMachO &MMIMacho =
555 MMI->getObjFileInfo<MachineModuleInfoMachO>();
556
557 // Output non-lazy-pointers for external and common global variables.
559
560 if (!Stubs.empty()) {
561 // Switch with ".non_lazy_symbol_pointer" directive.
562 OutStreamer->switchSection(TLOFMacho.getNonLazySymbolPointerSection());
564
565 for (auto &Stub : Stubs)
566 emitNonLazySymbolPointer(*OutStreamer, Stub.first, Stub.second);
567
568 Stubs.clear();
569 OutStreamer->addBlankLine();
570 }
571
572 Stubs = MMIMacho.GetThreadLocalGVStubList();
573 if (!Stubs.empty()) {
574 // Switch with ".non_lazy_symbol_pointer" directive.
575 OutStreamer->switchSection(TLOFMacho.getThreadLocalPointerSection());
577
578 for (auto &Stub : Stubs)
579 emitNonLazySymbolPointer(*OutStreamer, Stub.first, Stub.second);
580
581 Stubs.clear();
582 OutStreamer->addBlankLine();
583 }
584
585 // Funny Darwin hack: This flag tells the linker that no global symbols
586 // contain code that falls through to other global symbols (e.g. the obvious
587 // implementation of multiple entry points). If this doesn't occur, the
588 // linker can safely perform dead code stripping. Since LLVM never
589 // generates code that does this, it is always safe to set.
590 OutStreamer->emitSubsectionsViaSymbols();
591 }
592
593 // The last attribute to be emitted is ABI_optimization_goals
594 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
595 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
596
597 if (OptimizationGoals > 0 &&
598 (Subtarget->isTargetAEABI() || Subtarget->isTargetGNUAEABI() ||
599 Subtarget->isTargetMuslAEABI()))
601 OptimizationGoals = -1;
602
604}
605
606//===----------------------------------------------------------------------===//
607// Helper routines for emitStartOfAsmFile() and emitEndOfAsmFile()
608// FIXME:
609// The following seem like one-off assembler flags, but they actually need
610// to appear in the .ARM.attributes section in ELF.
611// Instead of subclassing the MCELFStreamer, we do the work here.
612
613 // Returns true if all functions have the same function attribute value.
614 // It also returns true when the module has no functions.
617 return !any_of(M, [&](const Function &F) {
618 return F.getFnAttribute(Attr).getValueAsString() != Value;
619 });
620}
621// Returns true if all functions have the same denormal mode.
622// It also returns true when the module has no functions.
624 StringRef Attr,
626 return !any_of(M, [&](const Function &F) {
627 StringRef AttrVal = F.getFnAttribute(Attr).getValueAsString();
628 return parseDenormalFPAttribute(AttrVal) != Value;
629 });
630}
631
632void ARMAsmPrinter::emitAttributes() {
633 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
634 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
635
637
638 ATS.switchVendor("aeabi");
639
640 // Compute ARM ELF Attributes based on the default subtarget that
641 // we'd have constructed. The existing ARM behavior isn't LTO clean
642 // anyhow.
643 // FIXME: For ifunc related functions we could iterate over and look
644 // for a feature string that doesn't match the default one.
645 const Triple &TT = TM.getTargetTriple();
646 StringRef CPU = TM.getTargetCPU();
647 StringRef FS = TM.getTargetFeatureString();
648 std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
649 if (!FS.empty()) {
650 if (!ArchFS.empty())
651 ArchFS = (Twine(ArchFS) + "," + FS).str();
652 else
653 ArchFS = std::string(FS);
654 }
655 const ARMBaseTargetMachine &ATM =
656 static_cast<const ARMBaseTargetMachine &>(TM);
657 const ARMSubtarget STI(TT, std::string(CPU), ArchFS, ATM,
658 ATM.isLittleEndian());
659
660 // Emit build attributes for the available hardware.
661 ATS.emitTargetAttributes(STI);
662
663 // RW data addressing.
664 if (isPositionIndependent()) {
667 } else if (STI.isRWPI()) {
668 // RWPI specific attributes.
671 }
672
673 // RO data addressing.
674 if (isPositionIndependent() || STI.isROPI()) {
677 }
678
679 // GOT use.
680 if (isPositionIndependent()) {
683 } else {
686 }
687
688 // Set FP Denormals.
689 if (checkDenormalAttributeConsistency(*MMI->getModule(), "denormal-fp-math",
693 else if (checkDenormalAttributeConsistency(*MMI->getModule(),
694 "denormal-fp-math",
698 else if (!TM.Options.UnsafeFPMath)
701 else {
702 if (!STI.hasVFP2Base()) {
703 // When the target doesn't have an FPU (by design or
704 // intention), the assumptions made on the software support
705 // mirror that of the equivalent hardware support *if it
706 // existed*. For v7 and better we indicate that denormals are
707 // flushed preserving sign, and for V6 we indicate that
708 // denormals are flushed to positive zero.
709 if (STI.hasV7Ops())
712 } else if (STI.hasVFP3Base()) {
713 // In VFPv4, VFPv4U, VFPv3, or VFPv3U, it is preserved. That is,
714 // the sign bit of the zero matches the sign bit of the input or
715 // result that is being flushed to zero.
718 }
719 // For VFPv2 implementations it is implementation defined as
720 // to whether denormals are flushed to positive zero or to
721 // whatever the sign of zero is (ARM v7AR ARM 2.7.5). Historically
722 // LLVM has chosen to flush this to positive zero (most likely for
723 // GCC compatibility), so that's the chosen value here (the
724 // absence of its emission implies zero).
725 }
726
727 // Set FP exceptions and rounding
728 if (checkFunctionsAttributeConsistency(*MMI->getModule(),
729 "no-trapping-math", "true") ||
730 TM.Options.NoTrappingFPMath)
733 else if (!TM.Options.UnsafeFPMath) {
735
736 // If the user has permitted this code to choose the IEEE 754
737 // rounding at run-time, emit the rounding attribute.
738 if (TM.Options.HonorSignDependentRoundingFPMathOption)
740 }
741
742 // TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath is the
743 // equivalent of GCC's -ffinite-math-only flag.
744 if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath)
747 else
750
751 // FIXME: add more flags to ARMBuildAttributes.h
752 // 8-bytes alignment stuff.
755
756 // Hard float. Use both S and D registers and conform to AAPCS-VFP.
757 if (getTM().isAAPCS_ABI() && TM.Options.FloatABIType == FloatABI::Hard)
759
760 // FIXME: To support emitting this build attribute as GCC does, the
761 // -mfp16-format option and associated plumbing must be
762 // supported. For now the __fp16 type is exposed by default, so this
763 // attribute should be emitted with value 1.
766
767 if (const Module *SourceModule = MMI->getModule()) {
768 // ABI_PCS_wchar_t to indicate wchar_t width
769 // FIXME: There is no way to emit value 0 (wchar_t prohibited).
770 if (auto WCharWidthValue = mdconst::extract_or_null<ConstantInt>(
771 SourceModule->getModuleFlag("wchar_size"))) {
772 int WCharWidth = WCharWidthValue->getZExtValue();
773 assert((WCharWidth == 2 || WCharWidth == 4) &&
774 "wchar_t width must be 2 or 4 bytes");
776 }
777
778 // ABI_enum_size to indicate enum width
779 // FIXME: There is no way to emit value 0 (enums prohibited) or value 3
780 // (all enums contain a value needing 32 bits to encode).
781 if (auto EnumWidthValue = mdconst::extract_or_null<ConstantInt>(
782 SourceModule->getModuleFlag("min_enum_size"))) {
783 int EnumWidth = EnumWidthValue->getZExtValue();
784 assert((EnumWidth == 1 || EnumWidth == 4) &&
785 "Minimum enum width must be 1 or 4 bytes");
786 int EnumBuildAttr = EnumWidth == 1 ? 1 : 2;
788 }
789
791 SourceModule->getModuleFlag("sign-return-address"));
792 if (PACValue && PACValue->isOne()) {
793 // If "+pacbti" is used as an architecture extension,
794 // Tag_PAC_extension is emitted in
795 // ARMTargetStreamer::emitTargetAttributes().
796 if (!STI.hasPACBTI()) {
799 }
801 }
802
804 SourceModule->getModuleFlag("branch-target-enforcement"));
805 if (BTIValue && BTIValue->isOne()) {
806 // If "+pacbti" is used as an architecture extension,
807 // Tag_BTI_extension is emitted in
808 // ARMTargetStreamer::emitTargetAttributes().
809 if (!STI.hasPACBTI()) {
812 }
814 }
815 }
816
817 // We currently do not support using R9 as the TLS pointer.
818 if (STI.isRWPI())
821 else if (STI.isR9Reserved())
824 else
827}
828
829//===----------------------------------------------------------------------===//
830
831static MCSymbol *getBFLabel(StringRef Prefix, unsigned FunctionNumber,
832 unsigned LabelId, MCContext &Ctx) {
833
834 MCSymbol *Label = Ctx.getOrCreateSymbol(Twine(Prefix)
835 + "BF" + Twine(FunctionNumber) + "_" + Twine(LabelId));
836 return Label;
837}
838
839static MCSymbol *getPICLabel(StringRef Prefix, unsigned FunctionNumber,
840 unsigned LabelId, MCContext &Ctx) {
841
842 MCSymbol *Label = Ctx.getOrCreateSymbol(Twine(Prefix)
843 + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
844 return Label;
845}
846
848 switch (Modifier) {
850 return ARM::S_None;
851 case ARMCP::TLSGD:
852 return ARM::S_TLSGD;
853 case ARMCP::TPOFF:
854 return ARM::S_TPOFF;
855 case ARMCP::GOTTPOFF:
856 return ARM::S_GOTTPOFF;
857 case ARMCP::SBREL:
858 return ARM::S_SBREL;
859 case ARMCP::GOT_PREL:
860 return ARM::S_GOT_PREL;
861 case ARMCP::SECREL:
862 return ARM::S_COFF_SECREL;
863 }
864 llvm_unreachable("Invalid ARMCPModifier!");
865}
866
867MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV,
868 unsigned char TargetFlags) {
869 if (Subtarget->isTargetMachO()) {
870 bool IsIndirect =
871 (TargetFlags & ARMII::MO_NONLAZY) && Subtarget->isGVIndirectSymbol(GV);
872
873 if (!IsIndirect)
874 return getSymbol(GV);
875
876 // FIXME: Remove this when Darwin transition to @GOT like syntax.
877 MCSymbol *MCSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
878 MachineModuleInfoMachO &MMIMachO =
879 MMI->getObjFileInfo<MachineModuleInfoMachO>();
881 GV->isThreadLocal() ? MMIMachO.getThreadLocalGVStubEntry(MCSym)
882 : MMIMachO.getGVStubEntry(MCSym);
883
884 if (!StubSym.getPointer())
886 !GV->hasInternalLinkage());
887 return MCSym;
888 } else if (Subtarget->isTargetCOFF()) {
889 assert(Subtarget->isTargetWindows() &&
890 "Windows is the only supported COFF target");
891
892 bool IsIndirect =
893 (TargetFlags & (ARMII::MO_DLLIMPORT | ARMII::MO_COFFSTUB));
894 if (!IsIndirect)
895 return getSymbol(GV);
896
897 SmallString<128> Name;
898 if (TargetFlags & ARMII::MO_DLLIMPORT)
899 Name = "__imp_";
900 else if (TargetFlags & ARMII::MO_COFFSTUB)
901 Name = ".refptr.";
902 getNameWithPrefix(Name, GV);
903
904 MCSymbol *MCSym = OutContext.getOrCreateSymbol(Name);
905
906 if (TargetFlags & ARMII::MO_COFFSTUB) {
907 MachineModuleInfoCOFF &MMICOFF =
908 MMI->getObjFileInfo<MachineModuleInfoCOFF>();
910 MMICOFF.getGVStubEntry(MCSym);
911
912 if (!StubSym.getPointer())
914 }
915
916 return MCSym;
917 } else if (Subtarget->isTargetELF()) {
918 return getSymbolPreferLocal(*GV);
919 }
920 llvm_unreachable("unexpected target");
921}
922
925 const DataLayout &DL = getDataLayout();
926 int Size = DL.getTypeAllocSize(MCPV->getType());
927
928 ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
929
930 if (ACPV->isPromotedGlobal()) {
931 // This constant pool entry is actually a global whose storage has been
932 // promoted into the constant pool. This global may be referenced still
933 // by debug information, and due to the way AsmPrinter is set up, the debug
934 // info is immutable by the time we decide to promote globals to constant
935 // pools. Because of this, we need to ensure we emit a symbol for the global
936 // with private linkage (the default) so debug info can refer to it.
937 //
938 // However, if this global is promoted into several functions we must ensure
939 // we don't try and emit duplicate symbols!
940 auto *ACPC = cast<ARMConstantPoolConstant>(ACPV);
941 for (const auto *GV : ACPC->promotedGlobals()) {
942 if (!EmittedPromotedGlobalLabels.count(GV)) {
943 MCSymbol *GVSym = getSymbol(GV);
944 OutStreamer->emitLabel(GVSym);
945 EmittedPromotedGlobalLabels.insert(GV);
946 }
947 }
948 return emitGlobalConstant(DL, ACPC->getPromotedGlobalInit());
949 }
950
951 MCSymbol *MCSym;
952 if (ACPV->isLSDA()) {
953 MCSym = getMBBExceptionSym(MF->front());
954 } else if (ACPV->isBlockAddress()) {
955 const BlockAddress *BA =
956 cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress();
957 MCSym = GetBlockAddressSymbol(BA);
958 } else if (ACPV->isGlobalValue()) {
959 const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV();
960
961 // On Darwin, const-pool entries may get the "FOO$non_lazy_ptr" mangling, so
962 // flag the global as MO_NONLAZY.
963 unsigned char TF = Subtarget->isTargetMachO() ? ARMII::MO_NONLAZY : 0;
964 MCSym = GetARMGVSymbol(GV, TF);
965 } else if (ACPV->isMachineBasicBlock()) {
966 const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB();
967 MCSym = MBB->getSymbol();
968 } else {
969 assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
970 auto Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol();
971 MCSym = GetExternalSymbolSymbol(Sym);
972 }
973
974 // Create an MCSymbol for the reference.
975 const MCExpr *Expr = MCSymbolRefExpr::create(
977
978 if (ACPV->getPCAdjustment()) {
979 MCSymbol *PCLabel =
980 getPICLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(),
981 ACPV->getLabelId(), OutContext);
982 const MCExpr *PCRelExpr = MCSymbolRefExpr::create(PCLabel, OutContext);
983 PCRelExpr =
984 MCBinaryExpr::createAdd(PCRelExpr,
986 OutContext),
987 OutContext);
988 if (ACPV->mustAddCurrentAddress()) {
989 // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
990 // label, so just emit a local label end reference that instead.
991 MCSymbol *DotSym = OutContext.createTempSymbol();
992 OutStreamer->emitLabel(DotSym);
993 const MCExpr *DotExpr = MCSymbolRefExpr::create(DotSym, OutContext);
994 PCRelExpr = MCBinaryExpr::createSub(PCRelExpr, DotExpr, OutContext);
995 }
996 Expr = MCBinaryExpr::createSub(Expr, PCRelExpr, OutContext);
997 }
998 OutStreamer->emitValue(Expr, Size);
999}
1000
1002 const MachineOperand &MO1 = MI->getOperand(1);
1003 unsigned JTI = MO1.getIndex();
1004
1005 // Make sure the Thumb jump table is 4-byte aligned. This will be a nop for
1006 // ARM mode tables.
1007 emitAlignment(Align(4));
1008
1009 // Emit a label for the jump table.
1010 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);
1011 OutStreamer->emitLabel(JTISymbol);
1012
1013 // Mark the jump table as data-in-code.
1014 OutStreamer->emitDataRegion(MCDR_DataRegionJT32);
1015
1016 // Emit each entry of the table.
1017 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1018 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1019 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1020
1021 for (MachineBasicBlock *MBB : JTBBs) {
1022 // Construct an MCExpr for the entry. We want a value of the form:
1023 // (BasicBlockAddr - TableBeginAddr)
1024 //
1025 // For example, a table with entries jumping to basic blocks BB0 and BB1
1026 // would look like:
1027 // LJTI_0_0:
1028 // .word (LBB0 - LJTI_0_0)
1029 // .word (LBB1 - LJTI_0_0)
1030 const MCExpr *Expr = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext);
1031
1032 if (isPositionIndependent() || Subtarget->isROPI())
1033 Expr = MCBinaryExpr::createSub(Expr, MCSymbolRefExpr::create(JTISymbol,
1034 OutContext),
1035 OutContext);
1036 // If we're generating a table of Thumb addresses in static relocation
1037 // model, we need to add one to keep interworking correctly.
1038 else if (AFI->isThumbFunction())
1040 OutContext);
1041 OutStreamer->emitValue(Expr, 4);
1042 }
1043 // Mark the end of jump table data-in-code region.
1044 OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
1045}
1046
1048 const MachineOperand &MO1 = MI->getOperand(1);
1049 unsigned JTI = MO1.getIndex();
1050
1051 // Make sure the Thumb jump table is 4-byte aligned. This will be a nop for
1052 // ARM mode tables.
1053 emitAlignment(Align(4));
1054
1055 // Emit a label for the jump table.
1056 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);
1057 OutStreamer->emitLabel(JTISymbol);
1058
1059 // Emit each entry of the table.
1060 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1061 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1062 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1063
1064 for (MachineBasicBlock *MBB : JTBBs) {
1065 const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::create(MBB->getSymbol(),
1066 OutContext);
1067 // If this isn't a TBB or TBH, the entries are direct branch instructions.
1069 .addExpr(MBBSymbolExpr)
1070 .addImm(ARMCC::AL)
1071 .addReg(0));
1072 }
1073}
1074
1076 unsigned OffsetWidth) {
1077 assert((OffsetWidth == 1 || OffsetWidth == 2) && "invalid tbb/tbh width");
1078 const MachineOperand &MO1 = MI->getOperand(1);
1079 unsigned JTI = MO1.getIndex();
1080
1081 if (Subtarget->isThumb1Only())
1082 emitAlignment(Align(4));
1083
1084 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);
1085 OutStreamer->emitLabel(JTISymbol);
1086
1087 // Emit each entry of the table.
1088 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1089 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1090 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1091
1092 // Mark the jump table as data-in-code.
1093 OutStreamer->emitDataRegion(OffsetWidth == 1 ? MCDR_DataRegionJT8
1095
1096 for (auto *MBB : JTBBs) {
1097 const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::create(MBB->getSymbol(),
1098 OutContext);
1099 // Otherwise it's an offset from the dispatch instruction. Construct an
1100 // MCExpr for the entry. We want a value of the form:
1101 // (BasicBlockAddr - TBBInstAddr + 4) / 2
1102 //
1103 // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
1104 // would look like:
1105 // LJTI_0_0:
1106 // .byte (LBB0 - (LCPI0_0 + 4)) / 2
1107 // .byte (LBB1 - (LCPI0_0 + 4)) / 2
1108 // where LCPI0_0 is a label defined just before the TBB instruction using
1109 // this table.
1110 MCSymbol *TBInstPC = GetCPISymbol(MI->getOperand(0).getImm());
1111 const MCExpr *Expr = MCBinaryExpr::createAdd(
1114 Expr = MCBinaryExpr::createSub(MBBSymbolExpr, Expr, OutContext);
1116 OutContext);
1117 OutStreamer->emitValue(Expr, OffsetWidth);
1118 }
1119 // Mark the end of jump table data-in-code region. 32-bit offsets use
1120 // actual branch instructions here, so we don't mark those as a data-region
1121 // at all.
1122 OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
1123
1124 // Make sure the next instruction is 2-byte aligned.
1125 emitAlignment(Align(2));
1126}
1127
1128std::tuple<const MCSymbol *, uint64_t, const MCSymbol *,
1131 const MachineInstr *BranchInstr,
1132 const MCSymbol *BranchLabel) const {
1134 const MCSymbol *BaseLabel;
1135 uint64_t BaseOffset = 0;
1136 switch (BranchInstr->getOpcode()) {
1137 case ARM::BR_JTadd:
1138 case ARM::BR_JTr:
1139 case ARM::tBR_JTr:
1140 // Word relative to the jump table address.
1142 BaseLabel = GetARMJTIPICJumpTableLabel(JTI);
1143 break;
1144 case ARM::tTBH_JT:
1145 case ARM::t2TBH_JT:
1146 // half-word shifted left, relative to *after* the branch instruction.
1148 BranchLabel = GetCPISymbol(BranchInstr->getOperand(3).getImm());
1149 BaseLabel = BranchLabel;
1150 BaseOffset = 4;
1151 break;
1152 case ARM::tTBB_JT:
1153 case ARM::t2TBB_JT:
1154 // byte shifted left, relative to *after* the branch instruction.
1156 BranchLabel = GetCPISymbol(BranchInstr->getOperand(3).getImm());
1157 BaseLabel = BranchLabel;
1158 BaseOffset = 4;
1159 break;
1160 case ARM::t2BR_JT:
1161 // Direct jump.
1162 BaseLabel = nullptr;
1164 break;
1165 default:
1166 llvm_unreachable("Unknown jump table instruction");
1167 }
1168
1169 return std::make_tuple(BaseLabel, BaseOffset, BranchLabel, EntrySize);
1170}
1171
1172void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
1174 "Only instruction which are involved into frame setup code are allowed");
1175
1176 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
1177 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1178 const MachineFunction &MF = *MI->getParent()->getParent();
1179 const TargetRegisterInfo *TargetRegInfo =
1181 const MachineRegisterInfo &MachineRegInfo = MF.getRegInfo();
1182
1183 Register FramePtr = TargetRegInfo->getFrameRegister(MF);
1184 unsigned Opc = MI->getOpcode();
1185 unsigned SrcReg, DstReg;
1186
1187 switch (Opc) {
1188 case ARM::tPUSH:
1189 // special case: tPUSH does not have src/dst regs.
1190 SrcReg = DstReg = ARM::SP;
1191 break;
1192 case ARM::tLDRpci:
1193 case ARM::t2MOVi16:
1194 case ARM::t2MOVTi16:
1195 case ARM::tMOVi8:
1196 case ARM::tADDi8:
1197 case ARM::tLSLri:
1198 // special cases:
1199 // 1) for Thumb1 code we sometimes materialize the constant via constpool
1200 // load.
1201 // 2) for Thumb1 execute only code we materialize the constant via the
1202 // following pattern:
1203 // movs r3, #:upper8_15:<const>
1204 // lsls r3, #8
1205 // adds r3, #:upper0_7:<const>
1206 // lsls r3, #8
1207 // adds r3, #:lower8_15:<const>
1208 // lsls r3, #8
1209 // adds r3, #:lower0_7:<const>
1210 // So we need to special-case MOVS, ADDS and LSLS, and keep track of
1211 // where we are in the sequence with the simplest of state machines.
1212 // 3) for Thumb2 execute only code we materialize the constant via
1213 // immediate constants in 2 separate instructions (MOVW/MOVT).
1214 SrcReg = ~0U;
1215 DstReg = MI->getOperand(0).getReg();
1216 break;
1217 case ARM::VMRS:
1218 SrcReg = ARM::FPSCR;
1219 DstReg = MI->getOperand(0).getReg();
1220 break;
1221 case ARM::VMRS_FPEXC:
1222 SrcReg = ARM::FPEXC;
1223 DstReg = MI->getOperand(0).getReg();
1224 break;
1225 default:
1226 SrcReg = MI->getOperand(1).getReg();
1227 DstReg = MI->getOperand(0).getReg();
1228 break;
1229 }
1230
1231 // Try to figure out the unwinding opcode out of src / dst regs.
1232 if (MI->mayStore()) {
1233 // Register saves.
1234 assert(DstReg == ARM::SP &&
1235 "Only stack pointer as a destination reg is supported");
1236
1238 // Skip src & dst reg, and pred ops.
1239 unsigned StartOp = 2 + 2;
1240 // Use all the operands.
1241 unsigned NumOffset = 0;
1242 // Amount of SP adjustment folded into a push, before the
1243 // registers are stored (pad at higher addresses).
1244 unsigned PadBefore = 0;
1245 // Amount of SP adjustment folded into a push, after the
1246 // registers are stored (pad at lower addresses).
1247 unsigned PadAfter = 0;
1248
1249 switch (Opc) {
1250 default:
1251 MI->print(errs());
1252 llvm_unreachable("Unsupported opcode for unwinding information");
1253 case ARM::tPUSH:
1254 // Special case here: no src & dst reg, but two extra imp ops.
1255 StartOp = 2; NumOffset = 2;
1256 [[fallthrough]];
1257 case ARM::STMDB_UPD:
1258 case ARM::t2STMDB_UPD:
1259 case ARM::VSTMDDB_UPD:
1260 assert(SrcReg == ARM::SP &&
1261 "Only stack pointer as a source reg is supported");
1262 for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset;
1263 i != NumOps; ++i) {
1264 const MachineOperand &MO = MI->getOperand(i);
1265 // Actually, there should never be any impdef stuff here. Skip it
1266 // temporary to workaround PR11902.
1267 if (MO.isImplicit())
1268 continue;
1269 // Registers, pushed as a part of folding an SP update into the
1270 // push instruction are marked as undef and should not be
1271 // restored when unwinding, because the function can modify the
1272 // corresponding stack slots.
1273 if (MO.isUndef()) {
1274 assert(RegList.empty() &&
1275 "Pad registers must come before restored ones");
1276 unsigned Width =
1277 TargetRegInfo->getRegSizeInBits(MO.getReg(), MachineRegInfo) / 8;
1278 PadAfter += Width;
1279 continue;
1280 }
1281 // Check for registers that are remapped (for a Thumb1 prologue that
1282 // saves high registers).
1283 Register Reg = MO.getReg();
1284 if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(Reg))
1285 Reg = RemappedReg;
1286 RegList.push_back(Reg);
1287 }
1288 break;
1289 case ARM::STR_PRE_IMM:
1290 case ARM::STR_PRE_REG:
1291 case ARM::t2STR_PRE:
1292 assert(MI->getOperand(2).getReg() == ARM::SP &&
1293 "Only stack pointer as a source reg is supported");
1294 if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(SrcReg))
1295 SrcReg = RemappedReg;
1296
1297 RegList.push_back(SrcReg);
1298 break;
1299 case ARM::t2STRD_PRE:
1300 assert(MI->getOperand(3).getReg() == ARM::SP &&
1301 "Only stack pointer as a source reg is supported");
1302 SrcReg = MI->getOperand(1).getReg();
1303 if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(SrcReg))
1304 SrcReg = RemappedReg;
1305 RegList.push_back(SrcReg);
1306 SrcReg = MI->getOperand(2).getReg();
1307 if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(SrcReg))
1308 SrcReg = RemappedReg;
1309 RegList.push_back(SrcReg);
1310 PadBefore = -MI->getOperand(4).getImm() - 8;
1311 break;
1312 }
1313 if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM) {
1314 if (PadBefore)
1315 ATS.emitPad(PadBefore);
1316 ATS.emitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);
1317 // Account for the SP adjustment, folded into the push.
1318 if (PadAfter)
1319 ATS.emitPad(PadAfter);
1320 }
1321 } else {
1322 // Changes of stack / frame pointer.
1323 if (SrcReg == ARM::SP) {
1324 int64_t Offset = 0;
1325 switch (Opc) {
1326 default:
1327 MI->print(errs());
1328 llvm_unreachable("Unsupported opcode for unwinding information");
1329 case ARM::tLDRspi:
1330 // Used to restore LR in a prologue which uses it as a temporary, has
1331 // no effect on unwind tables.
1332 return;
1333 case ARM::MOVr:
1334 case ARM::tMOVr:
1335 Offset = 0;
1336 break;
1337 case ARM::ADDri:
1338 case ARM::t2ADDri:
1339 case ARM::t2ADDri12:
1340 case ARM::t2ADDspImm:
1341 case ARM::t2ADDspImm12:
1342 Offset = -MI->getOperand(2).getImm();
1343 break;
1344 case ARM::SUBri:
1345 case ARM::t2SUBri:
1346 case ARM::t2SUBri12:
1347 case ARM::t2SUBspImm:
1348 case ARM::t2SUBspImm12:
1349 Offset = MI->getOperand(2).getImm();
1350 break;
1351 case ARM::tSUBspi:
1352 Offset = MI->getOperand(2).getImm()*4;
1353 break;
1354 case ARM::tADDspi:
1355 case ARM::tADDrSPi:
1356 Offset = -MI->getOperand(2).getImm()*4;
1357 break;
1358 case ARM::tADDhirr:
1359 Offset =
1360 -AFI->EHPrologueOffsetInRegs.lookup(MI->getOperand(2).getReg());
1361 break;
1362 }
1363
1364 if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM) {
1365 if (DstReg == FramePtr && FramePtr != ARM::SP)
1366 // Set-up of the frame pointer. Positive values correspond to "add"
1367 // instruction.
1368 ATS.emitSetFP(FramePtr, ARM::SP, -Offset);
1369 else if (DstReg == ARM::SP) {
1370 // Change of SP by an offset. Positive values correspond to "sub"
1371 // instruction.
1372 ATS.emitPad(Offset);
1373 } else {
1374 // Move of SP to a register. Positive values correspond to an "add"
1375 // instruction.
1376 ATS.emitMovSP(DstReg, -Offset);
1377 }
1378 }
1379 } else if (DstReg == ARM::SP) {
1380 MI->print(errs());
1381 llvm_unreachable("Unsupported opcode for unwinding information");
1382 } else {
1383 int64_t Offset = 0;
1384 switch (Opc) {
1385 case ARM::tMOVr:
1386 // If a Thumb1 function spills r8-r11, we copy the values to low
1387 // registers before pushing them. Record the copy so we can emit the
1388 // correct ".save" later.
1389 AFI->EHPrologueRemappedRegs[DstReg] = SrcReg;
1390 break;
1391 case ARM::VMRS:
1392 case ARM::VMRS_FPEXC:
1393 // If a function spills FPSCR or FPEXC, we copy the values to low
1394 // registers before pushing them. However, we can't issue annotations
1395 // for FP status registers because ".save" requires GPR registers, and
1396 // ".vsave" requires DPR registers, so don't record the copy and simply
1397 // emit annotations for the source registers used for the store.
1398 break;
1399 case ARM::tLDRpci: {
1400 // Grab the constpool index and check, whether it corresponds to
1401 // original or cloned constpool entry.
1402 unsigned CPI = MI->getOperand(1).getIndex();
1403 const MachineConstantPool *MCP = MF.getConstantPool();
1404 if (CPI >= MCP->getConstants().size())
1405 CPI = AFI->getOriginalCPIdx(CPI);
1406 assert(CPI != -1U && "Invalid constpool index");
1407
1408 // Derive the actual offset.
1409 const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI];
1410 assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry");
1411 Offset = cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue();
1412 AFI->EHPrologueOffsetInRegs[DstReg] = Offset;
1413 break;
1414 }
1415 case ARM::t2MOVi16:
1416 Offset = MI->getOperand(1).getImm();
1417 AFI->EHPrologueOffsetInRegs[DstReg] = Offset;
1418 break;
1419 case ARM::t2MOVTi16:
1420 Offset = MI->getOperand(2).getImm();
1421 AFI->EHPrologueOffsetInRegs[DstReg] |= (Offset << 16);
1422 break;
1423 case ARM::tMOVi8:
1424 Offset = MI->getOperand(2).getImm();
1425 AFI->EHPrologueOffsetInRegs[DstReg] = Offset;
1426 break;
1427 case ARM::tLSLri:
1428 assert(MI->getOperand(3).getImm() == 8 &&
1429 "The shift amount is not equal to 8");
1430 assert(MI->getOperand(2).getReg() == MI->getOperand(0).getReg() &&
1431 "The source register is not equal to the destination register");
1432 AFI->EHPrologueOffsetInRegs[DstReg] <<= 8;
1433 break;
1434 case ARM::tADDi8:
1435 assert(MI->getOperand(2).getReg() == MI->getOperand(0).getReg() &&
1436 "The source register is not equal to the destination register");
1437 Offset = MI->getOperand(3).getImm();
1438 AFI->EHPrologueOffsetInRegs[DstReg] += Offset;
1439 break;
1440 case ARM::t2PAC:
1441 case ARM::t2PACBTI:
1442 AFI->EHPrologueRemappedRegs[ARM::R12] = ARM::RA_AUTH_CODE;
1443 break;
1444 default:
1445 MI->print(errs());
1446 llvm_unreachable("Unsupported opcode for unwinding information");
1447 }
1448 }
1449 }
1450}
1451
1452// Simple pseudo-instructions have their lowering (with expansion to real
1453// instructions) auto-generated.
1454#include "ARMGenMCPseudoLowering.inc"
1455
1457 ARM_MC::verifyInstructionPredicates(MI->getOpcode(),
1458 getSubtargetInfo().getFeatureBits());
1459
1460 const DataLayout &DL = getDataLayout();
1461 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
1462 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1463
1464 // If we just ended a constant pool, mark it as such.
1465 if (InConstantPool && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) {
1466 OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
1467 InConstantPool = false;
1468 }
1469
1470 // Emit unwinding stuff for frame-related instructions
1471 if (Subtarget->isTargetEHABICompatible() &&
1472 MI->getFlag(MachineInstr::FrameSetup))
1473 EmitUnwindingInstruction(MI);
1474
1475 // Do any auto-generated pseudo lowerings.
1476 if (MCInst OutInst; lowerPseudoInstExpansion(MI, OutInst)) {
1477 EmitToStreamer(*OutStreamer, OutInst);
1478 return;
1479 }
1480
1481 assert(!convertAddSubFlagsOpcode(MI->getOpcode()) &&
1482 "Pseudo flag setting opcode should be expanded early");
1483
1484 // Check for manual lowerings.
1485 unsigned Opc = MI->getOpcode();
1486 switch (Opc) {
1487 case ARM::t2MOVi32imm: llvm_unreachable("Should be lowered by thumb2it pass");
1488 case ARM::DBG_VALUE: llvm_unreachable("Should be handled by generic printing");
1489 case ARM::LEApcrel:
1490 case ARM::tLEApcrel:
1491 case ARM::t2LEApcrel: {
1492 // FIXME: Need to also handle globals and externals
1493 MCSymbol *CPISymbol = GetCPISymbol(MI->getOperand(1).getIndex());
1494 EmitToStreamer(*OutStreamer, MCInstBuilder(MI->getOpcode() ==
1495 ARM::t2LEApcrel ? ARM::t2ADR
1496 : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR
1497 : ARM::ADR))
1498 .addReg(MI->getOperand(0).getReg())
1500 // Add predicate operands.
1501 .addImm(MI->getOperand(2).getImm())
1502 .addReg(MI->getOperand(3).getReg()));
1503 return;
1504 }
1505 case ARM::LEApcrelJT:
1506 case ARM::tLEApcrelJT:
1507 case ARM::t2LEApcrelJT: {
1508 MCSymbol *JTIPICSymbol =
1509 GetARMJTIPICJumpTableLabel(MI->getOperand(1).getIndex());
1510 EmitToStreamer(*OutStreamer, MCInstBuilder(MI->getOpcode() ==
1511 ARM::t2LEApcrelJT ? ARM::t2ADR
1512 : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR
1513 : ARM::ADR))
1514 .addReg(MI->getOperand(0).getReg())
1516 // Add predicate operands.
1517 .addImm(MI->getOperand(2).getImm())
1518 .addReg(MI->getOperand(3).getReg()));
1519 return;
1520 }
1521 // Darwin call instructions are just normal call instructions with different
1522 // clobber semantics (they clobber R9).
1523 case ARM::BX_CALL: {
1525 .addReg(ARM::LR)
1526 .addReg(ARM::PC)
1527 // Add predicate operands.
1528 .addImm(ARMCC::AL)
1529 .addReg(0)
1530 // Add 's' bit operand (always reg0 for this)
1531 .addReg(0));
1532
1533 assert(Subtarget->hasV4TOps());
1535 .addReg(MI->getOperand(0).getReg()));
1536 return;
1537 }
1538 case ARM::tBX_CALL: {
1539 if (Subtarget->hasV5TOps())
1540 llvm_unreachable("Expected BLX to be selected for v5t+");
1541
1542 // On ARM v4t, when doing a call from thumb mode, we need to ensure
1543 // that the saved lr has its LSB set correctly (the arch doesn't
1544 // have blx).
1545 // So here we generate a bl to a small jump pad that does bx rN.
1546 // The jump pads are emitted after the function body.
1547
1548 Register TReg = MI->getOperand(0).getReg();
1549 MCSymbol *TRegSym = nullptr;
1550 for (std::pair<unsigned, MCSymbol *> &TIP : ThumbIndirectPads) {
1551 if (TIP.first == TReg) {
1552 TRegSym = TIP.second;
1553 break;
1554 }
1555 }
1556
1557 if (!TRegSym) {
1558 TRegSym = OutContext.createTempSymbol();
1559 ThumbIndirectPads.push_back(std::make_pair(TReg, TRegSym));
1560 }
1561
1562 // Create a link-saving branch to the Reg Indirect Jump Pad.
1564 // Predicate comes first here.
1565 .addImm(ARMCC::AL).addReg(0)
1566 .addExpr(MCSymbolRefExpr::create(TRegSym, OutContext)));
1567 return;
1568 }
1569 case ARM::BMOVPCRX_CALL: {
1571 .addReg(ARM::LR)
1572 .addReg(ARM::PC)
1573 // Add predicate operands.
1574 .addImm(ARMCC::AL)
1575 .addReg(0)
1576 // Add 's' bit operand (always reg0 for this)
1577 .addReg(0));
1578
1580 .addReg(ARM::PC)
1581 .addReg(MI->getOperand(0).getReg())
1582 // Add predicate operands.
1584 .addReg(0)
1585 // Add 's' bit operand (always reg0 for this)
1586 .addReg(0));
1587 return;
1588 }
1589 case ARM::BMOVPCB_CALL: {
1591 .addReg(ARM::LR)
1592 .addReg(ARM::PC)
1593 // Add predicate operands.
1594 .addImm(ARMCC::AL)
1595 .addReg(0)
1596 // Add 's' bit operand (always reg0 for this)
1597 .addReg(0));
1598
1599 const MachineOperand &Op = MI->getOperand(0);
1600 const GlobalValue *GV = Op.getGlobal();
1601 const unsigned TF = Op.getTargetFlags();
1602 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1603 const MCExpr *GVSymExpr = MCSymbolRefExpr::create(GVSym, OutContext);
1605 .addExpr(GVSymExpr)
1606 // Add predicate operands.
1607 .addImm(ARMCC::AL)
1608 .addReg(0));
1609 return;
1610 }
1611 case ARM::MOVi16_ga_pcrel:
1612 case ARM::t2MOVi16_ga_pcrel: {
1613 MCInst TmpInst;
1614 TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16);
1615 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1616
1617 unsigned TF = MI->getOperand(1).getTargetFlags();
1618 const GlobalValue *GV = MI->getOperand(1).getGlobal();
1619 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1620 const MCExpr *GVSymExpr = MCSymbolRefExpr::create(GVSym, OutContext);
1621
1622 MCSymbol *LabelSym =
1623 getPICLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(),
1624 MI->getOperand(2).getImm(), OutContext);
1625 const MCExpr *LabelSymExpr= MCSymbolRefExpr::create(LabelSym, OutContext);
1626 unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;
1627 const MCExpr *PCRelExpr = ARM::createLower16(
1629 GVSymExpr,
1630 MCBinaryExpr::createAdd(LabelSymExpr,
1632 OutContext),
1633 OutContext),
1634 OutContext);
1635 TmpInst.addOperand(MCOperand::createExpr(PCRelExpr));
1636
1637 // Add predicate operands.
1639 TmpInst.addOperand(MCOperand::createReg(0));
1640 // Add 's' bit operand (always reg0 for this)
1641 TmpInst.addOperand(MCOperand::createReg(0));
1642 EmitToStreamer(*OutStreamer, TmpInst);
1643 return;
1644 }
1645 case ARM::MOVTi16_ga_pcrel:
1646 case ARM::t2MOVTi16_ga_pcrel: {
1647 MCInst TmpInst;
1648 TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel
1649 ? ARM::MOVTi16 : ARM::t2MOVTi16);
1650 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1651 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(1).getReg()));
1652
1653 unsigned TF = MI->getOperand(2).getTargetFlags();
1654 const GlobalValue *GV = MI->getOperand(2).getGlobal();
1655 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1656 const MCExpr *GVSymExpr = MCSymbolRefExpr::create(GVSym, OutContext);
1657
1658 MCSymbol *LabelSym =
1659 getPICLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(),
1660 MI->getOperand(3).getImm(), OutContext);
1661 const MCExpr *LabelSymExpr= MCSymbolRefExpr::create(LabelSym, OutContext);
1662 unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;
1663 const MCExpr *PCRelExpr = ARM::createUpper16(
1665 GVSymExpr,
1666 MCBinaryExpr::createAdd(LabelSymExpr,
1668 OutContext),
1669 OutContext),
1670 OutContext);
1671 TmpInst.addOperand(MCOperand::createExpr(PCRelExpr));
1672 // Add predicate operands.
1674 TmpInst.addOperand(MCOperand::createReg(0));
1675 // Add 's' bit operand (always reg0 for this)
1676 TmpInst.addOperand(MCOperand::createReg(0));
1677 EmitToStreamer(*OutStreamer, TmpInst);
1678 return;
1679 }
1680 case ARM::t2BFi:
1681 case ARM::t2BFic:
1682 case ARM::t2BFLi:
1683 case ARM::t2BFr:
1684 case ARM::t2BFLr: {
1685 // This is a Branch Future instruction.
1686
1687 const MCExpr *BranchLabel = MCSymbolRefExpr::create(
1688 getBFLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(),
1689 MI->getOperand(0).getIndex(), OutContext),
1690 OutContext);
1691
1692 auto MCInst = MCInstBuilder(Opc).addExpr(BranchLabel);
1693 if (MI->getOperand(1).isReg()) {
1694 // For BFr/BFLr
1695 MCInst.addReg(MI->getOperand(1).getReg());
1696 } else {
1697 // For BFi/BFLi/BFic
1698 const MCExpr *BranchTarget;
1699 if (MI->getOperand(1).isMBB())
1700 BranchTarget = MCSymbolRefExpr::create(
1701 MI->getOperand(1).getMBB()->getSymbol(), OutContext);
1702 else if (MI->getOperand(1).isGlobal()) {
1703 const GlobalValue *GV = MI->getOperand(1).getGlobal();
1704 BranchTarget = MCSymbolRefExpr::create(
1705 GetARMGVSymbol(GV, MI->getOperand(1).getTargetFlags()), OutContext);
1706 } else if (MI->getOperand(1).isSymbol()) {
1707 BranchTarget = MCSymbolRefExpr::create(
1708 GetExternalSymbolSymbol(MI->getOperand(1).getSymbolName()),
1709 OutContext);
1710 } else
1711 llvm_unreachable("Unhandled operand kind in Branch Future instruction");
1712
1713 MCInst.addExpr(BranchTarget);
1714 }
1715
1716 if (Opc == ARM::t2BFic) {
1717 const MCExpr *ElseLabel = MCSymbolRefExpr::create(
1718 getBFLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(),
1719 MI->getOperand(2).getIndex(), OutContext),
1720 OutContext);
1721 MCInst.addExpr(ElseLabel);
1722 MCInst.addImm(MI->getOperand(3).getImm());
1723 } else {
1724 MCInst.addImm(MI->getOperand(2).getImm())
1725 .addReg(MI->getOperand(3).getReg());
1726 }
1727
1729 return;
1730 }
1731 case ARM::t2BF_LabelPseudo: {
1732 // This is a pseudo op for a label used by a branch future instruction
1733
1734 // Emit the label.
1735 OutStreamer->emitLabel(getBFLabel(DL.getPrivateGlobalPrefix(),
1737 MI->getOperand(0).getIndex(), OutContext));
1738 return;
1739 }
1740 case ARM::tPICADD: {
1741 // This is a pseudo op for a label + instruction sequence, which looks like:
1742 // LPC0:
1743 // add r0, pc
1744 // This adds the address of LPC0 to r0.
1745
1746 // Emit the label.
1747 OutStreamer->emitLabel(getPICLabel(DL.getPrivateGlobalPrefix(),
1749 MI->getOperand(2).getImm(), OutContext));
1750
1751 // Form and emit the add.
1753 .addReg(MI->getOperand(0).getReg())
1754 .addReg(MI->getOperand(0).getReg())
1755 .addReg(ARM::PC)
1756 // Add predicate operands.
1758 .addReg(0));
1759 return;
1760 }
1761 case ARM::PICADD: {
1762 // This is a pseudo op for a label + instruction sequence, which looks like:
1763 // LPC0:
1764 // add r0, pc, r0
1765 // This adds the address of LPC0 to r0.
1766
1767 // Emit the label.
1768 OutStreamer->emitLabel(getPICLabel(DL.getPrivateGlobalPrefix(),
1770 MI->getOperand(2).getImm(), OutContext));
1771
1772 // Form and emit the add.
1774 .addReg(MI->getOperand(0).getReg())
1775 .addReg(ARM::PC)
1776 .addReg(MI->getOperand(1).getReg())
1777 // Add predicate operands.
1778 .addImm(MI->getOperand(3).getImm())
1779 .addReg(MI->getOperand(4).getReg())
1780 // Add 's' bit operand (always reg0 for this)
1781 .addReg(0));
1782 return;
1783 }
1784 case ARM::PICSTR:
1785 case ARM::PICSTRB:
1786 case ARM::PICSTRH:
1787 case ARM::PICLDR:
1788 case ARM::PICLDRB:
1789 case ARM::PICLDRH:
1790 case ARM::PICLDRSB:
1791 case ARM::PICLDRSH: {
1792 // This is a pseudo op for a label + instruction sequence, which looks like:
1793 // LPC0:
1794 // OP r0, [pc, r0]
1795 // The LCP0 label is referenced by a constant pool entry in order to get
1796 // a PC-relative address at the ldr instruction.
1797
1798 // Emit the label.
1799 OutStreamer->emitLabel(getPICLabel(DL.getPrivateGlobalPrefix(),
1801 MI->getOperand(2).getImm(), OutContext));
1802
1803 // Form and emit the load
1804 unsigned Opcode;
1805 switch (MI->getOpcode()) {
1806 default:
1807 llvm_unreachable("Unexpected opcode!");
1808 case ARM::PICSTR: Opcode = ARM::STRrs; break;
1809 case ARM::PICSTRB: Opcode = ARM::STRBrs; break;
1810 case ARM::PICSTRH: Opcode = ARM::STRH; break;
1811 case ARM::PICLDR: Opcode = ARM::LDRrs; break;
1812 case ARM::PICLDRB: Opcode = ARM::LDRBrs; break;
1813 case ARM::PICLDRH: Opcode = ARM::LDRH; break;
1814 case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
1815 case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
1816 }
1818 .addReg(MI->getOperand(0).getReg())
1819 .addReg(ARM::PC)
1820 .addReg(MI->getOperand(1).getReg())
1821 .addImm(0)
1822 // Add predicate operands.
1823 .addImm(MI->getOperand(3).getImm())
1824 .addReg(MI->getOperand(4).getReg()));
1825
1826 return;
1827 }
1828 case ARM::CONSTPOOL_ENTRY: {
1829 if (Subtarget->genExecuteOnly())
1830 llvm_unreachable("execute-only should not generate constant pools");
1831
1832 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1833 /// in the function. The first operand is the ID# for this instruction, the
1834 /// second is the index into the MachineConstantPool that this is, the third
1835 /// is the size in bytes of this constant pool entry.
1836 /// The required alignment is specified on the basic block holding this MI.
1837 unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1838 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();
1839
1840 // If this is the first entry of the pool, mark it.
1841 if (!InConstantPool) {
1842 OutStreamer->emitDataRegion(MCDR_DataRegion);
1843 InConstantPool = true;
1844 }
1845
1846 OutStreamer->emitLabel(GetCPISymbol(LabelId));
1847
1848 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1849 if (MCPE.isMachineConstantPoolEntry())
1851 else
1853 return;
1854 }
1855 case ARM::JUMPTABLE_ADDRS:
1857 return;
1858 case ARM::JUMPTABLE_INSTS:
1860 return;
1861 case ARM::JUMPTABLE_TBB:
1862 case ARM::JUMPTABLE_TBH:
1863 emitJumpTableTBInst(MI, MI->getOpcode() == ARM::JUMPTABLE_TBB ? 1 : 2);
1864 return;
1865 case ARM::t2BR_JT: {
1867 .addReg(ARM::PC)
1868 .addReg(MI->getOperand(0).getReg())
1869 // Add predicate operands.
1871 .addReg(0));
1872 return;
1873 }
1874 case ARM::t2TBB_JT:
1875 case ARM::t2TBH_JT: {
1876 unsigned Opc = MI->getOpcode() == ARM::t2TBB_JT ? ARM::t2TBB : ARM::t2TBH;
1877 // Lower and emit the PC label, then the instruction itself.
1878 OutStreamer->emitLabel(GetCPISymbol(MI->getOperand(3).getImm()));
1880 .addReg(MI->getOperand(0).getReg())
1881 .addReg(MI->getOperand(1).getReg())
1882 // Add predicate operands.
1884 .addReg(0));
1885 return;
1886 }
1887 case ARM::tTBB_JT:
1888 case ARM::tTBH_JT: {
1889
1890 bool Is8Bit = MI->getOpcode() == ARM::tTBB_JT;
1891 Register Base = MI->getOperand(0).getReg();
1892 Register Idx = MI->getOperand(1).getReg();
1893 assert(MI->getOperand(1).isKill() && "We need the index register as scratch!");
1894
1895 // Multiply up idx if necessary.
1896 if (!Is8Bit)
1898 .addReg(Idx)
1899 .addReg(ARM::CPSR)
1900 .addReg(Idx)
1901 .addImm(1)
1902 // Add predicate operands.
1903 .addImm(ARMCC::AL)
1904 .addReg(0));
1905
1906 if (Base == ARM::PC) {
1907 // TBB [base, idx] =
1908 // ADDS idx, idx, base
1909 // LDRB idx, [idx, #4] ; or LDRH if TBH
1910 // LSLS idx, #1
1911 // ADDS pc, pc, idx
1912
1913 // When using PC as the base, it's important that there is no padding
1914 // between the last ADDS and the start of the jump table. The jump table
1915 // is 4-byte aligned, so we ensure we're 4 byte aligned here too.
1916 //
1917 // FIXME: Ideally we could vary the LDRB index based on the padding
1918 // between the sequence and jump table, however that relies on MCExprs
1919 // for load indexes which are currently not supported.
1920 OutStreamer->emitCodeAlignment(Align(4), &getSubtargetInfo());
1922 .addReg(Idx)
1923 .addReg(Idx)
1924 .addReg(Base)
1925 // Add predicate operands.
1926 .addImm(ARMCC::AL)
1927 .addReg(0));
1928
1929 unsigned Opc = Is8Bit ? ARM::tLDRBi : ARM::tLDRHi;
1931 .addReg(Idx)
1932 .addReg(Idx)
1933 .addImm(Is8Bit ? 4 : 2)
1934 // Add predicate operands.
1935 .addImm(ARMCC::AL)
1936 .addReg(0));
1937 } else {
1938 // TBB [base, idx] =
1939 // LDRB idx, [base, idx] ; or LDRH if TBH
1940 // LSLS idx, #1
1941 // ADDS pc, pc, idx
1942
1943 unsigned Opc = Is8Bit ? ARM::tLDRBr : ARM::tLDRHr;
1945 .addReg(Idx)
1946 .addReg(Base)
1947 .addReg(Idx)
1948 // Add predicate operands.
1949 .addImm(ARMCC::AL)
1950 .addReg(0));
1951 }
1952
1954 .addReg(Idx)
1955 .addReg(ARM::CPSR)
1956 .addReg(Idx)
1957 .addImm(1)
1958 // Add predicate operands.
1959 .addImm(ARMCC::AL)
1960 .addReg(0));
1961
1962 OutStreamer->emitLabel(GetCPISymbol(MI->getOperand(3).getImm()));
1964 .addReg(ARM::PC)
1965 .addReg(ARM::PC)
1966 .addReg(Idx)
1967 // Add predicate operands.
1968 .addImm(ARMCC::AL)
1969 .addReg(0));
1970 return;
1971 }
1972 case ARM::tBR_JTr:
1973 case ARM::BR_JTr: {
1974 // mov pc, target
1975 MCInst TmpInst;
1976 unsigned Opc = MI->getOpcode() == ARM::BR_JTr ?
1977 ARM::MOVr : ARM::tMOVr;
1978 TmpInst.setOpcode(Opc);
1979 TmpInst.addOperand(MCOperand::createReg(ARM::PC));
1980 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1981 // Add predicate operands.
1983 TmpInst.addOperand(MCOperand::createReg(0));
1984 // Add 's' bit operand (always reg0 for this)
1985 if (Opc == ARM::MOVr)
1986 TmpInst.addOperand(MCOperand::createReg(0));
1987 EmitToStreamer(*OutStreamer, TmpInst);
1988 return;
1989 }
1990 case ARM::BR_JTm_i12: {
1991 // ldr pc, target
1992 MCInst TmpInst;
1993 TmpInst.setOpcode(ARM::LDRi12);
1994 TmpInst.addOperand(MCOperand::createReg(ARM::PC));
1995 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1996 TmpInst.addOperand(MCOperand::createImm(MI->getOperand(2).getImm()));
1997 // Add predicate operands.
1999 TmpInst.addOperand(MCOperand::createReg(0));
2000 EmitToStreamer(*OutStreamer, TmpInst);
2001 return;
2002 }
2003 case ARM::BR_JTm_rs: {
2004 // ldr pc, target
2005 MCInst TmpInst;
2006 TmpInst.setOpcode(ARM::LDRrs);
2007 TmpInst.addOperand(MCOperand::createReg(ARM::PC));
2008 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
2009 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(1).getReg()));
2010 TmpInst.addOperand(MCOperand::createImm(MI->getOperand(2).getImm()));
2011 // Add predicate operands.
2013 TmpInst.addOperand(MCOperand::createReg(0));
2014 EmitToStreamer(*OutStreamer, TmpInst);
2015 return;
2016 }
2017 case ARM::BR_JTadd: {
2018 // add pc, target, idx
2020 .addReg(ARM::PC)
2021 .addReg(MI->getOperand(0).getReg())
2022 .addReg(MI->getOperand(1).getReg())
2023 // Add predicate operands.
2025 .addReg(0)
2026 // Add 's' bit operand (always reg0 for this)
2027 .addReg(0));
2028 return;
2029 }
2030 case ARM::SPACE:
2031 OutStreamer->emitZeros(MI->getOperand(1).getImm());
2032 return;
2033 case ARM::TRAP: {
2034 // Non-Darwin binutils don't yet support the "trap" mnemonic.
2035 // FIXME: Remove this special case when they do.
2036 if (!Subtarget->isTargetMachO()) {
2037 uint32_t Val = 0xe7ffdefeUL;
2038 OutStreamer->AddComment("trap");
2039 ATS.emitInst(Val);
2040 return;
2041 }
2042 break;
2043 }
2044 case ARM::tTRAP: {
2045 // Non-Darwin binutils don't yet support the "trap" mnemonic.
2046 // FIXME: Remove this special case when they do.
2047 if (!Subtarget->isTargetMachO()) {
2048 uint16_t Val = 0xdefe;
2049 OutStreamer->AddComment("trap");
2050 ATS.emitInst(Val, 'n');
2051 return;
2052 }
2053 break;
2054 }
2055 case ARM::t2Int_eh_sjlj_setjmp:
2056 case ARM::t2Int_eh_sjlj_setjmp_nofp:
2057 case ARM::tInt_eh_sjlj_setjmp: {
2058 // Two incoming args: GPR:$src, GPR:$val
2059 // mov $val, pc
2060 // adds $val, #7
2061 // str $val, [$src, #4]
2062 // movs r0, #0
2063 // b LSJLJEH
2064 // movs r0, #1
2065 // LSJLJEH:
2066 Register SrcReg = MI->getOperand(0).getReg();
2067 Register ValReg = MI->getOperand(1).getReg();
2068 MCSymbol *Label = OutContext.createTempSymbol("SJLJEH");
2069 OutStreamer->AddComment("eh_setjmp begin");
2071 .addReg(ValReg)
2072 .addReg(ARM::PC)
2073 // Predicate.
2074 .addImm(ARMCC::AL)
2075 .addReg(0));
2076
2078 .addReg(ValReg)
2079 // 's' bit operand
2080 .addReg(ARM::CPSR)
2081 .addReg(ValReg)
2082 .addImm(7)
2083 // Predicate.
2084 .addImm(ARMCC::AL)
2085 .addReg(0));
2086
2088 .addReg(ValReg)
2089 .addReg(SrcReg)
2090 // The offset immediate is #4. The operand value is scaled by 4 for the
2091 // tSTR instruction.
2092 .addImm(1)
2093 // Predicate.
2094 .addImm(ARMCC::AL)
2095 .addReg(0));
2096
2098 .addReg(ARM::R0)
2099 .addReg(ARM::CPSR)
2100 .addImm(0)
2101 // Predicate.
2102 .addImm(ARMCC::AL)
2103 .addReg(0));
2104
2105 const MCExpr *SymbolExpr = MCSymbolRefExpr::create(Label, OutContext);
2107 .addExpr(SymbolExpr)
2108 .addImm(ARMCC::AL)
2109 .addReg(0));
2110
2111 OutStreamer->AddComment("eh_setjmp end");
2113 .addReg(ARM::R0)
2114 .addReg(ARM::CPSR)
2115 .addImm(1)
2116 // Predicate.
2117 .addImm(ARMCC::AL)
2118 .addReg(0));
2119
2120 OutStreamer->emitLabel(Label);
2121 return;
2122 }
2123
2124 case ARM::Int_eh_sjlj_setjmp_nofp:
2125 case ARM::Int_eh_sjlj_setjmp: {
2126 // Two incoming args: GPR:$src, GPR:$val
2127 // add $val, pc, #8
2128 // str $val, [$src, #+4]
2129 // mov r0, #0
2130 // add pc, pc, #0
2131 // mov r0, #1
2132 Register SrcReg = MI->getOperand(0).getReg();
2133 Register ValReg = MI->getOperand(1).getReg();
2134
2135 OutStreamer->AddComment("eh_setjmp begin");
2137 .addReg(ValReg)
2138 .addReg(ARM::PC)
2139 .addImm(8)
2140 // Predicate.
2141 .addImm(ARMCC::AL)
2142 .addReg(0)
2143 // 's' bit operand (always reg0 for this).
2144 .addReg(0));
2145
2147 .addReg(ValReg)
2148 .addReg(SrcReg)
2149 .addImm(4)
2150 // Predicate.
2151 .addImm(ARMCC::AL)
2152 .addReg(0));
2153
2155 .addReg(ARM::R0)
2156 .addImm(0)
2157 // Predicate.
2158 .addImm(ARMCC::AL)
2159 .addReg(0)
2160 // 's' bit operand (always reg0 for this).
2161 .addReg(0));
2162
2164 .addReg(ARM::PC)
2165 .addReg(ARM::PC)
2166 .addImm(0)
2167 // Predicate.
2168 .addImm(ARMCC::AL)
2169 .addReg(0)
2170 // 's' bit operand (always reg0 for this).
2171 .addReg(0));
2172
2173 OutStreamer->AddComment("eh_setjmp end");
2175 .addReg(ARM::R0)
2176 .addImm(1)
2177 // Predicate.
2178 .addImm(ARMCC::AL)
2179 .addReg(0)
2180 // 's' bit operand (always reg0 for this).
2181 .addReg(0));
2182 return;
2183 }
2184 case ARM::Int_eh_sjlj_longjmp: {
2185 // ldr sp, [$src, #8]
2186 // ldr $scratch, [$src, #4]
2187 // ldr r7, [$src]
2188 // bx $scratch
2189 Register SrcReg = MI->getOperand(0).getReg();
2190 Register ScratchReg = MI->getOperand(1).getReg();
2192 .addReg(ARM::SP)
2193 .addReg(SrcReg)
2194 .addImm(8)
2195 // Predicate.
2196 .addImm(ARMCC::AL)
2197 .addReg(0));
2198
2200 .addReg(ScratchReg)
2201 .addReg(SrcReg)
2202 .addImm(4)
2203 // Predicate.
2204 .addImm(ARMCC::AL)
2205 .addReg(0));
2206
2207 const MachineFunction &MF = *MI->getParent()->getParent();
2208 const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();
2209
2210 if (STI.isTargetDarwin() || STI.isTargetWindows()) {
2211 // These platforms always use the same frame register
2213 .addReg(STI.getFramePointerReg())
2214 .addReg(SrcReg)
2215 .addImm(0)
2216 // Predicate.
2218 .addReg(0));
2219 } else {
2220 // If the calling code might use either R7 or R11 as
2221 // frame pointer register, restore it into both.
2223 .addReg(ARM::R7)
2224 .addReg(SrcReg)
2225 .addImm(0)
2226 // Predicate.
2227 .addImm(ARMCC::AL)
2228 .addReg(0));
2230 .addReg(ARM::R11)
2231 .addReg(SrcReg)
2232 .addImm(0)
2233 // Predicate.
2234 .addImm(ARMCC::AL)
2235 .addReg(0));
2236 }
2237
2238 assert(Subtarget->hasV4TOps());
2240 .addReg(ScratchReg)
2241 // Predicate.
2242 .addImm(ARMCC::AL)
2243 .addReg(0));
2244 return;
2245 }
2246 case ARM::tInt_eh_sjlj_longjmp: {
2247 // ldr $scratch, [$src, #8]
2248 // mov sp, $scratch
2249 // ldr $scratch, [$src, #4]
2250 // ldr r7, [$src]
2251 // bx $scratch
2252 Register SrcReg = MI->getOperand(0).getReg();
2253 Register ScratchReg = MI->getOperand(1).getReg();
2254
2255 const MachineFunction &MF = *MI->getParent()->getParent();
2256 const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();
2257
2259 .addReg(ScratchReg)
2260 .addReg(SrcReg)
2261 // The offset immediate is #8. The operand value is scaled by 4 for the
2262 // tLDR instruction.
2263 .addImm(2)
2264 // Predicate.
2265 .addImm(ARMCC::AL)
2266 .addReg(0));
2267
2269 .addReg(ARM::SP)
2270 .addReg(ScratchReg)
2271 // Predicate.
2272 .addImm(ARMCC::AL)
2273 .addReg(0));
2274
2276 .addReg(ScratchReg)
2277 .addReg(SrcReg)
2278 .addImm(1)
2279 // Predicate.
2280 .addImm(ARMCC::AL)
2281 .addReg(0));
2282
2283 if (STI.isTargetDarwin() || STI.isTargetWindows()) {
2284 // These platforms always use the same frame register
2286 .addReg(STI.getFramePointerReg())
2287 .addReg(SrcReg)
2288 .addImm(0)
2289 // Predicate.
2291 .addReg(0));
2292 } else {
2293 // If the calling code might use either R7 or R11 as
2294 // frame pointer register, restore it into both.
2296 .addReg(ARM::R7)
2297 .addReg(SrcReg)
2298 .addImm(0)
2299 // Predicate.
2300 .addImm(ARMCC::AL)
2301 .addReg(0));
2303 .addReg(ARM::R11)
2304 .addReg(SrcReg)
2305 .addImm(0)
2306 // Predicate.
2307 .addImm(ARMCC::AL)
2308 .addReg(0));
2309 }
2310
2312 .addReg(ScratchReg)
2313 // Predicate.
2314 .addImm(ARMCC::AL)
2315 .addReg(0));
2316 return;
2317 }
2318 case ARM::tInt_WIN_eh_sjlj_longjmp: {
2319 // ldr.w r11, [$src, #0]
2320 // ldr.w sp, [$src, #8]
2321 // ldr.w pc, [$src, #4]
2322
2323 Register SrcReg = MI->getOperand(0).getReg();
2324
2326 .addReg(ARM::R11)
2327 .addReg(SrcReg)
2328 .addImm(0)
2329 // Predicate
2330 .addImm(ARMCC::AL)
2331 .addReg(0));
2333 .addReg(ARM::SP)
2334 .addReg(SrcReg)
2335 .addImm(8)
2336 // Predicate
2337 .addImm(ARMCC::AL)
2338 .addReg(0));
2340 .addReg(ARM::PC)
2341 .addReg(SrcReg)
2342 .addImm(4)
2343 // Predicate
2344 .addImm(ARMCC::AL)
2345 .addReg(0));
2346 return;
2347 }
2348 case ARM::PATCHABLE_FUNCTION_ENTER:
2350 return;
2351 case ARM::PATCHABLE_FUNCTION_EXIT:
2353 return;
2354 case ARM::PATCHABLE_TAIL_CALL:
2356 return;
2357 case ARM::SpeculationBarrierISBDSBEndBB: {
2358 // Print DSB SYS + ISB
2359 MCInst TmpInstDSB;
2360 TmpInstDSB.setOpcode(ARM::DSB);
2361 TmpInstDSB.addOperand(MCOperand::createImm(0xf));
2362 EmitToStreamer(*OutStreamer, TmpInstDSB);
2363 MCInst TmpInstISB;
2364 TmpInstISB.setOpcode(ARM::ISB);
2365 TmpInstISB.addOperand(MCOperand::createImm(0xf));
2366 EmitToStreamer(*OutStreamer, TmpInstISB);
2367 return;
2368 }
2369 case ARM::t2SpeculationBarrierISBDSBEndBB: {
2370 // Print DSB SYS + ISB
2371 MCInst TmpInstDSB;
2372 TmpInstDSB.setOpcode(ARM::t2DSB);
2373 TmpInstDSB.addOperand(MCOperand::createImm(0xf));
2375 TmpInstDSB.addOperand(MCOperand::createReg(0));
2376 EmitToStreamer(*OutStreamer, TmpInstDSB);
2377 MCInst TmpInstISB;
2378 TmpInstISB.setOpcode(ARM::t2ISB);
2379 TmpInstISB.addOperand(MCOperand::createImm(0xf));
2381 TmpInstISB.addOperand(MCOperand::createReg(0));
2382 EmitToStreamer(*OutStreamer, TmpInstISB);
2383 return;
2384 }
2385 case ARM::SpeculationBarrierSBEndBB: {
2386 // Print SB
2387 MCInst TmpInstSB;
2388 TmpInstSB.setOpcode(ARM::SB);
2389 EmitToStreamer(*OutStreamer, TmpInstSB);
2390 return;
2391 }
2392 case ARM::t2SpeculationBarrierSBEndBB: {
2393 // Print SB
2394 MCInst TmpInstSB;
2395 TmpInstSB.setOpcode(ARM::t2SB);
2396 EmitToStreamer(*OutStreamer, TmpInstSB);
2397 return;
2398 }
2399
2400 case ARM::SEH_StackAlloc:
2401 ATS.emitARMWinCFIAllocStack(MI->getOperand(0).getImm(),
2402 MI->getOperand(1).getImm());
2403 return;
2404
2405 case ARM::SEH_SaveRegs:
2406 case ARM::SEH_SaveRegs_Ret:
2407 ATS.emitARMWinCFISaveRegMask(MI->getOperand(0).getImm(),
2408 MI->getOperand(1).getImm());
2409 return;
2410
2411 case ARM::SEH_SaveSP:
2412 ATS.emitARMWinCFISaveSP(MI->getOperand(0).getImm());
2413 return;
2414
2415 case ARM::SEH_SaveFRegs:
2416 ATS.emitARMWinCFISaveFRegs(MI->getOperand(0).getImm(),
2417 MI->getOperand(1).getImm());
2418 return;
2419
2420 case ARM::SEH_SaveLR:
2421 ATS.emitARMWinCFISaveLR(MI->getOperand(0).getImm());
2422 return;
2423
2424 case ARM::SEH_Nop:
2425 case ARM::SEH_Nop_Ret:
2426 ATS.emitARMWinCFINop(MI->getOperand(0).getImm());
2427 return;
2428
2429 case ARM::SEH_PrologEnd:
2430 ATS.emitARMWinCFIPrologEnd(/*Fragment=*/false);
2431 return;
2432
2433 case ARM::SEH_EpilogStart:
2435 return;
2436
2437 case ARM::SEH_EpilogEnd:
2439 return;
2440 }
2441
2442 MCInst TmpInst;
2443 LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
2444
2445 EmitToStreamer(*OutStreamer, TmpInst);
2446}
2447
2448char ARMAsmPrinter::ID = 0;
2449
2450INITIALIZE_PASS(ARMAsmPrinter, "arm-asm-printer", "ARM Assembly Printer", false,
2451 false)
2452
2453//===----------------------------------------------------------------------===//
2454// Target Registry Stuff
2455//===----------------------------------------------------------------------===//
2456
2457// Force static initialization.
2458extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
2459LLVMInitializeARMAsmPrinter() {
2464}
unsigned SubReg
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, MachineModuleInfoImpl::StubValueTy &MCSym)
static uint8_t getModifierSpecifier(ARMCP::ARMCPModifier Modifier)
static MCSymbol * getPICLabel(StringRef Prefix, unsigned FunctionNumber, unsigned LabelId, MCContext &Ctx)
static bool checkFunctionsAttributeConsistency(const Module &M, StringRef Attr, StringRef Value)
static bool isThumb(const MCSubtargetInfo &STI)
static MCSymbol * getBFLabel(StringRef Prefix, unsigned FunctionNumber, unsigned LabelId, MCContext &Ctx)
static bool checkDenormalAttributeConsistency(const Module &M, StringRef Attr, DenormalMode Value)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:213
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
This file contains the declarations for the subclasses of Constant, which represent the different fla...
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
#define F(x, y, z)
Definition MD5.cpp:55
Machine Check Debug Module
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:480
This file defines the SmallString class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static const unsigned FramePtr
void emitJumpTableAddrs(const MachineInstr *MI)
void emitJumpTableTBInst(const MachineInstr *MI, unsigned OffsetWidth)
void emitFunctionBodyEnd() override
Targets can override this to emit stuff after the last basic block in the function.
bool runOnMachineFunction(MachineFunction &F) override
runOnMachineFunction - This uses the emitInstruction() method to print assembly for each instruction.
MCSymbol * GetCPISymbol(unsigned CPID) const override
Return the symbol for the specified constant pool entry.
void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O)
void emitStartOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the start of their fi...
ARMAsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer)
void emitFunctionEntryLabel() override
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, const MCSubtargetInfo *EndInfo) const override
Let the target do anything it needs to do after emitting inlineasm.
void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI)
void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override
EmitMachineConstantPoolValue - Print a machine constantpool value to the .s file.
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
void emitXXStructor(const DataLayout &DL, const Constant *CV) override
Targets can override this to change how global constants that are part of a C++ static/global constru...
void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI)
void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI)
void emitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
std::tuple< const MCSymbol *, uint64_t, const MCSymbol *, codeview::JumpTableEntrySize > getCodeViewJumpTableInfo(int JTI, const MachineInstr *BranchInstr, const MCSymbol *BranchLabel) const override
Gets information required to create a CodeView debug symbol for a jump table.
void emitJumpTableInsts(const MachineInstr *MI)
const ARMBaseTargetMachine & getTM() const
void emitGlobalVariable(const GlobalVariable *GV) override
Emit the specified global variable to the .s file.
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override
Print the MachineOperand as a symbol.
ARMConstantPoolValue - ARM specific constantpool value.
unsigned char getPCAdjustment() const
ARMCP::ARMCPModifier getModifier() const
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=ARM::NoRegAltName)
MCPhysReg getFramePointerReg() const
bool isTargetWindows() const
bool isTargetDarwin() const
void emitTargetAttributes(const MCSubtargetInfo &STI)
Emit the build attributes that only depend on the hardware that we expect.
virtual void emitSetFP(MCRegister FpReg, MCRegister SpReg, int64_t Offset=0)
virtual void finishAttributeSection()
virtual void emitMovSP(MCRegister Reg, int64_t Offset=0)
virtual void emitARMWinCFISaveSP(unsigned Reg)
virtual void emitInst(uint32_t Inst, char Suffix='\0')
virtual void emitARMWinCFISaveLR(unsigned Offset)
virtual void emitTextAttribute(unsigned Attribute, StringRef String)
virtual void emitARMWinCFIAllocStack(unsigned Size, bool Wide)
virtual void emitARMWinCFISaveRegMask(unsigned Mask, bool Wide)
virtual void emitRegSave(const SmallVectorImpl< MCRegister > &RegList, bool isVector)
virtual void emitARMWinCFIEpilogEnd()
virtual void emitARMWinCFIPrologEnd(bool Fragment)
virtual void switchVendor(StringRef Vendor)
virtual void emitARMWinCFISaveFRegs(unsigned First, unsigned Last)
virtual void emitARMWinCFIEpilogStart(unsigned Condition)
virtual void emitPad(int64_t Offset)
virtual void emitAttribute(unsigned Attribute, unsigned Value)
virtual void emitARMWinCFINop(bool Wide)
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
MCSymbol * getSymbolWithGlobalValueBase(const GlobalValue *GV, StringRef Suffix) const
Return the MCSymbol for a private symbol with global value name as its base, with the specified suffi...
MCSymbol * getSymbol(const GlobalValue *GV) const
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
virtual void emitGlobalVariable(const GlobalVariable *GV)
Emit the specified global variable to the .s file.
TargetMachine & TM
Target machine description.
Definition AsmPrinter.h:93
void emitXRayTable()
Emit a table with all XRay instrumentation points.
MCSymbol * getMBBExceptionSym(const MachineBasicBlock &MBB)
const MCAsmInfo * MAI
Target Asm Printer information.
Definition AsmPrinter.h:96
MachineFunction * MF
The current machine function.
Definition AsmPrinter.h:108
virtual void SetupMachineFunction(MachineFunction &MF)
This should be called when a new MachineFunction is being processed from runOnMachineFunction.
void emitFunctionBody()
This method emits the body and trailer for a function.
virtual void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const
This emits linkage information about GVSym based on GV, if this is supported by the target.
unsigned getFunctionNumber() const
Return a unique ID for the current function.
AsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer, char &ID=AsmPrinter::ID)
void printOffset(int64_t Offset, raw_ostream &OS) const
This is just convenient handler for printing offsets.
void emitGlobalConstant(const DataLayout &DL, const Constant *CV, AliasMapTy *AliasList=nullptr)
EmitGlobalConstant - Print a general LLVM constant to the .s file.
MCSymbol * getSymbolPreferLocal(const GlobalValue &GV) const
Similar to getSymbol() but preferred for references.
MCSymbol * CurrentFnSym
The symbol for the current function.
Definition AsmPrinter.h:127
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
Definition AsmPrinter.h:111
void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr, unsigned MaxBytesToEmit=0) const
Emit an alignment directive to the specified power of two boundary.
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition AsmPrinter.h:100
bool isPositionIndependent() const
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition AsmPrinter.h:105
void getNameWithPrefix(SmallVectorImpl< char > &Name, const GlobalValue *GV) const
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
const DataLayout & getDataLayout() const
Return information about data layout.
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
MCSymbol * GetExternalSymbolSymbol(const Twine &Sym) const
Return the MCSymbol for the specified ExternalSymbol.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
The address of a basic block.
Definition Constants.h:899
This is an important base class in LLVM.
Definition Constant.h:43
const Constant * stripPointerCasts() const
Definition Constant.h:219
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:63
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
bool hasInternalLinkage() const
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:343
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:353
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:428
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
void addOperand(const MCOperand Op)
Definition MCInst.h:215
void setOpcode(unsigned Op)
Definition MCInst.h:201
MCSection * getThreadLocalPointerSection() const
MCSection * getNonLazySymbolPointerSection() const
static MCOperand createExpr(const MCExpr *Val)
Definition MCInst.h:166
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:33
Streaming machine code generation interface.
Definition MCStreamer.h:220
virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
Add the given Attribute to Symbol.
MCContext & getContext() const
Definition MCStreamer.h:314
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:214
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
LLVM_ABI void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition MCSymbol.cpp:59
Target specific streamer interface.
Definition MCStreamer.h:93
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
This class is a data container for one entry in a MachineConstantPool.
union llvm::MachineConstantPoolEntry::@004270020304201266316354007027341142157160323045 Val
The constant itself.
bool isMachineConstantPoolEntry() const
isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry is indeed a target specific ...
MachineConstantPoolValue * MachineCPVal
Abstract base class for all machine specific constantpool value subclasses.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
const std::vector< MachineJumpTableEntry > & getJumpTables() const
StubValueTy & getGVStubEntry(MCSymbol *Sym)
std::vector< std::pair< MCSymbol *, StubValueTy > > SymbolListTy
PointerIntPair< MCSymbol *, 1, bool > StubValueTy
MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation for MachO targets.
StubValueTy & getGVStubEntry(MCSymbol *Sym)
StubValueTy & getThreadLocalGVStubEntry(MCSymbol *Sym)
SymbolListTy GetGVStubList()
Accessor methods to return the set of stubs in sorted order.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
const GlobalValue * getGlobal() const
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
unsigned getTargetFlags() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
int64_t getOffset() const
Return the offset from the symbol in this operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
Definition Pass.cpp:140
IntType getInt() const
PointerTy getPointer() const
Wrapper class representing virtual and physical registers.
Definition Register.h:19
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Primary interface to the complete machine description for the target machine.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TypeSize getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
virtual Register getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:256
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SECREL
Thread Pointer Offset.
@ GOT_PREL
Thread Local Storage (General Dynamic Mode)
@ SBREL
Section Relative (Windows TLS)
@ GOTTPOFF
Global Offset Table, PC Relative.
@ TPOFF
Global Offset Table, Thread Pointer Offset.
@ MO_LO16
MO_LO16 - On a symbol operand, this represents a relocation containing lower 16 bit of the address.
@ MO_LO_0_7
MO_LO_0_7 - On a symbol operand, this represents a relocation containing bits 0 through 7 of the addr...
@ MO_LO_8_15
MO_LO_8_15 - On a symbol operand, this represents a relocation containing bits 8 through 15 of the ad...
@ MO_NONLAZY
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which,...
@ MO_HI_8_15
MO_HI_8_15 - On a symbol operand, this represents a relocation containing bits 24 through 31 of the a...
@ MO_HI16
MO_HI16 - On a symbol operand, this represents a relocation containing higher 16 bit of the address.
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand, this represents that the reference to the symbol is for an import...
@ MO_HI_0_7
MO_HI_0_7 - On a symbol operand, this represents a relocation containing bits 16 through 23 of the ad...
@ MO_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
std::string ParseARMTriple(const Triple &TT, StringRef CPU)
const MCSpecifierExpr * createLower16(const MCExpr *Expr, MCContext &Ctx)
const MCSpecifierExpr * createUpper16(const MCExpr *Expr, MCContext &Ctx)
SymbolStorageClass
Storage class tells where and what the symbol represents.
Definition COFF.h:218
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
Definition COFF.h:224
@ IMAGE_SYM_CLASS_STATIC
Static.
Definition COFF.h:225
@ IMAGE_SYM_DTYPE_FUNCTION
A function that returns a base type.
Definition COFF.h:276
@ SCT_COMPLEX_TYPE_SHIFT
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
Definition COFF.h:280
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)
Extract a Value from Metadata, allowing null.
Definition Metadata.h:681
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
Target & getTheThumbBETarget()
@ MCDR_DataRegionEnd
.end_data_region
@ MCDR_DataRegion
.data_region
@ MCDR_DataRegionJT8
.data_region jt8
@ MCDR_DataRegionJT32
.data_region jt32
@ MCDR_DataRegionJT16
.data_region jt16
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1714
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, ARMAsmPrinter &AP)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
DWARFExpression::Operation Op
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1849
DenormalMode parseDenormalFPAttribute(StringRef Str)
Returns the denormal mode to use for inputs and outputs.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565
Target & getTheARMLETarget()
unsigned convertAddSubFlagsOpcode(unsigned OldOpc)
Map pseudo instructions that imply an 'S' bit onto real opcodes.
@ MCSA_IndirectSymbol
.indirect_symbol (MachO)
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Target & getTheARMBETarget()
Target & getTheThumbLETarget()
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:851
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Represent subnormal handling kind for floating point instruction inputs and outputs.
static constexpr DenormalMode getPositiveZero()
static constexpr DenormalMode getPreserveSign()
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...