Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Support/AArch64TargetParser.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- AArch64TargetParser - Parser for AArch64 features -------*- 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
// This file implements a target parser to recognise AArch64 hardware features
10
// such as FPU/CPU/ARCH and extension names.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "llvm/Support/AArch64TargetParser.h"
15
#include "llvm/ADT/StringRef.h"
16
#include "llvm/ADT/StringSwitch.h"
17
#include <cctype>
18
19
using namespace llvm;
20
21
322
static unsigned checkArchVersion(llvm::StringRef Arch) {
22
322
  if (Arch.size() >= 2 && Arch[0] == 'v' && 
std::isdigit(Arch[1])319
)
23
319
    return (Arch[1] - 48);
24
3
  return 0;
25
3
}
26
27
0
unsigned AArch64::getDefaultFPU(StringRef CPU, AArch64::ArchKind AK) {
28
0
  if (CPU == "generic")
29
0
    return AArch64ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
30
0
31
0
  return StringSwitch<unsigned>(CPU)
32
0
#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)       \
33
0
  .Case(NAME, ARM::DEFAULT_FPU)
34
0
#include "../../include/llvm/Support/AArch64TargetParser.def"
35
0
  .Default(ARM::FK_INVALID);
36
0
}
37
38
22.8k
unsigned AArch64::getDefaultExtensions(StringRef CPU, AArch64::ArchKind AK) {
39
22.8k
  if (CPU == "generic")
40
37
    return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
41
22.7k
42
22.7k
  return StringSwitch<unsigned>(CPU)
43
22.7k
#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)       \
44
569k
  .Case(NAME, AArch64ARCHNames[static_cast<unsigned>(ArchKind::ID)]            \
45
569k
                      .ArchBaseExtensions |                                    \
46
569k
                  DEFAULT_EXT)
47
22.7k
#include "../../include/llvm/Support/AArch64TargetParser.def"
48
22.7k
  .Default(AArch64::AEK_INVALID);
49
22.7k
}
50
51
36
AArch64::ArchKind AArch64::getCPUArchKind(StringRef CPU) {
52
36
  if (CPU == "generic")
53
36
    return ArchKind::ARMV8A;
54
0
55
0
  return StringSwitch<AArch64::ArchKind>(CPU)
56
0
#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)       \
57
0
  .Case(NAME, ArchKind::ID)
58
0
#include "../../include/llvm/Support/AArch64TargetParser.def"
59
0
  .Default(ArchKind::INVALID);
60
0
}
61
62
bool AArch64::getExtensionFeatures(unsigned Extensions,
63
22.7k
                                   std::vector<StringRef> &Features) {
64
22.7k
  if (Extensions == AArch64::AEK_INVALID)
65
1
    return false;
66
22.7k
67
22.7k
  if (Extensions & AEK_FP)
68
22.7k
    Features.push_back("+fp-armv8");
69
22.7k
  if (Extensions & AEK_SIMD)
70
22.7k
    Features.push_back("+neon");
71
22.7k
  if (Extensions & AEK_CRC)
72
593
    Features.push_back("+crc");
73
22.7k
  if (Extensions & AEK_CRYPTO)
74
22.7k
    Features.push_back("+crypto");
75
22.7k
  if (Extensions & AEK_DOTPROD)
76
169
    Features.push_back("+dotprod");
77
22.7k
  if (Extensions & AEK_FP16FML)
78
1
    Features.push_back("+fp16fml");
79
22.7k
  if (Extensions & AEK_FP16)
80
169
    Features.push_back("+fullfp16");
81
22.7k
  if (Extensions & AEK_PROFILE)
82
1
    Features.push_back("+spe");
83
22.7k
  if (Extensions & AEK_RAS)
84
169
    Features.push_back("+ras");
85
22.7k
  if (Extensions & AEK_LSE)
86
212
    Features.push_back("+lse");
87
22.7k
  if (Extensions & AEK_RDM)
88
231
    Features.push_back("+rdm");
89
22.7k
  if (Extensions & AEK_SVE)
90
1
    Features.push_back("+sve");
91
22.7k
  if (Extensions & AEK_SVE2)
92
1
    Features.push_back("+sve2");
93
22.7k
  if (Extensions & AEK_SVE2AES)
94
1
    Features.push_back("+sve2-aes");
95
22.7k
  if (Extensions & AEK_SVE2SM4)
96
1
    Features.push_back("+sve2-sm4");
97
22.7k
  if (Extensions & AEK_SVE2SHA3)
98
1
    Features.push_back("+sve2-sha3");
99
22.7k
  if (Extensions & AEK_BITPERM)
100
1
    Features.push_back("+bitperm");
101
22.7k
  if (Extensions & AEK_RCPC)
102
99
    Features.push_back("+rcpc");
103
22.7k
104
22.7k
  return true;
105
22.7k
}
106
107
bool AArch64::getArchFeatures(AArch64::ArchKind AK,
108
23.0k
                              std::vector<StringRef> &Features) {
109
23.0k
  if (AK == ArchKind::ARMV8_1A)
110
79
    Features.push_back("+v8.1a");
111
23.0k
  if (AK == ArchKind::ARMV8_2A)
112
252
    Features.push_back("+v8.2a");
113
23.0k
  if (AK == ArchKind::ARMV8_3A)
114
42
    Features.push_back("+v8.3a");
115
23.0k
  if (AK == ArchKind::ARMV8_4A)
116
48
    Features.push_back("+v8.4a");
117
23.0k
  if (AK == ArchKind::ARMV8_5A)
118
23
    Features.push_back("+v8.5a");
119
23.0k
120
23.0k
  return AK != ArchKind::INVALID;
121
23.0k
}
122
123
25
StringRef AArch64::getArchName(AArch64::ArchKind AK) {
124
25
  return AArch64ARCHNames[static_cast<unsigned>(AK)].getName();
125
25
}
126
127
25
StringRef AArch64::getCPUAttr(AArch64::ArchKind AK) {
128
25
  return AArch64ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
129
25
}
130
131
6
StringRef AArch64::getSubArch(AArch64::ArchKind AK) {
132
6
  return AArch64ARCHNames[static_cast<unsigned>(AK)].getSubArch();
133
6
}
134
135
6
unsigned AArch64::getArchAttr(AArch64::ArchKind AK) {
136
6
  return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
137
6
}
138
139
0
StringRef AArch64::getArchExtName(unsigned ArchExtKind) {
140
0
  for (const auto &AE : AArch64ARCHExtNames)
141
0
    if (ArchExtKind == AE.ID)
142
0
      return AE.getName();
143
0
  return StringRef();
144
0
}
145
146
329
StringRef AArch64::getArchExtFeature(StringRef ArchExt) {
147
329
  if (ArchExt.startswith("no")) {
148
139
    StringRef ArchExtBase(ArchExt.substr(2));
149
1.84k
    for (const auto &AE : AArch64ARCHExtNames) {
150
1.84k
      if (AE.NegFeature && 
ArchExtBase == AE.getName()1.56k
)
151
136
        return StringRef(AE.NegFeature);
152
1.84k
    }
153
139
  }
154
329
155
329
  
for (const auto &AE : AArch64ARCHExtNames)193
156
2.64k
    if (AE.Feature && 
ArchExt == AE.getName()2.26k
)
157
187
      return StringRef(AE.Feature);
158
193
  
return StringRef()6
;
159
193
}
160
161
6
StringRef AArch64::getDefaultCPU(StringRef Arch) {
162
6
  ArchKind AK = parseArch(Arch);
163
6
  if (AK == ArchKind::INVALID)
164
0
    return StringRef();
165
6
166
6
  // Look for multiple AKs to find the default for pair AK+Name.
167
6
  for (const auto &CPU : AArch64CPUNames)
168
127
    if (CPU.ArchID == AK && 
CPU.Default11
)
169
1
      return CPU.getName();
170
6
171
6
  // If we can't find a default then target the architecture instead
172
6
  
return "generic"5
;
173
6
}
174
175
2
void AArch64::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
176
50
  for (const auto &Arch : AArch64CPUNames) {
177
50
    if (Arch.ArchID != ArchKind::INVALID)
178
48
      Values.push_back(Arch.getName());
179
50
  }
180
2
}
181
182
9.10k
bool AArch64::isX18ReservedByDefault(const Triple &TT) {
183
9.10k
  return TT.isAndroid() || 
TT.isOSDarwin()9.08k
||
TT.isOSFuchsia()1.56k
||
184
9.10k
         
TT.isOSWindows()1.55k
;
185
9.10k
}
186
187
// Allows partial match, ex. "v8a" matches "armv8a".
188
322
AArch64::ArchKind AArch64::parseArch(StringRef Arch) {
189
322
  Arch = ARM::getCanonicalArchName(Arch);
190
322
  if (checkArchVersion(Arch) < 8)
191
3
    return ArchKind::INVALID;
192
319
193
319
  StringRef Syn = ARM::getArchSynonym(Arch);
194
1.29k
  for (const auto A : AArch64ARCHNames) {
195
1.29k
    if (A.getName().endswith(Syn))
196
319
      return A.ID;
197
1.29k
  }
198
319
  
return ArchKind::INVALID0
;
199
319
}
200
201
58
AArch64::ArchExtKind AArch64::parseArchExt(StringRef ArchExt) {
202
738
  for (const auto A : AArch64ARCHExtNames) {
203
738
    if (ArchExt == A.getName())
204
58
      return static_cast<ArchExtKind>(A.ID);
205
738
  }
206
58
  
return AArch64::AEK_INVALID0
;
207
58
}
208
209
30.0k
AArch64::ArchKind AArch64::parseCPUArch(StringRef CPU) {
210
299k
  for (const auto C : AArch64CPUNames) {
211
299k
    if (CPU == C.getName())
212
30.0k
      return C.ArchID;
213
299k
  }
214
30.0k
  
return ArchKind::INVALID5
;
215
30.0k
}