LLVM 24.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), AFI(nullptr), MCP(nullptr),
55 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 =
83 OutContext.getOrCreateSymbol("__acle_se_" + CurrentFnSym->getName());
84 emitLinkage(&MF->getFunction(), 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
96 assert(GV && "C++ constructor pointer was not a GlobalValue!");
97
99 GetARMGVSymbol(GV, ARMII::MO_NO_FLAG),
100 (TM.getTargetTriple().isOSBinFormatELF() ? ARM::S_TARGET1 : ARM::S_None),
101 OutContext);
102
103 OutStreamer->emitValue(E, Size);
104}
105
106// An alias to a cmse entry function should also emit a `__acle_se_` symbol.
107void ARMAsmPrinter::emitCMSEVeneerAlias(const GlobalAlias &GA) {
109 if (!BaseFn || !BaseFn->hasFnAttribute("cmse_nonsecure_entry"))
110 return;
111
112 MCSymbol *AliasSym = getSymbol(&GA);
113 MCSymbol *FnSym = getSymbol(BaseFn);
114
115 MCSymbol *SEAliasSym =
116 OutContext.getOrCreateSymbol(Twine("__acle_se_") + AliasSym->getName());
117 MCSymbol *SEBaseSym =
118 OutContext.getOrCreateSymbol(Twine("__acle_se_") + FnSym->getName());
119
120 // Mirror alias linkage/visibility onto the veneer-alias symbol.
121 emitLinkage(&GA, SEAliasSym);
122 OutStreamer->emitSymbolAttribute(SEAliasSym, MCSA_ELF_TypeFunction);
123 emitVisibility(SEAliasSym, GA.getVisibility());
124
125 // emit "__acle_se_<alias> = __acle_se_<aliasee>"
126 const MCExpr *SEExpr = MCSymbolRefExpr::create(SEBaseSym, OutContext);
127 OutStreamer->emitAssignment(SEAliasSym, SEExpr);
128}
129
132 emitCMSEVeneerAlias(GA);
133}
134
136 if (PromotedGlobals.count(GV))
137 // The global was promoted into a constant pool. It should not be emitted.
138 return;
140}
141
142/// runOnMachineFunction - This uses the emitInstruction()
143/// method to print assembly for each instruction.
144///
146 AFI = MF.getInfo<ARMFunctionInfo>();
147 MCP = MF.getConstantPool();
148
150 const Function &F = MF.getFunction();
151 const TargetMachine& TM = MF.getTarget();
152
153 // Collect all globals that had their storage promoted to a constant pool.
154 // Functions are emitted before variables, so this accumulates promoted
155 // globals from all functions in PromotedGlobals.
156 PromotedGlobals.insert_range(AFI->getGlobalsPromotedToConstantPool());
157
158 // Calculate this function's optimization goal.
159 unsigned OptimizationGoal;
160 if (F.hasOptNone())
161 // For best debugging illusion, speed and small size sacrificed
162 OptimizationGoal = 6;
163 else if (F.hasMinSize())
164 // Aggressively for small size, speed and debug illusion sacrificed
165 OptimizationGoal = 4;
166 else if (F.hasOptSize())
167 // For small size, but speed and debugging illusion preserved
168 OptimizationGoal = 3;
169 else if (TM.getOptLevel() == CodeGenOptLevel::Aggressive)
170 // Aggressively for speed, small size and debug illusion sacrificed
171 OptimizationGoal = 2;
172 else if (TM.getOptLevel() > CodeGenOptLevel::None)
173 // For speed, but small size and good debug illusion preserved
174 OptimizationGoal = 1;
175 else // TM.getOptLevel() == CodeGenOptLevel::None
176 // For good debugging, but speed and small size preserved
177 OptimizationGoal = 5;
178
179 // Combine a new optimization goal with existing ones.
180 if (OptimizationGoals == -1) // uninitialized goals
181 OptimizationGoals = OptimizationGoal;
182 else if (OptimizationGoals != (int)OptimizationGoal) // conflicting goals
183 OptimizationGoals = 0;
184
185 if (TM.getTargetTriple().isOSBinFormatCOFF()) {
186 bool Local = F.hasLocalLinkage();
190
191 OutStreamer->beginCOFFSymbolDef(CurrentFnSym);
192 OutStreamer->emitCOFFSymbolStorageClass(Scl);
193 OutStreamer->emitCOFFSymbolType(Type);
194 OutStreamer->endCOFFSymbolDef();
195 }
196
197 // Emit the rest of the function body.
199
200 // Emit the XRay table for this function.
202
203 // If we need V4T thumb mode Register Indirect Jump pads, emit them.
204 // These are created per function, rather than per TU, since it's
205 // relatively easy to exceed the thumb branch range within a TU.
206 if (! ThumbIndirectPads.empty()) {
207 auto &TS =
208 static_cast<ARMTargetStreamer &>(*OutStreamer->getTargetStreamer());
209 TS.emitCode16();
211 for (std::pair<unsigned, MCSymbol *> &TIP : ThumbIndirectPads) {
212 OutStreamer->emitLabel(TIP.second);
214 .addReg(TIP.first)
215 // Add predicate operands.
217 .addReg(0));
218 }
219 ThumbIndirectPads.clear();
220 }
221
222 // We didn't modify anything.
223 return false;
224}
225
227 raw_ostream &O) {
228 assert(MO.isGlobal() && "caller should check MO.isGlobal");
229 unsigned TF = MO.getTargetFlags();
230 if (TF & ARMII::MO_LO16)
231 O << ":lower16:";
232 else if (TF & ARMII::MO_HI16)
233 O << ":upper16:";
234 else if (TF & ARMII::MO_LO_0_7)
235 O << ":lower0_7:";
236 else if (TF & ARMII::MO_LO_8_15)
237 O << ":lower8_15:";
238 else if (TF & ARMII::MO_HI_0_7)
239 O << ":upper0_7:";
240 else if (TF & ARMII::MO_HI_8_15)
241 O << ":upper8_15:";
242
243 GetARMGVSymbol(MO.getGlobal(), TF)->print(O, MAI);
244 printOffset(MO.getOffset(), O);
245}
246
248 raw_ostream &O) {
249 const MachineOperand &MO = MI->getOperand(OpNum);
250
251 switch (MO.getType()) {
252 default: llvm_unreachable("<unknown operand type>");
254 Register Reg = MO.getReg();
255 assert(Reg.isPhysical());
256 assert(!MO.getSubReg() && "Subregs should be eliminated!");
257 if(ARM::GPRPairRegClass.contains(Reg)) {
258 const MachineFunction &MF = *MI->getParent()->getParent();
259 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
260 Reg = TRI->getSubReg(Reg, ARM::gsub_0);
261 }
263 break;
264 }
266 O << '#';
267 unsigned TF = MO.getTargetFlags();
268 if (TF == ARMII::MO_LO16)
269 O << ":lower16:";
270 else if (TF == ARMII::MO_HI16)
271 O << ":upper16:";
272 else if (TF == ARMII::MO_LO_0_7)
273 O << ":lower0_7:";
274 else if (TF == ARMII::MO_LO_8_15)
275 O << ":lower8_15:";
276 else if (TF == ARMII::MO_HI_0_7)
277 O << ":upper0_7:";
278 else if (TF == ARMII::MO_HI_8_15)
279 O << ":upper8_15:";
280 O << MO.getImm();
281 break;
282 }
284 MO.getMBB()->getSymbol()->print(O, MAI);
285 return;
287 PrintSymbolOperand(MO, O);
288 break;
289 }
291 assert(!MF->getSubtarget<ARMSubtarget>().genExecuteOnly() &&
292 "execute-only should not generate constant pools");
293 GetCPISymbol(MO.getIndex())->print(O, MAI);
294 break;
295 }
296}
297
299 // The AsmPrinter::GetCPISymbol superclass method tries to use CPID as
300 // indexes in MachineConstantPool, which isn't in sync with indexes used here.
301 const DataLayout &DL = getDataLayout();
302 return OutContext.getOrCreateSymbol(Twine(DL.getInternalSymbolPrefix()) +
303 "CPI" + Twine(getFunctionNumber()) + "_" +
304 Twine(CPID));
305}
306
307//===--------------------------------------------------------------------===//
308
309MCSymbol *ARMAsmPrinter::
310GetARMJTIPICJumpTableLabel(unsigned uid) const {
311 const DataLayout &DL = getDataLayout();
312 SmallString<60> Name;
313 raw_svector_ostream(Name) << DL.getInternalSymbolPrefix() << "JTI"
314 << getFunctionNumber() << '_' << uid;
315 return OutContext.getOrCreateSymbol(Name);
316}
317
319 const char *ExtraCode, raw_ostream &O) {
320 // Does this asm operand have a single letter operand modifier?
321 if (ExtraCode && ExtraCode[0]) {
322 if (ExtraCode[1] != 0) return true; // Unknown modifier.
323
324 switch (ExtraCode[0]) {
325 default:
326 // See if this is a generic print operand
327 return AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O);
328 case 'P': // Print a VFP double precision register.
329 case 'q': // Print a NEON quad precision register.
330 printOperand(MI, OpNum, O);
331 return false;
332 case 'y': // Print a VFP single precision register as indexed double.
333 if (MI->getOperand(OpNum).isReg()) {
334 MCRegister Reg = MI->getOperand(OpNum).getReg().asMCReg();
335 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
336 // Find the 'd' register that has this 's' register as a sub-register,
337 // and determine the lane number.
338 for (MCPhysReg SR : TRI->superregs(Reg)) {
339 if (!ARM::DPRRegClass.contains(SR))
340 continue;
341 bool Lane0 = TRI->getSubReg(SR, ARM::ssub_0) == Reg;
342 O << ARMInstPrinter::getRegisterName(SR) << (Lane0 ? "[0]" : "[1]");
343 return false;
344 }
345 }
346 return true;
347 case 'B': // Bitwise inverse of integer or symbol without a preceding #.
348 if (!MI->getOperand(OpNum).isImm())
349 return true;
350 O << ~(MI->getOperand(OpNum).getImm());
351 return false;
352 case 'L': // The low 16 bits of an immediate constant.
353 if (!MI->getOperand(OpNum).isImm())
354 return true;
355 O << (MI->getOperand(OpNum).getImm() & 0xffff);
356 return false;
357 case 'M': { // A register range suitable for LDM/STM.
358 if (!MI->getOperand(OpNum).isReg())
359 return true;
360 const MachineOperand &MO = MI->getOperand(OpNum);
361 Register RegBegin = MO.getReg();
362 // This takes advantage of the 2 operand-ness of ldm/stm and that we've
363 // already got the operands in registers that are operands to the
364 // inline asm statement.
365 O << "{";
366 if (ARM::GPRPairRegClass.contains(RegBegin)) {
367 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
368 Register Reg0 = TRI->getSubReg(RegBegin, ARM::gsub_0);
369 O << ARMInstPrinter::getRegisterName(Reg0) << ", ";
370 RegBegin = TRI->getSubReg(RegBegin, ARM::gsub_1);
371 }
372 O << ARMInstPrinter::getRegisterName(RegBegin);
373
374 // FIXME: The register allocator not only may not have given us the
375 // registers in sequence, but may not be in ascending registers. This
376 // will require changes in the register allocator that'll need to be
377 // propagated down here if the operands change.
378 unsigned RegOps = OpNum + 1;
379 while (MI->getOperand(RegOps).isReg()) {
380 O << ", "
381 << ARMInstPrinter::getRegisterName(MI->getOperand(RegOps).getReg());
382 RegOps++;
383 }
384
385 O << "}";
386
387 return false;
388 }
389 case 'R': // The most significant register of a pair.
390 case 'Q': { // The least significant register of a pair.
391 if (OpNum == 0)
392 return true;
393 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
394 if (!FlagsOP.isImm())
395 return true;
396 InlineAsm::Flag F(FlagsOP.getImm());
397
398 // This operand may not be the one that actually provides the register. If
399 // it's tied to a previous one then we should refer instead to that one
400 // for registers and their classes.
401 unsigned TiedIdx;
402 if (F.isUseOperandTiedToDef(TiedIdx)) {
403 for (OpNum = InlineAsm::MIOp_FirstOperand; TiedIdx; --TiedIdx) {
404 unsigned OpFlags = MI->getOperand(OpNum).getImm();
405 const InlineAsm::Flag F(OpFlags);
406 OpNum += F.getNumOperandRegisters() + 1;
407 }
408 F = InlineAsm::Flag(MI->getOperand(OpNum).getImm());
409
410 // Later code expects OpNum to be pointing at the register rather than
411 // the flags.
412 OpNum += 1;
413 }
414
415 const unsigned NumVals = F.getNumOperandRegisters();
416 unsigned RC;
417 bool FirstHalf;
418 const ARMBaseTargetMachine &ATM =
419 static_cast<const ARMBaseTargetMachine &>(TM);
420
421 // 'Q' should correspond to the low order register and 'R' to the high
422 // order register. Whether this corresponds to the upper or lower half
423 // depends on the endianness mode.
424 if (ExtraCode[0] == 'Q')
425 FirstHalf = ATM.isLittleEndian();
426 else
427 // ExtraCode[0] == 'R'.
428 FirstHalf = !ATM.isLittleEndian();
429 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
430 if (F.hasRegClassConstraint(RC) &&
431 ARM::GPRPairRegClass.hasSubClassEq(TRI->getRegClass(RC))) {
432 if (NumVals != 1)
433 return true;
434 const MachineOperand &MO = MI->getOperand(OpNum);
435 if (!MO.isReg())
436 return true;
437 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
438 Register Reg =
439 TRI->getSubReg(MO.getReg(), FirstHalf ? ARM::gsub_0 : ARM::gsub_1);
441 return false;
442 }
443 if (NumVals != 2)
444 return true;
445 unsigned RegOp = FirstHalf ? OpNum : OpNum + 1;
446 if (RegOp >= MI->getNumOperands())
447 return true;
448 const MachineOperand &MO = MI->getOperand(RegOp);
449 if (!MO.isReg())
450 return true;
451 Register Reg = MO.getReg();
453 return false;
454 }
455
456 case 'e': // The low doubleword register of a NEON quad register.
457 case 'f': { // The high doubleword register of a NEON quad register.
458 if (!MI->getOperand(OpNum).isReg())
459 return true;
460 Register Reg = MI->getOperand(OpNum).getReg();
461 if (!ARM::QPRRegClass.contains(Reg))
462 return true;
463 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
464 Register SubReg =
465 TRI->getSubReg(Reg, ExtraCode[0] == 'e' ? ARM::dsub_0 : ARM::dsub_1);
467 return false;
468 }
469
470 // This modifier is not yet supported.
471 case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1.
472 return true;
473 case 'H': { // The highest-numbered register of a pair.
474 const MachineOperand &MO = MI->getOperand(OpNum);
475 if (!MO.isReg())
476 return true;
477 const MachineFunction &MF = *MI->getParent()->getParent();
478 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
479 Register Reg = MO.getReg();
480 if(!ARM::GPRPairRegClass.contains(Reg))
481 return false;
482 Reg = TRI->getSubReg(Reg, ARM::gsub_1);
484 return false;
485 }
486 }
487 }
488
489 printOperand(MI, OpNum, O);
490 return false;
491}
492
494 unsigned OpNum, const char *ExtraCode,
495 raw_ostream &O) {
496 // Does this asm operand have a single letter operand modifier?
497 if (ExtraCode && ExtraCode[0]) {
498 if (ExtraCode[1] != 0) return true; // Unknown modifier.
499
500 switch (ExtraCode[0]) {
501 case 'A': // A memory operand for a VLD1/VST1 instruction.
502 default: return true; // Unknown modifier.
503 case 'm': // The base register of a memory operand.
504 if (!MI->getOperand(OpNum).isReg())
505 return true;
506 O << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg());
507 return false;
508 }
509 }
510
511 const MachineOperand &MO = MI->getOperand(OpNum);
512 assert(MO.isReg() && "unexpected inline asm memory operand");
513 O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
514 return false;
515}
516
517static bool isThumb(const MCSubtargetInfo& STI) {
518 return STI.hasFeature(ARM::ModeThumb);
519}
520
522 const MCSubtargetInfo *EndInfo,
523 const MachineInstr *MI) {
524 // If either end mode is unknown (EndInfo == NULL) or different than
525 // the start mode, then restore the start mode.
526 const bool WasThumb = isThumb(StartInfo);
527 if (!EndInfo || WasThumb != isThumb(*EndInfo)) {
528 auto &TS =
529 static_cast<ARMTargetStreamer &>(*OutStreamer->getTargetStreamer());
530 if (WasThumb)
531 TS.emitCode16();
532 else
533 TS.emitCode32();
534 }
535}
536
538 const Triple &TT = TM.getTargetTriple();
539 auto &TS =
540 static_cast<ARMTargetStreamer &>(*OutStreamer->getTargetStreamer());
541 // Use unified assembler syntax.
543
544 // Emit ARM Build Attributes
545 if (TT.isOSBinFormatELF())
546 emitAttributes();
547
548 // Use the triple's architecture and subarchitecture to determine
549 // if we're thumb for the purposes of the top level code16 state.
550 if (!M.getModuleInlineAsm().empty() && TT.isThumb())
551 TS.emitCode16();
552}
553
554static void
557 // L_foo$stub:
558 OutStreamer.emitLabel(StubLabel);
559 // .indirect_symbol _foo
561
562 if (MCSym.getInt())
563 // External to current translation unit.
564 OutStreamer.emitIntValue(0, 4/*size*/);
565 else
566 // Internal to current translation unit.
567 //
568 // When we place the LSDA into the TEXT section, the type info
569 // pointers need to be indirect and pc-rel. We accomplish this by
570 // using NLPs; however, sometimes the types are local to the file.
571 // We need to fill in the value for the NLP in those cases.
572 OutStreamer.emitValue(
573 MCSymbolRefExpr::create(MCSym.getPointer(), OutStreamer.getContext()),
574 4 /*size*/);
575}
576
577
579 const Triple &TT = TM.getTargetTriple();
580 if (TT.isOSBinFormatMachO()) {
581 // All darwin targets use mach-o.
582 const TargetLoweringObjectFileMachO &TLOFMacho =
584 MachineModuleInfoMachO &MMIMacho =
585 MMI->getObjFileInfo<MachineModuleInfoMachO>();
586
587 // Output non-lazy-pointers for external and common global variables.
589
590 if (!Stubs.empty()) {
591 // Switch with ".non_lazy_symbol_pointer" directive.
592 OutStreamer->switchSection(TLOFMacho.getNonLazySymbolPointerSection());
594
595 for (auto &Stub : Stubs)
596 emitNonLazySymbolPointer(*OutStreamer, Stub.first, Stub.second);
597
598 Stubs.clear();
599 OutStreamer->addBlankLine();
600 }
601
602 Stubs = MMIMacho.GetThreadLocalGVStubList();
603 if (!Stubs.empty()) {
604 // Switch with ".non_lazy_symbol_pointer" directive.
605 OutStreamer->switchSection(TLOFMacho.getThreadLocalPointerSection());
607
608 for (auto &Stub : Stubs)
609 emitNonLazySymbolPointer(*OutStreamer, Stub.first, Stub.second);
610
611 Stubs.clear();
612 OutStreamer->addBlankLine();
613 }
614
615 // Funny Darwin hack: This flag tells the linker that no global symbols
616 // contain code that falls through to other global symbols (e.g. the obvious
617 // implementation of multiple entry points). If this doesn't occur, the
618 // linker can safely perform dead code stripping. Since LLVM never
619 // generates code that does this, it is always safe to set.
620 OutStreamer->emitSubsectionsViaSymbols();
621 }
622
623 // The last attribute to be emitted is ABI_optimization_goals
624 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
625 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
626
627 if (OptimizationGoals > 0 &&
628 (TT.isTargetAEABI() || TT.isTargetGNUAEABI() || TT.isTargetMuslAEABI()))
630 OptimizationGoals = -1;
631
633}
634
635//===----------------------------------------------------------------------===//
636// Helper routines for emitStartOfAsmFile() and emitEndOfAsmFile()
637// FIXME:
638// The following seem like one-off assembler flags, but they actually need
639// to appear in the .ARM.attributes section in ELF.
640// Instead of subclassing the MCELFStreamer, we do the work here.
641
642// Returns true if all function definitions have the same function attribute
643// value. It also returns true when the module has no functions.
646 return !any_of(M, [&](const Function &F) {
647 if (F.isDeclaration())
648 return false;
649 return F.getFnAttribute(Attr).getValueAsString() != Value;
650 });
651}
652// Returns true if all functions definitions have the same denormal mode.
653// It also returns true when the module has no functions.
656 return !any_of(M, [&](const Function &F) {
657 if (F.isDeclaration())
658 return false;
659 return F.getDenormalFPEnv() != Value;
660 });
661}
662
663// Returns true if all functions have different denormal modes.
665 auto F = M.functions().begin();
666 auto E = M.functions().end();
667 if (F == E)
668 return false;
669 DenormalFPEnv Value = F->getDenormalFPEnv();
670 ++F;
671 return std::any_of(F, E, [&](const Function &F) {
672 return !F.isDeclaration() && F.getDenormalFPEnv() != Value;
673 });
674}
675
676void ARMAsmPrinter::emitAttributes() {
677 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
678 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
679
681
682 ATS.switchVendor("aeabi");
683
684 // Compute ARM ELF Attributes based on the default subtarget that
685 // we'd have constructed. The existing ARM behavior isn't LTO clean
686 // anyhow.
687 // FIXME: For ifunc related functions we could iterate over and look
688 // for a feature string that doesn't match the default one.
689 const Triple &TT = TM.getTargetTriple();
690 StringRef CPU = TM.getTargetCPU();
691 StringRef FS = TM.getTargetFeatureString();
692 std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
693 if (!FS.empty()) {
694 if (!ArchFS.empty())
695 ArchFS = (Twine(ArchFS) + "," + FS).str();
696 else
697 ArchFS = std::string(FS);
698 }
699 const ARMBaseTargetMachine &ATM =
700 static_cast<const ARMBaseTargetMachine &>(TM);
701 const ARMSubtarget STI(TT, std::string(CPU), ArchFS, ATM,
703
704 // Emit build attributes for the available hardware.
705 ATS.emitTargetAttributes(STI);
706
707 // RW data addressing.
708 if (isPositionIndependent()) {
711 } else if (STI.isRWPI()) {
712 // RWPI specific attributes.
715 }
716
717 // RO data addressing.
718 if (isPositionIndependent() || STI.isROPI()) {
721 }
722
723 // GOT use.
724 if (isPositionIndependent()) {
727 } else {
730 }
731
732 // Set FP Denormals.
734 MMI->getModule()->getModuleFlag("arm-eabi-fp-denormal"))) {
735 if (unsigned TagVal = DM->getZExtValue())
737 } else if (checkDenormalAttributeConsistency(*MMI->getModule(),
741 else if (checkDenormalAttributeConsistency(*MMI->getModule(),
745 else if (checkDenormalAttributeInconsistency(*MMI->getModule()) ||
750 else {
751 if (!STI.hasVFP2Base()) {
752 // When the target doesn't have an FPU (by design or
753 // intention), the assumptions made on the software support
754 // mirror that of the equivalent hardware support *if it
755 // existed*. For v7 and better we indicate that denormals are
756 // flushed preserving sign, and for V6 we indicate that
757 // denormals are flushed to positive zero.
758 if (STI.hasV7Ops())
761 } else if (STI.hasVFP3Base()) {
762 // In VFPv4, VFPv4U, VFPv3, or VFPv3U, it is preserved. That is,
763 // the sign bit of the zero matches the sign bit of the input or
764 // result that is being flushed to zero.
767 }
768 // For VFPv2 implementations it is implementation defined as
769 // to whether denormals are flushed to positive zero or to
770 // whatever the sign of zero is (ARM v7AR ARM 2.7.5). Historically
771 // LLVM has chosen to flush this to positive zero (most likely for
772 // GCC compatibility), so that's the chosen value here (the
773 // absence of its emission implies zero).
774 }
775
776 // Set FP exceptions and rounding
778 MMI->getModule()->getModuleFlag("arm-eabi-fp-exceptions"))) {
779 if (unsigned TagVal = Ex->getZExtValue())
781 } else if (checkFunctionsAttributeConsistency(*MMI->getModule(),
782 "no-trapping-math", "true") ||
783 TM.Options.NoTrappingFPMath)
786 else {
788
789 // If the user has permitted this code to choose the IEEE 754
790 // rounding at run-time, emit the rounding attribute.
791 if (TM.Options.HonorSignDependentRoundingFPMathOption)
793 }
794
795 // Generate ABI tags from module flags.
796 if (auto *NumModel = mdconst::extract_or_null<ConstantInt>(
797 MMI->getModule()->getModuleFlag("arm-eabi-fp-number-model"))) {
798 if (unsigned TagVal = NumModel->getZExtValue())
800 } else
803
804 // FIXME: add more flags to ARMBuildAttributes.h
805 // 8-bytes alignment stuff.
808
809 // Hard float. Use both S and D registers and conform to AAPCS-VFP.
810 if (getTM().isAAPCS_ABI() && STI.isTargetHardFloat())
812
813 // FIXME: To support emitting this build attribute as GCC does, the
814 // -mfp16-format option and associated plumbing must be
815 // supported. For now the __fp16 type is exposed by default, so this
816 // attribute should be emitted with value 1.
819
820 if (const Module *SourceModule = MMI->getModule()) {
821 // ABI_PCS_wchar_t to indicate wchar_t width
822 // FIXME: There is no way to emit value 0 (wchar_t prohibited).
823 int WCharWidth = TM.getTargetTriple().getDefaultWCharSize();
824 if (auto WCharWidthValue = mdconst::extract_or_null<ConstantInt>(
825 SourceModule->getModuleFlag("wchar_size")))
826 WCharWidth = WCharWidthValue->getZExtValue();
827 assert((WCharWidth == 2 || WCharWidth == 4) &&
828 "wchar_t width must be 2 or 4 bytes");
830
831 // ABI_enum_size to indicate enum width
832 // FIXME: There is no way to emit value 0 (enums prohibited) or value 3
833 // (all enums contain a value needing 32 bits to encode).
834 if (auto EnumWidthValue = mdconst::extract_or_null<ConstantInt>(
835 SourceModule->getModuleFlag("min_enum_size"))) {
836 int EnumWidth = EnumWidthValue->getZExtValue();
837 assert((EnumWidth == 1 || EnumWidth == 4) &&
838 "Minimum enum width must be 1 or 4 bytes");
839 int EnumBuildAttr = EnumWidth == 1 ? 1 : 2;
841 }
842
844 SourceModule->getModuleFlag("sign-return-address"));
845 if (PACValue && PACValue->isOne()) {
846 // If "+pacbti" is used as an architecture extension,
847 // Tag_PAC_extension is emitted in
848 // ARMTargetStreamer::emitTargetAttributes().
849 if (!STI.hasPACBTI()) {
852 }
854 }
855
857 SourceModule->getModuleFlag("branch-target-enforcement"));
858 if (BTIValue && !BTIValue->isZero()) {
859 // If "+pacbti" is used as an architecture extension,
860 // Tag_BTI_extension is emitted in
861 // ARMTargetStreamer::emitTargetAttributes().
862 if (!STI.hasPACBTI()) {
865 }
867 }
868 }
869
870 // We currently do not support using R9 as the TLS pointer.
871 if (STI.isRWPI())
874 else if (STI.isR9Reserved())
877 else
880}
881
882//===----------------------------------------------------------------------===//
883
884static MCSymbol *getBFLabel(StringRef Prefix, unsigned FunctionNumber,
885 unsigned LabelId, MCContext &Ctx) {
886
887 MCSymbol *Label = Ctx.getOrCreateSymbol(Twine(Prefix)
888 + "BF" + Twine(FunctionNumber) + "_" + Twine(LabelId));
889 return Label;
890}
891
892static MCSymbol *getPICLabel(StringRef Prefix, unsigned FunctionNumber,
893 unsigned LabelId, MCContext &Ctx) {
894
895 MCSymbol *Label = Ctx.getOrCreateSymbol(Twine(Prefix)
896 + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
897 return Label;
898}
899
901 switch (Modifier) {
903 return ARM::S_None;
904 case ARMCP::TLSGD:
905 return ARM::S_TLSGD;
906 case ARMCP::TPOFF:
907 return ARM::S_TPOFF;
908 case ARMCP::GOTTPOFF:
909 return ARM::S_GOTTPOFF;
910 case ARMCP::SBREL:
911 return ARM::S_SBREL;
912 case ARMCP::GOT_PREL:
913 return ARM::S_GOT_PREL;
914 case ARMCP::SECREL:
915 return ARM::S_COFF_SECREL;
916 }
917 llvm_unreachable("Invalid ARMCPModifier!");
918}
919
920MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV,
921 unsigned char TargetFlags) {
922 const Triple &TT = TM.getTargetTriple();
923 if (TT.isOSBinFormatMachO()) {
924 bool IsIndirect =
925 (TargetFlags & ARMII::MO_NONLAZY) && getTM().isGVIndirectSymbol(GV);
926
927 if (!IsIndirect)
928 return getSymbol(GV);
929
930 // FIXME: Remove this when Darwin transition to @GOT like syntax.
931 MCSymbol *MCSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
932 MachineModuleInfoMachO &MMIMachO =
933 MMI->getObjFileInfo<MachineModuleInfoMachO>();
935 GV->isThreadLocal() ? MMIMachO.getThreadLocalGVStubEntry(MCSym)
936 : MMIMachO.getGVStubEntry(MCSym);
937
938 if (!StubSym.getPointer())
940 !GV->hasInternalLinkage());
941 return MCSym;
942 } else if (TT.isOSBinFormatCOFF()) {
943 assert(TT.isOSWindows() && "Windows is the only supported COFF target");
944
945 bool IsIndirect =
946 (TargetFlags & (ARMII::MO_DLLIMPORT | ARMII::MO_COFFSTUB));
947 if (!IsIndirect)
948 return getSymbol(GV);
949
950 SmallString<128> Name;
951 if (TargetFlags & ARMII::MO_DLLIMPORT)
952 Name = "__imp_";
953 else if (TargetFlags & ARMII::MO_COFFSTUB)
954 Name = ".refptr.";
955 getNameWithPrefix(Name, GV);
956
957 MCSymbol *MCSym = OutContext.getOrCreateSymbol(Name);
958
959 if (TargetFlags & ARMII::MO_COFFSTUB) {
960 MachineModuleInfoCOFF &MMICOFF =
961 MMI->getObjFileInfo<MachineModuleInfoCOFF>();
963 MMICOFF.getGVStubEntry(MCSym);
964
965 if (!StubSym.getPointer())
967 }
968
969 return MCSym;
970 } else if (TT.isOSBinFormatELF()) {
971 return getSymbolPreferLocal(*GV);
972 }
973 llvm_unreachable("unexpected target");
974}
975
978 const DataLayout &DL = getDataLayout();
979 int Size = DL.getTypeAllocSize(MCPV->getType());
980
981 ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
982
983 if (ACPV->isPromotedGlobal()) {
984 // This constant pool entry is actually a global whose storage has been
985 // promoted into the constant pool. This global may be referenced still
986 // by debug information, and due to the way AsmPrinter is set up, the debug
987 // info is immutable by the time we decide to promote globals to constant
988 // pools. Because of this, we need to ensure we emit a symbol for the global
989 // with private linkage (the default) so debug info can refer to it.
990 //
991 // However, if this global is promoted into several functions we must ensure
992 // we don't try and emit duplicate symbols!
993 auto *ACPC = cast<ARMConstantPoolConstant>(ACPV);
994 for (const auto *GV : ACPC->promotedGlobals()) {
995 if (!EmittedPromotedGlobalLabels.count(GV)) {
996 MCSymbol *GVSym = getSymbol(GV);
997 OutStreamer->emitLabel(GVSym);
998 EmittedPromotedGlobalLabels.insert(GV);
999 }
1000 }
1001 return emitGlobalConstant(DL, ACPC->getPromotedGlobalInit());
1002 }
1003
1004 MCSymbol *MCSym;
1005 if (ACPV->isLSDA()) {
1006 MCSym = getMBBExceptionSym(MF->front());
1007 } else if (ACPV->isBlockAddress()) {
1008 const BlockAddress *BA =
1009 cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress();
1010 MCSym = GetBlockAddressSymbol(BA);
1011 } else if (ACPV->isGlobalValue()) {
1012 const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV();
1013
1014 // On Darwin, const-pool entries may get the "FOO$non_lazy_ptr" mangling, so
1015 // flag the global as MO_NONLAZY.
1016 unsigned char TF =
1017 TM.getTargetTriple().isOSBinFormatMachO() ? ARMII::MO_NONLAZY : 0;
1018 MCSym = GetARMGVSymbol(GV, TF);
1019
1020 // For dso_local weak symbols in ELF PIC mode, the assembler would eagerly
1021 // resolve a PC-relative expression like sym-(LPC+8) when the symbol and
1022 // reference are in the same section, preventing the linker from overriding
1023 // a weak definition with a non-weak definition from another section. Use a
1024 // .reloc directive rather than a fixup to force the generation of a
1025 // relocation (R_ARM_REL32) so the linker can perform the override. This is
1026 // restricted to dso_local, non-TLS symbols: a preemptible/external weak
1027 // symbol (e.g. an extern_weak reference) must use the GOT, as R_ARM_REL32
1028 // against an external symbol cannot be used when making a shared object;
1029 // and TLS symbols require TLS-specific relocations, not R_ARM_REL32.
1030 if (GV->isWeakForLinker() && GV->isDSOLocal() && !GV->isThreadLocal() &&
1031 TM.getTargetTriple().isOSBinFormatELF() && TM.isPositionIndependent() &&
1032 ACPV->getPCAdjustment() != 0) {
1033 MCSymbol *CPILabel = OutContext.createTempSymbol();
1034 OutStreamer->emitLabel(CPILabel);
1035 // Emit local-only expression: CPILabel - (LPC+PCAdj)
1036 const MCExpr *LocalExpr = MCSymbolRefExpr::create(CPILabel, OutContext);
1037 MCSymbol *PCLabel =
1038 getPICLabel(DL.getInternalSymbolPrefix(), getFunctionNumber(),
1039 ACPV->getLabelId(), OutContext);
1040 const MCExpr *PCRelExpr = MCSymbolRefExpr::create(PCLabel, OutContext);
1041 PCRelExpr = MCBinaryExpr::createAdd(
1042 PCRelExpr,
1044 OutContext);
1045 LocalExpr = MCBinaryExpr::createSub(LocalExpr, PCRelExpr, OutContext);
1046 OutStreamer->emitValue(LocalExpr, Size);
1047 // Emit .reloc to force linker resolution of the weak symbol.
1048 const MCExpr *CPIExpr = MCSymbolRefExpr::create(CPILabel, OutContext);
1049 const MCExpr *SymExpr = MCSymbolRefExpr::create(MCSym, OutContext);
1050 OutStreamer->emitRelocDirective(*CPIExpr, "R_ARM_REL32", SymExpr,
1051 SMLoc());
1052 return;
1053 }
1054 } else if (ACPV->isMachineBasicBlock()) {
1055 const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB();
1056 MCSym = MBB->getSymbol();
1057 } else {
1058 assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
1059 auto Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol();
1060 MCSym = GetExternalSymbolSymbol(Sym);
1061 }
1062
1063 // Create an MCSymbol for the reference.
1064 const MCExpr *Expr = MCSymbolRefExpr::create(
1066
1067 if (ACPV->getPCAdjustment()) {
1068 MCSymbol *PCLabel =
1069 getPICLabel(DL.getInternalSymbolPrefix(), getFunctionNumber(),
1070 ACPV->getLabelId(), OutContext);
1071 const MCExpr *PCRelExpr = MCSymbolRefExpr::create(PCLabel, OutContext);
1072 PCRelExpr =
1073 MCBinaryExpr::createAdd(PCRelExpr,
1075 OutContext),
1076 OutContext);
1077 if (ACPV->mustAddCurrentAddress()) {
1078 // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
1079 // label, so just emit a local label end reference that instead.
1080 MCSymbol *DotSym = OutContext.createTempSymbol();
1081 OutStreamer->emitLabel(DotSym);
1082 const MCExpr *DotExpr = MCSymbolRefExpr::create(DotSym, OutContext);
1083 PCRelExpr = MCBinaryExpr::createSub(PCRelExpr, DotExpr, OutContext);
1084 }
1085 Expr = MCBinaryExpr::createSub(Expr, PCRelExpr, OutContext);
1086 }
1087 OutStreamer->emitValue(Expr, Size);
1088}
1089
1091 const MachineOperand &MO1 = MI->getOperand(1);
1092 unsigned JTI = MO1.getIndex();
1093
1094 // Make sure the Thumb jump table is 4-byte aligned. This will be a nop for
1095 // ARM mode tables.
1096 emitAlignment(Align(4));
1097
1098 // Emit a label for the jump table.
1099 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);
1100 OutStreamer->emitLabel(JTISymbol);
1101
1102 // Mark the jump table as data-in-code.
1103 OutStreamer->emitDataRegion(MCDR_DataRegionJT32);
1104
1105 // Emit each entry of the table.
1106 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1107 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1108 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1109
1110 for (MachineBasicBlock *MBB : JTBBs) {
1111 // Construct an MCExpr for the entry. We want a value of the form:
1112 // (BasicBlockAddr - TableBeginAddr)
1113 //
1114 // For example, a table with entries jumping to basic blocks BB0 and BB1
1115 // would look like:
1116 // LJTI_0_0:
1117 // .word (LBB0 - LJTI_0_0)
1118 // .word (LBB1 - LJTI_0_0)
1119 const MCExpr *Expr = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext);
1120
1121 const ARMSubtarget &STI = MF->getSubtarget<ARMSubtarget>();
1122 if (isPositionIndependent() || STI.isROPI())
1123 Expr = MCBinaryExpr::createSub(Expr, MCSymbolRefExpr::create(JTISymbol,
1124 OutContext),
1125 OutContext);
1126 // If we're generating a table of Thumb addresses in static relocation
1127 // model, we need to add one to keep interworking correctly.
1128 else if (AFI->isThumbFunction())
1130 OutContext);
1131 OutStreamer->emitValue(Expr, 4);
1132 }
1133 // Mark the end of jump table data-in-code region.
1134 OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
1135}
1136
1138 const MachineOperand &MO1 = MI->getOperand(1);
1139 unsigned JTI = MO1.getIndex();
1140
1141 // Make sure the Thumb jump table is 4-byte aligned. This will be a nop for
1142 // ARM mode tables.
1143 emitAlignment(Align(4));
1144
1145 // Emit a label for the jump table.
1146 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);
1147 OutStreamer->emitLabel(JTISymbol);
1148
1149 // Emit each entry of the table.
1150 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1151 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1152 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1153
1154 for (MachineBasicBlock *MBB : JTBBs) {
1155 const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::create(MBB->getSymbol(),
1156 OutContext);
1157 // If this isn't a TBB or TBH, the entries are direct branch instructions.
1159 .addExpr(MBBSymbolExpr)
1160 .addImm(ARMCC::AL)
1161 .addReg(0));
1162 }
1163}
1164
1166 unsigned OffsetWidth) {
1167 assert((OffsetWidth == 1 || OffsetWidth == 2) && "invalid tbb/tbh width");
1168 const MachineOperand &MO1 = MI->getOperand(1);
1169 unsigned JTI = MO1.getIndex();
1170
1171 const ARMSubtarget &STI = MF->getSubtarget<ARMSubtarget>();
1172 if (STI.isThumb1Only())
1173 emitAlignment(Align(4));
1174
1175 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);
1176 OutStreamer->emitLabel(JTISymbol);
1177
1178 // Emit each entry of the table.
1179 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1180 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1181 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1182
1183 // Mark the jump table as data-in-code.
1184 OutStreamer->emitDataRegion(OffsetWidth == 1 ? MCDR_DataRegionJT8
1186
1187 for (auto *MBB : JTBBs) {
1188 const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::create(MBB->getSymbol(),
1189 OutContext);
1190 // Otherwise it's an offset from the dispatch instruction. Construct an
1191 // MCExpr for the entry. We want a value of the form:
1192 // (BasicBlockAddr - TBBInstAddr + 4) / 2
1193 //
1194 // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
1195 // would look like:
1196 // LJTI_0_0:
1197 // .byte (LBB0 - (LCPI0_0 + 4)) / 2
1198 // .byte (LBB1 - (LCPI0_0 + 4)) / 2
1199 // where LCPI0_0 is a label defined just before the TBB instruction using
1200 // this table.
1201 MCSymbol *TBInstPC = GetCPISymbol(MI->getOperand(0).getImm());
1202 const MCExpr *Expr = MCBinaryExpr::createAdd(
1205 Expr = MCBinaryExpr::createSub(MBBSymbolExpr, Expr, OutContext);
1207 OutContext);
1208 OutStreamer->emitValue(Expr, OffsetWidth);
1209 }
1210 // Mark the end of jump table data-in-code region. 32-bit offsets use
1211 // actual branch instructions here, so we don't mark those as a data-region
1212 // at all.
1213 OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
1214
1215 // Make sure the next instruction is 2-byte aligned.
1216 emitAlignment(Align(2));
1217}
1218
1219std::tuple<const MCSymbol *, uint64_t, const MCSymbol *,
1222 const MachineInstr *BranchInstr,
1223 const MCSymbol *BranchLabel) const {
1225 const MCSymbol *BaseLabel;
1226 uint64_t BaseOffset = 0;
1227 switch (BranchInstr->getOpcode()) {
1228 case ARM::BR_JTadd:
1229 case ARM::BR_JTr:
1230 case ARM::tBR_JTr:
1231 // Word relative to the jump table address.
1233 BaseLabel = GetARMJTIPICJumpTableLabel(JTI);
1234 break;
1235 case ARM::tTBH_JT:
1236 case ARM::t2TBH_JT:
1237 // half-word shifted left, relative to *after* the branch instruction.
1239 BranchLabel = GetCPISymbol(BranchInstr->getOperand(3).getImm());
1240 BaseLabel = BranchLabel;
1241 BaseOffset = 4;
1242 break;
1243 case ARM::tTBB_JT:
1244 case ARM::t2TBB_JT:
1245 // byte shifted left, relative to *after* the branch instruction.
1247 BranchLabel = GetCPISymbol(BranchInstr->getOperand(3).getImm());
1248 BaseLabel = BranchLabel;
1249 BaseOffset = 4;
1250 break;
1251 case ARM::t2BR_JT:
1252 // Direct jump.
1253 BaseLabel = nullptr;
1255 break;
1256 default:
1257 llvm_unreachable("Unknown jump table instruction");
1258 }
1259
1260 return std::make_tuple(BaseLabel, BaseOffset, BranchLabel, EntrySize);
1261}
1262
1263void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
1265 "Only instruction which are involved into frame setup code are allowed");
1266
1267 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
1268 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1269 const MachineFunction &MF = *MI->getParent()->getParent();
1270 const TargetRegisterInfo *TargetRegInfo =
1272 const MachineRegisterInfo &MachineRegInfo = MF.getRegInfo();
1273
1274 Register FramePtr = TargetRegInfo->getFrameRegister(MF);
1275 unsigned Opc = MI->getOpcode();
1276 unsigned SrcReg, DstReg;
1277
1278 switch (Opc) {
1279 case ARM::tPUSH:
1280 // special case: tPUSH does not have src/dst regs.
1281 SrcReg = DstReg = ARM::SP;
1282 break;
1283 case ARM::tLDRpci:
1284 case ARM::t2MOVi16:
1285 case ARM::t2MOVTi16:
1286 case ARM::tMOVi8:
1287 case ARM::tADDi8:
1288 case ARM::tLSLri:
1289 // special cases:
1290 // 1) for Thumb1 code we sometimes materialize the constant via constpool
1291 // load.
1292 // 2) for Thumb1 execute only code we materialize the constant via the
1293 // following pattern:
1294 // movs r3, #:upper8_15:<const>
1295 // lsls r3, #8
1296 // adds r3, #:upper0_7:<const>
1297 // lsls r3, #8
1298 // adds r3, #:lower8_15:<const>
1299 // lsls r3, #8
1300 // adds r3, #:lower0_7:<const>
1301 // So we need to special-case MOVS, ADDS and LSLS, and keep track of
1302 // where we are in the sequence with the simplest of state machines.
1303 // 3) for Thumb2 execute only code we materialize the constant via
1304 // immediate constants in 2 separate instructions (MOVW/MOVT).
1305 SrcReg = ~0U;
1306 DstReg = MI->getOperand(0).getReg();
1307 break;
1308 case ARM::VMRS:
1309 SrcReg = ARM::FPSCR;
1310 DstReg = MI->getOperand(0).getReg();
1311 break;
1312 case ARM::VMRS_FPEXC:
1313 SrcReg = ARM::FPEXC;
1314 DstReg = MI->getOperand(0).getReg();
1315 break;
1316 default:
1317 SrcReg = MI->getOperand(1).getReg();
1318 DstReg = MI->getOperand(0).getReg();
1319 break;
1320 }
1321
1322 // Try to figure out the unwinding opcode out of src / dst regs.
1323 if (MI->mayStore()) {
1324 // Register saves.
1325 assert(DstReg == ARM::SP &&
1326 "Only stack pointer as a destination reg is supported");
1327
1329 // Skip src & dst reg, and pred ops.
1330 unsigned StartOp = 2 + 2;
1331 // Use all the operands.
1332 unsigned NumOffset = 0;
1333 // Amount of SP adjustment folded into a push, before the
1334 // registers are stored (pad at higher addresses).
1335 unsigned PadBefore = 0;
1336 // Amount of SP adjustment folded into a push, after the
1337 // registers are stored (pad at lower addresses).
1338 unsigned PadAfter = 0;
1339
1340 switch (Opc) {
1341 default:
1342 MI->print(errs());
1343 llvm_unreachable("Unsupported opcode for unwinding information");
1344 case ARM::tPUSH:
1345 // Special case here: no src & dst reg, but two extra imp ops.
1346 StartOp = 2; NumOffset = 2;
1347 [[fallthrough]];
1348 case ARM::STMDB_UPD:
1349 case ARM::t2STMDB_UPD:
1350 case ARM::VSTMDDB_UPD:
1351 assert(SrcReg == ARM::SP &&
1352 "Only stack pointer as a source reg is supported");
1353 for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset;
1354 i != NumOps; ++i) {
1355 const MachineOperand &MO = MI->getOperand(i);
1356 // Actually, there should never be any impdef stuff here. Skip it
1357 // temporary to workaround PR11902.
1358 if (MO.isImplicit())
1359 continue;
1360 // Registers, pushed as a part of folding an SP update into the
1361 // push instruction are marked as undef and should not be
1362 // restored when unwinding, because the function can modify the
1363 // corresponding stack slots.
1364 if (MO.isUndef()) {
1365 assert(RegList.empty() &&
1366 "Pad registers must come before restored ones");
1367 unsigned Width =
1368 TargetRegInfo->getRegSizeInBits(MO.getReg(), MachineRegInfo) / 8;
1369 PadAfter += Width;
1370 continue;
1371 }
1372 // Check for registers that are remapped (for a Thumb1 prologue that
1373 // saves high registers).
1374 Register Reg = MO.getReg();
1375 if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(Reg))
1376 Reg = RemappedReg;
1377 RegList.push_back(Reg);
1378 }
1379 break;
1380 case ARM::STR_PRE_IMM:
1381 case ARM::STR_PRE_REG:
1382 case ARM::t2STR_PRE:
1383 assert(MI->getOperand(2).getReg() == ARM::SP &&
1384 "Only stack pointer as a source reg is supported");
1385 if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(SrcReg))
1386 SrcReg = RemappedReg;
1387
1388 RegList.push_back(SrcReg);
1389 break;
1390 case ARM::t2STRD_PRE:
1391 assert(MI->getOperand(3).getReg() == ARM::SP &&
1392 "Only stack pointer as a source reg is supported");
1393 SrcReg = MI->getOperand(1).getReg();
1394 if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(SrcReg))
1395 SrcReg = RemappedReg;
1396 RegList.push_back(SrcReg);
1397 SrcReg = MI->getOperand(2).getReg();
1398 if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(SrcReg))
1399 SrcReg = RemappedReg;
1400 RegList.push_back(SrcReg);
1401 PadBefore = -MI->getOperand(4).getImm() - 8;
1402 break;
1403 }
1404 if (MAI.getExceptionHandlingType() == ExceptionHandling::ARM) {
1405 if (PadBefore)
1406 ATS.emitPad(PadBefore);
1407 ATS.emitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);
1408 // Account for the SP adjustment, folded into the push.
1409 if (PadAfter)
1410 ATS.emitPad(PadAfter);
1411 }
1412 } else {
1413 // Changes of stack / frame pointer.
1414 if (SrcReg == ARM::SP) {
1415 int64_t Offset = 0;
1416 switch (Opc) {
1417 default:
1418 MI->print(errs());
1419 llvm_unreachable("Unsupported opcode for unwinding information");
1420 case ARM::tLDRspi:
1421 // Used to restore LR in a prologue which uses it as a temporary, has
1422 // no effect on unwind tables.
1423 return;
1424 case ARM::MOVr:
1425 case ARM::tMOVr:
1426 Offset = 0;
1427 break;
1428 case ARM::ADDri:
1429 case ARM::t2ADDri:
1430 case ARM::t2ADDri12:
1431 case ARM::t2ADDspImm:
1432 case ARM::t2ADDspImm12:
1433 Offset = -MI->getOperand(2).getImm();
1434 break;
1435 case ARM::SUBri:
1436 case ARM::t2SUBri:
1437 case ARM::t2SUBri12:
1438 case ARM::t2SUBspImm:
1439 case ARM::t2SUBspImm12:
1440 Offset = MI->getOperand(2).getImm();
1441 break;
1442 case ARM::tSUBspi:
1443 Offset = MI->getOperand(2).getImm()*4;
1444 break;
1445 case ARM::tADDspi:
1446 case ARM::tADDrSPi:
1447 Offset = -MI->getOperand(2).getImm()*4;
1448 break;
1449 case ARM::tADDhirr:
1450 Offset =
1451 -AFI->EHPrologueOffsetInRegs.lookup(MI->getOperand(2).getReg());
1452 break;
1453 }
1454
1455 if (MAI.getExceptionHandlingType() == ExceptionHandling::ARM) {
1456 if (DstReg == FramePtr && FramePtr != ARM::SP)
1457 // Set-up of the frame pointer. Positive values correspond to "add"
1458 // instruction.
1459 ATS.emitSetFP(FramePtr, ARM::SP, -Offset);
1460 else if (DstReg == ARM::SP) {
1461 // Change of SP by an offset. Positive values correspond to "sub"
1462 // instruction.
1463 ATS.emitPad(Offset);
1464 } else {
1465 // Move of SP to a register. Positive values correspond to an "add"
1466 // instruction.
1467 ATS.emitMovSP(DstReg, -Offset);
1468 }
1469 }
1470 } else if (DstReg == ARM::SP) {
1471 MI->print(errs());
1472 llvm_unreachable("Unsupported opcode for unwinding information");
1473 } else {
1474 int64_t Offset = 0;
1475 switch (Opc) {
1476 case ARM::tMOVr:
1477 // If a Thumb1 function spills r8-r11, we copy the values to low
1478 // registers before pushing them. Record the copy so we can emit the
1479 // correct ".save" later.
1480 AFI->EHPrologueRemappedRegs[DstReg] = SrcReg;
1481 break;
1482 case ARM::VMRS:
1483 case ARM::VMRS_FPEXC:
1484 // If a function spills FPSCR or FPEXC, we copy the values to low
1485 // registers before pushing them. However, we can't issue annotations
1486 // for FP status registers because ".save" requires GPR registers, and
1487 // ".vsave" requires DPR registers, so don't record the copy and simply
1488 // emit annotations for the source registers used for the store.
1489 break;
1490 case ARM::tLDRpci: {
1491 // Grab the constpool index and check, whether it corresponds to
1492 // original or cloned constpool entry.
1493 unsigned CPI = MI->getOperand(1).getIndex();
1494 const MachineConstantPool *MCP = MF.getConstantPool();
1495 if (CPI >= MCP->getConstants().size())
1496 CPI = AFI->getOriginalCPIdx(CPI);
1497 assert(CPI != -1U && "Invalid constpool index");
1498
1499 // Derive the actual offset.
1500 const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI];
1501 assert(!CPE.isMachineConstantPoolEntry() && "Invalid constpool entry");
1502 Offset = cast<ConstantInt>(CPE.Val.ConstVal)->getSExtValue();
1503 AFI->EHPrologueOffsetInRegs[DstReg] = Offset;
1504 break;
1505 }
1506 case ARM::t2MOVi16:
1507 Offset = MI->getOperand(1).getImm();
1508 AFI->EHPrologueOffsetInRegs[DstReg] = Offset;
1509 break;
1510 case ARM::t2MOVTi16:
1511 Offset = MI->getOperand(2).getImm();
1512 AFI->EHPrologueOffsetInRegs[DstReg] |= (Offset << 16);
1513 break;
1514 case ARM::tMOVi8:
1515 Offset = MI->getOperand(2).getImm();
1516 AFI->EHPrologueOffsetInRegs[DstReg] = Offset;
1517 break;
1518 case ARM::tLSLri:
1519 assert(MI->getOperand(3).getImm() == 8 &&
1520 "The shift amount is not equal to 8");
1521 assert(MI->getOperand(2).getReg() == MI->getOperand(0).getReg() &&
1522 "The source register is not equal to the destination register");
1523 AFI->EHPrologueOffsetInRegs[DstReg] <<= 8;
1524 break;
1525 case ARM::tADDi8:
1526 assert(MI->getOperand(2).getReg() == MI->getOperand(0).getReg() &&
1527 "The source register is not equal to the destination register");
1528 Offset = MI->getOperand(3).getImm();
1529 AFI->EHPrologueOffsetInRegs[DstReg] += Offset;
1530 break;
1531 case ARM::t2PAC:
1532 case ARM::t2PACBTI:
1533 AFI->EHPrologueRemappedRegs[ARM::R12] = ARM::RA_AUTH_CODE;
1534 break;
1535 default:
1536 MI->print(errs());
1537 llvm_unreachable("Unsupported opcode for unwinding information");
1538 }
1539 }
1540 }
1541}
1542
1543// Simple pseudo-instructions have their lowering (with expansion to real
1544// instructions) auto-generated.
1545#include "ARMGenMCPseudoLowering.inc"
1546
1547// Helper function to check if a register is live (used as an implicit operand)
1548// in the given call instruction.
1550 for (const MachineOperand &MO : Call.implicit_operands()) {
1551 if (MO.isReg() && MO.getReg() == Reg && MO.isUse()) {
1552 return true;
1553 }
1554 }
1555 return false;
1556}
1557
1558void ARMAsmPrinter::EmitKCFI_CHECK_ARM32(Register AddrReg, int64_t Type,
1559 const MachineInstr &Call,
1560 int64_t PrefixNops) {
1561 // Choose scratch register: r12 primary, r3 if target is r12.
1562 unsigned ScratchReg = ARM::R12;
1563 if (AddrReg == ARM::R12) {
1564 ScratchReg = ARM::R3;
1565 }
1566
1567 // Calculate ESR for ARM mode (16-bit): 0x8000 | (scratch_reg << 5) | addr_reg
1568 // Note: scratch_reg is always 0x1F since the EOR sequence clobbers it.
1569 const ARMBaseRegisterInfo *TRI = static_cast<const ARMBaseRegisterInfo *>(
1570 MF->getSubtarget().getRegisterInfo());
1571 unsigned AddrIndex = TRI->getEncodingValue(AddrReg);
1572 unsigned ESR = 0x8000 | (31 << 5) | (AddrIndex & 31);
1573
1574 // Check if r3 is live and needs to be spilled.
1575 bool NeedSpillR3 =
1576 (ScratchReg == ARM::R3) && isRegisterLiveInCall(Call, ARM::R3);
1577
1578 // If we need to spill r3, push it first.
1579 if (NeedSpillR3) {
1580 // push {r3}
1581 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::STMDB_UPD)
1582 .addReg(ARM::SP)
1583 .addReg(ARM::SP)
1584 .addImm(ARMCC::AL)
1585 .addReg(0)
1586 .addReg(ARM::R3));
1587 }
1588
1589 // Clear bit 0 of target address to handle Thumb function pointers.
1590 // In 32-bit ARM, function pointers may have the low bit set to indicate
1591 // Thumb state when ARM/Thumb interworking is enabled (ARMv4T and later).
1592 // We need to clear it to avoid an alignment fault when loading.
1593 // bic scratch, target, #1
1594 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::BICri)
1595 .addReg(ScratchReg)
1596 .addReg(AddrReg)
1597 .addImm(1)
1598 .addImm(ARMCC::AL)
1599 .addReg(0)
1600 .addReg(0));
1601
1602 // ldr scratch, [scratch, #-(PrefixNops * 4 + 4)]
1603 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::LDRi12)
1604 .addReg(ScratchReg)
1605 .addReg(ScratchReg)
1606 .addImm(-(PrefixNops * 4 + 4))
1607 .addImm(ARMCC::AL)
1608 .addReg(0));
1609
1610 // Each EOR instruction XORs one byte of the type, shifted to its position.
1611 for (int i = 0; i < 4; i++) {
1612 uint8_t byte = (Type >> (i * 8)) & 0xFF;
1613 uint32_t imm = byte << (i * 8);
1614 bool isLast = (i == 3);
1615
1616 // Encode as ARM modified immediate.
1617 int SOImmVal = ARM_AM::getSOImmVal(imm);
1618 assert(SOImmVal != -1 &&
1619 "Cannot encode immediate as ARM modified immediate");
1620
1621 // eor[s] scratch, scratch, #imm (last one sets flags with CPSR)
1623 MCInstBuilder(ARM::EORri)
1624 .addReg(ScratchReg)
1625 .addReg(ScratchReg)
1626 .addImm(SOImmVal)
1627 .addImm(ARMCC::AL)
1628 .addReg(0)
1629 .addReg(isLast ? ARM::CPSR : ARM::NoRegister));
1630 }
1631
1632 // If we spilled r3, restore it immediately after the comparison.
1633 // This must happen before the branch so r3 is valid on both paths.
1634 if (NeedSpillR3) {
1635 // pop {r3}
1636 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::LDMIA_UPD)
1637 .addReg(ARM::SP)
1638 .addReg(ARM::SP)
1639 .addImm(ARMCC::AL)
1640 .addReg(0)
1641 .addReg(ARM::R3));
1642 }
1643
1644 // beq .Lpass (branch if types match, i.e., scratch is zero)
1645 MCSymbol *Pass = OutContext.createTempSymbol();
1647 MCInstBuilder(ARM::Bcc)
1649 .addImm(ARMCC::EQ)
1650 .addReg(ARM::CPSR));
1651
1652 // udf #ESR (trap with encoded diagnostic)
1653 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::UDF).addImm(ESR));
1654
1655 OutStreamer->emitLabel(Pass);
1656}
1657
1658void ARMAsmPrinter::EmitKCFI_CHECK_Thumb2(Register AddrReg, int64_t Type,
1659 const MachineInstr &Call,
1660 int64_t PrefixNops) {
1661 // Choose scratch register: r12 primary, r3 if target is r12.
1662 unsigned ScratchReg = ARM::R12;
1663 if (AddrReg == ARM::R12) {
1664 ScratchReg = ARM::R3;
1665 }
1666
1667 // Calculate ESR for Thumb mode (8-bit): 0x80 | addr_reg
1668 // Bit 7: KCFI trap indicator
1669 // Bits 6-5: Reserved
1670 // Bits 4-0: Address register encoding
1671 const ARMBaseRegisterInfo *TRI = static_cast<const ARMBaseRegisterInfo *>(
1672 MF->getSubtarget().getRegisterInfo());
1673 unsigned AddrIndex = TRI->getEncodingValue(AddrReg);
1674 unsigned ESR = 0x80 | (AddrIndex & 0x1F);
1675
1676 // Check if r3 is live and needs to be spilled.
1677 bool NeedSpillR3 =
1678 (ScratchReg == ARM::R3) && isRegisterLiveInCall(Call, ARM::R3);
1679
1680 // If we need to spill r3, push it first.
1681 if (NeedSpillR3) {
1682 // push {r3}
1684 *OutStreamer,
1685 MCInstBuilder(ARM::tPUSH).addImm(ARMCC::AL).addReg(0).addReg(ARM::R3));
1686 }
1687
1688 // Clear bit 0 of target address to handle Thumb function pointers.
1689 // In 32-bit ARM, function pointers may have the low bit set to indicate
1690 // Thumb state when ARM/Thumb interworking is enabled (ARMv4T and later).
1691 // We need to clear it to avoid an alignment fault when loading.
1692 // bic scratch, target, #1
1693 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2BICri)
1694 .addReg(ScratchReg)
1695 .addReg(AddrReg)
1696 .addImm(1)
1697 .addImm(ARMCC::AL)
1698 .addReg(0)
1699 .addReg(0));
1700
1701 // ldr scratch, [scratch, #-(PrefixNops * 4 + 4)]
1702 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::t2LDRi8)
1703 .addReg(ScratchReg)
1704 .addReg(ScratchReg)
1705 .addImm(-(PrefixNops * 4 + 4))
1706 .addImm(ARMCC::AL)
1707 .addReg(0));
1708
1709 // Each EOR instruction XORs one byte of the type, shifted to its position.
1710 for (int i = 0; i < 4; i++) {
1711 uint8_t byte = (Type >> (i * 8)) & 0xFF;
1712 uint32_t imm = byte << (i * 8);
1713 bool isLast = (i == 3);
1714
1715 // Verify the immediate can be encoded as Thumb2 modified immediate.
1716 assert(ARM_AM::getT2SOImmVal(imm) != -1 &&
1717 "Cannot encode immediate as Thumb2 modified immediate");
1718
1719 // eor[s] scratch, scratch, #imm (last one sets flags with CPSR)
1721 MCInstBuilder(ARM::t2EORri)
1722 .addReg(ScratchReg)
1723 .addReg(ScratchReg)
1724 .addImm(imm)
1725 .addImm(ARMCC::AL)
1726 .addReg(0)
1727 .addReg(isLast ? ARM::CPSR : ARM::NoRegister));
1728 }
1729
1730 // If we spilled r3, restore it immediately after the comparison.
1731 // This must happen before the branch so r3 is valid on both paths.
1732 if (NeedSpillR3) {
1733 // pop {r3}
1735 *OutStreamer,
1736 MCInstBuilder(ARM::tPOP).addImm(ARMCC::AL).addReg(0).addReg(ARM::R3));
1737 }
1738
1739 // beq .Lpass (branch if types match, i.e., scratch is zero)
1740 MCSymbol *Pass = OutContext.createTempSymbol();
1742 MCInstBuilder(ARM::t2Bcc)
1744 .addImm(ARMCC::EQ)
1745 .addReg(ARM::CPSR));
1746
1747 // udf #ESR (trap with encoded diagnostic)
1748 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tUDF).addImm(ESR));
1749
1750 OutStreamer->emitLabel(Pass);
1751}
1752
1753void ARMAsmPrinter::EmitKCFI_CHECK_Thumb1(Register AddrReg, int64_t Type,
1754 const MachineInstr &Call,
1755 int64_t PrefixNops) {
1756 // For Thumb1, use R2 unconditionally as scratch register (a low register
1757 // required for tLDRi). R3 is used for building the type hash.
1758 unsigned ScratchReg = ARM::R2;
1759 unsigned TempReg = ARM::R3;
1760
1761 // Check if r3 is live and needs to be spilled.
1762 bool NeedSpillR3 = isRegisterLiveInCall(Call, ARM::R3);
1763
1764 // Spill r3 if needed
1765 if (NeedSpillR3) {
1767 *OutStreamer,
1768 MCInstBuilder(ARM::tPUSH).addImm(ARMCC::AL).addReg(0).addReg(ARM::R3));
1769 }
1770
1771 // Check if r2 is live and needs to be spilled.
1772 bool NeedSpillR2 = isRegisterLiveInCall(Call, ARM::R2);
1773
1774 // Push R2 if it's live
1775 if (NeedSpillR2) {
1777 *OutStreamer,
1778 MCInstBuilder(ARM::tPUSH).addImm(ARMCC::AL).addReg(0).addReg(ARM::R2));
1779 }
1780
1781 // Clear bit 0 from target address
1782 // TempReg (R3) is used first as helper for BIC, then later for building type
1783 // hash.
1784
1785 // movs temp, #1
1786 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVi8)
1787 .addReg(TempReg)
1788 .addReg(ARM::CPSR)
1789 .addImm(1)
1790 .addImm(ARMCC::AL)
1791 .addReg(0));
1792
1793 // mov scratch, target
1794 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVr)
1795 .addReg(ScratchReg)
1796 .addReg(AddrReg)
1797 .addImm(ARMCC::AL));
1798
1799 // bics scratch, temp (scratch = scratch & ~temp)
1800 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tBIC)
1801 .addReg(ScratchReg)
1802 .addReg(ARM::CPSR)
1803 .addReg(ScratchReg)
1804 .addReg(TempReg)
1805 .addImm(ARMCC::AL)
1806 .addReg(0));
1807
1808 // Load type hash. Thumb1 doesn't support negative offsets, so subtract.
1809 int offset = PrefixNops * 4 + 4;
1810
1811 // subs scratch, #offset
1812 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tSUBi8)
1813 .addReg(ScratchReg)
1814 .addReg(ARM::CPSR)
1815 .addReg(ScratchReg)
1816 .addImm(offset)
1817 .addImm(ARMCC::AL)
1818 .addReg(0));
1819
1820 // ldr scratch, [scratch, #0]
1821 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLDRi)
1822 .addReg(ScratchReg)
1823 .addReg(ScratchReg)
1824 .addImm(0)
1825 .addImm(ARMCC::AL)
1826 .addReg(0));
1827
1828 // Load expected type inline (instead of EOR sequence)
1829 //
1830 // This creates the 32-bit value byte-by-byte in the temp register:
1831 // movs temp, #byte3 (high byte)
1832 // lsls temp, temp, #8
1833 // adds temp, #byte2
1834 // lsls temp, temp, #8
1835 // adds temp, #byte1
1836 // lsls temp, temp, #8
1837 // adds temp, #byte0 (low byte)
1838
1839 uint8_t byte0 = (Type >> 0) & 0xFF;
1840 uint8_t byte1 = (Type >> 8) & 0xFF;
1841 uint8_t byte2 = (Type >> 16) & 0xFF;
1842 uint8_t byte3 = (Type >> 24) & 0xFF;
1843
1844 // movs temp, #byte3 (start with high byte)
1845 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tMOVi8)
1846 .addReg(TempReg)
1847 .addReg(ARM::CPSR)
1848 .addImm(byte3)
1849 .addImm(ARMCC::AL)
1850 .addReg(0));
1851
1852 // lsls temp, temp, #8
1853 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLSLri)
1854 .addReg(TempReg)
1855 .addReg(ARM::CPSR)
1856 .addReg(TempReg)
1857 .addImm(8)
1858 .addImm(ARMCC::AL)
1859 .addReg(0));
1860
1861 // adds temp, #byte2
1862 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tADDi8)
1863 .addReg(TempReg)
1864 .addReg(ARM::CPSR)
1865 .addReg(TempReg)
1866 .addImm(byte2)
1867 .addImm(ARMCC::AL)
1868 .addReg(0));
1869
1870 // lsls temp, temp, #8
1871 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLSLri)
1872 .addReg(TempReg)
1873 .addReg(ARM::CPSR)
1874 .addReg(TempReg)
1875 .addImm(8)
1876 .addImm(ARMCC::AL)
1877 .addReg(0));
1878
1879 // adds temp, #byte1
1880 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tADDi8)
1881 .addReg(TempReg)
1882 .addReg(ARM::CPSR)
1883 .addReg(TempReg)
1884 .addImm(byte1)
1885 .addImm(ARMCC::AL)
1886 .addReg(0));
1887
1888 // lsls temp, temp, #8
1889 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLSLri)
1890 .addReg(TempReg)
1891 .addReg(ARM::CPSR)
1892 .addReg(TempReg)
1893 .addImm(8)
1894 .addImm(ARMCC::AL)
1895 .addReg(0));
1896
1897 // adds temp, #byte0 (low byte)
1898 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tADDi8)
1899 .addReg(TempReg)
1900 .addReg(ARM::CPSR)
1901 .addReg(TempReg)
1902 .addImm(byte0)
1903 .addImm(ARMCC::AL)
1904 .addReg(0));
1905
1906 // cmp scratch, temp
1907 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tCMPr)
1908 .addReg(ScratchReg)
1909 .addReg(TempReg)
1910 .addImm(ARMCC::AL)
1911 .addReg(0));
1912
1913 // Restore registers if spilled (pop in reverse order of push: R2, then R3)
1914 if (NeedSpillR2) {
1915 // pop {r2}
1917 *OutStreamer,
1918 MCInstBuilder(ARM::tPOP).addImm(ARMCC::AL).addReg(0).addReg(ARM::R2));
1919 }
1920
1921 // Restore r3 if spilled
1922 if (NeedSpillR3) {
1923 // pop {r3}
1925 *OutStreamer,
1926 MCInstBuilder(ARM::tPOP).addImm(ARMCC::AL).addReg(0).addReg(ARM::R3));
1927 }
1928
1929 // beq .Lpass (branch if types match, i.e., scratch == temp)
1930 MCSymbol *Pass = OutContext.createTempSymbol();
1932 MCInstBuilder(ARM::tBcc)
1934 .addImm(ARMCC::EQ)
1935 .addReg(ARM::CPSR));
1936
1937 // bkpt #0 (trap with encoded diagnostic)
1938 EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tBKPT).addImm(0));
1939
1940 OutStreamer->emitLabel(Pass);
1941}
1942
1944 Register AddrReg = MI.getOperand(0).getReg();
1945 const int64_t Type = MI.getOperand(1).getImm();
1946
1947 // Get the call instruction that follows this KCFI_CHECK.
1948 assert(std::next(MI.getIterator())->isCall() &&
1949 "KCFI_CHECK not followed by a call instruction");
1950 const MachineInstr &Call = *std::next(MI.getIterator());
1951
1952 // Adjust the offset for patchable-function-prefix.
1953 int64_t PrefixNops = MI.getMF()->getFunction().getFnAttributeAsParsedInteger(
1954 "patchable-function-prefix");
1955
1956 // Emit the appropriate instruction sequence based on the opcode variant.
1957 switch (MI.getOpcode()) {
1958 case ARM::KCFI_CHECK_ARM:
1959 EmitKCFI_CHECK_ARM32(AddrReg, Type, Call, PrefixNops);
1960 break;
1961 case ARM::KCFI_CHECK_Thumb2:
1962 EmitKCFI_CHECK_Thumb2(AddrReg, Type, Call, PrefixNops);
1963 break;
1964 case ARM::KCFI_CHECK_Thumb1:
1965 EmitKCFI_CHECK_Thumb1(AddrReg, Type, Call, PrefixNops);
1966 break;
1967 default:
1968 llvm_unreachable("Unexpected KCFI_CHECK opcode");
1969 }
1970}
1971
1973 ARM_MC::verifyInstructionPredicates(MI->getOpcode(),
1974 getSubtargetInfo().getFeatureBits());
1975
1976 const ARMSubtarget &STI = MF->getSubtarget<ARMSubtarget>();
1977 const DataLayout &DL = getDataLayout();
1978 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();
1979 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1980
1981 // If we just ended a constant pool, mark it as such.
1982 if (InConstantPool && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) {
1983 OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
1984 InConstantPool = false;
1985 }
1986
1987 // Emit unwinding stuff for frame-related instructions
1988 if (TM.getTargetTriple().isTargetEHABICompatible() &&
1989 MI->getFlag(MachineInstr::FrameSetup))
1990 EmitUnwindingInstruction(MI);
1991
1992 // Do any auto-generated pseudo lowerings.
1993 if (MCInst OutInst; lowerPseudoInstExpansion(MI, OutInst)) {
1994 EmitToStreamer(*OutStreamer, OutInst);
1995 return;
1996 }
1997
1998 assert(!convertAddSubFlagsOpcode(MI->getOpcode()) &&
1999 "Pseudo flag setting opcode should be expanded early");
2000
2001 // Check for manual lowerings.
2002 unsigned Opc = MI->getOpcode();
2003 switch (Opc) {
2004 case ARM::t2MOVi32imm: llvm_unreachable("Should be lowered by thumb2it pass");
2005 case ARM::DBG_VALUE: llvm_unreachable("Should be handled by generic printing");
2006 case ARM::KCFI_CHECK_ARM:
2007 case ARM::KCFI_CHECK_Thumb2:
2008 case ARM::KCFI_CHECK_Thumb1:
2010 return;
2011 case ARM::LEApcrel:
2012 case ARM::tLEApcrel:
2013 case ARM::t2LEApcrel: {
2014 // FIXME: Need to also handle globals and externals
2015 MCSymbol *CPISymbol = GetCPISymbol(MI->getOperand(1).getIndex());
2016 EmitToStreamer(*OutStreamer, MCInstBuilder(MI->getOpcode() ==
2017 ARM::t2LEApcrel ? ARM::t2ADR
2018 : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR
2019 : ARM::ADR))
2020 .addReg(MI->getOperand(0).getReg())
2022 // Add predicate operands.
2023 .addImm(MI->getOperand(2).getImm())
2024 .addReg(MI->getOperand(3).getReg()));
2025 return;
2026 }
2027 case ARM::LEApcrelJT:
2028 case ARM::tLEApcrelJT:
2029 case ARM::t2LEApcrelJT: {
2030 MCSymbol *JTIPICSymbol =
2031 GetARMJTIPICJumpTableLabel(MI->getOperand(1).getIndex());
2032 EmitToStreamer(*OutStreamer, MCInstBuilder(MI->getOpcode() ==
2033 ARM::t2LEApcrelJT ? ARM::t2ADR
2034 : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR
2035 : ARM::ADR))
2036 .addReg(MI->getOperand(0).getReg())
2038 // Add predicate operands.
2039 .addImm(MI->getOperand(2).getImm())
2040 .addReg(MI->getOperand(3).getReg()));
2041 return;
2042 }
2043 // Darwin call instructions are just normal call instructions with different
2044 // clobber semantics (they clobber R9).
2045 case ARM::BX_CALL: {
2047 .addReg(ARM::LR)
2048 .addReg(ARM::PC)
2049 // Add predicate operands.
2050 .addImm(ARMCC::AL)
2051 .addReg(0)
2052 // Add 's' bit operand (always reg0 for this)
2053 .addReg(0));
2054
2055 assert(STI.hasV4TOps() && "Expected V4TOps for BX call");
2057 MCInstBuilder(ARM::BX).addReg(MI->getOperand(0).getReg()));
2058 return;
2059 }
2060 case ARM::tBX_CALL: {
2061 assert(!STI.hasV5TOps() && "Expected BLX to be selected for v5t+");
2062
2063 // On ARM v4t, when doing a call from thumb mode, we need to ensure
2064 // that the saved lr has its LSB set correctly (the arch doesn't
2065 // have blx).
2066 // So here we generate a bl to a small jump pad that does bx rN.
2067 // The jump pads are emitted after the function body.
2068
2069 Register TReg = MI->getOperand(0).getReg();
2070 MCSymbol *TRegSym = nullptr;
2071 for (std::pair<unsigned, MCSymbol *> &TIP : ThumbIndirectPads) {
2072 if (TIP.first == TReg) {
2073 TRegSym = TIP.second;
2074 break;
2075 }
2076 }
2077
2078 if (!TRegSym) {
2079 TRegSym = OutContext.createTempSymbol();
2080 ThumbIndirectPads.push_back(std::make_pair(TReg, TRegSym));
2081 }
2082
2083 // Create a link-saving branch to the Reg Indirect Jump Pad.
2085 // Predicate comes first here.
2086 .addImm(ARMCC::AL).addReg(0)
2087 .addExpr(MCSymbolRefExpr::create(TRegSym, OutContext)));
2088 return;
2089 }
2090 case ARM::BMOVPCRX_CALL: {
2092 .addReg(ARM::LR)
2093 .addReg(ARM::PC)
2094 // Add predicate operands.
2095 .addImm(ARMCC::AL)
2096 .addReg(0)
2097 // Add 's' bit operand (always reg0 for this)
2098 .addReg(0));
2099
2101 .addReg(ARM::PC)
2102 .addReg(MI->getOperand(0).getReg())
2103 // Add predicate operands.
2105 .addReg(0)
2106 // Add 's' bit operand (always reg0 for this)
2107 .addReg(0));
2108 return;
2109 }
2110 case ARM::BMOVPCB_CALL: {
2112 .addReg(ARM::LR)
2113 .addReg(ARM::PC)
2114 // Add predicate operands.
2115 .addImm(ARMCC::AL)
2116 .addReg(0)
2117 // Add 's' bit operand (always reg0 for this)
2118 .addReg(0));
2119
2120 const MachineOperand &Op = MI->getOperand(0);
2121 const GlobalValue *GV = Op.getGlobal();
2122 const unsigned TF = Op.getTargetFlags();
2123 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
2124 const MCExpr *GVSymExpr = MCSymbolRefExpr::create(GVSym, OutContext);
2126 .addExpr(GVSymExpr)
2127 // Add predicate operands.
2128 .addImm(ARMCC::AL)
2129 .addReg(0));
2130 return;
2131 }
2132 case ARM::MOVi16_ga_pcrel:
2133 case ARM::t2MOVi16_ga_pcrel: {
2134 MCInst TmpInst;
2135 TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16);
2136 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
2137
2138 unsigned TF = MI->getOperand(1).getTargetFlags();
2139 const GlobalValue *GV = MI->getOperand(1).getGlobal();
2140 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
2141 const MCExpr *GVSymExpr = MCSymbolRefExpr::create(GVSym, OutContext);
2142
2143 MCSymbol *LabelSym =
2144 getPICLabel(DL.getInternalSymbolPrefix(), getFunctionNumber(),
2145 MI->getOperand(2).getImm(), OutContext);
2146 const MCExpr *LabelSymExpr= MCSymbolRefExpr::create(LabelSym, OutContext);
2147 unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;
2148 const MCExpr *PCRelExpr = ARM::createLower16(
2150 GVSymExpr,
2151 MCBinaryExpr::createAdd(LabelSymExpr,
2153 OutContext),
2154 OutContext),
2155 OutContext);
2156 TmpInst.addOperand(MCOperand::createExpr(PCRelExpr));
2157
2158 // Add predicate operands.
2160 TmpInst.addOperand(MCOperand::createReg(0));
2161 // Add 's' bit operand (always reg0 for this)
2162 TmpInst.addOperand(MCOperand::createReg(0));
2163 EmitToStreamer(*OutStreamer, TmpInst);
2164 return;
2165 }
2166 case ARM::MOVTi16_ga_pcrel:
2167 case ARM::t2MOVTi16_ga_pcrel: {
2168 MCInst TmpInst;
2169 TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel
2170 ? ARM::MOVTi16 : ARM::t2MOVTi16);
2171 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
2172 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(1).getReg()));
2173
2174 unsigned TF = MI->getOperand(2).getTargetFlags();
2175 const GlobalValue *GV = MI->getOperand(2).getGlobal();
2176 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);
2177 const MCExpr *GVSymExpr = MCSymbolRefExpr::create(GVSym, OutContext);
2178
2179 MCSymbol *LabelSym =
2180 getPICLabel(DL.getInternalSymbolPrefix(), getFunctionNumber(),
2181 MI->getOperand(3).getImm(), OutContext);
2182 const MCExpr *LabelSymExpr= MCSymbolRefExpr::create(LabelSym, OutContext);
2183 unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;
2184 const MCExpr *PCRelExpr = ARM::createUpper16(
2186 GVSymExpr,
2187 MCBinaryExpr::createAdd(LabelSymExpr,
2189 OutContext),
2190 OutContext),
2191 OutContext);
2192 TmpInst.addOperand(MCOperand::createExpr(PCRelExpr));
2193 // Add predicate operands.
2195 TmpInst.addOperand(MCOperand::createReg(0));
2196 // Add 's' bit operand (always reg0 for this)
2197 TmpInst.addOperand(MCOperand::createReg(0));
2198 EmitToStreamer(*OutStreamer, TmpInst);
2199 return;
2200 }
2201 case ARM::t2BFi:
2202 case ARM::t2BFic:
2203 case ARM::t2BFLi:
2204 case ARM::t2BFr:
2205 case ARM::t2BFLr: {
2206 // This is a Branch Future instruction.
2207
2208 const MCExpr *BranchLabel = MCSymbolRefExpr::create(
2209 getBFLabel(DL.getInternalSymbolPrefix(), getFunctionNumber(),
2210 MI->getOperand(0).getIndex(), OutContext),
2211 OutContext);
2212
2213 auto MCInst = MCInstBuilder(Opc).addExpr(BranchLabel);
2214 if (MI->getOperand(1).isReg()) {
2215 // For BFr/BFLr
2216 MCInst.addReg(MI->getOperand(1).getReg());
2217 } else {
2218 // For BFi/BFLi/BFic
2219 const MCExpr *BranchTarget;
2220 if (MI->getOperand(1).isMBB())
2221 BranchTarget = MCSymbolRefExpr::create(
2222 MI->getOperand(1).getMBB()->getSymbol(), OutContext);
2223 else if (MI->getOperand(1).isGlobal()) {
2224 const GlobalValue *GV = MI->getOperand(1).getGlobal();
2225 BranchTarget = MCSymbolRefExpr::create(
2226 GetARMGVSymbol(GV, MI->getOperand(1).getTargetFlags()), OutContext);
2227 } else if (MI->getOperand(1).isSymbol()) {
2228 BranchTarget = MCSymbolRefExpr::create(
2229 GetExternalSymbolSymbol(MI->getOperand(1).getSymbolName()),
2230 OutContext);
2231 } else
2232 llvm_unreachable("Unhandled operand kind in Branch Future instruction");
2233
2234 MCInst.addExpr(BranchTarget);
2235 }
2236
2237 if (Opc == ARM::t2BFic) {
2238 const MCExpr *ElseLabel = MCSymbolRefExpr::create(
2239 getBFLabel(DL.getInternalSymbolPrefix(), getFunctionNumber(),
2240 MI->getOperand(2).getIndex(), OutContext),
2241 OutContext);
2242 MCInst.addExpr(ElseLabel);
2243 MCInst.addImm(MI->getOperand(3).getImm());
2244 } else {
2245 MCInst.addImm(MI->getOperand(2).getImm())
2246 .addReg(MI->getOperand(3).getReg());
2247 }
2248
2250 return;
2251 }
2252 case ARM::t2BF_LabelPseudo: {
2253 // This is a pseudo op for a label used by a branch future instruction
2254
2255 // Emit the label.
2256 OutStreamer->emitLabel(
2257 getBFLabel(DL.getInternalSymbolPrefix(), getFunctionNumber(),
2258 MI->getOperand(0).getIndex(), OutContext));
2259 return;
2260 }
2261 case ARM::tPICADD: {
2262 // This is a pseudo op for a label + instruction sequence, which looks like:
2263 // LPC0:
2264 // add r0, pc
2265 // This adds the address of LPC0 to r0.
2266
2267 // Emit the label.
2268 OutStreamer->emitLabel(getPICLabel(DL.getInternalSymbolPrefix(),
2270 MI->getOperand(2).getImm(), OutContext));
2271
2272 // Form and emit the add.
2274 .addReg(MI->getOperand(0).getReg())
2275 .addReg(MI->getOperand(0).getReg())
2276 .addReg(ARM::PC)
2277 // Add predicate operands.
2279 .addReg(0));
2280 return;
2281 }
2282 case ARM::PICADD: {
2283 // This is a pseudo op for a label + instruction sequence, which looks like:
2284 // LPC0:
2285 // add r0, pc, r0
2286 // This adds the address of LPC0 to r0.
2287
2288 // Emit the label.
2289 OutStreamer->emitLabel(getPICLabel(DL.getInternalSymbolPrefix(),
2291 MI->getOperand(2).getImm(), OutContext));
2292
2293 // Form and emit the add.
2295 .addReg(MI->getOperand(0).getReg())
2296 .addReg(ARM::PC)
2297 .addReg(MI->getOperand(1).getReg())
2298 // Add predicate operands.
2299 .addImm(MI->getOperand(3).getImm())
2300 .addReg(MI->getOperand(4).getReg())
2301 // Add 's' bit operand (always reg0 for this)
2302 .addReg(0));
2303 return;
2304 }
2305 case ARM::PICSTR:
2306 case ARM::PICSTRB:
2307 case ARM::PICSTRH:
2308 case ARM::PICLDR:
2309 case ARM::PICLDRB:
2310 case ARM::PICLDRH:
2311 case ARM::PICLDRSB:
2312 case ARM::PICLDRSH: {
2313 // This is a pseudo op for a label + instruction sequence, which looks like:
2314 // LPC0:
2315 // OP r0, [pc, r0]
2316 // The LCP0 label is referenced by a constant pool entry in order to get
2317 // a PC-relative address at the ldr instruction.
2318
2319 // Emit the label.
2320 OutStreamer->emitLabel(getPICLabel(DL.getInternalSymbolPrefix(),
2322 MI->getOperand(2).getImm(), OutContext));
2323
2324 // Form and emit the load
2325 unsigned Opcode;
2326 switch (MI->getOpcode()) {
2327 default:
2328 llvm_unreachable("Unexpected opcode!");
2329 case ARM::PICSTR: Opcode = ARM::STRrs; break;
2330 case ARM::PICSTRB: Opcode = ARM::STRBrs; break;
2331 case ARM::PICSTRH: Opcode = ARM::STRH; break;
2332 case ARM::PICLDR: Opcode = ARM::LDRrs; break;
2333 case ARM::PICLDRB: Opcode = ARM::LDRBrs; break;
2334 case ARM::PICLDRH: Opcode = ARM::LDRH; break;
2335 case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
2336 case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
2337 }
2339 .addReg(MI->getOperand(0).getReg())
2340 .addReg(ARM::PC)
2341 .addReg(MI->getOperand(1).getReg())
2342 .addImm(0)
2343 // Add predicate operands.
2344 .addImm(MI->getOperand(3).getImm())
2345 .addReg(MI->getOperand(4).getReg()));
2346
2347 return;
2348 }
2349 case ARM::CONSTPOOL_ENTRY: {
2350 assert(!STI.genExecuteOnly() &&
2351 "execute-only should not generate constant pools");
2352
2353 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
2354 /// in the function. The first operand is the ID# for this instruction, the
2355 /// second is the index into the MachineConstantPool that this is, the third
2356 /// is the size in bytes of this constant pool entry.
2357 /// The required alignment is specified on the basic block holding this MI.
2358 unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
2359 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();
2360
2361 // If this is the first entry of the pool, mark it.
2362 if (!InConstantPool) {
2363 OutStreamer->emitDataRegion(MCDR_DataRegion);
2364 InConstantPool = true;
2365 }
2366
2367 OutStreamer->emitLabel(GetCPISymbol(LabelId));
2368
2369 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
2370 if (MCPE.isMachineConstantPoolEntry())
2372 else
2374 return;
2375 }
2376 case ARM::JUMPTABLE_ADDRS:
2378 return;
2379 case ARM::JUMPTABLE_INSTS:
2381 return;
2382 case ARM::JUMPTABLE_TBB:
2383 case ARM::JUMPTABLE_TBH:
2384 emitJumpTableTBInst(MI, MI->getOpcode() == ARM::JUMPTABLE_TBB ? 1 : 2);
2385 return;
2386 case ARM::t2BR_JT: {
2388 .addReg(ARM::PC)
2389 .addReg(MI->getOperand(0).getReg())
2390 // Add predicate operands.
2392 .addReg(0));
2393 return;
2394 }
2395 case ARM::t2TBB_JT:
2396 case ARM::t2TBH_JT: {
2397 unsigned Opc = MI->getOpcode() == ARM::t2TBB_JT ? ARM::t2TBB : ARM::t2TBH;
2398 // Lower and emit the PC label, then the instruction itself.
2399 OutStreamer->emitLabel(GetCPISymbol(MI->getOperand(3).getImm()));
2401 .addReg(MI->getOperand(0).getReg())
2402 .addReg(MI->getOperand(1).getReg())
2403 // Add predicate operands.
2405 .addReg(0));
2406 return;
2407 }
2408 case ARM::tTBB_JT:
2409 case ARM::tTBH_JT: {
2410
2411 bool Is8Bit = MI->getOpcode() == ARM::tTBB_JT;
2412 Register Base = MI->getOperand(0).getReg();
2413 Register Idx = MI->getOperand(1).getReg();
2414 assert(MI->getOperand(1).isKill() && "We need the index register as scratch!");
2415
2416 // Multiply up idx if necessary.
2417 if (!Is8Bit)
2419 .addReg(Idx)
2420 .addReg(ARM::CPSR)
2421 .addReg(Idx)
2422 .addImm(1)
2423 // Add predicate operands.
2424 .addImm(ARMCC::AL)
2425 .addReg(0));
2426
2427 if (Base == ARM::PC) {
2428 // TBB [base, idx] =
2429 // ADDS idx, idx, base
2430 // LDRB idx, [idx, #4] ; or LDRH if TBH
2431 // LSLS idx, #1
2432 // ADDS pc, pc, idx
2433
2434 // When using PC as the base, it's important that there is no padding
2435 // between the last ADDS and the start of the jump table. The jump table
2436 // is 4-byte aligned, so we ensure we're 4 byte aligned here too.
2437 //
2438 // FIXME: Ideally we could vary the LDRB index based on the padding
2439 // between the sequence and jump table, however that relies on MCExprs
2440 // for load indexes which are currently not supported.
2441 OutStreamer->emitCodeAlignment(Align(4), getSubtargetInfo());
2443 .addReg(Idx)
2444 .addReg(Idx)
2445 .addReg(Base)
2446 // Add predicate operands.
2447 .addImm(ARMCC::AL)
2448 .addReg(0));
2449
2450 unsigned Opc = Is8Bit ? ARM::tLDRBi : ARM::tLDRHi;
2452 .addReg(Idx)
2453 .addReg(Idx)
2454 .addImm(Is8Bit ? 4 : 2)
2455 // Add predicate operands.
2456 .addImm(ARMCC::AL)
2457 .addReg(0));
2458 } else {
2459 // TBB [base, idx] =
2460 // LDRB idx, [base, idx] ; or LDRH if TBH
2461 // LSLS idx, #1
2462 // ADDS pc, pc, idx
2463
2464 unsigned Opc = Is8Bit ? ARM::tLDRBr : ARM::tLDRHr;
2466 .addReg(Idx)
2467 .addReg(Base)
2468 .addReg(Idx)
2469 // Add predicate operands.
2470 .addImm(ARMCC::AL)
2471 .addReg(0));
2472 }
2473
2475 .addReg(Idx)
2476 .addReg(ARM::CPSR)
2477 .addReg(Idx)
2478 .addImm(1)
2479 // Add predicate operands.
2480 .addImm(ARMCC::AL)
2481 .addReg(0));
2482
2483 OutStreamer->emitLabel(GetCPISymbol(MI->getOperand(3).getImm()));
2485 .addReg(ARM::PC)
2486 .addReg(ARM::PC)
2487 .addReg(Idx)
2488 // Add predicate operands.
2489 .addImm(ARMCC::AL)
2490 .addReg(0));
2491 return;
2492 }
2493 case ARM::tBR_JTr:
2494 case ARM::BR_JTr: {
2495 // mov pc, target
2496 MCInst TmpInst;
2497 unsigned Opc = MI->getOpcode() == ARM::BR_JTr ?
2498 ARM::MOVr : ARM::tMOVr;
2499 TmpInst.setOpcode(Opc);
2500 TmpInst.addOperand(MCOperand::createReg(ARM::PC));
2501 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
2502 // Add predicate operands.
2504 TmpInst.addOperand(MCOperand::createReg(0));
2505 // Add 's' bit operand (always reg0 for this)
2506 if (Opc == ARM::MOVr)
2507 TmpInst.addOperand(MCOperand::createReg(0));
2508 EmitToStreamer(*OutStreamer, TmpInst);
2509 return;
2510 }
2511 case ARM::BR_JTm_i12: {
2512 // ldr pc, target
2513 MCInst TmpInst;
2514 TmpInst.setOpcode(ARM::LDRi12);
2515 TmpInst.addOperand(MCOperand::createReg(ARM::PC));
2516 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
2517 TmpInst.addOperand(MCOperand::createImm(MI->getOperand(2).getImm()));
2518 // Add predicate operands.
2520 TmpInst.addOperand(MCOperand::createReg(0));
2521 EmitToStreamer(*OutStreamer, TmpInst);
2522 return;
2523 }
2524 case ARM::BR_JTm_rs: {
2525 // ldr pc, target
2526 MCInst TmpInst;
2527 TmpInst.setOpcode(ARM::LDRrs);
2528 TmpInst.addOperand(MCOperand::createReg(ARM::PC));
2529 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
2530 TmpInst.addOperand(MCOperand::createReg(MI->getOperand(1).getReg()));
2531 TmpInst.addOperand(MCOperand::createImm(MI->getOperand(2).getImm()));
2532 // Add predicate operands.
2534 TmpInst.addOperand(MCOperand::createReg(0));
2535 EmitToStreamer(*OutStreamer, TmpInst);
2536 return;
2537 }
2538 case ARM::BR_JTadd: {
2539 // add pc, target, idx
2541 .addReg(ARM::PC)
2542 .addReg(MI->getOperand(0).getReg())
2543 .addReg(MI->getOperand(1).getReg())
2544 // Add predicate operands.
2546 .addReg(0)
2547 // Add 's' bit operand (always reg0 for this)
2548 .addReg(0));
2549 return;
2550 }
2551 case ARM::SPACE:
2552 OutStreamer->emitZeros(MI->getOperand(1).getImm());
2553 return;
2554 case ARM::TRAP: {
2555 // Non-Darwin binutils don't yet support the "trap" mnemonic.
2556 // FIXME: Remove this special case when they do.
2557 if (!TM.getTargetTriple().isOSBinFormatMachO()) {
2558 uint32_t Val = 0xe7ffdefeUL;
2559 OutStreamer->AddComment("trap");
2560 ATS.emitInst(Val);
2561 return;
2562 }
2563 break;
2564 }
2565 case ARM::tTRAP: {
2566 // Non-Darwin binutils don't yet support the "trap" mnemonic.
2567 // FIXME: Remove this special case when they do.
2568 if (!TM.getTargetTriple().isOSBinFormatMachO()) {
2569 uint16_t Val = 0xdefe;
2570 OutStreamer->AddComment("trap");
2571 ATS.emitInst(Val, 'n');
2572 return;
2573 }
2574 break;
2575 }
2576 case ARM::t2Int_eh_sjlj_setjmp:
2577 case ARM::t2Int_eh_sjlj_setjmp_nofp:
2578 case ARM::tInt_eh_sjlj_setjmp: {
2579 // Two incoming args: GPR:$src, GPR:$val
2580 // mov $val, pc
2581 // adds $val, #7
2582 // str $val, [$src, #4]
2583 // movs r0, #0
2584 // b LSJLJEH
2585 // movs r0, #1
2586 // LSJLJEH:
2587 Register SrcReg = MI->getOperand(0).getReg();
2588 Register ValReg = MI->getOperand(1).getReg();
2589 MCSymbol *Label = OutContext.createTempSymbol("SJLJEH");
2590 OutStreamer->AddComment("eh_setjmp begin");
2592 .addReg(ValReg)
2593 .addReg(ARM::PC)
2594 // Predicate.
2595 .addImm(ARMCC::AL)
2596 .addReg(0));
2597
2599 .addReg(ValReg)
2600 // 's' bit operand
2601 .addReg(ARM::CPSR)
2602 .addReg(ValReg)
2603 .addImm(7)
2604 // Predicate.
2605 .addImm(ARMCC::AL)
2606 .addReg(0));
2607
2609 .addReg(ValReg)
2610 .addReg(SrcReg)
2611 // The offset immediate is #4. The operand value is scaled by 4 for the
2612 // tSTR instruction.
2613 .addImm(1)
2614 // Predicate.
2615 .addImm(ARMCC::AL)
2616 .addReg(0));
2617
2619 .addReg(ARM::R0)
2620 .addReg(ARM::CPSR)
2621 .addImm(0)
2622 // Predicate.
2623 .addImm(ARMCC::AL)
2624 .addReg(0));
2625
2626 const MCExpr *SymbolExpr = MCSymbolRefExpr::create(Label, OutContext);
2628 .addExpr(SymbolExpr)
2629 .addImm(ARMCC::AL)
2630 .addReg(0));
2631
2632 OutStreamer->AddComment("eh_setjmp end");
2634 .addReg(ARM::R0)
2635 .addReg(ARM::CPSR)
2636 .addImm(1)
2637 // Predicate.
2638 .addImm(ARMCC::AL)
2639 .addReg(0));
2640
2641 OutStreamer->emitLabel(Label);
2642 return;
2643 }
2644
2645 case ARM::Int_eh_sjlj_setjmp_nofp:
2646 case ARM::Int_eh_sjlj_setjmp: {
2647 // Two incoming args: GPR:$src, GPR:$val
2648 // add $val, pc, #8
2649 // str $val, [$src, #+4]
2650 // mov r0, #0
2651 // add pc, pc, #0
2652 // mov r0, #1
2653 Register SrcReg = MI->getOperand(0).getReg();
2654 Register ValReg = MI->getOperand(1).getReg();
2655
2656 OutStreamer->AddComment("eh_setjmp begin");
2658 .addReg(ValReg)
2659 .addReg(ARM::PC)
2660 .addImm(8)
2661 // Predicate.
2662 .addImm(ARMCC::AL)
2663 .addReg(0)
2664 // 's' bit operand (always reg0 for this).
2665 .addReg(0));
2666
2668 .addReg(ValReg)
2669 .addReg(SrcReg)
2670 .addImm(4)
2671 // Predicate.
2672 .addImm(ARMCC::AL)
2673 .addReg(0));
2674
2676 .addReg(ARM::R0)
2677 .addImm(0)
2678 // Predicate.
2679 .addImm(ARMCC::AL)
2680 .addReg(0)
2681 // 's' bit operand (always reg0 for this).
2682 .addReg(0));
2683
2685 .addReg(ARM::PC)
2686 .addReg(ARM::PC)
2687 .addImm(0)
2688 // Predicate.
2689 .addImm(ARMCC::AL)
2690 .addReg(0)
2691 // 's' bit operand (always reg0 for this).
2692 .addReg(0));
2693
2694 OutStreamer->AddComment("eh_setjmp end");
2696 .addReg(ARM::R0)
2697 .addImm(1)
2698 // Predicate.
2699 .addImm(ARMCC::AL)
2700 .addReg(0)
2701 // 's' bit operand (always reg0 for this).
2702 .addReg(0));
2703 return;
2704 }
2705 case ARM::Int_eh_sjlj_longjmp: {
2706 // ldr sp, [$src, #8]
2707 // ldr $scratch, [$src, #4]
2708 // ldr r7, [$src]
2709 // bx $scratch
2710 Register SrcReg = MI->getOperand(0).getReg();
2711 Register ScratchReg = MI->getOperand(1).getReg();
2713 .addReg(ARM::SP)
2714 .addReg(SrcReg)
2715 .addImm(8)
2716 // Predicate.
2717 .addImm(ARMCC::AL)
2718 .addReg(0));
2719
2721 .addReg(ScratchReg)
2722 .addReg(SrcReg)
2723 .addImm(4)
2724 // Predicate.
2725 .addImm(ARMCC::AL)
2726 .addReg(0));
2727
2728 if (STI.isTargetDarwin() || STI.isTargetWindows()) {
2729 // These platforms always use the same frame register
2731 .addReg(STI.getFramePointerReg())
2732 .addReg(SrcReg)
2733 .addImm(0)
2734 // Predicate.
2736 .addReg(0));
2737 } else {
2738 // If the calling code might use either R7 or R11 as
2739 // frame pointer register, restore it into both.
2741 .addReg(ARM::R7)
2742 .addReg(SrcReg)
2743 .addImm(0)
2744 // Predicate.
2745 .addImm(ARMCC::AL)
2746 .addReg(0));
2748 .addReg(ARM::R11)
2749 .addReg(SrcReg)
2750 .addImm(0)
2751 // Predicate.
2752 .addImm(ARMCC::AL)
2753 .addReg(0));
2754 }
2755
2756 assert(STI.hasV4TOps());
2758 .addReg(ScratchReg)
2759 // Predicate.
2760 .addImm(ARMCC::AL)
2761 .addReg(0));
2762 return;
2763 }
2764 case ARM::tInt_eh_sjlj_longjmp: {
2765 // ldr $scratch, [$src, #8]
2766 // mov sp, $scratch
2767 // ldr $scratch, [$src, #4]
2768 // ldr r7, [$src]
2769 // bx $scratch
2770 Register SrcReg = MI->getOperand(0).getReg();
2771 Register ScratchReg = MI->getOperand(1).getReg();
2772
2774 .addReg(ScratchReg)
2775 .addReg(SrcReg)
2776 // The offset immediate is #8. The operand value is scaled by 4 for the
2777 // tLDR instruction.
2778 .addImm(2)
2779 // Predicate.
2780 .addImm(ARMCC::AL)
2781 .addReg(0));
2782
2784 .addReg(ARM::SP)
2785 .addReg(ScratchReg)
2786 // Predicate.
2787 .addImm(ARMCC::AL)
2788 .addReg(0));
2789
2791 .addReg(ScratchReg)
2792 .addReg(SrcReg)
2793 .addImm(1)
2794 // Predicate.
2795 .addImm(ARMCC::AL)
2796 .addReg(0));
2797
2798 if (STI.isTargetDarwin() || STI.isTargetWindows()) {
2799 // These platforms always use the same frame register
2801 .addReg(STI.getFramePointerReg())
2802 .addReg(SrcReg)
2803 .addImm(0)
2804 // Predicate.
2806 .addReg(0));
2807 } else {
2808 // If the calling code might use either R7 or R11 as
2809 // frame pointer register, restore it into both.
2811 .addReg(ARM::R7)
2812 .addReg(SrcReg)
2813 .addImm(0)
2814 // Predicate.
2815 .addImm(ARMCC::AL)
2816 .addReg(0));
2818 .addReg(ARM::R11)
2819 .addReg(SrcReg)
2820 .addImm(0)
2821 // Predicate.
2822 .addImm(ARMCC::AL)
2823 .addReg(0));
2824 }
2825
2827 .addReg(ScratchReg)
2828 // Predicate.
2829 .addImm(ARMCC::AL)
2830 .addReg(0));
2831 return;
2832 }
2833 case ARM::tInt_WIN_eh_sjlj_longjmp: {
2834 // ldr.w r11, [$src, #0]
2835 // ldr.w sp, [$src, #8]
2836 // ldr.w pc, [$src, #4]
2837
2838 Register SrcReg = MI->getOperand(0).getReg();
2839
2841 .addReg(ARM::R11)
2842 .addReg(SrcReg)
2843 .addImm(0)
2844 // Predicate
2845 .addImm(ARMCC::AL)
2846 .addReg(0));
2848 .addReg(ARM::SP)
2849 .addReg(SrcReg)
2850 .addImm(8)
2851 // Predicate
2852 .addImm(ARMCC::AL)
2853 .addReg(0));
2855 .addReg(ARM::PC)
2856 .addReg(SrcReg)
2857 .addImm(4)
2858 // Predicate
2859 .addImm(ARMCC::AL)
2860 .addReg(0));
2861 return;
2862 }
2863 case ARM::PATCHABLE_FUNCTION_ENTER:
2865 return;
2866 case ARM::PATCHABLE_FUNCTION_EXIT:
2868 return;
2869 case ARM::PATCHABLE_TAIL_CALL:
2871 return;
2872 case ARM::SpeculationBarrierISBDSBEndBB: {
2873 // Print DSB SYS + ISB
2874 MCInst TmpInstDSB;
2875 TmpInstDSB.setOpcode(ARM::DSB);
2876 TmpInstDSB.addOperand(MCOperand::createImm(0xf));
2877 EmitToStreamer(*OutStreamer, TmpInstDSB);
2878 MCInst TmpInstISB;
2879 TmpInstISB.setOpcode(ARM::ISB);
2880 TmpInstISB.addOperand(MCOperand::createImm(0xf));
2881 EmitToStreamer(*OutStreamer, TmpInstISB);
2882 return;
2883 }
2884 case ARM::t2SpeculationBarrierISBDSBEndBB: {
2885 // Print DSB SYS + ISB
2886 MCInst TmpInstDSB;
2887 TmpInstDSB.setOpcode(ARM::t2DSB);
2888 TmpInstDSB.addOperand(MCOperand::createImm(0xf));
2890 TmpInstDSB.addOperand(MCOperand::createReg(0));
2891 EmitToStreamer(*OutStreamer, TmpInstDSB);
2892 MCInst TmpInstISB;
2893 TmpInstISB.setOpcode(ARM::t2ISB);
2894 TmpInstISB.addOperand(MCOperand::createImm(0xf));
2896 TmpInstISB.addOperand(MCOperand::createReg(0));
2897 EmitToStreamer(*OutStreamer, TmpInstISB);
2898 return;
2899 }
2900 case ARM::SpeculationBarrierSBEndBB: {
2901 // Print SB
2902 MCInst TmpInstSB;
2903 TmpInstSB.setOpcode(ARM::SB);
2904 EmitToStreamer(*OutStreamer, TmpInstSB);
2905 return;
2906 }
2907 case ARM::t2SpeculationBarrierSBEndBB: {
2908 // Print SB
2909 MCInst TmpInstSB;
2910 TmpInstSB.setOpcode(ARM::t2SB);
2911 EmitToStreamer(*OutStreamer, TmpInstSB);
2912 return;
2913 }
2914
2915 case ARM::SEH_StackAlloc:
2916 ATS.emitARMWinCFIAllocStack(MI->getOperand(0).getImm(),
2917 MI->getOperand(1).getImm());
2918 return;
2919
2920 case ARM::SEH_SaveRegs:
2921 case ARM::SEH_SaveRegs_Ret:
2922 ATS.emitARMWinCFISaveRegMask(MI->getOperand(0).getImm(),
2923 MI->getOperand(1).getImm());
2924 return;
2925
2926 case ARM::SEH_SaveSP:
2927 ATS.emitARMWinCFISaveSP(MI->getOperand(0).getImm());
2928 return;
2929
2930 case ARM::SEH_SaveFRegs:
2931 ATS.emitARMWinCFISaveFRegs(MI->getOperand(0).getImm(),
2932 MI->getOperand(1).getImm());
2933 return;
2934
2935 case ARM::SEH_SaveLR:
2936 ATS.emitARMWinCFISaveLR(MI->getOperand(0).getImm());
2937 return;
2938
2939 case ARM::SEH_Nop:
2940 case ARM::SEH_Nop_Ret:
2941 ATS.emitARMWinCFINop(MI->getOperand(0).getImm());
2942 return;
2943
2944 case ARM::SEH_PrologEnd:
2945 ATS.emitARMWinCFIPrologEnd(/*Fragment=*/false);
2946 return;
2947
2948 case ARM::SEH_EpilogStart:
2950 return;
2951
2952 case ARM::SEH_EpilogEnd:
2954 return;
2955 }
2956
2957 MCInst TmpInst;
2958 LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
2959
2960 EmitToStreamer(*OutStreamer, TmpInst);
2961}
2962
2963char ARMAsmPrinter::ID = 0;
2964
2965INITIALIZE_PASS(ARMAsmPrinter, "arm-asm-printer", "ARM Assembly Printer", false,
2966 false)
2967
2968//===----------------------------------------------------------------------===//
2969// Target Registry Stuff
2970//===----------------------------------------------------------------------===//
2971
2972// Force static initialization.
2973extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
2974LLVMInitializeARMAsmPrinter() {
2979}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isRegisterLiveInCall(const MachineInstr &Call, MCRegister Reg)
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 checkDenormalAttributeInconsistency(const Module &M)
static bool checkDenormalAttributeConsistency(const Module &M, DenormalFPEnv Value)
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)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
#define F(x, y, z)
Definition MD5.cpp:54
Machine Check Debug Module
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#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:484
This file defines the SmallString class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
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 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.
void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, const MCSubtargetInfo *EndInfo, const MachineInstr *MI) override
Let the target do anything it needs to do after emitting inlineasm.
void LowerKCFI_CHECK(const MachineInstr &MI)
void emitGlobalAlias(const Module &M, const GlobalAlias &GA) override
bool isGVIndirectSymbol(const GlobalValue *GV) const
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...
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=ARM::NoRegAltName)
bool isThumb1Only() const
MCPhysReg getFramePointerReg() const
bool isTargetWindows() const
bool isTargetDarwin() const
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)
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
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
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
virtual void emitGlobalVariable(const GlobalVariable *GV)
Emit the specified global variable to the .s file.
TargetMachine & TM
Target machine description.
Definition AsmPrinter.h:94
void emitXRayTable()
Emit a table with all XRay instrumentation points.
virtual void emitGlobalAlias(const Module &M, const GlobalAlias &GA)
Align emitAlignment(Align Alignment, const GlobalObject *GV=nullptr, unsigned MaxBytesToEmit=0) const
Emit an alignment directive to the specified power of two boundary.
MCSymbol * getMBBExceptionSym(const MachineBasicBlock &MBB)
MachineFunction * MF
The current machine function.
Definition AsmPrinter.h:109
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.
unsigned getFunctionNumber() const
Return a unique ID for the current function.
AsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer, char &ID=AsmPrinter::ID)
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.
MCSymbol * CurrentFnSym
The symbol for the current function.
Definition AsmPrinter.h:128
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
Definition AsmPrinter.h:112
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition AsmPrinter.h:101
bool isPositionIndependent() const
void emitVisibility(MCSymbol *Sym, unsigned Visibility, bool IsDefinition=true) const
This emits visibility information about symbol, if this is supported by the target.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition AsmPrinter.h:106
const MCAsmInfo & MAI
Target Asm Printer information.
Definition AsmPrinter.h:97
void getNameWithPrefix(SmallVectorImpl< char > &Name, const GlobalValue *GV) const
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.
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.
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:1088
This is an important base class in LLVM.
Definition Constant.h:43
const Constant * stripPointerCasts() const
Definition Constant.h:233
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:727
LLVM_ABI const GlobalObject * getAliaseeObject() const
Definition Globals.cpp:730
bool isDSOLocal() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
VisibilityTypes getVisibility() const
bool hasInternalLinkage() const
static bool isWeakForLinker(LinkageTypes Linkage)
Whether the definition of this global may be replaced at link time.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:342
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:352
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:427
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 * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
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.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
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:41
Streaming machine code generation interface.
Definition MCStreamer.h:222
virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
Add the given Attribute to Symbol.
MCContext & getContext() const
Definition MCStreamer.h:326
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
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.
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:213
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:95
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::@004270020304201266316354007027341142157160323045 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.
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.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
const std::vector< MachineJumpTableEntry > & getJumpTables() const
StubValueTy & getGVStubEntry(MCSymbol *Sym)
std::vector< std::pair< MCSymbol *, StubValueTy > > SymbolListTy
PointerIntPair< MCSymbol *, 1, bool > StubValueTy
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.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
const GlobalValue * getGlobal() const
int64_t getImm() 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
Pass(PassKind K, char &pid)
Definition Pass.h:105
IntType getInt() const
PointerTy getPointer() const
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Represents a location in source code.
Definition SMLoc.h:22
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Primary interface to the complete machine description for the target machine.
TargetOptions Options
FloatABI::ABIType FloatABIType
FloatABIType - This setting is set by -float-abi=xxx option is specfied on the command line.
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:48
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:46
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an SmallVector or SmallString.
CallInst * Call
#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.
@ MO_LO_0_7
MO_LO_0_7 - On a symbol operand, this represents a relocation containing bits 0 through 7 of the addr...
@ MO_LO_8_15
MO_LO_8_15 - On a symbol operand, this represents a relocation containing bits 8 through 15 of the ad...
@ MO_NONLAZY
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which,...
@ MO_HI_8_15
MO_HI_8_15 - On a symbol operand, this represents a relocation containing bits 24 through 31 of the a...
@ MO_HI16
MO_HI16 - On a symbol operand, this represents a relocation containing higher 16 bit of the address.
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand, this represents that the reference to the symbol is for an import...
@ MO_HI_0_7
MO_HI_0_7 - On a symbol operand, this represents a relocation containing bits 16 through 23 of the ad...
@ MO_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
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
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)
Extract a Value from Metadata, allowing null.
Definition Metadata.h:683
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:578
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
Target & getTheThumbBETarget()
@ MCDR_DataRegionEnd
.end_data_region
@ MCDR_DataRegion
.data_region
@ MCDR_DataRegionJT8
.data_region jt8
@ MCDR_DataRegionJT32
.data_region jt32
@ MCDR_DataRegionJT16
.data_region jt16
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
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)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
DWARFExpression::Operation Op
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:1917
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
Target & getTheARMLETarget()
unsigned convertAddSubFlagsOpcode(unsigned OldOpc)
Map pseudo instructions that imply an 'S' bit onto real opcodes.
@ MCSA_IndirectSymbol
.indirect_symbol (MachO)
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Target & getTheARMBETarget()
Target & getTheThumbLETarget()
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Represents the full denormal controls for a function, including the default mode and the f32 specific...
static constexpr DenormalMode getPositiveZero()
static constexpr DenormalMode getPreserveSign()
static constexpr DenormalMode getIEEE()
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...