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,
42 AEK_DOTPROD
= 1 << 13,
45 AEK_FP16FML
= 1 << 16,
49 // Unsupported extensions.
51 AEK_IWMMXT
= 0x10000000,
52 AEK_IWMMXT2
= 0x20000000,
53 AEK_MAVERICK
= 0x40000000,
54 AEK_XSCALE
= 0x80000000,
57 // List of Arch Extension names.
58 // FIXME: TableGen this.
64 const char *NegFeature
;
66 StringRef
getName() const { return StringRef(NameCStr
, NameLength
); }
69 const ExtName ARCHExtNames
[] = {
70 #define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
71 {NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE},
72 #include "ARMTargetParser.def"
75 // List of HWDiv names (use getHWDivSynonym) and which architectural
76 // features they correspond to (use getHWDivFeatures).
77 // FIXME: TableGen this.
83 StringRef
getName() const { return StringRef(NameCStr
, NameLength
); }
85 #define ARM_HW_DIV_NAME(NAME, ID) {NAME, sizeof(NAME) - 1, ID},
86 #include "ARMTargetParser.def"
91 #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) ID,
92 #include "ARMTargetParser.def"
95 // List of CPU names and their arches.
96 // The same CPU can have multiple arches and can be default on multiple arches.
97 // When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
98 // When this becomes table-generated, we'd probably need two tables.
99 // FIXME: TableGen this.
100 template <typename T
> struct CpuNames
{
101 const char *NameCStr
;
104 bool Default
; // is $Name the default CPU for $ArchID ?
105 unsigned DefaultExtensions
;
107 StringRef
getName() const { return StringRef(NameCStr
, NameLength
); }
110 const CpuNames
<ArchKind
> CPUNames
[] = {
111 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
112 {NAME, sizeof(NAME) - 1, ARM::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT},
113 #include "ARMTargetParser.def"
118 #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) KIND,
119 #include "ARMTargetParser.def"
124 enum class FPUVersion
{
134 // An FPU name restricts the FPU in one of three ways:
135 enum class FPURestriction
{
136 None
= 0, ///< No restriction
137 D16
, ///< Only 16 D registers
138 SP_D16
///< Only single-precision instructions, with 16 D registers
141 // An FPU name implies one of three levels of Neon support:
142 enum class NeonSupportLevel
{
143 None
= 0, ///< No Neon
145 Crypto
///< Neon with Crypto
149 enum class ISAKind
{ INVALID
= 0, ARM
, THUMB
, AARCH64
};
152 // FIXME: BE8 vs. BE32?
153 enum class EndianKind
{ INVALID
= 0, LITTLE
, BIG
};
156 enum class ProfileKind
{ INVALID
= 0, A
, R
, M
};
158 // List of canonical FPU names (use getFPUSynonym) and which architectural
159 // features they correspond to (use getFPUFeatures).
160 // FIXME: TableGen this.
161 // The entries must appear in the order listed in ARM::FPUKind for correct
164 const char *NameCStr
;
168 NeonSupportLevel NeonSupport
;
169 FPURestriction Restriction
;
171 StringRef
getName() const { return StringRef(NameCStr
, NameLength
); }
174 static const FPUName FPUNames
[] = {
175 #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
176 {NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION},
177 #include "llvm/Support/ARMTargetParser.def"
180 // List of canonical arch names (use getArchSynonym).
181 // This table also provides the build attribute fields for CPU arch
182 // and Arch ID, according to the Addenda to the ARM ABI, chapters
183 // 2.4 and 2.3.5.2 respectively.
184 // FIXME: SubArch values were simplified to fit into the expectations
185 // of the triples and are not conforming with their official names.
186 // Check to see if the expectation should be changed.
187 // FIXME: TableGen this.
188 template <typename T
> struct ArchNames
{
189 const char *NameCStr
;
191 const char *CPUAttrCStr
;
192 size_t CPUAttrLength
;
193 const char *SubArchCStr
;
194 size_t SubArchLength
;
196 unsigned ArchBaseExtensions
;
198 ARMBuildAttrs::CPUArch ArchAttr
; // Arch ID in build attributes.
200 StringRef
getName() const { return StringRef(NameCStr
, NameLength
); }
202 // CPU class in build attributes.
203 StringRef
getCPUAttr() const { return StringRef(CPUAttrCStr
, CPUAttrLength
); }
206 StringRef
getSubArch() const { return StringRef(SubArchCStr
, SubArchLength
); }
209 static const ArchNames
<ArchKind
> ARCHNames
[] = {
210 #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, \
212 {NAME, sizeof(NAME) - 1, \
213 CPU_ATTR, sizeof(CPU_ATTR) - 1, \
214 SUB_ARCH, sizeof(SUB_ARCH) - 1, \
215 ARCH_FPU, ARCH_BASE_EXT, \
216 ArchKind::ID, ARCH_ATTR},
217 #include "llvm/Support/ARMTargetParser.def"
221 StringRef
getFPUName(unsigned FPUKind
);
222 FPUVersion
getFPUVersion(unsigned FPUKind
);
223 NeonSupportLevel
getFPUNeonSupportLevel(unsigned FPUKind
);
224 FPURestriction
getFPURestriction(unsigned FPUKind
);
226 // FIXME: These should be moved to TargetTuple once it exists
227 bool getFPUFeatures(unsigned FPUKind
, std::vector
<StringRef
> &Features
);
228 bool getHWDivFeatures(unsigned HWDivKind
, std::vector
<StringRef
> &Features
);
229 bool getExtensionFeatures(unsigned Extensions
,
230 std::vector
<StringRef
> &Features
);
232 StringRef
getArchName(ArchKind AK
);
233 unsigned getArchAttr(ArchKind AK
);
234 StringRef
getCPUAttr(ArchKind AK
);
235 StringRef
getSubArch(ArchKind AK
);
236 StringRef
getArchExtName(unsigned ArchExtKind
);
237 StringRef
getArchExtFeature(StringRef ArchExt
);
238 bool appendArchExtFeatures(StringRef CPU
, ARM::ArchKind AK
, StringRef ArchExt
,
239 std::vector
<StringRef
> &Features
);
240 StringRef
getHWDivName(unsigned HWDivKind
);
242 // Information by Name
243 unsigned getDefaultFPU(StringRef CPU
, ArchKind AK
);
244 unsigned getDefaultExtensions(StringRef CPU
, ArchKind AK
);
245 StringRef
getDefaultCPU(StringRef Arch
);
246 StringRef
getCanonicalArchName(StringRef Arch
);
247 StringRef
getFPUSynonym(StringRef FPU
);
248 StringRef
getArchSynonym(StringRef Arch
);
251 unsigned parseHWDiv(StringRef HWDiv
);
252 unsigned parseFPU(StringRef FPU
);
253 ArchKind
parseArch(StringRef Arch
);
254 unsigned parseArchExt(StringRef ArchExt
);
255 ArchKind
parseCPUArch(StringRef CPU
);
256 ISAKind
parseArchISA(StringRef Arch
);
257 EndianKind
parseArchEndian(StringRef Arch
);
258 ProfileKind
parseArchProfile(StringRef Arch
);
259 unsigned parseArchVersion(StringRef Arch
);
261 void fillValidCPUArchList(SmallVectorImpl
<StringRef
> &Values
);
262 StringRef
computeDefaultTargetABI(const Triple
&TT
, StringRef CPU
);