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