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