diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -36,6 +36,7 @@ bool HasFP16FML; bool HasMTE; bool HasTME; + bool HasLS64; bool HasMatMul; bool HasSVE2; bool HasSVE2AES; @@ -81,6 +82,8 @@ MacroBuilder &Builder) const; void getTargetDefinesARMV86A(const LangOptions &Opts, MacroBuilder &Builder) const; + void getTargetDefinesARMV87A(const LangOptions &Opts, + MacroBuilder &Builder) const; void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -196,6 +196,12 @@ getTargetDefinesARMV85A(Opts, Builder); } +void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts, + MacroBuilder &Builder) const { + // Also include the Armv8.6 defines + getTargetDefinesARMV86A(Opts, Builder); +} + void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { // Target identification. @@ -371,6 +377,9 @@ case llvm::AArch64::ArchKind::ARMV8_6A: getTargetDefinesARMV86A(Opts, Builder); break; + case llvm::AArch64::ArchKind::ARMV8_7A: + getTargetDefinesARMV87A(Opts, Builder); + break; } // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work. @@ -411,6 +420,7 @@ HasFP16FML = false; HasMTE = false; HasTME = false; + HasLS64 = false; HasMatMul = false; HasBFloat16 = false; HasSVE2 = false; @@ -486,6 +496,8 @@ ArchKind = llvm::AArch64::ArchKind::ARMV8_5A; if (Feature == "+v8.6a") ArchKind = llvm::AArch64::ArchKind::ARMV8_6A; + if (Feature == "+v8.7a") + ArchKind = llvm::AArch64::ArchKind::ARMV8_7A; if (Feature == "+v8r") ArchKind = llvm::AArch64::ArchKind::ARMV8R; if (Feature == "+fullfp16") @@ -504,6 +516,8 @@ HasBFloat16 = true; if (Feature == "+lse") HasLSE = true; + if (Feature == "+ls64") + HasLS64 = true; } setDataLayout(); diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -79,9 +79,10 @@ else return false; - // +sve implies +f32mm if the base architecture is v8.6A + // +sve implies +f32mm if the base architecture is v8.6A or v8.7A // it isn't the case in general that sve implies both f64mm and f32mm - if ((ArchKind == llvm::AArch64::ArchKind::ARMV8_6A) && Feature == "sve") + if ((ArchKind == llvm::AArch64::ArchKind::ARMV8_6A || + ArchKind == llvm::AArch64::ArchKind::ARMV8_7A) && Feature == "sve") Features.push_back("+f32mm"); } return true; diff --git a/clang/test/Driver/aarch64-cpus.c b/clang/test/Driver/aarch64-cpus.c --- a/clang/test/Driver/aarch64-cpus.c +++ b/clang/test/Driver/aarch64-cpus.c @@ -738,6 +738,28 @@ // NO-F64MM-NOT: "-target-feature" "+f64mm" // F64MM: "-target-feature" "+f64mm" +// RUN: %clang -target aarch64 -march=armv8.7a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A %s +// RUN: %clang -target aarch64 -march=armv8.7-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A %s +// RUN: %clang -target aarch64 -mlittle-endian -march=armv8.7a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A %s +// RUN: %clang -target aarch64 -mlittle-endian -march=armv8.7-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A %s +// RUN: %clang -target aarch64_be -mlittle-endian -march=armv8.7a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A %s +// RUN: %clang -target aarch64_be -mlittle-endian -march=armv8.7-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A %s +// GENERICV87A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.7a" + +// RUN: %clang -target aarch64_be -march=armv8.7a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-BE %s +// RUN: %clang -target aarch64_be -march=armv8.7-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-BE %s +// RUN: %clang -target aarch64 -mbig-endian -march=armv8.7a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-BE %s +// RUN: %clang -target aarch64 -mbig-endian -march=armv8.7-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-BE %s +// RUN: %clang -target aarch64_be -mbig-endian -march=armv8.7a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-BE %s +// RUN: %clang -target aarch64_be -mbig-endian -march=armv8.7-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV87A-BE %s +// GENERICV87A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.7a" + +// Tha LD64B/ST64B accelerator extension is disabled by default. +// RUN: %clang -target aarch64 -march=armv8.7a -### -c %s 2>&1 | FileCheck -check-prefix=NO-LS64 %s +// RUN: %clang -target aarch64 -march=armv8.7a+ls64 -### -c %s 2>&1 | FileCheck -check-prefix=LS64 %s +// NO-LS64-NOT: "-target-feature" "+ls64" +// LS64: "-target-feature" "+ls64" + // fullfp16 is off by default for v8a, feature must not be mentioned // RUN: %clang -target aarch64 -march=armv8a -### -c %s 2>&1 | FileCheck -check-prefix=V82ANOFP16 -check-prefix=GENERIC %s // RUN: %clang -target aarch64 -march=armv8-a -### -c %s 2>&1 | FileCheck -check-prefix=V82ANOFP16 -check-prefix=GENERIC %s diff --git a/clang/test/Driver/aarch64-ls64.c b/clang/test/Driver/aarch64-ls64.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/aarch64-ls64.c @@ -0,0 +1,12 @@ +// Test that target feature ls64 is implemented and available correctly +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.7-a+ls64 %s 2>&1 | FileCheck %s +// CHECK: "-target-feature" "+ls64" + +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.7-a+nols64 %s 2>&1 | FileCheck %s --check-prefix=NO_LS64 +// NO_LS64: "-target-feature" "-ls64" + +// RUN: %clang -### -target aarch64-none-none-eabi %s 2>&1 | FileCheck %s --check-prefix=ABSENT_LS64 +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.7-a %s 2>&1 | FileCheck %s --check-prefix=ABSENT_LS64 +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.7-a %s 2>&1 | FileCheck %s --check-prefix=ABSENT_LS64 +// ABSENT_LS64-NOT: "-target-feature" "+ls64" +// ABSENT_LS64-NOT: "-target-feature" "-ls64" diff --git a/llvm/include/llvm/Support/AArch64TargetParser.h b/llvm/include/llvm/Support/AArch64TargetParser.h --- a/llvm/include/llvm/Support/AArch64TargetParser.h +++ b/llvm/include/llvm/Support/AArch64TargetParser.h @@ -62,6 +62,7 @@ AEK_I8MM = 1 << 30, AEK_F32MM = 1ULL << 31, AEK_F64MM = 1ULL << 32, + AEK_LS64 = 1ULL << 33, }; enum class ArchKind { diff --git a/llvm/include/llvm/Support/AArch64TargetParser.def b/llvm/include/llvm/Support/AArch64TargetParser.def --- a/llvm/include/llvm/Support/AArch64TargetParser.def +++ b/llvm/include/llvm/Support/AArch64TargetParser.def @@ -51,6 +51,13 @@ AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_SM4 | AArch64::AEK_SHA3 | AArch64::AEK_BF16 | AArch64::AEK_SHA2 | AArch64::AEK_AES | AArch64::AEK_I8MM)) +AARCH64_ARCH("armv8.7-a", ARMV8_7A, "8.7-A", "v8.7a", + ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8, + (AArch64::AEK_CRC | AArch64::AEK_FP | + AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE | + AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | + AArch64::AEK_SM4 | AArch64::AEK_SHA3 | AArch64::AEK_BF16 | + AArch64::AEK_SHA2 | AArch64::AEK_AES | AArch64::AEK_I8MM)) // For v8-R, we do not enable crypto and align with GCC that enables a more // minimal set of optional architecture extensions. AARCH64_ARCH("armv8-r", ARMV8R, "8-R", "v8r", @@ -99,6 +106,7 @@ AARCH64_ARCH_EXT_NAME("f32mm", AArch64::AEK_F32MM, "+f32mm", "-f32mm") AARCH64_ARCH_EXT_NAME("f64mm", AArch64::AEK_F64MM, "+f64mm", "-f64mm") AARCH64_ARCH_EXT_NAME("tme", AArch64::AEK_TME, "+tme", "-tme") +AARCH64_ARCH_EXT_NAME("ls64", AArch64::AEK_LS64, "+ls64", "-ls64") #undef AARCH64_ARCH_EXT_NAME #ifndef AARCH64_CPU_NAME diff --git a/llvm/lib/Support/AArch64TargetParser.cpp b/llvm/lib/Support/AArch64TargetParser.cpp --- a/llvm/lib/Support/AArch64TargetParser.cpp +++ b/llvm/lib/Support/AArch64TargetParser.cpp @@ -118,6 +118,8 @@ Features.push_back("+v8.5a"); if (AK == AArch64::ArchKind::ARMV8_6A) Features.push_back("+v8.6a"); + if (AK == AArch64::ArchKind::ARMV8_7A) + Features.push_back("+v8.7a"); if(AK == AArch64::ArchKind::ARMV8R) Features.push_back("+v8r"); 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 @@ -154,6 +154,7 @@ .Case("v8.4a", "v8.4-a") .Case("v8.5a", "v8.5-a") .Case("v8.6a", "v8.6-a") + .Case("v8.7a", "v8.7-a") .Case("v8r", "v8-r") .Case("v8m.base", "v8-m.base") .Case("v8m.main", "v8-m.main") diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -5354,6 +5354,7 @@ case AArch64::ArchKind::ARMV8_4A: case AArch64::ArchKind::ARMV8_5A: case AArch64::ArchKind::ARMV8_6A: + case AArch64::ArchKind::ARMV8_7A: case AArch64::ArchKind::ARMV8R: RequestedExtensions.push_back("sm4"); RequestedExtensions.push_back("sha3"); @@ -5375,6 +5376,7 @@ case AArch64::ArchKind::ARMV8_4A: case AArch64::ArchKind::ARMV8_5A: case AArch64::ArchKind::ARMV8_6A: + case AArch64::ArchKind::ARMV8_7A: RequestedExtensions.push_back("nosm4"); RequestedExtensions.push_back("nosha3"); RequestedExtensions.push_back("nosha2"); diff --git a/llvm/unittests/Support/TargetParserTest.cpp b/llvm/unittests/Support/TargetParserTest.cpp --- a/llvm/unittests/Support/TargetParserTest.cpp +++ b/llvm/unittests/Support/TargetParserTest.cpp @@ -1100,6 +1100,8 @@ ARMBuildAttrs::CPUArch::v8_A)); EXPECT_TRUE(testAArch64Arch("armv8.6-a", "generic", "v8.6a", ARMBuildAttrs::CPUArch::v8_A)); + EXPECT_TRUE(testAArch64Arch("armv8.7-a", "generic", "v8.7a", + ARMBuildAttrs::CPUArch::v8_A)); } bool testAArch64Extension(StringRef CPUName, AArch64::ArchKind AK,