1//===-- TargetParser - Parser for target features ---------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements a target parser to recognise hardware features such as
11// FPU/CPU/ARCH names as well as specific support such as HDIV, etc.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_SUPPORT_TARGETPARSER_H
16#define LLVM_SUPPORT_TARGETPARSER_H
17
18// FIXME: vector is used because that's what clang uses for subtarget feature
19// lists, but SmallVector would probably be better
20#include "llvm/ADT/Triple.h"
21#include <vector>
22
23namespace llvm {
24class StringRef;
25
26// Target specific information into their own namespaces. These should be
27// generated from TableGen because the information is already there, and there
28// is where new information about targets will be added.
29// FIXME: To TableGen this we need to make some table generated files available
30// even if the back-end is not compiled with LLVM, plus we need to create a new
31// back-end to TableGen to create these clean tables.
32namespace ARM {
33
34// FPU Version
35enum class FPUVersion {
36  NONE,
37  VFPV2,
38  VFPV3,
39  VFPV3_FP16,
40  VFPV4,
41  VFPV5
42};
43
44// An FPU name restricts the FPU in one of three ways:
45enum class FPURestriction {
46  None = 0, ///< No restriction
47  D16,      ///< Only 16 D registers
48  SP_D16    ///< Only single-precision instructions, with 16 D registers
49};
50
51// An FPU name implies one of three levels of Neon support:
52enum class NeonSupportLevel {
53  None = 0, ///< No Neon
54  Neon,     ///< Neon
55  Crypto    ///< Neon with Crypto
56};
57
58// FPU names.
59enum FPUKind {
60#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) KIND,
61#include "ARMTargetParser.def"
62  FK_LAST
63};
64
65// Arch names.
66enum class ArchKind {
67#define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) ID,
68#include "ARMTargetParser.def"
69};
70
71// Arch extension modifiers for CPUs.
72enum ArchExtKind : unsigned {
73  AEK_INVALID =     0,
74  AEK_NONE =        1,
75  AEK_CRC =         1 << 1,
76  AEK_CRYPTO =      1 << 2,
77  AEK_FP =          1 << 3,
78  AEK_HWDIVTHUMB =  1 << 4,
79  AEK_HWDIVARM =    1 << 5,
80  AEK_MP =          1 << 6,
81  AEK_SIMD =        1 << 7,
82  AEK_SEC =         1 << 8,
83  AEK_VIRT =        1 << 9,
84  AEK_DSP =         1 << 10,
85  AEK_FP16 =        1 << 11,
86  AEK_RAS =         1 << 12,
87  AEK_SVE =         1 << 13,
88  AEK_DOTPROD =     1 << 14,
89  // Unsupported extensions.
90  AEK_OS = 0x8000000,
91  AEK_IWMMXT = 0x10000000,
92  AEK_IWMMXT2 = 0x20000000,
93  AEK_MAVERICK = 0x40000000,
94  AEK_XSCALE = 0x80000000,
95};
96
97// ISA kinds.
98enum class ISAKind { INVALID = 0, ARM, THUMB, AARCH64 };
99
100// Endianness
101// FIXME: BE8 vs. BE32?
102enum class EndianKind { INVALID = 0, LITTLE, BIG };
103
104// v6/v7/v8 Profile
105enum class ProfileKind { INVALID = 0, A, R, M };
106
107StringRef getCanonicalArchName(StringRef Arch);
108
109// Information by ID
110StringRef getFPUName(unsigned FPUKind);
111FPUVersion getFPUVersion(unsigned FPUKind);
112NeonSupportLevel getFPUNeonSupportLevel(unsigned FPUKind);
113FPURestriction getFPURestriction(unsigned FPUKind);
114
115// FIXME: These should be moved to TargetTuple once it exists
116bool getFPUFeatures(unsigned FPUKind, std::vector<StringRef> &Features);
117bool getHWDivFeatures(unsigned HWDivKind, std::vector<StringRef> &Features);
118bool getExtensionFeatures(unsigned Extensions,
119                          std::vector<StringRef> &Features);
120
121StringRef getArchName(ArchKind AK);
122unsigned getArchAttr(ArchKind AK);
123StringRef getCPUAttr(ArchKind AK);
124StringRef getSubArch(ArchKind AK);
125StringRef getArchExtName(unsigned ArchExtKind);
126StringRef getArchExtFeature(StringRef ArchExt);
127StringRef getHWDivName(unsigned HWDivKind);
128
129// Information by Name
130unsigned  getDefaultFPU(StringRef CPU, ArchKind AK);
131unsigned  getDefaultExtensions(StringRef CPU, ArchKind AK);
132StringRef getDefaultCPU(StringRef Arch);
133
134// Parser
135unsigned parseHWDiv(StringRef HWDiv);
136unsigned parseFPU(StringRef FPU);
137ArchKind parseArch(StringRef Arch);
138unsigned parseArchExt(StringRef ArchExt);
139ArchKind parseCPUArch(StringRef CPU);
140ISAKind parseArchISA(StringRef Arch);
141EndianKind parseArchEndian(StringRef Arch);
142ProfileKind parseArchProfile(StringRef Arch);
143unsigned parseArchVersion(StringRef Arch);
144
145StringRef computeDefaultTargetABI(const Triple &TT, StringRef CPU);
146
147} // namespace ARM
148
149// FIXME:This should be made into class design,to avoid dupplication.
150namespace AArch64 {
151
152// Arch names.
153enum class ArchKind {
154#define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) ID,
155#include "AArch64TargetParser.def"
156};
157
158// Arch extension modifiers for CPUs.
159enum ArchExtKind : unsigned {
160  AEK_INVALID =     0,
161  AEK_NONE =        1,
162  AEK_CRC =         1 << 1,
163  AEK_CRYPTO =      1 << 2,
164  AEK_FP =          1 << 3,
165  AEK_SIMD =        1 << 4,
166  AEK_FP16 =        1 << 5,
167  AEK_PROFILE =     1 << 6,
168  AEK_RAS =         1 << 7,
169  AEK_LSE =         1 << 8,
170  AEK_RDM =         1 << 9,
171  AEK_SVE =         1 << 10,
172  AEK_DOTPROD =     1 << 11,
173  AEK_RCPC =        1 << 12
174};
175
176StringRef getCanonicalArchName(StringRef Arch);
177
178// Information by ID
179StringRef getFPUName(unsigned FPUKind);
180ARM::FPUVersion getFPUVersion(unsigned FPUKind);
181ARM::NeonSupportLevel getFPUNeonSupportLevel(unsigned FPUKind);
182ARM::FPURestriction getFPURestriction(unsigned FPUKind);
183
184// FIXME: These should be moved to TargetTuple once it exists
185bool getFPUFeatures(unsigned FPUKind, std::vector<StringRef> &Features);
186bool getExtensionFeatures(unsigned Extensions,
187                                   std::vector<StringRef> &Features);
188bool getArchFeatures(ArchKind AK, std::vector<StringRef> &Features);
189
190StringRef getArchName(ArchKind AK);
191unsigned getArchAttr(ArchKind AK);
192StringRef getCPUAttr(ArchKind AK);
193StringRef getSubArch(ArchKind AK);
194StringRef getArchExtName(unsigned ArchExtKind);
195StringRef getArchExtFeature(StringRef ArchExt);
196unsigned checkArchVersion(StringRef Arch);
197
198// Information by Name
199unsigned  getDefaultFPU(StringRef CPU, ArchKind AK);
200unsigned  getDefaultExtensions(StringRef CPU, ArchKind AK);
201StringRef getDefaultCPU(StringRef Arch);
202
203// Parser
204unsigned parseFPU(StringRef FPU);
205AArch64::ArchKind parseArch(StringRef Arch);
206unsigned parseArchExt(StringRef ArchExt);
207ArchKind parseCPUArch(StringRef CPU);
208ARM::ISAKind parseArchISA(StringRef Arch);
209ARM::EndianKind parseArchEndian(StringRef Arch);
210ARM::ProfileKind parseArchProfile(StringRef Arch);
211unsigned parseArchVersion(StringRef Arch);
212
213} // namespace AArch64
214} // namespace llvm
215
216#endif
217