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;

782 Value = Value - 8;

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 }

798 Value = Value - 4;

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 }

825 Value = Value - 4;

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.