//===-- TargetParser - Parser for target features ---------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements a target parser to recognise hardware features such as // FPU/CPU/ARCH names as well as specific support such as HDIV, etc. // //===----------------------------------------------------------------------===// #ifndef LLVM_SUPPORT_TARGETPARSER_H #define LLVM_SUPPORT_TARGETPARSER_H // FIXME: vector is used because that's what clang uses for subtarget feature // lists, but SmallVector would probably be better #include "llvm/ADT/Triple.h" #include namespace llvm { class StringRef; // Target specific information into their own namespaces. These should be // generated from TableGen because the information is already there, and there // is where new information about targets will be added. // FIXME: To TableGen this we need to make some table generated files available // even if the back-end is not compiled with LLVM, plus we need to create a new // back-end to TableGen to create these clean tables. namespace ARM { // FPU Version enum class FPUVersion { NONE, VFPV2, VFPV3, VFPV3_FP16, VFPV4, VFPV5 }; // An FPU name restricts the FPU in one of three ways: enum class FPURestriction { None = 0, ///< No restriction D16, ///< Only 16 D registers SP_D16 ///< Only single-precision instructions, with 16 D registers }; // An FPU name implies one of three levels of Neon support: enum class NeonSupportLevel { None = 0, ///< No Neon Neon, ///< Neon Crypto ///< Neon with Crypto }; // FPU names. enum FPUKind { #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) KIND, #include "ARMTargetParser.def" FK_LAST }; // Arch names. enum class ArchKind { #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) ID, #include "ARMTargetParser.def" }; // Arch extension modifiers for CPUs. enum ArchExtKind : unsigned { AEK_INVALID = 0, AEK_NONE = 1, AEK_CRC = 1 << 1, AEK_CRYPTO = 1 << 2, AEK_FP = 1 << 3, AEK_HWDIVTHUMB = 1 << 4, AEK_HWDIVARM = 1 << 5, AEK_MP = 1 << 6, AEK_SIMD = 1 << 7, AEK_SEC = 1 << 8, AEK_VIRT = 1 << 9, AEK_DSP = 1 << 10, AEK_FP16 = 1 << 11, AEK_RAS = 1 << 12, AEK_SVE = 1 << 13, AEK_DOTPROD = 1 << 14, // Unsupported extensions. AEK_OS = 0x8000000, AEK_IWMMXT = 0x10000000, AEK_IWMMXT2 = 0x20000000, AEK_MAVERICK = 0x40000000, AEK_XSCALE = 0x80000000, }; // ISA kinds. enum class ISAKind { INVALID = 0, ARM, THUMB, AARCH64 }; // Endianness // FIXME: BE8 vs. BE32? enum class EndianKind { INVALID = 0, LITTLE, BIG }; // v6/v7/v8 Profile enum class ProfileKind { INVALID = 0, A, R, M }; StringRef getCanonicalArchName(StringRef Arch); // Information by ID StringRef getFPUName(unsigned FPUKind); FPUVersion getFPUVersion(unsigned FPUKind); NeonSupportLevel getFPUNeonSupportLevel(unsigned FPUKind); FPURestriction getFPURestriction(unsigned FPUKind); // FIXME: These should be moved to TargetTuple once it exists bool getFPUFeatures(unsigned FPUKind, std::vector &Features); bool getHWDivFeatures(unsigned HWDivKind, std::vector &Features); bool getExtensionFeatures(unsigned Extensions, std::vector &Features); StringRef getArchName(ArchKind AK); unsigned getArchAttr(ArchKind AK); StringRef getCPUAttr(ArchKind AK); StringRef getSubArch(ArchKind AK); StringRef getArchExtName(unsigned ArchExtKind); StringRef getArchExtFeature(StringRef ArchExt); StringRef getHWDivName(unsigned HWDivKind); // Information by Name unsigned getDefaultFPU(StringRef CPU, ArchKind AK); unsigned getDefaultExtensions(StringRef CPU, ArchKind AK); StringRef getDefaultCPU(StringRef Arch); // Parser unsigned parseHWDiv(StringRef HWDiv); unsigned parseFPU(StringRef FPU); ArchKind parseArch(StringRef Arch); unsigned parseArchExt(StringRef ArchExt); ArchKind parseCPUArch(StringRef CPU); ISAKind parseArchISA(StringRef Arch); EndianKind parseArchEndian(StringRef Arch); ProfileKind parseArchProfile(StringRef Arch); unsigned parseArchVersion(StringRef Arch); StringRef computeDefaultTargetABI(const Triple &TT, StringRef CPU); } // namespace ARM // FIXME:This should be made into class design,to avoid dupplication. namespace AArch64 { // Arch names. enum class ArchKind { #define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) ID, #include "AArch64TargetParser.def" }; // Arch extension modifiers for CPUs. enum ArchExtKind : unsigned { AEK_INVALID = 0, AEK_NONE = 1, AEK_CRC = 1 << 1, AEK_CRYPTO = 1 << 2, AEK_FP = 1 << 3, AEK_SIMD = 1 << 4, AEK_FP16 = 1 << 5, AEK_PROFILE = 1 << 6, AEK_RAS = 1 << 7, AEK_LSE = 1 << 8, AEK_SVE = 1 << 9, AEK_DOTPROD = 1 << 10, AEK_RCPC = 1 << 11, AEK_RDM = 1 << 12 }; StringRef getCanonicalArchName(StringRef Arch); // Information by ID StringRef getFPUName(unsigned FPUKind); ARM::FPUVersion getFPUVersion(unsigned FPUKind); ARM::NeonSupportLevel getFPUNeonSupportLevel(unsigned FPUKind); ARM::FPURestriction getFPURestriction(unsigned FPUKind); // FIXME: These should be moved to TargetTuple once it exists bool getFPUFeatures(unsigned FPUKind, std::vector &Features); bool getExtensionFeatures(unsigned Extensions, std::vector &Features); bool getArchFeatures(ArchKind AK, std::vector &Features); StringRef getArchName(ArchKind AK); unsigned getArchAttr(ArchKind AK); StringRef getCPUAttr(ArchKind AK); StringRef getSubArch(ArchKind AK); StringRef getArchExtName(unsigned ArchExtKind); StringRef getArchExtFeature(StringRef ArchExt); unsigned checkArchVersion(StringRef Arch); // Information by Name unsigned getDefaultFPU(StringRef CPU, ArchKind AK); unsigned getDefaultExtensions(StringRef CPU, ArchKind AK); StringRef getDefaultCPU(StringRef Arch); // Parser unsigned parseFPU(StringRef FPU); AArch64::ArchKind parseArch(StringRef Arch); unsigned parseArchExt(StringRef ArchExt); ArchKind parseCPUArch(StringRef CPU); ARM::ISAKind parseArchISA(StringRef Arch); ARM::EndianKind parseArchEndian(StringRef Arch); ARM::ProfileKind parseArchProfile(StringRef Arch); unsigned parseArchVersion(StringRef Arch); } // namespace AArch64 namespace X86 { // This should be kept in sync with libcc/compiler-rt as its included by clang // as a proxy for what's in libgcc/compiler-rt. enum ProcessorVendors : unsigned { VENDOR_DUMMY, #define X86_VENDOR(ENUM, STRING) \ ENUM, #include "llvm/Support/X86TargetParser.def" VENDOR_OTHER }; // This should be kept in sync with libcc/compiler-rt as its included by clang // as a proxy for what's in libgcc/compiler-rt. enum ProcessorTypes : unsigned { CPU_TYPE_DUMMY, #define X86_CPU_TYPE(ARCHNAME, ENUM) \ ENUM, #include "llvm/Support/X86TargetParser.def" CPU_TYPE_MAX }; // This should be kept in sync with libcc/compiler-rt as its included by clang // as a proxy for what's in libgcc/compiler-rt. enum ProcessorSubtypes : unsigned { CPU_SUBTYPE_DUMMY, #define X86_CPU_SUBTYPE(ARCHNAME, ENUM) \ ENUM, #include "llvm/Support/X86TargetParser.def" CPU_SUBTYPE_MAX }; // This should be kept in sync with libcc/compiler-rt as it should be used // by clang as a proxy for what's in libgcc/compiler-rt. enum ProcessorFeatures { #define X86_FEATURE(VAL, ENUM) \ ENUM = VAL, #include "llvm/Support/X86TargetParser.def" }; } // namespace X86 } // namespace llvm #endif