15#include "llvm/TargetParser/Host.h"
16#include "llvm/TargetParser/LoongArchTargetParser.h"
24 const llvm::Triple &Triple) {
25 assert((Triple.getArch() == llvm::Triple::loongarch32 ||
26 Triple.getArch() == llvm::Triple::loongarch64) &&
28 bool IsLA32 = Triple.getArch() == llvm::Triple::loongarch32;
31 const Arg *MABIArg = Args.getLastArg(options::OPT_mabi_EQ);
34 MABIValue = MABIArg->getValue();
38 const Arg *MFPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
41 StringRef
V = MFPUArg->getValue();
46 else if (
V ==
"0" ||
V ==
"none")
49 D.
Diag(diag::err_drv_loongarch_invalid_mfpu_EQ) <<
V;
53 if (
const Arg *A = Args.getLastArg(options::OPT_mdouble_float,
54 options::OPT_msingle_float,
55 options::OPT_msoft_float)) {
58 if (A->getOption().matches(options::OPT_mdouble_float)) {
59 ImpliedABI = IsLA32 ?
"ilp32d" :
"lp64d";
62 if (A->getOption().matches(options::OPT_msingle_float)) {
63 ImpliedABI = IsLA32 ?
"ilp32f" :
"lp64f";
66 if (A->getOption().matches(options::OPT_msoft_float)) {
67 ImpliedABI = IsLA32 ?
"ilp32s" :
"lp64s";
76 if (!MABIValue.empty() && ImpliedABI != MABIValue)
77 D.
Diag(diag::warn_drv_loongarch_conflicting_implied_val)
78 << MABIArg->getAsString(Args) << A->getAsString(Args) << ImpliedABI;
80 if (FPU != -1 && ImpliedFPU != FPU)
81 D.
Diag(diag::warn_drv_loongarch_conflicting_implied_val)
82 << MFPUArg->getAsString(Args) << A->getAsString(Args) << ImpliedFPU;
88 if (!MABIValue.empty())
94 return IsLA32 ?
"ilp32d" :
"lp64d";
96 return IsLA32 ?
"ilp32f" :
"lp64f";
98 return IsLA32 ?
"ilp32s" :
"lp64s";
104 switch (Triple.getEnvironment()) {
105 case llvm::Triple::GNUSF:
106 case llvm::Triple::MuslSF:
107 return IsLA32 ?
"ilp32s" :
"lp64s";
108 case llvm::Triple::GNUF32:
109 case llvm::Triple::MuslF32:
110 return IsLA32 ?
"ilp32f" :
"lp64f";
111 case llvm::Triple::GNUF64:
122 case llvm::Triple::GNU:
124 return IsLA32 ?
"ilp32d" :
"lp64d";
129 const llvm::Triple &Triple,
131 std::vector<StringRef> &Features) {
133 if (Triple.isLoongArch64() &&
134 (!Args.hasArgNoClaim(clang::driver::options::OPT_march_EQ)))
135 Features.push_back(
"+lsx");
139 if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax,
140 Triple.isLoongArch64() ?
true :
false)) {
141 Features.push_back(
"+relax");
146 D.
Diag(clang::diag::err_drv_loongarch_unsupported_with_linker_relaxation)
147 << A->getAsString(Args);
148 }
else if (Args.getLastArg(options::OPT_mno_relax)) {
149 Features.push_back(
"-relax");
152 std::string ArchName;
153 const Arg *MArch = Args.getLastArg(options::OPT_march_EQ);
155 ArchName = MArch->getValue();
157 llvm::LoongArch::getArchFeatures(ArchName, Features);
158 if (MArch && StringRef(MArch->getValue()) ==
"native")
159 for (
auto &F : llvm::sys::getHostCPUFeatures())
161 Args.MakeArgString((F.second ?
"+" :
"-") + F.first()));
166 if (
const Arg *A = Args.getLastArg(options::OPT_mdouble_float,
167 options::OPT_msingle_float,
168 options::OPT_msoft_float)) {
169 if (A->getOption().matches(options::OPT_mdouble_float)) {
170 Features.push_back(
"+f");
171 Features.push_back(
"+d");
172 }
else if (A->getOption().matches(options::OPT_msingle_float)) {
173 Features.push_back(
"+f");
174 Features.push_back(
"-d");
175 Features.push_back(
"-lsx");
177 Features.push_back(
"-f");
178 Features.push_back(
"-d");
179 Features.push_back(
"-lsx");
181 }
else if (
const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) {
182 StringRef FPU = A->getValue();
184 Features.push_back(
"+f");
185 Features.push_back(
"+d");
186 }
else if (FPU ==
"32") {
187 Features.push_back(
"+f");
188 Features.push_back(
"-d");
189 Features.push_back(
"-lsx");
190 }
else if (FPU ==
"0" || FPU ==
"none") {
191 Features.push_back(
"-f");
192 Features.push_back(
"-d");
193 Features.push_back(
"-lsx");
195 D.
Diag(diag::err_drv_loongarch_invalid_mfpu_EQ) << FPU;
200 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mabi_EQ))
201 A->ignoreTargetSpecific();
202 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mfpu_EQ))
203 A->ignoreTargetSpecific();
204 if (Arg *A = Args.getLastArgNoClaim(options::OPT_msimd_EQ))
205 A->ignoreTargetSpecific();
209 if (
const Arg *A = Args.getLastArg(options::OPT_msimd_EQ)) {
210 StringRef MSIMD = A->getValue();
211 if (MSIMD ==
"lsx") {
214 if (llvm::is_contained(Features,
"-d"))
215 D.
Diag(diag::err_drv_loongarch_wrong_fpu_width) << 0;
217 Features.push_back(
"+lsx");
218 }
else if (MSIMD ==
"lasx") {
221 if (llvm::is_contained(Features,
"-d"))
222 D.
Diag(diag::err_drv_loongarch_wrong_fpu_width) << 1;
223 else if (llvm::is_contained(Features,
"-lsx"))
224 D.
Diag(diag::err_drv_loongarch_invalid_simd_option_combination);
227 if (!Args.getLastArg(options::OPT_mno_lasx)) {
228 Features.push_back(
"+lsx");
229 Features.push_back(
"+lasx");
231 }
else if (MSIMD ==
"none") {
232 if (llvm::is_contained(Features,
"+lsx"))
233 Features.push_back(
"-lsx");
234 if (llvm::is_contained(Features,
"+lasx"))
235 Features.push_back(
"-lasx");
237 D.
Diag(diag::err_drv_loongarch_invalid_msimd_EQ) << MSIMD;
242 if (
const Arg *A = Args.getLastArg(options::OPT_mlsx, options::OPT_mno_lsx)) {
245 if (A->getOption().matches(options::OPT_mlsx)) {
246 if (llvm::find(Features,
"-d") != Features.end())
247 D.
Diag(diag::err_drv_loongarch_wrong_fpu_width) << 0;
249 Features.push_back(
"+lsx");
251 Features.push_back(
"-lsx");
252 Features.push_back(
"-lasx");
258 Args.getLastArg(options::OPT_mlasx, options::OPT_mno_lasx)) {
261 if (A->getOption().matches(options::OPT_mlasx)) {
262 if (llvm::find(Features,
"-d") != Features.end())
263 D.
Diag(diag::err_drv_loongarch_wrong_fpu_width) << 1;
265 Features.push_back(
"+lsx");
266 Features.push_back(
"+lasx");
269 Features.push_back(
"-lasx");
273 options::OPT_mstrict_align,
"ual");
275 options::OPT_mstrict_align,
"ual");
277 options::OPT_mno_frecipe,
"frecipe");
279 options::OPT_mno_lam_bh,
"lam-bh");
281 options::OPT_mno_lamcas,
"lamcas");
283 options::OPT_mno_ld_seq_sa,
"ld-seq-sa");
285 options::OPT_mno_div32,
"div32");
291 const llvm::Triple &Triple) {
292 std::string CPUString = CPU;
293 if (CPUString ==
"native") {
294 CPUString = llvm::sys::getHostCPUName();
295 if (CPUString ==
"generic")
296 CPUString = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64());
298 if (CPUString.empty())
299 CPUString = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64());
304 const llvm::Triple &Triple) {
308 if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
309 Arch = A->getValue();
310 if (
Arch ==
"la64v1.0" ||
Arch ==
"la64v1.1")
311 CPU = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64());
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
DiagnosticBuilder Diag(unsigned DiagID) const
The JSON file list parser is used to communicate input to InstallAPI.