From 70f83f308449710a55c4898f18f06949df2d1559 Mon Sep 17 00:00:00 2001 From: SForeKeeper Date: Mon, 24 Jan 2022 20:33:46 +0800 Subject: [PATCH] [RISCV] add support for zbkx subextension in MC layer. This patch adds support for zbkx extension from K extension(v1.0.0) in MC layer. Instructions with same functionality and same encoding is defined in the bitmanip extension. It defines {Xperm8, Xperm4} as instruction aliases for xperm.* in Zbp extension. When Zbkx is enabled while Zbp is not, xperm.h will not be available. When Zbkx and Zbp are both enabled, the instructions will be decoded in Zbp format. [[ https://reviews.llvm.org/D94999 | D94999 ]] this is the patch that introduces xperm.* instructions. Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D117889 --- llvm/lib/Support/RISCVISAInfo.cpp | 5 +++-- llvm/lib/Target/RISCV/RISCV.td | 15 +++++++++++++++ llvm/lib/Target/RISCV/RISCVInstrInfoZb.td | 15 +++++++++++++-- llvm/lib/Target/RISCV/RISCVSchedRocket.td | 8 ++++---- llvm/lib/Target/RISCV/RISCVSchedSiFive7.td | 7 ++++--- llvm/lib/Target/RISCV/RISCVSubtarget.h | 2 ++ llvm/test/CodeGen/RISCV/attributes.ll | 16 ++++++++++------ llvm/test/MC/RISCV/attribute-arch.s | 9 ++++++--- llvm/test/MC/RISCV/rv32zbkx-invalid.s | 9 +++++++++ llvm/test/MC/RISCV/rv32zbkx-valid.s | 17 +++++++++++++++++ 10 files changed, 83 insertions(+), 20 deletions(-) create mode 100644 llvm/test/MC/RISCV/rv32zbkx-invalid.s create mode 100644 llvm/test/MC/RISCV/rv32zbkx-valid.s diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp index e6df48e5bb41..55a644e98aac 100644 --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -58,6 +58,7 @@ static const RISCVSupportedExtension SupportedExtensions[] = { {"zbkb", RISCVExtensionVersion{1, 0}}, {"zbkc", RISCVExtensionVersion{1, 0}}, + {"zbkx", RISCVExtensionVersion{1, 0}}, {"zknd", RISCVExtensionVersion{1, 0}}, {"zkne", RISCVExtensionVersion{1, 0}}, {"zknh", RISCVExtensionVersion{1, 0}}, @@ -770,8 +771,8 @@ static const char *ImpliedExtsZvl256b[] = {"zvl128b"}; static const char *ImpliedExtsZvl128b[] = {"zvl64b"}; static const char *ImpliedExtsZvl64b[] = {"zvl32b"}; static const char *ImpliedExtsZk[] = {"zkn", "zkt", "zkr"}; -static const char *ImpliedExtsZkn[] = {"zbkb", "zbkc", "zkne", "zknd", "zknh"}; -static const char *ImpliedExtsZks[] = {"zbkb", "zbkc", "zksed", "zksh"}; +static const char *ImpliedExtsZkn[] = {"zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"}; +static const char *ImpliedExtsZks[] = {"zbkb", "zbkc", "zbkx", "zksed", "zksh"}; struct ImpliedExtsEntry { StringLiteral Name; diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td index cd8885f6a6e8..aea082d0a0f0 100644 --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -150,6 +150,19 @@ def HasStdExtZbkb : Predicate<"Subtarget->hasStdExtZbkb()">, AssemblerPredicate<(all_of FeatureStdExtZbkb), "'Zbkb' (Bitmanip instructions for Cryptography)">; +def FeatureStdExtZbkx + : SubtargetFeature<"zbkx", "HasStdExtZbkx", "true", + "'Zbkx' (Crossbar permutation instructions)">; +def HasStdExtZbkx : Predicate<"Subtarget->hasStdExtZbkx()">, + AssemblerPredicate<(all_of FeatureStdExtZbkx), + "'Zbkx' (Crossbar permutation instructions)">; + +def HasStdExtZbpOrZbkx + : Predicate<"Subtarget->hasStdExtZbp() || Subtarget->hasStdExtZbkx()">, + AssemblerPredicate<(any_of FeatureStdExtZbp, FeatureStdExtZbkx), + "'Zbp' (Permutation 'Zb' Instructions) or " + "'Zbkx' (Crossbar permutation instructions)">; + def HasStdExtZbpOrZbkb : Predicate<"Subtarget->hasStdExtZbp() || Subtarget->hasStdExtZbkb()">, AssemblerPredicate<(any_of FeatureStdExtZbp, FeatureStdExtZbkb), @@ -233,6 +246,7 @@ def FeatureStdExtZkn "'Zkn' (NIST Algorithm Suite)", [FeatureStdExtZbkb, FeatureStdExtZbkc, + FeatureStdExtZbkx, FeatureStdExtZkne, FeatureStdExtZknd, FeatureStdExtZknh]>; @@ -242,6 +256,7 @@ def FeatureStdExtZks "'Zks' (ShangMi Algorithm Suite)", [FeatureStdExtZbkb, FeatureStdExtZbkc, + FeatureStdExtZbkx, FeatureStdExtZksed, FeatureStdExtZksh]>; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td index 25c5c35c0350..75f9ec98cc1a 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td @@ -27,6 +27,7 @@ // versions: // Zbkb - 1.0 // Zbkc - 1.0 +// Zbkx - 1.0 // //===----------------------------------------------------------------------===// @@ -359,9 +360,12 @@ def GORC : ALU_rr<0b0010100, 0b101, "gorc">, Sched<[]>; def GREV : ALU_rr<0b0110100, 0b101, "grev">, Sched<[]>; } // Predicates = [HasStdExtZbp] +let Predicates = [HasStdExtZbpOrZbkx] in { +def XPERMN : ALU_rr<0b0010100, 0b010, "xperm4">, Sched<[]>; +def XPERMB : ALU_rr<0b0010100, 0b100, "xperm8">, Sched<[]>; +} // Predicates = [HasStdExtZbpOrZbkx] + let Predicates = [HasStdExtZbp] in { -def XPERMN : ALU_rr<0b0010100, 0b010, "xperm.n">, Sched<[]>; -def XPERMB : ALU_rr<0b0010100, 0b100, "xperm.b">, Sched<[]>; def XPERMH : ALU_rr<0b0010100, 0b110, "xperm.h">, Sched<[]>; } // Predicates = [HasStdExtZbp] @@ -768,6 +772,13 @@ def : InstAlias<"gorcw $rd, $rs1, $shamt", (GORCIW GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>; } // Predicates = [HasStdExtZbp, IsRV64] +// Zbp is unratified and that it would likely adopt the already ratified Zbkx names. +// Thus current Zbp instructions are defined as aliases for Zbkx instructions. +let Predicates = [HasStdExtZbp] in { + def : InstAlias<"xperm.b $rd, $rs1, $rs2", (XPERMB GPR:$rd, GPR:$rs1, GPR:$rs2)>; + def : InstAlias<"xperm.n $rd, $rs1, $rs2", (XPERMN GPR:$rd, GPR:$rs1, GPR:$rs2)>; +} // Predicates = [HasStdExtZbp] + let Predicates = [HasStdExtZbs] in { def : InstAlias<"bset $rd, $rs1, $shamt", (BSETI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>; diff --git a/llvm/lib/Target/RISCV/RISCVSchedRocket.td b/llvm/lib/Target/RISCV/RISCVSchedRocket.td index 92dd3175a460..78cf34c8c582 100644 --- a/llvm/lib/Target/RISCV/RISCVSchedRocket.td +++ b/llvm/lib/Target/RISCV/RISCVSchedRocket.td @@ -17,10 +17,10 @@ def RocketModel : SchedMachineModel { let LoadLatency = 3; let MispredictPenalty = 3; let CompleteModel = false; - let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasStdExtZknd, - HasStdExtZkne, HasStdExtZknh, HasStdExtZksed, - HasStdExtZksh, HasStdExtZkr, HasVInstructions, - HasVInstructionsI64]; + let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasStdExtZbkx, + HasStdExtZknd, HasStdExtZkne, HasStdExtZknh, + HasStdExtZksed, HasStdExtZksh, HasStdExtZkr, + HasVInstructions, HasVInstructionsI64]; } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td index e5eaad2a6dd0..9f5e5ff1223c 100644 --- a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td +++ b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td @@ -15,9 +15,10 @@ def SiFive7Model : SchedMachineModel { let LoadLatency = 3; let MispredictPenalty = 3; let CompleteModel = 0; - let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasStdExtZknd, - HasStdExtZkne, HasStdExtZknh, HasStdExtZksed, - HasStdExtZksh, HasStdExtZkr, HasVInstructions]; + let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasStdExtZbkx, + HasStdExtZknd, HasStdExtZkne, HasStdExtZknh, + HasStdExtZksed, HasStdExtZksh, HasStdExtZkr, + 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 index 62b3d5435077..8f32e88d57c0 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -85,6 +85,7 @@ private: bool HasStdExtZfh = false; bool HasStdExtZbkb = false; bool HasStdExtZbkc = false; + bool HasStdExtZbkx = false; bool HasStdExtZknd = false; bool HasStdExtZkne = false; bool HasStdExtZknh = false; @@ -170,6 +171,7 @@ public: bool hasStdExtZfh() const { return HasStdExtZfh; } bool hasStdExtZbkb() const { return HasStdExtZbkb; } bool hasStdExtZbkc() const { return HasStdExtZbkc; } + bool hasStdExtZbkx() const { return HasStdExtZbkx; } bool hasStdExtZknd() const { return HasStdExtZknd; } bool hasStdExtZkne() const { return HasStdExtZkne; } bool hasStdExtZknh() const { return HasStdExtZknh; } diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll index 86b384f6df6f..32a852050a5e 100644 --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -21,6 +21,7 @@ ; RUN: llc -mtriple=riscv32 -mattr=+zbb,+zfh,+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=riscv32 -mattr=+zbkx %s -o - | FileCheck --check-prefix=RV32ZBKX %s ; RUN: llc -mtriple=riscv32 -mattr=+zknd %s -o - | FileCheck --check-prefix=RV32ZKND %s ; RUN: llc -mtriple=riscv32 -mattr=+zkne %s -o - | FileCheck --check-prefix=RV32ZKNE %s ; RUN: llc -mtriple=riscv32 -mattr=+zknh %s -o - | FileCheck --check-prefix=RV32ZKNH %s @@ -52,6 +53,7 @@ ; RUN: llc -mtriple=riscv64 -mattr=+zbb,+zfh,+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 +; RUN: llc -mtriple=riscv64 -mattr=+zbkx %s -o - | FileCheck --check-prefix=RV64ZBKX %s ; RUN: llc -mtriple=riscv64 -mattr=+zknd %s -o - | FileCheck --check-prefix=RV64ZKND %s ; RUN: llc -mtriple=riscv64 -mattr=+zkne %s -o - | FileCheck --check-prefix=RV64ZKNE %s ; RUN: llc -mtriple=riscv64 -mattr=+zknh %s -o - | FileCheck --check-prefix=RV64ZKNH %s @@ -84,16 +86,17 @@ ; RV32COMBINED: .attribute 5, "rv32i2p0_f2p0_d2p0_v1p0_zfh1p0_zfhmin1p0_zbb1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0" ; RV32ZBKB: .attribute 5, "rv32i2p0_zbkb1p0" ; RV32ZBKC: .attribute 5, "rv32i2p0_zbkc1p0" +; RV32ZBKX: .attribute 5, "rv32i2p0_zbkx1p0" ; RV32ZKND: .attribute 5, "rv32i2p0_zknd1p0" ; RV32ZKNE: .attribute 5, "rv32i2p0_zkne1p0" ; RV32ZKNH: .attribute 5, "rv32i2p0_zknh1p0" ; RV32ZKSED: .attribute 5, "rv32i2p0_zksed1p0" ; RV32ZKSH: .attribute 5, "rv32i2p0_zksh1p0" ; RV32ZKR: .attribute 5, "rv32i2p0_zkr1p0" -; RV32ZKN: .attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0" -; RV32ZKS: .attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zks1p0_zksed1p0_zksh1p0" +; RV32ZKN: .attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zbkx1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0" +; RV32ZKS: .attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zbkx1p0_zks1p0_zksed1p0_zksh1p0" ; RV32ZKT: .attribute 5, "rv32i2p0_zkt1p0" -; RV32ZK: .attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zk1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0" +; RV32ZK: .attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zbkx1p0_zk1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0" ; RV64M: .attribute 5, "rv64i2p0_m2p0" ; RV64A: .attribute 5, "rv64i2p0_a2p0" @@ -116,16 +119,17 @@ ; RV64COMBINED: .attribute 5, "rv64i2p0_f2p0_d2p0_v1p0_zfh1p0_zfhmin1p0_zbb1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0" ; RV64ZBKB: .attribute 5, "rv64i2p0_zbkb1p0" ; RV64ZBKC: .attribute 5, "rv64i2p0_zbkc1p0" +; RV64ZBKX: .attribute 5, "rv64i2p0_zbkx1p0" ; RV64ZKND: .attribute 5, "rv64i2p0_zknd1p0" ; RV64ZKNE: .attribute 5, "rv64i2p0_zkne1p0" ; RV64ZKNH: .attribute 5, "rv64i2p0_zknh1p0" ; RV64ZKSED: .attribute 5, "rv64i2p0_zksed1p0" ; RV64ZKSH: .attribute 5, "rv64i2p0_zksh1p0" ; RV64ZKR: .attribute 5, "rv64i2p0_zkr1p0" -; RV64ZKN: .attribute 5, "rv64i2p0_zbkb1p0_zbkc1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0" -; RV64ZKS: .attribute 5, "rv64i2p0_zbkb1p0_zbkc1p0_zks1p0_zksed1p0_zksh1p0" +; RV64ZKN: .attribute 5, "rv64i2p0_zbkb1p0_zbkc1p0_zbkx1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0" +; RV64ZKS: .attribute 5, "rv64i2p0_zbkb1p0_zbkc1p0_zbkx1p0_zks1p0_zksed1p0_zksh1p0" ; RV64ZKT: .attribute 5, "rv64i2p0_zkt1p0" -; RV64ZK: .attribute 5, "rv64i2p0_zbkb1p0_zbkc1p0_zk1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0" +; RV64ZK: .attribute 5, "rv64i2p0_zbkb1p0_zbkc1p0_zbkx1p0_zk1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0" 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 index d39566eb81cd..ee2c6fd6af9b 100644 --- a/llvm/test/MC/RISCV/attribute-arch.s +++ b/llvm/test/MC/RISCV/attribute-arch.s @@ -131,6 +131,9 @@ .attribute arch, "rv32i_zbkc1p0" # CHECK: attribute 5, "rv32i2p0_zbkc1p0" +.attribute arch, "rv32i_zbkx1p0" +# CHECK: attribute 5, "rv32i2p0_zbkx1p0" + .attribute arch, "rv32i_zknd1p0" # CHECK: attribute 5, "rv32i2p0_zknd1p0" @@ -150,13 +153,13 @@ # CHECK: attribute 5, "rv32i2p0_zkr1p0" .attribute arch, "rv32i_zkn1p0" -# CHECK: attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0" +# CHECK: attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zbkx1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0" .attribute arch, "rv32i_zks1p0" -# CHECK: attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zks1p0_zksed1p0_zksh1p0" +# CHECK: attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zbkx1p0_zks1p0_zksed1p0_zksh1p0" .attribute arch, "rv32i_zkt1p0" # CHECK: attribute 5, "rv32i2p0_zkt1p0" .attribute arch, "rv32i_zk1p0" -# CHECK: attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zk1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0" +# CHECK: attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zbkx1p0_zk1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0" diff --git a/llvm/test/MC/RISCV/rv32zbkx-invalid.s b/llvm/test/MC/RISCV/rv32zbkx-invalid.s new file mode 100644 index 000000000000..d79a2afb391a --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zbkx-invalid.s @@ -0,0 +1,9 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+zbkx < %s 2>&1 | FileCheck %s + +# Too few operands +xperm8 t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction +# Too few operands +xperm4 t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction + +# Undefined Zbp instruction in Zbkx +xperm.h t0, t1, t2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zbp' (Permutation 'B' Instructions) \ No newline at end of file diff --git a/llvm/test/MC/RISCV/rv32zbkx-valid.s b/llvm/test/MC/RISCV/rv32zbkx-valid.s new file mode 100644 index 000000000000..6567dfed8ba7 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zbkx-valid.s @@ -0,0 +1,17 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zbkx -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+zbkx -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=zbkx < %s \ +# RUN: | llvm-objdump --mattr=+zbkx -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=zbkx < %s \ +# RUN: | llvm-objdump --mattr=+zbkx -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: xperm8 t0, t1, t2 +# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x28] +xperm8 t0, t1, t2 +# CHECK-ASM-AND-OBJ: xperm4 t0, t1, t2 +# CHECK-ASM: encoding: [0xb3,0x22,0x73,0x28] +xperm4 t0, t1, t2