diff --git a/clang/test/CodeGen/arm-target-features.c b/clang/test/CodeGen/arm-target-features.c --- a/clang/test/CodeGen/arm-target-features.c +++ b/clang/test/CodeGen/arm-target-features.c @@ -38,24 +38,24 @@ // CHECK-BASIC-V8-ARM: "target-features"="+armv8-a,+crc,+crypto,+d32,+dsp,+fp-armv8,+fp-armv8d16,+fp-armv8d16sp,+fp-armv8sp,+fp16,+fp64,+fpregs,+hwdiv,+hwdiv-arm,+neon,+vfp2,+vfp2d16,+vfp2d16sp,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,+vfp4,+vfp4d16,+vfp4d16sp,+vfp4sp,-thumb-mode" // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-r5 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3-D16-DIV -// CHECK-VFP3-D16-DIV: "target-features"="+armv7-r,+dsp,+fp64,+fpregs,+hwdiv,+hwdiv-arm,+thumb-mode,+vfp2d16,+vfp2d16sp,+vfp3d16,+vfp3d16sp" +// CHECK-VFP3-D16-DIV: "target-features"="+armv7-r,+dsp,+fp64,+fpregs,+hwdiv,+hwdiv-arm,+thumb-mode,+vfp2,+vfp2d16,+vfp2d16sp,+vfp2sp,+vfp3d16,+vfp3d16sp" // RUN: %clang_cc1 -triple armv7-linux-gnueabi -target-cpu cortex-r4f -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3-D16-THUMB-DIV -// CHECK-VFP3-D16-THUMB-DIV: "target-features"="+armv7-r,+dsp,+fp64,+fpregs,+hwdiv,+vfp2d16,+vfp2d16sp,+vfp3d16,+vfp3d16sp,-thumb-mode" +// CHECK-VFP3-D16-THUMB-DIV: "target-features"="+armv7-r,+dsp,+fp64,+fpregs,+hwdiv,+vfp2,+vfp2d16,+vfp2d16sp,+vfp2sp,+vfp3d16,+vfp3d16sp,-thumb-mode" // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-r7 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3-D16-FP16-DIV // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-r8 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3-D16-FP16-DIV -// CHECK-VFP3-D16-FP16-DIV: "target-features"="+armv7-r,+dsp,+fp16,+fp64,+fpregs,+hwdiv,+hwdiv-arm,+thumb-mode,+vfp2d16,+vfp2d16sp,+vfp3d16,+vfp3d16sp" +// CHECK-VFP3-D16-FP16-DIV: "target-features"="+armv7-r,+dsp,+fp16,+fp64,+fpregs,+hwdiv,+hwdiv-arm,+thumb-mode,+vfp2,+vfp2d16,+vfp2d16sp,+vfp2sp,+vfp3d16,+vfp3d16sp" // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-m4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-D16-SP-THUMB-DIV -// CHECK-VFP4-D16-SP-THUMB-DIV: "target-features"="+armv7e-m,+dsp,+fp16,+fpregs,+hwdiv,+thumb-mode,+vfp2d16sp,+vfp3d16sp,+vfp4d16sp" +// CHECK-VFP4-D16-SP-THUMB-DIV: "target-features"="+armv7e-m,+dsp,+fp16,+fpregs,+hwdiv,+thumb-mode,+vfp2d16sp,+vfp2sp,+vfp3d16sp,+vfp4d16sp" // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-m7 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP5-D16-THUMB-DIV -// CHECK-VFP5-D16-THUMB-DIV: "target-features"="+armv7e-m,+dsp,+fp-armv8d16,+fp-armv8d16sp,+fp16,+fp64,+fpregs,+hwdiv,+thumb-mode,+vfp2d16,+vfp2d16sp,+vfp3d16,+vfp3d16sp,+vfp4d16,+vfp4d16sp" +// CHECK-VFP5-D16-THUMB-DIV: "target-features"="+armv7e-m,+dsp,+fp-armv8d16,+fp-armv8d16sp,+fp16,+fp64,+fpregs,+hwdiv,+thumb-mode,+vfp2,+vfp2d16,+vfp2d16sp,+vfp2sp,+vfp3d16,+vfp3d16sp,+vfp4d16,+vfp4d16sp" // RUN: %clang_cc1 -triple armv7-linux-gnueabi -target-cpu cortex-r4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-THUMB-DIV @@ -107,6 +107,6 @@ // CHECK-ARMV8M-M23-LINUX: "target-features"="+armv8-m.base,+hwdiv,+thumb-mode" // RUN: %clang_cc1 -triple thumb-linux-gnueabi -target-cpu cortex-m33 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARMV8M-MAIN-LINUX -// CHECK-ARMV8M-MAIN-LINUX: "target-features"="+armv8-m.main,+dsp,+fp-armv8d16sp,+fp16,+fpregs,+hwdiv,+thumb-mode,+vfp2d16sp,+vfp3d16sp,+vfp4d16sp" +// CHECK-ARMV8M-MAIN-LINUX: "target-features"="+armv8-m.main,+dsp,+fp-armv8d16sp,+fp16,+fpregs,+hwdiv,+thumb-mode,+vfp2d16sp,+vfp2sp,+vfp3d16sp,+vfp4d16sp" void foo() {} diff --git a/llvm/lib/Support/ARMTargetParser.cpp b/llvm/lib/Support/ARMTargetParser.cpp --- a/llvm/lib/Support/ARMTargetParser.cpp +++ b/llvm/lib/Support/ARMTargetParser.cpp @@ -176,10 +176,10 @@ // exist). {"+fpregs", "-fpregs", FPUVersion::VFPV2, FPURestriction::SP_D16}, - {"+vfp2", "-vfp2", FPUVersion::VFPV2, FPURestriction::None}, + {"+vfp2", "-vfp2", FPUVersion::VFPV2, FPURestriction::D16}, {"+vfp2d16", "-vfp2d16", FPUVersion::VFPV2, FPURestriction::D16}, {"+vfp2d16sp", "-vfp2d16sp", FPUVersion::VFPV2, FPURestriction::SP_D16}, - {"+vfp2sp", "-vfp2sp", FPUVersion::VFPV2, FPURestriction::None}, + {"+vfp2sp", "-vfp2sp", FPUVersion::VFPV2, FPURestriction::SP_D16}, {"+vfp3", "-vfp3", FPUVersion::VFPV3, FPURestriction::None}, {"+vfp3d16", "-vfp3d16", FPUVersion::VFPV3, FPURestriction::D16}, {"+vfp3d16sp", "-vfp3d16sp", FPUVersion::VFPV3, FPURestriction::SP_D16}, @@ -195,7 +195,7 @@ {"+fp-armv8sp", "-fp-armv8sp", FPUVersion::VFPV5, FPURestriction::None}, {"+fullfp16", "-fullfp16", FPUVersion::VFPV5_FULLFP16, FPURestriction::SP_D16}, {"+fp64", "-fp64", FPUVersion::VFPV2, FPURestriction::D16}, - {"+d32", "-d32", FPUVersion::VFPV2, FPURestriction::None}, + {"+d32", "-d32", FPUVersion::VFPV3, FPURestriction::None}, }; for (const auto &Info: FPUFeatureInfoList) { diff --git a/llvm/lib/Target/ARM/ARM.td b/llvm/lib/Target/ARM/ARM.td --- a/llvm/lib/Target/ARM/ARM.td +++ b/llvm/lib/Target/ARM/ARM.td @@ -57,12 +57,15 @@ "Extend FP to 32 double registers">; multiclass VFPver prev = [], - list otherimplies = []> { + list prev, + list otherimplies, + list vfp2prev = []> { def _D16_SP: SubtargetFeature< name#"d16sp", query#"D16SP", "true", description#" with only 16 d-registers and no double precision", - !foreach(v, prev, !cast(v # "_D16_SP")) # otherimplies>; + !foreach(v, prev, !cast(v # "_D16_SP")) # + !foreach(v, vfp2prev, !cast(v # "_SP")) # + otherimplies>; def _SP: SubtargetFeature< name#"sp", query#"SP", "true", description#" with no double precision", @@ -72,6 +75,7 @@ name#"d16", query#"D16", "true", description#" with only 16 d-registers", !foreach(v, prev, !cast(v # "_D16")) # + vfp2prev # otherimplies # [FeatureFP64, !cast(NAME # "_D16_SP")]>; def "": SubtargetFeature< name, query, "true", description, @@ -80,11 +84,23 @@ !cast(NAME # "_SP")]>; } -defm FeatureVFP2: VFPver<"vfp2", "HasVFPv2", "Enable VFP2 instructions", - [], [FeatureFPRegs]>; +def FeatureVFP2_D16_SP : SubtargetFeature<"vfp2d16sp", "HasVFPv2D16SP", "true", + "Enable VFP2 instructions with " + "no double precision", + [FeatureFPRegs]>; +def FeatureVFP2_SP : SubtargetFeature<"vfp2sp", "HasVFPv2SP", "true", + "Enable VFP2 instructions with " + "no double precision", + [FeatureVFP2_D16_SP]>; +def FeatureVFP2_D16 : SubtargetFeature<"vfp2d16", "HasVFPv2D16", "true", + "Enable VFP2 instructions", + [FeatureFP64, FeatureVFP2_D16_SP]>; +def FeatureVFP2 : SubtargetFeature<"vfp2", "HasVFPv2", "true", + "Enable VFP2 instructions", + [FeatureVFP2_D16, FeatureVFP2_SP]>; defm FeatureVFP3: VFPver<"vfp3", "HasVFPv3", "Enable VFP3 instructions", - [FeatureVFP2]>; + [], [], [FeatureVFP2]>; def FeatureNEON : SubtargetFeature<"neon", "HasNEON", "true", "Enable NEON instructions", @@ -98,7 +114,7 @@ [FeatureVFP3], [FeatureFP16]>; defm FeatureFPARMv8: VFPver<"fp-armv8", "HasFPARMv8", "Enable ARMv8 FP", - [FeatureVFP4]>; + [FeatureVFP4], []>; def FeatureFullFP16 : SubtargetFeature<"fullfp16", "HasFullFP16", "true", "Enable full half-precision " diff --git a/llvm/test/MC/ARM/vfp-aliases-diagnostics.s b/llvm/test/MC/ARM/vfp-aliases-diagnostics.s --- a/llvm/test/MC/ARM/vfp-aliases-diagnostics.s +++ b/llvm/test/MC/ARM/vfp-aliases-diagnostics.s @@ -13,17 +13,17 @@ fldmeax sp!, {s0} @ CHECK-LABEL: aliases -@ CHECK: error: operand must be a list of registers in range [d0, d31] +@ CHECK: error: operand must be a list of registers in range [d0, d15] @ CHECK: fstmeax sp!, {s0} @ CHECK: ^ -@ CHECK: error: operand must be a list of registers in range [d0, d31] +@ CHECK: error: operand must be a list of registers in range [d0, d15] @ CHECK: fldmfdx sp!, {s0} @ CHECK: ^ -@ CHECK: error: operand must be a list of registers in range [d0, d31] +@ CHECK: error: operand must be a list of registers in range [d0, d15] @ CHECK: fstmfdx sp!, {s0} @ CHECK: ^ -@ CHECK: error: operand must be a list of registers in range [d0, d31] +@ CHECK: error: operand must be a list of registers in range [d0, d15] @ CHECK: fldmeax sp!, {s0} @ CHECK: ^ @@ -31,16 +31,16 @@ fstmiaxhs r0, {s0} fstmiaxls r0, {s0} fstmiaxvs r0, {s0} -@ CHECK: error: operand must be a list of registers in range [d0, d31] +@ CHECK: error: operand must be a list of registers in range [d0, d15] @ CHECK: fstmiaxcs r0, {s0} @ CHECK: ^ -@ CHECK: error: operand must be a list of registers in range [d0, d31] +@ CHECK: error: operand must be a list of registers in range [d0, d15] @ CHECK: fstmiaxhs r0, {s0} @ CHECK: ^ -@ CHECK: error: operand must be a list of registers in range [d0, d31] +@ CHECK: error: operand must be a list of registers in range [d0, d15] @ CHECK: fstmiaxls r0, {s0} @ CHECK: ^ -@ CHECK: error: operand must be a list of registers in range [d0, d31] +@ CHECK: error: operand must be a list of registers in range [d0, d15] @ CHECK: fstmiaxvs r0, {s0} @ CHECK: ^