14 #include "llvm/Option/ArgList.h" 15 #include "llvm/ADT/Optional.h" 16 #include "llvm/Support/TargetParser.h" 17 #include "llvm/Support/raw_ostream.h" 22 using namespace clang;
27 struct RISCVExtensionVersion {
34 if (Ext.startswith(
"sx"))
35 return "non-standard supervisor-level extension";
36 if (Ext.startswith(
"s"))
37 return "standard supervisor-level extension";
38 if (Ext.startswith(
"x"))
39 return "non-standard user-level extension";
40 if (Ext.startswith(
"z"))
41 return "standard user-level extension";
46 if (Ext.startswith(
"sx"))
48 if (Ext.startswith(
"s"))
50 if (Ext.startswith(
"x"))
52 if (Ext.startswith(
"z"))
61 if (Ext ==
"b" || Ext ==
"zbb" || Ext ==
"zbc" || Ext ==
"zbe" ||
62 Ext ==
"zbf" || Ext ==
"zbm" || Ext ==
"zbp" || Ext ==
"zbr" ||
63 Ext ==
"zbs" || Ext ==
"zbt" || Ext ==
"zbproposedc")
64 return RISCVExtensionVersion{
"0",
"92"};
66 return RISCVExtensionVersion{
"0",
"9"};
68 return RISCVExtensionVersion{
"0",
"1"};
87 StringRef MArch, StringRef Ext, StringRef In,
88 std::string &Major, std::string &Minor) {
89 Major = std::string(In.take_while(
isDigit));
90 In = In.substr(Major.size());
92 if (Major.size() && In.consume_front(
"p")) {
93 Minor = std::string(In.take_while(
isDigit));
94 In = In.substr(Major.size() + 1);
99 "minor version number missing after 'p' for extension";
100 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
101 << MArch <<
Error << Ext;
109 if (Ext.size() > 1 && In.size()) {
111 "multi-character extensions must be separated by underscores";
112 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name) << MArch <<
Error << In;
118 if (!Args.hasArg(options::OPT_menable_experimental_extensions)) {
120 "requires '-menable-experimental-extensions' for experimental extension";
121 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
122 << MArch <<
Error << Ext;
124 }
else if (Major.empty() && Minor.empty()) {
126 "experimental extension requires explicit version number";
127 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
128 << MArch <<
Error << Ext;
131 auto SupportedVers = *ExperimentalExtension;
132 if (Major != SupportedVers.Major || Minor != SupportedVers.Minor) {
134 "unsupported version number " + Major;
136 Error +=
"." + Minor;
137 Error +=
" for experimental extension (this compiler supports " 138 + SupportedVers.Major.str() +
"." 139 + SupportedVers.Minor.str() +
")";
141 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
142 << MArch <<
Error << Ext;
149 if (Major.empty() && Minor.empty())
153 std::string
Error =
"unsupported version number " + Major;
155 Error +=
"." + Minor;
156 Error +=
" for extension";
157 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name) << MArch <<
Error << Ext;
173 std::vector<StringRef> &Features,
174 StringRef &MArch, StringRef &Exts) {
181 Exts.split(
Split, StringRef(
"_"));
184 auto I = Prefix.begin();
185 auto E = Prefix.end();
189 for (StringRef Ext :
Split) {
191 D.
Diag(diag::err_drv_invalid_riscv_arch_name) << MArch
192 <<
"extension name missing after separator '_'";
198 auto Pos = Ext.find_if(
isDigit);
199 StringRef Name(Ext.substr(0, Pos));
200 StringRef Vers(Ext.substr(Pos));
203 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
204 << MArch <<
"invalid extension prefix" << Ext;
209 while (I != E && *I !=
Type)
213 std::string
Error = std::string(Desc);
214 Error +=
" not given in canonical order";
215 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
216 << MArch <<
Error << Ext;
223 if (Name.size() ==
Type.size()) {
224 std::string
Error = std::string(Desc);
225 Error +=
" name missing after";
226 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
231 std::string Major, Minor;
236 if (llvm::is_contained(AllExts, Name)) {
237 std::string
Error =
"duplicated ";
239 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
240 << MArch <<
Error << Name;
246 AllExts.push_back(Name);
252 for (
auto Ext : AllExts) {
255 std::string
Error =
"unsupported ";
257 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
258 << MArch <<
Error << Ext;
262 Features.push_back(Args.MakeArgString(
"+experimental-" + Ext));
264 Features.push_back(Args.MakeArgString(
"+" + Ext));
270 std::vector<StringRef> &Features,
271 const ArgList &Args) {
273 if (llvm::any_of(MArch, [](
char c) {
return isupper(
c); })) {
274 D.
Diag(diag::err_drv_invalid_riscv_arch_name)
275 << MArch <<
"string must be lowercase";
280 if (!(MArch.startswith(
"rv32") || MArch.startswith(
"rv64")) ||
281 (MArch.size() < 5)) {
282 D.
Diag(diag::err_drv_invalid_riscv_arch_name)
283 << MArch <<
"string must begin with rv32{i,e,g} or rv64{i,g}";
287 bool HasRV64 = MArch.startswith(
"rv64");
291 StringRef StdExts =
"mafdqlcbjtpvn";
292 bool HasF =
false, HasD =
false;
293 char Baseline = MArch[4];
298 D.
Diag(diag::err_drv_invalid_riscv_arch_name)
299 << MArch <<
"first letter should be 'e', 'i' or 'g'";
306 Error =
"standard user-level extension 'e' requires 'rv32'";
308 Error =
"unsupported standard user-level extension 'e'";
309 D.
Diag(diag::err_drv_invalid_riscv_arch_name) << MArch <<
Error;
316 StdExts = StdExts.drop_front(4);
317 Features.push_back(
"+m");
318 Features.push_back(
"+a");
319 Features.push_back(
"+f");
320 Features.push_back(
"+d");
327 StringRef Exts = MArch.substr(5);
334 size_t Pos = Exts.find_first_of(
"zsx");
335 if (Pos != StringRef::npos) {
336 OtherExts = Exts.substr(Pos);
337 Exts = Exts.substr(0, Pos);
340 std::string Major, Minor;
347 Exts = Exts.drop_front(Major.size());
349 Exts = Exts.drop_front(Minor.size() + 1 );
350 Exts.consume_front(
"_");
354 auto StdExtsItr = StdExts.begin();
355 auto StdExtsEnd = StdExts.end();
357 for (
auto I = Exts.begin(), E = Exts.end(); I != E; ) {
361 while (StdExtsItr != StdExtsEnd && *StdExtsItr !=
c)
364 if (StdExtsItr == StdExtsEnd) {
368 if (StdExts.contains(
c))
369 Error =
"standard user-level extension not given in canonical order";
371 Error =
"invalid standard user-level extension";
372 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
373 << MArch <<
Error << std::string(1,
c);
380 std::string Next, Major, Minor;
381 if (std::next(I) != E)
382 Next = std::string(std::next(I), E);
392 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
393 << MArch <<
"unsupported standard user-level extension" 394 << std::string(1,
c);
397 Features.push_back(
"+m");
400 Features.push_back(
"+a");
403 Features.push_back(
"+f");
407 Features.push_back(
"+d");
411 Features.push_back(
"+c");
414 Features.push_back(
"+experimental-b");
417 Features.push_back(
"+experimental-v");
426 I += Minor.size() + 1 ;
436 D.
Diag(diag::err_drv_invalid_riscv_arch_name)
437 << MArch <<
"d requires f extension to also be specified";
453 const llvm::opt::ArgList &Args,
454 const llvm::opt::Arg *A, StringRef Mcpu,
455 std::vector<StringRef> &Features) {
456 bool Is64Bit = (Triple.getArch() == llvm::Triple::riscv64);
457 llvm::RISCV::CPUKind CPUKind = llvm::RISCV::parseCPUKind(Mcpu);
458 if (!llvm::RISCV::checkCPUKind(CPUKind, Is64Bit) ||
459 !llvm::RISCV::getCPUFeaturesExceptStdExt(CPUKind, Features)) {
460 D.
Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
466 std::vector<StringRef> &Features) {
474 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
478 if (Args.hasArg(options::OPT_ffixed_x1))
479 Features.push_back(
"+reserve-x1");
480 if (Args.hasArg(options::OPT_ffixed_x2))
481 Features.push_back(
"+reserve-x2");
482 if (Args.hasArg(options::OPT_ffixed_x3))
483 Features.push_back(
"+reserve-x3");
484 if (Args.hasArg(options::OPT_ffixed_x4))
485 Features.push_back(
"+reserve-x4");
486 if (Args.hasArg(options::OPT_ffixed_x5))
487 Features.push_back(
"+reserve-x5");
488 if (Args.hasArg(options::OPT_ffixed_x6))
489 Features.push_back(
"+reserve-x6");
490 if (Args.hasArg(options::OPT_ffixed_x7))
491 Features.push_back(
"+reserve-x7");
492 if (Args.hasArg(options::OPT_ffixed_x8))
493 Features.push_back(
"+reserve-x8");
494 if (Args.hasArg(options::OPT_ffixed_x9))
495 Features.push_back(
"+reserve-x9");
496 if (Args.hasArg(options::OPT_ffixed_x10))
497 Features.push_back(
"+reserve-x10");
498 if (Args.hasArg(options::OPT_ffixed_x11))
499 Features.push_back(
"+reserve-x11");
500 if (Args.hasArg(options::OPT_ffixed_x12))
501 Features.push_back(
"+reserve-x12");
502 if (Args.hasArg(options::OPT_ffixed_x13))
503 Features.push_back(
"+reserve-x13");
504 if (Args.hasArg(options::OPT_ffixed_x14))
505 Features.push_back(
"+reserve-x14");
506 if (Args.hasArg(options::OPT_ffixed_x15))
507 Features.push_back(
"+reserve-x15");
508 if (Args.hasArg(options::OPT_ffixed_x16))
509 Features.push_back(
"+reserve-x16");
510 if (Args.hasArg(options::OPT_ffixed_x17))
511 Features.push_back(
"+reserve-x17");
512 if (Args.hasArg(options::OPT_ffixed_x18))
513 Features.push_back(
"+reserve-x18");
514 if (Args.hasArg(options::OPT_ffixed_x19))
515 Features.push_back(
"+reserve-x19");
516 if (Args.hasArg(options::OPT_ffixed_x20))
517 Features.push_back(
"+reserve-x20");
518 if (Args.hasArg(options::OPT_ffixed_x21))
519 Features.push_back(
"+reserve-x21");
520 if (Args.hasArg(options::OPT_ffixed_x22))
521 Features.push_back(
"+reserve-x22");
522 if (Args.hasArg(options::OPT_ffixed_x23))
523 Features.push_back(
"+reserve-x23");
524 if (Args.hasArg(options::OPT_ffixed_x24))
525 Features.push_back(
"+reserve-x24");
526 if (Args.hasArg(options::OPT_ffixed_x25))
527 Features.push_back(
"+reserve-x25");
528 if (Args.hasArg(options::OPT_ffixed_x26))
529 Features.push_back(
"+reserve-x26");
530 if (Args.hasArg(options::OPT_ffixed_x27))
531 Features.push_back(
"+reserve-x27");
532 if (Args.hasArg(options::OPT_ffixed_x28))
533 Features.push_back(
"+reserve-x28");
534 if (Args.hasArg(options::OPT_ffixed_x29))
535 Features.push_back(
"+reserve-x29");
536 if (Args.hasArg(options::OPT_ffixed_x30))
537 Features.push_back(
"+reserve-x30");
538 if (Args.hasArg(options::OPT_ffixed_x31))
539 Features.push_back(
"+reserve-x31");
542 if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax,
true))
543 Features.push_back(
"+relax");
545 Features.push_back(
"-relax");
549 if (Args.hasFlag(options::OPT_msave_restore, options::OPT_mno_save_restore,
false))
550 Features.push_back(
"+save-restore");
552 Features.push_back(
"-save-restore");
560 assert((Triple.getArch() == llvm::Triple::riscv32 ||
561 Triple.getArch() == llvm::Triple::riscv64) &&
562 "Unexpected triple");
585 if (
const Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
586 return A->getValue();
597 if (MArch.startswith_lower(
"rv32")) {
599 if (MArch.substr(4).contains_lower(
"d") || MArch.startswith_lower(
"rv32g"))
601 else if (MArch.startswith_lower(
"rv32e"))
605 }
else if (MArch.startswith_lower(
"rv64")) {
607 if (MArch.substr(4).contains_lower(
"d") || MArch.startswith_lower(
"rv64g"))
618 if (Triple.getArch() == llvm::Triple::riscv32) {
619 if (Triple.getOS() == llvm::Triple::UnknownOS)
624 if (Triple.getOS() == llvm::Triple::UnknownOS)
632 const llvm::Triple &Triple) {
633 assert((Triple.getArch() == llvm::Triple::riscv32 ||
634 Triple.getArch() == llvm::Triple::riscv64) &&
635 "Unexpected triple");
664 if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ))
665 return A->getValue();
668 if (
const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
669 StringRef MArch = llvm::RISCV::getMArchFromMcpu(A->getValue());
680 if (
const Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
681 StringRef MABI = A->getValue();
683 if (MABI.equals_lower(
"ilp32e"))
685 else if (MABI.startswith_lower(
"ilp32"))
687 else if (MABI.startswith_lower(
"lp64"))
696 if (Triple.getArch() == llvm::Triple::riscv32) {
697 if (Triple.getOS() == llvm::Triple::UnknownOS)
702 if (Triple.getOS() == llvm::Triple::UnknownOS)
The base class of the type hierarchy.
DiagnosticBuilder Diag(unsigned DiagID) const
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Dataflow Directional Tag Classes.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
__device__ __2f16 float c