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,
48 // Unsupported extensions.
50 AEK_IWMMXT
= 0x10000000,
51 AEK_IWMMXT2
= 0x20000000,
52 AEK_MAVERICK
= 0x40000000,
53 AEK_XSCALE
= 0x80000000,
56 // List of Arch Extension names.
57 // FIXME: TableGen this.
63 const char *NegFeature
;
65 StringRef
getName() const { return StringRef(NameCStr
, NameLength
); }
68 const ExtName ARCHExtNames
[] = {
69 #define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
70 {NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE},
71 #include "ARMTargetParser.def"
74 // List of HWDiv names (use getHWDivSynonym) and which architectural
75 // features they correspond to (use getHWDivFeatures).
76 // FIXME: TableGen this.
82 StringRef
getName() const { return StringRef(NameCStr
, NameLength
); }
84 #define ARM_HW_DIV_NAME(NAME, ID) {NAME, sizeof(NAME) - 1, ID},
85 #include "ARMTargetParser.def"
90 #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) ID,
91 #include "ARMTargetParser.def"
94 // List of CPU names and their arches.
95 // The same CPU can have multiple arches and can be default on multiple arches.
96 // When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
97 // When this becomes table-generated, we'd probably need two tables.
98 // FIXME: TableGen this.
99 template <typename T
> struct CpuNames
{
100 const char *NameCStr
;
103 bool Default
; // is $Name the default CPU for $ArchID ?
104 unsigned DefaultExtensions
;
106 StringRef
getName() const { return StringRef(NameCStr
, NameLength
); }
109 const CpuNames
<ArchKind
> CPUNames
[] = {
110 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
111 {NAME, sizeof(NAME) - 1, ARM::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT},
112 #include "ARMTargetParser.def"
117 #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) KIND,
118 #include "ARMTargetParser.def"
123 enum class FPUVersion
{
132 // An FPU name restricts the FPU in one of three ways:
133 enum class FPURestriction
{
134 None
= 0, ///< No restriction
135 D16
, ///< Only 16 D registers
136 SP_D16
///< Only single-precision instructions, with 16 D registers
139 // An FPU name implies one of three levels of Neon support:
140 enum class NeonSupportLevel
{
141 None
= 0, ///< No Neon
143 Crypto
///< Neon with Crypto
147 enum class ISAKind
{ INVALID
= 0, ARM
, THUMB
, AARCH64
};
150 // FIXME: BE8 vs. BE32?
151 enum class EndianKind
{ INVALID
= 0, LITTLE
, BIG
};
154 enum class ProfileKind
{ INVALID
= 0, A
, R
, M
};
156 // List of canonical FPU names (use getFPUSynonym) and which architectural
157 // features they correspond to (use getFPUFeatures).
158 // FIXME: TableGen this.
159 // The entries must appear in the order listed in ARM::FPUKind for correct
162 const char *NameCStr
;
166 NeonSupportLevel NeonSupport
;
167 FPURestriction Restriction
;
169 StringRef
getName() const { return StringRef(NameCStr
, NameLength
); }
172 static const FPUName FPUNames
[] = {
173 #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
174 {NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION},
175 #include "llvm/Support/ARMTargetParser.def"
178 // List of canonical arch names (use getArchSynonym).
179 // This table also provides the build attribute fields for CPU arch
180 // and Arch ID, according to the Addenda to the ARM ABI, chapters
181 // 2.4 and 2.3.5.2 respectively.
182 // FIXME: SubArch values were simplified to fit into the expectations
183 // of the triples and are not conforming with their official names.
184 // Check to see if the expectation should be changed.
185 // FIXME: TableGen this.
186 template <typename T
> struct ArchNames
{
187 const char *NameCStr
;
189 const char *CPUAttrCStr
;
190 size_t CPUAttrLength
;
191 const char *SubArchCStr
;
192 size_t SubArchLength
;
194 unsigned ArchBaseExtensions
;
196 ARMBuildAttrs::CPUArch ArchAttr
; // Arch ID in build attributes.
198 StringRef
getName() const { return StringRef(NameCStr
, NameLength
); }
200 // CPU class in build attributes.
201 StringRef
getCPUAttr() const { return StringRef(CPUAttrCStr
, CPUAttrLength
); }
204 StringRef
getSubArch() const { return StringRef(SubArchCStr
, SubArchLength
); }
207 static const ArchNames
<ArchKind
> ARCHNames
[] = {
208 #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, \
210 {NAME, sizeof(NAME) - 1, \
211 CPU_ATTR, sizeof(CPU_ATTR) - 1, \
212 SUB_ARCH, sizeof(SUB_ARCH) - 1, \
213 ARCH_FPU, ARCH_BASE_EXT, \
214 ArchKind::ID, ARCH_ATTR},
215 #include "llvm/Support/ARMTargetParser.def"
219 StringRef
getFPUName(unsigned FPUKind
);
220 FPUVersion
getFPUVersion(unsigned FPUKind
);
221 NeonSupportLevel
getFPUNeonSupportLevel(unsigned FPUKind
);
222 FPURestriction
getFPURestriction(unsigned FPUKind
);
224 // FIXME: These should be moved to TargetTuple once it exists
225 bool getFPUFeatures(unsigned FPUKind
, std::vector
<StringRef
> &Features
);
226 bool getHWDivFeatures(unsigned HWDivKind
, std::vector
<StringRef
> &Features
);
227 bool getExtensionFeatures(unsigned Extensions
,
228 std::vector
<StringRef
> &Features
);
230 StringRef
getArchName(ArchKind AK
);
231 unsigned getArchAttr(ArchKind AK
);
232 StringRef
getCPUAttr(ArchKind AK
);
233 StringRef
getSubArch(ArchKind AK
);
234 StringRef
getArchExtName(unsigned ArchExtKind
);
235 StringRef
getArchExtFeature(StringRef ArchExt
);
236 StringRef
getHWDivName(unsigned HWDivKind
);
238 // Information by Name
239 unsigned getDefaultFPU(StringRef CPU
, ArchKind AK
);
240 unsigned getDefaultExtensions(StringRef CPU
, ArchKind AK
);
241 StringRef
getDefaultCPU(StringRef Arch
);
242 StringRef
getCanonicalArchName(StringRef Arch
);
243 StringRef
getFPUSynonym(StringRef FPU
);
244 StringRef
getArchSynonym(StringRef Arch
);
247 unsigned parseHWDiv(StringRef HWDiv
);
248 unsigned parseFPU(StringRef FPU
);
249 ArchKind
parseArch(StringRef Arch
);
250 unsigned parseArchExt(StringRef ArchExt
);
251 ArchKind
parseCPUArch(StringRef CPU
);
252 ISAKind
parseArchISA(StringRef Arch
);
253 EndianKind
parseArchEndian(StringRef Arch
);
254 ProfileKind
parseArchProfile(StringRef Arch
);
255 unsigned parseArchVersion(StringRef Arch
);
257 void fillValidCPUArchList(SmallVectorImpl
<StringRef
> &Values
);
258 StringRef
computeDefaultTargetABI(const Triple
&TT
, StringRef CPU
);