15#include "llvm/Option/ArgList.h"
16#include "llvm/Support/Error.h"
17#include "llvm/TargetParser/Host.h"
18#include "llvm/TargetParser/RISCVISAInfo.h"
19#include "llvm/TargetParser/RISCVTargetParser.h"
28 std::vector<StringRef> &Features,
29 const ArgList &Args) {
30 bool EnableExperimentalExtensions =
31 Args.hasArg(options::OPT_menable_experimental_extensions);
33 llvm::RISCVISAInfo::parseArchString(
Arch, EnableExperimentalExtensions);
35 handleAllErrors(ISAInfo.takeError(), [&](llvm::StringError &ErrMsg) {
36 D.Diag(diag::err_drv_invalid_riscv_arch_name)
37 << Arch << ErrMsg.getMessage();
43 for (
const std::string &Str : (*ISAInfo)->toFeatures(
true,
45 Features.push_back(Args.MakeArgString(Str));
47 if (EnableExperimentalExtensions)
48 Features.push_back(Args.MakeArgString(
"+experimental"));
54 const llvm::Triple &Triple, StringRef Mcpu) {
55 bool Is64Bit = Triple.isRISCV64();
56 if (!llvm::RISCV::parseCPU(Mcpu, Is64Bit)) {
58 if (llvm::RISCV::parseCPU(Mcpu, !Is64Bit))
59 D.
Diag(clang::diag::err_drv_invalid_riscv_cpu_name_for_target)
62 D.
Diag(clang::diag::err_drv_unsupported_option_argument)
63 << A->getSpelling() << Mcpu;
71 std::vector<StringRef> &Features) {
77 bool CPUFastScalarUnaligned =
false;
78 bool CPUFastVectorUnaligned =
false;
81 Arg *CPUArg =
nullptr;
83 if ((CPUArg = Args.getLastArg(options::OPT_mcpu_EQ))) {
84 CPU = CPUArg->getValue();
85 }
else if ((CPUArg = Args.getLastArg(options::OPT_march_EQ))) {
86 StringRef MArchValue = CPUArg->getValue();
87 if (MArchValue ==
"native")
93 CPU = llvm::sys::getHostCPUName();
98 if (llvm::RISCV::hasFastScalarUnalignedAccess(CPU))
99 CPUFastScalarUnaligned =
true;
100 if (llvm::RISCV::hasFastVectorUnalignedAccess(CPU))
101 CPUFastVectorUnaligned =
true;
105#define RESERVE_REG(REG) \
106 if (Args.hasArg(options::OPT_ffixed_##REG)) \
107 Features.push_back("+reserve-" #REG);
142 if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax,
true))
143 Features.push_back(
"+relax");
145 Features.push_back(
"-relax");
151 if (
const Arg *A = Args.getLastArg(
152 options::OPT_mno_strict_align, options::OPT_mscalar_strict_align,
153 options::OPT_mstrict_align, options::OPT_mno_scalar_strict_align)) {
154 if (A->getOption().matches(options::OPT_mno_strict_align) ||
155 A->getOption().matches(options::OPT_mno_scalar_strict_align)) {
156 Features.push_back(
"+unaligned-scalar-mem");
158 Features.push_back(
"-unaligned-scalar-mem");
160 }
else if (CPUFastScalarUnaligned || Triple.isAndroid()) {
161 Features.push_back(
"+unaligned-scalar-mem");
168 if (
const Arg *A = Args.getLastArg(
169 options::OPT_mno_strict_align, options::OPT_mvector_strict_align,
170 options::OPT_mstrict_align, options::OPT_mno_vector_strict_align)) {
171 if (A->getOption().matches(options::OPT_mno_strict_align) ||
172 A->getOption().matches(options::OPT_mno_vector_strict_align)) {
173 Features.push_back(
"+unaligned-vector-mem");
175 Features.push_back(
"-unaligned-vector-mem");
177 }
else if (CPUFastVectorUnaligned || Triple.isAndroid()) {
178 Features.push_back(
"+unaligned-vector-mem");
181 if (Triple.isRISCV32()) {
188 if (
const Arg *A = Args.getLastArg(
189 options::OPT_mstrict_align, options::OPT_mscalar_strict_align,
190 options::OPT_mzilsd_word_align, options::OPT_mno_strict_align,
191 options::OPT_mno_scalar_strict_align,
192 options::OPT_mzilsd_strict_align)) {
193 if (A->getOption().matches(options::OPT_mno_strict_align) ||
194 A->getOption().matches(options::OPT_mno_scalar_strict_align) ||
195 A->getOption().matches(options::OPT_mzilsd_word_align)) {
196 Features.push_back(
"+zilsd-word-align");
198 Features.push_back(
"-zilsd-word-align");
203 if (
const Arg *A = Args.getLastArg(options::OPT_mzilsd_word_align,
204 options::OPT_mzilsd_strict_align)) {
205 D.
Diag(clang::diag::err_drv_unsupported_opt_for_target)
206 << A->getSpelling() << Triple.getTriple();
213 for (
const std::string &TF : TuneFeatures)
214 Features.push_back(Args.MakeArgString(TF));
219 options::OPT_m_riscv_Features_Group);
223 assert(Triple.isRISCV() &&
"Unexpected triple");
246 if (
const Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
247 return A->getValue();
259 auto ParseResult = llvm::RISCVISAInfo::parseArchString(
262 if (!llvm::errorToBool(ParseResult.takeError()))
263 return (*ParseResult)->computeDefaultABI();
270 if (Triple.isRISCV32()) {
271 if (Triple.getOS() == llvm::Triple::UnknownOS)
276 if (Triple.getOS() == llvm::Triple::UnknownOS)
284 if (CPU ==
"native") {
285 CPU = llvm::sys::getHostCPUName();
287 if (CPU.starts_with(
"generic")) {
288 auto FeatureMap = llvm::sys::getHostCPUFeatures();
290 if (!FeatureMap.empty()) {
291 std::vector<std::string> Features;
292 for (
auto &F : FeatureMap)
293 Features.push_back(((F.second ?
"+" :
"-") + F.first()).str());
294 auto ParseResult = llvm::RISCVISAInfo::parseFeatures(
295 Triple.isRISCV32() ? 32 : 64, Features);
297 return (*ParseResult)->toString();
302 return llvm::RISCV::getMArchFromMcpu(CPU).str();
306 const llvm::Triple &Triple) {
307 assert(Triple.isRISCV() &&
"Unexpected triple");
339 bool HasMArch =
false;
340 if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
341 StringRef MArchValue = A->getValue();
342 if (MArchValue !=
"unset") {
344 if (MArchValue !=
"native")
345 return MArchValue.str();
357 if (
const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
371 if (
const Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
372 StringRef MABI = A->getValue();
374 if (MABI.equals_insensitive(
"ilp32e"))
376 if (MABI.equals_insensitive(
"lp64e"))
378 if (MABI.starts_with_insensitive(
"ilp32"))
380 if (MABI.starts_with_insensitive(
"lp64")) {
381 if (Triple.isAndroid())
382 return "rv64imafdcv_zba_zbb_zbs";
383 if (Triple.isOSFuchsia())
394 if (Triple.isRISCV32()) {
395 if (Triple.getOS() == llvm::Triple::UnknownOS)
400 if (Triple.getOS() == llvm::Triple::UnknownOS)
402 if (Triple.isAndroid())
403 return "rv64imafdcv_zba_zbb_zbs";
404 if (Triple.isOSFuchsia())
410 const llvm::Triple &Triple) {
413 if (
const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
415 }
else if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
417 StringRef MArchValue = A->getValue();
418 if (MArchValue ==
"native")
424 CPU = llvm::sys::getHostCPUName();
429 return Triple.isRISCV64() ?
"generic-rv64" :
"generic-rv32";
432std::optional<StringRef>
435 const Arg *MTuneArg = Args.getLastArg(options::OPT_mtune_EQ);
439 StringRef TuneCPU = MTuneArg->getValue();
442 auto Idx = TuneCPU.find(
':');
443 if (Idx != StringRef::npos) {
444 if (!Args.hasFlag(options::OPT_mexperimental_mtune_syntax,
445 options::OPT_mno_experimental_mtune_syntax,
false)) {
449 D.
Diag(diag::err_drv_invalid_riscv_mtune_string)
451 <<
"require '-mexperimental-mtune-syntax' to use with tune feature "
456 TFString = TuneCPU.substr(Idx + 1);
457 TuneCPU = TuneCPU.slice(0, Idx);
460 if (TuneFeatures && !TFString.empty()) {
461 if (
auto E = llvm::RISCV::parseTuneFeatureString(TuneCPU, TFString,
463 D.
Diag(diag::err_drv_invalid_riscv_mtune_string)
464 << 1 << TFString << llvm::toString(std::move(E));
472 if (TuneCPU ==
"native")
473 TuneCPU = llvm::sys::getHostCPUName();
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
DiagnosticBuilder Diag(unsigned DiagID) const
Top level wrappers for InstallAPI frontend operations.