13#include "llvm/Option/ArgList.h"
14#include "llvm/TargetParser/AArch64TargetParser.h"
15#include "llvm/TargetParser/Host.h"
25 return Triple.isOSDarwin();
32 const llvm::Triple &Triple, Arg *&A) {
35 if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
36 StringRef Mcpu = A->getValue();
37 CPU = Mcpu.split(
"+").first.lower();
40 CPU = llvm::AArch64::resolveCPUAlias(CPU);
44 return std::string(llvm::sys::getHostCPUName());
49 if (Triple.isTargetMachineMac() &&
50 Triple.getArch() == llvm::Triple::aarch64) {
55 if (Triple.getOS() == llvm::Triple::IOS) {
56 assert(!Triple.isSimulatorEnvironment() &&
"iossim should be mac-like");
58 if (!Triple.isOSVersionLT(26))
61 if (!Triple.isOSVersionLT(18) && !Triple.isArm64e())
65 if (Triple.isWatchOS()) {
66 assert(!Triple.isSimulatorEnvironment() &&
"watchossim should be mac-like");
68 if (Triple.getArch() == llvm::Triple::aarch64_32 || Triple.isArm64e())
69 return Triple.isOSVersionLT(26) ?
"apple-s4" :
"apple-s6";
74 if (Triple.isXROS()) {
76 assert(!Triple.isSimulatorEnvironment() &&
"xrossim should be mac-like");
80 if (Triple.isArm64e())
84 if (Triple.isOSDarwin())
85 return Triple.getArch() == llvm::Triple::aarch64_32 ?
"apple-s4"
93 llvm::AArch64::ExtensionSet &Extensions) {
95 text.split(
Split, StringRef(
"+"), -1,
false);
99 D.
Diag(clang::diag::err_drv_no_neon_modifier);
102 if (!Extensions.parseModifier(
Feature))
112 llvm::AArch64::ExtensionSet &Extensions) {
113 std::pair<StringRef, StringRef>
Split = Mcpu.split(
"+");
117 CPU = llvm::sys::getHostCPUName();
119 const std::optional<llvm::AArch64::CpuInfo> CpuInfo =
120 llvm::AArch64::parseCpu(CPU);
124 Extensions.addCPUDefaults(*CpuInfo);
126 if (
Split.second.size() &&
136 llvm::AArch64::ExtensionSet &Extensions) {
137 std::string MarchLowerCase = March.lower();
138 std::pair<StringRef, StringRef>
Split = StringRef(MarchLowerCase).split(
"+");
140 const llvm::AArch64::ArchInfo *ArchInfo =
141 llvm::AArch64::parseArch(
Split.first);
142 if (
Split.first ==
"native")
143 ArchInfo = llvm::AArch64::getArchForCpu(llvm::sys::getHostCPUName().str());
147 Extensions.addArchDefaults(*ArchInfo);
149 if ((
Split.second.size() &&
157 const Driver &D, StringRef Mcpu,
const ArgList &Args,
158 llvm::AArch64::ExtensionSet &Extensions, std::vector<StringRef> &Features) {
160 std::string McpuLowerCase = Mcpu.lower();
164 if (Mcpu ==
"native") {
165 llvm::StringMap<bool> HostFeatures = llvm::sys::getHostCPUFeatures();
166 for (
auto &[
Feature, Enabled] : HostFeatures) {
167 Features.push_back(Args.MakeArgString((Enabled ?
"+" :
"-") +
Feature));
177 std::vector<StringRef> &Features) {
179 std::string MtuneLowerCase = Mtune.lower();
180 llvm::AArch64::ExtensionSet Extensions;
188 std::vector<StringRef> &Features) {
193 const llvm::Triple &Triple,
195 std::vector<StringRef> &Features,
196 bool ForAS,
bool ForMultilib) {
199 llvm::StringRef WaMArch;
200 llvm::AArch64::ExtensionSet Extensions;
203 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler))
204 for (StringRef
Value : A->getValues())
205 if (
Value.starts_with(
"-march="))
206 WaMArch =
Value.substr(7);
210 if (!WaMArch.empty())
212 else if ((A = Args.getLastArg(options::OPT_march_EQ)))
215 else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
225 if (success && (A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)))
228 else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
236 auto Diag = D.
Diag(diag::err_drv_unsupported_option_argument);
239 if (!WaMArch.empty())
240 Diag <<
"-march=" << WaMArch;
242 Diag << A->getSpelling() << A->getValue();
246 if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
247 Extensions.disable(llvm::AArch64::AEK_FP);
251 if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
252 if (A->getOption().matches(options::OPT_mcrc))
253 Extensions.enable(llvm::AArch64::AEK_CRC);
255 Extensions.disable(llvm::AArch64::AEK_CRC);
260 Extensions.toLLVMFeatureList(Features);
262 if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
263 StringRef Mtp = A->getValue();
264 if (Mtp ==
"el3" || Mtp ==
"tpidr_el3")
265 Features.push_back(
"+tpidr-el3");
266 else if (Mtp ==
"el2" || Mtp ==
"tpidr_el2")
267 Features.push_back(
"+tpidr-el2");
268 else if (Mtp ==
"el1" || Mtp ==
"tpidr_el1")
269 Features.push_back(
"+tpidr-el1");
270 else if (Mtp ==
"tpidrro_el0")
271 Features.push_back(
"+tpidrro-el0");
272 else if (Mtp !=
"el0" && Mtp !=
"tpidr_el0")
273 D.
Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
277 if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) {
278 StringRef
Scope = A->getValue();
279 bool EnableRetBr =
false;
280 bool EnableBlr =
false;
281 bool DisableComdat =
false;
282 if (
Scope !=
"none") {
284 Scope.split(Opts,
",");
285 for (
auto Opt : Opts) {
292 if (Opt ==
"retbr") {
300 if (Opt ==
"comdat") {
301 DisableComdat =
false;
304 if (Opt ==
"nocomdat") {
305 DisableComdat =
true;
308 D.
Diag(diag::err_drv_unsupported_option_argument)
309 << A->getSpelling() <<
Scope;
315 Features.push_back(
"+harden-sls-retbr");
317 Features.push_back(
"+harden-sls-blr");
319 Features.push_back(
"+harden-sls-nocomdat");
323 if (Arg *A = Args.getLastArg(
324 options::OPT_mstrict_align, options::OPT_mno_strict_align,
325 options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) {
326 if (A->getOption().matches(options::OPT_mstrict_align) ||
327 A->getOption().matches(options::OPT_mno_unaligned_access))
328 Features.push_back(
"+strict-align");
329 }
else if (Triple.isOSOpenBSD())
330 Features.push_back(
"+strict-align");
336 if (!ForAS && !ForMultilib) {
337 if (Arg *A = Args.getLastArg(options::OPT_mexecute_only,
338 options::OPT_mno_execute_only)) {
339 if (A->getOption().matches(options::OPT_mexecute_only)) {
340 Features.push_back(
"+execute-only");
345 if (Args.hasArg(options::OPT_ffixed_x1))
346 Features.push_back(
"+reserve-x1");
348 if (Args.hasArg(options::OPT_ffixed_x2))
349 Features.push_back(
"+reserve-x2");
351 if (Args.hasArg(options::OPT_ffixed_x3))
352 Features.push_back(
"+reserve-x3");
354 if (Args.hasArg(options::OPT_ffixed_x4))
355 Features.push_back(
"+reserve-x4");
357 if (Args.hasArg(options::OPT_ffixed_x5))
358 Features.push_back(
"+reserve-x5");
360 if (Args.hasArg(options::OPT_ffixed_x6))
361 Features.push_back(
"+reserve-x6");
363 if (Args.hasArg(options::OPT_ffixed_x7))
364 Features.push_back(
"+reserve-x7");
366 if (Args.hasArg(options::OPT_ffixed_x9))
367 Features.push_back(
"+reserve-x9");
369 if (Args.hasArg(options::OPT_ffixed_x10))
370 Features.push_back(
"+reserve-x10");
372 if (Args.hasArg(options::OPT_ffixed_x11))
373 Features.push_back(
"+reserve-x11");
375 if (Args.hasArg(options::OPT_ffixed_x12))
376 Features.push_back(
"+reserve-x12");
378 if (Args.hasArg(options::OPT_ffixed_x13))
379 Features.push_back(
"+reserve-x13");
381 if (Args.hasArg(options::OPT_ffixed_x14))
382 Features.push_back(
"+reserve-x14");
384 if (Args.hasArg(options::OPT_ffixed_x15))
385 Features.push_back(
"+reserve-x15");
387 if (Args.hasArg(options::OPT_ffixed_x18))
388 Features.push_back(
"+reserve-x18");
390 if (Args.hasArg(options::OPT_ffixed_x20))
391 Features.push_back(
"+reserve-x20");
393 if (Args.hasArg(options::OPT_ffixed_x21))
394 Features.push_back(
"+reserve-x21");
396 if (Args.hasArg(options::OPT_ffixed_x22))
397 Features.push_back(
"+reserve-x22");
399 if (Args.hasArg(options::OPT_ffixed_x23))
400 Features.push_back(
"+reserve-x23");
402 if (Args.hasArg(options::OPT_ffixed_x24))
403 Features.push_back(
"+reserve-x24");
405 if (Args.hasArg(options::OPT_ffixed_x25))
406 Features.push_back(
"+reserve-x25");
408 if (Args.hasArg(options::OPT_ffixed_x26))
409 Features.push_back(
"+reserve-x26");
411 if (Args.hasArg(options::OPT_ffixed_x27))
412 Features.push_back(
"+reserve-x27");
414 if (Args.hasArg(options::OPT_ffixed_x28))
415 Features.push_back(
"+reserve-x28");
417 if (Args.hasArg(options::OPT_mlr_for_calls_only))
418 Features.push_back(
"+reserve-lr-for-ra");
420 if (Args.hasArg(options::OPT_fcall_saved_x8))
421 Features.push_back(
"+call-saved-x8");
423 if (Args.hasArg(options::OPT_fcall_saved_x9))
424 Features.push_back(
"+call-saved-x9");
426 if (Args.hasArg(options::OPT_fcall_saved_x10))
427 Features.push_back(
"+call-saved-x10");
429 if (Args.hasArg(options::OPT_fcall_saved_x11))
430 Features.push_back(
"+call-saved-x11");
432 if (Args.hasArg(options::OPT_fcall_saved_x12))
433 Features.push_back(
"+call-saved-x12");
435 if (Args.hasArg(options::OPT_fcall_saved_x13))
436 Features.push_back(
"+call-saved-x13");
438 if (Args.hasArg(options::OPT_fcall_saved_x14))
439 Features.push_back(
"+call-saved-x14");
441 if (Args.hasArg(options::OPT_fcall_saved_x15))
442 Features.push_back(
"+call-saved-x15");
444 if (Args.hasArg(options::OPT_fcall_saved_x18))
445 Features.push_back(
"+call-saved-x18");
447 if (Args.hasArg(options::OPT_mno_neg_immediates))
448 Features.push_back(
"+no-neg-immediates");
450 if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
451 options::OPT_mno_fix_cortex_a53_835769)) {
452 if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769))
453 Features.push_back(
"+fix-cortex-a53-835769");
455 Features.push_back(
"-fix-cortex-a53-835769");
456 }
else if (Triple.isAndroid() || Triple.isOHOSFamily()) {
458 Features.push_back(
"+fix-cortex-a53-835769");
459 }
else if (Triple.isOSFuchsia()) {
461 if (
CPU.empty() || CPU ==
"generic" || CPU ==
"cortex-a53")
462 Features.push_back(
"+fix-cortex-a53-835769");
465 if (Args.getLastArg(options::OPT_mno_bti_at_return_twice))
466 Features.push_back(
"+no-bti-at-return-twice");
470 llvm::Triple &Triple) {
471 Arg *ABIArg = Args.getLastArg(options::OPT_mabi_EQ);
473 ABIArg ? (StringRef(ABIArg->getValue()) ==
"pauthtest") :
false;
475 switch (Triple.getEnvironment()) {
476 case llvm::Triple::UnknownEnvironment:
478 Triple.setEnvironment(llvm::Triple::PAuthTest);
480 case llvm::Triple::PAuthTest:
484 D.
Diag(diag::err_drv_unsupported_opt_for_target)
485 << ABIArg->getAsString(Args) << Triple.getTriple();
492 if (Triple.getArch() != llvm::Triple::aarch64 &&
493 Triple.getArch() != llvm::Triple::aarch64_be)
496 if (Triple.getVendor() != llvm::Triple::UnknownVendor)
499 if (Triple.getOS() != llvm::Triple::UnknownOS)
502 return Triple.getEnvironmentName() ==
"elf";
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Scope - A scope is a transient data structure that is used while parsing the program.
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.