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