15 #include "llvm/Option/ArgList.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) {
62 Major.append(1, *I++);
67 if (I != E && *I ==
'p') {
71 Minor.append(1, *I++);
76 "minor version number missing after 'p' for extension";
77 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
78 << MArch << Error << Ext;
84 std::string Error =
"unsupported version number " + Major;
87 Error +=
" for extension";
88 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name) << MArch << Error << Ext;
104 std::vector<StringRef> &Features,
105 StringRef &MArch, StringRef &Exts) {
112 Exts.split(Split, StringRef(
"_"));
115 Prefix.push_back(
"x");
116 Prefix.push_back(
"s");
117 Prefix.push_back(
"sx");
118 auto I = Prefix.begin();
119 auto E = Prefix.end();
123 for (StringRef Ext : Split) {
126 D.
Diag(diag::err_drv_invalid_riscv_arch_name) << MArch
127 <<
"extension name missing after separator '_'";
132 StringRef Name(Ext.substr(Type.size()));
136 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
137 << MArch <<
"invalid extension prefix" << Ext;
142 while (I != E && *I != Type)
146 std::string Error = Desc;
147 Error +=
" not given in canonical order";
148 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
149 << MArch << Error << Ext;
157 std::string Error = Desc;
158 Error +=
" name missing after";
159 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
160 << MArch << Error << Ext;
164 std::string Major, Minor;
165 auto Pos = Name.find_if(
isDigit);
166 if (Pos != StringRef::npos) {
167 auto Next = Name.substr(Pos);
168 Name = Name.substr(0, Pos);
174 if (std::find(AllExts.begin(), AllExts.end(), Ext) != AllExts.end()) {
175 std::string Error =
"duplicated ";
177 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
178 << MArch << Error << Ext;
184 AllExts.push_back(Ext);
190 for (
auto Ext : AllExts) {
193 std::string Error =
"unsupported ";
195 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
196 << MArch << Error << Ext;
199 Features.push_back(Args.MakeArgString(
"+" + Ext));
204 std::vector<StringRef> &Features) {
205 if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
206 StringRef MArch = A->getValue();
209 if (std::any_of(std::begin(MArch), std::end(MArch),
210 [](
char c) {
return isupper(c); })) {
212 D.
Diag(diag::err_drv_invalid_riscv_arch_name) << MArch
213 <<
"string must be lowercase";
218 if (!(MArch.startswith(
"rv32") || MArch.startswith(
"rv64")) ||
219 (MArch.size() < 5)) {
220 D.
Diag(diag::err_drv_invalid_riscv_arch_name) << MArch
221 <<
"string must begin with rv32{i,e,g} or rv64{i,g}";
225 bool HasRV64 = MArch.startswith(
"rv64") ?
true :
false;
229 StringRef StdExts =
"mafdqlcbjtpvn";
230 bool HasF =
false, HasD =
false;
231 char Baseline = MArch[4];
236 D.
Diag(diag::err_drv_invalid_riscv_arch_name) << MArch
237 <<
"first letter should be 'e', 'i' or 'g'";
244 Error =
"standard user-level extension 'e' requires 'rv32'";
246 Error =
"unsupported standard user-level extension 'e'";
247 D.
Diag(diag::err_drv_invalid_riscv_arch_name)
255 StdExts = StdExts.drop_front(4);
256 Features.push_back(
"+m");
257 Features.push_back(
"+a");
258 Features.push_back(
"+f");
259 Features.push_back(
"+d");
266 StringRef Exts = MArch.substr(5);
272 size_t Pos = Exts.find_first_of(
"sx");
273 if (Pos != StringRef::npos) {
274 OtherExts = Exts.substr(Pos);
275 Exts = Exts.substr(0, Pos);
278 std::string Major, Minor;
286 auto StdExtsItr = StdExts.begin();
287 auto StdExtsEnd = StdExts.end();
289 for (
auto I = Exts.begin(), E = Exts.end(); I != E; ++I) {
293 while (StdExtsItr != StdExtsEnd && *StdExtsItr != c)
296 if (StdExtsItr == StdExtsEnd) {
300 if (StdExts.contains(c))
301 Error =
"standard user-level extension not given in canonical order";
303 Error =
"invalid standard user-level extension";
304 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
305 << MArch << Error << std::string(1, c);
312 if (std::next(I) != E) {
314 std::string Next = std::string(std::next(I), E);
315 std::string Major, Minor;
328 D.
Diag(diag::err_drv_invalid_riscv_ext_arch_name)
329 << MArch <<
"unsupported standard user-level extension" 330 << std::string(1, c);
333 Features.push_back(
"+m");
336 Features.push_back(
"+a");
339 Features.push_back(
"+f");
343 Features.push_back(
"+d");
347 Features.push_back(
"+c");
357 D.
Diag(diag::err_drv_invalid_riscv_arch_name) << MArch
358 <<
"d requires f extension to also be specified";
374 if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
375 return A->getValue();
377 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].