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 (->getOperand(OpNum).isImm())
349 return true;
350 O << ~(MI->getOperand(OpNum).getImm());
351 return false;
352 case 'L':
353 if (->getOperand(OpNum).isImm())
354 return true;
355 O << (MI->getOperand(OpNum).getImm() & 0xffff);
356 return false;
357 case 'M': {
358 if (->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 (->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 (->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();
668 return false;
670 ++F;
671 return std::any_of(F, E, [&](const Function &F) {
672 return .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 (.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 (.getTargetTriple().isOSBinFormatMachO()) {
2520 uint32_t Val = 0xe7ffdefeUL;
2523 return;
2524 }
2525 break;
2526 }
2527 case ARM::tTRAP: {
2528
2529
2530 if (.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,...