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

1

2

3

4

5

6

7

8

9

10

11

12

13

48using namespace llvm;

49

50#define DEBUG_TYPE "asm-printer"

51

53 std::unique_ptr Streamer)

55 InConstantPool(false), OptimizationGoals(-1) {}

56

60

62

63

64 if (!InConstantPool)

65 return;

66 InConstantPool = false;

68}

69

71 auto &TS =

73 if (AFI->isThumbFunction()) {

74 TS.emitCode16();

76 } else {

77 TS.emitCode32();

78 }

79

80

81 if (AFI->isCmseNSEntryFunction()) {

87 }

89}

90

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

94

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

97

102

104}

105

106

107void ARMAsmPrinter::emitCMSEVeneerAlias(const GlobalAlias &GA) {

109 if (!BaseFn || !BaseFn->hasFnAttribute("cmse_nonsecure_entry"))

110 return;

111

114

119

120

124

125

127 OutStreamer->emitAssignment(SEAliasSym, SEExpr);

128}

129

132 emitCMSEVeneerAlias(GA);

133}

134

136 if (PromotedGlobals.count(GV))

137

138 return;

140}

141

142

143

144

147 MCP = MF.getConstantPool();

148

152

153

154

155

156 PromotedGlobals.insert_range(AFI->getGlobalsPromotedToConstantPool());

157

158

159 unsigned OptimizationGoal;

160 if (F.hasOptNone())

161

162 OptimizationGoal = 6;

163 else if (F.hasMinSize())

164

165 OptimizationGoal = 4;

166 else if (F.hasOptSize())

167

168 OptimizationGoal = 3;

170

171 OptimizationGoal = 2;

173

174 OptimizationGoal = 1;

175 else

176

177 OptimizationGoal = 5;

178

179

180 if (OptimizationGoals == -1)

181 OptimizationGoals = OptimizationGoal;

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

183 OptimizationGoals = 0;

184

185 if (TM.getTargetTriple().isOSBinFormatCOFF()) {

186 bool Local = F.hasLocalLinkage();

190

192 OutStreamer->emitCOFFSymbolStorageClass(Scl);

195 }

196

197

199

200

202

203

204

205

206 if (! ThumbIndirectPads.empty()) {

207 auto &TS =

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

214 .addReg(TIP.first)

215

218 }

219 ThumbIndirectPads.clear();

220 }

221

222

223 return false;

224}

225

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

231 O << ":lower16:";

233 O << ":upper16:";

235 O << ":lower0_7:";

237 O << ":lower8_15:";

239 O << ":upper0_7:";

241 O << ":upper8_15:";

242

243 GetARMGVSymbol(MO.getGlobal(), TF)->print(O, MAI);

245}

246

250

255 assert(Reg.isPhysical());

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

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

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

261 }

263 break;

264 }

266 O << '#';

269 O << ":lower16:";

271 O << ":upper16:";

273 O << ":lower0_7:";

275 O << ":lower8_15:";

277 O << ":upper0_7:";

279 O << ":upper8_15:";

281 break;

282 }

285 return;

288 break;

289 }

292 "execute-only should not generate constant pools");

294 break;

295 }

296}

297

299

300

302 return OutContext.getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +

305}

306

307

308

310GetARMJTIPICJumpTableLabel(unsigned uid) const {

316}

317

320

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

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

323

324 switch (ExtraCode[0]) {

325 default:

326

328 case 'P':

329 case 'q':

331 return false;

332 case 'y':

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

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

336

337

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

340 continue;

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

343 return false;

344 }

345 }

346 return true;

347 case 'B':

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

349 return true;

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

351 return false;

352 case 'L':

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

354 return true;

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

356 return false;

357 case 'M': {

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

359 return true;

362

363

364

365 O << "{";

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

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

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

371 }

373

374

375

376

377

378 unsigned RegOps = OpNum + 1;

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

380 O << ", "

382 RegOps++;

383 }

384

385 O << "}";

386

387 return false;

388 }

389 case 'R':

390 case 'Q': {

391 if (OpNum == 0)

392 return true;

394 if (!FlagsOP.isImm())

395 return true;

397

398

399

400

401 unsigned TiedIdx;

402 if (F.isUseOperandTiedToDef(TiedIdx)) {

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

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

407 }

409

410

411

412 OpNum += 1;

413 }

414

415 const unsigned NumVals = F.getNumOperandRegisters();

416 unsigned RC;

417 bool FirstHalf;

420

421

422

423

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

426 else

427

430 if (F.hasRegClassConstraint(RC) &&

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

432 if (NumVals != 1)

433 return true;

436 return true;

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

441 return false;

442 }

443 if (NumVals != 2)

444 return true;

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

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

447 return true;

450 return true;

453 return false;

454 }

455

456 case 'e':

457 case 'f': {

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

459 return true;

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

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

462 return true;

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

467 return false;

468 }

469

470

471 case 'h':

472 return true;

473 case 'H': {

476 return true;

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

481 return false;

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

484 return false;

485 }

486 }

487 }

488

490 return false;

491}

492

494 unsigned OpNum, const char *ExtraCode,

496

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

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

499

500 switch (ExtraCode[0]) {

501 case 'A':

502 default: return true;

503 case 'm':

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

505 return true;

507 return false;

508 }

509 }

510

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

514 return false;

515}

516

520

523

524

525 const bool WasThumb = isThumb(StartInfo);

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

527 auto &TS =

529 if (WasThumb)

531 else

532 TS.emitCode32();

533 }

534}

535

537 const Triple &TT = TM.getTargetTriple();

538 auto &TS =

540

542

543

544 if (TT.isOSBinFormatELF())

545 emitAttributes();

546

547

548

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

550 TS.emitCode16();

551}

552

553static void

556

557 OutStreamer.emitLabel(StubLabel);

558

560

562

564 else

565

566

567

568

569

570

573 4 );

574}

575

576

578 const Triple &TT = TM.getTargetTriple();

579 if (TT.isOSBinFormatMachO()) {

580

585

586

588

589 if (!Stubs.empty()) {

590

593

594 for (auto &Stub : Stubs)

596

597 Stubs.clear();

599 }

600

602 if (!Stubs.empty()) {

603

606

607 for (auto &Stub : Stubs)

609

610 Stubs.clear();

612 }

613

614

615

616

617

618

619 OutStreamer->emitSubsectionsViaSymbols();

620 }

621

622

625

626 if (OptimizationGoals > 0 &&

627 (TT.isTargetAEABI() || TT.isTargetGNUAEABI() || TT.isTargetMuslAEABI()))

629 OptimizationGoals = -1;

630

632}

633

634

635

636

637

638

639

640

641

642

646 if (F.isDeclaration())

647 return false;

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

649 });

650}

651

652

656 if (F.isDeclaration())

657 return false;

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

660 });

661}

662

663

665 auto F = M.functions().begin();

666 auto E = M.functions().end();

667 if (F == E)

668 return false;

670 ++F;

671 return std::any_of(F, E, [&](const Function &F) {

672 return F.isDeclaration() && F.getDenormalModeRaw() != Value;

673 });

674}

675

676void ARMAsmPrinter::emitAttributes() {

677 MCTargetStreamer &TS = *OutStreamer->getTargetStreamer();

678 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);

679

681

683

684

685

686

687

688

689 const Triple &TT = TM.getTargetTriple();

690 StringRef CPU = TM.getTargetCPU();

691 StringRef FS = TM.getTargetFeatureString();

693 if (FS.empty()) {

694 if (!ArchFS.empty())

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

696 else

697 ArchFS = std::string(FS);

698 }

699 const ARMBaseTargetMachine &ATM =

700 static_cast<const ARMBaseTargetMachine &>(TM);

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

703

704

706

707

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

712

715 }

716

717

721 }

722

723

727 } else {

730 }

731

732

738 "denormal-fp-math",

747 else {

748 if (!STI.hasVFP2Base()) {

749

750

751

752

753

754

755 if (STI.hasV7Ops())

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

759

760

761

764 }

765

766

767

768

769

770

771 }

772

773

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

776 TM.Options.NoTrappingFPMath)

779 else {

781

782

783

784 if (TM.Options.HonorSignDependentRoundingFPMathOption)

786 }

787

788

789

790 if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath)

793 else

796

797

798

801

802

805

806

807

808

809

812

813 if (const Module *SourceModule = MMI->getModule()) {

814

815

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

818 int WCharWidth = WCharWidthValue->getZExtValue();

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

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

822 }

823

824

825

826

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

829 int EnumWidth = EnumWidthValue->getZExtValue();

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

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

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

834 }

835

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

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

839

840

841

842 if (!STI.hasPACBTI()) {

845 }

847 }

848

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

851 if (BTIValue && !BTIValue->isZero()) {

852

853

854

855 if (!STI.hasPACBTI()) {

858 }

860 }

861 }

862

863

864 if (STI.isRWPI())

867 else if (STI.isR9Reserved())

870 else

873}

874

875

876

878 unsigned LabelId, MCContext &Ctx) {

879

880 MCSymbol *Label = Ctx.getOrCreateSymbol(Twine(Prefix)

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

882 return Label;

883}

884

886 unsigned LabelId, MCContext &Ctx) {

887

888 MCSymbol *Label = Ctx.getOrCreateSymbol(Twine(Prefix)

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

890 return Label;

891}

892

894 switch (Modifier) {

909 }

911}

912

914 unsigned char TargetFlags) {

915 const Triple &TT = TM.getTargetTriple();

916 if (TT.isOSBinFormatMachO()) {

917 bool IsIndirect =

919

920 if (!IsIndirect)

922

923

925 MachineModuleInfoMachO &MMIMachO =

926 MMI->getObjFileInfo();

930

931 if (!StubSym.getPointer())

934 return MCSym;

935 } else if (TT.isOSBinFormatCOFF()) {

936 assert(TT.isOSWindows() && "Windows is the only supported COFF target");

937

938 bool IsIndirect =

940 if (!IsIndirect)

942

943 SmallString<128> Name;

945 Name = "__imp_";

947 Name = ".refptr.";

949

951

953 MachineModuleInfoCOFF &MMICOFF =

954 MMI->getObjFileInfo();

957

958 if (!StubSym.getPointer())

960 }

961

962 return MCSym;

963 } else if (TT.isOSBinFormatELF()) {

965 }

967}

968

973

975

977

978

979

980

981

982

983

984

985

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

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

991 EmittedPromotedGlobalLabels.insert(GV);

992 }

993 }

995 }

996

998 if (ACPV->isLSDA()) {

1006

1007

1008

1009 unsigned char TF =

1011 MCSym = GetARMGVSymbol(GV, TF);

1014 MCSym = MBB->getSymbol();

1015 } else {

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

1019 }

1020

1021

1024

1030 PCRelExpr =

1036

1037

1042 }

1044 }

1046}

1047

1050 unsigned JTI = MO1.getIndex();

1051

1052

1053

1055

1056

1057 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);

1059

1060

1062

1063

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

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

1067

1069

1070

1071

1072

1073

1074

1075

1076

1078

1084

1085

1086 else if (AFI->isThumbFunction())

1090 }

1091

1093}

1094

1097 unsigned JTI = MO1.getIndex();

1098

1099

1100

1102

1103

1104 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);

1106

1107

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

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

1111

1115

1117 .addExpr(MBBSymbolExpr)

1119 .addReg(0));

1120 }

1121}

1122

1124 unsigned OffsetWidth) {

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

1127 unsigned JTI = MO1.getIndex();

1128

1132

1133 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel(JTI);

1135

1136

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

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

1140

1141

1144

1145 for (auto *MBB : JTBBs) {

1148

1149

1150

1151

1152

1153

1154

1155

1156

1157

1158

1166 OutStreamer->emitValue(Expr, OffsetWidth);

1167 }

1168

1169

1170

1172

1173

1175}

1176

1181 const MCSymbol *BranchLabel) const {

1185 switch (BranchInstr->getOpcode()) {

1186 case ARM::BR_JTadd:

1187 case ARM::BR_JTr:

1188 case ARM::tBR_JTr:

1189

1191 BaseLabel = GetARMJTIPICJumpTableLabel(JTI);

1192 break;

1193 case ARM::tTBH_JT:

1194 case ARM::t2TBH_JT:

1195

1198 BaseLabel = BranchLabel;

1199 BaseOffset = 4;

1200 break;

1201 case ARM::tTBB_JT:

1202 case ARM::t2TBB_JT:

1203

1206 BaseLabel = BranchLabel;

1207 BaseOffset = 4;

1208 break;

1209 case ARM::t2BR_JT:

1210

1211 BaseLabel = nullptr;

1213 break;

1214 default:

1216 }

1217

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

1219}

1220

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

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

1224

1231

1233 unsigned Opc = MI->getOpcode();

1234 unsigned SrcReg, DstReg;

1235

1236 switch (Opc) {

1237 case ARM::tPUSH:

1238

1239 SrcReg = DstReg = ARM::SP;

1240 break;

1241 case ARM::tLDRpci:

1242 case ARM::t2MOVi16:

1243 case ARM::t2MOVTi16:

1244 case ARM::tMOVi8:

1245 case ARM::tADDi8:

1246 case ARM::tLSLri:

1247

1248

1249

1250

1251

1252

1253

1254

1255

1256

1257

1258

1259

1260

1261

1262

1263 SrcReg = ~0U;

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

1265 break;

1266 case ARM::VMRS:

1267 SrcReg = ARM::FPSCR;

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

1269 break;

1270 case ARM::VMRS_FPEXC:

1271 SrcReg = ARM::FPEXC;

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

1273 break;

1274 default:

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

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

1277 break;

1278 }

1279

1280

1281 if (MI->mayStore()) {

1282

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

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

1285

1287

1288 unsigned StartOp = 2 + 2;

1289

1290 unsigned NumOffset = 0;

1291

1292

1293 unsigned PadBefore = 0;

1294

1295

1296 unsigned PadAfter = 0;

1297

1298 switch (Opc) {

1299 default:

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

1302 case ARM::tPUSH:

1303

1304 StartOp = 2; NumOffset = 2;

1305 [[fallthrough]];

1306 case ARM::STMDB_UPD:

1307 case ARM::t2STMDB_UPD:

1308 case ARM::VSTMDDB_UPD:

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

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

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

1314

1315

1317 continue;

1318

1319

1320

1321

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

1325 unsigned Width =

1327 PadAfter += Width;

1328 continue;

1329 }

1330

1331

1333 if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(Reg))

1334 Reg = RemappedReg;

1336 }

1337 break;

1338 case ARM::STR_PRE_IMM:

1339 case ARM::STR_PRE_REG:

1340 case ARM::t2STR_PRE:

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

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

1343 if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(SrcReg))

1344 SrcReg = RemappedReg;

1345

1347 break;

1348 case ARM::t2STRD_PRE:

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

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

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

1352 if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(SrcReg))

1353 SrcReg = RemappedReg;

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

1356 if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(SrcReg))

1357 SrcReg = RemappedReg;

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

1360 break;

1361 }

1363 if (PadBefore)

1366

1367 if (PadAfter)

1369 }

1370 } else {

1371

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

1374 switch (Opc) {

1375 default:

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

1378 case ARM::tLDRspi:

1379

1380

1381 return;

1382 case ARM::MOVr:

1383 case ARM::tMOVr:

1385 break;

1386 case ARM::ADDri:

1387 case ARM::t2ADDri:

1388 case ARM::t2ADDri12:

1389 case ARM::t2ADDspImm:

1390 case ARM::t2ADDspImm12:

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

1392 break;

1393 case ARM::SUBri:

1394 case ARM::t2SUBri:

1395 case ARM::t2SUBri12:

1396 case ARM::t2SUBspImm:

1397 case ARM::t2SUBspImm12:

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

1399 break;

1400 case ARM::tSUBspi:

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

1402 break;

1403 case ARM::tADDspi:

1404 case ARM::tADDrSPi:

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

1406 break;

1407 case ARM::tADDhirr:

1409 -AFI->EHPrologueOffsetInRegs.lookup(MI->getOperand(2).getReg());

1410 break;

1411 }

1412

1415

1416

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

1419

1420

1422 } else {

1423

1424

1426 }

1427 }

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

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

1431 } else {

1433 switch (Opc) {

1434 case ARM::tMOVr:

1435

1436

1437

1438 AFI->EHPrologueRemappedRegs[DstReg] = SrcReg;

1439 break;

1440 case ARM::VMRS:

1441 case ARM::VMRS_FPEXC:

1442

1443

1444

1445

1446

1447 break;

1448 case ARM::tLDRpci: {

1449

1450

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

1452 const MachineConstantPool *MCP = MF.getConstantPool();

1453 if (CPI >= MCP->getConstants().size())

1454 CPI = AFI->getOriginalCPIdx(CPI);

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

1456

1457

1458 const MachineConstantPoolEntry &CPE = MCP->getConstants()[CPI];

1461 AFI->EHPrologueOffsetInRegs[DstReg] = Offset;

1462 break;

1463 }

1464 case ARM::t2MOVi16:

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

1466 AFI->EHPrologueOffsetInRegs[DstReg] = Offset;

1467 break;

1468 case ARM::t2MOVTi16:

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

1470 AFI->EHPrologueOffsetInRegs[DstReg] |= (Offset << 16);

1471 break;

1472 case ARM::tMOVi8:

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

1474 AFI->EHPrologueOffsetInRegs[DstReg] = Offset;

1475 break;

1476 case ARM::tLSLri:

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

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

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

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

1481 AFI->EHPrologueOffsetInRegs[DstReg] <<= 8;

1482 break;

1483 case ARM::tADDi8:

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

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

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

1487 AFI->EHPrologueOffsetInRegs[DstReg] += Offset;

1488 break;

1489 case ARM::t2PAC:

1490 case ARM::t2PACBTI:

1491 AFI->EHPrologueRemappedRegs[ARM::R12] = ARM::RA_AUTH_CODE;

1492 break;

1493 default:

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

1496 }

1497 }

1498 }

1499}

1500

1501

1502

1503#include "ARMGenMCPseudoLowering.inc"

1504

1505

1506

1510 return true;

1511 }

1512 }

1513 return false;

1514}

1515

1516void ARMAsmPrinter::EmitKCFI_CHECK_ARM32(Register AddrReg, int64_t Type,

1518 int64_t PrefixNops) {

1519

1520 unsigned ScratchReg = ARM::R12;

1521 if (AddrReg == ARM::R12) {

1522 ScratchReg = ARM::R3;

1523 }

1524

1525

1526

1527 const ARMBaseRegisterInfo *TRI = static_cast<const ARMBaseRegisterInfo *>(

1528 MF->getSubtarget().getRegisterInfo());

1529 unsigned AddrIndex = TRI->getEncodingValue(AddrReg);

1530 unsigned ESR = 0x8000 | (31 << 5) | (AddrIndex & 31);

1531

1532

1533 bool NeedSpillR3 =

1535

1536

1537 if (NeedSpillR3) {

1538

1540 .addReg(ARM::SP)

1541 .addReg(ARM::SP)

1543 .addReg(0)

1544 .addReg(ARM::R3));

1545 }

1546

1547

1548

1549

1550

1551

1553 .addReg(ScratchReg)

1554 .addReg(AddrReg)

1555 .addImm(1)

1557 .addReg(0)

1558 .addReg(0));

1559

1560

1562 .addReg(ScratchReg)

1563 .addReg(ScratchReg)

1564 .addImm(-(PrefixNops * 4 + 4))

1566 .addReg(0));

1567

1568

1569 for (int i = 0; i < 4; i++) {

1570 uint8_t byte = (Type >> (i * 8)) & 0xFF;

1571 uint32_t imm = byte << (i * 8);

1572 bool isLast = (i == 3);

1573

1574

1576 assert(SOImmVal != -1 &&

1577 "Cannot encode immediate as ARM modified immediate");

1578

1579

1581 MCInstBuilder(ARM::EORri)

1582 .addReg(ScratchReg)

1583 .addReg(ScratchReg)

1584 .addImm(SOImmVal)

1586 .addReg(0)

1587 .addReg(isLast ? ARM::CPSR : ARM::NoRegister));

1588 }

1589

1590

1591

1592 if (NeedSpillR3) {

1593

1595 .addReg(ARM::SP)

1596 .addReg(ARM::SP)

1598 .addReg(0)

1599 .addReg(ARM::R3));

1600 }

1601

1602

1605 MCInstBuilder(ARM::Bcc)

1608 .addReg(ARM::CPSR));

1609

1610

1612

1614}

1615

1616void ARMAsmPrinter::EmitKCFI_CHECK_Thumb2(Register AddrReg, int64_t Type,

1618 int64_t PrefixNops) {

1619

1620 unsigned ScratchReg = ARM::R12;

1621 if (AddrReg == ARM::R12) {

1622 ScratchReg = ARM::R3;

1623 }

1624

1625

1626

1627

1628

1629 const ARMBaseRegisterInfo *TRI = static_cast<const ARMBaseRegisterInfo *>(

1630 MF->getSubtarget().getRegisterInfo());

1631 unsigned AddrIndex = TRI->getEncodingValue(AddrReg);

1632 unsigned ESR = 0x80 | (AddrIndex & 0x1F);

1633

1634

1635 bool NeedSpillR3 =

1637

1638

1639 if (NeedSpillR3) {

1640

1643 MCInstBuilder(ARM::tPUSH).addImm(ARMCC::AL).addReg(0).addReg(ARM::R3));

1644 }

1645

1646

1647

1648

1649

1650

1652 .addReg(ScratchReg)

1653 .addReg(AddrReg)

1654 .addImm(1)

1656 .addReg(0)

1657 .addReg(0));

1658

1659

1661 .addReg(ScratchReg)

1662 .addReg(ScratchReg)

1663 .addImm(-(PrefixNops * 4 + 4))

1665 .addReg(0));

1666

1667

1668 for (int i = 0; i < 4; i++) {

1669 uint8_t byte = (Type >> (i * 8)) & 0xFF;

1670 uint32_t imm = byte << (i * 8);

1671 bool isLast = (i == 3);

1672

1673

1675 "Cannot encode immediate as Thumb2 modified immediate");

1676

1677

1679 MCInstBuilder(ARM::t2EORri)

1680 .addReg(ScratchReg)

1681 .addReg(ScratchReg)

1682 .addImm(imm)

1684 .addReg(0)

1685 .addReg(isLast ? ARM::CPSR : ARM::NoRegister));

1686 }

1687

1688

1689

1690 if (NeedSpillR3) {

1691

1694 MCInstBuilder(ARM::tPOP).addImm(ARMCC::AL).addReg(0).addReg(ARM::R3));

1695 }

1696

1697

1700 MCInstBuilder(ARM::t2Bcc)

1703 .addReg(ARM::CPSR));

1704

1705

1707

1709}

1710

1711void ARMAsmPrinter::EmitKCFI_CHECK_Thumb1(Register AddrReg, int64_t Type,

1713 int64_t PrefixNops) {

1714

1715

1716 unsigned ScratchReg = ARM::R2;

1717 unsigned TempReg = ARM::R3;

1718

1719

1721

1722

1723 if (NeedSpillR3) {

1726 MCInstBuilder(ARM::tPUSH).addImm(ARMCC::AL).addReg(0).addReg(ARM::R3));

1727 }

1728

1729

1731

1732

1733 if (NeedSpillR2) {

1736 MCInstBuilder(ARM::tPUSH).addImm(ARMCC::AL).addReg(0).addReg(ARM::R2));

1737 }

1738

1739

1740

1741

1742

1743

1745 .addReg(TempReg)

1746 .addReg(ARM::CPSR)

1747 .addImm(1)

1749 .addReg(0));

1750

1751

1753 .addReg(ScratchReg)

1754 .addReg(AddrReg)

1756

1757

1759 .addReg(ScratchReg)

1760 .addReg(ARM::CPSR)

1761 .addReg(ScratchReg)

1762 .addReg(TempReg)

1764 .addReg(0));

1765

1766

1767 int offset = PrefixNops * 4 + 4;

1768

1769

1771 .addReg(ScratchReg)

1772 .addReg(ARM::CPSR)

1773 .addReg(ScratchReg)

1774 .addImm(offset)

1776 .addReg(0));

1777

1778

1780 .addReg(ScratchReg)

1781 .addReg(ScratchReg)

1782 .addImm(0)

1784 .addReg(0));

1785

1786

1787

1788

1789

1790

1791

1792

1793

1794

1795

1796

1797 uint8_t byte0 = (Type >> 0) & 0xFF;

1798 uint8_t byte1 = (Type >> 8) & 0xFF;

1799 uint8_t byte2 = (Type >> 16) & 0xFF;

1800 uint8_t byte3 = (Type >> 24) & 0xFF;

1801

1802

1804 .addReg(TempReg)

1805 .addReg(ARM::CPSR)

1806 .addImm(byte3)

1808 .addReg(0));

1809

1810

1812 .addReg(TempReg)

1813 .addReg(ARM::CPSR)

1814 .addReg(TempReg)

1815 .addImm(8)

1817 .addReg(0));

1818

1819

1821 .addReg(TempReg)

1822 .addReg(ARM::CPSR)

1823 .addReg(TempReg)

1824 .addImm(byte2)

1826 .addReg(0));

1827

1828

1830 .addReg(TempReg)

1831 .addReg(ARM::CPSR)

1832 .addReg(TempReg)

1833 .addImm(8)

1835 .addReg(0));

1836

1837

1839 .addReg(TempReg)

1840 .addReg(ARM::CPSR)

1841 .addReg(TempReg)

1842 .addImm(byte1)

1844 .addReg(0));

1845

1846

1848 .addReg(TempReg)

1849 .addReg(ARM::CPSR)

1850 .addReg(TempReg)

1851 .addImm(8)

1853 .addReg(0));

1854

1855

1857 .addReg(TempReg)

1858 .addReg(ARM::CPSR)

1859 .addReg(TempReg)

1860 .addImm(byte0)

1862 .addReg(0));

1863

1864

1866 .addReg(ScratchReg)

1867 .addReg(TempReg)

1869 .addReg(0));

1870

1871

1872 if (NeedSpillR2) {

1873

1876 MCInstBuilder(ARM::tPOP).addImm(ARMCC::AL).addReg(0).addReg(ARM::R2));

1877 }

1878

1879

1880 if (NeedSpillR3) {

1881

1884 MCInstBuilder(ARM::tPOP).addImm(ARMCC::AL).addReg(0).addReg(ARM::R3));

1885 }

1886

1887

1890 MCInstBuilder(ARM::tBcc)

1893 .addReg(ARM::CPSR));

1894

1895

1897

1899}

1900

1902 Register AddrReg = MI.getOperand(0).getReg();

1903 const int64_t Type = MI.getOperand(1).getImm();

1904

1905

1906 assert(std::next(MI.getIterator())->isCall() &&

1907 "KCFI_CHECK not followed by a call instruction");

1909

1910

1911 int64_t PrefixNops = 0;

1912 MI.getMF()

1913 ->getFunction()

1914 .getFnAttribute("patchable-function-prefix")

1915 .getValueAsString()

1916 .getAsInteger(10, PrefixNops);

1917

1918

1919 switch (MI.getOpcode()) {

1920 case ARM::KCFI_CHECK_ARM:

1921 EmitKCFI_CHECK_ARM32(AddrReg, Type, Call, PrefixNops);

1922 break;

1923 case ARM::KCFI_CHECK_Thumb2:

1924 EmitKCFI_CHECK_Thumb2(AddrReg, Type, Call, PrefixNops);

1925 break;

1926 case ARM::KCFI_CHECK_Thumb1:

1927 EmitKCFI_CHECK_Thumb1(AddrReg, Type, Call, PrefixNops);

1928 break;

1929 default:

1931 }

1932}

1933

1935 ARM_MC::verifyInstructionPredicates(MI->getOpcode(),

1937

1942

1943

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

1946 InConstantPool = false;

1947 }

1948

1949

1950 if (TM.getTargetTriple().isTargetEHABICompatible() &&

1952 EmitUnwindingInstruction(MI);

1953

1954

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

1957 return;

1958 }

1959

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

1962

1963

1964 unsigned Opc = MI->getOpcode();

1965 switch (Opc) {

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

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

1968 case ARM::KCFI_CHECK_ARM:

1969 case ARM::KCFI_CHECK_Thumb2:

1970 case ARM::KCFI_CHECK_Thumb1:

1972 return;

1973 case ARM::LEApcrel:

1974 case ARM::tLEApcrel:

1975 case ARM::t2LEApcrel: {

1976

1979 ARM::t2LEApcrel ? ARM::t2ADR

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

1981 : ARM::ADR))

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

1984

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

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

1987 return;

1988 }

1989 case ARM::LEApcrelJT:

1990 case ARM::tLEApcrelJT:

1991 case ARM::t2LEApcrelJT: {

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

1995 ARM::t2LEApcrelJT ? ARM::t2ADR

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

1997 : ARM::ADR))

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

2000

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

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

2003 return;

2004 }

2005

2006

2007 case ARM::BX_CALL: {

2009 .addReg(ARM::LR)

2010 .addReg(ARM::PC)

2011

2013 .addReg(0)

2014

2015 .addReg(0));

2016

2017 assert(STI.hasV4TOps() && "Expected V4TOps for BX call");

2019 MCInstBuilder(ARM::BX).addReg(MI->getOperand(0).getReg()));

2020 return;

2021 }

2022 case ARM::tBX_CALL: {

2023 assert(!STI.hasV5TOps() && "Expected BLX to be selected for v5t+");

2024

2025

2026

2027

2028

2029

2030

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

2032 MCSymbol *TRegSym = nullptr;

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

2034 if (TIP.first == TReg) {

2035 TRegSym = TIP.second;

2036 break;

2037 }

2038 }

2039

2040 if (!TRegSym) {

2041 TRegSym = OutContext.createTempSymbol();

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

2043 }

2044

2045

2047

2050 return;

2051 }

2052 case ARM::BMOVPCRX_CALL: {

2054 .addReg(ARM::LR)

2055 .addReg(ARM::PC)

2056

2058 .addReg(0)

2059

2060 .addReg(0));

2061

2063 .addReg(ARM::PC)

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

2065

2068

2070 return;

2071 }

2072 case ARM::BMOVPCB_CALL: {

2074 .addReg(ARM::LR)

2075 .addReg(ARM::PC)

2076

2078 .addReg(0)

2079

2080 .addReg(0));

2081

2084 const unsigned TF = Op.getTargetFlags();

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

2088 .addExpr(GVSymExpr)

2089

2091 .addReg(0));

2092 return;

2093 }

2094 case ARM::MOVi16_ga_pcrel:

2095 case ARM::t2MOVi16_ga_pcrel: {

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

2099

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

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

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

2104

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

2112 GVSymExpr,

2119

2120

2123

2126 return;

2127 }

2128 case ARM::MOVTi16_ga_pcrel:

2129 case ARM::t2MOVTi16_ga_pcrel: {

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

2132 ? ARM::MOVTi16 : ARM::t2MOVTi16);

2135

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

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

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

2140

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

2148 GVSymExpr,

2155

2158

2161 return;

2162 }

2163 case ARM::t2BFi:

2164 case ARM::t2BFic:

2165 case ARM::t2BFLi:

2166 case ARM::t2BFr:

2167 case ARM::t2BFLr: {

2168

2169

2174

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

2177

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

2179 } else {

2180

2181 const MCExpr *BranchTarget;

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

2184 MI->getOperand(1).getMBB()->getSymbol(), OutContext);

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

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

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

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

2193 } else

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

2195

2196 MCInst.addExpr(BranchTarget);

2197 }

2198

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

2204 MCInst.addExpr(ElseLabel);

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

2206 } else {

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

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

2209 }

2210

2212 return;

2213 }

2214 case ARM::t2BF_LabelPseudo: {

2215

2216

2217

2221 return;

2222 }

2223 case ARM::tPICADD: {

2224

2225

2226

2227

2228

2229

2233

2234

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

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

2239

2242 return;

2243 }

2244 case ARM::PICADD: {

2245

2246

2247

2248

2249

2250

2254

2255

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

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

2260

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

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

2263

2265 return;

2266 }

2267 case ARM::PICSTR:

2268 case ARM::PICSTRB:

2269 case ARM::PICSTRH:

2270 case ARM::PICLDR:

2271 case ARM::PICLDRB:

2272 case ARM::PICLDRH:

2273 case ARM::PICLDRSB:

2274 case ARM::PICLDRSH: {

2275

2276

2277

2278

2279

2280

2281

2285

2286

2287 unsigned Opcode;

2288 switch (MI->getOpcode()) {

2289 default:

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

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

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

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

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

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

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

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

2299 }

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

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

2305

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

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

2308

2309 return;

2310 }

2311 case ARM::CONSTPOOL_ENTRY: {

2312 assert(!STI.genExecuteOnly() &&

2313 "execute-only should not generate constant pools");

2314

2315

2316

2317

2318

2319

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

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

2322

2323

2324 if (!InConstantPool) {

2326 InConstantPool = true;

2327 }

2328

2330

2334 else

2336 return;

2337 }

2338 case ARM::JUMPTABLE_ADDRS:

2340 return;

2341 case ARM::JUMPTABLE_INSTS:

2343 return;

2344 case ARM::JUMPTABLE_TBB:

2345 case ARM::JUMPTABLE_TBH:

2347 return;

2348 case ARM::t2BR_JT: {

2350 .addReg(ARM::PC)

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

2352

2355 return;

2356 }

2357 case ARM::t2TBB_JT:

2358 case ARM::t2TBH_JT: {

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

2360

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

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

2365

2368 return;

2369 }

2370 case ARM::tTBB_JT:

2371 case ARM::tTBH_JT: {

2372

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

2375 Register Idx = MI->getOperand(1).getReg();

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

2377

2378

2379 if (!Is8Bit)

2381 .addReg(Idx)

2382 .addReg(ARM::CPSR)

2383 .addReg(Idx)

2384 .addImm(1)

2385

2387 .addReg(0));

2388

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

2390

2391

2392

2393

2394

2395

2396

2397

2398

2399

2400

2401

2402

2405 .addReg(Idx)

2406 .addReg(Idx)

2407 .addReg(Base)

2408

2410 .addReg(0));

2411

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

2414 .addReg(Idx)

2415 .addReg(Idx)

2416 .addImm(Is8Bit ? 4 : 2)

2417

2419 .addReg(0));

2420 } else {

2421

2422

2423

2424

2425

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

2428 .addReg(Idx)

2429 .addReg(Base)

2430 .addReg(Idx)

2431

2433 .addReg(0));

2434 }

2435

2437 .addReg(Idx)

2438 .addReg(ARM::CPSR)

2439 .addReg(Idx)

2440 .addImm(1)

2441

2443 .addReg(0));

2444

2447 .addReg(ARM::PC)

2448 .addReg(ARM::PC)

2449 .addReg(Idx)

2450

2452 .addReg(0));

2453 return;

2454 }

2455 case ARM::tBR_JTr:

2456 case ARM::BR_JTr: {

2457

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

2460 ARM::MOVr : ARM::tMOVr;

2464

2467

2468 if (Opc == ARM::MOVr)

2471 return;

2472 }

2473 case ARM::BR_JTm_i12: {

2474

2480

2484 return;

2485 }

2486 case ARM::BR_JTm_rs: {

2487

2494

2498 return;

2499 }

2500 case ARM::BR_JTadd: {

2501

2503 .addReg(ARM::PC)

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

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

2506

2509

2511 return;

2512 }

2513 case ARM::SPACE:

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

2515 return;

2516 case ARM::TRAP: {

2517

2518

2519 if (TM.getTargetTriple().isOSBinFormatMachO()) {

2520 uint32_t Val = 0xe7ffdefeUL;

2523 return;

2524 }

2525 break;

2526 }

2527 case ARM::tTRAP: {

2528

2529

2530 if (TM.getTargetTriple().isOSBinFormatMachO()) {

2534 return;

2535 }

2536 break;

2537 }

2538 case ARM::t2Int_eh_sjlj_setjmp:

2539 case ARM::t2Int_eh_sjlj_setjmp_nofp:

2540 case ARM::tInt_eh_sjlj_setjmp: {

2541

2542

2543

2544

2545

2546

2547

2548

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

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

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

2554 .addReg(ValReg)

2555 .addReg(ARM::PC)

2556

2558 .addReg(0));

2559

2561 .addReg(ValReg)

2562

2563 .addReg(ARM::CPSR)

2564 .addReg(ValReg)

2565 .addImm(7)

2566

2568 .addReg(0));

2569

2571 .addReg(ValReg)

2572 .addReg(SrcReg)

2573

2574

2575 .addImm(1)

2576

2578 .addReg(0));

2579

2581 .addReg(ARM::R0)

2582 .addReg(ARM::CPSR)

2583 .addImm(0)

2584

2586 .addReg(0));

2587

2590 .addExpr(SymbolExpr)

2592 .addReg(0));

2593

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

2596 .addReg(ARM::R0)

2597 .addReg(ARM::CPSR)

2598 .addImm(1)

2599

2601 .addReg(0));

2602

2604 return;

2605 }

2606

2607 case ARM::Int_eh_sjlj_setjmp_nofp:

2608 case ARM::Int_eh_sjlj_setjmp: {

2609

2610

2611

2612

2613

2614

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

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

2617

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

2620 .addReg(ValReg)

2621 .addReg(ARM::PC)

2622 .addImm(8)

2623

2625 .addReg(0)

2626

2627 .addReg(0));

2628

2630 .addReg(ValReg)

2631 .addReg(SrcReg)

2632 .addImm(4)

2633

2635 .addReg(0));

2636

2638 .addReg(ARM::R0)

2639 .addImm(0)

2640

2642 .addReg(0)

2643

2644 .addReg(0));

2645

2647 .addReg(ARM::PC)

2648 .addReg(ARM::PC)

2649 .addImm(0)

2650

2652 .addReg(0)

2653

2654 .addReg(0));

2655

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

2658 .addReg(ARM::R0)

2659 .addImm(1)

2660

2662 .addReg(0)

2663

2664 .addReg(0));

2665 return;

2666 }

2667 case ARM::Int_eh_sjlj_longjmp: {

2668

2669

2670

2671

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

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

2675 .addReg(ARM::SP)

2676 .addReg(SrcReg)

2677 .addImm(8)

2678

2680 .addReg(0));

2681

2683 .addReg(ScratchReg)

2684 .addReg(SrcReg)

2685 .addImm(4)

2686

2688 .addReg(0));

2689

2691

2696

2699 } else {

2700

2701

2703 .addReg(ARM::R7)

2704 .addReg(SrcReg)

2705 .addImm(0)

2706

2708 .addReg(0));

2710 .addReg(ARM::R11)

2711 .addReg(SrcReg)

2712 .addImm(0)

2713

2715 .addReg(0));

2716 }

2717

2718 assert(STI.hasV4TOps());

2720 .addReg(ScratchReg)

2721

2723 .addReg(0));

2724 return;

2725 }

2726 case ARM::tInt_eh_sjlj_longjmp: {

2727

2728

2729

2730

2731

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

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

2734

2736 .addReg(ScratchReg)

2737 .addReg(SrcReg)

2738

2739

2740 .addImm(2)

2741

2743 .addReg(0));

2744

2746 .addReg(ARM::SP)

2747 .addReg(ScratchReg)

2748

2750 .addReg(0));

2751

2753 .addReg(ScratchReg)

2754 .addReg(SrcReg)

2755 .addImm(1)

2756

2758 .addReg(0));

2759

2761

2766

2769 } else {

2770

2771

2773 .addReg(ARM::R7)

2774 .addReg(SrcReg)

2775 .addImm(0)

2776

2778 .addReg(0));

2780 .addReg(ARM::R11)

2781 .addReg(SrcReg)

2782 .addImm(0)

2783

2785 .addReg(0));

2786 }

2787

2789 .addReg(ScratchReg)

2790

2792 .addReg(0));

2793 return;

2794 }

2795 case ARM::tInt_WIN_eh_sjlj_longjmp: {

2796

2797

2798

2799

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

2801

2803 .addReg(ARM::R11)

2804 .addReg(SrcReg)

2805 .addImm(0)

2806

2808 .addReg(0));

2810 .addReg(ARM::SP)

2811 .addReg(SrcReg)

2812 .addImm(8)

2813

2815 .addReg(0));

2817 .addReg(ARM::PC)

2818 .addReg(SrcReg)

2819 .addImm(4)

2820

2822 .addReg(0));

2823 return;

2824 }

2825 case ARM::PATCHABLE_FUNCTION_ENTER:

2827 return;

2828 case ARM::PATCHABLE_FUNCTION_EXIT:

2830 return;

2831 case ARM::PATCHABLE_TAIL_CALL:

2833 return;

2834 case ARM::SpeculationBarrierISBDSBEndBB: {

2835

2844 return;

2845 }

2846 case ARM::t2SpeculationBarrierISBDSBEndBB: {

2847

2849 TmpInstDSB.setOpcode(ARM::t2DSB);

2855 TmpInstISB.setOpcode(ARM::t2ISB);

2860 return;

2861 }

2862 case ARM::SpeculationBarrierSBEndBB: {

2863

2867 return;

2868 }

2869 case ARM::t2SpeculationBarrierSBEndBB: {

2870

2874 return;

2875 }

2876

2877 case ARM::SEH_StackAlloc:

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

2880 return;

2881

2882 case ARM::SEH_SaveRegs:

2883 case ARM::SEH_SaveRegs_Ret:

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

2886 return;

2887

2888 case ARM::SEH_SaveSP:

2890 return;

2891

2892 case ARM::SEH_SaveFRegs:

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

2895 return;

2896

2897 case ARM::SEH_SaveLR:

2899 return;

2900

2901 case ARM::SEH_Nop:

2902 case ARM::SEH_Nop_Ret:

2904 return;

2905

2906 case ARM::SEH_PrologEnd:

2908 return;

2909

2910 case ARM::SEH_EpilogStart:

2912 return;

2913

2914 case ARM::SEH_EpilogEnd:

2916 return;

2917 }

2918

2921

2923}

2924

2926

2928 false)

2929

2930

2931

2932

2933

2934

2936LLVMInitializeARMAsmPrinter() {

2941}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static bool isRegisterLiveInCall(const MachineInstr &Call, MCRegister Reg)

Definition ARMAsmPrinter.cpp:1507

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

Definition ARMAsmPrinter.cpp:554

static uint8_t getModifierSpecifier(ARMCP::ARMCPModifier Modifier)

Definition ARMAsmPrinter.cpp:893

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

Definition ARMAsmPrinter.cpp:885

static bool checkDenormalAttributeInconsistency(const Module &M)

Definition ARMAsmPrinter.cpp:664

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

Definition ARMAsmPrinter.cpp:643

static bool isThumb(const MCSubtargetInfo &STI)

Definition ARMAsmPrinter.cpp:517

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

Definition ARMAsmPrinter.cpp:877

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

Definition ARMAsmPrinter.cpp:653

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

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

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

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

#define LLVM_EXTERNAL_VISIBILITY

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

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

const size_t AbstractManglingParser< Derived, Alloc >::NumOps

Machine Check Debug Module

Register const TargetRegisterInfo * TRI

Promote Memory to Register

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

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

This file defines the SmallString class.

static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")

static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")

static const unsigned FramePtr

void emitJumpTableAddrs(const MachineInstr *MI)

Definition ARMAsmPrinter.cpp:1048

void emitJumpTableTBInst(const MachineInstr *MI, unsigned OffsetWidth)

Definition ARMAsmPrinter.cpp:1123

void emitFunctionBodyEnd() override

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

Definition ARMAsmPrinter.cpp:61

bool runOnMachineFunction(MachineFunction &F) override

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

Definition ARMAsmPrinter.cpp:145

MCSymbol * GetCPISymbol(unsigned CPID) const override

Return the symbol for the specified constant pool entry.

Definition ARMAsmPrinter.cpp:298

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

Definition ARMAsmPrinter.cpp:247

void emitStartOfAsmFile(Module &M) override

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

Definition ARMAsmPrinter.cpp:536

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

Definition ARMAsmPrinter.cpp:52

void emitFunctionEntryLabel() override

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

Definition ARMAsmPrinter.cpp:70

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

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

Definition ARMAsmPrinter.cpp:521

void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI)

void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override

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

Definition ARMAsmPrinter.cpp:969

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.

Definition ARMAsmPrinter.cpp:318

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...

Definition ARMAsmPrinter.cpp:91

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...

Definition ARMAsmPrinter.cpp:577

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.

Definition ARMAsmPrinter.cpp:1179

void emitJumpTableInsts(const MachineInstr *MI)

Definition ARMAsmPrinter.cpp:1095

const ARMBaseTargetMachine & getTM() const

Definition ARMAsmPrinter.cpp:57

void emitGlobalVariable(const GlobalVariable *GV) override

Emit the specified global variable to the .s file.

Definition ARMAsmPrinter.cpp:135

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...

Definition ARMAsmPrinter.cpp:493

void emitInstruction(const MachineInstr *MI) override

Targets should implement this to emit instructions.

Definition ARMAsmPrinter.cpp:1934

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

Print the MachineOperand as a symbol.

Definition ARMAsmPrinter.cpp:226

void LowerKCFI_CHECK(const MachineInstr &MI)

Definition ARMAsmPrinter.cpp:1901

void emitGlobalAlias(const Module &M, const GlobalAlias &GA) override

Definition ARMAsmPrinter.cpp:130

bool isGVIndirectSymbol(const GlobalValue *GV) const

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...

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

bool isThumb1Only() const

MCPhysReg getFramePointerReg() const

bool isTargetWindows() const

bool isTargetDarwin() const

void emitTargetAttributes(const MCSubtargetInfo &STI)

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

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

virtual void finishAttributeSection()

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

virtual void emitARMWinCFISaveSP(unsigned Reg)

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

virtual void emitARMWinCFISaveLR(unsigned Offset)

virtual void emitTextAttribute(unsigned Attribute, StringRef String)

virtual void emitARMWinCFIAllocStack(unsigned Size, bool Wide)

virtual void emitARMWinCFISaveRegMask(unsigned Mask, bool Wide)

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

virtual void emitARMWinCFIEpilogEnd()

virtual void emitARMWinCFIPrologEnd(bool Fragment)

virtual void switchVendor(StringRef Vendor)

virtual void emitCode16()

virtual void emitARMWinCFISaveFRegs(unsigned First, unsigned Last)

virtual void emitSyntaxUnified()

virtual void emitARMWinCFIEpilogStart(unsigned Condition)

virtual void emitPad(int64_t Offset)

virtual void emitAttribute(unsigned Attribute, unsigned Value)

virtual void emitARMWinCFINop(bool Wide)

const TargetLoweringObjectFile & getObjFileLowering() const

Return information about object file lowering.

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

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

MCSymbol * getSymbol(const GlobalValue *GV) const

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

virtual void emitGlobalVariable(const GlobalVariable *GV)

Emit the specified global variable to the .s file.

TargetMachine & TM

Target machine description.

void emitXRayTable()

Emit a table with all XRay instrumentation points.

virtual void emitGlobalAlias(const Module &M, const GlobalAlias &GA)

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.

AsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer, char &ID=AsmPrinter::ID)

void printOffset(int64_t Offset, raw_ostream &OS) const

This is just convenient handler for printing offsets.

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

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

MCSymbol * getSymbolPreferLocal(const GlobalValue &GV) const

Similar to getSymbol() but preferred for references.

MCSymbol * CurrentFnSym

The symbol for the current function.

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.

bool isPositionIndependent() const

void emitVisibility(MCSymbol *Sym, unsigned Visibility, bool IsDefinition=true) const

This emits visibility information about symbol, if this is supported by the target.

std::unique_ptr< MCStreamer > OutStreamer

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

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

MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const

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

const DataLayout & getDataLayout() const

Return information about data layout.

virtual void emitFunctionEntryLabel()

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

MCSymbol * GetExternalSymbolSymbol(const Twine &Sym) const

Return the MCSymbol for the specified ExternalSymbol.

const MCSubtargetInfo & getSubtargetInfo() const

Return information about subtarget.

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

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

The address of a basic block.

This is an important base class in LLVM.

const Constant * stripPointerCasts() const

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

LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const

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

bool hasFnAttribute(Attribute::AttrKind Kind) const

Return true if the function has the attribute.

LLVM_ABI const GlobalObject * getAliaseeObject() const

bool isThreadLocal() const

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

VisibilityTypes getVisibility() const

bool hasInternalLinkage() const

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

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 LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)

Lookup the symbol inside with the specified Name.

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

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, SMLoc Loc=SMLoc())

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

LLVM_ABI 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.

LLVM_ABI MCSymbol * getSymbol() const

Return the MCSymbol for this basic block.

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

union llvm::MachineConstantPoolEntry::@004270020304201266316354007027341142157160323045 Val

The constant itself.

bool isMachineConstantPoolEntry() const

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

MachineConstantPoolValue * MachineCPVal

const Constant * ConstVal

Abstract base class for all machine specific constantpool value subclasses.

const TargetSubtargetInfo & getSubtarget() const

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

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

const MachineOperand & getOperand(unsigned i) const

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

StubValueTy & getGVStubEntry(MCSymbol *Sym)

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

PointerIntPair< MCSymbol *, 1, bool > StubValueTy

MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation for MachO targets.

SymbolListTy GetThreadLocalGVStubList()

StubValueTy & getGVStubEntry(MCSymbol *Sym)

StubValueTy & getThreadLocalGVStubEntry(MCSymbol *Sym)

SymbolListTy GetGVStubList()

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

MachineOperand class - Representation of each machine instruction operand.

unsigned getSubReg() const

const GlobalValue * getGlobal() const

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.

Pass(PassKind K, char &pid)

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.

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

TypeSize getRegSizeInBits(const TargetRegisterClass &RC) const

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

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

Debug information queries.

virtual const TargetRegisterInfo * getRegisterInfo() const =0

Return the target's register information.

Triple - Helper class for working with autoconf configuration names.

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 "....

int getSOImmVal(unsigned Arg)

getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...

int getT2SOImmVal(unsigned Arg)

getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...

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

const MCSpecifierExpr * createLower16(const MCExpr *Expr, MCContext &Ctx)

const MCSpecifierExpr * createUpper16(const MCExpr *Expr, MCContext &Ctx)

SymbolStorageClass

Storage class tells where and what the symbol represents.

@ 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))

std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)

Extract a Value from Metadata, allowing null.

This is an optimization pass for GlobalISel generic memory operations.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

Target & getTheThumbBETarget()

@ MCDR_DataRegionEnd

.end_data_region

@ MCDR_DataRegion

.data_region

@ MCDR_DataRegionJT8

.data_region jt8

@ MCDR_DataRegionJT32

.data_region jt32

@ MCDR_DataRegionJT16

.data_region jt16

auto dyn_cast_or_null(const Y &Val)

bool any_of(R &&range, UnaryPredicate P)

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

MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

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

uint16_t MCPhysReg

An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...

DWARFExpression::Operation Op

OutputIt move(R &&Range, OutputIt Out)

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

DenormalMode parseDenormalFPAttribute(StringRef Str)

Returns the denormal mode to use for inputs and outputs.

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

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()

static constexpr DenormalMode getIEEE()

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