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