Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- AArch64.cpp - AArch64 (not ARM) Helpers for Tools ------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "AArch64.h"
10
#include "../CommonArgs.h"
11
#include "clang/Driver/Driver.h"
12
#include "clang/Driver/DriverDiagnostic.h"
13
#include "clang/Driver/Options.h"
14
#include "llvm/Option/ArgList.h"
15
#include "llvm/TargetParser/AArch64TargetParser.h"
16
#include "llvm/TargetParser/Host.h"
17
18
using namespace clang::driver;
19
using namespace clang::driver::tools;
20
using namespace clang;
21
using namespace llvm::opt;
22
23
/// \returns true if the given triple can determine the default CPU type even
24
/// if -arch is not specified.
25
2.19k
static bool isCPUDeterminedByTriple(const llvm::Triple &Triple) {
26
2.19k
  return Triple.isOSDarwin();
27
2.19k
}
28
29
/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
30
/// targeting. Set \p A to the Arg corresponding to the -mcpu argument if it is
31
/// provided, or to nullptr otherwise.
32
std::string aarch64::getAArch64TargetCPU(const ArgList &Args,
33
2.30k
                                         const llvm::Triple &Triple, Arg *&A) {
34
2.30k
  std::string CPU;
35
  // If we have -mcpu, use that.
36
2.30k
  if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
37
255
    StringRef Mcpu = A->getValue();
38
255
    CPU = Mcpu.split("+").first.lower();
39
255
  }
40
41
2.30k
  CPU = llvm::AArch64::resolveCPUAlias(CPU);
42
43
  // Handle CPU name is 'native'.
44
2.30k
  if (CPU == "native")
45
1
    return std::string(llvm::sys::getHostCPUName());
46
47
2.30k
  if (CPU.size())
48
254
    return CPU;
49
50
2.05k
  if (Triple.isTargetMachineMac() &&
51
2.05k
      
Triple.getArch() == llvm::Triple::aarch64290
) {
52
    // Apple Silicon macs default to M1 CPUs.
53
287
    return "apple-m1";
54
287
  }
55
56
  // arm64e requires v8.3a and only runs on apple-a12 and later CPUs.
57
1.76k
  if (Triple.isArm64e())
58
18
    return "apple-a12";
59
60
  // Make sure we pick the appropriate Apple CPU if -arch is used or when
61
  // targetting a Darwin OS.
62
1.74k
  if (Args.getLastArg(options::OPT_arch) || 
Triple.isOSDarwin()1.62k
)
63
279
    return Triple.getArch() == llvm::Triple::aarch64_32 ? 
"apple-s4"15
64
279
                                                        : 
"apple-a7"264
;
65
66
1.47k
  return "generic";
67
1.74k
}
68
69
// Decode AArch64 features from string like +[no]featureA+[no]featureB+...
70
static bool DecodeAArch64Features(const Driver &D, StringRef text,
71
                                  std::vector<StringRef> &Features,
72
450
                                  const llvm::AArch64::ArchInfo &ArchInfo) {
73
450
  SmallVector<StringRef, 8> Split;
74
450
  text.split(Split, StringRef("+"), -1, false);
75
76
601
  for (StringRef Feature : Split) {
77
601
    StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
78
601
    if (!FeatureName.empty())
79
595
      Features.push_back(FeatureName);
80
6
    else if (Feature == "neon" || 
Feature == "noneon"3
)
81
6
      D.Diag(clang::diag::err_drv_no_neon_modifier);
82
0
    else
83
0
      return false;
84
85
    // +sme implies +bf16.
86
    // +sme-f64f64 and +sme-i16i64 both imply +sme.
87
601
    if (Feature == "sme") {
88
3
      Features.push_back("+bf16");
89
598
    } else if (Feature == "nosme") {
90
4
      Features.push_back("-sme-f64f64");
91
4
      Features.push_back("-sme-i16i64");
92
594
    } else if (Feature == "sme-f64f64") {
93
3
      Features.push_back("+sme");
94
3
      Features.push_back("+bf16");
95
591
    } else if (Feature == "sme-i16i64") {
96
4
      Features.push_back("+sme");
97
4
      Features.push_back("+bf16");
98
587
    } else if (Feature == "nobf16") {
99
4
      Features.push_back("-sme");
100
4
      Features.push_back("-sme-f64f64");
101
4
      Features.push_back("-sme-i16i64");
102
4
    }
103
104
601
    if (Feature == "sve2")
105
9
      Features.push_back("+sve");
106
592
    else if (Feature == "sve2-bitperm" || 
Feature == "sve2-sha3"588
||
107
592
             
Feature == "sve2-aes"585
||
Feature == "sve2-sm4"580
) {
108
16
      Features.push_back("+sve");
109
16
      Features.push_back("+sve2");
110
576
    } else if (Feature == "nosve") {
111
8
      Features.push_back("-sve2");
112
8
      Features.push_back("-sve2-bitperm");
113
8
      Features.push_back("-sve2-sha3");
114
8
      Features.push_back("-sve2-aes");
115
8
      Features.push_back("-sve2-sm4");
116
568
    } else if (Feature == "nosve2") {
117
10
      Features.push_back("-sve2-bitperm");
118
10
      Features.push_back("-sve2-sha3");
119
10
      Features.push_back("-sve2-aes");
120
10
      Features.push_back("-sve2-sm4");
121
10
    }
122
123
    // +sve implies +f32mm if the base architecture is >= v8.6A (except v9A)
124
    // It isn't the case in general that sve implies both f64mm and f32mm
125
601
    if ((ArchInfo == llvm::AArch64::ARMV8_6A ||
126
601
         
ArchInfo == llvm::AArch64::ARMV8_7A569
||
127
601
         
ArchInfo == llvm::AArch64::ARMV8_8A541
||
128
601
         
ArchInfo == llvm::AArch64::ARMV8_9A507
||
129
601
         
ArchInfo == llvm::AArch64::ARMV9_1A501
||
130
601
         
ArchInfo == llvm::AArch64::ARMV9_2A501
||
131
601
         
ArchInfo == llvm::AArch64::ARMV9_3A497
||
132
601
         
ArchInfo == llvm::AArch64::ARMV9_4A487
) &&
133
601
        
Feature == "sve"125
)
134
5
      Features.push_back("+f32mm");
135
601
  }
136
450
  return true;
137
450
}
138
139
// Check if the CPU name and feature modifiers in -mcpu are legal. If yes,
140
// decode CPU and feature.
141
static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
142
1.43k
                              std::vector<StringRef> &Features) {
143
1.43k
  std::pair<StringRef, StringRef> Split = Mcpu.split("+");
144
1.43k
  CPU = Split.first;
145
1.43k
  const llvm::AArch64::ArchInfo *ArchInfo = &llvm::AArch64::ARMV8A;
146
147
1.43k
  if (CPU == "native")
148
1
    CPU = llvm::sys::getHostCPUName();
149
150
1.43k
  if (CPU == "generic") {
151
46
    Features.push_back("+neon");
152
1.39k
  } else {
153
1.39k
    const std::optional<llvm::AArch64::CpuInfo> CpuInfo =
154
1.39k
        llvm::AArch64::parseCpu(CPU);
155
1.39k
    if (!CpuInfo)
156
3
      return false;
157
1.38k
    ArchInfo = &CpuInfo->Arch;
158
159
1.38k
    Features.push_back(ArchInfo->ArchFeature);
160
161
1.38k
    auto Extension = CpuInfo->getImpliedExtensions();
162
1.38k
    if (!llvm::AArch64::getExtensionFeatures(Extension, Features))
163
0
      return false;
164
1.38k
  }
165
166
1.43k
  if (Split.second.size() &&
167
1.43k
      
!DecodeAArch64Features(D, Split.second, Features, *ArchInfo)50
)
168
0
    return false;
169
170
1.43k
  return true;
171
1.43k
}
172
173
static bool
174
getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
175
                                const ArgList &Args,
176
1.39k
                                std::vector<StringRef> &Features) {
177
1.39k
  std::string MarchLowerCase = March.lower();
178
1.39k
  std::pair<StringRef, StringRef> Split = StringRef(MarchLowerCase).split("+");
179
180
1.39k
  std::optional <llvm::AArch64::ArchInfo> ArchInfo =
181
1.39k
      llvm::AArch64::parseArch(Split.first);
182
1.39k
  if (Split.first == "native")
183
0
    ArchInfo = llvm::AArch64::getArchForCpu(llvm::sys::getHostCPUName().str());
184
1.39k
  if (!ArchInfo)
185
8
    return false;
186
1.39k
  Features.push_back(ArchInfo->ArchFeature);
187
188
  // Enable SVE2 by default on Armv9-A.
189
  // It can still be disabled if +nosve2 is present.
190
  // We must do this early so that DecodeAArch64Features has the correct state
191
1.39k
  if ((*ArchInfo == llvm::AArch64::ARMV9A ||
192
1.39k
       
*ArchInfo == llvm::AArch64::ARMV9_1A1.36k
||
193
1.39k
       
*ArchInfo == llvm::AArch64::ARMV9_2A1.34k
)) {
194
63
    Features.push_back("+sve");
195
63
    Features.push_back("+sve2");
196
63
  }
197
198
1.39k
  if ((Split.second.size() &&
199
1.39k
       
!DecodeAArch64Features(D, Split.second, Features, *ArchInfo)400
))
200
0
    return false;
201
202
1.39k
  return true;
203
1.39k
}
204
205
static bool
206
getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
207
                               const ArgList &Args,
208
437
                               std::vector<StringRef> &Features) {
209
437
  StringRef CPU;
210
437
  std::string McpuLowerCase = Mcpu.lower();
211
437
  if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, Features))
212
2
    return false;
213
214
435
  return true;
215
437
}
216
217
static bool
218
getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune,
219
                                     const ArgList &Args,
220
575
                                     std::vector<StringRef> &Features) {
221
575
  std::string MtuneLowerCase = Mtune.lower();
222
  // Check CPU name is valid
223
575
  std::vector<StringRef> MtuneFeatures;
224
575
  StringRef Tune;
225
575
  if (!DecodeAArch64Mcpu(D, MtuneLowerCase, Tune, MtuneFeatures))
226
1
    return false;
227
228
  // Handle CPU name is 'native'.
229
574
  if (MtuneLowerCase == "native")
230
0
    MtuneLowerCase = std::string(llvm::sys::getHostCPUName());
231
574
  if (MtuneLowerCase == "cyclone" ||
232
574
      
StringRef(MtuneLowerCase).startswith("apple")561
) {
233
220
    Features.push_back("+zcm");
234
220
    Features.push_back("+zcz");
235
220
  }
236
574
  return true;
237
575
}
238
239
static bool
240
getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
241
                                    const ArgList &Args,
242
426
                                    std::vector<StringRef> &Features) {
243
426
  StringRef CPU;
244
426
  std::vector<StringRef> DecodedFeature;
245
426
  std::string McpuLowerCase = Mcpu.lower();
246
426
  if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, DecodedFeature))
247
0
    return false;
248
249
426
  return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
250
426
}
251
252
void aarch64::getAArch64TargetFeatures(const Driver &D,
253
                                       const llvm::Triple &Triple,
254
                                       const ArgList &Args,
255
                                       std::vector<StringRef> &Features,
256
1.83k
                                       bool ForAS) {
257
1.83k
  Arg *A;
258
1.83k
  bool success = true;
259
  // Enable NEON by default.
260
1.83k
  Features.push_back("+neon");
261
1.83k
  llvm::StringRef WaMArch;
262
1.83k
  if (ForAS)
263
30
    for (const auto *A :
264
30
         Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler))
265
12
      for (StringRef Value : A->getValues())
266
13
        if (Value.startswith("-march="))
267
13
          WaMArch = Value.substr(7);
268
  // Call getAArch64ArchFeaturesFromMarch only if "-Wa,-march=" or
269
  // "-Xassembler -march" is detected. Otherwise it may return false
270
  // and causes Clang to error out.
271
1.83k
  if (!WaMArch.empty())
272
9
    success = getAArch64ArchFeaturesFromMarch(D, WaMArch, Args, Features);
273
1.82k
  else if ((A = Args.getLastArg(options::OPT_march_EQ)))
274
719
    success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features);
275
1.10k
  else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
276
242
    success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
277
866
  else if (Args.hasArg(options::OPT_arch) || 
isCPUDeterminedByTriple(Triple)807
)
278
195
    success = getAArch64ArchFeaturesFromMcpu(
279
195
        D, getAArch64TargetCPU(Args, Triple, A), Args, Features);
280
671
  else
281
    // Default to 'A' profile if the architecture is not specified.
282
671
    success = getAArch64ArchFeaturesFromMarch(D, "armv8-a", Args, Features);
283
284
1.83k
  if (success && 
(A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ))1.82k
)
285
149
    success =
286
149
        getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features);
287
1.68k
  else if (success && 
(A = Args.getLastArg(options::OPT_mcpu_EQ))1.67k
)
288
232
    success =
289
232
        getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
290
1.45k
  else if (success &&
291
1.45k
           
(1.44k
Args.hasArg(options::OPT_arch)1.44k
||
isCPUDeterminedByTriple(Triple)1.38k
))
292
194
    success = getAArch64MicroArchFeaturesFromMcpu(
293
194
        D, getAArch64TargetCPU(Args, Triple, A), Args, Features);
294
295
1.83k
  if (!success) {
296
11
    auto Diag = D.Diag(diag::err_drv_unsupported_option_argument);
297
    // If "-Wa,-march=" is used, 'WaMArch' will contain the argument's value,
298
    // while 'A' is uninitialized. Only dereference 'A' in the other case.
299
11
    if (!WaMArch.empty())
300
2
      Diag << "-march=" << WaMArch;
301
9
    else
302
9
      Diag << A->getSpelling() << A->getValue();
303
11
  }
304
305
1.83k
  if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
306
2
    Features.push_back("-fp-armv8");
307
2
    Features.push_back("-crypto");
308
2
    Features.push_back("-neon");
309
2
  }
310
311
1.83k
  if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
312
9
    StringRef Mtp = A->getValue();
313
9
    if (Mtp == "el3" || 
Mtp == "tpidr_el3"8
)
314
2
      Features.push_back("+tpidr-el3");
315
7
    else if (Mtp == "el2" || 
Mtp == "tpidr_el2"6
)
316
2
      Features.push_back("+tpidr-el2");
317
5
    else if (Mtp == "el1" || 
Mtp == "tpidr_el1"4
)
318
2
      Features.push_back("+tpidr-el1");
319
3
    else if (Mtp == "tpidrro_el0")
320
1
      Features.push_back("+tpidrro-el0");
321
2
    else if (Mtp != "el0" && 
Mtp != "tpidr_el0"1
)
322
0
      D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
323
9
  }
324
325
  // Enable/disable straight line speculation hardening.
326
1.83k
  if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) {
327
17
    StringRef Scope = A->getValue();
328
17
    bool EnableRetBr = false;
329
17
    bool EnableBlr = false;
330
17
    bool DisableComdat = false;
331
17
    if (Scope != "none") {
332
15
      SmallVector<StringRef, 4> Opts;
333
15
      Scope.split(Opts, ",");
334
30
      for (auto Opt : Opts) {
335
30
        Opt = Opt.trim();
336
30
        if (Opt == "all") {
337
4
          EnableBlr = true;
338
4
          EnableRetBr = true;
339
4
          continue;
340
4
        }
341
26
        if (Opt == "retbr") {
342
10
          EnableRetBr = true;
343
10
          continue;
344
10
        }
345
16
        if (Opt == "blr") {
346
6
          EnableBlr = true;
347
6
          continue;
348
6
        }
349
10
        if (Opt == "comdat") {
350
1
          DisableComdat = false;
351
1
          continue;
352
1
        }
353
9
        if (Opt == "nocomdat") {
354
3
          DisableComdat = true;
355
3
          continue;
356
3
        }
357
6
        D.Diag(diag::err_drv_unsupported_option_argument)
358
6
            << A->getSpelling() << Scope;
359
6
        break;
360
9
      }
361
15
    }
362
363
17
    if (EnableRetBr)
364
12
      Features.push_back("+harden-sls-retbr");
365
17
    if (EnableBlr)
366
10
      Features.push_back("+harden-sls-blr");
367
17
    if (DisableComdat) {
368
3
      Features.push_back("+harden-sls-nocomdat");
369
3
    }
370
17
  }
371
372
  // En/disable crc
373
1.83k
  if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
374
2
    if (A->getOption().matches(options::OPT_mcrc))
375
2
      Features.push_back("+crc");
376
0
    else
377
0
      Features.push_back("-crc");
378
2
  }
379
380
1.83k
  int V8Version = -1;
381
1.83k
  int V9Version = -1;
382
1.83k
  bool HasNoSM4 = false;
383
1.83k
  bool HasNoSHA3 = false;
384
1.83k
  bool HasNoSHA2 = false;
385
1.83k
  bool HasNoAES = false;
386
1.83k
  bool HasSM4 = false;
387
1.83k
  bool HasSHA3 = false;
388
1.83k
  bool HasSHA2 = false;
389
1.83k
  bool HasAES = false;
390
1.83k
  bool HasCrypto = false;
391
1.83k
  bool HasNoCrypto = false;
392
1.83k
  int FullFP16Pos = -1;
393
1.83k
  int NoFullFP16Pos = -1;
394
1.83k
  int FP16FMLPos = -1;
395
1.83k
  int NoFP16FMLPos = -1;
396
1.83k
  int ArchFeatPos = -1;
397
398
10.4k
  for (auto I = Features.begin(), E = Features.end(); I != E; 
I++8.60k
) {
399
8.60k
    if (*I == "+v8a")   
V8Version = 01.03k
;
400
7.57k
    else if (*I == "+v8.1a") 
V8Version = 155
;
401
7.51k
    else if (*I == "+v8.2a") 
V8Version = 2169
;
402
7.34k
    else if (*I == "+v8.3a") 
V8Version = 360
;
403
7.28k
    else if (*I == "+v8.4a") 
V8Version = 458
;
404
7.23k
    else if (*I == "+v8.5a") 
V8Version = 5152
;
405
7.07k
    else if (*I == "+v8.6a") 
V8Version = 641
;
406
7.03k
    else if (*I == "+v8.7a") 
V8Version = 739
;
407
6.99k
    else if (*I == "+v8.8a") 
V8Version = 844
;
408
6.95k
    else if (*I == "+v8.9a") 
V8Version = 922
;
409
6.93k
    else if (*I == "+v9a")   
V9Version = 040
;
410
6.89k
    else if (*I == "+v9.1a") 
V9Version = 114
;
411
6.87k
    else if (*I == "+v9.2a") 
V9Version = 219
;
412
6.85k
    else if (*I == "+v9.3a") 
V9Version = 330
;
413
6.82k
    else if (*I == "+v9.4a") 
V9Version = 430
;
414
6.79k
    else if (*I == "+sm4")  
HasSM4 = true8
;
415
6.79k
    else if (*I == "+sha3") 
HasSHA3 = true107
;
416
6.68k
    else if (*I == "+sha2") 
HasSHA2 = true410
;
417
6.27k
    else if (*I == "+aes")  
HasAES = true410
;
418
5.86k
    else if (*I == "-sm4")  
HasNoSM4 = true2
;
419
5.86k
    else if (*I == "-sha3") 
HasNoSHA3 = true2
;
420
5.86k
    else if (*I == "-sha2") 
HasNoSHA2 = true2
;
421
5.85k
    else if (*I == "-aes")  
HasNoAES = true2
;
422
5.85k
    else if (*I == "+fp16fml")  
FP16FMLPos = I - Features.begin()173
;
423
5.68k
    else if (*I == "-fp16fml")  
NoFP16FMLPos = I - Features.begin()34
;
424
5.64k
    else if (*I == "-fullfp16") 
NoFullFP16Pos = I - Features.begin()34
;
425
5.61k
    else if (*I == "+fullfp16") 
FullFP16Pos = I - Features.begin()286
;
426
    // Whichever option comes after (right-most option) will win
427
5.32k
    else if (*I == "+crypto") {
428
29
      HasCrypto = true;
429
29
      HasNoCrypto = false;
430
5.30k
    } else if (*I == "-crypto" || 
*I == "-neon"5.28k
) {
431
35
      HasCrypto = false;
432
35
      HasNoCrypto = true;
433
35
      HasSM4 = HasSHA2 = HasSHA3 = HasAES = false;
434
35
    }
435
    // Register the iterator position if this is an architecture feature
436
8.60k
    if (ArchFeatPos == -1 && 
(3.70k
V8Version != -13.70k
||
V9Version != -12.03k
))
437
1.80k
      ArchFeatPos = I - Features.begin();
438
8.60k
  }
439
440
  // Handle (arch-dependent) fp16fml/fullfp16 relationship.
441
  // FIXME: this fp16fml option handling will be reimplemented after the
442
  // TargetParser rewrite.
443
1.83k
  if (V8Version >= 4) {
444
    // "-fullfp16" "+fullfp16" && "+fp16fml" "+fullfp16" && no "+fullfp16" "-fp16fml" = "+fp16fml"
445
356
    if (FullFP16Pos > NoFullFP16Pos && 
FullFP16Pos > FP16FMLPos138
&&
FullFP16Pos > NoFP16FMLPos37
)
446
      // Only entangled feature that can be to the right of this +fullfp16 is -fp16fml.
447
      // Only append the +fp16fml if there is no -fp16fml after the +fullfp16.
448
26
      Features.push_back("+fp16fml");
449
330
    else
450
330
      goto fp16_fml_fallthrough;
451
1.48k
  } else {
452
1.81k
fp16_fml_fallthrough:
453
    // In both of these cases, putting the 'other' feature on the end of the vector will
454
    // result in the same effect as placing it immediately after the current feature.
455
    // "+fp16fml"  "-fullfp16" = "-fp16fml"
456
1.81k
    if (NoFullFP16Pos > FP16FMLPos)
457
18
      Features.push_back("-fp16fml");
458
    // "-fullfp16" "+fp16fml" = "+fullfp16"
459
1.79k
    else if (NoFullFP16Pos < FP16FMLPos)
460
157
      Features.push_back("+fullfp16");
461
1.81k
  }
462
463
  // FIXME: this needs reimplementation too after the TargetParser rewrite
464
  //
465
  // Context sensitive meaning of Crypto:
466
  // 1) For Arch >= ARMv8.4a:  crypto = sm4 + sha3 + sha2 + aes
467
  // 2) For Arch <= ARMv8.3a:  crypto = sha2 + aes
468
1.83k
  if (V8Version >= 4 || 
V9Version >= 01.48k
) {
469
489
    if (HasCrypto && 
!HasNoCrypto10
) {
470
      // Check if we have NOT disabled an algorithm with something like:
471
      //   +crypto, -algorithm
472
      // And if "-algorithm" does not occur, we enable that crypto algorithm.
473
10
      if (!HasNoSM4)
474
9
        Features.push_back("+sm4");
475
10
      if (!HasNoSHA3)
476
9
        Features.push_back("+sha3");
477
10
      if (!HasNoSHA2)
478
10
        Features.push_back("+sha2");
479
10
      if (!HasNoAES)
480
10
        Features.push_back("+aes");
481
479
    } else if (HasNoCrypto) {
482
      // Check if we have NOT enabled a crypto algorithm with something like:
483
      //   -crypto, +algorithm
484
      // And if "+algorithm" does not occur, we disable that crypto algorithm.
485
4
      if (!HasSM4)
486
4
        Features.push_back("-sm4");
487
4
      if (!HasSHA3)
488
4
        Features.push_back("-sha3");
489
4
      if (!HasSHA2)
490
4
        Features.push_back("-sha2");
491
4
      if (!HasAES)
492
4
        Features.push_back("-aes");
493
4
    }
494
1.34k
  } else {
495
1.34k
    if (HasCrypto && 
!HasNoCrypto14
) {
496
14
      if (!HasNoSHA2)
497
13
        Features.push_back("+sha2");
498
14
      if (!HasNoAES)
499
13
        Features.push_back("+aes");
500
1.33k
    } else if (HasNoCrypto) {
501
23
      if (!HasSHA2)
502
22
        Features.push_back("-sha2");
503
23
      if (!HasAES)
504
22
        Features.push_back("-aes");
505
23
      if (V8Version == 2 || 
V8Version == 322
) {
506
3
        Features.push_back("-sm4");
507
3
        Features.push_back("-sha3");
508
3
      }
509
23
    }
510
1.34k
  }
511
512
1.83k
  if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
513
1.83k
                               options::OPT_munaligned_access)) {
514
8
    if (A->getOption().matches(options::OPT_mno_unaligned_access))
515
5
      Features.push_back("+strict-align");
516
1.82k
  } else if (Triple.isOSOpenBSD())
517
11
    Features.push_back("+strict-align");
518
519
1.83k
  if (Args.hasArg(options::OPT_ffixed_x1))
520
3
    Features.push_back("+reserve-x1");
521
522
1.83k
  if (Args.hasArg(options::OPT_ffixed_x2))
523
3
    Features.push_back("+reserve-x2");
524
525
1.83k
  if (Args.hasArg(options::OPT_ffixed_x3))
526
2
    Features.push_back("+reserve-x3");
527
528
1.83k
  if (Args.hasArg(options::OPT_ffixed_x4))
529
2
    Features.push_back("+reserve-x4");
530
531
1.83k
  if (Args.hasArg(options::OPT_ffixed_x5))
532
2
    Features.push_back("+reserve-x5");
533
534
1.83k
  if (Args.hasArg(options::OPT_ffixed_x6))
535
2
    Features.push_back("+reserve-x6");
536
537
1.83k
  if (Args.hasArg(options::OPT_ffixed_x7))
538
2
    Features.push_back("+reserve-x7");
539
540
1.83k
  if (Args.hasArg(options::OPT_ffixed_x9))
541
2
    Features.push_back("+reserve-x9");
542
543
1.83k
  if (Args.hasArg(options::OPT_ffixed_x10))
544
2
    Features.push_back("+reserve-x10");
545
546
1.83k
  if (Args.hasArg(options::OPT_ffixed_x11))
547
2
    Features.push_back("+reserve-x11");
548
549
1.83k
  if (Args.hasArg(options::OPT_ffixed_x12))
550
2
    Features.push_back("+reserve-x12");
551
552
1.83k
  if (Args.hasArg(options::OPT_ffixed_x13))
553
2
    Features.push_back("+reserve-x13");
554
555
1.83k
  if (Args.hasArg(options::OPT_ffixed_x14))
556
2
    Features.push_back("+reserve-x14");
557
558
1.83k
  if (Args.hasArg(options::OPT_ffixed_x15))
559
2
    Features.push_back("+reserve-x15");
560
561
1.83k
  if (Args.hasArg(options::OPT_ffixed_x18))
562
7
    Features.push_back("+reserve-x18");
563
564
1.83k
  if (Args.hasArg(options::OPT_ffixed_x20))
565
2
    Features.push_back("+reserve-x20");
566
567
1.83k
  if (Args.hasArg(options::OPT_ffixed_x21))
568
2
    Features.push_back("+reserve-x21");
569
570
1.83k
  if (Args.hasArg(options::OPT_ffixed_x22))
571
2
    Features.push_back("+reserve-x22");
572
573
1.83k
  if (Args.hasArg(options::OPT_ffixed_x23))
574
2
    Features.push_back("+reserve-x23");
575
576
1.83k
  if (Args.hasArg(options::OPT_ffixed_x24))
577
2
    Features.push_back("+reserve-x24");
578
579
1.83k
  if (Args.hasArg(options::OPT_ffixed_x25))
580
2
    Features.push_back("+reserve-x25");
581
582
1.83k
  if (Args.hasArg(options::OPT_ffixed_x26))
583
2
    Features.push_back("+reserve-x26");
584
585
1.83k
  if (Args.hasArg(options::OPT_ffixed_x27))
586
2
    Features.push_back("+reserve-x27");
587
588
1.83k
  if (Args.hasArg(options::OPT_ffixed_x28))
589
2
    Features.push_back("+reserve-x28");
590
591
1.83k
  if (Args.hasArg(options::OPT_ffixed_x30))
592
1
    Features.push_back("+reserve-x30");
593
594
1.83k
  if (Args.hasArg(options::OPT_fcall_saved_x8))
595
2
    Features.push_back("+call-saved-x8");
596
597
1.83k
  if (Args.hasArg(options::OPT_fcall_saved_x9))
598
2
    Features.push_back("+call-saved-x9");
599
600
1.83k
  if (Args.hasArg(options::OPT_fcall_saved_x10))
601
2
    Features.push_back("+call-saved-x10");
602
603
1.83k
  if (Args.hasArg(options::OPT_fcall_saved_x11))
604
2
    Features.push_back("+call-saved-x11");
605
606
1.83k
  if (Args.hasArg(options::OPT_fcall_saved_x12))
607
2
    Features.push_back("+call-saved-x12");
608
609
1.83k
  if (Args.hasArg(options::OPT_fcall_saved_x13))
610
2
    Features.push_back("+call-saved-x13");
611
612
1.83k
  if (Args.hasArg(options::OPT_fcall_saved_x14))
613
2
    Features.push_back("+call-saved-x14");
614
615
1.83k
  if (Args.hasArg(options::OPT_fcall_saved_x15))
616
2
    Features.push_back("+call-saved-x15");
617
618
1.83k
  if (Args.hasArg(options::OPT_fcall_saved_x18))
619
3
    Features.push_back("+call-saved-x18");
620
621
1.83k
  if (Args.hasArg(options::OPT_mno_neg_immediates))
622
1
    Features.push_back("+no-neg-immediates");
623
624
1.83k
  if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
625
1.83k
                               options::OPT_mno_fix_cortex_a53_835769)) {
626
6
    if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769))
627
3
      Features.push_back("+fix-cortex-a53-835769");
628
3
    else
629
3
      Features.push_back("-fix-cortex-a53-835769");
630
1.83k
  } else if (Triple.isAndroid() || 
Triple.isOHOSFamily()1.75k
) {
631
    // Enabled A53 errata (835769) workaround by default on android
632
78
    Features.push_back("+fix-cortex-a53-835769");
633
1.75k
  } else if (Triple.isOSFuchsia()) {
634
20
    std::string CPU = getCPUName(D, Args, Triple);
635
20
    if (CPU.empty() || CPU == "generic" || 
CPU == "cortex-a53"2
)
636
19
      Features.push_back("+fix-cortex-a53-835769");
637
20
  }
638
639
1.83k
  if (Args.getLastArg(options::OPT_mno_bti_at_return_twice))
640
0
    Features.push_back("+no-bti-at-return-twice");
641
1.83k
}