[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
This commit is contained in:
SForeKeeper 2022-01-24 20:33:46 +08:00
parent b7f69b8d46
commit 70f83f3084
10 changed files with 83 additions and 20 deletions

View File

@ -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;

View File

@ -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]>;

View File

@ -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>;

View File

@ -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];
}
//===----------------------------------------------------------------------===//

View File

@ -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.

View File

@ -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; }

View File

@ -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

View File

@ -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"

View File

@ -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)

View File

@ -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