From 8baa31e81c5294b9d8b0e93b7cb211009ec7457b Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Fri, 30 Jan 2015 17:58:25 +0000 Subject: [PATCH] ARM: correct handling of .fpu directive The FPU directive permits the user to switch the target FPU, enabling instructions that would be otherwise unavailable. However, when configuring the new subtarget features, we would not enable the implied functions for newer FPUs. This would result in invalid rejection of valid input. Ensure that we inherit the implied FPU functionality when enabling newer versions of the FPU. Fortunately, these are mostly hierarchical, unlike the CPUs. Addresses PR22395. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227584 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 58 ++++++++++++--------- test/MC/ARM/pr22395.s | 63 +++++++++++++++++++++++ 2 files changed, 98 insertions(+), 23 deletions(-) create mode 100644 test/MC/ARM/pr22395.s diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 6a00b28f37a..96f3b4e6432 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -9191,27 +9191,39 @@ bool ARMAsmParser::parseDirectiveCPU(SMLoc L) { // FIXME: This is duplicated in getARMFPUFeatures() in // tools/clang/lib/Driver/Tools.cpp static const struct { - const unsigned Fpu; + const unsigned ID; 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::FPV5_D16, ARM::FeatureFPARMv8 | ARM::FeatureD16, - ARM::FeatureNEON | ARM::FeatureCrypto}, - {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}, +} FPUs[] = { + {ARM::VFP, ARM::FeatureVFP2, ARM::FeatureNEON}, + {ARM::VFPV2, ARM::FeatureVFP2, ARM::FeatureNEON}, + {ARM::VFPV3, ARM::FeatureVFP2 | ARM::FeatureVFP3, ARM::FeatureNEON}, + {ARM::VFPV3_D16, ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureD16, + ARM::FeatureNEON}, + {ARM::VFPV4, ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4, + ARM::FeatureNEON}, + {ARM::VFPV4_D16, + ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 | ARM::FeatureD16, + ARM::FeatureNEON}, + {ARM::FPV5_D16, ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 | + ARM::FeatureFPARMv8 | ARM::FeatureD16, + ARM::FeatureNEON | ARM::FeatureCrypto}, + {ARM::FP_ARMV8, ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 | + ARM::FeatureFPARMv8, + ARM::FeatureNEON | ARM::FeatureCrypto}, + {ARM::NEON, ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureNEON, 0}, + {ARM::NEON_VFPV4, + ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 | ARM::FeatureNEON, + 0}, + {ARM::NEON_FP_ARMV8, + ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 | + ARM::FeatureFPARMv8 | ARM::FeatureNEON, + ARM::FeatureCrypto}, + {ARM::CRYPTO_NEON_FP_ARMV8, + ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 | + ARM::FeatureFPARMv8 | ARM::FeatureNEON | ARM::FeatureCrypto, + 0}, + {ARM::SOFTVFP, 0, 0}, }; /// parseDirectiveFPU @@ -9229,14 +9241,14 @@ bool ARMAsmParser::parseDirectiveFPU(SMLoc L) { return false; } - for (const auto &Fpu : Fpus) { - if (Fpu.Fpu != ID) + for (const auto &Entry : FPUs) { + if (Entry.ID != ID) continue; // Need to toggle features that should be on but are off and that // should off but are on. - uint64_t Toggle = (Fpu.Enabled & ~STI.getFeatureBits()) | - (Fpu.Disabled & STI.getFeatureBits()); + uint64_t Toggle = (Entry.Enabled & ~STI.getFeatureBits()) | + (Entry.Disabled & STI.getFeatureBits()); setAvailableFeatures(ComputeAvailableFeatures(STI.ToggleFeature(Toggle))); break; } diff --git a/test/MC/ARM/pr22395.s b/test/MC/ARM/pr22395.s new file mode 100644 index 00000000000..5da5d964298 --- /dev/null +++ b/test/MC/ARM/pr22395.s @@ -0,0 +1,63 @@ +@ RUN: llvm-mc -triple armv4t-eabi -filetype asm -o - %s 2>&1 | FileCheck %s + + .text + .thumb + + .p2align 2 + + .fpu neon + vldmia r0, {d16-d31} + +@ CHECK: vldmia r0, {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31} +@ CHECK-NOT: error: instruction requires: VFP2 + + .fpu vfpv3 + vadd.f32 s1, s2, s3 +@ CHECK: vadd.f32 s1, s2, s3 +@ CHECK-NOT: error: instruction requires: VPF2 + + .fpu vfpv3-d16 + vadd.f32 s1, s2, s3 +@ CHECK: vadd.f32 s1, s2, s3 +@ CHECK-NOT: error: instruction requires: VPF2 + + .fpu vfpv4 + vadd.f32 s1, s2, s3 +@ CHECK: vadd.f32 s1, s2, s3 +@ CHECK-NOT: error: instruction requires: VPF2 + + .fpu vfpv4-d16 + vadd.f32 s1, s2, s3 +@ CHECK: vadd.f32 s1, s2, s3 +@ CHECK-NOT: error: instruction requires: VPF2 + + .fpu fpv5-d16 + vadd.f32 s1, s2, s3 +@ CHECK: vadd.f32 s1, s2, s3 +@ CHECK-NOT: error: instruction requires: VPF2 + + .fpu fp-armv8 + vadd.f32 s1, s2, s3 +@ CHECK: vadd.f32 s1, s2, s3 +@ CHECK-NOT: error: instruction requires: VPF2 + + .fpu fp-armv8 + vadd.f32 s1, s2, s3 +@ CHECK: vadd.f32 s1, s2, s3 +@ CHECK-NOT: error: instruction requires: VPF2 + + .fpu neon + vadd.f32 s1, s2, s3 +@ CHECK: vadd.f32 s1, s2, s3 +@ CHECK-NOT: error: instruction requires: VPF2 + + .fpu neon-vfpv4 + vadd.f32 s1, s2, s3 +@ CHECK: vadd.f32 s1, s2, s3 +@ CHECK-NOT: error: instruction requires: VPF2 + + .fpu crypto-neon-fp-armv8 + vadd.f32 s1, s2, s3 +@ CHECK: vadd.f32 s1, s2, s3 +@ CHECK-NOT: error: instruction requires: VPF2 + -- 2.34.1