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