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)
42 : MCELFObjectTargetWriter( false, OSABI, ELF::EM_ARM,
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
73 {"fixup_arm_ldst_pcrel_12", 0, 32, 0},
74 {"fixup_t2_ldst_pcrel_12", 0, 32, 0},
75 {"fixup_arm_pcrel_10_unscaled", 0, 32, 0},
76 {"fixup_arm_pcrel_10", 0, 32, 0},
77 {"fixup_t2_pcrel_10", 0, 32, 0},
78 {"fixup_arm_pcrel_9", 0, 32, 0},
79 {"fixup_t2_pcrel_9", 0, 32, 0},
80 {"fixup_arm_ldst_abs_12", 0, 32, 0},
81 {"fixup_thumb_adr_pcrel_10", 0, 8, 0},
82 {"fixup_arm_adr_pcrel_12", 0, 32, 0},
83 {"fixup_t2_adr_pcrel_12", 0, 32, 0},
84 {"fixup_arm_condbranch", 0, 24, 0},
85 {"fixup_arm_uncondbranch", 0, 24, 0},
86 {"fixup_t2_condbranch", 0, 32, 0},
87 {"fixup_t2_uncondbranch", 0, 32, 0},
88 {"fixup_arm_thumb_br", 0, 16, 0},
89 {"fixup_arm_uncondbl", 0, 24, 0},
90 {"fixup_arm_condbl", 0, 24, 0},
91 {"fixup_arm_blx", 0, 24, 0},
92 {"fixup_arm_thumb_bl", 0, 32, 0},
93 {"fixup_arm_thumb_blx", 0, 32, 0},
94 {"fixup_arm_thumb_cb", 0, 16, 0},
95 {"fixup_arm_thumb_cp", 0, 8, 0},
96 {"fixup_arm_thumb_bcc", 0, 8, 0},
97
98
99 {"fixup_arm_movt_hi16", 0, 20, 0},
100 {"fixup_arm_movw_lo16", 0, 20, 0},
101 {"fixup_t2_movt_hi16", 0, 20, 0},
102 {"fixup_t2_movw_lo16", 0, 20, 0},
103 {"fixup_arm_thumb_upper_8_15", 0, 8, 0},
104 {"fixup_arm_thumb_upper_0_7", 0, 8, 0},
105 {"fixup_arm_thumb_lower_8_15", 0, 8, 0},
106 {"fixup_arm_thumb_lower_0_7", 0, 8, 0},
107 {"fixup_arm_mod_imm", 0, 12, 0},
108 {"fixup_t2_so_imm", 0, 26, 0},
109 {"fixup_bf_branch", 0, 32, 0},
110 {"fixup_bf_target", 0, 32, 0},
111 {"fixup_bfl_target", 0, 32, 0},
112 {"fixup_bfc_target", 0, 32, 0},
113 {"fixup_bfcsel_else_target", 0, 32, 0},
114 {"fixup_wls", 0, 32, 0},
115 {"fixup_le", 0, 32, 0},
116 };
118
119
120
121
122 {"fixup_arm_ldst_pcrel_12", 0, 32, 0},
123 {"fixup_t2_ldst_pcrel_12", 0, 32, 0},
124 {"fixup_arm_pcrel_10_unscaled", 0, 32, 0},
125 {"fixup_arm_pcrel_10", 0, 32, 0},
126 {"fixup_t2_pcrel_10", 0, 32, 0},
127 {"fixup_arm_pcrel_9", 0, 32, 0},
128 {"fixup_t2_pcrel_9", 0, 32, 0},
129 {"fixup_arm_ldst_abs_12", 0, 32, 0},
130 {"fixup_thumb_adr_pcrel_10", 8, 8, 0},
131 {"fixup_arm_adr_pcrel_12", 0, 32, 0},
132 {"fixup_t2_adr_pcrel_12", 0, 32, 0},
133 {"fixup_arm_condbranch", 8, 24, 0},
134 {"fixup_arm_uncondbranch", 8, 24, 0},
135 {"fixup_t2_condbranch", 0, 32, 0},
136 {"fixup_t2_uncondbranch", 0, 32, 0},
137 {"fixup_arm_thumb_br", 0, 16, 0},
138 {"fixup_arm_uncondbl", 8, 24, 0},
139 {"fixup_arm_condbl", 8, 24, 0},
140 {"fixup_arm_blx", 8, 24, 0},
141 {"fixup_arm_thumb_bl", 0, 32, 0},
142 {"fixup_arm_thumb_blx", 0, 32, 0},
143 {"fixup_arm_thumb_cb", 0, 16, 0},
144 {"fixup_arm_thumb_cp", 8, 8, 0},
145 {"fixup_arm_thumb_bcc", 8, 8, 0},
146
147
148 {"fixup_arm_movt_hi16", 12, 20, 0},
149 {"fixup_arm_movw_lo16", 12, 20, 0},
150 {"fixup_t2_movt_hi16", 12, 20, 0},
151 {"fixup_t2_movw_lo16", 12, 20, 0},
152 {"fixup_arm_thumb_upper_8_15", 24, 8, 0},
153 {"fixup_arm_thumb_upper_0_7", 24, 8, 0},
154 {"fixup_arm_thumb_lower_8_15", 24, 8, 0},
155 {"fixup_arm_thumb_lower_0_7", 24, 8, 0},
156 {"fixup_arm_mod_imm", 20, 12, 0},
157 {"fixup_t2_so_imm", 26, 6, 0},
158 {"fixup_bf_branch", 0, 32, 0},
159 {"fixup_bf_target", 0, 32, 0},
160 {"fixup_bfl_target", 0, 32, 0},
161 {"fixup_bfc_target", 0, 32, 0},
162 {"fixup_bfcsel_else_target", 0, 32, 0},
163 {"fixup_wls", 0, 32, 0},
164 {"fixup_le", 0, 32, 0},
165 };
166
167
168
170 return {};
171
174
176 "Invalid kind!");
178 ? InfosLE
180}
181
184 bool HasThumb2 = STI.hasFeature(ARM::FeatureThumb2);
185 bool HasV8MBaselineOps = STI.hasFeature(ARM::HasV8MBaselineOps);
186
187 switch (Op) {
188 default:
189 return Op;
190 case ARM::tBcc:
191 return HasThumb2 ? (unsigned)ARM::t2Bcc : Op;
192 case ARM::tLDRpci:
193 return HasThumb2 ? (unsigned)ARM::t2LDRpci : Op;
194 case ARM::tADR:
195 return HasThumb2 ? (unsigned)ARM::t2ADR : Op;
196 case ARM::tB:
197 return HasV8MBaselineOps ? (unsigned)ARM::t2B : Op;
198 case ARM::tCBZ:
199 return ARM::tHINT;
200 case ARM::tCBNZ:
201 return ARM::tHINT;
202 }
203}
204
209
213 return "out of range pc-relative fixup value";
214 return nullptr;
215}
216
219 switch (Fixup.getKind()) {
221
222
223
224
225
226
229 return "out of range pc-relative fixup value";
230 break;
231 }
233
234
235
236
237
238
241 return "out of range pc-relative fixup value";
242 break;
243 }
246
247
250 return "misaligned pc-relative fixup value";
252 return "out of range pc-relative fixup value";
253 break;
254 }
256
257
258
261 return "will be converted to nop";
262 break;
263 }
275
276
277
278
279
280
281
282
286 return "out of range label-relative fixup value";
287 break;
288 }
289
290 default:
291 llvm_unreachable("Unexpected fixup kind in reasonForFixupRelaxation()!");
292 }
293 return nullptr;
294}
295
298
299
300 if (!Sym || !Asm.getContext().isELF())
301 return false;
305 return true;
310 return true;
311 }
312 return false;
313}
314
319 bool Resolved) const {
322 return true;
323
324 if (!Resolved)
325 return true;
327}
328
333
334
335
336 if ((Inst.getOpcode() == ARM::tCBZ || Inst.getOpcode() == ARM::tCBNZ) &&
337 RelaxedOp == ARM::tHINT) {
343 Inst = std::move(Res);
344 return;
345 }
346
347
348
350}
351
354 const uint16_t Thumb1_16bitNopEncoding = 0x46c0;
355 const uint16_t Thumb2_16bitNopEncoding = 0xbf00;
356 const uint32_t ARMv4_NopEncoding = 0xe1a00000;
357 const uint32_t ARMv6T2_NopEncoding = 0xe320f000;
358 if (STI->hasFeature(ARM::ModeThumb)) {
360 hasNOP(STI) ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding;
362 for (uint64_t i = 0; i != NumNops; ++i)
365 OS << '\0';
366 return true;
367 }
368
370 hasNOP(STI) ? ARMv6T2_NopEncoding : ARMv4_NopEncoding;
372 for (uint64_t i = 0; i != NumNops; ++i)
374
375
376 switch (Count % 4) {
377 default:
378 break;
379 case 1:
380 OS << '\0';
381 break;
382 case 2:
383 OS.write("\0\0", 2);
384 break;
385 case 3:
386 OS.write("\0\0\xa0", 3);
387 break;
388 }
389
390 return true;
391}
392
394 if (IsLittleEndian) {
395
396
398 Swapped |= (Value & 0x0000FFFF) << 16;
399 return Swapped;
400 } else
402}
403
405 bool IsLittleEndian) {
407
408 if (IsLittleEndian) {
409 Value = (SecondHalf & 0xFFFF) << 16;
410 Value |= (FirstHalf & 0xFFFF);
411 } else {
412 Value = (SecondHalf & 0xFFFF);
413 Value |= (FirstHalf & 0xFFFF) << 16;
414 }
415
417}
418
424 unsigned Kind = Fixup.getKind();
425 int64_t Addend = Target.getConstant();
426
427
428
431 !IsResolved && (Addend < minIntN(16) || Addend > maxIntN(16))) {
432 Ctx.reportError(Fixup.getLoc(), "Relocation Not In Range");
433 return 0;
434 }
435
436
437
438
439
440
443 if (Asm.isThumbFunc(SA) && SA->isExternal() &&
448 }
449 }
450
451 switch (Kind) {
452 default:
453 return 0;
463 assert(STI != nullptr);
466 [[fallthrough]];
468 unsigned Hi4 = (Value & 0xF000) >> 12;
469 unsigned Lo12 = Value & 0x0FFF;
470
471
472 Value = (Hi4 << 16) | (Lo12);
474 }
476 assert(STI != nullptr);
479 [[fallthrough]];
481 unsigned Hi4 = (Value & 0xF000) >> 12;
482 unsigned i = (Value & 0x800) >> 11;
483 unsigned Mid3 = (Value & 0x700) >> 8;
484 unsigned Lo8 = Value & 0x0FF;
485
486
487
488
489 Value = (Hi4 << 16) | (i << 26) | (Mid3 << 12) | (Lo8);
491 }
494 return (Value & 0xff000000) >> 24;
495 return Value & 0xff;
498 return (Value & 0x00ff0000) >> 16;
499 return Value & 0xff;
502 return (Value & 0x0000ff00) >> 8;
503 return Value & 0xff;
505 return Value & 0x000000ff;
507
509 [[fallthrough]];
511
513 [[fallthrough]];
515 bool isAdd = true;
516 if ((int64_t)Value < 0) {
518 isAdd = false;
519 }
520 if (Value >= 4096) {
521 Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
522 return 0;
523 }
524 Value |= isAdd << 23;
525
526
527
530
532 }
534
536 unsigned opc = 4;
537 if ((int64_t)Value < 0) {
539 opc = 2;
540 }
542 Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
543 return 0;
544 }
545
547 }
548
551 unsigned opc = 0;
552 if ((int64_t)Value < 0) {
554 opc = 5;
555 }
556
558 out |= (Value & 0x800) << 15;
559 out |= (Value & 0x700) << 4;
560 out |= (Value & 0x0FF);
561
563 }
564
570
573 Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
574 return 0;
575 }
576
577
580 Ctx.reportError(Fixup.getLoc(), "Relocation not aligned");
581 return 0;
582 }
583
584
585
589 return 0;
590 return 0xffffff & (Value >> 2);
594
595
596 Ctx.reportError(Fixup.getLoc(),
597 "cannot perform a PC-relative fixup with a non-zero "
598 "symbol offset");
599 }
602 Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
603 return 0;
604 }
605
606 Value >>= 1;
607
609 bool I = Value & 0x800000;
610 bool J1 = Value & 0x400000;
611 bool J2 = Value & 0x200000;
612 J1 ^= I;
613 J2 ^= I;
614
615 out |= I << 26;
616 out |= !J1 << 13;
617 out |= !J2 << 11;
618 out |= (Value & 0x1FF800) << 5;
619 out |= (Value & 0x0007FF);
620
622 }
626 Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
627 return 0;
628 }
629
630 Value >>= 1;
631
633 out |= (Value & 0x80000) << 7;
634 out |= (Value & 0x40000) >> 7;
635 out |= (Value & 0x20000) >> 4;
636 out |= (Value & 0x1F800) << 5;
637 out |= (Value & 0x007FF);
638
640 }
643 (!STI->hasFeature(ARM::FeatureThumb2) &&
644 !STI->hasFeature(ARM::HasV8MBaselineOps) &&
647 Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
648 return 0;
649 }
652
653
654 Ctx.reportError(Fixup.getLoc(),
655 "cannot perform a PC-relative fixup with a non-zero "
656 "symbol offset");
657 }
658
659
660
661
662
663
664
665
666
667
668
669
670
672 uint32_t signBit = (offset & 0x800000) >> 23;
673 uint32_t I1Bit = (offset & 0x400000) >> 22;
674 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
675 uint32_t I2Bit = (offset & 0x200000) >> 21;
676 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
677 uint32_t imm10Bits = (offset & 0x1FF800) >> 11;
678 uint32_t imm11Bits = (offset & 0x000007FF);
679
685 }
689
690
691 Ctx.reportError(Fixup.getLoc(),
692 "cannot perform a PC-relative fixup with a non-zero "
693 "symbol offset");
694 }
695
696
697
698
699
700
701
702
703
704
705
706
707 if (Value % 4 != 0) {
708 Ctx.reportError(Fixup.getLoc(), "misaligned ARM call destination");
709 return 0;
710 }
711
716 offset = 0;
717 uint32_t signBit = (offset & 0x400000) >> 22;
718 uint32_t I1Bit = (offset & 0x200000) >> 21;
719 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
720 uint32_t I2Bit = (offset & 0x100000) >> 20;
721 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
722 uint32_t imm10HBits = (offset & 0xFFC00) >> 10;
723 uint32_t imm10LBits = (offset & 0x3FF);
724
727 ((uint16_t)imm10LBits) << 1);
730 }
733
734
735 assert(STI != nullptr);
736 if (!STI->hasFeature(ARM::FeatureThumb2) && IsResolved) {
738 if (FixupDiagnostic) {
739 Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
740 return 0;
741 }
742 }
743
744 return ((Value - 4) >> 2) & 0xff;
746
747
748
750 Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
751 return 0;
752 }
753
754
756 return ((Binary & 0x20) << 4) | ((Binary & 0x1f) << 3);
757 }
759
760 assert(STI != nullptr);
761 if (!STI->hasFeature(ARM::FeatureThumb2) &&
762 !STI->hasFeature(ARM::HasV8MBaselineOps)) {
764 if (FixupDiagnostic) {
765 Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
766 return 0;
767 }
768 }
769 return ((Value - 4) >> 1) & 0x7ff;
771
772 assert(STI != nullptr);
773 if (!STI->hasFeature(ARM::FeatureThumb2)) {
775 if (FixupDiagnostic) {
776 Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
777 return 0;
778 }
779 }
780 return ((Value - 4) >> 1) & 0xff;
783
784 bool isAdd = true;
785 if ((int64_t)Value < 0) {
787 isAdd = false;
788 }
789
790 if (Value >= 256) {
791 Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
792 return 0;
793 }
795 return Value | (isAdd << 23);
796 }
799
800 [[fallthrough]];
802
804 bool isAdd = true;
805 if ((int64_t)Value < 0) {
807 isAdd = false;
808 }
809
811 if (Value >= 256) {
812 Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
813 return 0;
814 }
815 Value |= isAdd << 23;
816
817
818
821
823 }
826
827 [[fallthrough]];
829
831 bool isAdd = true;
832 if ((int64_t)Value < 0) {
834 isAdd = false;
835 }
836
838 Ctx.reportError(Fixup.getLoc(), "invalid value for this fixup");
839 return 0;
840 }
842 if (Value >= 256) {
843 Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
844 return 0;
845 }
846 Value |= isAdd << 23;
847
848
849
852
854 }
857 if (Value >> 12) {
858 Ctx.reportError(Fixup.getLoc(), "out of range immediate fixup value");
859 return 0;
860 }
864 if ((int64_t)Value < 0) {
865 Ctx.reportError(Fixup.getLoc(), "out of range immediate fixup value");
866 return 0;
867 }
868
869
870
871
872
874 EncValue |= (Value & 0x800) << 15;
875 EncValue |= (Value & 0x700) << 4;
876 EncValue |= (Value & 0xff);
878 }
881 if (FixupDiagnostic) {
882 Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
883 return 0;
884 }
887 }
892 if (FixupDiagnostic) {
893 Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
894 return 0;
895 }
899 out |= (((Value - 4) >> 1) & 0x1) << 11;
900 out |= (((Value - 4) >> 1) & 0x7fe);
901 out |= (((Value - 4) >> 1) & HighBitMask) << 5;
903 }
905
906
907
909
911 if (FixupDiagnostic) {
912 Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
913 return 0;
914 }
917 }
921 if (FixupDiagnostic) {
922 Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
923 return 0;
924 }
928 real_value = -real_value;
929 out |= ((real_value >> 1) & 0x1) << 11;
930 out |= ((real_value >> 1) & 0x7fe);
932 }
933 }
934}
935
940
941
943 return true;
944
945
946
951 return true;
952 return Target.getSpecifier();
953}
954
955
957 switch (Kind) {
958 default:
960
969 return 1;
970
975 return 2;
976
988 return 3;
989
1011 return 4;
1012
1014 return 2;
1016 return 4;
1017 }
1018}
1019
1020
1021
1023 switch (Kind) {
1024 default:
1026
1028 return 1;
1030 return 2;
1032 return 4;
1033
1043
1044 return 2;
1045
1077
1078 return 4;
1079 }
1080}
1081
1085
1086
1087
1088 switch (Fixup.getKind()) {
1096 Value = (Asm->getFragmentOffset(F) + Fixup.getOffset()) % 4;
1097 }
1098 return {};
1099}
1100
1105 IsResolved = false;
1107 auto Kind = Fixup.getKind();
1109 return;
1114 return;
1116
1117 assert(Fixup.getOffset() + NumBytes <= F.getSize() &&
1118 "Invalid fixup offset!");
1119
1120
1121 unsigned FullSizeBytes;
1124 assert(Fixup.getOffset() + FullSizeBytes <= F.getSize() &&
1125 "Invalid fixup size!");
1126 assert(NumBytes <= FullSizeBytes && "Invalid fixup size!");
1127 }
1128
1129
1130
1131
1132 for (unsigned i = 0; i != NumBytes; ++i) {
1133 unsigned Idx =
1136 }
1137}
1138
1139namespace CU {
1140
1141
1147
1149
1153
1159
1161
1163};
1164
1165}
1166
1167
1168
1169
1170
1174
1176 return 0;
1177
1179 if (Instrs.empty())
1180 return 0;
1184
1185
1187 int CFARegisterOffset = 0;
1188
1190 int FloatRegCount = 0;
1191
1194 switch (Inst.getOperation()) {
1196 CFARegisterOffset = Inst.getOffset();
1197 CFARegister = *MRI.getLLVMRegNum(Inst.getRegister(), true);
1198 break;
1200 CFARegisterOffset = Inst.getOffset();
1201 break;
1203 CFARegister = *MRI.getLLVMRegNum(Inst.getRegister(), true);
1204 break;
1206 Reg = *MRI.getLLVMRegNum(Inst.getRegister(), true);
1207 if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
1208 RegOffsets[Reg] = Inst.getOffset();
1209 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
1210 RegOffsets[Reg] = Inst.getOffset();
1211 ++FloatRegCount;
1212 } else {
1214 llvm::dbgs() << ".cfi_offset on unknown register="
1215 << Inst.getRegister() << "\n");
1217 }
1218 break;
1220
1221 break;
1222 default:
1223
1226 << "CFI directive not compatible with compact "
1227 "unwind encoding, opcode="
1228 << uint8_t(Inst.getOperation()) << "\n");
1230 break;
1231 }
1232 }
1233
1234
1235 if ((CFARegister == ARM::SP) && (CFARegisterOffset == 0))
1236 return 0;
1237
1238
1239 if (CFARegister != ARM::R7) {
1241 << CFARegister.id()
1242 << " instead of r7\n");
1244 }
1245 int StackAdjust = CFARegisterOffset - 8;
1246 if (RegOffsets.lookup(ARM::LR) != (-4 - StackAdjust)) {
1248 "compact-unwind",
1249 llvm::dbgs() << "LR not saved as standard frame, StackAdjust="
1250 << StackAdjust
1251 << ", CFARegisterOffset=" << CFARegisterOffset
1252 << ", lr save at offset=" << RegOffsets[ARM::LR] << "\n");
1254 }
1255 if (RegOffsets.lookup(ARM::R7) != (-8 - StackAdjust)) {
1257 llvm::dbgs() << "r7 not saved as standard frame\n");
1259 }
1261
1262
1263 switch (StackAdjust) {
1264 case 0:
1265 break;
1266 case 4:
1267 CompactUnwindEncoding |= 0x00400000;
1268 break;
1269 case 8:
1270 CompactUnwindEncoding |= 0x00800000;
1271 break;
1272 case 12:
1273 CompactUnwindEncoding |= 0x00C00000;
1274 break;
1275 default:
1277 << ".cfi_def_cfa stack adjust ("
1278 << StackAdjust << ") out of range\n");
1280 }
1281
1282
1283 static struct {
1284 unsigned Reg;
1285 unsigned Encoding;
1294
1295 int CurOffset = -8 - StackAdjust;
1296 for (auto CSReg : GPRCSRegs) {
1297 auto Offset = RegOffsets.find(CSReg.Reg);
1299 continue;
1300
1301 int RegOffset = Offset->second;
1302 if (RegOffset != CurOffset - 4) {
1304 llvm::dbgs() << MRI.getName(CSReg.Reg) << " saved at "
1305 << RegOffset << " but only supported at "
1306 << CurOffset << "\n");
1308 }
1309 CompactUnwindEncoding |= CSReg.Encoding;
1310 CurOffset -= 4;
1311 }
1312
1313
1314 if (FloatRegCount == 0)
1315 return CompactUnwindEncoding;
1316
1317
1318 CompactUnwindEncoding &= ~CU::UNWIND_ARM_MODE_MASK;
1320
1321
1322
1323 if (FloatRegCount > 4) {
1325 llvm::dbgs() << "unsupported number of D registers saved ("
1326 << FloatRegCount << ")\n");
1328 }
1329
1330
1331
1332
1333 static MCPhysReg FPRCSRegs[] = {ARM::D8, ARM::D10, ARM::D12, ARM::D14};
1334 for (int Idx = FloatRegCount - 1; Idx >= 0; --Idx) {
1335 auto Offset = RegOffsets.find(FPRCSRegs[Idx]);
1336 if (Offset == RegOffsets.end()) {
1338 llvm::dbgs() << FloatRegCount << " D-regs saved, but "
1339 << MRI.getName(FPRCSRegs[Idx])
1340 << " not saved\n");
1342 } else if (Offset->second != CurOffset - 8) {
1344 llvm::dbgs() << FloatRegCount << " D-regs saved, but "
1345 << MRI.getName(FPRCSRegs[Idx])
1346 << " saved at " << Offset->second
1347 << ", expected at " << CurOffset - 8
1348 << "\n");
1350 }
1351 CurOffset -= 8;
1352 }
1353
1354 return CompactUnwindEncoding | ((FloatRegCount - 1) << 8);
1355}
1356
1364 default:
1369 assert(TheTriple.isOSWindows() && "non-Windows ARM COFF is not supported");
1377 }
1378}
1379
1386
unsigned const MachineRegisterInfo * MRI
static unsigned getFixupKindNumBytes(unsigned Kind)
The number of bytes the fixup may change.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static uint32_t swapHalfWords(uint32_t Value, bool IsLittleEndian)
Definition ARMAsmBackend.cpp:393
static bool needsInterworking(const MCAssembler &Asm, const MCSymbol *Sym, unsigned FixupKind)
Definition ARMAsmBackend.cpp:296
static unsigned getFixupKindContainerSizeBytes(unsigned Kind)
getFixupKindContainerSizeBytes - The number of bytes of the container involved in big endian.
Definition ARMAsmBackend.cpp:1022
static MCAsmBackend * createARMAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options, llvm::endianness Endian)
Definition ARMAsmBackend.cpp:1357
static uint32_t joinHalfWords(uint32_t FirstHalf, uint32_t SecondHalf, bool IsLittleEndian)
Definition ARMAsmBackend.cpp:404
static const char * checkPCRelOffset(uint64_t Value, int64_t Min, int64_t Max)
Definition ARMAsmBackend.cpp:210
Function Alias Analysis false
PowerPC TLS Dynamic Call Fixup
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...
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
static SymbolRef::Type getType(const Symbol *Sym)
uint64_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI, const MCContext *Ctxt) const override
Generate compact unwind encoding for the function based on the CFI instructions.
Definition ARMAsmBackend.cpp:1171
const MachO::CPUSubTypeARM Subtype
std::optional< MCFixupKind > getFixupKind(StringRef Name) const override
Map a relocation name used in .reloc to a fixup kind.
Definition ARMAsmBackend.cpp:52
const char * reasonForFixupRelaxation(const MCFixup &Fixup, uint64_t Value) const
Definition ARMAsmBackend.cpp:217
bool mayNeedRelaxation(unsigned Opcode, ArrayRef< MCOperand > Operands, const MCSubtargetInfo &STI) const override
Check whether the given instruction (encoded as Opcode+Operands) may need relaxation.
Definition ARMAsmBackend.cpp:205
bool fixupNeedsRelaxationAdvanced(const MCFragment &, const MCFixup &, const MCValue &, uint64_t, bool) const override
Target specific predicate for whether a given fixup requires the associated instruction to be relaxed...
Definition ARMAsmBackend.cpp:315
void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target, uint8_t *Data, uint64_t Value, bool IsResolved) override
Definition ARMAsmBackend.cpp:1101
bool hasNOP(const MCSubtargetInfo *STI) const
MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override
Get information on a fixup kind.
Definition ARMAsmBackend.cpp:67
unsigned getRelaxedOpcode(unsigned Op, const MCSubtargetInfo &STI) const
Definition ARMAsmBackend.cpp:182
std::optional< bool > evaluateFixup(const MCFragment &, MCFixup &, MCValue &, uint64_t &) override
Definition ARMAsmBackend.cpp:1082
unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, uint64_t Value, bool IsResolved, MCContext &Ctx, const MCSubtargetInfo *STI) const
Definition ARMAsmBackend.cpp:419
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.
Definition ARMAsmBackend.cpp:352
std::optional< MCFixupKind > getFixupKind(StringRef Name) const override
Map a relocation name used in .reloc to a fixup kind.
Definition ARMAsmBackend.cpp:47
void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const override
Relax the instruction in the given fragment to the next wider instruction.
Definition ARMAsmBackend.cpp:329
bool shouldForceRelocation(const MCFixup &Fixup, const MCValue &Target)
Definition ARMAsmBackend.cpp:936
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.
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
static const MCSubtargetInfo * getSubtargetInfo(const MCFragment &F)
virtual MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
bool isDarwinCanonicalPersonality(const MCSymbol *Sym) const
MCContext & getContext() const
void maybeAddReloc(const MCFragment &, const MCFixup &, const MCValue &, uint64_t &Value, bool IsResolved)
Context object for machine code objects.
LLVM_ABI bool emitCompactUnwindNonCanonical() const
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.
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...
Wrapper class representing physical registers. Should be passed by value.
constexpr unsigned id() const
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 ...
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.
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)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
CompactUnwindEncodings
Compact unwind encoding values.
Definition ARMAsmBackend.cpp:1142
@ UNWIND_ARM_FRAME_SECOND_PUSH_R10
Definition ARMAsmBackend.cpp:1156
@ UNWIND_ARM_FRAME_FIRST_PUSH_R6
Definition ARMAsmBackend.cpp:1152
@ UNWIND_ARM_FRAME_SECOND_PUSH_R11
Definition ARMAsmBackend.cpp:1157
@ UNWIND_ARM_MODE_DWARF
Definition ARMAsmBackend.cpp:1146
@ UNWIND_ARM_DWARF_SECTION_OFFSET
Definition ARMAsmBackend.cpp:1162
@ UNWIND_ARM_FRAME_FIRST_PUSH_R4
Definition ARMAsmBackend.cpp:1150
@ UNWIND_ARM_FRAME_SECOND_PUSH_R9
Definition ARMAsmBackend.cpp:1155
@ UNWIND_ARM_FRAME_SECOND_PUSH_R8
Definition ARMAsmBackend.cpp:1154
@ UNWIND_ARM_FRAME_STACK_ADJUST_MASK
Definition ARMAsmBackend.cpp:1148
@ UNWIND_ARM_MODE_FRAME
Definition ARMAsmBackend.cpp:1144
@ UNWIND_ARM_FRAME_SECOND_PUSH_R12
Definition ARMAsmBackend.cpp:1158
@ UNWIND_ARM_FRAME_D_REG_COUNT_MASK
Definition ARMAsmBackend.cpp:1160
@ UNWIND_ARM_MODE_MASK
Definition ARMAsmBackend.cpp:1143
@ UNWIND_ARM_MODE_FRAME_D
Definition ARMAsmBackend.cpp:1145
@ UNWIND_ARM_FRAME_FIRST_PUSH_R5
Definition ARMAsmBackend.cpp:1151
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
bool isRelocation(MCFixupKind FixupKind)
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.
FunctionAddr VTableAddr Value
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
constexpr int64_t minIntN(int64_t N)
Gets the minimum value for a N-bit signed integer.
MCAsmBackend * createARMBEAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
Definition ARMAsmBackend.cpp:1387
MCAsmBackend * createARMLEAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
Definition ARMAsmBackend.cpp:1380
uint16_t MCFixupKind
Extensible enumeration to represent the type of a fixup.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static Lanai::Fixups FixupKind(const MCExpr *Expr)
FunctionAddr VTableAddr Count
@ FK_SecRel_2
A two-byte section relative fixup.
@ FirstLiteralRelocationKind
@ 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.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
constexpr int64_t maxIntN(int64_t N)
Gets the maximum value for a N-bit signed integer.
const MCSymbol * Personality
std::vector< MCCFIInstruction > Instructions
Target independent information on a fixup kind.