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