LLVM 21.0.0git
ARMAsmPrinter.cpp
Go to the documentation of this file.
1//===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains a printer that converts from our internal representation
10// of machine-dependent LLVM code to GAS-format ARM assembly language.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ARMAsmPrinter.h"
15#include "ARM.h"
18#include "ARMTargetMachine.h"
19#include "ARMTargetObjectFile.h"
27#include "llvm/IR/Constants.h"
28#include "llvm/IR/DataLayout.h"
29#include "llvm/IR/Mangler.h"
30#include "llvm/IR/Module.h"
31#include "llvm/IR/Type.h"
32#include "llvm/MC/MCAsmInfo.h"
33#include "llvm/MC/MCAssembler.h"
34#include "llvm/MC/MCContext.h"
36#include "llvm/MC/MCInst.h"
39#include "llvm/MC/MCStreamer.h"
40#include "llvm/MC/MCSymbol.h"
43#include "llvm/Support/Debug.h"
47using namespace llvm;
48
49#define DEBUG_TYPE "asm-printer"
50
52 std::unique_ptr<MCStreamer> Streamer)
53 : AsmPrinter(TM, std::move(Streamer)), Subtarget(nullptr), AFI(nullptr),
54 MCP(nullptr), InConstantPool(false), OptimizationGoals(-1) {}
55
57 // Make sure to terminate any constant pools that were at the end
58 // of the function.
59 if (!InConstantPool)
60 return;
61 InConstantPool = false;
62 OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
63}
64
66 auto &TS =
67 static_cast<ARMTargetStreamer &>(*OutStreamer->getTargetStreamer());
68 if (AFI->isThumbFunction()) {
69 OutStreamer->emitAssemblerFlag(MCAF_Code16);
70 TS.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::tLDRspi:
1315 // Used to restore LR in a prologue which uses it as a temporary, has
1316 // no effect on unwind tables.
1317 return;
1318 case ARM::MOVr:
1319 case ARM::tMOVr:
1320 Offset = 0;
1321 break;
1322 case ARM::ADDri:
1323 case ARM::t2ADDri:
1324 case ARM::t2ADDri12:
1325 case ARM::t2ADDspImm:
1326 case ARM::t2ADDspImm12:
1327 Offset = -MI->getOperand(2).getImm();
1328 break;
1329 case ARM::SUBri:
1330 case ARM::t2SUBri:
1331 case ARM::t2SUBri12:
1332 case ARM::t2SUBspImm:
1333 case ARM::t2SUBspImm12:
1334 Offset = MI->getOperand(2).getImm();
1335 break;
1336 case ARM::tSUBspi:
1337 Offset = MI->getOperand(2).getImm()*4;
1338 break;
1339 case ARM::tADDspi:
1340 case ARM::tADDrSPi:
1341 Offset = -MI->getOperand(2).getImm()*4;
1342 break;
1343 case ARM::tADDhirr:
1344 Offset =
1345 -AFI->EHPrologueOffsetInRegs.lookup(MI->getOperand(2).getReg());
1346 break;
1347 }
1348
1350 if (DstReg == FramePtr && FramePtr != ARM::SP)
1351 // Set-up of the frame pointer. Positive values correspond to "add"
1352 // instruction.
1353 ATS.emitSetFP(FramePtr, ARM::SP, -Offset);
1354 else if (DstReg == ARM::SP) {
1355 // Change of SP by an offset. Positive values correspond to "sub"
1356 // instruction.
1357 ATS.emitPad(Offset);
1358 } else {
1359 // Move of SP to a register. Positive values correspond to an "add"
1360 // instruction.
1361 ATS.emitMovSP(DstReg, -Offset);
1362 }
1363 }
1364 } else if (DstReg == ARM::SP) {
1365 MI->print(errs());
1366 llvm_unreachable("Unsupported opcode for unwinding information");
1367 } else {
1368 int64_t Offset = 0;
1369 switch (Opc) {
1370 case ARM::tMOVr:
1371 // If a Thumb1 function spills r8-r11, we copy the values to low
1372 // registers before pushing them. Record the copy so we can emit the
1373 // correct ".save" later.
1374 AFI->EHPrologueRemappedRegs[DstReg] = SrcReg;
1375 break;
1376 case ARM::tLDRpci: {
1377 // Grab the constpool index and check, whether it corresponds to
1378 // original or cloned constpool entry.
1379 unsigned CPI = MI->getOperand(1).getIndex();
1380 const MachineConstantPool *MCP = MF.getConstantPool();
1381 if (CPI >= MCP->getConstants().size())
1382 CPI = AFI->getOriginalCPIdx(CPI);
1383 assert(CPI != -1U && "Invalid constpool index");
1384
1385 // Derive the actual offset.
1386 const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI];
1387 assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry");
1388 Offset = cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue();
1389 AFI->EHPrologueOffsetInRegs[DstReg] = Offset;
1390 break;
1391 }
1392 case ARM::t2MOVi16:
1393 Offset = MI->getOperand(1).getImm();
1394 AFI->EHPrologueOffsetInRegs[DstReg] = Offset;
1395 break;
1396 case ARM::t2MOVTi16:
1397 Offset = MI->getOperand(2).getImm();
1398 AFI->EHPrologueOffsetInRegs[DstReg] |= (Offset << 16);
1399 break;
1400 case ARM::tMOVi8:
1401 Offset = MI->getOperand(2).getImm();
1402 AFI->EHPrologueOffsetInRegs[DstReg] = Offset;
1403 break;
1404 case ARM::tLSLri:
1405 assert(MI->getOperand(3).getImm() == 8 &&
1406 "The shift amount is not equal to 8");
1407 assert(MI->getOperand(2).getReg() == MI->getOperand(0).getReg() &&
1408 "The source register is not equal to the destination register");
1409 AFI->EHPrologueOffsetInRegs[DstReg] <<= 8;
1410 break;
1411 case ARM::tADDi8:
1412 assert(MI->getOperand(2).getReg() == MI->getOperand(0).getReg() &&
1413 "The source register is not equal to the destination register");
1414 Offset = MI->getOperand(3).getImm();
1415 AFI->EHPrologueOffsetInRegs[DstReg] += Offset;
1416 break;
1417 case ARM::t2PAC:
1418 case ARM::t2PACBTI:
1419 AFI->EHPrologueRemappedRegs[ARM::R12] = ARM::RA_AUTH_CODE;
1420 break;
1421 default:
1422 MI->print(errs());
1423 llvm_unreachable("Unsupported opcode for unwinding information");
1424 }
1425 }
1426 }
1427}
1428
1429// Simple pseudo-instructions have their lowering (with expansion to real
1430// instructions) auto-generated.
1431#include "ARMGenMCPseudoLowering.inc"
1432
1434 // TODOD FIXME: Enable feature predicate checks once all the test pass.
1435 // ARM_MC::verifyInstructionPredicates(MI->getOpcode(),
1436 // getSubtargetInfo().getFeatureBits());
1437
1438 const DataLayout &DL = getDataLayout();
1439 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
1440 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1441
1442 // If we just ended a constant pool, mark it as such.
1443 if (InConstantPool && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) {
1444 OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
1445 InConstantPool = false;
1446 }
1447
1448 // Emit unwinding stuff for frame-related instructions
1449 if (Subtarget->isTargetEHABICompatible() &&
1450 MI->getFlag(MachineInstr::FrameSetup))
1451 EmitUnwindingInstruction(MI);
1452
1453 // Do any auto-generated pseudo lowerings.
1454 if (MCInst OutInst; lowerPseudoInstExpansion(MI, OutInst)) {
1455 EmitToStreamer(*OutStreamer, OutInst);
1456 return;
1457 }
1458
1459 assert(!convertAddSubFlagsOpcode(MI->getOpcode()) &&
1460 "Pseudo flag setting opcode should be expanded early");
1461
1462 // Check for manual lowerings.
1463 unsigned Opc = MI->getOpcode();
1464 switch (Opc) {
1465 case ARM::t2MOVi32imm: llvm_unreachable("Should be lowered by thumb2it pass");
1466 case ARM::DBG_VALUE: llvm_unreachable("Should be handled by generic printing");
1467 case ARM::LEApcrel:
1468 case ARM::tLEApcrel:
1469 case ARM::t2LEApcrel: {
1470 // FIXME: Need to also handle globals and externals
1471 MCSymbol *CPISymbol = GetCPISymbol(MI->getOperand(1).getIndex());
1472 EmitToStreamer(*OutStreamer, MCInstBuilder(MI->getOpcode() ==
1473 ARM::t2LEApcrel ? ARM::t2ADR
1474 : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR
1475 : ARM::ADR))
1476 .addReg(MI->getOperand(0).getReg())
1478 // Add predicate operands.
1479 .addImm(MI->getOperand(2).getImm())
1480 .addReg(MI->getOperand(3).getReg()));
1481 return;
1482 }
1483 case ARM::LEApcrelJT:
1484 case ARM::tLEApcrelJT:
1485 case ARM::t2LEApcrelJT: {
1486 MCSymbol *JTIPICSymbol =
1487 GetARMJTIPICJumpTableLabel(MI->getOperand(1).getIndex());
1488 EmitToStreamer(*OutStreamer, MCInstBuilder(MI->getOpcode() ==
1489 ARM::t2LEApcrelJT ? ARM::t2ADR
1490 : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR
1491 : ARM::ADR))
1492 .addReg(MI->getOperand(0).getReg())
1494 // Add predicate operands.
1495 .addImm(MI->getOperand(2).getImm())
1496 .addReg(MI->getOperand(3).getReg()));
1497 return;
1498 }
1499 // Darwin call instructions are just normal call instructions with different
1500 // clobber semantics (they clobber R9).
1501 case ARM::BX_CALL: {
1503 .addReg(ARM::LR)
1504 .addReg(ARM::PC)
1505 // Add predicate operands.
1506 .addImm(ARMCC::AL)
1507 .addReg(0)
1508 // Add 's' bit operand (always reg0 for this)
1509 .addReg(0));
1510
1511 assert(Subtarget->hasV4TOps());
1513 .addReg(MI->getOperand(0).getReg()));
1514 return;
1515 }
1516 case ARM::tBX_CALL: {
1517 if (Subtarget->hasV5TOps())
1518 llvm_unreachable("Expected BLX to be selected for v5t+");
1519
1520 // On ARM v4t, when doing a call from thumb mode, we need to ensure
1521 // that the saved lr has its LSB set correctly (the arch doesn't
1522 // have blx).
1523 // So here we generate a bl to a small jump pad that does bx rN.
1524 // The jump pads are emitted after the function body.
1525
1526 Register TReg = MI->getOperand(0).getReg();
1527 MCSymbol *TRegSym = nullptr;
1528 for (std::pair<unsigned, MCSymbol *> &TIP : ThumbIndirectPads) {
1529 if (TIP.first == TReg) {
1530 TRegSym = TIP.second;
1531 break;
1532 }
1533 }
1534
1535 if (!TRegSym) {
1536 TRegSym = OutContext.createTempSymbol();
1537 ThumbIndirectPads.push_back(std::make_pair(TReg, TRegSym));
1538 }
1539
1540 // Create a link-saving branch to the Reg Indirect Jump Pad.
1542 // Predicate comes first here.
1543 .addImm(ARMCC::AL).addReg(0)
1544 .addExpr(MCSymbolRefExpr::create(TRegSym, OutContext)));
1545 return;
1546 }
1547 case ARM::BMOVPCRX_CALL: {
1549 .addReg(ARM::LR)
1550 .addReg(ARM::PC)
1551 // Add predicate operands.
1552 .addImm(ARMCC::AL)
1553 .addReg(0)
1554 // Add 's' bit operand (always reg0 for this)
1555 .addReg(0));
1556
1558 .addReg(ARM::PC)
1559 .addReg(MI->getOperand(0).getReg())
1560 // Add predicate operands.
1562 .addReg(0)
1563 // Add 's' bit operand (always reg0 for this)
1564 .addReg(0));
1565 return;
1566 }
1567 case ARM::BMOVPCB_CALL: {
1569 .addReg(ARM::LR)
1570 .addReg(ARM::PC)
1571 // Add predicate operands.
1572 .addImm(ARMCC::AL)
1573 .addReg(0)
1574 // Add 's' bit operand (always reg0 for this)
1575 .addReg(0));
1576
1577 const MachineOperand &Op = MI->getOperand(0);
1578 const GlobalValue *GV = Op.getGlobal();
1579 const unsigned TF = Op.getTargetFlags();
1580 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1581 const MCExpr *GVSymExpr = MCSymbolRefExpr::create(GVSym, OutContext);
1583 .addExpr(GVSymExpr)
1584 // Add predicate operands.
1585 .addImm(ARMCC::AL)
1586 .addReg(0));
1587 return;
1588 }
1589 case ARM::MOVi16_ga_pcrel:
1590 case ARM::t2MOVi16_ga_pcrel: {
1591 MCInst TmpInst;
1592 TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16);
1593 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1594
1595 unsigned TF = MI->getOperand(1).getTargetFlags();
1596 const GlobalValue *GV = MI->getOperand(1).getGlobal();
1597 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1598 const MCExpr *GVSymExpr = MCSymbolRefExpr::create(GVSym, OutContext);
1599
1600 MCSymbol *LabelSym =
1601 getPICLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(),
1602 MI->getOperand(2).getImm(), OutContext);
1603 const MCExpr *LabelSymExpr= MCSymbolRefExpr::create(LabelSym, OutContext);
1604 unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;
1605 const MCExpr *PCRelExpr =
1607 MCBinaryExpr::createAdd(LabelSymExpr,
1610 TmpInst.addOperand(MCOperand::createExpr(PCRelExpr));
1611
1612 // Add predicate operands.
1614 TmpInst.addOperand(MCOperand::createReg(0));
1615 // Add 's' bit operand (always reg0 for this)
1616 TmpInst.addOperand(MCOperand::createReg(0));
1617 EmitToStreamer(*OutStreamer, TmpInst);
1618 return;
1619 }
1620 case ARM::MOVTi16_ga_pcrel:
1621 case ARM::t2MOVTi16_ga_pcrel: {
1622 MCInst TmpInst;
1623 TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel
1624 ? ARM::MOVTi16 : ARM::t2MOVTi16);
1625 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1626 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(1).getReg()));
1627
1628 unsigned TF = MI->getOperand(2).getTargetFlags();
1629 const GlobalValue *GV = MI->getOperand(2).getGlobal();
1630 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
1631 const MCExpr *GVSymExpr = MCSymbolRefExpr::create(GVSym, OutContext);
1632
1633 MCSymbol *LabelSym =
1634 getPICLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(),
1635 MI->getOperand(3).getImm(), OutContext);
1636 const MCExpr *LabelSymExpr= MCSymbolRefExpr::create(LabelSym, OutContext);
1637 unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;
1638 const MCExpr *PCRelExpr =
1640 MCBinaryExpr::createAdd(LabelSymExpr,
1643 TmpInst.addOperand(MCOperand::createExpr(PCRelExpr));
1644 // Add predicate operands.
1646 TmpInst.addOperand(MCOperand::createReg(0));
1647 // Add 's' bit operand (always reg0 for this)
1648 TmpInst.addOperand(MCOperand::createReg(0));
1649 EmitToStreamer(*OutStreamer, TmpInst);
1650 return;
1651 }
1652 case ARM::t2BFi:
1653 case ARM::t2BFic:
1654 case ARM::t2BFLi:
1655 case ARM::t2BFr:
1656 case ARM::t2BFLr: {
1657 // This is a Branch Future instruction.
1658
1659 const MCExpr *BranchLabel = MCSymbolRefExpr::create(
1660 getBFLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(),
1661 MI->getOperand(0).getIndex(), OutContext),
1662 OutContext);
1663
1664 auto MCInst = MCInstBuilder(Opc).addExpr(BranchLabel);
1665 if (MI->getOperand(1).isReg()) {
1666 // For BFr/BFLr
1667 MCInst.addReg(MI->getOperand(1).getReg());
1668 } else {
1669 // For BFi/BFLi/BFic
1670 const MCExpr *BranchTarget;
1671 if (MI->getOperand(1).isMBB())
1672 BranchTarget = MCSymbolRefExpr::create(
1673 MI->getOperand(1).getMBB()->getSymbol(), OutContext);
1674 else if (MI->getOperand(1).isGlobal()) {
1675 const GlobalValue *GV = MI->getOperand(1).getGlobal();
1676 BranchTarget = MCSymbolRefExpr::create(
1677 GetARMGVSymbol(GV, MI->getOperand(1).getTargetFlags()), OutContext);
1678 } else if (MI->getOperand(1).isSymbol()) {
1679 BranchTarget = MCSymbolRefExpr::create(
1680 GetExternalSymbolSymbol(MI->getOperand(1).getSymbolName()),
1681 OutContext);
1682 } else
1683 llvm_unreachable("Unhandled operand kind in Branch Future instruction");
1684
1685 MCInst.addExpr(BranchTarget);
1686 }
1687
1688 if (Opc == ARM::t2BFic) {
1689 const MCExpr *ElseLabel = MCSymbolRefExpr::create(
1690 getBFLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(),
1691 MI->getOperand(2).getIndex(), OutContext),
1692 OutContext);
1693 MCInst.addExpr(ElseLabel);
1694 MCInst.addImm(MI->getOperand(3).getImm());
1695 } else {
1696 MCInst.addImm(MI->getOperand(2).getImm())
1697 .addReg(MI->getOperand(3).getReg());
1698 }
1699
1701 return;
1702 }
1703 case ARM::t2BF_LabelPseudo: {
1704 // This is a pseudo op for a label used by a branch future instruction
1705
1706 // Emit the label.
1707 OutStreamer->emitLabel(getBFLabel(DL.getPrivateGlobalPrefix(),
1709 MI->getOperand(0).getIndex(), OutContext));
1710 return;
1711 }
1712 case ARM::tPICADD: {
1713 // This is a pseudo op for a label + instruction sequence, which looks like:
1714 // LPC0:
1715 // add r0, pc
1716 // This adds the address of LPC0 to r0.
1717
1718 // Emit the label.
1719 OutStreamer->emitLabel(getPICLabel(DL.getPrivateGlobalPrefix(),
1721 MI->getOperand(2).getImm(), OutContext));
1722
1723 // Form and emit the add.
1725 .addReg(MI->getOperand(0).getReg())
1726 .addReg(MI->getOperand(0).getReg())
1727 .addReg(ARM::PC)
1728 // Add predicate operands.
1730 .addReg(0));
1731 return;
1732 }
1733 case ARM::PICADD: {
1734 // This is a pseudo op for a label + instruction sequence, which looks like:
1735 // LPC0:
1736 // add r0, pc, r0
1737 // This adds the address of LPC0 to r0.
1738
1739 // Emit the label.
1740 OutStreamer->emitLabel(getPICLabel(DL.getPrivateGlobalPrefix(),
1742 MI->getOperand(2).getImm(), OutContext));
1743
1744 // Form and emit the add.
1746 .addReg(MI->getOperand(0).getReg())
1747 .addReg(ARM::PC)
1748 .addReg(MI->getOperand(1).getReg())
1749 // Add predicate operands.
1750 .addImm(MI->getOperand(3).getImm())
1751 .addReg(MI->getOperand(4).getReg())
1752 // Add 's' bit operand (always reg0 for this)
1753 .addReg(0));
1754 return;
1755 }
1756 case ARM::PICSTR:
1757 case ARM::PICSTRB:
1758 case ARM::PICSTRH:
1759 case ARM::PICLDR:
1760 case ARM::PICLDRB:
1761 case ARM::PICLDRH:
1762 case ARM::PICLDRSB:
1763 case ARM::PICLDRSH: {
1764 // This is a pseudo op for a label + instruction sequence, which looks like:
1765 // LPC0:
1766 // OP r0, [pc, r0]
1767 // The LCP0 label is referenced by a constant pool entry in order to get
1768 // a PC-relative address at the ldr instruction.
1769
1770 // Emit the label.
1771 OutStreamer->emitLabel(getPICLabel(DL.getPrivateGlobalPrefix(),
1773 MI->getOperand(2).getImm(), OutContext));
1774
1775 // Form and emit the load
1776 unsigned Opcode;
1777 switch (MI->getOpcode()) {
1778 default:
1779 llvm_unreachable("Unexpected opcode!");
1780 case ARM::PICSTR: Opcode = ARM::STRrs; break;
1781 case ARM::PICSTRB: Opcode = ARM::STRBrs; break;
1782 case ARM::PICSTRH: Opcode = ARM::STRH; break;
1783 case ARM::PICLDR: Opcode = ARM::LDRrs; break;
1784 case ARM::PICLDRB: Opcode = ARM::LDRBrs; break;
1785 case ARM::PICLDRH: Opcode = ARM::LDRH; break;
1786 case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
1787 case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
1788 }
1790 .addReg(MI->getOperand(0).getReg())
1791 .addReg(ARM::PC)
1792 .addReg(MI->getOperand(1).getReg())
1793 .addImm(0)
1794 // Add predicate operands.
1795 .addImm(MI->getOperand(3).getImm())
1796 .addReg(MI->getOperand(4).getReg()));
1797
1798 return;
1799 }
1800 case ARM::CONSTPOOL_ENTRY: {
1801 if (Subtarget->genExecuteOnly())
1802 llvm_unreachable("execute-only should not generate constant pools");
1803
1804 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1805 /// in the function. The first operand is the ID# for this instruction, the
1806 /// second is the index into the MachineConstantPool that this is, the third
1807 /// is the size in bytes of this constant pool entry.
1808 /// The required alignment is specified on the basic block holding this MI.
1809 unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1810 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();
1811
1812 // If this is the first entry of the pool, mark it.
1813 if (!InConstantPool) {
1814 OutStreamer->emitDataRegion(MCDR_DataRegion);
1815 InConstantPool = true;
1816 }
1817
1818 OutStreamer->emitLabel(GetCPISymbol(LabelId));
1819
1820 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1821 if (MCPE.isMachineConstantPoolEntry())
1823 else
1825 return;
1826 }
1827 case ARM::JUMPTABLE_ADDRS:
1829 return;
1830 case ARM::JUMPTABLE_INSTS:
1832 return;
1833 case ARM::JUMPTABLE_TBB:
1834 case ARM::JUMPTABLE_TBH:
1835 emitJumpTableTBInst(MI, MI->getOpcode() == ARM::JUMPTABLE_TBB ? 1 : 2);
1836 return;
1837 case ARM::t2BR_JT: {
1839 .addReg(ARM::PC)
1840 .addReg(MI->getOperand(0).getReg())
1841 // Add predicate operands.
1843 .addReg(0));
1844 return;
1845 }
1846 case ARM::t2TBB_JT:
1847 case ARM::t2TBH_JT: {
1848 unsigned Opc = MI->getOpcode() == ARM::t2TBB_JT ? ARM::t2TBB : ARM::t2TBH;
1849 // Lower and emit the PC label, then the instruction itself.
1850 OutStreamer->emitLabel(GetCPISymbol(MI->getOperand(3).getImm()));
1852 .addReg(MI->getOperand(0).getReg())
1853 .addReg(MI->getOperand(1).getReg())
1854 // Add predicate operands.
1856 .addReg(0));
1857 return;
1858 }
1859 case ARM::tTBB_JT:
1860 case ARM::tTBH_JT: {
1861
1862 bool Is8Bit = MI->getOpcode() == ARM::tTBB_JT;
1863 Register Base = MI->getOperand(0).getReg();
1864 Register Idx = MI->getOperand(1).getReg();
1865 assert(MI->getOperand(1).isKill() && "We need the index register as scratch!");
1866
1867 // Multiply up idx if necessary.
1868 if (!Is8Bit)
1870 .addReg(Idx)
1871 .addReg(ARM::CPSR)
1872 .addReg(Idx)
1873 .addImm(1)
1874 // Add predicate operands.
1875 .addImm(ARMCC::AL)
1876 .addReg(0));
1877
1878 if (Base == ARM::PC) {
1879 // TBB [base, idx] =
1880 // ADDS idx, idx, base
1881 // LDRB idx, [idx, #4] ; or LDRH if TBH
1882 // LSLS idx, #1
1883 // ADDS pc, pc, idx
1884
1885 // When using PC as the base, it's important that there is no padding
1886 // between the last ADDS and the start of the jump table. The jump table
1887 // is 4-byte aligned, so we ensure we're 4 byte aligned here too.
1888 //
1889 // FIXME: Ideally we could vary the LDRB index based on the padding
1890 // between the sequence and jump table, however that relies on MCExprs
1891 // for load indexes which are currently not supported.
1892 OutStreamer->emitCodeAlignment(Align(4), &getSubtargetInfo());
1894 .addReg(Idx)
1895 .addReg(Idx)
1896 .addReg(Base)
1897 // Add predicate operands.
1898 .addImm(ARMCC::AL)
1899 .addReg(0));
1900
1901 unsigned Opc = Is8Bit ? ARM::tLDRBi : ARM::tLDRHi;
1903 .addReg(Idx)
1904 .addReg(Idx)
1905 .addImm(Is8Bit ? 4 : 2)
1906 // Add predicate operands.
1907 .addImm(ARMCC::AL)
1908 .addReg(0));
1909 } else {
1910 // TBB [base, idx] =
1911 // LDRB idx, [base, idx] ; or LDRH if TBH
1912 // LSLS idx, #1
1913 // ADDS pc, pc, idx
1914
1915 unsigned Opc = Is8Bit ? ARM::tLDRBr : ARM::tLDRHr;
1917 .addReg(Idx)
1918 .addReg(Base)
1919 .addReg(Idx)
1920 // Add predicate operands.
1921 .addImm(ARMCC::AL)
1922 .addReg(0));
1923 }
1924
1926 .addReg(Idx)
1927 .addReg(ARM::CPSR)
1928 .addReg(Idx)
1929 .addImm(1)
1930 // Add predicate operands.
1931 .addImm(ARMCC::AL)
1932 .addReg(0));
1933
1934 OutStreamer->emitLabel(GetCPISymbol(MI->getOperand(3).getImm()));
1936 .addReg(ARM::PC)
1937 .addReg(ARM::PC)
1938 .addReg(Idx)
1939 // Add predicate operands.
1940 .addImm(ARMCC::AL)
1941 .addReg(0));
1942 return;
1943 }
1944 case ARM::tBR_JTr:
1945 case ARM::BR_JTr: {
1946 // mov pc, target
1947 MCInst TmpInst;
1948 unsigned Opc = MI->getOpcode() == ARM::BR_JTr ?
1949 ARM::MOVr : ARM::tMOVr;
1950 TmpInst.setOpcode(Opc);
1951 TmpInst.addOperand(MCOperand::createReg(ARM::PC));
1952 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1953 // Add predicate operands.
1955 TmpInst.addOperand(MCOperand::createReg(0));
1956 // Add 's' bit operand (always reg0 for this)
1957 if (Opc == ARM::MOVr)
1958 TmpInst.addOperand(MCOperand::createReg(0));
1959 EmitToStreamer(*OutStreamer, TmpInst);
1960 return;
1961 }
1962 case ARM::BR_JTm_i12: {
1963 // ldr pc, target
1964 MCInst TmpInst;
1965 TmpInst.setOpcode(ARM::LDRi12);
1966 TmpInst.addOperand(MCOperand::createReg(ARM::PC));
1967 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1968 TmpInst.addOperand(MCOperand::createImm(MI->getOperand(2).getImm()));
1969 // Add predicate operands.
1971 TmpInst.addOperand(MCOperand::createReg(0));
1972 EmitToStreamer(*OutStreamer, TmpInst);
1973 return;
1974 }
1975 case ARM::BR_JTm_rs: {
1976 // ldr pc, target
1977 MCInst TmpInst;
1978 TmpInst.setOpcode(ARM::LDRrs);
1979 TmpInst.addOperand(MCOperand::createReg(ARM::PC));
1980 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1981 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(1).getReg()));
1982 TmpInst.addOperand(MCOperand::createImm(MI->getOperand(2).getImm()));
1983 // Add predicate operands.
1985 TmpInst.addOperand(MCOperand::createReg(0));
1986 EmitToStreamer(*OutStreamer, TmpInst);
1987 return;
1988 }
1989 case ARM::BR_JTadd: {
1990 // add pc, target, idx
1992 .addReg(ARM::PC)
1993 .addReg(MI->getOperand(0).getReg())
1994 .addReg(MI->getOperand(1).getReg())
1995 // Add predicate operands.
1997 .addReg(0)
1998 // Add 's' bit operand (always reg0 for this)
1999 .addReg(0));
2000 return;
2001 }
2002 case ARM::SPACE:
2003 OutStreamer->emitZeros(MI->getOperand(1).getImm());
2004 return;
2005 case ARM::TRAP: {
2006 // Non-Darwin binutils don't yet support the "trap" mnemonic.
2007 // FIXME: Remove this special case when they do.
2008 if (!Subtarget->isTargetMachO()) {
2009 uint32_t Val = 0xe7ffdefeUL;
2010 OutStreamer->AddComment("trap");
2011 ATS.emitInst(Val);
2012 return;
2013 }
2014 break;
2015 }
2016 case ARM::TRAPNaCl: {
2017 uint32_t Val = 0xe7fedef0UL;
2018 OutStreamer->AddComment("trap");
2019 ATS.emitInst(Val);
2020 return;
2021 }
2022 case ARM::tTRAP: {
2023 // Non-Darwin binutils don't yet support the "trap" mnemonic.
2024 // FIXME: Remove this special case when they do.
2025 if (!Subtarget->isTargetMachO()) {
2026 uint16_t Val = 0xdefe;
2027 OutStreamer->AddComment("trap");
2028 ATS.emitInst(Val, 'n');
2029 return;
2030 }
2031 break;
2032 }
2033 case ARM::t2Int_eh_sjlj_setjmp:
2034 case ARM::t2Int_eh_sjlj_setjmp_nofp:
2035 case ARM::tInt_eh_sjlj_setjmp: {
2036 // Two incoming args: GPR:$src, GPR:$val
2037 // mov $val, pc
2038 // adds $val, #7
2039 // str $val, [$src, #4]
2040 // movs r0, #0
2041 // b LSJLJEH
2042 // movs r0, #1
2043 // LSJLJEH:
2044 Register SrcReg = MI->getOperand(0).getReg();
2045 Register ValReg = MI->getOperand(1).getReg();
2046 MCSymbol *Label = OutContext.createTempSymbol("SJLJEH");
2047 OutStreamer->AddComment("eh_setjmp begin");
2049 .addReg(ValReg)
2050 .addReg(ARM::PC)
2051 // Predicate.
2052 .addImm(ARMCC::AL)
2053 .addReg(0));
2054
2056 .addReg(ValReg)
2057 // 's' bit operand
2058 .addReg(ARM::CPSR)
2059 .addReg(ValReg)
2060 .addImm(7)
2061 // Predicate.
2062 .addImm(ARMCC::AL)
2063 .addReg(0));
2064
2066 .addReg(ValReg)
2067 .addReg(SrcReg)
2068 // The offset immediate is #4. The operand value is scaled by 4 for the
2069 // tSTR instruction.
2070 .addImm(1)
2071 // Predicate.
2072 .addImm(ARMCC::AL)
2073 .addReg(0));
2074
2076 .addReg(ARM::R0)
2077 .addReg(ARM::CPSR)
2078 .addImm(0)
2079 // Predicate.
2080 .addImm(ARMCC::AL)
2081 .addReg(0));
2082
2083 const MCExpr *SymbolExpr = MCSymbolRefExpr::create(Label, OutContext);
2085 .addExpr(SymbolExpr)
2086 .addImm(ARMCC::AL)
2087 .addReg(0));
2088
2089 OutStreamer->AddComment("eh_setjmp end");
2091 .addReg(ARM::R0)
2092 .addReg(ARM::CPSR)
2093 .addImm(1)
2094 // Predicate.
2095 .addImm(ARMCC::AL)
2096 .addReg(0));
2097
2098 OutStreamer->emitLabel(Label);
2099 return;
2100 }
2101
2102 case ARM::Int_eh_sjlj_setjmp_nofp:
2103 case ARM::Int_eh_sjlj_setjmp: {
2104 // Two incoming args: GPR:$src, GPR:$val
2105 // add $val, pc, #8
2106 // str $val, [$src, #+4]
2107 // mov r0, #0
2108 // add pc, pc, #0
2109 // mov r0, #1
2110 Register SrcReg = MI->getOperand(0).getReg();
2111 Register ValReg = MI->getOperand(1).getReg();
2112
2113 OutStreamer->AddComment("eh_setjmp begin");
2115 .addReg(ValReg)
2116 .addReg(ARM::PC)
2117 .addImm(8)
2118 // Predicate.
2119 .addImm(ARMCC::AL)
2120 .addReg(0)
2121 // 's' bit operand (always reg0 for this).
2122 .addReg(0));
2123
2125 .addReg(ValReg)
2126 .addReg(SrcReg)
2127 .addImm(4)
2128 // Predicate.
2129 .addImm(ARMCC::AL)
2130 .addReg(0));
2131
2133 .addReg(ARM::R0)
2134 .addImm(0)
2135 // Predicate.
2136 .addImm(ARMCC::AL)
2137 .addReg(0)
2138 // 's' bit operand (always reg0 for this).
2139 .addReg(0));
2140
2142 .addReg(ARM::PC)
2143 .addReg(ARM::PC)
2144 .addImm(0)
2145 // Predicate.
2146 .addImm(ARMCC::AL)
2147 .addReg(0)
2148 // 's' bit operand (always reg0 for this).
2149 .addReg(0));
2150
2151 OutStreamer->AddComment("eh_setjmp end");
2153 .addReg(ARM::R0)
2154 .addImm(1)
2155 // Predicate.
2156 .addImm(ARMCC::AL)
2157 .addReg(0)
2158 // 's' bit operand (always reg0 for this).
2159 .addReg(0));
2160 return;
2161 }
2162 case ARM::Int_eh_sjlj_longjmp: {
2163 // ldr sp, [$src, #8]
2164 // ldr $scratch, [$src, #4]
2165 // ldr r7, [$src]
2166 // bx $scratch
2167 Register SrcReg = MI->getOperand(0).getReg();
2168 Register ScratchReg = MI->getOperand(1).getReg();
2170 .addReg(ARM::SP)
2171 .addReg(SrcReg)
2172 .addImm(8)
2173 // Predicate.
2174 .addImm(ARMCC::AL)
2175 .addReg(0));
2176
2178 .addReg(ScratchReg)
2179 .addReg(SrcReg)
2180 .addImm(4)
2181 // Predicate.
2182 .addImm(ARMCC::AL)
2183 .addReg(0));
2184
2185 const MachineFunction &MF = *MI->getParent()->getParent();
2186 const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();
2187
2188 if (STI.isTargetDarwin() || STI.isTargetWindows()) {
2189 // These platforms always use the same frame register
2191 .addReg(STI.getFramePointerReg())
2192 .addReg(SrcReg)
2193 .addImm(0)
2194 // Predicate.
2196 .addReg(0));
2197 } else {
2198 // If the calling code might use either R7 or R11 as
2199 // frame pointer register, restore it into both.
2201 .addReg(ARM::R7)
2202 .addReg(SrcReg)
2203 .addImm(0)
2204 // Predicate.
2205 .addImm(ARMCC::AL)
2206 .addReg(0));
2208 .addReg(ARM::R11)
2209 .addReg(SrcReg)
2210 .addImm(0)
2211 // Predicate.
2212 .addImm(ARMCC::AL)
2213 .addReg(0));
2214 }
2215
2216 assert(Subtarget->hasV4TOps());
2218 .addReg(ScratchReg)
2219 // Predicate.
2220 .addImm(ARMCC::AL)
2221 .addReg(0));
2222 return;
2223 }
2224 case ARM::tInt_eh_sjlj_longjmp: {
2225 // ldr $scratch, [$src, #8]
2226 // mov sp, $scratch
2227 // ldr $scratch, [$src, #4]
2228 // ldr r7, [$src]
2229 // bx $scratch
2230 Register SrcReg = MI->getOperand(0).getReg();
2231 Register ScratchReg = MI->getOperand(1).getReg();
2232
2233 const MachineFunction &MF = *MI->getParent()->getParent();
2234 const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();
2235
2237 .addReg(ScratchReg)
2238 .addReg(SrcReg)
2239 // The offset immediate is #8. The operand value is scaled by 4 for the
2240 // tLDR instruction.
2241 .addImm(2)
2242 // Predicate.
2243 .addImm(ARMCC::AL)
2244 .addReg(0));
2245
2247 .addReg(ARM::SP)
2248 .addReg(ScratchReg)
2249 // Predicate.
2250 .addImm(ARMCC::AL)
2251 .addReg(0));
2252
2254 .addReg(ScratchReg)
2255 .addReg(SrcReg)
2256 .addImm(1)
2257 // Predicate.
2258 .addImm(ARMCC::AL)
2259 .addReg(0));
2260
2261 if (STI.isTargetDarwin() || STI.isTargetWindows()) {
2262 // These platforms always use the same frame register
2264 .addReg(STI.getFramePointerReg())
2265 .addReg(SrcReg)
2266 .addImm(0)
2267 // Predicate.
2269 .addReg(0));
2270 } else {
2271 // If the calling code might use either R7 or R11 as
2272 // frame pointer register, restore it into both.
2274 .addReg(ARM::R7)
2275 .addReg(SrcReg)
2276 .addImm(0)
2277 // Predicate.
2278 .addImm(ARMCC::AL)
2279 .addReg(0));
2281 .addReg(ARM::R11)
2282 .addReg(SrcReg)
2283 .addImm(0)
2284 // Predicate.
2285 .addImm(ARMCC::AL)
2286 .addReg(0));
2287 }
2288
2290 .addReg(ScratchReg)
2291 // Predicate.
2292 .addImm(ARMCC::AL)
2293 .addReg(0));
2294 return;
2295 }
2296 case ARM::tInt_WIN_eh_sjlj_longjmp: {
2297 // ldr.w r11, [$src, #0]
2298 // ldr.w sp, [$src, #8]
2299 // ldr.w pc, [$src, #4]
2300
2301 Register SrcReg = MI->getOperand(0).getReg();
2302
2304 .addReg(ARM::R11)
2305 .addReg(SrcReg)
2306 .addImm(0)
2307 // Predicate
2308 .addImm(ARMCC::AL)
2309 .addReg(0));
2311 .addReg(ARM::SP)
2312 .addReg(SrcReg)
2313 .addImm(8)
2314 // Predicate
2315 .addImm(ARMCC::AL)
2316 .addReg(0));
2318 .addReg(ARM::PC)
2319 .addReg(SrcReg)
2320 .addImm(4)
2321 // Predicate
2322 .addImm(ARMCC::AL)
2323 .addReg(0));
2324 return;
2325 }
2326 case ARM::PATCHABLE_FUNCTION_ENTER:
2328 return;
2329 case ARM::PATCHABLE_FUNCTION_EXIT:
2331 return;
2332 case ARM::PATCHABLE_TAIL_CALL:
2334 return;
2335 case ARM::SpeculationBarrierISBDSBEndBB: {
2336 // Print DSB SYS + ISB
2337 MCInst TmpInstDSB;
2338 TmpInstDSB.setOpcode(ARM::DSB);
2339 TmpInstDSB.addOperand(MCOperand::createImm(0xf));
2340 EmitToStreamer(*OutStreamer, TmpInstDSB);
2341 MCInst TmpInstISB;
2342 TmpInstISB.setOpcode(ARM::ISB);
2343 TmpInstISB.addOperand(MCOperand::createImm(0xf));
2344 EmitToStreamer(*OutStreamer, TmpInstISB);
2345 return;
2346 }
2347 case ARM::t2SpeculationBarrierISBDSBEndBB: {
2348 // Print DSB SYS + ISB
2349 MCInst TmpInstDSB;
2350 TmpInstDSB.setOpcode(ARM::t2DSB);
2351 TmpInstDSB.addOperand(MCOperand::createImm(0xf));
2353 TmpInstDSB.addOperand(MCOperand::createReg(0));
2354 EmitToStreamer(*OutStreamer, TmpInstDSB);
2355 MCInst TmpInstISB;
2356 TmpInstISB.setOpcode(ARM::t2ISB);
2357 TmpInstISB.addOperand(MCOperand::createImm(0xf));
2359 TmpInstISB.addOperand(MCOperand::createReg(0));
2360 EmitToStreamer(*OutStreamer, TmpInstISB);
2361 return;
2362 }
2363 case ARM::SpeculationBarrierSBEndBB: {
2364 // Print SB
2365 MCInst TmpInstSB;
2366 TmpInstSB.setOpcode(ARM::SB);
2367 EmitToStreamer(*OutStreamer, TmpInstSB);
2368 return;
2369 }
2370 case ARM::t2SpeculationBarrierSBEndBB: {
2371 // Print SB
2372 MCInst TmpInstSB;
2373 TmpInstSB.setOpcode(ARM::t2SB);
2374 EmitToStreamer(*OutStreamer, TmpInstSB);
2375 return;
2376 }
2377
2378 case ARM::SEH_StackAlloc:
2379 ATS.emitARMWinCFIAllocStack(MI->getOperand(0).getImm(),
2380 MI->getOperand(1).getImm());
2381 return;
2382
2383 case ARM::SEH_SaveRegs:
2384 case ARM::SEH_SaveRegs_Ret:
2385 ATS.emitARMWinCFISaveRegMask(MI->getOperand(0).getImm(),
2386 MI->getOperand(1).getImm());
2387 return;
2388
2389 case ARM::SEH_SaveSP:
2390 ATS.emitARMWinCFISaveSP(MI->getOperand(0).getImm());
2391 return;
2392
2393 case ARM::SEH_SaveFRegs:
2394 ATS.emitARMWinCFISaveFRegs(MI->getOperand(0).getImm(),
2395 MI->getOperand(1).getImm());
2396 return;
2397
2398 case ARM::SEH_SaveLR:
2399 ATS.emitARMWinCFISaveLR(MI->getOperand(0).getImm());
2400 return;
2401
2402 case ARM::SEH_Nop:
2403 case ARM::SEH_Nop_Ret:
2404 ATS.emitARMWinCFINop(MI->getOperand(0).getImm());
2405 return;
2406
2407 case ARM::SEH_PrologEnd:
2408 ATS.emitARMWinCFIPrologEnd(/*Fragment=*/false);
2409 return;
2410
2411 case ARM::SEH_EpilogStart:
2413 return;
2414
2415 case ARM::SEH_EpilogEnd:
2417 return;
2418 }
2419
2420 MCInst TmpInst;
2421 LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
2422
2423 EmitToStreamer(*OutStreamer, TmpInst);
2424}
2425
2426//===----------------------------------------------------------------------===//
2427// Target Registry Stuff
2428//===----------------------------------------------------------------------===//
2429
2430// Force static initialization.
2436}
unsigned SubReg
static void emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, MachineModuleInfoImpl::StubValueTy &MCSym)
static MCSymbolRefExpr::VariantKind getModifierVariantKind(ARMCP::ARMCPModifier Modifier)
static MCSymbol * getPICLabel(StringRef Prefix, unsigned FunctionNumber, unsigned LabelId, MCContext &Ctx)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMAsmPrinter()
static bool checkFunctionsAttributeConsistency(const Module &M, StringRef Attr, StringRef Value)
static bool isThumb(const MCSubtargetInfo &STI)
static MCSymbol * getBFLabel(StringRef Prefix, unsigned FunctionNumber, unsigned LabelId, MCContext &Ctx)
static bool checkDenormalAttributeConsistency(const Module &M, StringRef Attr, DenormalMode Value)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:128
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
std::string Name
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition: MD5.cpp:55
unsigned const TargetRegisterInfo * TRI
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:469
This file defines the SmallString class.
static const unsigned FramePtr
void emitJumpTableAddrs(const MachineInstr *MI)
void emitJumpTableTBInst(const MachineInstr *MI, unsigned OffsetWidth)
void emitFunctionBodyEnd() override
Targets can override this to emit stuff after the last basic block in the function.
bool runOnMachineFunction(MachineFunction &F) override
runOnMachineFunction - This uses the emitInstruction() method to print assembly for each instruction.
MCSymbol * GetCPISymbol(unsigned CPID) const override
Return the symbol for the specified constant pool entry.
void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O)
void emitStartOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the start of their fi...
ARMAsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer)
void emitFunctionEntryLabel() override
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, const MCSubtargetInfo *EndInfo) const override
Let the target do anything it needs to do after emitting inlineasm.
void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI)
void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override
EmitMachineConstantPoolValue - Print a machine constantpool value to the .s file.
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
void emitXXStructor(const DataLayout &DL, const Constant *CV) override
Targets can override this to change how global constants that are part of a C++ static/global constru...
void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI)
void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI)
void emitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
std::tuple< const MCSymbol *, uint64_t, const MCSymbol *, codeview::JumpTableEntrySize > getCodeViewJumpTableInfo(int JTI, const MachineInstr *BranchInstr, const MCSymbol *BranchLabel) const override
Gets information required to create a CodeView debug symbol for a jump table.
void emitJumpTableInsts(const MachineInstr *MI)
void emitGlobalVariable(const GlobalVariable *GV) override
Emit the specified global variable to the .s file.
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override
Print the MachineOperand as a symbol.
ARMConstantPoolValue - ARM specific constantpool value.
unsigned char getPCAdjustment() const
ARMCP::ARMCPModifier getModifier() const
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
SmallPtrSet< const GlobalVariable *, 2 > & getGlobalsPromotedToConstantPool()
DenseMap< unsigned, unsigned > EHPrologueRemappedRegs
DenseMap< unsigned, unsigned > EHPrologueOffsetInRegs
unsigned getOriginalCPIdx(unsigned CloneIdx) const
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=ARM::NoRegAltName)
static const ARMMCExpr * createLower16(const MCExpr *Expr, MCContext &Ctx)
Definition: ARMMCExpr.h:51
static const ARMMCExpr * createUpper16(const MCExpr *Expr, MCContext &Ctx)
Definition: ARMMCExpr.h:47
bool isTargetMachO() const
Definition: ARMSubtarget.h:349
bool isTargetAEABI() const
Definition: ARMSubtarget.h:358
bool isThumb1Only() const
Definition: ARMSubtarget.h:403
MCPhysReg getFramePointerReg() const
Definition: ARMSubtarget.h:413
bool isTargetWindows() const
Definition: ARMSubtarget.h:345
bool isTargetEHABICompatible() const
Definition: ARMSubtarget.h:379
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
bool isTargetDarwin() const
Definition: ARMSubtarget.h:337
bool isROPI() const
bool isTargetCOFF() const
Definition: ARMSubtarget.h:347
bool isTargetGNUAEABI() const
Definition: ARMSubtarget.h:363
bool isTargetMuslAEABI() const
Definition: ARMSubtarget.h:370
bool isTargetELF() const
Definition: ARMSubtarget.h:348
void emitTargetAttributes(const MCSubtargetInfo &STI)
Emit the build attributes that only depend on the hardware that we expect.
virtual void emitSetFP(MCRegister FpReg, MCRegister SpReg, int64_t Offset=0)
virtual void finishAttributeSection()
virtual void emitMovSP(MCRegister Reg, int64_t Offset=0)
virtual void emitARMWinCFISaveSP(unsigned Reg)
virtual void emitInst(uint32_t Inst, char Suffix='\0')
virtual void emitARMWinCFISaveLR(unsigned Offset)
virtual void emitTextAttribute(unsigned Attribute, StringRef String)
virtual void emitARMWinCFIAllocStack(unsigned Size, bool Wide)
virtual void emitARMWinCFISaveRegMask(unsigned Mask, bool Wide)
virtual void emitRegSave(const SmallVectorImpl< MCRegister > &RegList, bool isVector)
virtual void emitARMWinCFIEpilogEnd()
virtual void emitARMWinCFIPrologEnd(bool Fragment)
virtual void switchVendor(StringRef Vendor)
virtual void emitARMWinCFISaveFRegs(unsigned First, unsigned Last)
virtual void emitARMWinCFIEpilogStart(unsigned Condition)
virtual void emitPad(int64_t Offset)
virtual void emitAttribute(unsigned Attribute, unsigned Value)
virtual void emitARMWinCFINop(bool Wide)
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:87
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:408
MCSymbol * getSymbolWithGlobalValueBase(const GlobalValue *GV, StringRef Suffix) const
Return the MCSymbol for a private symbol with global value name as its base, with the specified suffi...
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:697
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:428
virtual void emitGlobalVariable(const GlobalVariable *GV)
Emit the specified global variable to the .s file.
Definition: AsmPrinter.cpp:719
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:90
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:93
MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:105
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:652
unsigned getFunctionNumber() const
Return a unique ID for the current function.
Definition: AsmPrinter.cpp:404
void printOffset(int64_t Offset, raw_ostream &OS) const
This is just convenient handler for printing offsets.
void emitGlobalConstant(const DataLayout &DL, const Constant *CV, AliasMapTy *AliasList=nullptr)
EmitGlobalConstant - Print a general LLVM constant to the .s file.
MCSymbol * getSymbolPreferLocal(const GlobalValue &GV) const
Similar to getSymbol() but preferred for references.
Definition: AsmPrinter.cpp:701
MCSymbol * CurrentFnSym
The symbol for the current function.
Definition: AsmPrinter.h:124
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
Definition: AsmPrinter.h:108
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:97
MCSymbol * GetExternalSymbolSymbol(Twine Sym) const
Return the MCSymbol for the specified ExternalSymbol.
bool isPositionIndependent() const
Definition: AsmPrinter.cpp:399
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:102
void getNameWithPrefix(SmallVectorImpl< char > &Name, const GlobalValue *GV) const
Definition: AsmPrinter.cpp:692
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
const DataLayout & getDataLayout() const
Return information about data layout.
Definition: AsmPrinter.cpp:412
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
Definition: AsmPrinter.cpp:423
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
The address of a basic block.
Definition: Constants.h:893
This is an important base class in LLVM.
Definition: Constant.h:42
const Constant * stripPointerCasts() const
Definition: Constant.h:218
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Definition: DataLayout.h:457
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: DenseMap.h:194
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
Definition: GlobalValue.h:264
bool hasInternalLinkage() const
Definition: GlobalValue.h:527
ExceptionHandling getExceptionHandlingType() const
Definition: MCAsmInfo.h:642
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:537
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:547
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:622
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:222
Context object for machine code objects.
Definition: MCContext.h:83
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:345
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:212
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
Definition: MCInstBuilder.h:37
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:43
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Definition: MCInstBuilder.h:61
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:185
void addOperand(const MCOperand Op)
Definition: MCInst.h:211
void setOpcode(unsigned Op)
Definition: MCInst.h:198
MCSection * getThreadLocalPointerSection() const
MCSection * getNonLazySymbolPointerSection() const
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:163
static MCOperand createReg(MCRegister Reg)
Definition: MCInst.h:135
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:142
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
Streaming machine code generation interface.
Definition: MCStreamer.h:215
virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
Add the given Attribute to Symbol.
MCContext & getContext() const
Definition: MCStreamer.h:308
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:179
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:420
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
Definition: MCStreamer.cpp:133
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:398
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:58
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
Target specific streamer interface.
Definition: MCStreamer.h:94
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
This class is a data container for one entry in a MachineConstantPool.
union llvm::MachineConstantPoolEntry::@205 Val
The constant itself.
bool isMachineConstantPoolEntry() const
isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry is indeed a target specific ...
MachineConstantPoolValue * MachineCPVal
Abstract base class for all machine specific constantpool value subclasses.
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
const std::vector< MachineConstantPoolEntry > & getConstants() const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const MachineBasicBlock & front() const
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Representation of each machine instruction.
Definition: MachineInstr.h:71
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:577
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:587
const std::vector< MachineJumpTableEntry > & getJumpTables() const
MachineModuleInfoCOFF - This is a MachineModuleInfoImpl implementation for COFF targets.
StubValueTy & getGVStubEntry(MCSymbol *Sym)
std::vector< std::pair< MCSymbol *, StubValueTy > > SymbolListTy
MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation for MachO targets.
StubValueTy & getGVStubEntry(MCSymbol *Sym)
StubValueTy & getThreadLocalGVStubEntry(MCSymbol *Sym)
SymbolListTy GetGVStubList()
Accessor methods to return the set of stubs in sorted order.
const Module * getModule() const
Ty & getObjFileInfo()
Keep track of various per-module pieces of information for backends that would like to do so.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
const GlobalValue * getGlobal() const
int64_t getImm() const
bool isImplicit() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
unsigned getTargetFlags() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
int64_t getOffset() const
Return the offset from the symbol in this operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
Definition: Pass.cpp:130
PointerIntPair - This class implements a pair of a pointer and small integer.
IntType getInt() const
PointerTy getPointer() const
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
bool empty() const
Definition: SmallVector.h:81
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:81
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
const Triple & getTargetTriple() const
StringRef getTargetFeatureString() const
StringRef getTargetCPU() const
TargetOptions Options
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
FloatABI::ABIType FloatABIType
FloatABIType - This setting is set by -float-abi=xxx option is specfied on the command line.
unsigned NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
unsigned HonorSignDependentRoundingFPMathOption
HonorSignDependentRoundingFPMath - This returns true when the -enable-sign-dependent-rounding-fp-math...
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
unsigned NoTrappingFPMath
NoTrappingFPMath - This flag is enabled when the -enable-no-trapping-fp-math is specified on the comm...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TypeSize getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
virtual Register getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:691
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SECREL
Thread Pointer Offset.
@ GOT_PREL
Thread Local Storage (General Dynamic Mode)
@ SBREL
Section Relative (Windows TLS)
@ GOTTPOFF
Global Offset Table, PC Relative.
@ TPOFF
Global Offset Table, Thread Pointer Offset.
@ MO_LO16
MO_LO16 - On a symbol operand, this represents a relocation containing lower 16 bit of the address.
Definition: ARMBaseInfo.h:250
@ MO_LO_0_7
MO_LO_0_7 - On a symbol operand, this represents a relocation containing bits 0 through 7 of the addr...
Definition: ARMBaseInfo.h:293
@ MO_LO_8_15
MO_LO_8_15 - On a symbol operand, this represents a relocation containing bits 8 through 15 of the ad...
Definition: ARMBaseInfo.h:299
@ MO_NONLAZY
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which,...
Definition: ARMBaseInfo.h:288
@ MO_HI_8_15
MO_HI_8_15 - On a symbol operand, this represents a relocation containing bits 24 through 31 of the a...
Definition: ARMBaseInfo.h:310
@ MO_HI16
MO_HI16 - On a symbol operand, this represents a relocation containing higher 16 bit of the address.
Definition: ARMBaseInfo.h:254
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand, this represents that the reference to the symbol is for an import...
Definition: ARMBaseInfo.h:275
@ MO_HI_0_7
MO_HI_0_7 - On a symbol operand, this represents a relocation containing bits 16 through 23 of the ad...
Definition: ARMBaseInfo.h:304
@ MO_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
Definition: ARMBaseInfo.h:263
std::string ParseARMTriple(const Triple &TT, StringRef CPU)
SymbolStorageClass
Storage class tells where and what the symbol represents.
Definition: COFF.h:217
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
Definition: COFF.h:223
@ IMAGE_SYM_CLASS_STATIC
Static.
Definition: COFF.h:224
@ IMAGE_SYM_DTYPE_FUNCTION
A function that returns a base type.
Definition: COFF.h:275
@ SCT_COMPLEX_TYPE_SHIFT
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
Definition: COFF.h:279
@ FS
Definition: X86.h:211
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
Target & getTheThumbBETarget()
@ MCDR_DataRegionEnd
.end_data_region
Definition: MCDirectives.h:66
@ MCDR_DataRegion
.data_region
Definition: MCDirectives.h:62
@ MCDR_DataRegionJT8
.data_region jt8
Definition: MCDirectives.h:63
@ MCDR_DataRegionJT32
.data_region jt32
Definition: MCDirectives.h:65
@ MCDR_DataRegionJT16
.data_region jt16
Definition: MCDirectives.h:64
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1746
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, ARMAsmPrinter &AP)
@ MCAF_SyntaxUnified
.syntax (ARM/ELF)
Definition: MCDirectives.h:54
@ MCAF_Code16
.code16 (X86) / .code 16 (ARM)
Definition: MCDirectives.h:56
@ MCAF_Code32
.code32 (X86) / .code 32 (ARM)
Definition: MCDirectives.h:57
@ MCAF_SubsectionsViaSymbols
.subsections_via_symbols (MachO)
Definition: MCDirectives.h:55
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1873
DenormalMode parseDenormalFPAttribute(StringRef Str)
Returns the denormal mode to use for inputs and outputs.
Target & getTheARMLETarget()
unsigned convertAddSubFlagsOpcode(unsigned OldOpc)
Map pseudo instructions that imply an 'S' bit onto real opcodes.
@ MCSA_IndirectSymbol
.indirect_symbol (MachO)
Definition: MCDirectives.h:35
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Definition: MCDirectives.h:23
Target & getTheARMBETarget()
Target & getTheThumbLETarget()
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Represent subnormal handling kind for floating point instruction inputs and outputs.
static constexpr DenormalMode getPositiveZero()
static constexpr DenormalMode getPreserveSign()
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...