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;
26 if (Ext.startswith(
"sx"))
27 return "non-standard supervisor-level extension";
28 if (Ext.startswith(
"s"))
29 return "standard supervisor-level extension";
30 if (Ext.startswith(
"x"))
31 return "non-standard user-level extension";
36 if (Ext.startswith(
"sx"))
38 if (Ext.startswith(
"s"))
40 if (Ext.startswith(
"x"))
56 StringRef Ext, StringRef In,
57 std::string &Major, std::string &Minor) {
59 In = In.substr(Major.size());
63 if (In.consume_front(
"p")) {
65 In = In.substr(Major.size());
70 "minor version number missing after 'p' for extension";
71 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
72 << MArch << Error << Ext;
78 std::string
Error =
"unsupported version number " + Major;
81 Error +=
" for extension";
82 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name) << MArch << Error << Ext;
98 std::vector<StringRef> &Features,
99 StringRef &MArch, StringRef &Exts) {
106 Exts.split(Split, StringRef(
"_"));
109 auto I = Prefix.begin();
110 auto E = Prefix.end();
114 for (StringRef Ext : Split) {
116 D.
Diag(diag::err_drv_invalid_riscv_arch_name) << MArch
117 <<
"extension name missing after separator '_'";
122 StringRef Name(Ext.substr(Type.size()));
126 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
127 << MArch <<
"invalid extension prefix" << Ext;
132 while (I != E && *I != Type)
136 std::string
Error = Desc;
137 Error +=
" not given in canonical order";
138 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
139 << MArch << Error << Ext;
147 std::string
Error = Desc;
148 Error +=
" name missing after";
149 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
150 << MArch << Error << Ext;
154 std::string Major, Minor;
155 auto Pos = Name.find_if(
isDigit);
156 if (Pos != StringRef::npos) {
157 auto Next = Name.substr(Pos);
158 Name = Name.substr(0, Pos);
164 if (llvm::is_contained(AllExts, Ext)) {
165 std::string
Error =
"duplicated ";
167 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
168 << MArch << Error << Ext;
174 AllExts.push_back(Ext);
180 for (
auto Ext : AllExts) {
183 std::string
Error =
"unsupported ";
185 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
186 << MArch << Error << Ext;
189 Features.push_back(Args.MakeArgString(
"+" + Ext));
195 std::vector<StringRef> &Features,
196 const ArgList &Args) {
198 if (llvm::any_of(MArch, [](
char c) {
return isupper(c); })) {
199 D.
Diag(diag::err_drv_invalid_riscv_arch_name)
200 << MArch <<
"string must be lowercase";
205 if (!(MArch.startswith(
"rv32") || MArch.startswith(
"rv64")) ||
206 (MArch.size() < 5)) {
207 D.
Diag(diag::err_drv_invalid_riscv_arch_name)
208 << MArch <<
"string must begin with rv32{i,e,g} or rv64{i,g}";
212 bool HasRV64 = MArch.startswith(
"rv64");
216 StringRef StdExts =
"mafdqlcbjtpvn";
217 bool HasF =
false, HasD =
false;
218 char Baseline = MArch[4];
223 D.
Diag(diag::err_drv_invalid_riscv_arch_name)
224 << MArch <<
"first letter should be 'e', 'i' or 'g'";
231 Error =
"standard user-level extension 'e' requires 'rv32'";
233 Error =
"unsupported standard user-level extension 'e'";
234 D.
Diag(diag::err_drv_invalid_riscv_arch_name) << MArch << Error;
241 StdExts = StdExts.drop_front(4);
242 Features.push_back(
"+m");
243 Features.push_back(
"+a");
244 Features.push_back(
"+f");
245 Features.push_back(
"+d");
252 StringRef Exts = MArch.substr(5);
258 size_t Pos = Exts.find_first_of(
"sx");
259 if (Pos != StringRef::npos) {
260 OtherExts = Exts.substr(Pos);
261 Exts = Exts.substr(0, Pos);
264 std::string Major, Minor;
272 auto StdExtsItr = StdExts.begin();
273 auto StdExtsEnd = StdExts.end();
275 for (
auto I = Exts.begin(), E = Exts.end(); I != E; ++I) {
279 while (StdExtsItr != StdExtsEnd && *StdExtsItr != c)
282 if (StdExtsItr == StdExtsEnd) {
286 if (StdExts.contains(c))
287 Error =
"standard user-level extension not given in canonical order";
289 Error =
"invalid standard user-level extension";
290 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
291 << MArch << Error << std::string(1, c);
298 if (std::next(I) != E) {
300 std::string Next = std::string(std::next(I), E);
301 std::string Major, Minor;
313 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
314 << MArch <<
"unsupported standard user-level extension" 315 << std::string(1, c);
318 Features.push_back(
"+m");
321 Features.push_back(
"+a");
324 Features.push_back(
"+f");
328 Features.push_back(
"+d");
332 Features.push_back(
"+c");
342 D.
Diag(diag::err_drv_invalid_riscv_arch_name)
343 << MArch <<
"d requires f extension to also be specified";
359 std::vector<StringRef> &Features) {
366 if (Args.hasArg(options::OPT_ffixed_x1))
367 Features.push_back(
"+reserve-x1");
368 if (Args.hasArg(options::OPT_ffixed_x2))
369 Features.push_back(
"+reserve-x2");
370 if (Args.hasArg(options::OPT_ffixed_x3))
371 Features.push_back(
"+reserve-x3");
372 if (Args.hasArg(options::OPT_ffixed_x4))
373 Features.push_back(
"+reserve-x4");
374 if (Args.hasArg(options::OPT_ffixed_x5))
375 Features.push_back(
"+reserve-x5");
376 if (Args.hasArg(options::OPT_ffixed_x6))
377 Features.push_back(
"+reserve-x6");
378 if (Args.hasArg(options::OPT_ffixed_x7))
379 Features.push_back(
"+reserve-x7");
380 if (Args.hasArg(options::OPT_ffixed_x8))
381 Features.push_back(
"+reserve-x8");
382 if (Args.hasArg(options::OPT_ffixed_x9))
383 Features.push_back(
"+reserve-x9");
384 if (Args.hasArg(options::OPT_ffixed_x10))
385 Features.push_back(
"+reserve-x10");
386 if (Args.hasArg(options::OPT_ffixed_x11))
387 Features.push_back(
"+reserve-x11");
388 if (Args.hasArg(options::OPT_ffixed_x12))
389 Features.push_back(
"+reserve-x12");
390 if (Args.hasArg(options::OPT_ffixed_x13))
391 Features.push_back(
"+reserve-x13");
392 if (Args.hasArg(options::OPT_ffixed_x14))
393 Features.push_back(
"+reserve-x14");
394 if (Args.hasArg(options::OPT_ffixed_x15))
395 Features.push_back(
"+reserve-x15");
396 if (Args.hasArg(options::OPT_ffixed_x16))
397 Features.push_back(
"+reserve-x16");
398 if (Args.hasArg(options::OPT_ffixed_x17))
399 Features.push_back(
"+reserve-x17");
400 if (Args.hasArg(options::OPT_ffixed_x18))
401 Features.push_back(
"+reserve-x18");
402 if (Args.hasArg(options::OPT_ffixed_x19))
403 Features.push_back(
"+reserve-x19");
404 if (Args.hasArg(options::OPT_ffixed_x20))
405 Features.push_back(
"+reserve-x20");
406 if (Args.hasArg(options::OPT_ffixed_x21))
407 Features.push_back(
"+reserve-x21");
408 if (Args.hasArg(options::OPT_ffixed_x22))
409 Features.push_back(
"+reserve-x22");
410 if (Args.hasArg(options::OPT_ffixed_x23))
411 Features.push_back(
"+reserve-x23");
412 if (Args.hasArg(options::OPT_ffixed_x24))
413 Features.push_back(
"+reserve-x24");
414 if (Args.hasArg(options::OPT_ffixed_x25))
415 Features.push_back(
"+reserve-x25");
416 if (Args.hasArg(options::OPT_ffixed_x26))
417 Features.push_back(
"+reserve-x26");
418 if (Args.hasArg(options::OPT_ffixed_x27))
419 Features.push_back(
"+reserve-x27");
420 if (Args.hasArg(options::OPT_ffixed_x28))
421 Features.push_back(
"+reserve-x28");
422 if (Args.hasArg(options::OPT_ffixed_x29))
423 Features.push_back(
"+reserve-x29");
424 if (Args.hasArg(options::OPT_ffixed_x30))
425 Features.push_back(
"+reserve-x30");
426 if (Args.hasArg(options::OPT_ffixed_x31))
427 Features.push_back(
"+reserve-x31");
430 if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax,
true))
431 Features.push_back(
"+relax");
433 Features.push_back(
"-relax");
437 if (Args.hasFlag(options::OPT_msave_restore, options::OPT_mno_save_restore,
false)) {
439 D.
Diag(diag::warn_drv_clang_unsupported)
440 << Args.getLastArg(options::OPT_msave_restore)->getAsString(Args);
449 assert((Triple.getArch() == llvm::Triple::riscv32 ||
450 Triple.getArch() == llvm::Triple::riscv64) &&
451 "Unexpected triple");
470 if (
const Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
471 return A->getValue();
480 if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
481 StringRef MArch = A->getValue();
483 if (MArch.startswith_lower(
"rv32")) {
485 if (MArch.substr(4).contains_lower(
"d") ||
486 MArch.startswith_lower(
"rv32g"))
488 else if (MArch.startswith_lower(
"rv32e"))
492 }
else if (MArch.startswith_lower(
"rv64")) {
494 if (MArch.substr(4).contains_lower(
"d") ||
495 MArch.startswith_lower(
"rv64g"))
507 if (Triple.getArch() == llvm::Triple::riscv32) {
508 if (Triple.getOS() == llvm::Triple::UnknownOS)
513 if (Triple.getOS() == llvm::Triple::UnknownOS)
521 const llvm::Triple &Triple) {
522 assert((Triple.getArch() == llvm::Triple::riscv32 ||
523 Triple.getArch() == llvm::Triple::riscv64) &&
524 "Unexpected triple");
546 if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ))
547 return A->getValue();
554 if (
const Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
555 StringRef MABI = A->getValue();
557 if (MABI.equals_lower(
"ilp32e"))
559 else if (MABI.startswith_lower(
"ilp32"))
561 else if (MABI.startswith_lower(
"lp64"))
570 if (Triple.getArch() == llvm::Triple::riscv32) {
571 if (Triple.getOS() == llvm::Triple::UnknownOS)
576 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].