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