diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index d47181bfca4fc..7d0f879b3daee 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -368,8 +368,21 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, // ACLE predefines. Many can only have one possible value on v8 AArch64. Builder.defineMacro("__ARM_ACLE", "200"); - Builder.defineMacro("__ARM_ARCH", - std::to_string(ArchInfo->Version.getMajor())); + + // ACLE 5.4.1 ARM/Thumb instruction set architecture + // __ARM_ARCH is defined as an integer value indicating the current ARM ISA. + // For ISAs up to and including v8, __ARM_ARCH is equal to the major version + // number. For ISAs from v8.1 onwards, __ARM_ARCH is scaled up to include the + // minor version number, e.g. for ARM architecture ARMvX.Y: + // __ARM_ARCH = X * 100 + Y. + if (ArchInfo->Version.getMajor() == 8 && ArchInfo->Version.getMinor() == 0) + Builder.defineMacro("__ARM_ARCH", + std::to_string(ArchInfo->Version.getMajor())); + else + Builder.defineMacro("__ARM_ARCH", + std::to_string(ArchInfo->Version.getMajor() * 100 + + ArchInfo->Version.getMinor().value())); + Builder.defineMacro("__ARM_ARCH_PROFILE", std::string("'") + (char)ArchInfo->Profile + "'"); diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp index 55b71557452fa..9ac558caa2886 100644 --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -130,6 +130,7 @@ void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) { SubArch = llvm::ARM::getSubArch(ArchKind); ArchProfile = llvm::ARM::parseArchProfile(SubArch); ArchVersion = llvm::ARM::parseArchVersion(SubArch); + ArchMinorVersion = llvm::ARM::parseArchMinorVersion(SubArch); // cache CPU related strings CPUAttr = getCPUAttr(); @@ -736,9 +737,17 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, if (!CPUAttr.empty()) Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__"); - // ACLE 6.4.1 ARM/Thumb instruction set architecture - // __ARM_ARCH is defined as an integer value indicating the current ARM ISA - Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion)); + // ACLE 5.4.1 ARM/Thumb instruction set architecture + // __ARM_ARCH is defined as an integer value indicating the current ARM ISA. + // For ISAs up to and including v8, __ARM_ARCH is equal to the major version + // number. For ISAs from v8.1 onwards, __ARM_ARCH is scaled up to include the + // minor version number, e.g. for ARM architecture ARMvX.Y: + // __ARM_ARCH = X * 100 + Y. + if (ArchVersion >= 9 || ArchMinorVersion != 0) + Builder.defineMacro("__ARM_ARCH", + Twine(ArchVersion * 100 + ArchMinorVersion)); + else + Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion)); if (ArchVersion >= 8) { // ACLE 6.5.7 Crypto Extension diff --git a/clang/lib/Basic/Targets/ARM.h b/clang/lib/Basic/Targets/ARM.h index 9802eb01abf3c..9c4bd299f6733 100644 --- a/clang/lib/Basic/Targets/ARM.h +++ b/clang/lib/Basic/Targets/ARM.h @@ -60,6 +60,7 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo { llvm::ARM::ArchKind ArchKind = llvm::ARM::ArchKind::ARMV4T; llvm::ARM::ProfileKind ArchProfile; unsigned ArchVersion; + unsigned ArchMinorVersion; unsigned FPU : 5; unsigned MVE : 2; diff --git a/clang/test/Preprocessor/arm-target-features.c b/clang/test/Preprocessor/arm-target-features.c index 236c9f2479b70..2122082760b6f 100644 --- a/clang/test/Preprocessor/arm-target-features.c +++ b/clang/test/Preprocessor/arm-target-features.c @@ -737,7 +737,7 @@ // Test whether predefines are as expected when targeting cortex-m55 (softfp FP ABI as default). // RUN: %clang -target arm-eabi -mcpu=cortex-m55 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=M55 %s -// M55: #define __ARM_ARCH 8 +// M55: #define __ARM_ARCH 801 // M55: #define __ARM_ARCH_8_1M_MAIN__ 1 // M55: #define __ARM_ARCH_EXT_IDIV__ 1 // M55-NOT: __ARM_ARCH_ISA_ARM @@ -764,7 +764,7 @@ // KRAIT-ALLOW-FP-INSTR:#define __ARM_VFPV4__ 1 // RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V81M %s -// CHECK-V81M: #define __ARM_ARCH 8 +// CHECK-V81M: #define __ARM_ARCH 801 // CHECK-V81M: #define __ARM_ARCH_8_1M_MAIN__ 1 // CHECK-V81M: #define __ARM_ARCH_ISA_THUMB 2 // CHECK-V81M: #define __ARM_ARCH_PROFILE 'M' @@ -821,14 +821,14 @@ // CHECK-V8M-CDE-MASK2: #define __ARM_FEATURE_CDE_COPROC 0xff // RUN: %clang -target armv8.1a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V81A %s -// CHECK-V81A: #define __ARM_ARCH 8 +// CHECK-V81A: #define __ARM_ARCH 801 // CHECK-V81A: #define __ARM_ARCH_8_1A__ 1 // CHECK-V81A: #define __ARM_ARCH_PROFILE 'A' // CHECK-V81A: #define __ARM_FEATURE_QRDMX 1 // CHECK-V81A: #define __ARM_FP 0xe // RUN: %clang -target armv8.2a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V82A %s -// CHECK-V82A: #define __ARM_ARCH 8 +// CHECK-V82A: #define __ARM_ARCH 802 // CHECK-V82A: #define __ARM_ARCH_8_2A__ 1 // CHECK-V82A: #define __ARM_ARCH_PROFILE 'A' // CHECK-V82A: #define __ARM_FEATURE_QRDMX 1 @@ -838,62 +838,62 @@ // CHECK-DRIVERKIT-NOT: #define __ARM_PCS_VFP 1 // RUN: %clang -target armv8.3a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V83A %s -// CHECK-V83A: #define __ARM_ARCH 8 +// CHECK-V83A: #define __ARM_ARCH 803 // CHECK-V83A: #define __ARM_ARCH_8_3A__ 1 // CHECK-V83A: #define __ARM_ARCH_PROFILE 'A' // RUN: %clang -target armv8.4a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V84A %s -// CHECK-V84A: #define __ARM_ARCH 8 +// CHECK-V84A: #define __ARM_ARCH 804 // CHECK-V84A: #define __ARM_ARCH_8_4A__ 1 // CHECK-V84A: #define __ARM_ARCH_PROFILE 'A' // RUN: %clang -target armv8.5a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V85A %s -// CHECK-V85A: #define __ARM_ARCH 8 +// CHECK-V85A: #define __ARM_ARCH 805 // CHECK-V85A: #define __ARM_ARCH_8_5A__ 1 // CHECK-V85A: #define __ARM_ARCH_PROFILE 'A' // RUN: %clang -target armv8.6a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V86A %s -// CHECK-V86A: #define __ARM_ARCH 8 +// CHECK-V86A: #define __ARM_ARCH 806 // CHECK-V86A: #define __ARM_ARCH_8_6A__ 1 // CHECK-V86A: #define __ARM_ARCH_PROFILE 'A' // RUN: %clang -target armv8.7a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V87A %s -// CHECK-V87A: #define __ARM_ARCH 8 +// CHECK-V87A: #define __ARM_ARCH 807 // CHECK-V87A: #define __ARM_ARCH_8_7A__ 1 // CHECK-V87A: #define __ARM_ARCH_PROFILE 'A' // RUN: %clang -target armv8.8a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V88A %s -// CHECK-V88A: #define __ARM_ARCH 8 +// CHECK-V88A: #define __ARM_ARCH 808 // CHECK-V88A: #define __ARM_ARCH_8_8A__ 1 // CHECK-V88A: #define __ARM_ARCH_PROFILE 'A' // RUN: %clang -target armv8.9a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V89A %s -// CHECK-V89A: #define __ARM_ARCH 8 +// CHECK-V89A: #define __ARM_ARCH 809 // CHECK-V89A: #define __ARM_ARCH_8_9A__ 1 // CHECK-V89A: #define __ARM_ARCH_PROFILE 'A' // RUN: %clang -target armv9a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V9A %s -// CHECK-V9A: #define __ARM_ARCH 9 +// CHECK-V9A: #define __ARM_ARCH 900 // CHECK-V9A: #define __ARM_ARCH_9A__ 1 // CHECK-V9A: #define __ARM_ARCH_PROFILE 'A' // RUN: %clang -target armv9.1a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V91A %s -// CHECK-V91A: #define __ARM_ARCH 9 +// CHECK-V91A: #define __ARM_ARCH 901 // CHECK-V91A: #define __ARM_ARCH_9_1A__ 1 // CHECK-V91A: #define __ARM_ARCH_PROFILE 'A' // RUN: %clang -target armv9.2a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V92A %s -// CHECK-V92A: #define __ARM_ARCH 9 +// CHECK-V92A: #define __ARM_ARCH 902 // CHECK-V92A: #define __ARM_ARCH_9_2A__ 1 // CHECK-V92A: #define __ARM_ARCH_PROFILE 'A' // RUN: %clang -target armv9.3a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V93A %s -// CHECK-V93A: #define __ARM_ARCH 9 +// CHECK-V93A: #define __ARM_ARCH 903 // CHECK-V93A: #define __ARM_ARCH_9_3A__ 1 // CHECK-V93A: #define __ARM_ARCH_PROFILE 'A' // RUN: %clang -target armv9.4a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V94A %s -// CHECK-V94A: #define __ARM_ARCH 9 +// CHECK-V94A: #define __ARM_ARCH 904 // CHECK-V94A: #define __ARM_ARCH_9_4A__ 1 // CHECK-V94A: #define __ARM_ARCH_PROFILE 'A' diff --git a/llvm/include/llvm/TargetParser/ARMTargetParser.h b/llvm/include/llvm/TargetParser/ARMTargetParser.h index c42d66f048fcc..ec3817134a5ac 100644 --- a/llvm/include/llvm/TargetParser/ARMTargetParser.h +++ b/llvm/include/llvm/TargetParser/ARMTargetParser.h @@ -258,6 +258,7 @@ uint64_t parseArchExt(StringRef ArchExt); ArchKind parseCPUArch(StringRef CPU); ProfileKind parseArchProfile(StringRef Arch); unsigned parseArchVersion(StringRef Arch); +unsigned parseArchMinorVersion(StringRef Arch); void fillValidCPUArchList(SmallVectorImpl &Values); StringRef computeDefaultTargetABI(const Triple &TT, StringRef CPU); diff --git a/llvm/lib/TargetParser/ARMTargetParser.cpp b/llvm/lib/TargetParser/ARMTargetParser.cpp index 67f937ebc33f9..dfbc2ff57ad16 100644 --- a/llvm/lib/TargetParser/ARMTargetParser.cpp +++ b/llvm/lib/TargetParser/ARMTargetParser.cpp @@ -94,6 +94,66 @@ unsigned ARM::parseArchVersion(StringRef Arch) { llvm_unreachable("Unhandled architecture"); } +unsigned ARM::parseArchMinorVersion(StringRef Arch) { + Arch = getCanonicalArchName(Arch); + switch (parseArch(Arch)) { + case ArchKind::ARMV4: + case ArchKind::ARMV4T: + case ArchKind::ARMV5T: + case ArchKind::ARMV5TE: + case ArchKind::IWMMXT: + case ArchKind::IWMMXT2: + case ArchKind::XSCALE: + case ArchKind::ARMV5TEJ: + case ArchKind::ARMV6: + case ArchKind::ARMV6K: + case ArchKind::ARMV6T2: + case ArchKind::ARMV6KZ: + case ArchKind::ARMV6M: + case ArchKind::ARMV7A: + case ArchKind::ARMV7VE: + case ArchKind::ARMV7R: + case ArchKind::ARMV7AR: + case ArchKind::ARMV7M: + case ArchKind::ARMV7S: + case ArchKind::ARMV7EM: + case ArchKind::ARMV7K: + case ArchKind::ARMV8AR: + case ArchKind::ARMV8A: + case ArchKind::ARMV8R: + case ArchKind::ARMV8MBaseline: + case ArchKind::ARMV8MMainline: + case ArchKind::ARMV9A: + case ArchKind::INVALID: + return 0; + case ArchKind::ARMV8_1A: + case ArchKind::ARMV8_1MMainline: + case ArchKind::ARMV9_1A: + return 1; + case ArchKind::ARMV8_2A: + case ArchKind::ARMV8_2MMainline: + case ArchKind::ARMV9_2A: + return 2; + case ArchKind::ARMV8_3A: + case ArchKind::ARMV9_3A: + return 3; + case ArchKind::ARMV8_4A: + case ArchKind::ARMV9_4A: + return 4; + case ArchKind::ARMV8_5A: + return 5; + case ArchKind::ARMV8_6A: + return 6; + case ArchKind::ARMV8_7A: + return 7; + case ArchKind::ARMV8_8A: + return 8; + case ArchKind::ARMV8_9A: + return 9; + } + llvm_unreachable("Unhandled architecture"); +} + static ARM::ProfileKind getProfileKind(ARM::ArchKind AK) { switch (AK) { case ARM::ArchKind::ARMV6M: diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp index d31fcd1bb1b00..e3de01c18d657 100644 --- a/llvm/unittests/TargetParser/TargetParserTest.cpp +++ b/llvm/unittests/TargetParser/TargetParserTest.cpp @@ -961,6 +961,14 @@ TEST(TargetParserTest, ARMparseArchVersion) { EXPECT_EQ(5u, ARM::parseArchVersion(ARMArch[i])); } +TEST(TargetParserTest, ARMparseArchMinorVersion) { + for (unsigned i = 0; i < std::size(ARMArch); i++) + if (((std::string)ARMArch[i]).find(".") == 5) + EXPECT_EQ((ARMArch[i][6] - 48u), ARM::parseArchMinorVersion(ARMArch[i])); + else + EXPECT_EQ(0u, ARM::parseArchMinorVersion(ARMArch[i])); +} + TEST(TargetParserTest, getARMCPUForArch) { // Platform specific defaults. {