14 #include "llvm/Option/ArgList.h" 15 #include "llvm/Support/TargetParser.h" 16 #include "llvm/Support/raw_ostream.h" 21 using namespace clang;
25 if (Ext.startswith(
"sx"))
26 return "non-standard supervisor-level extension";
27 if (Ext.startswith(
"s"))
28 return "standard supervisor-level extension";
29 if (Ext.startswith(
"x"))
30 return "non-standard user-level extension";
35 if (Ext.startswith(
"sx"))
37 if (Ext.startswith(
"s"))
39 if (Ext.startswith(
"x"))
55 StringRef Ext, StringRef In,
56 std::string &Major, std::string &Minor) {
58 In = In.substr(Major.size());
62 if (In.consume_front(
"p")) {
64 In = In.substr(Major.size());
69 "minor version number missing after 'p' for extension";
70 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
71 << MArch << Error << Ext;
77 std::string Error =
"unsupported version number " + Major;
80 Error +=
" for extension";
81 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name) << MArch << Error << Ext;
97 std::vector<StringRef> &Features,
98 StringRef &MArch, StringRef &Exts) {
105 Exts.split(Split, StringRef(
"_"));
108 auto I = Prefix.begin();
109 auto E = Prefix.end();
113 for (StringRef Ext : Split) {
115 D.
Diag(diag::err_drv_invalid_riscv_arch_name) << MArch
116 <<
"extension name missing after separator '_'";
121 StringRef Name(Ext.substr(Type.size()));
125 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
126 << MArch <<
"invalid extension prefix" << Ext;
131 while (I != E && *I != Type)
135 std::string Error = Desc;
136 Error +=
" not given in canonical order";
137 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
138 << MArch << Error << Ext;
146 std::string Error = Desc;
147 Error +=
" name missing after";
148 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
149 << MArch << Error << Ext;
153 std::string Major, Minor;
154 auto Pos = Name.find_if(
isDigit);
155 if (Pos != StringRef::npos) {
156 auto Next = Name.substr(Pos);
157 Name = Name.substr(0, Pos);
163 if (llvm::is_contained(AllExts, Ext)) {
164 std::string Error =
"duplicated ";
166 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
167 << MArch << Error << Ext;
173 AllExts.push_back(Ext);
179 for (
auto Ext : AllExts) {
182 std::string Error =
"unsupported ";
184 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
185 << MArch << Error << Ext;
188 Features.push_back(Args.MakeArgString(
"+" + Ext));
193 std::vector<StringRef> &Features) {
194 if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
195 StringRef MArch = A->getValue();
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) << MArch
208 <<
"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) << MArch
224 <<
"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)
242 StdExts = StdExts.drop_front(4);
243 Features.push_back(
"+m");
244 Features.push_back(
"+a");
245 Features.push_back(
"+f");
246 Features.push_back(
"+d");
253 StringRef Exts = MArch.substr(5);
259 size_t Pos = Exts.find_first_of(
"sx");
260 if (Pos != StringRef::npos) {
261 OtherExts = Exts.substr(Pos);
262 Exts = Exts.substr(0, Pos);
265 std::string Major, Minor;
273 auto StdExtsItr = StdExts.begin();
274 auto StdExtsEnd = StdExts.end();
276 for (
auto I = Exts.begin(), E = Exts.end(); I != E; ++I) {
280 while (StdExtsItr != StdExtsEnd && *StdExtsItr != c)
283 if (StdExtsItr == StdExtsEnd) {
287 if (StdExts.contains(c))
288 Error =
"standard user-level extension not given in canonical order";
290 Error =
"invalid standard user-level extension";
291 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
292 << MArch << Error << std::string(1, c);
299 if (std::next(I) != E) {
301 std::string Next = std::string(std::next(I), E);
302 std::string Major, Minor;
315 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
316 << MArch <<
"unsupported standard user-level extension" 317 << std::string(1, c);
320 Features.push_back(
"+m");
323 Features.push_back(
"+a");
326 Features.push_back(
"+f");
330 Features.push_back(
"+d");
334 Features.push_back(
"+c");
344 D.
Diag(diag::err_drv_invalid_riscv_arch_name) << MArch
345 <<
"d requires f extension to also be specified";
356 if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax,
true))
357 Features.push_back(
"+relax");
359 Features.push_back(
"-relax");
363 if (Args.hasFlag(options::OPT_msave_restore, options::OPT_mno_save_restore,
false)) {
365 D.
Diag(diag::warn_drv_clang_unsupported)
366 << Args.getLastArg(options::OPT_msave_restore)->getAsString(Args);
375 if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
376 return A->getValue();
378 return Triple.getArch() == llvm::Triple::riscv32 ?
"ilp32" :
"lp64";
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].