arm asm: Let .fpu enable instructions, PR20447.
authorNico Weber <nicolasweber@gmx.de>
Sat, 16 Aug 2014 05:37:51 +0000 (05:37 +0000)
committerNico Weber <nicolasweber@gmx.de>
Sat, 16 Aug 2014 05:37:51 +0000 (05:37 +0000)
I'm not very happy with duplicating the fpu->feature mapping in ARMAsmParser.cpp
and in clang's driver. See the bug for a patch that doesn't do that, and the
review thread [1] for why this duplication exists.

1: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140811/231052.html

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215811 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/directive-fpu-instrs.s [new file with mode: 0644]

index ba46c937d802b862f543ba387ca2919d2400d0b3..e4b59aedb3a3d8db5a42142d65f123e84a4b2c22 100644 (file)
@@ -8751,6 +8751,30 @@ bool ARMAsmParser::parseDirectiveCPU(SMLoc L) {
   return false;
 }
 
+// FIXME: This is duplicated in getARMFPUFeatures() in
+// tools/clang/lib/Driver/Tools.cpp
+static const struct {
+  const unsigned Fpu;
+  const uint64_t Enabled;
+  const uint64_t Disabled;
+} Fpus[] = {
+      {ARM::VFP, ARM::FeatureVFP2, ARM::FeatureNEON},
+      {ARM::VFPV2, ARM::FeatureVFP2, ARM::FeatureNEON},
+      {ARM::VFPV3, ARM::FeatureVFP3, ARM::FeatureNEON},
+      {ARM::VFPV3_D16, ARM::FeatureVFP3 | ARM::FeatureD16, ARM::FeatureNEON},
+      {ARM::VFPV4, ARM::FeatureVFP4, ARM::FeatureNEON},
+      {ARM::VFPV4_D16, ARM::FeatureVFP4 | ARM::FeatureD16, ARM::FeatureNEON},
+      {ARM::FP_ARMV8, ARM::FeatureFPARMv8,
+       ARM::FeatureNEON | ARM::FeatureCrypto},
+      {ARM::NEON, ARM::FeatureNEON, 0},
+      {ARM::NEON_VFPV4, ARM::FeatureVFP4 | ARM::FeatureNEON, 0},
+      {ARM::NEON_FP_ARMV8, ARM::FeatureFPARMv8 | ARM::FeatureNEON,
+       ARM::FeatureCrypto},
+      {ARM::CRYPTO_NEON_FP_ARMV8,
+       ARM::FeatureFPARMv8 | ARM::FeatureNEON | ARM::FeatureCrypto, 0},
+      {ARM::SOFTVFP, 0, 0},
+};
+
 /// parseDirectiveFPU
 ///  ::= .fpu str
 bool ARMAsmParser::parseDirectiveFPU(SMLoc L) {
@@ -8766,6 +8790,18 @@ bool ARMAsmParser::parseDirectiveFPU(SMLoc L) {
     return false;
   }
 
+  for (const auto &Fpu : Fpus) {
+    if (Fpu.Fpu != ID)
+      continue;
+
+    // Need to toggle features that should be on but are off and that
+    // should off but are on.
+    unsigned Toggle = (Fpu.Enabled & ~STI.getFeatureBits()) |
+                      (Fpu.Disabled & STI.getFeatureBits());
+    setAvailableFeatures(ComputeAvailableFeatures(STI.ToggleFeature(Toggle)));
+    break;
+  }
+
   getTargetStreamer().emitFPU(ID);
   return false;
 }
diff --git a/test/MC/ARM/directive-fpu-instrs.s b/test/MC/ARM/directive-fpu-instrs.s
new file mode 100644 (file)
index 0000000..0b1e8cc
--- /dev/null
@@ -0,0 +1,16 @@
+// RUN: llvm-mc -triple armv7-unknown-linux-gnueabi -mattr=+vfp3,+d16,-neon %s
+
+.fpu neon
+VAND d3, d5, d5
+vldr d21, [r7, #296]
+
+@ .thumb should not disable the prior .fpu neon
+.thumb
+
+vmov q4, q11 @ v4si
+str r6, [r7, #264]
+mov r6, r5
+vldr d21, [r7, #296]
+add r9, r7, #216
+
+fstmfdd sp!, {d8, d9, d10, d11, d12, d13, d14, d15}