diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -57,6 +57,7 @@ {"zbs", RISCVExtensionVersion{1, 0}}, {"zbkb", RISCVExtensionVersion{1, 0}}, + {"zbkc", RISCVExtensionVersion{1, 0}}, }; static const RISCVSupportedExtension SupportedExperimentalExtensions[] = { diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -163,6 +163,21 @@ "'Zbp' (Permutation 'B' Instructions) or " "'Zbkb' (Bitmanip instructions for Cryptography)">; +// The Carry-less multiply subextension for cryptography is a subset of basic carry-less multiply subextension. The former should be enabled if the latter is enabled. +def FeatureStdExtZbkc + : SubtargetFeature<"zbkc", "HasStdExtZbkc", "true", + "'Zbkc' (Carry-less multiply instructions for Cryptography)">; +def HasStdExtZbkc + : Predicate<"Subtarget->hasStdExtZbkc()">, + AssemblerPredicate<(all_of FeatureStdExtZbkc), + "'Zbkc' (Carry-less multiply instructions for Cryptography)">; + +def HasStdExtZbcOrZbkc + : Predicate<"Subtarget->hasStdExtZbc() || Subtarget->hasStdExtZbkc()">, + AssemblerPredicate<(any_of FeatureStdExtZbc, FeatureStdExtZbkc), + "'Zbc' (Carry-Less 'B' Instructions) or " + "'Zbkc' (Carry-less multiply instructions for Cryptography)">; + def FeatureNoRVCHints : SubtargetFeature<"no-rvc-hints", "EnableRVCHintInstrs", "false", "Disable RVC Hint Instructions.">; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td @@ -440,13 +440,16 @@ Sched<[]>; let Predicates = [HasStdExtZbc] in { -def CLMUL : ALU_rr<0b0000101, 0b001, "clmul">, - Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>; def CLMULR : ALU_rr<0b0000101, 0b010, "clmulr">, Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>; +} // Predicates = [HasStdExtZbc] + +let Predicates = [HasStdExtZbcOrZbkc] in { +def CLMUL : ALU_rr<0b0000101, 0b001, "clmul">, + Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>; def CLMULH : ALU_rr<0b0000101, 0b011, "clmulh">, Sched<[WriteCLMUL, ReadCLMUL, ReadCLMUL]>; -} // Predicates = [HasStdExtZbc] +} // Predicates = [HasStdExtZbcOrZbkc] let Predicates = [HasStdExtZbb] in { def MIN : ALU_rr<0b0000101, 0b100, "min">, diff --git a/llvm/lib/Target/RISCV/RISCVSchedRocket.td b/llvm/lib/Target/RISCV/RISCVSchedRocket.td --- a/llvm/lib/Target/RISCV/RISCVSchedRocket.td +++ b/llvm/lib/Target/RISCV/RISCVSchedRocket.td @@ -17,7 +17,7 @@ let LoadLatency = 3; let MispredictPenalty = 3; let CompleteModel = false; - let UnsupportedFeatures = [HasStdExtZbkb, HasVInstructions, HasVInstructionsI64]; + let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasVInstructions, HasVInstructionsI64]; } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td --- a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td +++ b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td @@ -15,7 +15,7 @@ let LoadLatency = 3; let MispredictPenalty = 3; let CompleteModel = 0; - let UnsupportedFeatures = [HasStdExtZbkb, HasVInstructions]; + let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasVInstructions]; } // The SiFive7 microarchitecture has two pipelines: A and B. diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -84,6 +84,7 @@ bool HasStdExtZfhmin = false; bool HasStdExtZfh = false; bool HasStdExtZbkb = false; + bool HasStdExtZbkc = false; bool HasRV64 = false; bool IsRV32E = false; bool EnableLinkerRelax = false; @@ -158,6 +159,7 @@ bool hasStdExtZfhmin() const { return HasStdExtZfhmin; } bool hasStdExtZfh() const { return HasStdExtZfh; } bool hasStdExtZbkb() const { return HasStdExtZbkb; } + bool hasStdExtZbkc() const { return HasStdExtZbkc; } bool is64Bit() const { return HasRV64; } bool isRV32E() const { return IsRV32E; } bool enableLinkerRelax() const { return EnableLinkerRelax; } diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -20,6 +20,7 @@ ; RUN: llc -mtriple=riscv32 -mattr=+experimental-v %s -o - | FileCheck --check-prefix=RV32V %s ; RUN: llc -mtriple=riscv32 -mattr=+zbb,+zfh,+experimental-v,+f %s -o - | FileCheck --check-prefix=RV32COMBINED %s ; RUN: llc -mtriple=riscv32 -mattr=+zbkb %s -o - | FileCheck --check-prefix=RV32ZBKB %s +; RUN: llc -mtriple=riscv32 -mattr=+zbkc %s -o - | FileCheck --check-prefix=RV32ZBKC %s ; RUN: llc -mtriple=riscv64 -mattr=+m %s -o - | FileCheck --check-prefix=RV64M %s ; RUN: llc -mtriple=riscv64 -mattr=+a %s -o - | FileCheck --check-prefix=RV64A %s ; RUN: llc -mtriple=riscv64 -mattr=+f %s -o - | FileCheck --check-prefix=RV64F %s @@ -40,6 +41,7 @@ ; RUN: llc -mtriple=riscv64 -mattr=+experimental-v %s -o - | FileCheck --check-prefix=RV64V %s ; RUN: llc -mtriple=riscv64 -mattr=+zbb,+zfh,+experimental-v,+f %s -o - | FileCheck --check-prefix=RV64COMBINED %s ; RUN: llc -mtriple=riscv64 -mattr=+zbkb %s -o - | FileCheck --check-prefix=RV64ZBKB %s +; RUN: llc -mtriple=riscv64 -mattr=+zbkc %s -o - | FileCheck --check-prefix=RV64ZBKC %s ; RV32M: .attribute 5, "rv32i2p0_m2p0" @@ -62,6 +64,7 @@ ; RV32V: .attribute 5, "rv32i2p0_f2p0_d2p0_v1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0" ; RV32COMBINED: .attribute 5, "rv32i2p0_f2p0_d2p0_v1p0_zfh1p0_zfhmin1p0_zbb1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0" ; RV32ZBKB: .attribute 5, "rv32i2p0_zbkb1p0" +; RV32ZBKC: .attribute 5, "rv32i2p0_zbkc1p0" ; RV64M: .attribute 5, "rv64i2p0_m2p0" ; RV64A: .attribute 5, "rv64i2p0_a2p0" @@ -83,6 +86,7 @@ ; RV64V: .attribute 5, "rv64i2p0_f2p0_d2p0_v1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0" ; RV64COMBINED: .attribute 5, "rv64i2p0_f2p0_d2p0_v1p0_zfh1p0_zfhmin1p0_zbb1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0" ; RV64ZBKB: .attribute 5, "rv64i2p0_zbkb1p0" +; RV64ZBKC: .attribute 5, "rv64i2p0_zbkc1p0" define i32 @addi(i32 %a) { %1 = add i32 %a, 1 diff --git a/llvm/test/MC/RISCV/attribute-arch.s b/llvm/test/MC/RISCV/attribute-arch.s --- a/llvm/test/MC/RISCV/attribute-arch.s +++ b/llvm/test/MC/RISCV/attribute-arch.s @@ -130,3 +130,6 @@ .attribute arch, "rv32i_zbkb1p0" # CHECK: attribute 5, "rv32i2p0_zbkb1p0" + +.attribute arch, "rv32i_zbkc1p0" +# CHECK: attribute 5, "rv32i2p0_zbkc1p0" diff --git a/llvm/test/MC/RISCV/rv32zbkc-invalid.s b/llvm/test/MC/RISCV/rv32zbkc-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zbkc-invalid.s @@ -0,0 +1,9 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+zbkc < %s 2>&1 | FileCheck %s + +# Too few operands +clmul t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction +# Too few operands +clmulh t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction + +# Undefined zbc instruction in zbkc +clmulr t0, t1, t2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zbc' (Carry-Less 'B' Instructions) diff --git a/llvm/test/MC/RISCV/rv32zbkc-valid.s b/llvm/test/MC/RISCV/rv32zbkc-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zbkc-valid.s @@ -0,0 +1,23 @@ +# With Bitmanip carry-less multiply extension: +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zbkc -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+zbkc -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zbkc < %s \ +# RUN: | llvm-objdump --mattr=+zbkc -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zbkc < %s \ +# RUN: | llvm-objdump --mattr=+zbkc -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zbkc,+zbc -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zbkc,+zbc < %s \ +# RUN: | llvm-objdump --mattr=+zbkc,+zbc -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: clmul t0, t1, t2 +# CHECK-ASM: encoding: [0xb3,0x12,0x73,0x0a] +clmul t0, t1, t2 +# CHECK-ASM-AND-OBJ: clmulh t0, t1, t2 +# CHECK-ASM: encoding: [0xb3,0x32,0x73,0x0a] +clmulh t0, t1, t2