Commit a37dfe66 authored by Hans Wennborg's avatar Hans Wennborg
Browse files

Merging r227584:

------------------------------------------------------------------------
r227584 | compnerd | 2015-01-30 09:58:25 -0800 (Fri, 30 Jan 2015) | 10 lines

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.
------------------------------------------------------------------------

llvm-svn: 227637
parent 7c5663d7
Loading
Loading
Loading
Loading
+35 −23
Original line number Diff line number Diff line
@@ -9191,26 +9191,38 @@ 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[] = {
} 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::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::FeatureFPARMv8,
    {ARM::FP_ARMV8, ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
                        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::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::FeatureFPARMv8 | ARM::FeatureNEON | ARM::FeatureCrypto, 0},
     ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
         ARM::FeatureFPARMv8 | ARM::FeatureNEON | ARM::FeatureCrypto,
     0},
    {ARM::SOFTVFP, 0, 0},
};

@@ -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;
  }
+63 −0
Original line number Diff line number Diff line
@ 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