16#include "llvm/TargetParser/Host.h"
17#include "llvm/TargetParser/LoongArchTargetParser.h"
25 const llvm::Triple &Triple) {
26 assert((Triple.getArch() == llvm::Triple::loongarch32 ||
27 Triple.getArch() == llvm::Triple::loongarch64) &&
29 bool IsLA32 = Triple.getArch() == llvm::Triple::loongarch32;
32 const Arg *MABIArg = Args.getLastArg(options::OPT_mabi_EQ);
35 MABIValue = MABIArg->getValue();
39 const Arg *MFPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
42 StringRef
V = MFPUArg->getValue();
47 else if (
V ==
"0" ||
V ==
"none")
50 D.Diag(diag::err_drv_loongarch_invalid_mfpu_EQ) <<
V;
54 if (
const Arg *A = Args.getLastArg(options::OPT_mdouble_float,
55 options::OPT_msingle_float,
56 options::OPT_msoft_float)) {
59 if (A->getOption().matches(options::OPT_mdouble_float)) {
60 ImpliedABI = IsLA32 ?
"ilp32d" :
"lp64d";
63 if (A->getOption().matches(options::OPT_msingle_float)) {
64 ImpliedABI = IsLA32 ?
"ilp32f" :
"lp64f";
67 if (A->getOption().matches(options::OPT_msoft_float)) {
68 ImpliedABI = IsLA32 ?
"ilp32s" :
"lp64s";
77 if (!MABIValue.empty() && ImpliedABI != MABIValue)
78 D.Diag(diag::warn_drv_loongarch_conflicting_implied_val)
79 << MABIArg->getAsString(Args) << A->getAsString(Args) << ImpliedABI;
81 if (FPU != -1 && ImpliedFPU != FPU)
82 D.Diag(diag::warn_drv_loongarch_conflicting_implied_val)
83 << MFPUArg->getAsString(Args) << A->getAsString(Args) << ImpliedFPU;
89 if (!MABIValue.empty())
95 return IsLA32 ?
"ilp32d" :
"lp64d";
97 return IsLA32 ?
"ilp32f" :
"lp64f";
99 return IsLA32 ?
"ilp32s" :
"lp64s";
105 switch (Triple.getEnvironment()) {
106 case llvm::Triple::GNUSF:
107 case llvm::Triple::MuslSF:
108 return IsLA32 ?
"ilp32s" :
"lp64s";
109 case llvm::Triple::GNUF32:
110 case llvm::Triple::MuslF32:
111 return IsLA32 ?
"ilp32f" :
"lp64f";
112 case llvm::Triple::GNUF64:
123 case llvm::Triple::GNU:
125 return IsLA32 ?
"ilp32d" :
"lp64d";
130 const llvm::Triple &Triple,
132 std::vector<StringRef> &Features) {
134 if (Triple.isLoongArch64() &&
135 (!Args.hasArgNoClaim(clang::driver::options::OPT_march_EQ)))
136 Features.push_back(
"+lsx");
141 Args.getLastArg(options::OPT_mrelax, options::OPT_mno_relax)) {
142 if (A->getOption().matches(options::OPT_mrelax)) {
143 Features.push_back(
"+relax");
149 clang::diag::err_drv_loongarch_unsupported_with_linker_relaxation)
150 << A->getAsString(Args);
152 Features.push_back(
"-relax");
156 std::string ArchName;
157 const Arg *MArch = Args.getLastArg(options::OPT_march_EQ);
159 ArchName = MArch->getValue();
161 llvm::LoongArch::getArchFeatures(ArchName, Features);
162 if (MArch && StringRef(MArch->getValue()) ==
"native")
163 for (
auto &F : llvm::sys::getHostCPUFeatures())
165 Args.MakeArgString((F.second ?
"+" :
"-") + F.first()));
170 if (
const Arg *A = Args.getLastArg(options::OPT_mdouble_float,
171 options::OPT_msingle_float,
172 options::OPT_msoft_float)) {
173 if (A->getOption().matches(options::OPT_mdouble_float)) {
174 Features.push_back(
"+f");
175 Features.push_back(
"+d");
176 }
else if (A->getOption().matches(options::OPT_msingle_float)) {
177 Features.push_back(
"+f");
178 Features.push_back(
"-d");
179 Features.push_back(
"-lsx");
181 Features.push_back(
"-f");
182 Features.push_back(
"-d");
183 Features.push_back(
"-lsx");
185 }
else if (
const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) {
186 StringRef FPU = A->getValue();
188 Features.push_back(
"+f");
189 Features.push_back(
"+d");
190 }
else if (FPU ==
"32") {
191 Features.push_back(
"+f");
192 Features.push_back(
"-d");
193 Features.push_back(
"-lsx");
194 }
else if (FPU ==
"0" || FPU ==
"none") {
195 Features.push_back(
"-f");
196 Features.push_back(
"-d");
197 Features.push_back(
"-lsx");
199 D.Diag(diag::err_drv_loongarch_invalid_mfpu_EQ) << FPU;
204 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mabi_EQ))
205 A->ignoreTargetSpecific();
206 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mfpu_EQ))
207 A->ignoreTargetSpecific();
208 if (Arg *A = Args.getLastArgNoClaim(options::OPT_msimd_EQ))
209 A->ignoreTargetSpecific();
213 if (
const Arg *A = Args.getLastArg(options::OPT_msimd_EQ)) {
214 StringRef MSIMD = A->getValue();
215 if (MSIMD ==
"lsx") {
218 if (llvm::find(Features,
"-d") != Features.end())
219 D.Diag(diag::err_drv_loongarch_wrong_fpu_width) << 0;
221 Features.push_back(
"+lsx");
222 }
else if (MSIMD ==
"lasx") {
225 if (llvm::find(Features,
"-d") != Features.end())
226 D.Diag(diag::err_drv_loongarch_wrong_fpu_width) << 1;
227 else if (llvm::find(Features,
"-lsx") != Features.end())
228 D.Diag(diag::err_drv_loongarch_invalid_simd_option_combination);
231 if (!Args.getLastArg(options::OPT_mno_lasx)) {
232 Features.push_back(
"+lsx");
233 Features.push_back(
"+lasx");
235 }
else if (MSIMD ==
"none") {
236 if (llvm::find(Features,
"+lsx") != Features.end())
237 Features.push_back(
"-lsx");
238 if (llvm::find(Features,
"+lasx") != Features.end())
239 Features.push_back(
"-lasx");
241 D.Diag(diag::err_drv_loongarch_invalid_msimd_EQ) << MSIMD;
246 if (
const Arg *A = Args.getLastArg(options::OPT_mlsx, options::OPT_mno_lsx)) {
249 if (A->getOption().matches(options::OPT_mlsx)) {
250 if (llvm::find(Features,
"-d") != Features.end())
251 D.Diag(diag::err_drv_loongarch_wrong_fpu_width) << 0;
253 Features.push_back(
"+lsx");
255 Features.push_back(
"-lsx");
261 Args.getLastArg(options::OPT_mlasx, options::OPT_mno_lasx)) {
264 if (A->getOption().matches(options::OPT_mlasx)) {
265 if (llvm::find(Features,
"-d") != Features.end())
266 D.Diag(diag::err_drv_loongarch_wrong_fpu_width) << 1;
268 Features.push_back(
"+lsx");
269 Features.push_back(
"+lasx");
272 Features.push_back(
"-lasx");
276 options::OPT_mstrict_align,
"ual");
278 options::OPT_mstrict_align,
"ual");
280 options::OPT_mno_frecipe,
"frecipe");
282 options::OPT_mno_lam_bh,
"lam-bh");
284 options::OPT_mno_lamcas,
"lamcas");
286 options::OPT_mno_ld_seq_sa,
"ld-seq-sa");
288 options::OPT_mno_div32,
"div32");
294 const llvm::Triple &Triple) {
295 std::string CPUString = CPU;
296 if (CPUString ==
"native") {
297 CPUString = llvm::sys::getHostCPUName();
298 if (CPUString ==
"generic")
299 CPUString = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64());
301 if (CPUString.empty())
302 CPUString = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64());
307 const llvm::Triple &Triple) {
311 if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
312 Arch = A->getValue();
313 if (Arch ==
"la64v1.0" || Arch ==
"la64v1.1")
314 CPU = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64());
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
The JSON file list parser is used to communicate input to InstallAPI.