LLVM: lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
36using namespace llvm;
37
38namespace {
40public:
41 ARMELFObjectWriter(uint8_t OSABI)
43 false) {}
44};
45}
46
48 return std::nullopt;
49}
50
51std::optional
54#define ELF_RELOC(X, Y) .Case(#X, Y)
55#include "llvm/BinaryFormat/ELFRelocs/ARM.def"
56#undef ELF_RELOC
57 .Case("BFD_RELOC_NONE", ELF::R_ARM_NONE)
58 .Case("BFD_RELOC_8", ELF::R_ARM_ABS8)
59 .Case("BFD_RELOC_16", ELF::R_ARM_ABS16)
60 .Case("BFD_RELOC_32", ELF::R_ARM_ABS32)
62 if (Type == -1u)
63 return std::nullopt;
65}
66
69
70
71
72
74 {"fixup_t2_ldst_pcrel_12", 0, 32,
79 {"fixup_t2_pcrel_10", 0, 32,
83 {"fixup_t2_pcrel_9", 0, 32,
86 {"fixup_arm_ldst_abs_12", 0, 32, 0},
87 {"fixup_thumb_adr_pcrel_10", 0, 8,
91 {"fixup_t2_adr_pcrel_12", 0, 32,
103 {"fixup_arm_thumb_blx", 0, 32,
107 {"fixup_arm_thumb_cp", 0, 8,
111
112
113 {"fixup_arm_movt_hi16", 0, 20, 0},
114 {"fixup_arm_movw_lo16", 0, 20, 0},
115 {"fixup_t2_movt_hi16", 0, 20, 0},
116 {"fixup_t2_movw_lo16", 0, 20, 0},
117 {"fixup_arm_thumb_upper_8_15", 0, 8, 0},
118 {"fixup_arm_thumb_upper_0_7", 0, 8, 0},
119 {"fixup_arm_thumb_lower_8_15", 0, 8, 0},
120 {"fixup_arm_thumb_lower_0_7", 0, 8, 0},
121 {"fixup_arm_mod_imm", 0, 12, 0},
122 {"fixup_t2_so_imm", 0, 26, 0},
127 {"fixup_bfcsel_else_target", 0, 32, 0},
131
132
133
134
136 {"fixup_t2_ldst_pcrel_12", 0, 32,
141 {"fixup_t2_pcrel_10", 0, 32,
145 {"fixup_t2_pcrel_9", 0, 32,
148 {"fixup_arm_ldst_abs_12", 0, 32, 0},
149 {"fixup_thumb_adr_pcrel_10", 8, 8,
153 {"fixup_t2_adr_pcrel_12", 0, 32,
165 {"fixup_arm_thumb_blx", 0, 32,
169 {"fixup_arm_thumb_cp", 8, 8,
173
174
175 {"fixup_arm_movt_hi16", 12, 20, 0},
176 {"fixup_arm_movw_lo16", 12, 20, 0},
177 {"fixup_t2_movt_hi16", 12, 20, 0},
178 {"fixup_t2_movw_lo16", 12, 20, 0},
179 {"fixup_arm_thumb_upper_8_15", 24, 8, 0},
180 {"fixup_arm_thumb_upper_0_7", 24, 8, 0},
181 {"fixup_arm_thumb_lower_8_15", 24, 8, 0},
182 {"fixup_arm_thumb_lower_0_7", 24, 8, 0},
183 {"fixup_arm_mod_imm", 20, 12, 0},
184 {"fixup_t2_so_imm", 26, 6, 0},
189 {"fixup_bfcsel_else_target", 0, 32, 0},
192
193
194
197
200
202 "Invalid kind!");
204 ? InfosLE
206}
207
209 switch (Flag) {
210 default:
211 break;
214 break;
217 break;
218 }
219}
220
223 bool HasThumb2 = STI.hasFeature(ARM::FeatureThumb2);
224 bool HasV8MBaselineOps = STI.hasFeature(ARM::HasV8MBaselineOps);
225
226 switch (Op) {
227 default:
228 return Op;
229 case ARM::tBcc:
230 return HasThumb2 ? (unsigned)ARM::t2Bcc : Op;
231 case ARM::tLDRpci:
232 return HasThumb2 ? (unsigned)ARM::t2LDRpci : Op;
233 case ARM::tADR:
234 return HasThumb2 ? (unsigned)ARM::t2ADR : Op;
235 case ARM::tB:
236 return HasV8MBaselineOps ? (unsigned)ARM::t2B : Op;
237 case ARM::tCBZ:
238 return ARM::tHINT;
239 case ARM::tCBNZ:
240 return ARM::tHINT;
241 }
242}
243
247 return true;
248 return false;
249}
250
253 if (Offset < Min || Offset > Max)
254 return "out of range pc-relative fixup value";
255 return nullptr;
256}
257
260 switch (Fixup.getTargetKind()) {
262
263
264
265
266
267
270 return "out of range pc-relative fixup value";
271 break;
272 }
274
275
276
277
278
279
282 return "out of range pc-relative fixup value";
283 break;
284 }
287
288
291 return "misaligned pc-relative fixup value";
293 return "out of range pc-relative fixup value";
294 break;
295 }
297
298
299
302 return "will be converted to nop";
303 break;
304 }
316
317
318
319
320
321
322
323
327 return "out of range label-relative fixup value";
328 break;
329 }
330
331 default:
332 llvm_unreachable("Unexpected fixup kind in reasonForFixupRelaxation()!");
333 }
334 return nullptr;
335}
336
340}
341
345
346
347 if (RelaxedOp == Inst.getOpcode()) {
351 OS << "\n";
353 }
354
355
356
357 if ((Inst.getOpcode() == ARM::tCBZ || Inst.getOpcode() == ARM::tCBNZ) &&
358 RelaxedOp == ARM::tHINT) {
364 Inst = std::move(Res);
365 return;
366 }
367
368
369
371}
372
375 const uint16_t Thumb1_16bitNopEncoding = 0x46c0;
376 const uint16_t Thumb2_16bitNopEncoding = 0xbf00;
377 const uint32_t ARMv4_NopEncoding = 0xe1a00000;
378 const uint32_t ARMv6T2_NopEncoding = 0xe320f000;
381 hasNOP(STI) ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding;
382 uint64_t NumNops = Count / 2;
383 for (uint64_t i = 0; i != NumNops; ++i)
385 if (Count & 1)
386 OS << '\0';
387 return true;
388 }
389
391 hasNOP(STI) ? ARMv6T2_NopEncoding : ARMv4_NopEncoding;
392 uint64_t NumNops = Count / 4;
393 for (uint64_t i = 0; i != NumNops; ++i)
395
396
397 switch (Count % 4) {
398 default:
399 break;
400 case 1:
401 OS << '\0';
402 break;
403 case 2:
405 break;
406 case 3:
408 break;
409 }
410
411 return true;
412}
413
415 if (IsLittleEndian) {
416
417
419 Swapped |= (Value & 0x0000FFFF) << 16;
420 return Swapped;
421 } else
423}
424
426 bool IsLittleEndian) {
428
429 if (IsLittleEndian) {
430 Value = (SecondHalf & 0xFFFF) << 16;
431 Value |= (FirstHalf & 0xFFFF);
432 } else {
433 Value = (SecondHalf & 0xFFFF);
434 Value |= (FirstHalf & 0xFFFF) << 16;
435 }
436
438}
439
445 unsigned Kind = Fixup.getKind();
446 int64_t Addend = Target.getConstant();
447
448
449
454 return 0;
455 }
456
457
458
459
460
461
463 if (A->hasSubsectionsViaSymbols() && Asm.isThumbFunc(&A->getSymbol()) &&
464 A->getSymbol().isExternal() &&
469 }
470
471 switch (Kind) {
472 default:
473 return 0;
483 assert(STI != nullptr);
486 [[fallthrough]];
488 unsigned Hi4 = (Value & 0xF000) >> 12;
489 unsigned Lo12 = Value & 0x0FFF;
490
491
492 Value = (Hi4 << 16) | (Lo12);
494 }
496 assert(STI != nullptr);
499 [[fallthrough]];
501 unsigned Hi4 = (Value & 0xF000) >> 12;
502 unsigned i = (Value & 0x800) >> 11;
503 unsigned Mid3 = (Value & 0x700) >> 8;
504 unsigned Lo8 = Value & 0x0FF;
505
506
507
508
509 Value = (Hi4 << 16) | (i << 26) | (Mid3 << 12) | (Lo8);
511 }
514 return (Value & 0xff000000) >> 24;
515 return Value & 0xff;
518 return (Value & 0x00ff0000) >> 16;
519 return Value & 0xff;
522 return (Value & 0x0000ff00) >> 8;
523 return Value & 0xff;
525 return Value & 0x000000ff;
527
529 [[fallthrough]];
531
533 [[fallthrough]];
535 bool isAdd = true;
536 if ((int64_t)Value < 0) {
538 isAdd = false;
539 }
540 if (Value >= 4096) {
541 Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
542 return 0;
543 }
544 Value |= isAdd << 23;
545
546
547
550
552 }
554
556 unsigned opc = 4;
557 if ((int64_t)Value < 0) {
559 opc = 2;
560 }
562 Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
563 return 0;
564 }
565
567 }
568
571 unsigned opc = 0;
572 if ((int64_t)Value < 0) {
574 opc = 5;
575 }
576
578 out |= (Value & 0x800) << 15;
579 out |= (Value & 0x700) << 4;
580 out |= (Value & 0x0FF);
581
583 }
584
590
592 if (!isInt<26>(Value)) {
594 return 0;
595 }
596
597
601 return 0;
602 }
603
604
605
607 dyn_cast(Fixup.getValue()))
609 return 0;
610 return 0xffffff & (Value >> 2);
614
615
617 "cannot perform a PC-relative fixup with a non-zero "
618 "symbol offset");
619 }
621 if (!isInt<25>(Value)) {
623 return 0;
624 }
625
626 Value >>= 1;
627
629 bool I = Value & 0x800000;
630 bool J1 = Value & 0x400000;
631 bool J2 = Value & 0x200000;
632 J1 ^= I;
633 J2 ^= I;
634
635 out |= I << 26;
636 out |= !J1 << 13;
637 out |= !J2 << 11;
638 out |= (Value & 0x1FF800) << 5;
639 out |= (Value & 0x0007FF);
640
642 }
645 if (!isInt<21>(Value)) {
647 return 0;
648 }
649
650 Value >>= 1;
651
653 out |= (Value & 0x80000) << 7;
654 out |= (Value & 0x40000) >> 7;
655 out |= (Value & 0x20000) >> 4;
656 out |= (Value & 0x1F800) << 5;
657 out |= (Value & 0x007FF);
658
660 }
662 if (!isInt<25>(Value - 4) ||
663 (!STI->hasFeature(ARM::FeatureThumb2) &&
664 !STI->hasFeature(ARM::HasV8MBaselineOps) &&
666 !isInt<23>(Value - 4))) {
668 return 0;
669 }
672
673
675 "cannot perform a PC-relative fixup with a non-zero "
676 "symbol offset");
677 }
678
679
680
681
682
683
684
685
686
687
688
689
690
692 uint32_t signBit = (offset & 0x800000) >> 23;
693 uint32_t I1Bit = (offset & 0x400000) >> 22;
694 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
695 uint32_t I2Bit = (offset & 0x200000) >> 21;
696 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
697 uint32_t imm10Bits = (offset & 0x1FF800) >> 11;
698 uint32_t imm11Bits = (offset & 0x000007FF);
699
705 }
709
710
712 "cannot perform a PC-relative fixup with a non-zero "
713 "symbol offset");
714 }
715
716
717
718
719
720
721
722
723
724
725
726
727 if (Value % 4 != 0) {
728 Ctx.reportError(Fixup.getLoc(), "misaligned ARM call destination");
729 return 0;
730 }
731
734 dyn_cast(Fixup.getValue()))
736 offset = 0;
737 uint32_t signBit = (offset & 0x400000) >> 22;
738 uint32_t I1Bit = (offset & 0x200000) >> 21;
739 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
740 uint32_t I2Bit = (offset & 0x100000) >> 20;
741 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
742 uint32_t imm10HBits = (offset & 0xFFC00) >> 10;
743 uint32_t imm10LBits = (offset & 0x3FF);
744
747 ((uint16_t)imm10LBits) << 1);
750 }
753
754
755 assert(STI != nullptr);
756 if (!STI->hasFeature(ARM::FeatureThumb2) && IsResolved) {
758 if (FixupDiagnostic) {
760 return 0;
761 }
762 }
763
764 return ((Value - 4) >> 2) & 0xff;
766
767
768
769 if ((int64_t)Value < 2 || Value > 0x82 || Value & 1) {
770 Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
771 return 0;
772 }
773
774
776 return ((Binary & 0x20) << 4) | ((Binary & 0x1f) << 3);
777 }
779
780 assert(STI != nullptr);
781 if (!STI->hasFeature(ARM::FeatureThumb2) &&
782 !STI->hasFeature(ARM::HasV8MBaselineOps)) {
784 if (FixupDiagnostic) {
786 return 0;
787 }
788 }
789 return ((Value - 4) >> 1) & 0x7ff;
791
792 assert(STI != nullptr);
793 if (!STI->hasFeature(ARM::FeatureThumb2)) {
795 if (FixupDiagnostic) {
797 return 0;
798 }
799 }
800 return ((Value - 4) >> 1) & 0xff;
803
804 bool isAdd = true;
805 if ((int64_t)Value < 0) {
807 isAdd = false;
808 }
809
810 if (Value >= 256) {
811 Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
812 return 0;
813 }
815 return Value | (isAdd << 23);
816 }
819
820 [[fallthrough]];
822
824 bool isAdd = true;
825 if ((int64_t)Value < 0) {
827 isAdd = false;
828 }
829
831 if (Value >= 256) {
832 Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
833 return 0;
834 }
835 Value |= isAdd << 23;
836
837
838
841
843 }
846
847 [[fallthrough]];
849
851 bool isAdd = true;
852 if ((int64_t)Value < 0) {
854 isAdd = false;
855 }
856
858 Ctx.reportError(Fixup.getLoc(), "invalid value for this fixup");
859 return 0;
860 }
862 if (Value >= 256) {
863 Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
864 return 0;
865 }
866 Value |= isAdd << 23;
867
868
869
872
874 }
877 if (Value >> 12) {
878 Ctx.reportError(Fixup.getLoc(), "out of range immediate fixup value");
879 return 0;
880 }
884 if ((int64_t)Value < 0) {
885 Ctx.reportError(Fixup.getLoc(), "out of range immediate fixup value");
886 return 0;
887 }
888
889
890
891
892
894 EncValue |= (Value & 0x800) << 15;
895 EncValue |= (Value & 0x700) << 4;
896 EncValue |= (Value & 0xff);
898 }
901 if (FixupDiagnostic) {
903 return 0;
904 }
907 }
912 if (FixupDiagnostic) {
914 return 0;
915 }
919 out |= (((Value - 4) >> 1) & 0x1) << 11;
920 out |= (((Value - 4) >> 1) & 0x7fe);
921 out |= (((Value - 4) >> 1) & HighBitMask) << 5;
923 }
925
926
927
929
931 if (FixupDiagnostic) {
933 return 0;
934 }
937 }
941 if (FixupDiagnostic) {
943 return 0;
944 }
948 real_value = -real_value;
949 out |= ((real_value >> 1) & 0x1) << 11;
950 out |= ((real_value >> 1) & 0x7fe);
952 }
953 }
954}
955
961 const MCSymbol *Sym = A ? &A->getSymbol() : nullptr;
962 const unsigned FixupKind = Fixup.getKind();
964 return true;
966 assert(Sym && "How did we resolve this?");
967
968
969
970
971
972
973 if (Sym->isExternal())
974 return true;
975 }
976
977
978 if (Sym && Sym->isELF()) {
979 unsigned Type = cast(Sym)->getType();
982 return true;
987 return true;
988 }
989 }
990
991
992
997 return true;
998 return false;
999}
1000
1001
1003 switch (Kind) {
1004 default:
1006
1015 return 1;
1016
1021 return 2;
1022
1034 return 3;
1035
1057 return 4;
1058
1060 return 2;
1062 return 4;
1063 }
1064}
1065
1066
1067
1069 switch (Kind) {
1070 default:
1072
1074 return 1;
1076 return 2;
1078 return 4;
1079
1089
1090 return 2;
1091
1123
1124 return 4;
1125 }
1126}
1127
1131 bool IsResolved,
1133 unsigned Kind = Fixup.getKind();
1135 return;
1136 MCContext &Ctx = Asm.getContext();
1139 return;
1141
1143 assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
1144
1145
1146 unsigned FullSizeBytes;
1149 assert((Offset + FullSizeBytes) <= Data.size() && "Invalid fixup size!");
1150 assert(NumBytes <= FullSizeBytes && "Invalid fixup size!");
1151 }
1152
1153
1154
1155
1156 for (unsigned i = 0; i != NumBytes; ++i) {
1157 unsigned Idx =
1160 }
1161}
1162
1163namespace CU {
1164
1165
1171
1173
1177
1183
1185
1188
1189}
1190
1191
1192
1193
1194
1198
1200 return 0;
1201
1203 if (Instrs.empty())
1204 return 0;
1208
1209
1211 int CFARegisterOffset = 0;
1212
1214 int FloatRegCount = 0;
1215
1218 switch (Inst.getOperation()) {
1220 CFARegisterOffset = Inst.getOffset();
1221 CFARegister = *MRI.getLLVMRegNum(Inst.getRegister(), true);
1222 break;
1224 CFARegisterOffset = Inst.getOffset();
1225 break;
1227 CFARegister = *MRI.getLLVMRegNum(Inst.getRegister(), true);
1228 break;
1230 Reg = *MRI.getLLVMRegNum(Inst.getRegister(), true);
1231 if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
1232 RegOffsets[Reg] = Inst.getOffset();
1233 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
1234 RegOffsets[Reg] = Inst.getOffset();
1235 ++FloatRegCount;
1236 } else {
1238 llvm::dbgs() << ".cfi_offset on unknown register="
1239 << Inst.getRegister() << "\n");
1241 }
1242 break;
1244
1245 break;
1246 default:
1247
1250 << "CFI directive not compatible with compact "
1251 "unwind encoding, opcode="
1252 << uint8_t(Inst.getOperation()) << "\n");
1254 break;
1255 }
1256 }
1257
1258
1259 if ((CFARegister == ARM::SP) && (CFARegisterOffset == 0))
1260 return 0;
1261
1262
1263 if (CFARegister != ARM::R7) {
1265 << CFARegister
1266 << " instead of r7\n");
1268 }
1269 int StackAdjust = CFARegisterOffset - 8;
1270 if (RegOffsets.lookup(ARM::LR) != (-4 - StackAdjust)) {
1272 "compact-unwind",
1273 llvm::dbgs() << "LR not saved as standard frame, StackAdjust="
1274 << StackAdjust
1275 << ", CFARegisterOffset=" << CFARegisterOffset
1276 << ", lr save at offset=" << RegOffsets[ARM::LR] << "\n");
1278 }
1279 if (RegOffsets.lookup(ARM::R7) != (-8 - StackAdjust)) {
1281 llvm::dbgs() << "r7 not saved as standard frame\n");
1283 }
1285
1286
1287 switch (StackAdjust) {
1288 case 0:
1289 break;
1290 case 4:
1291 CompactUnwindEncoding |= 0x00400000;
1292 break;
1293 case 8:
1294 CompactUnwindEncoding |= 0x00800000;
1295 break;
1296 case 12:
1297 CompactUnwindEncoding |= 0x00C00000;
1298 break;
1299 default:
1301 << ".cfi_def_cfa stack adjust ("
1302 << StackAdjust << ") out of range\n");
1304 }
1305
1306
1307 static struct {
1308 unsigned Reg;
1309 unsigned Encoding;
1318
1319 int CurOffset = -8 - StackAdjust;
1320 for (auto CSReg : GPRCSRegs) {
1321 auto Offset = RegOffsets.find(CSReg.Reg);
1323 continue;
1324
1325 int RegOffset = Offset->second;
1326 if (RegOffset != CurOffset - 4) {
1329 << RegOffset << " but only supported at "
1330 << CurOffset << "\n");
1332 }
1333 CompactUnwindEncoding |= CSReg.Encoding;
1334 CurOffset -= 4;
1335 }
1336
1337
1338 if (FloatRegCount == 0)
1339 return CompactUnwindEncoding;
1340
1341
1342 CompactUnwindEncoding &= ~CU::UNWIND_ARM_MODE_MASK;
1344
1345
1346
1347 if (FloatRegCount > 4) {
1349 llvm::dbgs() << "unsupported number of D registers saved ("
1350 << FloatRegCount << ")\n");
1352 }
1353
1354
1355
1356
1357 static MCPhysReg FPRCSRegs[] = {ARM::D8, ARM::D10, ARM::D12, ARM::D14};
1358 for (int Idx = FloatRegCount - 1; Idx >= 0; --Idx) {
1360 if (Offset == RegOffsets.end()) {
1362 llvm::dbgs() << FloatRegCount << " D-regs saved, but "
1364 << " not saved\n");
1366 } else if (Offset->second != CurOffset - 8) {
1368 llvm::dbgs() << FloatRegCount << " D-regs saved, but "
1370 << " saved at " << Offset->second
1371 << ", expected at " << CurOffset - 8
1372 << "\n");
1374 }
1375 CurOffset -= 8;
1376 }
1377
1378 return CompactUnwindEncoding | ((FloatRegCount - 1) << 8);
1379}
1380
1388 default:
1393 assert(TheTriple.isOSWindows() && "non-Windows ARM COFF is not supported");
1402 }
1403}
1404
1410}
1411
1417}
unsigned const MachineRegisterInfo * MRI
static unsigned getFixupKindNumBytes(unsigned Kind)
The number of bytes the fixup may change.
static uint32_t swapHalfWords(uint32_t Value, bool IsLittleEndian)
static unsigned getFixupKindContainerSizeBytes(unsigned Kind)
getFixupKindContainerSizeBytes - The number of bytes of the container involved in big endian.
static MCAsmBackend * createARMAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options, llvm::endianness Endian)
static uint32_t joinHalfWords(uint32_t FirstHalf, uint32_t SecondHalf, bool IsLittleEndian)
static const char * checkPCRelOffset(uint64_t Value, int64_t Min, int64_t Max)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
PowerPC TLS Dynamic Call Fixup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
uint64_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI, const MCContext *Ctxt) const override
Generate compact unwind encoding for the function based on the CFI instructions.
const MachO::CPUSubTypeARM Subtype
std::optional< MCFixupKind > getFixupKind(StringRef Name) const override
Map a relocation name used in .reloc to a fixup kind.
bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value) const override
Simple predicate for targets where !Resolved implies requiring relaxation.
const char * reasonForFixupRelaxation(const MCFixup &Fixup, uint64_t Value) const
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef< char > Data, uint64_t Value, bool IsResolved, const MCSubtargetInfo *STI) const override
Apply the Value for given Fixup into the provided data fragment, at the offset specified by the fixup...
const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const override
Get information on a fixup kind.
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, const uint64_t Value, const MCSubtargetInfo *STI) override
Hook to check if a relocation is needed for some target specific reason.
unsigned getNumFixupKinds() const override
Get the number of target specific fixup kinds.
bool hasNOP(const MCSubtargetInfo *STI) const
unsigned getRelaxedOpcode(unsigned Op, const MCSubtargetInfo &STI) const
unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, uint64_t Value, bool IsResolved, MCContext &Ctx, const MCSubtargetInfo *STI) const
bool writeNopData(raw_ostream &OS, uint64_t Count, const MCSubtargetInfo *STI) const override
Write an (optimal) nop sequence of Count bytes to the given output.
std::optional< MCFixupKind > getFixupKind(StringRef Name) const override
Map a relocation name used in .reloc to a fixup kind.
void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const override
Relax the instruction in the given fragment to the next wider instruction.
bool mayNeedRelaxation(const MCInst &Inst, const MCSubtargetInfo &STI) const override
Check whether the given instruction may need relaxation.
void handleAssemblerFlag(MCAssemblerFlag Flag) override
Handle any target-specific assembler flags. By default, do nothing.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
This class represents an Operation in the Expression.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
iterator find(const_arg_type_t< KeyT > Val)
Generic interface to target specific assembler backends.
const llvm::endianness Endian
bool isDarwinCanonicalPersonality(const MCSymbol *Sym) const
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
Context object for machine code objects.
bool emitCompactUnwindNonCanonical() const
void reportError(SMLoc L, const Twine &Msg)
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Instances of this class represent a single low-level machine instruction.
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ", const MCRegisterInfo *RegInfo=nullptr) const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
const char * getName(MCRegister RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register.
std::optional< MCRegister > getLLVMRegNum(uint64_t RegNum, bool isEH) const
Map a dwarf register back to a target register.
Wrapper class representing physical registers. Should be passed by value.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const Triple & getTargetTriple() const
Represent a reference to a symbol from inside an expression.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
This represents an "assembler immediate".
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef - Represent a constant reference to a string, i.e.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
bool isThumb() const
Tests whether the target is Thumb (little and big endian).
ObjectFormatType getObjectFormat() const
Get the object format for this triple.
OSType getOS() const
Get the parsed operating system type of this triple.
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
bool isOSWindows() const
Tests whether the OS is Windows.
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write(unsigned char C)
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.
CompactUnwindEncodings
Compact unwind encoding values.
@ UNWIND_ARM_FRAME_SECOND_PUSH_R10
@ UNWIND_ARM_FRAME_FIRST_PUSH_R6
@ UNWIND_ARM_FRAME_SECOND_PUSH_R11
@ UNWIND_ARM_DWARF_SECTION_OFFSET
@ UNWIND_ARM_FRAME_FIRST_PUSH_R4
@ UNWIND_ARM_FRAME_SECOND_PUSH_R9
@ UNWIND_ARM_FRAME_SECOND_PUSH_R8
@ UNWIND_ARM_FRAME_STACK_ADJUST_MASK
@ UNWIND_ARM_FRAME_SECOND_PUSH_R12
@ UNWIND_ARM_FRAME_D_REG_COUNT_MASK
@ UNWIND_ARM_MODE_FRAME_D
@ UNWIND_ARM_FRAME_FIRST_PUSH_R5
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...
@ fixup_thumb_adr_pcrel_10
@ fixup_arm_thumb_upper_8_15
@ fixup_arm_thumb_lower_0_7
@ fixup_arm_pcrel_10_unscaled
@ fixup_arm_thumb_upper_0_7
@ fixup_bfcsel_else_target
@ fixup_arm_ldst_pcrel_12
@ fixup_arm_thumb_lower_8_15
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
This is an optimization pass for GlobalISel generic memory operations.
int64_t maxIntN(int64_t N)
Gets the maximum value for a N-bit signed integer.
MCAsmBackend * createARMBEAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
MCAsmBackend * createARMLEAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
MCFixupKind
Extensible enumeration to represent the type of a fixup.
@ FK_SecRel_2
A two-byte section relative fixup.
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
@ FK_Data_1
A one-byte fixup.
@ FK_Data_4
A four-byte fixup.
@ FK_SecRel_4
A four-byte section relative fixup.
@ FK_Data_2
A two-byte fixup.
@ MCAF_Code16
.code16 (X86) / .code 16 (ARM)
@ MCAF_Code32
.code32 (X86) / .code 32 (ARM)
DWARFExpression::Operation Op
int64_t minIntN(int64_t N)
Gets the minimum value for a N-bit signed integer.
const MCSymbol * Personality
std::vector< MCCFIInstruction > Instructions
Target independent information on a fixup kind.
@ FKF_IsAlignedDownTo32Bits
Should this fixup kind force a 4-byte aligned effective PC value?
@ FKF_IsPCRel
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...