LLVM: lib/TargetParser/ARMTargetParser.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

20#include

21

22using namespace llvm;

23

26 .Case("thumb,arm", "arm,thumb")

28}

29

30

34 for (const auto &A : ARMArchNames) {

35 if (A.Name.ends_with(Syn))

36 return A.ID;

37 }

38 return ArchKind::INVALID;

39}

40

41

45 case ArchKind::ARMV4:

46 case ArchKind::ARMV4T:

47 return 4;

48 case ArchKind::ARMV5T:

49 case ArchKind::ARMV5TE:

50 case ArchKind::IWMMXT:

51 case ArchKind::IWMMXT2:

52 case ArchKind::XSCALE:

53 case ArchKind::ARMV5TEJ:

54 return 5;

55 case ArchKind::ARMV6:

56 case ArchKind::ARMV6K:

57 case ArchKind::ARMV6T2:

58 case ArchKind::ARMV6KZ:

59 case ArchKind::ARMV6M:

60 return 6;

61 case ArchKind::ARMV7A:

62 case ArchKind::ARMV7VE:

63 case ArchKind::ARMV7R:

64 case ArchKind::ARMV7M:

65 case ArchKind::ARMV7S:

66 case ArchKind::ARMV7EM:

67 case ArchKind::ARMV7K:

68 return 7;

69 case ArchKind::ARMV8A:

70 case ArchKind::ARMV8_1A:

71 case ArchKind::ARMV8_2A:

72 case ArchKind::ARMV8_3A:

73 case ArchKind::ARMV8_4A:

74 case ArchKind::ARMV8_5A:

75 case ArchKind::ARMV8_6A:

76 case ArchKind::ARMV8_7A:

77 case ArchKind::ARMV8_8A:

78 case ArchKind::ARMV8_9A:

79 case ArchKind::ARMV8R:

80 case ArchKind::ARMV8MBaseline:

81 case ArchKind::ARMV8MMainline:

82 case ArchKind::ARMV8_1MMainline:

83 return 8;

84 case ArchKind::ARMV9A:

85 case ArchKind::ARMV9_1A:

86 case ArchKind::ARMV9_2A:

87 case ArchKind::ARMV9_3A:

88 case ArchKind::ARMV9_4A:

89 case ArchKind::ARMV9_5A:

90 case ArchKind::ARMV9_6A:

91 return 9;

92 case ArchKind::INVALID:

93 return 0;

94 }

96}

97

99 switch (AK) {

100 case ARM::ArchKind::ARMV6M:

101 case ARM::ArchKind::ARMV7M:

102 case ARM::ArchKind::ARMV7EM:

103 case ARM::ArchKind::ARMV8MMainline:

104 case ARM::ArchKind::ARMV8MBaseline:

105 case ARM::ArchKind::ARMV8_1MMainline:

106 return ARM::ProfileKind::M;

107 case ARM::ArchKind::ARMV7R:

108 case ARM::ArchKind::ARMV8R:

109 return ARM::ProfileKind::R;

110 case ARM::ArchKind::ARMV7A:

111 case ARM::ArchKind::ARMV7VE:

112 case ARM::ArchKind::ARMV7K:

113 case ARM::ArchKind::ARMV8A:

114 case ARM::ArchKind::ARMV8_1A:

115 case ARM::ArchKind::ARMV8_2A:

116 case ARM::ArchKind::ARMV8_3A:

117 case ARM::ArchKind::ARMV8_4A:

118 case ARM::ArchKind::ARMV8_5A:

119 case ARM::ArchKind::ARMV8_6A:

120 case ARM::ArchKind::ARMV8_7A:

121 case ARM::ArchKind::ARMV8_8A:

122 case ARM::ArchKind::ARMV8_9A:

123 case ARM::ArchKind::ARMV9A:

124 case ARM::ArchKind::ARMV9_1A:

125 case ARM::ArchKind::ARMV9_2A:

126 case ARM::ArchKind::ARMV9_3A:

127 case ARM::ArchKind::ARMV9_4A:

128 case ARM::ArchKind::ARMV9_5A:

129 case ARM::ArchKind::ARMV9_6A:

130 return ARM::ProfileKind::A;

131 case ARM::ArchKind::ARMV4:

132 case ARM::ArchKind::ARMV4T:

133 case ARM::ArchKind::ARMV5T:

134 case ARM::ArchKind::ARMV5TE:

135 case ARM::ArchKind::ARMV5TEJ:

136 case ARM::ArchKind::ARMV6:

137 case ARM::ArchKind::ARMV6K:

138 case ARM::ArchKind::ARMV6T2:

139 case ARM::ArchKind::ARMV6KZ:

140 case ARM::ArchKind::ARMV7S:

141 case ARM::ArchKind::IWMMXT:

142 case ARM::ArchKind::IWMMXT2:

143 case ARM::ArchKind::XSCALE:

144 case ARM::ArchKind::INVALID:

145 return ARM::ProfileKind::INVALID;

146 }

148}

149

150

154}

155

157 std::vector &Features) {

158

160 return false;

161

162 static const struct FPUFeatureNameInfo {

163 const char *PlusName, *MinusName;

166 } FPUFeatureInfoList[] = {

167

168

169

170

171

172

173

174 {"+vfp2", "-vfp2", FPUVersion::VFPV2, FPURestriction::D16},

175 {"+vfp2sp", "-vfp2sp", FPUVersion::VFPV2, FPURestriction::SP_D16},

176 {"+vfp3", "-vfp3", FPUVersion::VFPV3, FPURestriction::None},

177 {"+vfp3d16", "-vfp3d16", FPUVersion::VFPV3, FPURestriction::D16},

178 {"+vfp3d16sp", "-vfp3d16sp", FPUVersion::VFPV3, FPURestriction::SP_D16},

179 {"+vfp3sp", "-vfp3sp", FPUVersion::VFPV3, FPURestriction::None},

180 {"+fp16", "-fp16", FPUVersion::VFPV3_FP16, FPURestriction::SP_D16},

181 {"+vfp4", "-vfp4", FPUVersion::VFPV4, FPURestriction::None},

182 {"+vfp4d16", "-vfp4d16", FPUVersion::VFPV4, FPURestriction::D16},

183 {"+vfp4d16sp", "-vfp4d16sp", FPUVersion::VFPV4, FPURestriction::SP_D16},

184 {"+vfp4sp", "-vfp4sp", FPUVersion::VFPV4, FPURestriction::None},

185 {"+fp-armv8", "-fp-armv8", FPUVersion::VFPV5, FPURestriction::None},

186 {"+fp-armv8d16", "-fp-armv8d16", FPUVersion::VFPV5, FPURestriction::D16},

187 {"+fp-armv8d16sp", "-fp-armv8d16sp", FPUVersion::VFPV5, FPURestriction::SP_D16},

188 {"+fp-armv8sp", "-fp-armv8sp", FPUVersion::VFPV5, FPURestriction::None},

189 {"+fullfp16", "-fullfp16", FPUVersion::VFPV5_FULLFP16, FPURestriction::SP_D16},

190 {"+fp64", "-fp64", FPUVersion::VFPV2, FPURestriction::D16},

191 {"+d32", "-d32", FPUVersion::VFPV3, FPURestriction::None},

192 };

193

194 for (const auto &Info: FPUFeatureInfoList) {

195 if (FPUNames[FPUKind].FPUVer >= Info.MinVersion &&

196 FPUNames[FPUKind].Restriction <= Info.MaxRestriction)

197 Features.push_back(Info.PlusName);

198 else

199 Features.push_back(Info.MinusName);

200 }

201

202 static const struct NeonFeatureNameInfo {

203 const char *PlusName, *MinusName;

205 } NeonFeatureInfoList[] = {

206 {"+neon", "-neon", NeonSupportLevel::Neon},

207 {"+sha2", "-sha2", NeonSupportLevel::Crypto},

208 {"+aes", "-aes", NeonSupportLevel::Crypto},

209 };

210

211 for (const auto &Info: NeonFeatureInfoList) {

212 if (FPUNames[FPUKind].NeonSupport >= Info.MinSupportLevel)

213 Features.push_back(Info.PlusName);

214 else

215 Features.push_back(Info.MinusName);

216 }

217

218 return true;

219}

220

223 for (const auto &F : FPUNames) {

224 if (Syn == F.Name)

225 return F.ID;

226 }

227 return FK_INVALID;

228}

229

232 return NeonSupportLevel::None;

233 return FPUNames[FPUKind].NeonSupport;

234}

235

238 .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid")

239 .Case("vfp2", "vfpv2")

240 .Case("vfp3", "vfpv3")

241 .Case("vfp4", "vfpv4")

242 .Case("vfp3-d16", "vfpv3-d16")

243 .Case("vfp4-d16", "vfpv4-d16")

244 .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")

245 .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")

246 .Case("fp5-sp-d16", "fpv5-sp-d16")

247 .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")

248

249 .Case("neon-vfpv3", "neon")

251}

252

256 return FPUNames[FPUKind].Name;

257}

258

261 return FPUVersion::NONE;

262 return FPUNames[FPUKind].FPUVer;

263}

264

267 return FPURestriction::None;

268 return FPUNames[FPUKind].Restriction;

269}

270

272 if (CPU == "generic")

274

276#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \

277 .Case(NAME, DEFAULT_FPU)

278#include "llvm/TargetParser/ARMTargetParser.def"

279 .Default(ARM::FK_INVALID);

280}

281

283 if (CPU == "generic")

284 return ARM::ARMArchNames[static_cast<unsigned>(AK)].ArchBaseExtensions;

285

287#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \

288 .Case(NAME, \

289 ARMArchNames[static_cast(ArchKind::ID)].ArchBaseExtensions | \

290 DEFAULT_EXT)

291#include "llvm/TargetParser/ARMTargetParser.def"

293}

294

296 std::vector &Features) {

297

299 return false;

300

302 Features.push_back("+hwdiv-arm");

303 else

304 Features.push_back("-hwdiv-arm");

305

307 Features.push_back("+hwdiv");

308 else

309 Features.push_back("-hwdiv");

310

311 return true;

312}

313

315 std::vector &Features) {

316

318 return false;

319

321 if ((Extensions & AE.ID) == AE.ID && !AE.Feature.empty())

322 Features.push_back(AE.Feature);

323 else if (!AE.NegFeature.empty())

324 Features.push_back(AE.NegFeature);

325 }

326

328}

329

331 return ARMArchNames[static_cast<unsigned>(AK)].Name;

332}

333

335 return ARMArchNames[static_cast<unsigned>(AK)].CPUAttr;

336}

337

339 return ARMArchNames[static_cast<unsigned>(AK)].getSubArch();

340}

341

343 return ARMArchNames[static_cast<unsigned>(AK)].ArchAttr;

344}

345

349 return AE.Name;

350 }

352}

353

355 return Name.consume_front("no");

356}

357

361 if (!AE.Feature.empty() && ArchExt == AE.Name)

362 return StringRef(Negated ? AE.NegFeature : AE.Feature);

363 }

364

366}

367

369 if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)

370 return ARM::FK_INVALID;

371

373

374

375

377 return InputFPUKind;

378

379

380

382 if (CandidateFPU.FPUVer == InputFPU.FPUVer &&

383 CandidateFPU.NeonSupport == InputFPU.NeonSupport &&

387 return CandidateFPU.ID;

388 }

389 }

390

391

392 return ARM::FK_INVALID;

393}

394

396 if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)

397 return ARM::FK_INVALID;

398

400

401

402

404 return InputFPUKind;

405

406

407

409 if (CandidateFPU.FPUVer == InputFPU.FPUVer &&

410 CandidateFPU.NeonSupport == InputFPU.NeonSupport &&

414 return CandidateFPU.ID;

415 }

416 }

417

418

419 return ARM::FK_INVALID;

420}

421

424 std::vector &Features,

426

427 size_t StartingNumFeatures = Features.size();

430

432 return false;

433

435 if (Negated) {

436 if ((AE.ID & ID) == ID && !AE.NegFeature.empty())

437 Features.push_back(AE.NegFeature);

438 } else {

439 if ((AE.ID & ID) == AE.ID && !AE.Feature.empty())

440 Features.push_back(AE.Feature);

441 }

442 }

443

444 if (CPU == "")

445 CPU = "generic";

446

447 if (ArchExt == "fp" || ArchExt == "fp.dp") {

450 if (ArchExt == "fp.dp") {

451 const bool IsDP = ArgFPUKind != ARM::FK_INVALID &&

452 ArgFPUKind != ARM::FK_NONE &&

454 if (Negated) {

455

456

457

458 if (ArgFPUKind != ARM::FK_INVALID && !IsDP)

459 return true;

461 if (FPUKind == ARM::FK_INVALID)

463 } else {

464 if (IsDP)

465 return true;

467 if (FPUKind == ARM::FK_INVALID)

468 return false;

469 }

470 } else if (Negated) {

472 } else {

474 }

476 return true;

477 }

478 return StartingNumFeatures != Features.size();

479}

480

483 return ARM::ArchKind::INVALID;

484 if (AK < ARM::ArchKind::ARMV9A || AK > ARM::ArchKind::ARMV9_3A)

485 return ARM::ArchKind::INVALID;

486 unsigned AK_v8 = static_cast<unsigned>(ARM::ArchKind::ARMV8_5A);

487 AK_v8 += static_cast<unsigned>(AK) -

488 static_cast<unsigned>(ARM::ArchKind::ARMV9A);

490}

491

494 if (AK == ArchKind::INVALID)

496

497

498 for (const auto &CPU : CPUNames) {

499 if (CPU.ArchID == AK && CPU.Default)

500 return CPU.Name;

501 }

502

503

504 return "generic";

505}

506

510 if (Syn == D.Name)

511 return D.ID;

512 }

514}

515

518 if (ArchExt == A.Name)

519 return A.ID;

520 }

522}

523

526 if (CPU == C.Name)

527 return C.ArchID;

528 }

529 return ArchKind::INVALID;

530}

531

533 for (const auto &Arch : CPUNames) {

534 if (Arch.ArchID != ArchKind::INVALID)

536 }

537}

538

542

543 if (TT.isOSBinFormatMachO()) {

547 return "aapcs";

548 if (TT.isWatchABI())

549 return "aapcs16";

550 return "apcs-gnu";

551 } else if (TT.isOSWindows())

552

553 return "aapcs";

554

555

556 switch (TT.getEnvironment()) {

565 return "aapcs-linux";

568 return "aapcs";

569 default:

570 if (TT.isOSNetBSD())

571 return "apcs-gnu";

572 if (TT.isOSFreeBSD() || TT.isOSOpenBSD() || TT.isOSHaiku() ||

573 TT.isOHOSFamily())

574 return "aapcs-linux";

575 return "aapcs";

576 }

577}

578

580 if (MArch.empty())

583

584

590 if (!MArch.empty() && MArch == "v6")

591 return "arm1176jzf-s";

592 if (!MArch.empty() && MArch == "v7")

593 return "cortex-a8";

594 break;

596

598 return "cortex-a9";

599 break;

606 if (MArch == "v7k")

607 return "cortex-a7";

608 break;

609 default:

610 break;

611 }

612

613 if (MArch.empty())

615

617 if (!CPU.empty() && CPU != "invalid")

618 return CPU;

619

620

621

624 return "arm1176jzf-s";

631 return "arm926ej-s";

632 default:

633 return "strongarm";

634 }

637 return "cortex-a8";

638 default:

644 return "arm1176jzf-s";

645 default:

646 return "arm7tdmi";

647 }

648 }

649

651}

652

654 outs() << "All available -march extensions for ARM\n\n"

656 << (DescMap.empty() ? "\n" : "Description\n");

658

659 if (!Ext.Feature.empty()) {

660 std::string Description = DescMap[Ext.Name].str();

661 outs() << " "

662 << format(Description.empty() ? "%s\n" : "%-20s%s\n",

663 Ext.Name.str().c_str(), Description.c_str());

664 }

665 }

666}

static ARM::FPUKind findSinglePrecisionFPU(ARM::FPUKind InputFPUKind)

static StringRef getHWDivSynonym(StringRef HWDiv)

static bool stripNegationPrefix(StringRef &Name)

static ARM::ProfileKind getProfileKind(ARM::ArchKind AK)

static ARM::FPUKind findDoublePrecisionFPU(ARM::FPUKind InputFPUKind)

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

Analysis containing CSE Info

static cl::opt< std::set< SPIRV::Extension::Extension >, false, SPIRVExtensionsParser > Extensions("spirv-ext", cl::desc("Specify list of enabled SPIR-V extensions"))

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

static Triple::ArchType parseArch(StringRef ArchName)

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void push_back(const T &Elt)

StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...

StringRef - Represent a constant reference to a string, i.e.

constexpr bool empty() const

empty - Check if the string is empty.

A switch()-like statement whose cases are string literals.

StringSwitch & Case(StringLiteral S, T Value)

StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)

Triple - Helper class for working with autoconf configuration names.

OSType getOS() const

Get the parsed operating system type of this triple.

EnvironmentType getEnvironment() const

Get the parsed environment type of this triple.

StringRef getArchName() const

Get the architecture (first) component of the triple.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

StringRef getArchExtName(uint64_t ArchExtKind)

StringRef getFPUSynonym(StringRef FPU)

bool getFPUFeatures(FPUKind FPUKind, std::vector< StringRef > &Features)

StringRef getCanonicalArchName(StringRef Arch)

MArch is expected to be of the form (arm|thumb)?(eb)?(v.

uint64_t parseHWDiv(StringRef HWDiv)

StringRef getCPUAttr(ArchKind AK)

const struct llvm::ARM::@432 HWDivNames[]

StringRef getArchName(ArchKind AK)

StringRef computeDefaultTargetABI(const Triple &TT, StringRef CPU)

void fillValidCPUArchList(SmallVectorImpl< StringRef > &Values)

static const FPUName FPUNames[]

uint64_t parseArchExt(StringRef ArchExt)

ArchKind convertV9toV8(ArchKind AK)

ArchKind parseArch(StringRef Arch)

FPURestriction getFPURestriction(FPUKind FPUKind)

bool appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK, StringRef ArchExt, std::vector< StringRef > &Features, FPUKind &ArgFPUKind)

StringRef getArchSynonym(StringRef Arch)

Converts e.g. "armv8" -> "armv8-a".

StringRef getDefaultCPU(StringRef Arch)

StringRef getArchExtFeature(StringRef ArchExt)

const CpuNames CPUNames[]

ProfileKind parseArchProfile(StringRef Arch)

FPUKind parseFPU(StringRef FPU)

StringRef getSubArch(ArchKind AK)

static const ArchNames ARMArchNames[]

StringRef getARMCPUForArch(const llvm::Triple &Triple, StringRef MArch={})

Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.

unsigned parseArchVersion(StringRef Arch)

const ExtName ARCHExtNames[]

bool has32Regs(const FPURestriction restriction)

NeonSupportLevel getFPUNeonSupportLevel(FPUKind FPUKind)

ArchKind parseCPUArch(StringRef CPU)

bool isDoublePrecision(const FPURestriction restriction)

unsigned getArchAttr(ArchKind AK)

StringRef getFPUName(FPUKind FPUKind)

FPUVersion getFPUVersion(FPUKind FPUKind)

bool getHWDivFeatures(uint64_t HWDivKind, std::vector< StringRef > &Features)

uint64_t getDefaultExtensions(StringRef CPU, ArchKind AK)

FPUKind getDefaultFPU(StringRef CPU, ArchKind AK)

bool getExtensionFeatures(uint64_t Extensions, std::vector< StringRef > &Features)

void PrintSupportedExtensions(StringMap< StringRef > DescMap)

@ C

The default llvm calling convention, compatible with C.

This is an optimization pass for GlobalISel generic memory operations.

raw_fd_ostream & outs()

This returns a reference to a raw_fd_ostream for standard output.

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

FormattedString left_justify(StringRef Str, unsigned Width)

left_justify - append spaces after string so total output is Width characters.

FPURestriction Restriction

NeonSupportLevel NeonSupport