Coverage Report

Created: 2022-01-15 10:30

/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 "clang/Driver/Driver.h"
11
#include "clang/Driver/DriverDiagnostic.h"
12
#include "clang/Driver/Options.h"
13
#include "llvm/Option/ArgList.h"
14
#include "llvm/Support/TargetParser.h"
15
#include "llvm/Support/Host.h"
16
17
using namespace clang::driver;
18
using namespace clang::driver::tools;
19
using namespace clang;
20
using namespace llvm::opt;
21
22
/// \returns true if the given triple can determine the default CPU type even
23
/// if -arch is not specified.
24
1.62k
static bool isCPUDeterminedByTriple(const llvm::Triple &Triple) {
25
1.62k
  return Triple.isOSDarwin();
26
1.62k
}
27
28
/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
29
/// targeting. Set \p A to the Arg corresponding to the -mcpu argument if it is
30
/// provided, or to nullptr otherwise.
31
std::string aarch64::getAArch64TargetCPU(const ArgList &Args,
32
1.71k
                                         const llvm::Triple &Triple, Arg *&A) {
33
1.71k
  std::string CPU;
34
  // If we have -mcpu, use that.
35
1.71k
  if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
36
241
    StringRef Mcpu = A->getValue();
37
241
    CPU = Mcpu.split("+").first.lower();
38
241
  }
39
40
  // Handle CPU name is 'native'.
41
1.71k
  if (CPU == "native")
42
1
    return std::string(llvm::sys::getHostCPUName());
43
44
1.71k
  if (CPU.size())
45
240
    return CPU;
46
47
1.47k
  if (Triple.isTargetMachineMac() &&
48
1.47k
      
Triple.getArch() == llvm::Triple::aarch64120
) {
49
    // Apple Silicon macs default to M1 CPUs.
50
117
    return "apple-m1";
51
117
  }
52
53
  // arm64e requires v8.3a and only runs on apple-a12 and later CPUs.
54
1.36k
  if (Triple.isArm64e())
55
6
    return "apple-a12";
56
57
  // Make sure we pick the appropriate Apple CPU if -arch is used or when
58
  // targetting a Darwin OS.
59
1.35k
  if (Args.getLastArg(options::OPT_arch) || 
Triple.isOSDarwin()1.25k
)
60
257
    return Triple.getArch() == llvm::Triple::aarch64_32 ? 
"apple-s4"15
61
257
                                                        : 
"apple-a7"242
;
62
63
1.09k
  return "generic";
64
1.35k
}
65
66
// Decode AArch64 features from string like +[no]featureA+[no]featureB+...
67
static bool DecodeAArch64Features(const Driver &D, StringRef text,
68
                                  std::vector<StringRef> &Features,
69
317
                                  llvm::AArch64::ArchKind ArchKind) {
70
317
  SmallVector<StringRef, 8> Split;
71
317
  text.split(Split, StringRef("+"), -1, false);
72
73
425
  for (StringRef Feature : Split) {
74
425
    StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
75
425
    if (!FeatureName.empty())
76
419
      Features.push_back(FeatureName);
77
6
    else if (Feature == "neon" || 
Feature == "noneon"3
)
78
6
      D.Diag(clang::diag::err_drv_no_neon_modifier);
79
0
    else
80
0
      return false;
81
82
425
    if (Feature == "sve2")
83
8
      Features.push_back("+sve");
84
417
    else if (Feature == "sve2-bitperm" || 
Feature == "sve2-sha3"413
||
85
417
             
Feature == "sve2-aes"410
||
Feature == "sve2-sm4"405
) {
86
16
      Features.push_back("+sve");
87
16
      Features.push_back("+sve2");
88
401
    } else if (Feature == "nosve") {
89
8
      Features.push_back("-sve2");
90
8
      Features.push_back("-sve2-bitperm");
91
8
      Features.push_back("-sve2-sha3");
92
8
      Features.push_back("-sve2-aes");
93
8
      Features.push_back("-sve2-sm4");
94
393
    } else if (Feature == "nosve2") {
95
10
      Features.push_back("-sve2-bitperm");
96
10
      Features.push_back("-sve2-sha3");
97
10
      Features.push_back("-sve2-aes");
98
10
      Features.push_back("-sve2-sm4");
99
10
    }
100
101
    // +sve implies +f32mm if the base architecture is >= v8.6A (except v9A)
102
    // It isn't the case in general that sve implies both f64mm and f32mm
103
425
    if ((ArchKind == llvm::AArch64::ArchKind::ARMV8_6A ||
104
425
         
ArchKind == llvm::AArch64::ArchKind::ARMV8_7A414
||
105
425
         
ArchKind == llvm::AArch64::ArchKind::ARMV8_8A410
||
106
425
         
ArchKind == llvm::AArch64::ArchKind::ARMV9_1A408
||
107
425
         
ArchKind == llvm::AArch64::ArchKind::ARMV9_2A408
||
108
425
         
ArchKind == llvm::AArch64::ArchKind::ARMV9_3A408
) &&
109
425
        
Feature == "sve"17
)
110
5
      Features.push_back("+f32mm");
111
425
  }
112
317
  return true;
113
317
}
114
115
// Check if the CPU name and feature modifiers in -mcpu are legal. If yes,
116
// decode CPU and feature.
117
static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
118
1.20k
                              std::vector<StringRef> &Features) {
119
1.20k
  std::pair<StringRef, StringRef> Split = Mcpu.split("+");
120
1.20k
  CPU = Split.first;
121
1.20k
  llvm::AArch64::ArchKind ArchKind = llvm::AArch64::ArchKind::ARMV8A;
122
123
1.20k
  if (CPU == "native")
124
1
    CPU = llvm::sys::getHostCPUName();
125
126
1.20k
  if (CPU == "generic") {
127
46
    Features.push_back("+neon");
128
1.15k
  } else {
129
1.15k
    ArchKind = llvm::AArch64::parseCPUArch(CPU);
130
1.15k
    if (!llvm::AArch64::getArchFeatures(ArchKind, Features))
131
3
      return false;
132
133
1.15k
    uint64_t Extension = llvm::AArch64::getDefaultExtensions(CPU, ArchKind);
134
1.15k
    if (!llvm::AArch64::getExtensionFeatures(Extension, Features))
135
0
      return false;
136
1.15k
   }
137
138
1.20k
   if (Split.second.size() &&
139
1.20k
       
!DecodeAArch64Features(D, Split.second, Features, ArchKind)48
)
140
0
     return false;
141
142
1.20k
   return true;
143
1.20k
}
144
145
static bool
146
getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
147
                                const ArgList &Args,
148
1.06k
                                std::vector<StringRef> &Features) {
149
1.06k
  std::string MarchLowerCase = March.lower();
150
1.06k
  std::pair<StringRef, StringRef> Split = StringRef(MarchLowerCase).split("+");
151
152
1.06k
  llvm::AArch64::ArchKind ArchKind = llvm::AArch64::parseArch(Split.first);
153
1.06k
  if (ArchKind == llvm::AArch64::ArchKind::INVALID ||
154
1.06k
      
!llvm::AArch64::getArchFeatures(ArchKind, Features)1.05k
)
155
8
    return false;
156
157
  // Enable SVE2 by default on Armv9-A.
158
  // It can still be disabled if +nosve2 is present.
159
  // We must do this early so that DecodeAArch64Features has the correct state
160
1.05k
  if ((ArchKind == llvm::AArch64::ArchKind::ARMV9A ||
161
1.05k
       
ArchKind == llvm::AArch64::ArchKind::ARMV9_1A1.03k
||
162
1.05k
       
ArchKind == llvm::AArch64::ArchKind::ARMV9_2A1.02k
)) {
163
48
    Features.push_back("+sve");
164
48
    Features.push_back("+sve2");
165
48
  }
166
167
1.05k
  if ((Split.second.size() &&
168
1.05k
       
!DecodeAArch64Features(D, Split.second, Features, ArchKind)269
))
169
0
    return false;
170
171
1.05k
  return true;
172
1.05k
}
173
174
static bool
175
getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
176
                               const ArgList &Args,
177
359
                               std::vector<StringRef> &Features) {
178
359
  StringRef CPU;
179
359
  std::string McpuLowerCase = Mcpu.lower();
180
359
  if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, Features))
181
2
    return false;
182
183
357
  return true;
184
359
}
185
186
static bool
187
getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune,
188
                                     const ArgList &Args,
189
497
                                     std::vector<StringRef> &Features) {
190
497
  std::string MtuneLowerCase = Mtune.lower();
191
  // Check CPU name is valid
192
497
  std::vector<StringRef> MtuneFeatures;
193
497
  StringRef Tune;
194
497
  if (!DecodeAArch64Mcpu(D, MtuneLowerCase, Tune, MtuneFeatures))
195
1
    return false;
196
197
  // Handle CPU name is 'native'.
198
496
  if (MtuneLowerCase == "native")
199
0
    MtuneLowerCase = std::string(llvm::sys::getHostCPUName());
200
496
  if (MtuneLowerCase == "cyclone" ||
201
496
      
StringRef(MtuneLowerCase).startswith("apple")483
) {
202
152
    Features.push_back("+zcm");
203
152
    Features.push_back("+zcz");
204
152
  }
205
496
  return true;
206
497
}
207
208
static bool
209
getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
210
                                    const ArgList &Args,
211
348
                                    std::vector<StringRef> &Features) {
212
348
  StringRef CPU;
213
348
  std::vector<StringRef> DecodedFeature;
214
348
  std::string McpuLowerCase = Mcpu.lower();
215
348
  if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, DecodedFeature))
216
0
    return false;
217
218
348
  return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
219
348
}
220
221
void aarch64::getAArch64TargetFeatures(const Driver &D,
222
                                       const llvm::Triple &Triple,
223
                                       const ArgList &Args,
224
                                       std::vector<StringRef> &Features,
225
1.42k
                                       bool ForAS) {
226
1.42k
  Arg *A;
227
1.42k
  bool success = true;
228
  // Enable NEON by default.
229
1.42k
  Features.push_back("+neon");
230
1.42k
  llvm::StringRef WaMArch;
231
1.42k
  if (ForAS)
232
25
    for (const auto *A :
233
25
         Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler))
234
12
      for (StringRef Value : A->getValues())
235
13
        if (Value.startswith("-march="))
236
13
          WaMArch = Value.substr(7);
237
  // Call getAArch64ArchFeaturesFromMarch only if "-Wa,-march=" or
238
  // "-Xassembler -march" is detected. Otherwise it may return false
239
  // and causes Clang to error out.
240
1.42k
  if (!WaMArch.empty())
241
9
    success = getAArch64ArchFeaturesFromMarch(D, WaMArch, Args, Features);
242
1.41k
  else if ((A = Args.getLastArg(options::OPT_march_EQ)))
243
510
    success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features);
244
904
  else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
245
232
    success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
246
672
  else if (Args.hasArg(options::OPT_arch) || 
isCPUDeterminedByTriple(Triple)627
)
247
127
    success = getAArch64ArchFeaturesFromMcpu(
248
127
        D, getAArch64TargetCPU(Args, Triple, A), Args, Features);
249
545
  else
250
    // Default to 'A' profile if the architecture is not specified.
251
545
    success = getAArch64ArchFeaturesFromMarch(D, "armv8-a", Args, Features);
252
253
1.42k
  if (success && 
(A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ))1.41k
)
254
149
    success =
255
149
        getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features);
256
1.27k
  else if (success && 
(A = Args.getLastArg(options::OPT_mcpu_EQ))1.26k
)
257
222
    success =
258
222
        getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
259
1.05k
  else if (success &&
260
1.05k
           
(1.04k
Args.hasArg(options::OPT_arch)1.04k
||
isCPUDeterminedByTriple(Triple)998
))
261
126
    success = getAArch64MicroArchFeaturesFromMcpu(
262
126
        D, getAArch64TargetCPU(Args, Triple, A), Args, Features);
263
264
1.42k
  if (!success) {
265
11
    auto Diag = D.Diag(diag::err_drv_clang_unsupported);
266
    // If "-Wa,-march=" is used, 'WaMArch' will contain the argument's value,
267
    // while 'A' is uninitialized. Only dereference 'A' in the other case.
268
11
    if (!WaMArch.empty())
269
2
      Diag << "-march=" + WaMArch.str();
270
9
    else
271
9
      Diag << A->getAsString(Args);
272
11
  }
273
274
1.42k
  if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
275
2
    Features.push_back("-fp-armv8");
276
2
    Features.push_back("-crypto");
277
2
    Features.push_back("-neon");
278
2
  }
279
280
1.42k
  if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
281
4
    StringRef Mtp = A->getValue();
282
4
    if (Mtp == "el3")
283
1
      Features.push_back("+tpidr-el3");
284
3
    else if (Mtp == "el2")
285
1
      Features.push_back("+tpidr-el2");
286
2
    else if (Mtp == "el1")
287
1
      Features.push_back("+tpidr-el1");
288
1
    else if (Mtp != "el0")
289
0
      D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
290
4
  }
291
292
  // Enable/disable straight line speculation hardening.
293
1.42k
  if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) {
294
17
    StringRef Scope = A->getValue();
295
17
    bool EnableRetBr = false;
296
17
    bool EnableBlr = false;
297
17
    bool DisableComdat = false;
298
17
    if (Scope != "none") {
299
15
      SmallVector<StringRef, 4> Opts;
300
15
      Scope.split(Opts, ",");
301
30
      for (auto Opt : Opts) {
302
30
        Opt = Opt.trim();
303
30
        if (Opt == "all") {
304
4
          EnableBlr = true;
305
4
          EnableRetBr = true;
306
4
          continue;
307
4
        }
308
26
        if (Opt == "retbr") {
309
10
          EnableRetBr = true;
310
10
          continue;
311
10
        }
312
16
        if (Opt == "blr") {
313
6
          EnableBlr = true;
314
6
          continue;
315
6
        }
316
10
        if (Opt == "comdat") {
317
1
          DisableComdat = false;
318
1
          continue;
319
1
        }
320
9
        if (Opt == "nocomdat") {
321
3
          DisableComdat = true;
322
3
          continue;
323
3
        }
324
6
        D.Diag(diag::err_invalid_sls_hardening)
325
6
            << Scope << A->getAsString(Args);
326
6
        break;
327
9
      }
328
15
    }
329
330
17
    if (EnableRetBr)
331
12
      Features.push_back("+harden-sls-retbr");
332
17
    if (EnableBlr)
333
10
      Features.push_back("+harden-sls-blr");
334
17
    if (DisableComdat) {
335
3
      Features.push_back("+harden-sls-nocomdat");
336
3
    }
337
17
  }
338
339
  // En/disable crc
340
1.42k
  if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
341
2
    if (A->getOption().matches(options::OPT_mcrc))
342
2
      Features.push_back("+crc");
343
0
    else
344
0
      Features.push_back("-crc");
345
2
  }
346
347
  // Handle (arch-dependent) fp16fml/fullfp16 relationship.
348
  // FIXME: this fp16fml option handling will be reimplemented after the
349
  // TargetParser rewrite.
350
1.42k
  const auto ItRNoFullFP16 = std::find(Features.rbegin(), Features.rend(), "-fullfp16");
351
1.42k
  const auto ItRFP16FML = std::find(Features.rbegin(), Features.rend(), "+fp16fml");
352
1.42k
  if (llvm::is_contained(Features, "+v8.4a")) {
353
53
    const auto ItRFullFP16  = std::find(Features.rbegin(), Features.rend(), "+fullfp16");
354
53
    if (ItRFullFP16 < ItRNoFullFP16 && 
ItRFullFP16 < ItRFP16FML13
) {
355
      // Only entangled feature that can be to the right of this +fullfp16 is -fp16fml.
356
      // Only append the +fp16fml if there is no -fp16fml after the +fullfp16.
357
13
      if (std::find(Features.rbegin(), ItRFullFP16, "-fp16fml") == ItRFullFP16)
358
10
        Features.push_back("+fp16fml");
359
13
    }
360
40
    else
361
40
      goto fp16_fml_fallthrough;
362
1.37k
  } else {
363
1.41k
fp16_fml_fallthrough:
364
    // In both of these cases, putting the 'other' feature on the end of the vector will
365
    // result in the same effect as placing it immediately after the current feature.
366
1.41k
    if (ItRNoFullFP16 < ItRFP16FML)
367
10
      Features.push_back("-fp16fml");
368
1.40k
    else if (ItRNoFullFP16 > ItRFP16FML)
369
76
      Features.push_back("+fullfp16");
370
1.41k
  }
371
372
  // FIXME: this needs reimplementation too after the TargetParser rewrite
373
  //
374
  // Context sensitive meaning of Crypto:
375
  // 1) For Arch >= ARMv8.4a:  crypto = sm4 + sha3 + sha2 + aes
376
  // 2) For Arch <= ARMv8.3a:  crypto = sha2 + aes
377
1.42k
  const auto ItBegin = Features.begin();
378
1.42k
  const auto ItEnd = Features.end();
379
1.42k
  const auto ItRBegin = Features.rbegin();
380
1.42k
  const auto ItREnd = Features.rend();
381
1.42k
  const auto ItRCrypto = std::find(ItRBegin, ItREnd, "+crypto");
382
1.42k
  const auto ItRNoCrypto = std::find(ItRBegin, ItREnd, "-crypto");
383
1.42k
  const auto HasCrypto  = ItRCrypto != ItREnd;
384
1.42k
  const auto HasNoCrypto = ItRNoCrypto != ItREnd;
385
1.42k
  const ptrdiff_t PosCrypto = ItRCrypto - ItRBegin;
386
1.42k
  const ptrdiff_t PosNoCrypto = ItRNoCrypto - ItRBegin;
387
388
1.42k
  bool NoCrypto = false;
389
1.42k
  if (HasCrypto && 
HasNoCrypto356
) {
390
8
    if (PosNoCrypto < PosCrypto)
391
6
      NoCrypto = true;
392
8
  }
393
394
1.42k
  if (std::find(ItBegin, ItEnd, "+v8.4a") != ItEnd ||
395
1.42k
      
std::find(ItBegin, ItEnd, "+v8.8a") != ItEnd1.37k
||
396
1.42k
      
std::find(ItBegin, ItEnd, "+v9a") != ItEnd1.35k
||
397
1.42k
      
std::find(ItBegin, ItEnd, "+v9.1a") != ItEnd1.32k
||
398
1.42k
      
std::find(ItBegin, ItEnd, "+v9.2a") != ItEnd1.31k
||
399
1.42k
      
std::find(ItBegin, ItEnd, "+v9.3a") != ItEnd1.30k
) {
400
133
    if (HasCrypto && 
!NoCrypto10
) {
401
      // Check if we have NOT disabled an algorithm with something like:
402
      //   +crypto, -algorithm
403
      // And if "-algorithm" does not occur, we enable that crypto algorithm.
404
10
      const bool HasSM4  = (std::find(ItBegin, ItEnd, "-sm4") == ItEnd);
405
10
      const bool HasSHA3 = (std::find(ItBegin, ItEnd, "-sha3") == ItEnd);
406
10
      const bool HasSHA2 = (std::find(ItBegin, ItEnd, "-sha2") == ItEnd);
407
10
      const bool HasAES  = (std::find(ItBegin, ItEnd, "-aes") == ItEnd);
408
10
      if (HasSM4)
409
9
        Features.push_back("+sm4");
410
10
      if (HasSHA3)
411
9
        Features.push_back("+sha3");
412
10
      if (HasSHA2)
413
10
        Features.push_back("+sha2");
414
10
      if (HasAES)
415
10
        Features.push_back("+aes");
416
123
    } else if (HasNoCrypto) {
417
      // Check if we have NOT enabled a crypto algorithm with something like:
418
      //   -crypto, +algorithm
419
      // And if "+algorithm" does not occur, we disable that crypto algorithm.
420
1
      const bool HasSM4  = (std::find(ItBegin, ItEnd, "+sm4") != ItEnd);
421
1
      const bool HasSHA3 = (std::find(ItBegin, ItEnd, "+sha3") != ItEnd);
422
1
      const bool HasSHA2 = (std::find(ItBegin, ItEnd, "+sha2") != ItEnd);
423
1
      const bool HasAES  = (std::find(ItBegin, ItEnd, "+aes") != ItEnd);
424
1
      if (!HasSM4)
425
1
        Features.push_back("-sm4");
426
1
      if (!HasSHA3)
427
1
        Features.push_back("-sha3");
428
1
      if (!HasSHA2)
429
1
        Features.push_back("-sha2");
430
1
      if (!HasAES)
431
1
        Features.push_back("-aes");
432
1
    }
433
1.29k
  } else {
434
1.29k
    if (HasCrypto && 
!NoCrypto346
) {
435
340
      const bool HasSHA2 = (std::find(ItBegin, ItEnd, "-sha2") == ItEnd);
436
340
      const bool HasAES = (std::find(ItBegin, ItEnd, "-aes") == ItEnd);
437
340
      if (HasSHA2)
438
339
        Features.push_back("+sha2");
439
340
      if (HasAES)
440
339
        Features.push_back("+aes");
441
950
    } else if (HasNoCrypto) {
442
16
      const bool HasSHA2 = (std::find(ItBegin, ItEnd, "+sha2") != ItEnd);
443
16
      const bool HasAES  = (std::find(ItBegin, ItEnd, "+aes") != ItEnd);
444
16
      const bool HasV82a = (std::find(ItBegin, ItEnd, "+v8.2a") != ItEnd);
445
16
      const bool HasV83a = (std::find(ItBegin, ItEnd, "+v8.3a") != ItEnd);
446
16
      const bool HasV84a = (std::find(ItBegin, ItEnd, "+v8.4a") != ItEnd);
447
16
      if (!HasSHA2)
448
15
        Features.push_back("-sha2");
449
16
      if (!HasAES)
450
15
        Features.push_back("-aes");
451
16
      if (HasV82a || 
HasV83a15
||
HasV84a13
) {
452
3
        Features.push_back("-sm4");
453
3
        Features.push_back("-sha3");
454
3
      }
455
16
    }
456
1.29k
  }
457
458
1.42k
  const char *Archs[] = {"+v8.6a", "+v8.7a", "+v8.8a",
459
1.42k
                         "+v9.1a", "+v9.2a", "+v9.3a"};
460
1.42k
  auto Pos = std::find_first_of(Features.begin(), Features.end(),
461
1.42k
                                std::begin(Archs), std::end(Archs));
462
1.42k
  if (Pos != std::end(Features))
463
93
    Pos = Features.insert(std::next(Pos), {"+i8mm", "+bf16"});
464
465
1.42k
  if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
466
1.42k
                               options::OPT_munaligned_access)) {
467
8
    if (A->getOption().matches(options::OPT_mno_unaligned_access))
468
5
      Features.push_back("+strict-align");
469
1.41k
  } else if (Triple.isOSOpenBSD())
470
11
    Features.push_back("+strict-align");
471
472
1.42k
  if (Args.hasArg(options::OPT_ffixed_x1))
473
3
    Features.push_back("+reserve-x1");
474
475
1.42k
  if (Args.hasArg(options::OPT_ffixed_x2))
476
3
    Features.push_back("+reserve-x2");
477
478
1.42k
  if (Args.hasArg(options::OPT_ffixed_x3))
479
2
    Features.push_back("+reserve-x3");
480
481
1.42k
  if (Args.hasArg(options::OPT_ffixed_x4))
482
2
    Features.push_back("+reserve-x4");
483
484
1.42k
  if (Args.hasArg(options::OPT_ffixed_x5))
485
2
    Features.push_back("+reserve-x5");
486
487
1.42k
  if (Args.hasArg(options::OPT_ffixed_x6))
488
2
    Features.push_back("+reserve-x6");
489
490
1.42k
  if (Args.hasArg(options::OPT_ffixed_x7))
491
2
    Features.push_back("+reserve-x7");
492
493
1.42k
  if (Args.hasArg(options::OPT_ffixed_x9))
494
2
    Features.push_back("+reserve-x9");
495
496
1.42k
  if (Args.hasArg(options::OPT_ffixed_x10))
497
2
    Features.push_back("+reserve-x10");
498
499
1.42k
  if (Args.hasArg(options::OPT_ffixed_x11))
500
2
    Features.push_back("+reserve-x11");
501
502
1.42k
  if (Args.hasArg(options::OPT_ffixed_x12))
503
2
    Features.push_back("+reserve-x12");
504
505
1.42k
  if (Args.hasArg(options::OPT_ffixed_x13))
506
2
    Features.push_back("+reserve-x13");
507
508
1.42k
  if (Args.hasArg(options::OPT_ffixed_x14))
509
2
    Features.push_back("+reserve-x14");
510
511
1.42k
  if (Args.hasArg(options::OPT_ffixed_x15))
512
2
    Features.push_back("+reserve-x15");
513
514
1.42k
  if (Args.hasArg(options::OPT_ffixed_x18))
515
7
    Features.push_back("+reserve-x18");
516
517
1.42k
  if (Args.hasArg(options::OPT_ffixed_x20))
518
2
    Features.push_back("+reserve-x20");
519
520
1.42k
  if (Args.hasArg(options::OPT_ffixed_x21))
521
2
    Features.push_back("+reserve-x21");
522
523
1.42k
  if (Args.hasArg(options::OPT_ffixed_x22))
524
2
    Features.push_back("+reserve-x22");
525
526
1.42k
  if (Args.hasArg(options::OPT_ffixed_x23))
527
2
    Features.push_back("+reserve-x23");
528
529
1.42k
  if (Args.hasArg(options::OPT_ffixed_x24))
530
2
    Features.push_back("+reserve-x24");
531
532
1.42k
  if (Args.hasArg(options::OPT_ffixed_x25))
533
2
    Features.push_back("+reserve-x25");
534
535
1.42k
  if (Args.hasArg(options::OPT_ffixed_x26))
536
2
    Features.push_back("+reserve-x26");
537
538
1.42k
  if (Args.hasArg(options::OPT_ffixed_x27))
539
2
    Features.push_back("+reserve-x27");
540
541
1.42k
  if (Args.hasArg(options::OPT_ffixed_x28))
542
2
    Features.push_back("+reserve-x28");
543
544
1.42k
  if (Args.hasArg(options::OPT_ffixed_x30))
545
1
    Features.push_back("+reserve-x30");
546
547
1.42k
  if (Args.hasArg(options::OPT_fcall_saved_x8))
548
2
    Features.push_back("+call-saved-x8");
549
550
1.42k
  if (Args.hasArg(options::OPT_fcall_saved_x9))
551
2
    Features.push_back("+call-saved-x9");
552
553
1.42k
  if (Args.hasArg(options::OPT_fcall_saved_x10))
554
2
    Features.push_back("+call-saved-x10");
555
556
1.42k
  if (Args.hasArg(options::OPT_fcall_saved_x11))
557
2
    Features.push_back("+call-saved-x11");
558
559
1.42k
  if (Args.hasArg(options::OPT_fcall_saved_x12))
560
2
    Features.push_back("+call-saved-x12");
561
562
1.42k
  if (Args.hasArg(options::OPT_fcall_saved_x13))
563
2
    Features.push_back("+call-saved-x13");
564
565
1.42k
  if (Args.hasArg(options::OPT_fcall_saved_x14))
566
2
    Features.push_back("+call-saved-x14");
567
568
1.42k
  if (Args.hasArg(options::OPT_fcall_saved_x15))
569
2
    Features.push_back("+call-saved-x15");
570
571
1.42k
  if (Args.hasArg(options::OPT_fcall_saved_x18))
572
3
    Features.push_back("+call-saved-x18");
573
574
1.42k
  if (Args.hasArg(options::OPT_mno_neg_immediates))
575
1
    Features.push_back("+no-neg-immediates");
576
577
1.42k
  if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
578
1.42k
                               options::OPT_mno_fix_cortex_a53_835769)) {
579
6
    if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769))
580
3
      Features.push_back("+fix-cortex-a53-835769");
581
3
    else
582
3
      Features.push_back("-fix-cortex-a53-835769");
583
1.41k
  } else if (Triple.isAndroid()) {
584
    // Enabled A53 errata (835769) workaround by default on android
585
52
    Features.push_back("+fix-cortex-a53-835769");
586
52
  }
587
1.42k
}