Added arch extensions and default target features in TargetParser.
[oota-llvm.git] / lib / Support / TargetParser.cpp
index 3280035dca9457210b3c21c814491a50d5d91f6b..b2bf980cf6d41290def57ca2b718a774235a9abf 100644 (file)
@@ -59,6 +59,7 @@ struct {
   const char *SubArchCStr;
   size_t SubArchLength;
   ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
+  unsigned ArchBaseExtensions;
 
   StringRef getName() const { return StringRef(NameCStr, NameLength); }
 
@@ -68,9 +69,9 @@ struct {
   // Sub-Arch name.
   StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
 } ARCHNames[] = {
-#define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR)                      \
+#define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_BASE_EXT)       \
   {NAME, sizeof(NAME) - 1, ID, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH,       \
-   sizeof(SUB_ARCH) - 1, ARCH_ATTR},
+   sizeof(SUB_ARCH) - 1, ARCH_ATTR, ARCH_BASE_EXT},
 #include "llvm/Support/ARMTargetParser.def"
 };
 
@@ -110,13 +111,13 @@ struct {
   const char *NameCStr;
   size_t NameLength;
   ARM::ArchKind ArchID;
-  ARM::FPUKind DefaultFPU;
   bool Default; // is $Name the default CPU for $ArchID ?
+  unsigned DefaultExtensions;
 
   StringRef getName() const { return StringRef(NameCStr, NameLength); }
 } CPUNames[] = {
-#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT) \
-  { NAME, sizeof(NAME) - 1, ID, DEFAULT_FPU, IS_DEFAULT },
+#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
+  { NAME, sizeof(NAME) - 1, ID, IS_DEFAULT, DEFAULT_EXT },
 #include "llvm/Support/ARMTargetParser.def"
 };
 
@@ -151,11 +152,11 @@ unsigned llvm::ARM::getFPURestriction(unsigned FPUKind) {
 }
 
 unsigned llvm::ARM::getDefaultFPU(StringRef CPU) {
-  for (const auto C : CPUNames) {
-    if (CPU == C.getName())
-      return C.DefaultFPU;
-  }
-  return ARM::FK_INVALID;
+  return StringSwitch<unsigned>(CPU)
+#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
+    .Case(NAME, DEFAULT_FPU)
+#include "llvm/Support/ARMTargetParser.def"
+    .Default(ARM::FK_INVALID);
 }
 
 bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
@@ -177,6 +178,20 @@ bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
   return true;
 }
 
+bool llvm::ARM::getExtensionFeatures(unsigned Extensions,
+                                     std::vector<const char *> &Features) {
+
+  if (Extensions == ARM::AEK_INVALID)
+    return false;
+
+  if (Extensions & ARM::AEK_CRC)
+    Features.push_back("+crc");
+  else
+    Features.push_back("-crc");
+
+  return getHWDivFeatures(Extensions, Features);
+}
+
 bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
                                std::vector<const char *> &Features) {
 
@@ -243,6 +258,7 @@ bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
   // crypto includes neon, so we handle this similarly to FPU version.
   switch (FPUNames[FPUKind].NeonSupport) {
   case ARM::NS_Crypto:
+    Features.push_back("+neon");
     Features.push_back("+crypto");
     break;
   case ARM::NS_Neon:
@@ -298,6 +314,14 @@ StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
   return StringRef();
 }
 
+unsigned llvm::ARM::getDefaultExtensions(StringRef CPU) {
+  for (const auto C : CPUNames) {
+    if (CPU == C.getName())
+      return (ARCHNames[C.ArchID].ArchBaseExtensions | C.DefaultExtensions);
+  }
+  return ARM::AEK_INVALID;
+}
+
 StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {
   unsigned AK = parseArch(Arch);
   if (AK == ARM::AK_INVALID)