1//===-- ARMAsmBackend.cpp - ARM Assembler Backend -------------------------===//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//===----------------------------------------------------------------------===//
41 ARMELFObjectWriter(uint8_t OSABI)
43 /*HasRelocationAddend*/ false) {}
45}
// end anonymous namespace
51std::optional<MCFixupKind>
54#define ELF_RELOC(X, Y) .Case(#X, Y)
55#include "llvm/BinaryFormat/ELFRelocs/ARM.def"
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)
69 // This table *must* be in the order that the fixup_* kinds are defined in
72 // Name Offset (bits) Size (bits) Flags
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 // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
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},
118 // This table *must* be in the order that the fixup_* kinds are defined in
121 // Name Offset (bits) Size (bits) Flags
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 // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
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},
167 // Fixup kinds from .reloc directive are like R_ARM_NONE. They do not require
168 // any extra processing.
184 bool HasThumb2 = STI.
hasFeature(ARM::FeatureThumb2);
185 bool HasV8MBaselineOps = STI.
hasFeature(ARM::HasV8MBaselineOps);
193 return HasThumb2 ? (
unsigned)ARM::t2LDRpci :
Op;
197 return HasV8MBaselineOps ? (
unsigned)ARM::t2B :
Op;
213 return "out of range pc-relative fixup value";
219 switch (
Fixup.getKind()) {
221 // Relaxing tB to t2B. tB has a signed 12-bit displacement with the
222 // low bit being an implied zero. There's an implied +4 offset for the
223 // branch, so we adjust the other way here to determine what's
226 // Relax if the value is too big for a (signed) i8.
229 return "out of range pc-relative fixup value";
233 // Relaxing tBcc to t2Bcc. tBcc has a signed 9-bit displacement with the
234 // low bit being an implied zero. There's an implied +4 offset for the
235 // branch, so we adjust the other way here to determine what's
238 // Relax if the value is too big for a (signed) i8.
241 return "out of range pc-relative fixup value";
246 // If the immediate is negative, greater than 1020, or not a multiple
247 // of four, the wide version of the instruction must be used.
250 return "misaligned pc-relative fixup value";
252 return "out of range pc-relative fixup value";
256 // If we have a Thumb CBZ or CBNZ instruction and its target is the next
257 // instruction it is actually out of range for the instruction.
258 // It will be changed to a NOP.
261 return "will be converted to nop";
275 // The offset field in the LE and LETP instructions is an 11-bit
276 // value shifted left by 2 (i.e. 0,2,4,...,4094), and it is
277 // interpreted as a negative offset from the value read from pc,
278 // i.e. from instruction_address+4.
280 // So an LE instruction can in principle address the instruction
281 // immediately after itself, or (not very usefully) the address
282 // half way through the 4-byte LE.
286 return "out of range label-relative fixup value";
298 // Create relocations for unconditional branches to function symbols with
299 // different execution mode in ELF binaries.
300 if (!Sym || !Asm.getContext().isELF())
319 bool Resolved)
const {
334 // If we are changing Thumb CBZ or CBNZ instruction to a NOP, aka tHINT, we
335 // have to change the operands too.
337 RelaxedOp == ARM::tHINT) {
343 Inst = std::move(Res);
347 // The rest of instructions we're relaxing have the same operands.
348 // We just need to update to the proper opcode.
354 const uint16_t Thumb1_16bitNopEncoding = 0x46c0;
// using MOV r8,r8
355 const uint16_t Thumb2_16bitNopEncoding = 0xbf00;
// NOP
356 const uint32_t ARMv4_NopEncoding = 0xe1a00000;
// using MOV r0,r0
357 const uint32_t ARMv6T2_NopEncoding = 0xe320f000;
// NOP
360 hasNOP(STI) ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding;
362 for (
uint64_t i = 0; i != NumNops; ++i)
370 hasNOP(STI) ? ARMv6T2_NopEncoding : ARMv4_NopEncoding;
372 for (
uint64_t i = 0; i != NumNops; ++i)
374 // FIXME: should this function return false when unable to write exactly
375 // 'Count' bytes with NOP encodings?
378 break;
// No leftover bytes to write
386 OS.
write(
"0円0円\xa0", 3);
394 if (IsLittleEndian) {
395 // Note that the halfwords are stored high first and low second in thumb;
396 // so we need to swap the fixup value here to map properly.
398 Swapped |= (
Value & 0x0000FFFF) << 16;
405 bool IsLittleEndian) {
408 if (IsLittleEndian) {
409 Value = (SecondHalf & 0xFFFF) << 16;
410 Value |= (FirstHalf & 0xFFFF);
412 Value = (SecondHalf & 0xFFFF);
413 Value |= (FirstHalf & 0xFFFF) << 16;
424 unsigned Kind =
Fixup.getKind();
425 int64_t Addend =
Target.getConstant();
427 // For MOVW/MOVT Instructions, the fixup value must already be within a
428 // signed 16bit range.
432 Ctx.reportError(
Fixup.getLoc(),
"Relocation Not In Range");
436 // MachO tries to make .o files that look vaguely pre-linked, so for MOVW/MOVT
437 // and .word relocations they put the Thumb bit into the addend if possible.
438 // Other relocation types don't want this bit though (branches couldn't encode
439 // it if it *was* present, and no other relocations exist) and it can
440 // interfere with checking valid expressions.
443 if (
Asm.isThumbFunc(SA) && SA->isExternal() &&
468 unsigned Hi4 = (
Value & 0xF000) >> 12;
469 unsigned Lo12 =
Value & 0x0FFF;
470 // inst{19-16} = Hi4;
471 // inst{11-0} = Lo12;
472 Value = (Hi4 << 16) | (Lo12);
481 unsigned Hi4 = (
Value & 0xF000) >> 12;
482 unsigned i = (
Value & 0x800) >> 11;
483 unsigned Mid3 = (
Value & 0x700) >> 8;
484 unsigned Lo8 =
Value & 0x0FF;
485 // inst{19-16} = Hi4;
487 // inst{14-12} = Mid3;
489 Value = (Hi4 << 16) | (i << 26) | (Mid3 << 12) | (Lo8);
494 return (
Value & 0xff000000) >> 24;
498 return (
Value & 0x00ff0000) >> 16;
502 return (
Value & 0x0000ff00) >> 8;
505 return Value & 0x000000ff;
507 // ARM PC-relative values are offset by 8.
511 // Offset by 4, adjusted by two due to the half-word ordering of thumb.
516 if ((int64_t)
Value < 0) {
521 Ctx.reportError(
Fixup.getLoc(),
"out of range pc-relative fixup value");
524 Value |= isAdd << 23;
526 // Same addressing mode as fixup_arm_pcrel_10,
527 // but with 16-bit halfwords swapped.
534 // ARM PC-relative values are offset by 8.
536 unsigned opc = 4;
// bits {24-21}. Default to add: 0b0100
537 if ((int64_t)
Value < 0) {
542 Ctx.reportError(
Fixup.getLoc(),
"out of range pc-relative fixup value");
545 // Encode the immediate and shift the opcode into place.
552 if ((int64_t)
Value < 0) {
558 out |= (
Value & 0x800) << 15;
559 out |= (
Value & 0x700) << 4;
560 out |= (
Value & 0x0FF);
570 // Check that the relocation value is legal.
573 Ctx.reportError(
Fixup.getLoc(),
"Relocation out of range");
576 // Alignment differs for blx. Because we are switching to thumb ISA, we use
577 // 16-bit alignment. Otherwise, use 32-bit.
580 Ctx.reportError(
Fixup.getLoc(),
"Relocation not aligned");
584 // These values don't encode the low two bits since they're always zero.
585 // Offset by 8 just as above.
590 return 0xffffff & (
Value >> 2);
594 // MSVC link.exe and lld do not support this relocation type
595 // with a non-zero offset. ("Value" is offset by 4 at this point.)
596 Ctx.reportError(
Fixup.getLoc(),
597 "cannot perform a PC-relative fixup with a non-zero "
602 Ctx.reportError(
Fixup.getLoc(),
"Relocation out of range");
606 Value >>= 1;
// Low bit is not encoded.
609 bool I =
Value & 0x800000;
610 bool J1 =
Value & 0x400000;
611 bool J2 =
Value & 0x200000;
615 out |=
I << 26;
// S bit
616 out |= !J1 << 13;
// J1 bit
617 out |= !J2 << 11;
// J2 bit
618 out |= (
Value & 0x1FF800) << 5;
// imm6 field
619 out |= (
Value & 0x0007FF);
// imm11 field
626 Ctx.reportError(
Fixup.getLoc(),
"Relocation out of range");
630 Value >>= 1;
// Low bit is not encoded.
633 out |= (
Value & 0x80000) << 7;
// S bit
634 out |= (
Value & 0x40000) >> 7;
// J2 bit
635 out |= (
Value & 0x20000) >> 4;
// J1 bit
636 out |= (
Value & 0x1F800) << 5;
// imm6 field
637 out |= (
Value & 0x007FF);
// imm11 field
647 Ctx.reportError(
Fixup.getLoc(),
"Relocation out of range");
652 // MSVC link.exe and lld do not support this relocation type
653 // with a non-zero offset. ("Value" is offset by 4 at this point.)
654 Ctx.reportError(
Fixup.getLoc(),
655 "cannot perform a PC-relative fixup with a non-zero "
659 // The value doesn't encode the low bit (always zero) and is offset by
660 // four. The 32-bit immediate value is encoded as
661 // imm32 = SignExtend(S:I1:I2:imm10:imm11:0)
662 // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S).
663 // The value is encoded into disjoint bit positions in the destination
664 // opcode. x = unchanged, I = immediate value bit, S = sign extension bit,
665 // J = either J1 or J2 bit
667 // BL: xxxxxSIIIIIIIIII xxJxJIIIIIIIIIII
669 // Note that the halfwords are stored high first, low second; so we need
670 // to transpose the fixup value here to map properly.
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);
689 // MSVC link.exe and lld do not support this relocation type
690 // with a non-zero offset. ("Value" is offset by 4 at this point.)
691 Ctx.reportError(
Fixup.getLoc(),
692 "cannot perform a PC-relative fixup with a non-zero "
695 // The value doesn't encode the low two bits (always zero) and is offset by
696 // four (see fixup_arm_thumb_cp). The 32-bit immediate value is encoded as
697 // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:00)
698 // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S).
699 // The value is encoded into disjoint bit positions in the destination
700 // opcode. x = unchanged, I = immediate value bit, S = sign extension bit,
701 // J = either J1 or J2 bit, 0 = zero.
703 // BLX: xxxxxSIIIIIIIIII xxJxJIIIIIIIIII0
705 // Note that the halfwords are stored high first, low second; so we need
706 // to transpose the fixup value here to map properly.
707 if (
Value % 4 != 0) {
708 Ctx.reportError(
Fixup.getLoc(),
"misaligned ARM call destination");
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);
733 // On CPUs supporting Thumb2, this will be relaxed to an ldr.w, otherwise we
734 // could have an error on our hands.
736 if (!STI->
hasFeature(ARM::FeatureThumb2) && IsResolved) {
738 if (FixupDiagnostic) {
739 Ctx.reportError(
Fixup.getLoc(), FixupDiagnostic);
743 // Offset by 4, and don't encode the low two bits.
744 return ((
Value - 4) >> 2) & 0xff;
746 // CB instructions can only branch to offsets in [4, 126] in multiples of 2
747 // so ensure that the raw value LSB is zero and it lies in [2, 130].
748 // An offset of 2 will be relaxed to a NOP.
750 Ctx.reportError(
Fixup.getLoc(),
"out of range pc-relative fixup value");
753 // Offset by 4 and don't encode the lower bit, which is always 0.
754 // FIXME: diagnose if no Thumb2
756 return ((Binary & 0x20) << 4) | ((Binary & 0x1f) << 3);
759 // Offset by 4 and don't encode the lower bit, which is always 0.
764 if (FixupDiagnostic) {
765 Ctx.reportError(
Fixup.getLoc(), FixupDiagnostic);
769 return ((
Value - 4) >> 1) & 0x7ff;
771 // Offset by 4 and don't encode the lower bit, which is always 0.
775 if (FixupDiagnostic) {
776 Ctx.reportError(
Fixup.getLoc(), FixupDiagnostic);
780 return ((
Value - 4) >> 1) & 0xff;
782 Value =
Value - 8;
// ARM fixups offset by an additional word and don't
783 // need to adjust for the half-word ordering.
785 if ((int64_t)
Value < 0) {
789 // The value has the low 4 bits encoded in [3:0] and the high 4 in [11:8].
791 Ctx.reportError(
Fixup.getLoc(),
"out of range pc-relative fixup value");
795 return Value | (isAdd << 23);
798 Value =
Value - 4;
// ARM fixups offset by an additional word and don't
799 // need to adjust for the half-word ordering.
802 // Offset by 4, adjusted by two due to the half-word ordering of thumb.
805 if ((int64_t)
Value < 0) {
809 // These values don't encode the low two bits since they're always zero.
812 Ctx.reportError(
Fixup.getLoc(),
"out of range pc-relative fixup value");
815 Value |= isAdd << 23;
817 // Same addressing mode as fixup_arm_pcrel_10, but with 16-bit halfwords
825 Value =
Value - 4;
// ARM fixups offset by an additional word and don't
826 // need to adjust for the half-word ordering.
829 // Offset by 4, adjusted by two due to the half-word ordering of thumb.
832 if ((int64_t)
Value < 0) {
836 // These values don't encode the low bit since it's always zero.
838 Ctx.reportError(
Fixup.getLoc(),
"invalid value for this fixup");
843 Ctx.reportError(
Fixup.getLoc(),
"out of range pc-relative fixup value");
846 Value |= isAdd << 23;
848 // Same addressing mode as fixup_arm_pcrel_9, but with 16-bit halfwords
858 Ctx.reportError(
Fixup.getLoc(),
"out of range immediate fixup value");
864 if ((int64_t)
Value < 0) {
865 Ctx.reportError(
Fixup.getLoc(),
"out of range immediate fixup value");
868 // Value will contain a 12-bit value broken up into a 4-bit shift in bits
869 // 11:8 and the 8-bit immediate in 0:7. The instruction has the immediate
870 // in 0:7. The 4-bit shift is split up into i:imm3 where i is placed at bit
871 // 10 of the upper half-word and imm3 is placed at 14:12 of the lower
874 EncValue |= (
Value & 0x800) << 15;
875 EncValue |= (
Value & 0x700) << 4;
876 EncValue |= (
Value & 0xff);
881 if (FixupDiagnostic) {
882 Ctx.reportError(
Fixup.getLoc(), FixupDiagnostic);
892 if (FixupDiagnostic) {
893 Ctx.reportError(
Fixup.getLoc(), FixupDiagnostic);
899 out |= (((
Value - 4) >> 1) & 0x1) << 11;
900 out |= (((
Value - 4) >> 1) & 0x7fe);
901 out |= (((
Value - 4) >> 1) & HighBitMask) << 5;
905 // If this is a fixup of a branch future's else target then it should be a
906 // constant MCExpr representing the distance between the branch targetted
907 // and the instruction after that same branch.
911 if (FixupDiagnostic) {
912 Ctx.reportError(
Fixup.getLoc(), FixupDiagnostic);
921 if (FixupDiagnostic) {
922 Ctx.reportError(
Fixup.getLoc(), FixupDiagnostic);
928 real_value = -real_value;
929 out |= ((real_value >> 1) & 0x1) << 11;
930 out |= ((real_value >> 1) & 0x7fe);
940 // Create relocations for unconditional branches to function symbols with
941 // different execution mode in ELF binaries.
944 // We must always generate a relocation for BL/BLX instructions if we have
945 // a symbol to reference, as the linker relies on knowing the destination
946 // symbol's thumb-ness to get interworking right.
952 return Target.getSpecifier();
955/// getFixupKindNumBytes - The number of bytes the fixup may change.
1020/// getFixupKindContainerSizeBytes - The number of bytes of the
1021/// container involved in big endian.
1043 // Instruction size is 2 bytes.
1077 // Instruction size is 4 bytes.
1085 // For a few PC-relative fixups in Thumb mode, offsets need to be aligned
1086 // down. We compensate here because the default handler's `Value` decrement
1087 // doesn't account for this alignment.
1088 switch (
Fixup.getKind()) {
1107 auto Kind =
Fixup.getKind();
1114 return;
// Doesn't change encoding.
1118 "Invalid fixup offset!");
1120 // Used to point to big endian bytes.
1121 unsigned FullSizeBytes;
1124 assert(
Fixup.getOffset() + FullSizeBytes <=
F.getSize() &&
1125 "Invalid fixup size!");
1126 assert(NumBytes <= FullSizeBytes &&
"Invalid fixup size!");
1129 // For each byte of the fragment that the fixup touches, mask in the bits from
1130 // the fixup value. The Value has been "split up" into the appropriate
1132 for (
unsigned i = 0; i != NumBytes; ++i) {
1141/// Compact unwind encoding values.
1165}
// end CU namespace
1167/// Generate compact unwind encoding for the function based on the CFI
1168/// instructions. If the CFI instructions describe a frame that cannot be
1169/// encoded in compact unwind, the method returns UNWIND_ARM_MODE_DWARF which
1170/// tells the runtime to fallback and unwind using dwarf.
1174 // Only armv7k uses CFI based unwinding.
1177 // No .cfi directives means no frame.
1185 // Start off assuming CFA is at SP+0.
1187 int CFARegisterOffset = 0;
1188 // Mark savable registers as initially unsaved
1190 int FloatRegCount = 0;
1191 // Process each .cfi directive and build up compact unwind info.
1194 switch (Inst.getOperation()) {
1196 CFARegisterOffset = Inst.getOffset();
1197 CFARegister = *MRI.getLLVMRegNum(Inst.getRegister(),
true);
1200 CFARegisterOffset = Inst.getOffset();
1203 CFARegister = *MRI.getLLVMRegNum(Inst.getRegister(),
true);
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();
1214 llvm::dbgs() <<
".cfi_offset on unknown register="
1215 << Inst.getRegister() <<
"\n");
1223 // Directive not convertable to compact unwind, bail out.
1226 <<
"CFI directive not compatible with compact "
1227 "unwind encoding, opcode="
1228 <<
uint8_t(Inst.getOperation()) <<
"\n");
1234 // If no frame set up, return no unwind info.
1235 if ((CFARegister == ARM::SP) && (CFARegisterOffset == 0))
1238 // Verify standard frame (lr/r7) was used.
1239 if (CFARegister != ARM::R7) {
1242 <<
" instead of r7\n");
1245 int StackAdjust = CFARegisterOffset - 8;
1246 if (RegOffsets.
lookup(ARM::LR) != (-4 - StackAdjust)) {
1249 llvm::dbgs() <<
"LR not saved as standard frame, StackAdjust="
1251 <<
", CFARegisterOffset=" << CFARegisterOffset
1252 <<
", lr save at offset=" << RegOffsets[ARM::LR] <<
"\n");
1255 if (RegOffsets.
lookup(ARM::R7) != (-8 - StackAdjust)) {
1257 llvm::dbgs() <<
"r7 not saved as standard frame\n");
1262 // If var-args are used, there may be a stack adjust required.
1263 switch (StackAdjust) {
1267 CompactUnwindEncoding |= 0x00400000;
1270 CompactUnwindEncoding |= 0x00800000;
1273 CompactUnwindEncoding |= 0x00C00000;
1277 <<
".cfi_def_cfa stack adjust ("
1278 << StackAdjust <<
") out of range\n");
1282 // If r6 is saved, it must be right below r7.
1295 int CurOffset = -8 - StackAdjust;
1296 for (
auto CSReg : GPRCSRegs) {
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");
1309 CompactUnwindEncoding |= CSReg.Encoding;
1313 // If no floats saved, we are done.
1314 if (FloatRegCount == 0)
1315 return CompactUnwindEncoding;
1317 // Switch mode to include D register saving.
1318 CompactUnwindEncoding &=
~CU::UNWIND_ARM_MODE_MASK;
1321 // FIXME: supporting more than 4 saved D-registers compactly would be trivial,
1322 // but needs coordination with the linker and libunwind.
1323 if (FloatRegCount > 4) {
1325 llvm::dbgs() <<
"unsupported number of D registers saved ("
1326 << FloatRegCount <<
")\n");
1330 // Floating point registers must either be saved sequentially, or we defer to
1331 // DWARF. No gaps allowed here so check that each saved d-register is
1332 // precisely where it should be.
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]);
1338 llvm::dbgs() << FloatRegCount <<
" D-regs saved, but "
1339 << MRI.getName(FPRCSRegs[Idx])
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
1354 return CompactUnwindEncoding | ((FloatRegCount - 1) << 8);
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)
static bool needsInterworking(const MCAssembler &Asm, const MCSymbol *Sym, unsigned FixupKind)
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)
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.
const MachO::CPUSubTypeARM Subtype
std::optional< MCFixupKind > getFixupKind(StringRef Name) const override
Map a relocation name used in .reloc to a fixup kind.
const char * reasonForFixupRelaxation(const MCFixup &Fixup, uint64_t Value) const
bool mayNeedRelaxation(unsigned Opcode, ArrayRef< MCOperand > Operands, const MCSubtargetInfo &STI) const override
Check whether the given instruction (encoded as Opcode+Operands) may need relaxation.
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...
void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target, uint8_t *Data, uint64_t Value, bool IsResolved) override
bool hasNOP(const MCSubtargetInfo *STI) const
MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override
Get information on a fixup kind.
unsigned getRelaxedOpcode(unsigned Op, const MCSubtargetInfo &STI) const
std::optional< bool > evaluateFixup(const MCFragment &, MCFixup &, MCValue &, uint64_t &) override
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 shouldForceRelocation(const MCFixup &Fixup, const MCValue &Target)
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.
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.
@ 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
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<X> - 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)
MCAsmBackend * createARMLEAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
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.