1 //===-- ARMTargetParser - Parser for ARM target features --------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements a target parser to recognise ARM hardware features
10 // such as FPU/CPU/ARCH/extensions and specific support such as HWDIV.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_SUPPORT_ARMTARGETPARSER_H
15 #define LLVM_SUPPORT_ARMTARGETPARSER_H
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/Support/ARMBuildAttributes.h"
25 // Arch extension modifiers for CPUs.
26 // Note that this is not the same as the AArch64 list
27 enum ArchExtKind
: unsigned {
33 AEK_HWDIVTHUMB
= 1 << 4,
34 AEK_HWDIVARM
= 1 << 5,
43 AEK_DOTPROD
= 1 << 14,
46 AEK_FP16FML
= 1 << 17,
49 AEK_SVE2AES
= 1 << 20,
50 AEK_SVE2SM4
= 1 << 21,
51 AEK_SVE2SHA3
= 1 << 22,
52 AEK_BITPERM
= 1 << 23,
55 // Unsupported extensions.
57 AEK_IWMMXT
= 0x10000000,
58 AEK_IWMMXT2
= 0x20000000,
59 AEK_MAVERICK
= 0x40000000,
60 AEK_XSCALE
= 0x80000000,
63 // List of Arch Extension names.
64 // FIXME: TableGen this.
70 const char *NegFeature
;
72 StringRef
getName() const { return StringRef(NameCStr
, NameLength
); }
75 const ExtName ARCHExtNames
[] = {
76 #define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
77 {NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE},
78 #include "ARMTargetParser.def"
81 // List of HWDiv names (use getHWDivSynonym) and which architectural
82 // features they correspond to (use getHWDivFeatures).
83 // FIXME: TableGen this.
89 StringRef
getName() const { return StringRef(NameCStr
, NameLength
); }
91 #define ARM_HW_DIV_NAME(NAME, ID) {NAME, sizeof(NAME) - 1, ID},
92 #include "ARMTargetParser.def"
97 #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) ID,
98 #include "ARMTargetParser.def"
101 // List of CPU names and their arches.
102 // The same CPU can have multiple arches and can be default on multiple arches.
103 // When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
104 // When this becomes table-generated, we'd probably need two tables.
105 // FIXME: TableGen this.
106 template <typename T
> struct CpuNames
{
107 const char *NameCStr
;
110 bool Default
; // is $Name the default CPU for $ArchID ?
111 unsigned DefaultExtensions
;
113 StringRef
getName() const { return StringRef(NameCStr
, NameLength
); }
116 const CpuNames
<ArchKind
> CPUNames
[] = {
117 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
118 {NAME, sizeof(NAME) - 1, ARM::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT},
119 #include "ARMTargetParser.def"
124 #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) KIND,
125 #include "ARMTargetParser.def"
130 enum class FPUVersion
{
140 // An FPU name restricts the FPU in one of three ways:
141 enum class FPURestriction
{
142 None
= 0, ///< No restriction
143 D16
, ///< Only 16 D registers
144 SP_D16
///< Only single-precision instructions, with 16 D registers
147 // An FPU name implies one of three levels of Neon support:
148 enum class NeonSupportLevel
{
149 None
= 0, ///< No Neon
151 Crypto
///< Neon with Crypto
155 enum class ISAKind
{ INVALID
= 0, ARM
, THUMB
, AARCH64
};
158 // FIXME: BE8 vs. BE32?
159 enum class EndianKind
{ INVALID
= 0, LITTLE
, BIG
};
162 enum class ProfileKind
{ INVALID
= 0, A
, R
, M
};
164 // List of canonical FPU names (use getFPUSynonym) and which architectural
165 // features they correspond to (use getFPUFeatures).
166 // FIXME: TableGen this.
167 // The entries must appear in the order listed in ARM::FPUKind for correct
170 const char *NameCStr
;
174 NeonSupportLevel NeonSupport
;
175 FPURestriction Restriction
;
177 StringRef
getName() const { return StringRef(NameCStr
, NameLength
); }
180 static const FPUName FPUNames
[] = {
181 #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
182 {NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION},
183 #include "llvm/Support/ARMTargetParser.def"
186 // List of canonical arch names (use getArchSynonym).
187 // This table also provides the build attribute fields for CPU arch
188 // and Arch ID, according to the Addenda to the ARM ABI, chapters
189 // 2.4 and 2.3.5.2 respectively.
190 // FIXME: SubArch values were simplified to fit into the expectations
191 // of the triples and are not conforming with their official names.
192 // Check to see if the expectation should be changed.
193 // FIXME: TableGen this.
194 template <typename T
> struct ArchNames
{
195 const char *NameCStr
;
197 const char *CPUAttrCStr
;
198 size_t CPUAttrLength
;
199 const char *SubArchCStr
;
200 size_t SubArchLength
;
202 unsigned ArchBaseExtensions
;
204 ARMBuildAttrs::CPUArch ArchAttr
; // Arch ID in build attributes.
206 StringRef
getName() const { return StringRef(NameCStr
, NameLength
); }
208 // CPU class in build attributes.
209 StringRef
getCPUAttr() const { return StringRef(CPUAttrCStr
, CPUAttrLength
); }
212 StringRef
getSubArch() const { return StringRef(SubArchCStr
, SubArchLength
); }
215 static const ArchNames
<ArchKind
> ARCHNames
[] = {
216 #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, \
218 {NAME, sizeof(NAME) - 1, \
219 CPU_ATTR, sizeof(CPU_ATTR) - 1, \
220 SUB_ARCH, sizeof(SUB_ARCH) - 1, \
221 ARCH_FPU, ARCH_BASE_EXT, \
222 ArchKind::ID, ARCH_ATTR},
223 #include "llvm/Support/ARMTargetParser.def"
227 StringRef
getFPUName(unsigned FPUKind
);
228 FPUVersion
getFPUVersion(unsigned FPUKind
);
229 NeonSupportLevel
getFPUNeonSupportLevel(unsigned FPUKind
);
230 FPURestriction
getFPURestriction(unsigned FPUKind
);
232 // FIXME: These should be moved to TargetTuple once it exists
233 bool getFPUFeatures(unsigned FPUKind
, std::vector
<StringRef
> &Features
);
234 bool getHWDivFeatures(unsigned HWDivKind
, std::vector
<StringRef
> &Features
);
235 bool getExtensionFeatures(unsigned Extensions
,
236 std::vector
<StringRef
> &Features
);
238 StringRef
getArchName(ArchKind AK
);
239 unsigned getArchAttr(ArchKind AK
);
240 StringRef
getCPUAttr(ArchKind AK
);
241 StringRef
getSubArch(ArchKind AK
);
242 StringRef
getArchExtName(unsigned ArchExtKind
);
243 StringRef
getArchExtFeature(StringRef ArchExt
);
244 bool appendArchExtFeatures(StringRef CPU
, ARM::ArchKind AK
, StringRef ArchExt
,
245 std::vector
<StringRef
> &Features
);
246 StringRef
getHWDivName(unsigned HWDivKind
);
248 // Information by Name
249 unsigned getDefaultFPU(StringRef CPU
, ArchKind AK
);
250 unsigned getDefaultExtensions(StringRef CPU
, ArchKind AK
);
251 StringRef
getDefaultCPU(StringRef Arch
);
252 StringRef
getCanonicalArchName(StringRef Arch
);
253 StringRef
getFPUSynonym(StringRef FPU
);
254 StringRef
getArchSynonym(StringRef Arch
);
257 unsigned parseHWDiv(StringRef HWDiv
);
258 unsigned parseFPU(StringRef FPU
);
259 ArchKind
parseArch(StringRef Arch
);
260 unsigned parseArchExt(StringRef ArchExt
);
261 ArchKind
parseCPUArch(StringRef CPU
);
262 ISAKind
parseArchISA(StringRef Arch
);
263 EndianKind
parseArchEndian(StringRef Arch
);
264 ProfileKind
parseArchProfile(StringRef Arch
);
265 unsigned parseArchVersion(StringRef Arch
);
267 void fillValidCPUArchList(SmallVectorImpl
<StringRef
> &Values
);
268 StringRef
computeDefaultTargetABI(const Triple
&TT
, StringRef CPU
);