LLVM: lib/Target/ARM/ARMAsmPrinter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

47using namespace llvm;

48

49#define DEBUG_TYPE "asm-printer"

50

52 std::unique_ptr Streamer)

53 : AsmPrinter(TM, std::move(Streamer)), Subtarget(nullptr), AFI(nullptr),

54 MCP(nullptr), InConstantPool(false), OptimizationGoals(-1) {}

55

57

58

59 if (!InConstantPool)

60 return;

61 InConstantPool = false;

63}

64

69 } else {

71 }

72

73

80 }

82}

83

86 assert(Size && "C++ constructor pointer had zero size!");

87

89 assert(GV && "C++ constructor pointer was not a GlobalValue!");

90

97

99}

100

102 if (PromotedGlobals.count(GV))

103

104 return;

106}

107

108

109

110

115

119

120

121

122

124 PromotedGlobals.insert(GV);

125

126

127 unsigned OptimizationGoal;

128 if (F.hasOptNone())

129

130 OptimizationGoal = 6;

131 else if (F.hasMinSize())

132

133 OptimizationGoal = 4;

134 else if (F.hasOptSize())

135

136 OptimizationGoal = 3;

138

139 OptimizationGoal = 2;

141

142 OptimizationGoal = 1;

143 else

144

145 OptimizationGoal = 5;

146

147

148 if (OptimizationGoals == -1)

149 OptimizationGoals = OptimizationGoal;

150 else if (OptimizationGoals != (int)OptimizationGoal)

151 OptimizationGoals = 0;

152

154 bool Local = F.hasLocalLinkage();

158

160 OutStreamer->emitCOFFSymbolStorageClass(Scl);

163 }

164

165

167

168

170

171

172

173

174 if (! ThumbIndirectPads.empty()) {

177 for (std::pair<unsigned, MCSymbol *> &TIP : ThumbIndirectPads) {

180 .addReg(TIP.first)

181

184 }

185 ThumbIndirectPads.clear();

186 }

187

188

189 return false;

190}

191

194 assert(MO.isGlobal() && "caller should check MO.isGlobal");

197 O << ":lower16:";

199 O << ":upper16:";

201 O << ":lower0_7:";

203 O << ":lower8_15:";

205 O << ":upper0_7:";

207 O << ":upper8_15:";

208

211}

212

216

221 assert(Reg.isPhysical());

222 assert(!MO.getSubReg() && "Subregs should be eliminated!");

223 if(ARM::GPRPairRegClass.contains(Reg)) {

226 Reg = TRI->getSubReg(Reg, ARM::gsub_0);

227 }

229 break;

230 }

232 O << '#';

235 O << ":lower16:";

237 O << ":upper16:";

239 O << ":lower0_7:";

241 O << ":lower8_15:";

243 O << ":upper0_7:";

245 O << ":upper8_15:";

247 break;

248 }

251 return;

254 break;

255 }

257 if (Subtarget->genExecuteOnly())

258 llvm_unreachable("execute-only should not generate constant pools");

260 break;

261 }

262}

263

265

266

271}

272

273

274

276GetARMJTIPICJumpTableLabel(unsigned uid) const {

282}

283

286

287 if (ExtraCode && ExtraCode[0]) {

288 if (ExtraCode[1] != 0) return true;

289

290 switch (ExtraCode[0]) {

291 default:

292

294 case 'P':

295 case 'q':

297 return false;

298 case 'y':

299 if (MI->getOperand(OpNum).isReg()) {

300 MCRegister Reg = MI->getOperand(OpNum).getReg().asMCReg();

302

303

305 if (!ARM::DPRRegClass.contains(SR))

306 continue;

307 bool Lane0 = TRI->getSubReg(SR, ARM::ssub_0) == Reg;

309 return false;

310 }

311 }

312 return true;

313 case 'B':

314 if (MI->getOperand(OpNum).isImm())

315 return true;

316 O << ~(MI->getOperand(OpNum).getImm());

317 return false;

318 case 'L':

319 if (MI->getOperand(OpNum).isImm())

320 return true;

321 O << (MI->getOperand(OpNum).getImm() & 0xffff);

322 return false;

323 case 'M': {

324 if (MI->getOperand(OpNum).isReg())

325 return true;

328

329

330

331 O << "{";

332 if (ARM::GPRPairRegClass.contains(RegBegin)) {

334 Register Reg0 = TRI->getSubReg(RegBegin, ARM::gsub_0);

336 RegBegin = TRI->getSubReg(RegBegin, ARM::gsub_1);

337 }

339

340

341

342

343

344 unsigned RegOps = OpNum + 1;

345 while (MI->getOperand(RegOps).isReg()) {

346 O << ", "

348 RegOps++;

349 }

350

351 O << "}";

352

353 return false;

354 }

355 case 'R':

356 case 'Q': {

357 if (OpNum == 0)

358 return true;

360 if (!FlagsOP.isImm())

361 return true;

363

364

365

366

367 unsigned TiedIdx;

368 if (F.isUseOperandTiedToDef(TiedIdx)) {

370 unsigned OpFlags = MI->getOperand(OpNum).getImm();

372 OpNum += F.getNumOperandRegisters() + 1;

373 }

375

376

377

378 OpNum += 1;

379 }

380

381 const unsigned NumVals = F.getNumOperandRegisters();

382 unsigned RC;

383 bool FirstHalf;

386

387

388

389

390 if (ExtraCode[0] == 'Q')

392 else

393

396 if (F.hasRegClassConstraint(RC) &&

397 ARM::GPRPairRegClass.hasSubClassEq(TRI->getRegClass(RC))) {

398 if (NumVals != 1)

399 return true;

402 return true;

405 TRI->getSubReg(MO.getReg(), FirstHalf ? ARM::gsub_0 : ARM::gsub_1);

407 return false;

408 }

409 if (NumVals != 2)

410 return true;

411 unsigned RegOp = FirstHalf ? OpNum : OpNum + 1;

412 if (RegOp >= MI->getNumOperands())

413 return true;

416 return true;

419 return false;

420 }

421

422 case 'e':

423 case 'f': {

424 if (MI->getOperand(OpNum).isReg())

425 return true;

426 Register Reg = MI->getOperand(OpNum).getReg();

427 if (!ARM::QPRRegClass.contains(Reg))

428 return true;

431 TRI->getSubReg(Reg, ExtraCode[0] == 'e' ? ARM::dsub_0 : ARM::dsub_1);

433 return false;

434 }

435

436

437 case 'h':

438 return true;

439 case 'H': {

442 return true;

446 if(!ARM::GPRPairRegClass.contains(Reg))

447 return false;

448 Reg = TRI->getSubReg(Reg, ARM::gsub_1);

450 return false;

451 }

452 }

453 }

454

456 return false;

457}

458

460 unsigned OpNum, const char *ExtraCode,

462

463 if (ExtraCode && ExtraCode[0]) {

464 if (ExtraCode[1] != 0) return true;

465

466 switch (ExtraCode[0]) {

467 case 'A':

468 default: return true;

469 case 'm':

470 if (MI->getOperand(OpNum).isReg())

471 return true;

473 return false;

474 }

475 }

476

478 assert(MO.isReg() && "unexpected inline asm memory operand");

480 return false;

481}

482

484 return STI.hasFeature(ARM::ModeThumb);

485}

486

489

490

491 const bool WasThumb = isThumb(StartInfo);

492 if (!EndInfo || WasThumb != isThumb(*EndInfo)) {

494 }

495}

496

499

501

502

503 if (TT.isOSBinFormatELF())

504 emitAttributes();

505

506

507

508

509 if (!M.getModuleInlineAsm().empty() && TT.isThumb())

511}

512

513static void

516

517 OutStreamer.emitLabel(StubLabel);

518

520

522

524 else

525

526

527

528

529

530

533 4 );

534}

535

536

539 if (TT.isOSBinFormatMachO()) {

540

545

546

548

549 if (!Stubs.empty()) {

550

553

554 for (auto &Stub : Stubs)

556

557 Stubs.clear();

559 }

560

562 if (!Stubs.empty()) {

563

566

567 for (auto &Stub : Stubs)

569

570 Stubs.clear();

572 }

573

574

575

576

577

578

580 }

581

582

585

586 if (OptimizationGoals > 0 &&

590 OptimizationGoals = -1;

591

593}

594

595

596

597

598

599

600

601

602

603

607 return F.getFnAttribute(Attr).getValueAsString() != Value;

608 });

609}

610

611

616 StringRef AttrVal = F.getFnAttribute(Attr).getValueAsString();

618 });

619}

620

621void ARMAsmPrinter::emitAttributes() {

624

626

628

629

630

631

632

633

638 if (FS.empty()) {

639 if (!ArchFS.empty())

640 ArchFS = (Twine(ArchFS) + "," + FS).str();

641 else

642 ArchFS = std::string(FS);

643 }

646 const ARMSubtarget STI(TT, std::string(CPU), ArchFS, ATM,

648

649

651

652

656 } else if (STI.isRWPI()) {

657

660 }

661

662

666 }

667

668

672 } else {

675 }

676

677

683 "denormal-fp-math",

690 else {

691 if (!STI.hasVFP2Base()) {

692

693

694

695

696

697

698 if (STI.hasV7Ops())

701 } else if (STI.hasVFP3Base()) {

702

703

704

707 }

708

709

710

711

712

713

714 }

715

716

718 "no-trapping-math", "true") ||

724

725

726

729 }

730

731

732

736 else

739

740

741

744

745

748

749

750

751

752

755

757

758

759 if (auto WCharWidthValue = mdconst::extract_or_null(

760 SourceModule->getModuleFlag("wchar_size"))) {

761 int WCharWidth = WCharWidthValue->getZExtValue();

762 assert((WCharWidth == 2 || WCharWidth == 4) &&

763 "wchar_t width must be 2 or 4 bytes");

765 }

766

767

768

769

770 if (auto EnumWidthValue = mdconst::extract_or_null(

771 SourceModule->getModuleFlag("min_enum_size"))) {

772 int EnumWidth = EnumWidthValue->getZExtValue();

773 assert((EnumWidth == 1 || EnumWidth == 4) &&

774 "Minimum enum width must be 1 or 4 bytes");

775 int EnumBuildAttr = EnumWidth == 1 ? 1 : 2;

777 }

778

779 auto *PACValue = mdconst::extract_or_null(

780 SourceModule->getModuleFlag("sign-return-address"));

781 if (PACValue && PACValue->isOne()) {

782

783

784

785 if (!STI.hasPACBTI()) {

788 }

790 }

791

792 auto *BTIValue = mdconst::extract_or_null(

793 SourceModule->getModuleFlag("branch-target-enforcement"));

794 if (BTIValue && BTIValue->isOne()) {

795

796

797

798 if (!STI.hasPACBTI()) {

801 }

803 }

804 }

805

806

807 if (STI.isRWPI())

810 else if (STI.isR9Reserved())

813 else

816}

817

818

819

821 unsigned LabelId, MCContext &Ctx) {

822

824 + "BF" + Twine(FunctionNumber) + "_" + Twine(LabelId));

825 return Label;

826}

827

829 unsigned LabelId, MCContext &Ctx) {

830

832 + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));

833 return Label;

834}

835

838 switch (Modifier) {

853 }

855}

856

858 unsigned char TargetFlags) {

860 bool IsIndirect =

862

863 if (!IsIndirect)

865

866

873

874 if (!StubSym.getPointer())

877 return MCSym;

880 "Windows is the only supported COFF target");

881

882 bool IsIndirect =

884 if (!IsIndirect)

886

889 Name = "__imp_";

891 Name = ".refptr.";

893

895

901

902 if (!StubSym.getPointer())

904 }

905

906 return MCSym;

909 }

911}

912

917

919

921

922

923

924

925

926

927

928

929

930 auto *ACPC = cast(ACPV);

931 for (const auto *GV : ACPC->promotedGlobals()) {

932 if (!EmittedPromotedGlobalLabels.count(GV)) {

935 EmittedPromotedGlobalLabels.insert(GV);

936 }

937 }

939 }

940

942 if (ACPV->isLSDA()) {

946 cast(ACPV)->getBlockAddress();

949 const GlobalValue *GV = cast(ACPV)->getGV();

950

951

952

954 MCSym = GetARMGVSymbol(GV, TF);

958 } else {

959 assert(ACPV->isExtSymbol() && "unrecognized constant pool value");

960 auto Sym = cast(ACPV)->getSymbol();

962 }

963

964

968

974 PCRelExpr =

980

981

986 }

988 }

990}

991

994 unsigned JTI = MO1.getIndex();

995

996

997

999

1000

1001 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);

1003

1004

1006

1007

1009 const std::vector &JT = MJTI->getJumpTables();

1010 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;

1011

1013

1014

1015

1016

1017

1018

1019

1020

1022

1027

1028

1033 }

1034

1036}

1037

1040 unsigned JTI = MO1.getIndex();

1041

1042

1043

1045

1046

1047 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);

1049

1050

1052 const std::vector &JT = MJTI->getJumpTables();

1053 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;

1054

1058

1060 .addExpr(MBBSymbolExpr)

1062 .addReg(0));

1063 }

1064}

1065

1067 unsigned OffsetWidth) {

1068 assert((OffsetWidth == 1 || OffsetWidth == 2) && "invalid tbb/tbh width");

1070 unsigned JTI = MO1.getIndex();

1071

1074

1075 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);

1077

1078

1080 const std::vector &JT = MJTI->getJumpTables();

1081 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;

1082

1083

1086

1087 for (auto *MBB : JTBBs) {

1090

1091

1092

1093

1094

1095

1096

1097

1098

1099

1100

1108 OutStreamer->emitValue(Expr, OffsetWidth);

1109 }

1110

1111

1112

1114

1115

1117}

1118

1123 const MCSymbol *BranchLabel) const {

1127 switch (BranchInstr->getOpcode()) {

1128 case ARM::BR_JTadd:

1129 case ARM::BR_JTr:

1130 case ARM::tBR_JTr:

1131

1133 BaseLabel = GetARMJTIPICJumpTableLabel(JTI);

1134 break;

1135 case ARM::tTBH_JT:

1136 case ARM::t2TBH_JT:

1137

1140 BaseLabel = BranchLabel;

1141 BaseOffset = 4;

1142 break;

1143 case ARM::tTBB_JT:

1144 case ARM::t2TBB_JT:

1145

1148 BaseLabel = BranchLabel;

1149 BaseOffset = 4;

1150 break;

1151 case ARM::t2BR_JT:

1152

1153 BaseLabel = nullptr;

1155 break;

1156 default:

1158 }

1159

1160 return std::make_tuple(BaseLabel, BaseOffset, BranchLabel, EntrySize);

1161}

1162

1163void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {

1165 "Only instruction which are involved into frame setup code are allowed");

1166

1173

1175 unsigned Opc = MI->getOpcode();

1176 unsigned SrcReg, DstReg;

1177

1178 switch (Opc) {

1179 case ARM::tPUSH:

1180

1181 SrcReg = DstReg = ARM::SP;

1182 break;

1183 case ARM::tLDRpci:

1184 case ARM::t2MOVi16:

1185 case ARM::t2MOVTi16:

1186 case ARM::tMOVi8:

1187 case ARM::tADDi8:

1188 case ARM::tLSLri:

1189

1190

1191

1192

1193

1194

1195

1196

1197

1198

1199

1200

1201

1202

1203

1204

1205 SrcReg = ~0U;

1206 DstReg = MI->getOperand(0).getReg();

1207 break;

1208 default:

1209 SrcReg = MI->getOperand(1).getReg();

1210 DstReg = MI->getOperand(0).getReg();

1211 break;

1212 }

1213

1214

1215 if (MI->mayStore()) {

1216

1217 assert(DstReg == ARM::SP &&

1218 "Only stack pointer as a destination reg is supported");

1219

1221

1222 unsigned StartOp = 2 + 2;

1223

1224 unsigned NumOffset = 0;

1225

1226

1227 unsigned PadBefore = 0;

1228

1229

1230 unsigned PadAfter = 0;

1231

1232 switch (Opc) {

1233 default:

1235 llvm_unreachable("Unsupported opcode for unwinding information");

1236 case ARM::tPUSH:

1237

1238 StartOp = 2; NumOffset = 2;

1239 [[fallthrough]];

1240 case ARM::STMDB_UPD:

1241 case ARM::t2STMDB_UPD:

1242 case ARM::VSTMDDB_UPD:

1243 assert(SrcReg == ARM::SP &&

1244 "Only stack pointer as a source reg is supported");

1245 for (unsigned i = StartOp, NumOps = MI->getNumOperands() - NumOffset;

1246 i != NumOps; ++i) {

1248

1249

1251 continue;

1252

1253

1254

1255

1258 "Pad registers must come before restored ones");

1259 unsigned Width =

1261 PadAfter += Width;

1262 continue;

1263 }

1264

1265

1268 Reg = RemappedReg;

1270 }

1271 break;

1272 case ARM::STR_PRE_IMM:

1273 case ARM::STR_PRE_REG:

1274 case ARM::t2STR_PRE:

1275 assert(MI->getOperand(2).getReg() == ARM::SP &&

1276 "Only stack pointer as a source reg is supported");

1278 SrcReg = RemappedReg;

1279

1281 break;

1282 case ARM::t2STRD_PRE:

1283 assert(MI->getOperand(3).getReg() == ARM::SP &&

1284 "Only stack pointer as a source reg is supported");

1285 SrcReg = MI->getOperand(1).getReg();

1287 SrcReg = RemappedReg;

1289 SrcReg = MI->getOperand(2).getReg();

1291 SrcReg = RemappedReg;

1293 PadBefore = -MI->getOperand(4).getImm() - 8;

1294 break;

1295 }

1297 if (PadBefore)

1299 ATS.emitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);

1300

1301 if (PadAfter)

1303 }

1304 } else {

1305

1306 if (SrcReg == ARM::SP) {

1308 switch (Opc) {

1309 default:

1311 llvm_unreachable("Unsupported opcode for unwinding information");

1312 case ARM::tLDRspi:

1313

1314

1315 return;

1316 case ARM::MOVr:

1317 case ARM::tMOVr:

1319 break;

1320 case ARM::ADDri:

1321 case ARM::t2ADDri:

1322 case ARM::t2ADDri12:

1323 case ARM::t2ADDspImm:

1324 case ARM::t2ADDspImm12:

1325 Offset = -MI->getOperand(2).getImm();

1326 break;

1327 case ARM::SUBri:

1328 case ARM::t2SUBri:

1329 case ARM::t2SUBri12:

1330 case ARM::t2SUBspImm:

1331 case ARM::t2SUBspImm12:

1332 Offset = MI->getOperand(2).getImm();

1333 break;

1334 case ARM::tSUBspi:

1335 Offset = MI->getOperand(2).getImm()*4;

1336 break;

1337 case ARM::tADDspi:

1338 case ARM::tADDrSPi:

1339 Offset = -MI->getOperand(2).getImm()*4;

1340 break;

1341 case ARM::tADDhirr:

1344 break;

1345 }

1346

1349

1350

1352 else if (DstReg == ARM::SP) {

1353

1354

1356 } else {

1357

1358

1360 }

1361 }

1362 } else if (DstReg == ARM::SP) {

1364 llvm_unreachable("Unsupported opcode for unwinding information");

1365 } else {

1367 switch (Opc) {

1368 case ARM::tMOVr:

1369

1370

1371

1373 break;

1374 case ARM::tLDRpci: {

1375

1376

1377 unsigned CPI = MI->getOperand(1).getIndex();

1381 assert(CPI != -1U && "Invalid constpool index");

1382

1383

1388 break;

1389 }

1390 case ARM::t2MOVi16:

1391 Offset = MI->getOperand(1).getImm();

1393 break;

1394 case ARM::t2MOVTi16:

1395 Offset = MI->getOperand(2).getImm();

1397 break;

1398 case ARM::tMOVi8:

1399 Offset = MI->getOperand(2).getImm();

1401 break;

1402 case ARM::tLSLri:

1403 assert(MI->getOperand(3).getImm() == 8 &&

1404 "The shift amount is not equal to 8");

1405 assert(MI->getOperand(2).getReg() == MI->getOperand(0).getReg() &&

1406 "The source register is not equal to the destination register");

1408 break;

1409 case ARM::tADDi8:

1410 assert(MI->getOperand(2).getReg() == MI->getOperand(0).getReg() &&

1411 "The source register is not equal to the destination register");

1412 Offset = MI->getOperand(3).getImm();

1414 break;

1415 case ARM::t2PAC:

1416 case ARM::t2PACBTI:

1418 break;

1419 default:

1421 llvm_unreachable("Unsupported opcode for unwinding information");

1422 }

1423 }

1424 }

1425}

1426

1427

1428

1429#include "ARMGenMCPseudoLowering.inc"

1430

1432

1433

1434

1435

1439

1440

1441 if (InConstantPool && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) {

1443 InConstantPool = false;

1444 }

1445

1446

1449 EmitUnwindingInstruction(MI);

1450

1451

1452 if (MCInst OutInst; lowerPseudoInstExpansion(MI, OutInst)) {

1454 return;

1455 }

1456

1458 "Pseudo flag setting opcode should be expanded early");

1459

1460

1461 unsigned Opc = MI->getOpcode();

1462 switch (Opc) {

1463 case ARM::t2MOVi32imm: llvm_unreachable("Should be lowered by thumb2it pass");

1464 case ARM::DBG_VALUE: llvm_unreachable("Should be handled by generic printing");

1465 case ARM::LEApcrel:

1466 case ARM::tLEApcrel:

1467 case ARM::t2LEApcrel: {

1468

1471 ARM::t2LEApcrel ? ARM::t2ADR

1472 : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR

1473 : ARM::ADR))

1474 .addReg(MI->getOperand(0).getReg())

1476

1477 .addImm(MI->getOperand(2).getImm())

1478 .addReg(MI->getOperand(3).getReg()));

1479 return;

1480 }

1481 case ARM::LEApcrelJT:

1482 case ARM::tLEApcrelJT:

1483 case ARM::t2LEApcrelJT: {

1485 GetARMJTIPICJumpTableLabel(MI->getOperand(1).getIndex());

1487 ARM::t2LEApcrelJT ? ARM::t2ADR

1488 : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR

1489 : ARM::ADR))

1490 .addReg(MI->getOperand(0).getReg())

1492

1493 .addImm(MI->getOperand(2).getImm())

1494 .addReg(MI->getOperand(3).getReg()));

1495 return;

1496 }

1497

1498

1499 case ARM::BX_CALL: {

1501 .addReg(ARM::LR)

1502 .addReg(ARM::PC)

1503

1505 .addReg(0)

1506

1507 .addReg(0));

1508

1509 assert(Subtarget->hasV4TOps());

1511 .addReg(MI->getOperand(0).getReg()));

1512 return;

1513 }

1514 case ARM::tBX_CALL: {

1515 if (Subtarget->hasV5TOps())

1517

1518

1519

1520

1521

1522

1523

1524 Register TReg = MI->getOperand(0).getReg();

1525 MCSymbol *TRegSym = nullptr;

1526 for (std::pair<unsigned, MCSymbol *> &TIP : ThumbIndirectPads) {

1527 if (TIP.first == TReg) {

1528 TRegSym = TIP.second;

1529 break;

1530 }

1531 }

1532

1533 if (!TRegSym) {

1535 ThumbIndirectPads.push_back(std::make_pair(TReg, TRegSym));

1536 }

1537

1538

1540

1543 return;

1544 }

1545 case ARM::BMOVPCRX_CALL: {

1547 .addReg(ARM::LR)

1548 .addReg(ARM::PC)

1549

1551 .addReg(0)

1552

1553 .addReg(0));

1554

1556 .addReg(ARM::PC)

1557 .addReg(MI->getOperand(0).getReg())

1558

1561

1563 return;

1564 }

1565 case ARM::BMOVPCB_CALL: {

1567 .addReg(ARM::LR)

1568 .addReg(ARM::PC)

1569

1571 .addReg(0)

1572

1573 .addReg(0));

1574

1577 const unsigned TF = Op.getTargetFlags();

1578 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);

1581 .addExpr(GVSymExpr)

1582

1584 .addReg(0));

1585 return;

1586 }

1587 case ARM::MOVi16_ga_pcrel:

1588 case ARM::t2MOVi16_ga_pcrel: {

1590 TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16);

1592

1593 unsigned TF = MI->getOperand(1).getTargetFlags();

1594 const GlobalValue *GV = MI->getOperand(1).getGlobal();

1595 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);

1597

1602 unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4;

1603 const MCExpr *PCRelExpr =

1609

1610

1613

1616 return;

1617 }

1618 case ARM::MOVTi16_ga_pcrel:

1619 case ARM::t2MOVTi16_ga_pcrel: {

1621 TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel

1622 ? ARM::MOVTi16 : ARM::t2MOVTi16);

1625

1626 unsigned TF = MI->getOperand(2).getTargetFlags();

1627 const GlobalValue *GV = MI->getOperand(2).getGlobal();

1628 MCSymbol *GVSym = GetARMGVSymbol(GV, TF);

1630

1635 unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4;

1636 const MCExpr *PCRelExpr =

1642

1645

1648 return;

1649 }

1650 case ARM::t2BFi:

1651 case ARM::t2BFic:

1652 case ARM::t2BFLi:

1653 case ARM::t2BFr:

1654 case ARM::t2BFLr: {

1655

1656

1661

1663 if (MI->getOperand(1).isReg()) {

1664

1665 MCInst.addReg(MI->getOperand(1).getReg());

1666 } else {

1667

1668 const MCExpr *BranchTarget;

1669 if (MI->getOperand(1).isMBB())

1672 else if (MI->getOperand(1).isGlobal()) {

1673 const GlobalValue *GV = MI->getOperand(1).getGlobal();

1675 GetARMGVSymbol(GV, MI->getOperand(1).getTargetFlags()), OutContext);

1676 } else if (MI->getOperand(1).isSymbol()) {

1680 } else

1681 llvm_unreachable("Unhandled operand kind in Branch Future instruction");

1682

1683 MCInst.addExpr(BranchTarget);

1684 }

1685

1686 if (Opc == ARM::t2BFic) {

1691 MCInst.addExpr(ElseLabel);

1692 MCInst.addImm(MI->getOperand(3).getImm());

1693 } else {

1694 MCInst.addImm(MI->getOperand(2).getImm())

1695 .addReg(MI->getOperand(3).getReg());

1696 }

1697

1699 return;

1700 }

1701 case ARM::t2BF_LabelPseudo: {

1702

1703

1704

1708 return;

1709 }

1710 case ARM::tPICADD: {

1711

1712

1713

1714

1715

1716

1720

1721

1723 .addReg(MI->getOperand(0).getReg())

1724 .addReg(MI->getOperand(0).getReg())

1726

1729 return;

1730 }

1731 case ARM::PICADD: {

1732

1733

1734

1735

1736

1737

1741

1742

1744 .addReg(MI->getOperand(0).getReg())

1746 .addReg(MI->getOperand(1).getReg())

1747

1748 .addImm(MI->getOperand(3).getImm())

1749 .addReg(MI->getOperand(4).getReg())

1750

1752 return;

1753 }

1754 case ARM::PICSTR:

1755 case ARM::PICSTRB:

1756 case ARM::PICSTRH:

1757 case ARM::PICLDR:

1758 case ARM::PICLDRB:

1759 case ARM::PICLDRH:

1760 case ARM::PICLDRSB:

1761 case ARM::PICLDRSH: {

1762

1763

1764

1765

1766

1767

1768

1772

1773

1774 unsigned Opcode;

1775 switch (MI->getOpcode()) {

1776 default:

1778 case ARM::PICSTR: Opcode = ARM::STRrs; break;

1779 case ARM::PICSTRB: Opcode = ARM::STRBrs; break;

1780 case ARM::PICSTRH: Opcode = ARM::STRH; break;

1781 case ARM::PICLDR: Opcode = ARM::LDRrs; break;

1782 case ARM::PICLDRB: Opcode = ARM::LDRBrs; break;

1783 case ARM::PICLDRH: Opcode = ARM::LDRH; break;

1784 case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;

1785 case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;

1786 }

1788 .addReg(MI->getOperand(0).getReg())

1790 .addReg(MI->getOperand(1).getReg())

1792

1793 .addImm(MI->getOperand(3).getImm())

1794 .addReg(MI->getOperand(4).getReg()));

1795

1796 return;

1797 }

1798 case ARM::CONSTPOOL_ENTRY: {

1799 if (Subtarget->genExecuteOnly())

1800 llvm_unreachable("execute-only should not generate constant pools");

1801

1802

1803

1804

1805

1806

1807 unsigned LabelId = (unsigned)MI->getOperand(0).getImm();

1808 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();

1809

1810

1811 if (!InConstantPool) {

1813 InConstantPool = true;

1814 }

1815

1817

1821 else

1823 return;

1824 }

1825 case ARM::JUMPTABLE_ADDRS:

1827 return;

1828 case ARM::JUMPTABLE_INSTS:

1830 return;

1831 case ARM::JUMPTABLE_TBB:

1832 case ARM::JUMPTABLE_TBH:

1834 return;

1835 case ARM::t2BR_JT: {

1837 .addReg(ARM::PC)

1838 .addReg(MI->getOperand(0).getReg())

1839

1842 return;

1843 }

1844 case ARM::t2TBB_JT:

1845 case ARM::t2TBH_JT: {

1846 unsigned Opc = MI->getOpcode() == ARM::t2TBB_JT ? ARM::t2TBB : ARM::t2TBH;

1847

1850 .addReg(MI->getOperand(0).getReg())

1851 .addReg(MI->getOperand(1).getReg())

1852

1855 return;

1856 }

1857 case ARM::tTBB_JT:

1858 case ARM::tTBH_JT: {

1859

1860 bool Is8Bit = MI->getOpcode() == ARM::tTBB_JT;

1863 assert(MI->getOperand(1).isKill() && "We need the index register as scratch!");

1864

1865

1866 if (!Is8Bit)

1868 .addReg(Idx)

1869 .addReg(ARM::CPSR)

1870 .addReg(Idx)

1871 .addImm(1)

1872

1874 .addReg(0));

1875

1876 if (Base == ARM::PC) {

1877

1878

1879

1880

1881

1882

1883

1884

1885

1886

1887

1888

1889

1892 .addReg(Idx)

1893 .addReg(Idx)

1894 .addReg(Base)

1895

1897 .addReg(0));

1898

1899 unsigned Opc = Is8Bit ? ARM::tLDRBi : ARM::tLDRHi;

1901 .addReg(Idx)

1902 .addReg(Idx)

1903 .addImm(Is8Bit ? 4 : 2)

1904

1906 .addReg(0));

1907 } else {

1908

1909

1910

1911

1912

1913 unsigned Opc = Is8Bit ? ARM::tLDRBr : ARM::tLDRHr;

1915 .addReg(Idx)

1916 .addReg(Base)

1917 .addReg(Idx)

1918

1920 .addReg(0));

1921 }

1922

1924 .addReg(Idx)

1925 .addReg(ARM::CPSR)

1926 .addReg(Idx)

1927 .addImm(1)

1928

1930 .addReg(0));

1931

1934 .addReg(ARM::PC)

1935 .addReg(ARM::PC)

1936 .addReg(Idx)

1937

1939 .addReg(0));

1940 return;

1941 }

1942 case ARM::tBR_JTr:

1943 case ARM::BR_JTr: {

1944

1946 unsigned Opc = MI->getOpcode() == ARM::BR_JTr ?

1947 ARM::MOVr : ARM::tMOVr;

1951

1954

1955 if (Opc == ARM::MOVr)

1958 return;

1959 }

1960 case ARM::BR_JTm_i12: {

1961

1967

1971 return;

1972 }

1973 case ARM::BR_JTm_rs: {

1974

1981

1985 return;

1986 }

1987 case ARM::BR_JTadd: {

1988

1990 .addReg(ARM::PC)

1991 .addReg(MI->getOperand(0).getReg())

1992 .addReg(MI->getOperand(1).getReg())

1993

1996

1998 return;

1999 }

2000 case ARM::SPACE:

2001 OutStreamer->emitZeros(MI->getOperand(1).getImm());

2002 return;

2003 case ARM::TRAP: {

2004

2005

2007 uint32_t Val = 0xe7ffdefeUL;

2010 return;

2011 }

2012 break;

2013 }

2014 case ARM::TRAPNaCl: {

2015 uint32_t Val = 0xe7fedef0UL;

2018 return;

2019 }

2020 case ARM::tTRAP: {

2021

2022

2027 return;

2028 }

2029 break;

2030 }

2031 case ARM::t2Int_eh_sjlj_setjmp:

2032 case ARM::t2Int_eh_sjlj_setjmp_nofp:

2033 case ARM::tInt_eh_sjlj_setjmp: {

2034

2035

2036

2037

2038

2039

2040

2041

2042 Register SrcReg = MI->getOperand(0).getReg();

2043 Register ValReg = MI->getOperand(1).getReg();

2045 OutStreamer->AddComment("eh_setjmp begin");

2047 .addReg(ValReg)

2048 .addReg(ARM::PC)

2049

2051 .addReg(0));

2052

2054 .addReg(ValReg)

2055

2056 .addReg(ARM::CPSR)

2057 .addReg(ValReg)

2058 .addImm(7)

2059

2061 .addReg(0));

2062

2064 .addReg(ValReg)

2065 .addReg(SrcReg)

2066

2067

2068 .addImm(1)

2069

2071 .addReg(0));

2072

2074 .addReg(ARM::R0)

2075 .addReg(ARM::CPSR)

2076 .addImm(0)

2077

2079 .addReg(0));

2080

2083 .addExpr(SymbolExpr)

2085 .addReg(0));

2086

2087 OutStreamer->AddComment("eh_setjmp end");

2089 .addReg(ARM::R0)

2090 .addReg(ARM::CPSR)

2091 .addImm(1)

2092

2094 .addReg(0));

2095

2097 return;

2098 }

2099

2100 case ARM::Int_eh_sjlj_setjmp_nofp:

2101 case ARM::Int_eh_sjlj_setjmp: {

2102

2103

2104

2105

2106

2107

2108 Register SrcReg = MI->getOperand(0).getReg();

2109 Register ValReg = MI->getOperand(1).getReg();

2110

2111 OutStreamer->AddComment("eh_setjmp begin");

2113 .addReg(ValReg)

2114 .addReg(ARM::PC)

2115 .addImm(8)

2116

2118 .addReg(0)

2119

2120 .addReg(0));

2121

2123 .addReg(ValReg)

2124 .addReg(SrcReg)

2125 .addImm(4)

2126

2128 .addReg(0));

2129

2131 .addReg(ARM::R0)

2132 .addImm(0)

2133

2135 .addReg(0)

2136

2137 .addReg(0));

2138

2140 .addReg(ARM::PC)

2141 .addReg(ARM::PC)

2142 .addImm(0)

2143

2145 .addReg(0)

2146

2147 .addReg(0));

2148

2149 OutStreamer->AddComment("eh_setjmp end");

2151 .addReg(ARM::R0)

2152 .addImm(1)

2153

2155 .addReg(0)

2156

2157 .addReg(0));

2158 return;

2159 }

2160 case ARM::Int_eh_sjlj_longjmp: {

2161

2162

2163

2164

2165 Register SrcReg = MI->getOperand(0).getReg();

2166 Register ScratchReg = MI->getOperand(1).getReg();

2168 .addReg(ARM::SP)

2169 .addReg(SrcReg)

2170 .addImm(8)

2171

2173 .addReg(0));

2174

2176 .addReg(ScratchReg)

2177 .addReg(SrcReg)

2178 .addImm(4)

2179

2181 .addReg(0));

2182

2185

2187

2192

2195 } else {

2196

2197

2199 .addReg(ARM::R7)

2200 .addReg(SrcReg)

2201 .addImm(0)

2202

2204 .addReg(0));

2206 .addReg(ARM::R11)

2207 .addReg(SrcReg)

2208 .addImm(0)

2209

2211 .addReg(0));

2212 }

2213

2214 assert(Subtarget->hasV4TOps());

2216 .addReg(ScratchReg)

2217

2219 .addReg(0));

2220 return;

2221 }

2222 case ARM::tInt_eh_sjlj_longjmp: {

2223

2224

2225

2226

2227

2228 Register SrcReg = MI->getOperand(0).getReg();

2229 Register ScratchReg = MI->getOperand(1).getReg();

2230

2233

2235 .addReg(ScratchReg)

2236 .addReg(SrcReg)

2237

2238

2239 .addImm(2)

2240

2242 .addReg(0));

2243

2245 .addReg(ARM::SP)

2246 .addReg(ScratchReg)

2247

2249 .addReg(0));

2250

2252 .addReg(ScratchReg)

2253 .addReg(SrcReg)

2254 .addImm(1)

2255

2257 .addReg(0));

2258

2260

2265

2268 } else {

2269

2270

2272 .addReg(ARM::R7)

2273 .addReg(SrcReg)

2274 .addImm(0)

2275

2277 .addReg(0));

2279 .addReg(ARM::R11)

2280 .addReg(SrcReg)

2281 .addImm(0)

2282

2284 .addReg(0));

2285 }

2286

2288 .addReg(ScratchReg)

2289

2291 .addReg(0));

2292 return;

2293 }

2294 case ARM::tInt_WIN_eh_sjlj_longjmp: {

2295

2296

2297

2298

2299 Register SrcReg = MI->getOperand(0).getReg();

2300

2302 .addReg(ARM::R11)

2303 .addReg(SrcReg)

2304 .addImm(0)

2305

2307 .addReg(0));

2309 .addReg(ARM::SP)

2310 .addReg(SrcReg)

2311 .addImm(8)

2312

2314 .addReg(0));

2316 .addReg(ARM::PC)

2317 .addReg(SrcReg)

2318 .addImm(4)

2319

2321 .addReg(0));

2322 return;

2323 }

2324 case ARM::PATCHABLE_FUNCTION_ENTER:

2326 return;

2327 case ARM::PATCHABLE_FUNCTION_EXIT:

2329 return;

2330 case ARM::PATCHABLE_TAIL_CALL:

2332 return;

2333 case ARM::SpeculationBarrierISBDSBEndBB: {

2334

2343 return;

2344 }

2345 case ARM::t2SpeculationBarrierISBDSBEndBB: {

2346

2348 TmpInstDSB.setOpcode(ARM::t2DSB);

2354 TmpInstISB.setOpcode(ARM::t2ISB);

2359 return;

2360 }

2361 case ARM::SpeculationBarrierSBEndBB: {

2362

2366 return;

2367 }

2368 case ARM::t2SpeculationBarrierSBEndBB: {

2369

2373 return;

2374 }

2375

2376 case ARM::SEH_StackAlloc:

2378 MI->getOperand(1).getImm());

2379 return;

2380

2381 case ARM::SEH_SaveRegs:

2382 case ARM::SEH_SaveRegs_Ret:

2384 MI->getOperand(1).getImm());

2385 return;

2386

2387 case ARM::SEH_SaveSP:

2389 return;

2390

2391 case ARM::SEH_SaveFRegs:

2393 MI->getOperand(1).getImm());

2394 return;

2395

2396 case ARM::SEH_SaveLR:

2398 return;

2399

2400 case ARM::SEH_Nop:

2401 case ARM::SEH_Nop_Ret:

2403 return;

2404

2405 case ARM::SEH_PrologEnd:

2407 return;

2408

2409 case ARM::SEH_EpilogStart:

2411 return;

2412

2413 case ARM::SEH_EpilogEnd:

2415 return;

2416 }

2417

2420

2422}

2423

2424

2425

2426

2427

2428

2434}

static void emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, MachineModuleInfoImpl::StubValueTy &MCSym)

static MCSymbolRefExpr::VariantKind getModifierVariantKind(ARMCP::ARMCPModifier Modifier)

static MCSymbol * getPICLabel(StringRef Prefix, unsigned FunctionNumber, unsigned LabelId, MCContext &Ctx)

LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMAsmPrinter()

static bool checkFunctionsAttributeConsistency(const Module &M, StringRef Attr, StringRef Value)

static bool isThumb(const MCSubtargetInfo &STI)

static MCSymbol * getBFLabel(StringRef Prefix, unsigned FunctionNumber, unsigned LabelId, MCContext &Ctx)

static bool checkDenormalAttributeConsistency(const Module &M, StringRef Attr, DenormalMode Value)

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

#define LLVM_EXTERNAL_VISIBILITY

This file contains the declarations for the subclasses of Constant, which represent the different fla...

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")

Module.h This file contains the declarations for the Module class.

unsigned const TargetRegisterInfo * TRI

static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)

This file defines the SmallString class.

static const unsigned FramePtr

void emitJumpTableAddrs(const MachineInstr *MI)

void emitJumpTableTBInst(const MachineInstr *MI, unsigned OffsetWidth)

void emitFunctionBodyEnd() override

Targets can override this to emit stuff after the last basic block in the function.

bool runOnMachineFunction(MachineFunction &F) override

runOnMachineFunction - This uses the emitInstruction() method to print assembly for each instruction.

MCSymbol * GetCPISymbol(unsigned CPID) const override

Return the symbol for the specified constant pool entry.

void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O)

void emitStartOfAsmFile(Module &M) override

This virtual method can be overridden by targets that want to emit something at the start of their fi...

ARMAsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer)

void emitFunctionEntryLabel() override

EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.

void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, const MCSubtargetInfo *EndInfo) const override

Let the target do anything it needs to do after emitting inlineasm.

void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI)

void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override

EmitMachineConstantPoolValue - Print a machine constantpool value to the .s file.

bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override

Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.

void emitXXStructor(const DataLayout &DL, const Constant *CV) override

Targets can override this to change how global constants that are part of a C++ static/global constru...

void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI)

void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI)

void emitEndOfAsmFile(Module &M) override

This virtual method can be overridden by targets that want to emit something at the end of their file...

std::tuple< const MCSymbol *, uint64_t, const MCSymbol *, codeview::JumpTableEntrySize > getCodeViewJumpTableInfo(int JTI, const MachineInstr *BranchInstr, const MCSymbol *BranchLabel) const override

Gets information required to create a CodeView debug symbol for a jump table.

void emitJumpTableInsts(const MachineInstr *MI)

void emitGlobalVariable(const GlobalVariable *GV) override

Emit the specified global variable to the .s file.

bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override

Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...

void emitInstruction(const MachineInstr *MI) override

Targets should implement this to emit instructions.

void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override

Print the MachineOperand as a symbol.

bool isLittleEndian() const

ARMConstantPoolValue - ARM specific constantpool value.

bool isPromotedGlobal() const

unsigned char getPCAdjustment() const

bool isMachineBasicBlock() const

bool isGlobalValue() const

ARMCP::ARMCPModifier getModifier() const

bool mustAddCurrentAddress() const

unsigned getLabelId() const

bool isBlockAddress() const

ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...

SmallPtrSet< const GlobalVariable *, 2 > & getGlobalsPromotedToConstantPool()

DenseMap< unsigned, unsigned > EHPrologueRemappedRegs

bool isThumbFunction() const

bool isCmseNSEntryFunction() const

DenseMap< unsigned, unsigned > EHPrologueOffsetInRegs

unsigned getOriginalCPIdx(unsigned CloneIdx) const

static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=ARM::NoRegAltName)

static const ARMMCExpr * createLower16(const MCExpr *Expr, MCContext &Ctx)

static const ARMMCExpr * createUpper16(const MCExpr *Expr, MCContext &Ctx)

bool isTargetMachO() const

bool isTargetAEABI() const

bool isThumb1Only() const

MCPhysReg getFramePointerReg() const

bool isTargetWindows() const

bool isTargetEHABICompatible() const

bool isGVIndirectSymbol(const GlobalValue *GV) const

True if the GV will be accessed via an indirect symbol.

bool isTargetDarwin() const

bool isTargetCOFF() const

bool isTargetGNUAEABI() const

bool isTargetMuslAEABI() const

void emitTargetAttributes(const MCSubtargetInfo &STI)

Emit the build attributes that only depend on the hardware that we expect.

virtual void emitSetFP(MCRegister FpReg, MCRegister SpReg, int64_t Offset=0)

virtual void finishAttributeSection()

virtual void emitMovSP(MCRegister Reg, int64_t Offset=0)

virtual void emitARMWinCFISaveSP(unsigned Reg)

virtual void emitInst(uint32_t Inst, char Suffix='\0')

virtual void emitARMWinCFISaveLR(unsigned Offset)

virtual void emitTextAttribute(unsigned Attribute, StringRef String)

virtual void emitARMWinCFIAllocStack(unsigned Size, bool Wide)

virtual void emitARMWinCFISaveRegMask(unsigned Mask, bool Wide)

virtual void emitRegSave(const SmallVectorImpl< MCRegister > &RegList, bool isVector)

virtual void emitARMWinCFIEpilogEnd()

virtual void emitARMWinCFIPrologEnd(bool Fragment)

virtual void switchVendor(StringRef Vendor)

virtual void emitARMWinCFISaveFRegs(unsigned First, unsigned Last)

virtual void emitARMWinCFIEpilogStart(unsigned Condition)

virtual void emitPad(int64_t Offset)

virtual void emitAttribute(unsigned Attribute, unsigned Value)

virtual void emitARMWinCFINop(bool Wide)

This class is intended to be used as a driving class for all asm writers.

const TargetLoweringObjectFile & getObjFileLowering() const

Return information about object file lowering.

MCSymbol * getSymbolWithGlobalValueBase(const GlobalValue *GV, StringRef Suffix) const

Return the MCSymbol for a private symbol with global value name as its base, with the specified suffi...

MCSymbol * getSymbol(const GlobalValue *GV) const

void EmitToStreamer(MCStreamer &S, const MCInst &Inst)

virtual void emitGlobalVariable(const GlobalVariable *GV)

Emit the specified global variable to the .s file.

TargetMachine & TM

Target machine description.

void emitXRayTable()

Emit a table with all XRay instrumentation points.

MCSymbol * getMBBExceptionSym(const MachineBasicBlock &MBB)

const MCAsmInfo * MAI

Target Asm Printer information.

MachineFunction * MF

The current machine function.

virtual void SetupMachineFunction(MachineFunction &MF)

This should be called when a new MachineFunction is being processed from runOnMachineFunction.

void emitFunctionBody()

This method emits the body and trailer for a function.

virtual void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const

This emits linkage information about GVSym based on GV, if this is supported by the target.

unsigned getFunctionNumber() const

Return a unique ID for the current function.

void printOffset(int64_t Offset, raw_ostream &OS) const

This is just convenient handler for printing offsets.

void emitGlobalConstant(const DataLayout &DL, const Constant *CV, AliasMapTy *AliasList=nullptr)

EmitGlobalConstant - Print a general LLVM constant to the .s file.

MCSymbol * getSymbolPreferLocal(const GlobalValue &GV) const

Similar to getSymbol() but preferred for references.

MCSymbol * CurrentFnSym

The symbol for the current function.

MachineModuleInfo * MMI

This is a pointer to the current MachineModuleInfo.

void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr, unsigned MaxBytesToEmit=0) const

Emit an alignment directive to the specified power of two boundary.

MCContext & OutContext

This is the context for the output file that we are streaming.

MCSymbol * GetExternalSymbolSymbol(Twine Sym) const

Return the MCSymbol for the specified ExternalSymbol.

bool isPositionIndependent() const

std::unique_ptr< MCStreamer > OutStreamer

This is the MCStreamer object for the file we are generating.

void getNameWithPrefix(SmallVectorImpl< char > &Name, const GlobalValue *GV) const

MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const

Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.

const DataLayout & getDataLayout() const

Return information about data layout.

virtual void emitFunctionEntryLabel()

EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.

const MCSubtargetInfo & getSubtargetInfo() const

Return information about subtarget.

virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)

Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.

The address of a basic block.

This is an important base class in LLVM.

const Constant * stripPointerCasts() const

This class represents an Operation in the Expression.

A parsed version of the target data layout string in and methods for querying it.

TypeSize getTypeAllocSize(Type *Ty) const

Returns the offset in bytes between successive objects of the specified type, including alignment pad...

ValueT lookup(const_arg_type_t< KeyT > Val) const

lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...

bool isThreadLocal() const

If the value is "Thread Local", its value isn't shared by the threads.

bool hasInternalLinkage() const

ExceptionHandling getExceptionHandlingType() const

static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)

static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)

static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)

static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

MCSymbol * createTempSymbol()

Create a temporary symbol with a unique name.

MCSymbol * getOrCreateSymbol(const Twine &Name)

Lookup the symbol inside with the specified Name.

Base class for the full range of assembler expressions which are needed for parsing.

MCInstBuilder & addReg(MCRegister Reg)

Add a new register operand.

MCInstBuilder & addImm(int64_t Val)

Add a new integer immediate operand.

MCInstBuilder & addExpr(const MCExpr *Val)

Add a new MCExpr operand.

Instances of this class represent a single low-level machine instruction.

void addOperand(const MCOperand Op)

void setOpcode(unsigned Op)

MCSection * getThreadLocalPointerSection() const

MCSection * getNonLazySymbolPointerSection() const

static MCOperand createExpr(const MCExpr *Val)

static MCOperand createReg(MCRegister Reg)

static MCOperand createImm(int64_t Val)

Wrapper class representing physical registers. Should be passed by value.

Streaming machine code generation interface.

virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0

Add the given Attribute to Symbol.

MCContext & getContext() const

void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())

virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())

Emit a label for Symbol into the current section.

virtual void emitIntValue(uint64_t Value, unsigned Size)

Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.

Generic base class for all target subtargets.

bool hasFeature(unsigned Feature) const

static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

void print(raw_ostream &OS, const MCAsmInfo *MAI) const

print - Print the value to the stream OS.

StringRef getName() const

getName - Get the symbol name.

Target specific streamer interface.

MCSymbol * getSymbol() const

Return the MCSymbol for this basic block.

This class is a data container for one entry in a MachineConstantPool.

bool isMachineConstantPoolEntry() const

isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry is indeed a target specific ...

union llvm::MachineConstantPoolEntry::@204 Val

The constant itself.

MachineConstantPoolValue * MachineCPVal

const Constant * ConstVal

Abstract base class for all machine specific constantpool value subclasses.

The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...

const std::vector< MachineConstantPoolEntry > & getConstants() const

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Function & getFunction()

Return the LLVM function that this machine code represents.

Ty * getInfo()

getInfo - Keep track of various per-function pieces of information for backends that would like to do...

MachineConstantPool * getConstantPool()

getConstantPool - Return the constant pool object for the current function.

const MachineBasicBlock & front() const

const MachineJumpTableInfo * getJumpTableInfo() const

getJumpTableInfo - Return the jump table info object for the current function.

const TargetMachine & getTarget() const

getTarget - Return the target machine this machine code is compiled with

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

const MachineOperand & getOperand(unsigned i) const

const std::vector< MachineJumpTableEntry > & getJumpTables() const

MachineModuleInfoCOFF - This is a MachineModuleInfoImpl implementation for COFF targets.

StubValueTy & getGVStubEntry(MCSymbol *Sym)

std::vector< std::pair< MCSymbol *, StubValueTy > > SymbolListTy

MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation for MachO targets.

SymbolListTy GetThreadLocalGVStubList()

StubValueTy & getGVStubEntry(MCSymbol *Sym)

StubValueTy & getThreadLocalGVStubEntry(MCSymbol *Sym)

SymbolListTy GetGVStubList()

Accessor methods to return the set of stubs in sorted order.

const Module * getModule() const

Ty & getObjFileInfo()

Keep track of various per-module pieces of information for backends that would like to do so.

MachineOperand class - Representation of each machine instruction operand.

unsigned getSubReg() const

const GlobalValue * getGlobal() const

bool isReg() const

isReg - Tests if this is a MO_Register operand.

MachineBasicBlock * getMBB() const

bool isImm() const

isImm - Tests if this is a MO_Immediate operand.

unsigned getTargetFlags() const

bool isGlobal() const

isGlobal - Tests if this is a MO_GlobalAddress operand.

MachineOperandType getType() const

getType - Returns the MachineOperandType for this operand.

Register getReg() const

getReg - Returns the register number.

@ MO_Immediate

Immediate operand.

@ MO_ConstantPoolIndex

Address of indexed Constant in Constant Pool.

@ MO_GlobalAddress

Address of a global value.

@ MO_MachineBasicBlock

MachineBasicBlock reference.

@ MO_Register

Register operand.

int64_t getOffset() const

Return the offset from the symbol in this operand.

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

A Module instance is used to store all the information related to an LLVM module.

virtual void print(raw_ostream &OS, const Module *M) const

print - Print out the internal state of the pass.

PointerIntPair - This class implements a pair of a pointer and small integer.

PointerTy getPointer() const

Wrapper class representing virtual and physical registers.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

Primary interface to the complete machine description for the target machine.

CodeGenOptLevel getOptLevel() const

Returns the optimization level: None, Less, Default, or Aggressive.

const Triple & getTargetTriple() const

StringRef getTargetFeatureString() const

StringRef getTargetCPU() const

unsigned UnsafeFPMath

UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...

FloatABI::ABIType FloatABIType

FloatABIType - This setting is set by -float-abi=xxx option is specfied on the command line.

unsigned NoInfsFPMath

NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...

unsigned HonorSignDependentRoundingFPMathOption

HonorSignDependentRoundingFPMath - This returns true when the -enable-sign-dependent-rounding-fp-math...

unsigned NoNaNsFPMath

NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...

unsigned NoTrappingFPMath

NoTrappingFPMath - This flag is enabled when the -enable-no-trapping-fp-math is specified on the comm...

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

TypeSize getRegSizeInBits(const TargetRegisterClass &RC) const

Return the size in bits of a register from class RC.

virtual Register getFrameRegister(const MachineFunction &MF) const =0

Debug information queries.

virtual const TargetRegisterInfo * getRegisterInfo() const

getRegisterInfo - If register information is available, return it.

Triple - Helper class for working with autoconf configuration names.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

The instances of the Type class are immutable: once they are created, they are never changed.

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

This class implements an extremely fast bulk output stream that can only output to a stream.

A raw_ostream that writes to an SmallVector or SmallString.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ SECREL

Thread Pointer Offset.

@ GOT_PREL

Thread Local Storage (General Dynamic Mode)

@ SBREL

Section Relative (Windows TLS)

@ GOTTPOFF

Global Offset Table, PC Relative.

@ TPOFF

Global Offset Table, Thread Pointer Offset.

@ MO_LO16

MO_LO16 - On a symbol operand, this represents a relocation containing lower 16 bit of the address.

@ MO_LO_0_7

MO_LO_0_7 - On a symbol operand, this represents a relocation containing bits 0 through 7 of the addr...

@ MO_LO_8_15

MO_LO_8_15 - On a symbol operand, this represents a relocation containing bits 8 through 15 of the ad...

@ MO_NONLAZY

MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which,...

@ MO_HI_8_15

MO_HI_8_15 - On a symbol operand, this represents a relocation containing bits 24 through 31 of the a...

@ MO_HI16

MO_HI16 - On a symbol operand, this represents a relocation containing higher 16 bit of the address.

@ MO_DLLIMPORT

MO_DLLIMPORT - On a symbol operand, this represents that the reference to the symbol is for an import...

@ MO_HI_0_7

MO_HI_0_7 - On a symbol operand, this represents a relocation containing bits 16 through 23 of the ad...

@ MO_COFFSTUB

MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....

std::string ParseARMTriple(const Triple &TT, StringRef CPU)

SymbolStorageClass

Storage class tells where and what the symbol represents.

@ IMAGE_SYM_CLASS_EXTERNAL

External symbol.

@ IMAGE_SYM_CLASS_STATIC

Static.

@ IMAGE_SYM_DTYPE_FUNCTION

A function that returns a base type.

@ SCT_COMPLEX_TYPE_SHIFT

Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))

Reg

All possible values of the reg field in the ModR/M byte.

This is an optimization pass for GlobalISel generic memory operations.

Target & getTheThumbBETarget()

@ MCDR_DataRegionEnd

.end_data_region

@ MCDR_DataRegion

.data_region

@ MCDR_DataRegionJT8

.data_region jt8

@ MCDR_DataRegionJT32

.data_region jt32

@ MCDR_DataRegionJT16

.data_region jt16

bool any_of(R &&range, UnaryPredicate P)

Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.

raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, ARMAsmPrinter &AP)

@ MCAF_SyntaxUnified

.syntax (ARM/ELF)

@ MCAF_Code16

.code16 (X86) / .code 16 (ARM)

@ MCAF_Code32

.code32 (X86) / .code 32 (ARM)

@ MCAF_SubsectionsViaSymbols

.subsections_via_symbols (MachO)

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

DenormalMode parseDenormalFPAttribute(StringRef Str)

Returns the denormal mode to use for inputs and outputs.

Target & getTheARMLETarget()

unsigned convertAddSubFlagsOpcode(unsigned OldOpc)

Map pseudo instructions that imply an 'S' bit onto real opcodes.

@ MCSA_IndirectSymbol

.indirect_symbol (MachO)

@ MCSA_ELF_TypeFunction

.type _foo, STT_FUNC # aka @function

Target & getTheARMBETarget()

Target & getTheThumbLETarget()

Implement std::hash so that hash_code can be used in STL containers.

This struct is a compact representation of a valid (non-zero power of two) alignment.

Represent subnormal handling kind for floating point instruction inputs and outputs.

static constexpr DenormalMode getPositiveZero()

static constexpr DenormalMode getPreserveSign()

RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...