Index: include/llvm/Support/AArch64TargetParser.def =================================================================== --- include/llvm/Support/AArch64TargetParser.def +++ include/llvm/Support/AArch64TargetParser.def @@ -117,6 +117,9 @@ (AArch64::AEK_CRC | AArch64::AEK_PROFILE)) AARCH64_CPU_NAME("thunderxt83", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, (AArch64::AEK_CRC | AArch64::AEK_PROFILE)) +AARCH64_CPU_NAME("tsv110", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false, + (AArch64::AEK_PROFILE | AArch64::AEK_FP16 | AArch64::AEK_FP16FML | + AArch64::AEK_DOTPROD)) // Invalid CPU AARCH64_CPU_NAME("invalid", INVALID, FK_INVALID, true, AArch64::AEK_INVALID) #undef AARCH64_CPU_NAME Index: lib/Support/Host.cpp =================================================================== --- lib/Support/Host.cpp +++ lib/Support/Host.cpp @@ -211,6 +211,17 @@ } } + if (Implementer == "0x48") // HiSilicon Technologies, Inc. + // Look for the CPU part line. + for (unsigned I = 0, E = Lines.size(); I != E; ++I) + if (Lines[I].startswith("CPU part")) + // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The + // values correspond to the "Part number" in the CP15/c0 register. The + // contents are specified in the various processor manuals. + return StringSwitch(Lines[I].substr(8).ltrim("\t :")) + .Case("0xd01", "tsv110") + .Default("generic"); + if (Implementer == "0x51") // Qualcomm Technologies, Inc. // Look for the CPU part line. for (unsigned I = 0, E = Lines.size(); I != E; ++I) Index: lib/Target/AArch64/AArch64.td =================================================================== --- lib/Target/AArch64/AArch64.td +++ lib/Target/AArch64/AArch64.td @@ -546,6 +546,21 @@ FeaturePredictableSelectIsExpensive, FeatureNEON]>; +def ProcTSV110 : SubtargetFeature<"tsv110", "ARMProcFamily", "TSV110", + "HiSilicon TS-V110 processors", [ + HasV8_2aOps, + FeatureCrypto, + FeatureCustomCheapAsMoveHandling, + FeatureFPARMv8, + FeatureFuseAES, + FeatureNEON, + FeaturePerfMon, + FeaturePostRAScheduler, + FeatureSPE, + FeatureFullFP16, + FeatureFP16FML, + FeatureDotProd]>; + def : ProcessorModel<"generic", NoSchedModel, [ FeatureFPARMv8, FeatureFuseAES, @@ -578,6 +593,8 @@ def : ProcessorModel<"thunderxt83", ThunderXT8XModel, [ProcThunderXT83]>; // Cavium ThunderX2T9X Processors. Formerly Broadcom Vulcan. def : ProcessorModel<"thunderx2t99", ThunderX2T99Model, [ProcThunderX2T99]>; +// FIXME: HiSilicon TSV110 is currently modeled as a Cortex-A57. +def : ProcessorModel<"tsv110", CortexA57Model, [ProcTSV110]>; //===----------------------------------------------------------------------===// // Assembly parser Index: lib/Target/AArch64/AArch64Subtarget.h =================================================================== --- lib/Target/AArch64/AArch64Subtarget.h +++ lib/Target/AArch64/AArch64Subtarget.h @@ -56,7 +56,8 @@ ThunderX, ThunderXT81, ThunderXT83, - ThunderXT88 + ThunderXT88, + TSV110 }; protected: Index: lib/Target/AArch64/AArch64Subtarget.cpp =================================================================== --- lib/Target/AArch64/AArch64Subtarget.cpp +++ lib/Target/AArch64/AArch64Subtarget.cpp @@ -148,6 +148,11 @@ // FIXME: remove this to enable 64-bit SLP if performance looks good. MinVectorRegisterBitWidth = 128; break; + case TSV110: + CacheLineSize = 64; + PrefFunctionAlignment = 4; + PrefLoopAlignment = 2; + break; } } Index: test/CodeGen/AArch64/cpus.ll =================================================================== --- test/CodeGen/AArch64/cpus.ll +++ test/CodeGen/AArch64/cpus.ll @@ -17,6 +17,7 @@ ; RUN: llc < %s -mtriple=arm64-unknown-unknown -mcpu=saphira 2>&1 | FileCheck %s ; RUN: llc < %s -mtriple=arm64-unknown-unknown -mcpu=kryo 2>&1 | FileCheck %s ; RUN: llc < %s -mtriple=arm64-unknown-unknown -mcpu=thunderx2t99 2>&1 | FileCheck %s +; RUN: llc < %s -mtriple=arm64-unknown-unknown -mcpu=tsv110 2>&1 | FileCheck %s ; RUN: llc < %s -mtriple=arm64-unknown-unknown -mcpu=invalidcpu 2>&1 | FileCheck %s --check-prefix=INVALID ; CHECK-NOT: {{.*}} is not a recognized processor for this target Index: test/CodeGen/AArch64/remat.ll =================================================================== --- test/CodeGen/AArch64/remat.ll +++ test/CodeGen/AArch64/remat.ll @@ -13,6 +13,7 @@ ; RUN: llc -mtriple=aarch64-linux-gnuabi -mcpu=saphira -o - %s | FileCheck %s ; RUN: llc -mtriple=aarch64-linux-gnuabi -mcpu=kryo -o - %s | FileCheck %s ; RUN: llc -mtriple=aarch64-linux-gnuabi -mcpu=thunderx2t99 -o - %s | FileCheck %s +; RUN: llc -mtriple=aarch64-linux-gnuabi -mcpu=tsv110 -o - %s | FileCheck %s ; RUN: llc -mtriple=aarch64-linux-gnuabi -mattr=+custom-cheap-as-move -o - %s | FileCheck %s %X = type { i64, i64, i64 } Index: test/MC/AArch64/armv8.1a-lse.s =================================================================== --- test/MC/AArch64/armv8.1a-lse.s +++ test/MC/AArch64/armv8.1a-lse.s @@ -4,6 +4,8 @@ // RUN: FileCheck -check-prefix=CHECK-ERROR < %t %s // RUN: not llvm-mc -triple aarch64-none-linux-gnu -mcpu=cortex-a75 -show-encoding < %s 2> %t | FileCheck %s // RUN: FileCheck -check-prefix=CHECK-ERROR < %t %s +// RUN: not llvm-mc -triple aarch64-none-linux-gnu -mcpu=tsv110 -show-encoding < %s 2> %t | FileCheck %s +// RUN: FileCheck -check-prefix=CHECK-ERROR < %t %s .text cas w0, w1, [x2] Index: test/MC/AArch64/armv8.2a-dotprod.s =================================================================== --- test/MC/AArch64/armv8.2a-dotprod.s +++ test/MC/AArch64/armv8.2a-dotprod.s @@ -1,6 +1,7 @@ // RUN: llvm-mc -triple aarch64 -mattr=+dotprod -show-encoding < %s | FileCheck %s --check-prefix=CHECK-DOTPROD // RUN: llvm-mc -triple aarch64 -mcpu=cortex-a75 -show-encoding < %s | FileCheck %s --check-prefix=CHECK-DOTPROD // RUN: llvm-mc -triple aarch64 -mcpu=cortex-a55 -show-encoding < %s | FileCheck %s --check-prefix=CHECK-DOTPROD +// RUN: llvm-mc -triple aarch64 -mcpu=tsv110 -show-encoding < %s | FileCheck %s --check-prefix=CHECK-DOTPROD // RUN: not llvm-mc -triple aarch64 -mattr=+v8.2a -show-encoding < %s 2> %t // RUN: FileCheck --check-prefix=CHECK-NO-DOTPROD < %t %s Index: test/MC/AArch64/crc.s =================================================================== --- test/MC/AArch64/crc.s +++ test/MC/AArch64/crc.s @@ -5,6 +5,8 @@ // RUN: FileCheck %s --check-prefix=CRC // RUN: llvm-mc -triple aarch64-- -mcpu=cortex-a75 %s 2>&1 |\ // RUN: FileCheck %s --check-prefix=CRC +// RUN: llvm-mc -triple aarch64-- -mcpu=tsv110 %s 2>&1 |\ +// RUN: FileCheck %s --check-prefix=CRC // RUN: not llvm-mc -triple aarch64-- %s 2>&1 |\ // RUN: FileCheck %s --check-prefix=NOCRC Index: test/MC/AArch64/ras-extension.s =================================================================== --- test/MC/AArch64/ras-extension.s +++ test/MC/AArch64/ras-extension.s @@ -1,6 +1,7 @@ // RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+ras < %s | FileCheck %s // RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mcpu=cortex-a55 < %s | FileCheck %s // RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mcpu=cortex-a75 < %s | FileCheck %s +// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mcpu=tsv110 < %s | FileCheck %s esb // CHECK: esb // encoding: [0x1f,0x22,0x03,0xd5] Index: test/MC/Disassembler/AArch64/armv8.2a-dotprod.txt =================================================================== --- test/MC/Disassembler/AArch64/armv8.2a-dotprod.txt +++ test/MC/Disassembler/AArch64/armv8.2a-dotprod.txt @@ -1,6 +1,7 @@ # RUN: llvm-mc -triple aarch64-none-linux-gnu -mattr=+dotprod --disassemble < %s | FileCheck %s # RUN: llvm-mc -triple aarch64-none-linux-gnu -mcpu=cortex-a75 --disassemble < %s | FileCheck %s # RUN: llvm-mc -triple aarch64-none-linux-gnu -mcpu=cortex-a55 --disassemble < %s | FileCheck %s +# RUN: llvm-mc -triple aarch64-none-linux-gnu -mcpu=tsv110 --disassemble < %s | FileCheck %s # RUN: llvm-mc -triple aarch64-none-linux-gnu -mattr=-dotprod --disassemble < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR 0x20,0x94,0x82,0x2e Index: unittests/Support/Host.cpp =================================================================== --- unittests/Support/Host.cpp +++ unittests/Support/Host.cpp @@ -242,6 +242,11 @@ "CPU implementer : 0x43\n" "CPU part : 0xa1"), "thunderxt88"); + + // Verify HiSilicon processors. + EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x48\n" + "CPU part : 0xd01"), + "tsv110"); } #if defined(__APPLE__) Index: unittests/Support/TargetParserTest.cpp =================================================================== --- unittests/Support/TargetParserTest.cpp +++ unittests/Support/TargetParserTest.cpp @@ -488,7 +488,7 @@ ARM::ArchKind::ARMV7EM, "crypto")); EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8A, "ras")); EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_1A, "ras")); - EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "spe")); + EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "profile")); EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "fp16")); EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "fp16fml")); EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A, "fp16")); @@ -795,9 +795,16 @@ AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_SIMD | AArch64::AEK_FP | AArch64::AEK_PROFILE, "8-A")); + EXPECT_TRUE(testAArch64CPU( + "tsv110", "armv8.2-a", "crypto-neon-fp-armv8", + AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | + AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE | + AArch64::AEK_RDM | AArch64::AEK_PROFILE | AArch64::AEK_FP16 | + AArch64::AEK_FP16FML | AArch64::AEK_DOTPROD, + "8.2-A")); } -static constexpr unsigned NumAArch64CPUArchs = 20; +static constexpr unsigned NumAArch64CPUArchs = 21; TEST(TargetParserTest, testAArch64CPUArchList) { SmallVector List; @@ -888,10 +895,14 @@ AArch64::ArchKind::INVALID, "fp16")); EXPECT_FALSE(testAArch64Extension("cortex-a55", AArch64::ArchKind::INVALID, "fp16fml")); + EXPECT_TRUE(testAArch64Extension("cortex-a55", + AArch64::ArchKind::INVALID, "dotprod")); EXPECT_TRUE(testAArch64Extension("cortex-a75", AArch64::ArchKind::INVALID, "fp16")); EXPECT_FALSE(testAArch64Extension("cortex-a75", AArch64::ArchKind::INVALID, "fp16fml")); + EXPECT_TRUE(testAArch64Extension("cortex-a75", + AArch64::ArchKind::INVALID, "dotprod")); EXPECT_FALSE(testAArch64Extension("thunderx2t99", AArch64::ArchKind::INVALID, "ras")); EXPECT_FALSE(testAArch64Extension("thunderx", @@ -902,13 +913,29 @@ AArch64::ArchKind::INVALID, "lse")); EXPECT_FALSE(testAArch64Extension("thunderxt88", AArch64::ArchKind::INVALID, "lse")); + EXPECT_TRUE(testAArch64Extension("tsv110", + AArch64::ArchKind::INVALID, "crypto")); + EXPECT_FALSE(testAArch64Extension("tsv110", + AArch64::ArchKind::INVALID, "sha3")); + EXPECT_FALSE(testAArch64Extension("tsv110", + AArch64::ArchKind::INVALID, "sm4")); + EXPECT_TRUE(testAArch64Extension("tsv110", + AArch64::ArchKind::INVALID, "ras")); + EXPECT_TRUE(testAArch64Extension("tsv110", + AArch64::ArchKind::INVALID, "profile")); + EXPECT_TRUE(testAArch64Extension("tsv110", + AArch64::ArchKind::INVALID, "fp16")); + EXPECT_TRUE(testAArch64Extension("tsv110", + AArch64::ArchKind::INVALID, "fp16fml")); + EXPECT_TRUE(testAArch64Extension("tsv110", + AArch64::ArchKind::INVALID, "dotprod")); EXPECT_FALSE(testAArch64Extension( "generic", AArch64::ArchKind::ARMV8A, "ras")); EXPECT_FALSE(testAArch64Extension( "generic", AArch64::ArchKind::ARMV8_1A, "ras")); EXPECT_FALSE(testAArch64Extension( - "generic", AArch64::ArchKind::ARMV8_2A, "spe")); + "generic", AArch64::ArchKind::ARMV8_2A, "profile")); EXPECT_FALSE(testAArch64Extension( "generic", AArch64::ArchKind::ARMV8_2A, "fp16")); EXPECT_FALSE(testAArch64Extension(