From fe6f0b48d94e796528fb3352770363cc1c781e38 Mon Sep 17 00:00:00 2001
From: Sjoerd Meijer <sjoerd.meijer@arm.com>
Date: Fri, 7 Jun 2019 15:20:56 +0000
Subject: [PATCH] [ARM] Add ACLE feature macros for MVE

If MVE is present at all, then the macro __ARM_FEATURE_MVE is defined
to a value which has bit 0 set for integer MVE, and bit 1 set for
floating-point MVE.

(Floating-point MVE implies integer MVE, so if this macro is defined
at all then it will be set to 1 or 3, never 2.)

Patch mostly by Simon Tatham

Differential Revision: https://reviews.llvm.org/D60710


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@362806 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Basic/Targets/ARM.cpp               | 22 ++++++++++++++++++++++
 lib/Basic/Targets/ARM.h                 |  8 ++++++++
 test/Preprocessor/arm-target-features.c | 21 +++++++++++++++++++++
 3 files changed, 51 insertions(+)

diff --git a/lib/Basic/Targets/ARM.cpp b/lib/Basic/Targets/ARM.cpp
index 259adedd61..d9028f8e4f 100644
--- a/lib/Basic/Targets/ARM.cpp
+++ b/lib/Basic/Targets/ARM.cpp
@@ -146,6 +146,14 @@ void ARMTargetInfo::setAtomic() {
   }
 }
 
+bool ARMTargetInfo::hasMVE() const {
+  return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline && MVE != 0;
+}
+
+bool ARMTargetInfo::hasMVEFloat() const {
+  return hasMVE() && (MVE & MVE_FP);
+}
+
 bool ARMTargetInfo::isThumb() const {
   return ArchISA == llvm::ARM::ISAKind::THUMB;
 }
@@ -460,6 +468,15 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
       HasLegalHalfType = true;
     } else if (Feature == "+dotprod") {
       DotProd = true;
+    } else if (Feature == "+mve") {
+      DSP = 1;
+      MVE |= MVE_INT;
+    } else if (Feature == "+mve.fp") {
+      DSP = 1;
+      HasLegalHalfType = true;
+      FPU |= FPARMV8;
+      MVE |= MVE_INT | MVE_FP;
+      HW_FP |= HW_FP_SP | HW_FP_HP;
     }
   }
 
@@ -510,6 +527,7 @@ bool ARMTargetInfo::hasFeature(StringRef Feature) const {
       .Case("vfp", FPU && !SoftFloat)
       .Case("hwdiv", HWDiv & HWDivThumb)
       .Case("hwdiv-arm", HWDiv & HWDivARM)
+      .Case("mve", hasMVE())
       .Default(false);
 }
 
@@ -725,6 +743,10 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
                         "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
   }
 
+  if (hasMVE()) {
+    Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
+  }
+
   Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
                       Twine(Opts.WCharSize ? Opts.WCharSize : 4));
 
diff --git a/lib/Basic/Targets/ARM.h b/lib/Basic/Targets/ARM.h
index c977c78a75..e05ceab0dc 100644
--- a/lib/Basic/Targets/ARM.h
+++ b/lib/Basic/Targets/ARM.h
@@ -33,6 +33,11 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
     FPARMV8 = (1 << 4)
   };
 
+  enum MVEMode {
+      MVE_INT = (1 << 0),
+      MVE_FP  = (1 << 1)
+  };
+
   // Possible HWDiv features.
   enum HWDivMode { HWDivThumb = (1 << 0), HWDivARM = (1 << 1) };
 
@@ -56,6 +61,7 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
   unsigned ArchVersion;
 
   unsigned FPU : 5;
+  unsigned MVE : 2;
 
   unsigned IsAAPCS : 1;
   unsigned HWDiv : 2;
@@ -100,6 +106,8 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
   bool isThumb() const;
   bool supportsThumb() const;
   bool supportsThumb2() const;
+  bool hasMVE() const;
+  bool hasMVEFloat() const;
 
   StringRef getCPUAttr() const;
   StringRef getCPUProfile() const;
diff --git a/test/Preprocessor/arm-target-features.c b/test/Preprocessor/arm-target-features.c
index ccc6d720a3..95231e2a81 100644
--- a/test/Preprocessor/arm-target-features.c
+++ b/test/Preprocessor/arm-target-features.c
@@ -748,6 +748,27 @@
 // KRAIT-ALLOW-FP-INSTR:#define __ARM_FEATURE_DSP 1
 // KRAIT-ALLOW-FP-INSTR:#define  __ARM_VFPV4__ 1
 
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V81M %s
+// CHECK-V81M: #define __ARM_ARCH 8
+// CHECK-V81M: #define __ARM_ARCH_8_1M_MAIN__ 1
+// CHECK-V81M: #define __ARM_ARCH_ISA_THUMB 2
+// CHECK-V81M: #define __ARM_ARCH_PROFILE 'M'
+// CHECK-V81M-NOT: #define __ARM_FEATURE_DSP
+// CHECK-V81M-NOT: #define __ARM_FEATURE_MVE
+// CHECK-V81M-NOT: #define __ARM_FEATURE_SIMD32
+
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+mve -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V81M-MVE %s
+// CHECK-V81M-MVE: #define __ARM_FEATURE_DSP 1
+// CHECK-V81M-MVE: #define __ARM_FEATURE_MVE 1
+// CHECK-V81M-MVE: #define __ARM_FEATURE_SIMD32 1
+
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+mve.fp -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V81M-MVE-FP %s
+// CHECK-V81M-MVE-FP: #define __ARM_FEATURE_DSP 1
+// CHECK-V81M-MVE-FP: #define __ARM_FEATURE_FP16_SCALAR_ARITHMETIC 1
+// CHECK-V81M-MVE-FP: #define __ARM_FEATURE_MVE 3
+// CHECK-V81M-MVE-FP: #define __ARM_FEATURE_SIMD32 1
+// CHECK-V81M-MVE-FP: #define __ARM_FPV5__ 1
+
 // RUN: %clang -target armv8.1a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V81A %s
 // CHECK-V81A: #define __ARM_ARCH 8
 // CHECK-V81A: #define __ARM_ARCH_8_1A__ 1
-- 
2.40.0