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

1

2

3

4

5

6

7

8

16

17#include

18#include

19#include

20#include

21

22using namespace llvm;

23

24namespace {

25

26struct RISCVSupportedExtension {

27 const char *Name;

28

29 RISCVISAUtils::ExtensionVersion Version;

30

31 bool operator<(const RISCVSupportedExtension &RHS) const {

32 return StringRef(Name) < StringRef(RHS.Name);

33 }

34};

35

36struct RISCVProfile {

37 StringLiteral Name;

38 StringLiteral MArch;

39

40 bool operator<(const RISCVProfile &RHS) const {

41 return StringRef(Name) < StringRef(RHS.Name);

42 }

43};

44

45}

46

49

50#define GET_SUPPORTED_EXTENSIONS

51#include "llvm/TargetParser/RISCVTargetParserDef.inc"

52

53#define GET_SUPPORTED_PROFILES

54#include "llvm/TargetParser/RISCVTargetParserDef.inc"

55

57#ifndef NDEBUG

58 static std::atomic TableChecked(false);

59 if (!TableChecked.load(std::memory_order_relaxed)) {

61 "Extensions are not sorted by name");

63 "Experimental extensions are not sorted by name");

65 "Profiles are not sorted by name");

67 "Experimental profiles are not sorted by name");

68 TableChecked.store(true, std::memory_order_relaxed);

69 }

70#endif

71}

72

76 unsigned VersionWidth = Description.empty() ? 0 : 10;

78 << Description << "\n";

79}

80

82 outs() << "All available -march extensions for RISC-V\n\n";

83 PrintExtension("Name", "Version", (DescMap.empty() ? "" : "Description"));

84

86 for (const auto &E : SupportedExtensions)

87 ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};

88 for (const auto &E : ExtMap) {

90 std::to_string(E.second.Major) + "." + std::to_string(E.second.Minor);

92 }

93

94 outs() << "\nExperimental extensions\n";

95 ExtMap.clear();

96 for (const auto &E : SupportedExperimentalExtensions)

97 ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};

98 for (const auto &E : ExtMap) {

100 std::to_string(E.second.Major) + "." + std::to_string(E.second.Minor);

102 }

103

104 outs() << "\nSupported Profiles\n";

105 for (const auto &P : SupportedProfiles)

107

108 outs() << "\nExperimental Profiles\n";

109 for (const auto &P : SupportedExperimentalProfiles)

111

112 outs() << "\nUse -march to specify the target's extension.\n"

113 "For example, clang -march=rv32i_v1p0\n";

114}

115

117 bool IsRV64, std::set &EnabledFeatureNames,

119 outs() << "Extensions enabled for the given RISC-V target\n\n";

120 PrintExtension("Name", "Version", (DescMap.empty() ? "" : "Description"));

121

124 for (const auto &E : SupportedExtensions)

125 if (EnabledFeatureNames.count(E.Name) != 0) {

126 FullExtMap[E.Name] = {E.Version.Major, E.Version.Minor};

127 ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};

128 }

129 for (const auto &E : ExtMap) {

131 std::to_string(E.second.Major) + "." + std::to_string(E.second.Minor);

133 }

134

135 outs() << "\nExperimental extensions\n";

136 ExtMap.clear();

137 for (const auto &E : SupportedExperimentalExtensions) {

139 if (EnabledFeatureNames.count("experimental-" + Name.str()) != 0) {

140 FullExtMap[E.Name] = {E.Version.Major, E.Version.Minor};

141 ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};

142 }

143 }

144 for (const auto &E : ExtMap) {

146 std::to_string(E.second.Major) + "." + std::to_string(E.second.Minor);

148 }

149

150 unsigned XLen = IsRV64 ? 64 : 32;

152 outs() << "\nISA String: " << ISAString.get()->toString() << "\n";

153}

154

158

159

160

161

162

163

164

165

168 "Already guarded by if-statement in ::parseArchString");

169

170 int Pos = Ext.size() - 1;

171 while (Pos > 0 && isDigit(Ext[Pos]))

172 Pos--;

173 if (Pos > 0 && Ext[Pos] == 'p' && isDigit(Ext[Pos - 1])) {

174 Pos--;

175 while (Pos > 0 && isDigit(Ext[Pos]))

176 Pos--;

177 }

178 return Pos;

179}

180

181namespace {

182struct LessExtName {

183 bool operator()(const RISCVSupportedExtension &LHS, StringRef RHS) {

184 return StringRef(LHS.Name) < RHS;

185 }

186 bool operator()(StringRef LHS, const RISCVSupportedExtension &RHS) {

187 return LHS < StringRef(RHS.Name);

188 }

189};

190}

191

192static std::optionalRISCVISAUtils::ExtensionVersion

194

195

196 for (auto &ExtInfo : {ArrayRef(SupportedExtensions),

197 ArrayRef(SupportedExperimentalExtensions)}) {

199

200 if (I == ExtInfo.end() || I->Name != ExtName)

201 continue;

202

203 return I->Version;

204 }

205 return std::nullopt;

206}

207

210 return "standard supervisor-level extension";

212 return "non-standard user-level extension";

214 return "standard user-level extension";

216}

217

220 return "s";

222 return "x";

224 return "z";

226}

227

228static std::optionalRISCVISAUtils::ExtensionVersion

230 auto I =

231 llvm::lower_bound(SupportedExperimentalExtensions, Ext, LessExtName());

232 if (I == std::end(SupportedExperimentalExtensions) || I->Name != Ext)

233 return std::nullopt;

234

235 return I->Version;

236}

237

240

242 IsExperimental ? ArrayRef(SupportedExperimentalExtensions)

243 : ArrayRef(SupportedExtensions);

244

246 return I != ExtInfo.end() && I->Name == Ext;

247}

248

251

252 for (auto ExtInfo : {ArrayRef(SupportedExtensions),

253 ArrayRef(SupportedExperimentalExtensions)}) {

255 if (I != ExtInfo.end() && I->Name == Ext)

256 return true;

257 }

258

259 return false;

260}

261

263 unsigned MinorVersion) {

264 for (auto ExtInfo : {ArrayRef(SupportedExtensions),

265 ArrayRef(SupportedExperimentalExtensions)}) {

267 std::equal_range(ExtInfo.begin(), ExtInfo.end(), Ext, LessExtName());

268 for (auto I = Range.first, E = Range.second; I != E; ++I)

269 if (I->Version.Major == MajorVersion && I->Version.Minor == MinorVersion)

270 return true;

271 }

272

273 return false;

274}

275

278

280 return false;

281

282 return Exts.count(Ext.str()) != 0;

283}

284

286 bool IgnoreUnknown) const {

287 std::vectorstd::string Features;

288 for (const auto &[ExtName, _] : Exts) {

290 continue;

291

293 Features.push_back((llvm::Twine("+experimental-") + ExtName).str());

294 } else {

295 Features.push_back((llvm::Twine("+") + ExtName).str());

296 }

297 }

298 if (AddAllExtensions) {

299 for (const RISCVSupportedExtension &Ext : SupportedExtensions) {

300 if (Exts.count(Ext.Name))

301 continue;

302 Features.push_back((llvm::Twine("-") + Ext.Name).str());

303 }

304

305 for (const RISCVSupportedExtension &Ext : SupportedExperimentalExtensions) {

306 if (Exts.count(Ext.Name))

307 continue;

308 Features.push_back((llvm::Twine("-experimental-") + Ext.Name).str());

309 }

310 }

311 return Features;

312}

313

317

319 if (ExtName.size() == 1) {

320 return getError("unsupported standard user-level extension '" + ExtName +

321 "'");

322 }

324 ExtName + "'");

325}

326

327

328

329

330

331

333 unsigned &Minor, unsigned &ConsumeLength,

334 bool EnableExperimentalExtension,

335 bool ExperimentalExtensionVersionCheck) {

337 Major = 0;

338 Minor = 0;

339 ConsumeLength = 0;

340 MajorStr = In.take_while(isDigit);

341 In = In.substr(MajorStr.size());

342

343 if (!MajorStr.empty() && In.consume_front("p")) {

344 MinorStr = In.take_while(isDigit);

345 In = In.substr(MajorStr.size() + MinorStr.size() - 1);

346

347

348 if (MinorStr.empty()) {

349 return getError("minor version number missing after 'p' for extension '" +

350 Ext + "'");

351 }

352 }

353

355 return getError("Failed to parse major version number for extension '" +

356 Ext + "'");

357

359 return getError("Failed to parse minor version number for extension '" +

360 Ext + "'");

361

362 ConsumeLength = MajorStr.size();

363

364 if (!MinorStr.empty())

365 ConsumeLength += MinorStr.size() + 1 ;

366

367

368

369

370 if (Ext.size() > 1 && In.size())

372 "multi-character extensions must be separated by underscores");

373

374

376 if (!EnableExperimentalExtension)

377 return getError("requires '-menable-experimental-extensions' "

378 "for experimental extension '" +

379 Ext + "'");

380

381 if (ExperimentalExtensionVersionCheck &&

382 (MajorStr.empty() && MinorStr.empty()))

384 "experimental extension requires explicit version number `" + Ext +

385 "`");

386

387 auto SupportedVers = *ExperimentalExtension;

388 if (ExperimentalExtensionVersionCheck &&

389 (Major != SupportedVers.Major || Minor != SupportedVers.Minor)) {

390 std::string Error = "unsupported version number " + MajorStr.str();

391 if (!MinorStr.empty())

392 Error += "." + MinorStr.str();

393 Error += " for experimental extension '" + Ext.str() +

394 "' (this compiler supports " + utostr(SupportedVers.Major) +

395 "." + utostr(SupportedVers.Minor) + ")";

397 }

399 }

400

401

402

403 if (Ext == "g")

405

406 if (MajorStr.empty() && MinorStr.empty()) {

408 Major = DefaultVersion->Major;

409 Minor = DefaultVersion->Minor;

410 }

411

412

414 }

415

418

421

422 std::string Error = "unsupported version number " + MajorStr.str();

423 if (!MinorStr.empty())

424 Error += "." + MinorStr.str();

425 Error += " for extension '" + Ext.str() + "'";

427}

428

432 assert(XLen == 32 || XLen == 64);

433 std::unique_ptr ISAInfo(new RISCVISAInfo(XLen));

434

435 ISAInfo->Exts = Exts;

436

437 return RISCVISAInfo::postProcessAndChecking(std::move(ISAInfo));

438}

439

442 const std::vectorstd::string &Features) {

443 assert(XLen == 32 || XLen == 64);

444 std::unique_ptr ISAInfo(new RISCVISAInfo(XLen));

445

446 for (StringRef ExtName : Features) {

447 assert(ExtName.size() > 1 && (ExtName[0] == '+' || ExtName[0] == '-'));

448 bool Add = ExtName[0] == '+';

449 ExtName = ExtName.drop_front(1);

451 auto ExtensionInfos = Experimental

452 ? ArrayRef(SupportedExperimentalExtensions)

453 : ArrayRef(SupportedExtensions);

454 auto ExtensionInfoIterator =

456

457

458

459 if (ExtensionInfoIterator == ExtensionInfos.end() ||

460 ExtensionInfoIterator->Name != ExtName)

461 continue;

462

464 ISAInfo->Exts[ExtName.str()] = ExtensionInfoIterator->Version;

465 else

466 ISAInfo->Exts.erase(ExtName.str());

467 }

468

469 return RISCVISAInfo::postProcessAndChecking(std::move(ISAInfo));

470}

471

474

477 return getError("string may only contain [a-z0-9_]");

478

479

480 unsigned XLen = 0;

482 XLen = 32;

484 XLen = 64;

485

486 if (XLen == 0 || Arch.empty() || (Arch[0] != 'i' && Arch[0] != 'e'))

487 return getError("arch string must begin with valid base ISA");

488

489 std::unique_ptr ISAInfo(new RISCVISAInfo(XLen));

490

491

492

493

494 while (!Arch.empty()) {

495 if (Arch[0] == '_') {

496 if (Arch.size() == 1 || Arch[1] == '_')

497 return getError("extension name missing after separator '_'");

499 }

500

501 size_t Idx = Arch.find('_');

503 Arch = Arch.substr(Idx);

504

505 StringRef Prefix, MinorVersionStr;

506 std::tie(Prefix, MinorVersionStr) = Ext.rsplit('p');

507 if (MinorVersionStr.empty())

508 return getError("extension lacks version in expected format");

509 unsigned MajorVersion, MinorVersion;

510 if (MinorVersionStr.getAsInteger(10, MinorVersion))

511 return getError("failed to parse minor version number");

512

513

514

515 size_t VersionStart = Prefix.size();

516 while (VersionStart != 0) {

517 if (isDigit(Prefix[VersionStart - 1]))

518 break;

519 --VersionStart;

520 }

521 if (VersionStart == Prefix.size())

522 return getError("extension lacks version in expected format");

523

524 if (VersionStart == 0)

525 return getError("missing extension name");

526

527 StringRef ExtName = Prefix.slice(0, VersionStart);

528 StringRef MajorVersionStr = Prefix.substr(VersionStart);

529 if (MajorVersionStr.getAsInteger(10, MajorVersion))

530 return getError("failed to parse major version number");

531

532 if ((ExtName[0] == 'z' || ExtName[0] == 's' || ExtName[0] == 'x') &&

533 (ExtName.size() == 1 || isDigit(ExtName[1])))

535 "' must be followed by a letter");

536

537 if (!ISAInfo->Exts

538 .emplace(

539 ExtName.str(),

541 .second)

542 return getError("duplicate extension '" + ExtName + "'");

543 }

544 ISAInfo->updateImpliedLengths();

545 return std::move(ISAInfo);

546}

547

550 bool ExperimentalExtensionVersionCheck) {

551

554 return getError("string may only contain [a-z0-9_]");

555

556

557 unsigned XLen = 0;

559 XLen = 32;

561 XLen = 64;

562 } else {

563

564 auto ProfileCmp = [](StringRef Arch, const RISCVProfile &Profile) {

565 return Arch < Profile.Name;

566 };

568 bool FoundProfile = I != std::begin(SupportedProfiles) &&

570 if (!FoundProfile) {

571 I = llvm::upper_bound(SupportedExperimentalProfiles, Arch, ProfileCmp);

572 FoundProfile = (I != std::begin(SupportedExperimentalProfiles) &&

574 if (FoundProfile && !EnableExperimentalExtension) {

575 return getError("requires '-menable-experimental-extensions' "

576 "for profile '" +

577 std::prev(I)->Name + "'");

578 }

579 }

580 if (FoundProfile) {

581 --I;

582 std::string NewArch = I->MArch.str();

584 if (!ArchWithoutProfile.empty()) {

585 if (ArchWithoutProfile.front() != '_')

586 return getError("additional extensions must be after separator '_'");

587 NewArch += ArchWithoutProfile.str();

588 }

589 return parseArchString(NewArch, EnableExperimentalExtension,

590 ExperimentalExtensionVersionCheck);

591 }

592 }

593

594 if (XLen == 0 || Arch.empty())

596 "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported "

597 "profile name");

598

599 std::unique_ptr ISAInfo(new RISCVISAInfo(XLen));

600

601

602

603 char Baseline = Arch.front();

604

606

607 unsigned Major, Minor, ConsumeLength;

608

609

610 switch (Baseline) {

611 default:

612 return getError("first letter after \'rv" + Twine(XLen) +

613 "\' should be 'e', 'i' or 'g'");

614 case 'e':

615 case 'i':

616

618 StringRef(&Baseline, 1), Arch, Major, Minor, ConsumeLength,

619 EnableExperimentalExtension, ExperimentalExtensionVersionCheck))

620 return std::move(E);

621

622 ISAInfo->Exts[std::string(1, Baseline)] = {Major, Minor};

623 break;

624 case 'g':

625

627 return getError("version not supported for 'g'");

628

629

630 ConsumeLength = 0;

631

632

633

634

637 assert(Version && "Default extension version not found?");

638 ISAInfo->Exts[std::string(Ext)] = {Version->Major, Version->Minor};

639 }

640 break;

641 }

642

643

644

645 Arch = Arch.drop_front(ConsumeLength);

646

647 while (!Arch.empty()) {

648 if (Arch.front() == '_') {

649 if (Arch.size() == 1 || Arch[1] == '_')

650 return getError("extension name missing after separator '_'");

652 }

653

654 size_t Idx = Arch.find('_');

656 Arch = Arch.substr(Idx);

657

658 do {

663 Vers = Ext;

664 Desc = "standard user-level extension";

665 } else if (Ext.front() == 'z' || Ext.front() == 's' ||

666 Ext.front() == 'x') {

667

668

669

670

671

672

673

674

678 Name = Ext.substr(0, Pos);

679 Vers = Ext.substr(Pos);

681

682 assert(Type.empty() && "Empty type?");

683 if (Name.size() == Type.size())

684 return getError(Desc + " name missing after '" + Type + "'");

685 } else {

686 return getError("invalid standard user-level extension '" +

688 }

689

690 unsigned Major, Minor, ConsumeLength;

691 if (auto E = getExtensionVersion(Name, Vers, Major, Minor, ConsumeLength,

692 EnableExperimentalExtension,

693 ExperimentalExtensionVersionCheck))

694 return E;

695

696 if (Name.size() == 1)

697 Ext = Ext.substr(ConsumeLength);

698

701

702

703 if (!ISAInfo->Exts

704 .emplace(Name.str(),

706 .second)

707 return getError("duplicated " + Desc + " '" + Name + "'");

708

709 } while (!Ext.empty());

710 }

711

712

713

714 if (Baseline == 'g') {

716 if (ISAInfo->Exts.count(Ext))

717 continue;

718

720 assert(Version && "Default extension version not found?");

721 ISAInfo->Exts[std::string(Ext)] = {Version->Major, Version->Minor};

722 }

723 }

724

725 return RISCVISAInfo::postProcessAndChecking(std::move(ISAInfo));

726}

727

729 return getError("'" + Ext1 + "' and '" + Ext2 +

730 "' extensions are incompatible");

731}

732

734 return getError("'" + Ext + "' requires '" + ReqExt +

735 "' extension to also be specified");

736}

737

738Error RISCVISAInfo::checkDependency() {

739 bool HasE = Exts.count("e") != 0;

740 bool HasI = Exts.count("i") != 0;

741 bool HasC = Exts.count("c") != 0;

742 bool HasF = Exts.count("f") != 0;

743 bool HasD = Exts.count("d") != 0;

744 bool HasZfinx = Exts.count("zfinx") != 0;

745 bool HasVector = Exts.count("zve32x") != 0;

746 bool HasZvl = MinVLen != 0;

747 bool HasZcmp = Exts.count("zcmp") != 0;

748 bool HasXqccmp = Exts.count("xqccmp") != 0;

749

750 static constexpr StringLiteral XqciExts[] = {

751 {"xqcia"}, {"xqciac"}, {"xqcibi"}, {"xqcibm"}, {"xqcicli"},

752 {"xqcicm"}, {"xqcics"}, {"xqcicsr"}, {"xqciint"}, {"xqciio"},

753 {"xqcilb"}, {"xqcili"}, {"xqcilia"}, {"xqcilo"}, {"xqcilsm"},

754 {"xqcisim"}, {"xqcisls"}, {"xqcisync"}};

755 static constexpr StringLiteral ZcdOverlaps[] = {

756 {"zcmt"}, {"zcmp"}, {"xqccmp"}, {"xqciac"}, {"xqcicm"}};

757

758 if (HasI && HasE)

760

761 if (HasF && HasZfinx)

763

764 if (HasZvl && !HasVector)

766

767 if (Exts.count("xsfvfbfexp16e") &&

768 !(Exts.count("zvfbfmin") || Exts.count("zvfbfa")))

770 "'xsfvfbfexp16e' requires 'zvfbfmin' or "

771 "'zvfbfa' extension to also be specified");

772

773 if (HasD && (HasC || Exts.count("zcd")))

774 for (auto Ext : ZcdOverlaps)

775 if (Exts.count(Ext.str()))

777 Twine("'") + Ext + "' extension is incompatible with '" +

778 (HasC ? "c" : "zcd") + "' extension when 'd' extension is enabled");

779

780 if (XLen != 32 && Exts.count("zcf"))

781 return getError("'zcf' is only supported for 'rv32'");

782

783 if (Exts.count("xwchc") != 0) {

784 if (XLen != 32)

785 return getError("'xwchc' is only supported for 'rv32'");

786

787 if (HasD)

789

790 if (Exts.count("zcb") != 0)

792 }

793

794 if (Exts.count("zclsd") != 0) {

795 if (XLen != 32)

796 return getError("'zclsd' is only supported for 'rv32'");

797

798 if (Exts.count("zcf") != 0)

800 }

801

802 if (XLen != 32 && Exts.count("zilsd") != 0)

803 return getError("'zilsd' is only supported for 'rv32'");

804

805 for (auto Ext : XqciExts)

806 if (Exts.count(Ext.str()) && (XLen != 32))

807 return getError("'" + Twine(Ext) + "'" + " is only supported for 'rv32'");

808

809 if (HasZcmp && HasXqccmp)

811

813}

814

823

825 return LHS.Name < RHS;

826}

827

829 return LHS < RHS.Name;

830}

831

832#define GET_IMPLIED_EXTENSIONS

833#include "llvm/TargetParser/RISCVTargetParserDef.inc"

834

835void RISCVISAInfo::updateImplication() {

837

838

839

841 for (auto const &Ext : Exts)

843

844 while (!WorkList.empty()) {

846 auto Range = std::equal_range(std::begin(ImpliedExts),

847 std::end(ImpliedExts), ExtName);

849 const char *ImpliedExt = Implied.ImpliedExt;

850 auto [It, Inserted] = Exts.try_emplace(ImpliedExt);

851 if (!Inserted)

852 continue;

854 It->second = *Version;

856 }

857 }

858

859

860 if (Exts.count("c") && Exts.count("d") && !Exts.count("zcd")) {

862 Exts["zcd"] = *Version;

863 }

864

865

866 if (XLen == 32 && Exts.count("c") && Exts.count("f") && !Exts.count("zcf")) {

868 Exts["zcf"] = *Version;

869 }

870

871

872 if (XLen == 32 && Exts.count("zce") && Exts.count("f") &&

873 !Exts.count("zcf")) {

875 Exts["zcf"] = *Version;

876 }

877

878

879

880 bool HasE = Exts.count("e") != 0;

881 bool HasI = Exts.count("i") != 0;

882

883

884

885 if (!HasE && !HasI) {

887 Exts["i"] = *Version;

888 }

889

890 if (HasE && HasI)

891 Exts.erase("i");

892}

893

895 {"a"}, {"b"}, {"zk"}, {"zkn"}, {"zks"}, {"zvkn"},

896 {"zvknc"}, {"zvkng"}, {"zvks"}, {"zvksc"}, {"zvksg"},

897};

898

899void RISCVISAInfo::updateCombination() {

900 bool MadeChange = false;

901 do {

902 MadeChange = false;

904 if (Exts.count(CombineExt.str()))

905 continue;

906

907

908

909 auto Range = std::equal_range(std::begin(ImpliedExts),

910 std::end(ImpliedExts), CombineExt);

911 bool HasAllRequiredFeatures = std::all_of(

912 Range.first, Range.second, [&](const ImpliedExtsEntry &Implied) {

913 return Exts.count(Implied.ImpliedExt);

914 });

915 if (HasAllRequiredFeatures) {

917 Exts[CombineExt.str()] = *Version;

918 MadeChange = true;

919 }

920 }

921 } while (MadeChange);

922}

923

924void RISCVISAInfo::updateImpliedLengths() {

925 assert(FLen == 0 && MaxELenFp == 0 && MaxELen == 0 && MinVLen == 0 &&

926 "Expected lengths to be initialied to zero");

927

928 if (Exts.count("q"))

929 FLen = 128;

930 else if (Exts.count("d"))

931 FLen = 64;

932 else if (Exts.count("f"))

933 FLen = 32;

934

935 if (Exts.count("v")) {

936 MaxELenFp = std::max(MaxELenFp, 64u);

937 MaxELen = std::max(MaxELen, 64u);

938 }

939

940 for (auto const &Ext : Exts) {

941 StringRef ExtName = Ext.first;

942

944 unsigned ZveELen;

946 continue;

947

948 if (ExtName == "f")

949 MaxELenFp = std::max(MaxELenFp, 32u);

950 else if (ExtName == "d")

951 MaxELenFp = std::max(MaxELenFp, 64u);

952 else if (ExtName != "x")

953 continue;

954

955 MaxELen = std::max(MaxELen, ZveELen);

956 continue;

957 }

958

959

961 unsigned ZvlLen;

963 continue;

964

965 if (ExtName != "b")

966 continue;

967

968 MinVLen = std::max(MinVLen, ZvlLen);

969 continue;

970 }

971 }

972}

973

975 std::string Buffer;

977

978 Arch << "rv" << XLen;

979

981 for (auto const &Ext : Exts) {

983 auto ExtInfo = Ext.second;

984 Arch << LS << ExtName;

985 Arch << ExtInfo.Major << "p" << ExtInfo.Minor;

986 }

987

988 return Arch.str();

989}

990

992RISCVISAInfo::postProcessAndChecking(std::unique_ptr &&ISAInfo) {

993 ISAInfo->updateImplication();

994 ISAInfo->updateCombination();

995 ISAInfo->updateImpliedLengths();

996

997 if (Error Result = ISAInfo->checkDependency())

998 return std::move(Result);

999 return std::move(ISAInfo);

1000}

1001

1003 if (XLen == 32) {

1004 if (Exts.count("e"))

1005 return "ilp32e";

1006 if (Exts.count("d"))

1007 return "ilp32d";

1008 if (Exts.count("f"))

1009 return "ilp32f";

1010 return "ilp32";

1011 } else if (XLen == 64) {

1012 if (Exts.count("e"))

1013 return "lp64e";

1014 if (Exts.count("d"))

1015 return "lp64d";

1016 if (Exts.count("f"))

1017 return "lp64f";

1018 return "lp64";

1019 }

1021}

1022

1024 if (Ext.empty())

1025 return false;

1026

1030 if (Vers.empty())

1031 return false;

1032

1033 unsigned Major, Minor, ConsumeLength;

1034 if (auto E = getExtensionVersion(Name, Vers, Major, Minor, ConsumeLength,

1035 true, true)) {

1037 return false;

1038 }

1039

1040 return true;

1041}

1042

1044 if (Ext.empty())

1045 return std::string();

1046

1049

1051 return std::string();

1052

1054 return std::string();

1055

1057 : Name.str();

1058}

1059

1065

1071

1072#define GET_RISCVExtensionBitmaskTable_IMPL

1073#include "llvm/TargetParser/RISCVTargetParserDef.inc"

1074

1076

1077

1078

1079 for (auto E : ExtensionBitmask)

1081 return std::make_pair(E.GroupID, E.BitPosition);

1082 return std::make_pair(-1, -1);

1083}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))

static void verifyTables()

Definition RISCVISAInfo.cpp:56

static StringRef getExtensionTypeDesc(StringRef Ext)

Definition RISCVISAInfo.cpp:208

static const char * RISCVGImplicationsZi[]

Definition RISCVISAInfo.cpp:48

static std::optional< RISCVISAUtils::ExtensionVersion > findDefaultVersion(StringRef ExtName)

Definition RISCVISAInfo.cpp:193

static size_t findLastNonVersionCharacter(StringRef Ext)

Definition RISCVISAInfo.cpp:166

static Error getExtensionRequiresError(StringRef Ext, StringRef ReqExt)

Definition RISCVISAInfo.cpp:733

static StringRef getExtensionType(StringRef Ext)

Definition RISCVISAInfo.cpp:218

static Error getErrorForInvalidExt(StringRef ExtName)

Definition RISCVISAInfo.cpp:318

static constexpr StringLiteral CombineIntoExts[]

Definition RISCVISAInfo.cpp:894

static bool stripExperimentalPrefix(StringRef &Ext)

Definition RISCVISAInfo.cpp:155

static std::optional< RISCVISAUtils::ExtensionVersion > isExperimentalExtension(StringRef Ext)

Definition RISCVISAInfo.cpp:229

static void PrintExtension(StringRef Name, StringRef Version, StringRef Description)

Definition RISCVISAInfo.cpp:73

static Error getExtensionVersion(StringRef Ext, StringRef In, unsigned &Major, unsigned &Minor, unsigned &ConsumeLength, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck)

Definition RISCVISAInfo.cpp:332

static Error getIncompatibleError(StringRef Ext1, StringRef Ext2)

Definition RISCVISAInfo.cpp:728

static Error getError(const Twine &Message)

Definition RISCVISAInfo.cpp:314

static const char * RISCVGImplications[]

Definition RISCVISAInfo.cpp:47

static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)

static void verifyTables()

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

A helper class to return the specified delimiter string after the first invocation of operator String...

static LLVM_ABI bool isSupportedExtensionFeature(StringRef Ext)

Definition RISCVISAInfo.cpp:238

static LLVM_ABI std::string getTargetFeatureForExtension(StringRef Ext)

Definition RISCVISAInfo.cpp:1043

static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseNormalizedArchString(StringRef Arch)

Parse RISC-V ISA info from an arch string that is already in normalized form (as defined in the psABI...

Definition RISCVISAInfo.cpp:473

LLVM_ABI bool hasExtension(StringRef Ext) const

Definition RISCVISAInfo.cpp:276

RISCVISAInfo(const RISCVISAInfo &)=delete

LLVM_ABI std::string toString() const

Definition RISCVISAInfo.cpp:974

LLVM_ABI StringRef computeDefaultABI() const

Definition RISCVISAInfo.cpp:1002

static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true)

Parse RISC-V ISA info from arch string.

Definition RISCVISAInfo.cpp:549

static LLVM_ABI bool isSupportedExtension(StringRef Ext)

Definition RISCVISAInfo.cpp:249

static LLVM_ABI void printEnabledExtensions(bool IsRV64, std::set< StringRef > &EnabledFeatureNames, StringMap< StringRef > &DescMap)

Definition RISCVISAInfo.cpp:116

static LLVM_ABI void printSupportedExtensions(StringMap< StringRef > &DescMap)

Definition RISCVISAInfo.cpp:81

static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatures(unsigned XLen, const std::vector< std::string > &Features)

Parse RISC-V ISA info from feature vector.

Definition RISCVISAInfo.cpp:441

static LLVM_ABI std::pair< int, int > getRISCVFeaturesBitsInfo(StringRef Ext)

Return the group id and bit position of __riscv_feature_bits.

Definition RISCVISAInfo.cpp:1075

static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > createFromExtMap(unsigned XLen, const RISCVISAUtils::OrderedExtensionMap &Exts)

Definition RISCVISAInfo.cpp:430

LLVM_ABI std::vector< std::string > toFeatures(bool AddAllExtensions=false, bool IgnoreUnknown=true) const

Convert RISC-V ISA info to a feature vector.

Definition RISCVISAInfo.cpp:285

static LLVM_ABI bool isSupportedExtensionWithVersion(StringRef Ext)

Definition RISCVISAInfo.cpp:1023

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...

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.

bool consumeInteger(unsigned Radix, T &Result)

Parse the current string as an integer of the specified radix.

bool getAsInteger(unsigned Radix, T &Result) const

Parse the current string as an integer of the specified radix.

std::string str() const

str - Get the contents as an std::string.

constexpr StringRef substr(size_t Start, size_t N=npos) const

Return a reference to the substring from [Start, Start + N).

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr bool empty() const

empty - Check if the string is empty.

StringRef drop_front(size_t N=1) const

Return a StringRef equal to 'this' but with the first N elements dropped.

StringRef slice(size_t Start, size_t End) const

Return a reference to the substring from [Start, End).

constexpr size_t size() const

size - Get the string size.

char front() const

front - Get the first character in the string.

bool consume_front(StringRef Prefix)

Returns true if this StringRef has the given prefix and removes that prefix.

StringRef take_front(size_t N=1) const

Return a StringRef equal to 'this' but with only the first N elements remaining.

size_t find(char C, size_t From=0) const

Search for the first character C in the string.

std::pair< StringRef, StringRef > rsplit(StringRef Separator) const

Split into two substrings around the last occurrence of a separator string.

bool equals_insensitive(StringRef RHS) const

Check for string equality, ignoring case.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

The instances of the Type class are immutable: once they are created, they are never changed.

raw_ostream & indent(unsigned NumSpaces)

indent - Insert 'NumSpaces' spaces.

A raw_ostream that writes to an std::string.

std::string & str()

Returns the string's reference.

#define llvm_unreachable(msg)

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

@ C

The default llvm calling convention, compatible with C.

constexpr StringLiteral AllStdExts

std::map< std::string, ExtensionVersion, ExtensionComparator > OrderedExtensionMap

OrderedExtensionMap is std::map, it's specialized to keep entries in canonical order of extension.

This is an optimization pass for GlobalISel generic memory operations.

bool operator<(int64_t V1, const APSInt &V2)

bool all_of(R &&range, UnaryPredicate P)

Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.

bool isLower(char C)

Checks if character C is a lowercase letter as classified by "C" locale.

LLVM_ABI raw_fd_ostream & outs()

This returns a reference to a raw_fd_ostream for standard output.

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

std::string utostr(uint64_t X, bool isNeg=false)

auto upper_bound(R &&Range, T &&Value)

Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...

Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)

Create formatted StringError object.

FunctionAddr VTableAddr uintptr_t uintptr_t Version

bool isDigit(char C)

Checks if character C is one of the 10 decimal digits.

bool is_sorted(R &&Range, Compare C)

Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...

FormattedString left_justify(StringRef Str, unsigned Width)

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

auto lower_bound(R &&Range, T &&Value)

Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...

ArrayRef(const T &OneElt) -> ArrayRef< T >

void consumeError(Error Err)

Consume a Error without doing anything.

Definition RISCVISAInfo.cpp:815

StringLiteral Name

Definition RISCVISAInfo.cpp:816

bool operator<(const ImpliedExtsEntry &Other) const

Definition RISCVISAInfo.cpp:819

const char * ImpliedExt

Definition RISCVISAInfo.cpp:817

Definition RISCVISAInfo.cpp:1060

uint8_t bitpos

Definition RISCVISAInfo.cpp:1063

uint8_t groupid

Definition RISCVISAInfo.cpp:1062

const StringLiteral ext

Definition RISCVISAInfo.cpp:1061

Definition RISCVISAInfo.cpp:1066

const char * Name

Definition RISCVISAInfo.cpp:1067

unsigned BitPosition

Definition RISCVISAInfo.cpp:1069

unsigned GroupID

Definition RISCVISAInfo.cpp:1068

Represents the major and version number components of a RISC-V extension.