riscv64: Add bitmanip extension flags (#5847)

This commit is contained in:
Afonso Bordado
2023-02-21 22:12:44 +00:00
committed by GitHub
parent bd3dcd313d
commit 6e6a1034d7
6 changed files with 152 additions and 82 deletions

View File

@@ -11,13 +11,50 @@ fn define_settings(_shared: &SettingGroup) -> SettingGroup {
let _has_f = setting.add_bool("has_f", "has extension F?", "", false); let _has_f = setting.add_bool("has_f", "has extension F?", "", false);
let _has_d = setting.add_bool("has_d", "has extension D?", "", false); let _has_d = setting.add_bool("has_d", "has extension D?", "", false);
let _has_v = setting.add_bool("has_v", "has extension V?", "", false); let _has_v = setting.add_bool("has_v", "has extension V?", "", false);
let _has_b = setting.add_bool("has_b", "has extension B?", "", false);
let _has_c = setting.add_bool("has_c", "has extension C?", "", false); let _has_c = setting.add_bool("has_c", "has extension C?", "", false);
let _has_zbkb = setting.add_bool("has_zbkb", "has extension zbkb?", "", false); let _has_zbkb = setting.add_bool(
let _has_zbb = setting.add_bool("has_zbb", "has extension zbb?", "", false); "has_zbkb",
"has extension zbkb?",
"Zbkb: Bit-manipulation for Cryptography",
false,
);
let _has_zba = setting.add_bool(
"has_zba",
"has extension zba?",
"Zba: Address Generation",
false,
);
let _has_zbb = setting.add_bool(
"has_zbb",
"has extension zbb?",
"Zbb: Basic bit-manipulation",
false,
);
let _has_zbc = setting.add_bool(
"has_zbc",
"has extension zbc?",
"Zbc: Carry-less multiplication",
false,
);
let _has_zbx = setting.add_bool(
"has_zbs",
"has extension zbs?",
"Zbs: Single-bit instructions",
false,
);
let _has_zicsr = setting.add_bool("has_zicsr", "has extension zicsr?", "", false); let _has_zicsr = setting.add_bool(
let _has_zifencei = setting.add_bool("has_zifencei", "has extension zifencei?", "", false); "has_zicsr",
"has extension zicsr?",
"Zicsr: Control and Status Register (CSR) Instructions",
false,
);
let _has_zifencei = setting.add_bool(
"has_zifencei",
"has extension zifencei?",
"Zifencei: Instruction-Fetch Fence",
false,
);
setting.build() setting.build()
} }

View File

@@ -531,39 +531,44 @@
(RemU) (RemU)
;; RV64M Standard Extension (in addition to RV32M) ;; RV64M Standard Extension (in addition to RV32M)
(Mulw) (Mulw)
(Divw) (Divw)
(Divuw) (Divuw)
(Remw) (Remw)
(Remuw) (Remuw)
;; bitmapip ;; Zba: Address Generation Instructions
(Adduw) (Adduw)
(Andn)
(Bclr)
(Bext)
(Binv)
(Bset)
(Clmul)
(Clmulh)
(Clmulr)
(Max)
(Maxu)
(Min)
(Minu)
(Orn)
(Rol)
(Rolw)
(Ror)
(Rorw)
(Sh1add) (Sh1add)
(Sh1adduw) (Sh1adduw)
(Sh2add) (Sh2add)
(Sh2adduw) (Sh2adduw)
(Sh3add) (Sh3add)
(Sh3adduw) (Sh3adduw)
;; Zbb: Bit Manipulation Instructions
(Andn)
(Orn)
(Xnor) (Xnor)
(Max)
(Maxu)
(Min)
(Minu)
(Rol)
(Rolw)
(Ror)
(Rorw)
;; Zbs: Single-bit instructions
(Bclr)
(Bext)
(Binv)
(Bset)
;; Zbc: Carry-less multiplication
(Clmul)
(Clmulh)
(Clmulr)
)) ))
@@ -601,6 +606,7 @@
(type AluOPRRI (enum (type AluOPRRI (enum
;; Base ISA
(Addi) (Addi)
(Slti) (Slti)
(SltiU) (SltiU)
@@ -614,25 +620,31 @@
(Slliw) (Slliw)
(SrliW) (SrliW)
(Sraiw) (Sraiw)
;; Zba: Address Generation Instructions
(SlliUw)
;; Zbb: Bit Manipulation Instructions
(Clz)
(Clzw)
(Ctz)
(Ctzw)
(Cpop)
(Cpopw)
(Sextb)
(Sexth)
(Zexth)
(Rori)
(Roriw)
(Rev8)
(Brev8)
(Orcb)
;; Zbs: Single-bit instructions
(Bclri) (Bclri)
(Bexti) (Bexti)
(Binvi) (Binvi)
(Bseti) (Bseti)
(Rori)
(Roriw)
(SlliUw)
(Clz)
(Clzw)
(Cpop)
(Cpopw)
(Ctz)
(Ctzw)
(Rev8)
(Sextb)
(Sexth)
(Zexth)
(Orcb)
(Brev8)
)) ))
@@ -695,6 +707,23 @@
(type AMO (primitive AMO)) (type AMO (primitive AMO))
(type VecMachLabel extern (enum)) (type VecMachLabel extern (enum))
;; ISA Extension helpers
(decl pure has_zbkb () bool)
(extern constructor has_zbkb has_zbkb)
(decl pure has_zba () bool)
(extern constructor has_zba has_zba)
(decl pure has_zbb () bool)
(extern constructor has_zbb has_zbb)
(decl pure has_zbc () bool)
(extern constructor has_zbc has_zbc)
(decl pure has_zbs () bool)
(extern constructor has_zbs has_zbs)
;; Helper for creating the zero register. ;; Helper for creating the zero register.
(decl zero_reg () Reg) (decl zero_reg () Reg)
(extern constructor zero_reg zero_reg) (extern constructor zero_reg zero_reg)
@@ -908,22 +937,24 @@
(decl lower_ctz (Type Reg) Reg) (decl lower_ctz (Type Reg) Reg)
(rule (rule
(lower_ctz ty x) (lower_ctz ty x)
(if-let $false (has_b)) (if-let $false (has_zbb))
(gen_cltz $false x ty)) (gen_cltz $false x ty))
(rule 2 (rule 2
(lower_ctz $I64 x) (lower_ctz $I64 x)
(if-let $true (has_b)) (if-let $true (has_zbb))
(alu_rr_funct12 (AluOPRRI.Ctz) x)) (alu_rr_funct12 (AluOPRRI.Ctz) x))
(rule 2 (rule 2
(lower_ctz $I32 x) (lower_ctz $I32 x)
(if-let $true (has_b)) (if-let $true (has_zbb))
(alu_rr_funct12 (AluOPRRI.Ctzw) x)) (alu_rr_funct12 (AluOPRRI.Ctzw) x))
;;;; for I8 and I16 ;;;; for I8 and I16
(rule 1 (rule 1
(lower_ctz ty x) (lower_ctz ty x)
(if-let $true (has_b)) (if-let $true (has_zbb))
(if-let $true (has_zbs))
(let (let
((tmp Reg (alu_rr_imm12 (AluOPRRI.Bseti) x (imm12_const (ty_bits ty))))) ((tmp Reg (alu_rr_imm12 (AluOPRRI.Bseti) x (imm12_const (ty_bits ty)))))
(alu_rr_funct12 (AluOPRRI.Ctzw) x))) (alu_rr_funct12 (AluOPRRI.Ctzw) x)))
@@ -954,21 +985,21 @@
(decl lower_clz (Type Reg) Reg) (decl lower_clz (Type Reg) Reg)
(rule (rule
(lower_clz ty rs) (lower_clz ty rs)
(if-let $false (has_b)) (if-let $false (has_zbb))
(gen_cltz $true rs ty)) (gen_cltz $true rs ty))
(rule 2 (rule 2
(lower_clz $I64 r) (lower_clz $I64 r)
(if-let $true (has_b)) (if-let $true (has_zbb))
(alu_rr_funct12 (AluOPRRI.Clz) r)) (alu_rr_funct12 (AluOPRRI.Clz) r))
(rule 2 (rule 2
(lower_clz $I32 r) (lower_clz $I32 r)
(if-let $true (has_b)) (if-let $true (has_zbb))
(alu_rr_funct12 (AluOPRRI.Clzw) r)) (alu_rr_funct12 (AluOPRRI.Clzw) r))
;;; for I8 and I16 ;;; for I8 and I16
(rule 1 (rule 1
(lower_clz ty r) (lower_clz ty r)
(if-let $true (has_b)) (if-let $true (has_zbb))
(let (let
( ;; narrow int make all upper bits are zeros. ( ;; narrow int make all upper bits are zeros.
(tmp Reg (ext_int_if_need $false r ty )) (tmp Reg (ext_int_if_need $false r ty ))
@@ -1078,30 +1109,26 @@
(alu_rr_imm12 (AluOPRRI.Srli) tmp (imm12_const (ty_bits ty))))) (alu_rr_imm12 (AluOPRRI.Srli) tmp (imm12_const (ty_bits ty)))))
;;; has extension B??
(decl pure has_b () bool)
(extern constructor has_b has_b)
(decl lower_rotl (Type Reg Reg) Reg) (decl lower_rotl (Type Reg Reg) Reg)
(rule 1 (rule 1
(lower_rotl $I64 rs amount) (lower_rotl $I64 rs amount)
(if-let $true (has_b)) (if-let $true (has_zbb))
(alu_rrr (AluOPRRR.Rol) rs amount)) (alu_rrr (AluOPRRR.Rol) rs amount))
(rule (rule
(lower_rotl $I64 rs amount) (lower_rotl $I64 rs amount)
(if-let $false (has_b)) (if-let $false (has_zbb))
(lower_rotl_shift $I64 rs amount)) (lower_rotl_shift $I64 rs amount))
(rule 1 (rule 1
(lower_rotl $I32 rs amount) (lower_rotl $I32 rs amount)
(if-let $true (has_b)) (if-let $true (has_zbb))
(alu_rrr (AluOPRRR.Rolw) rs amount)) (alu_rrr (AluOPRRR.Rolw) rs amount))
(rule (rule
(lower_rotl $I32 rs amount) (lower_rotl $I32 rs amount)
(if-let $false (has_b)) (if-let $false (has_zbb))
(lower_rotl_shift $I32 rs amount)) (lower_rotl_shift $I32 rs amount))
(rule -1 (rule -1
@@ -1136,21 +1163,21 @@
(rule 1 (rule 1
(lower_rotr $I64 rs amount) (lower_rotr $I64 rs amount)
(if-let $true (has_b)) (if-let $true (has_zbb))
(alu_rrr (AluOPRRR.Ror) rs amount)) (alu_rrr (AluOPRRR.Ror) rs amount))
(rule (rule
(lower_rotr $I64 rs amount) (lower_rotr $I64 rs amount)
(if-let $false (has_b)) (if-let $false (has_zbb))
(lower_rotr_shift $I64 rs amount)) (lower_rotr_shift $I64 rs amount))
(rule 1 (rule 1
(lower_rotr $I32 rs amount) (lower_rotr $I32 rs amount)
(if-let $true (has_b)) (if-let $true (has_zbb))
(alu_rrr (AluOPRRR.Rorw) rs amount)) (alu_rrr (AluOPRRR.Rorw) rs amount))
(rule (rule
(lower_rotr $I32 rs amount) (lower_rotr $I32 rs amount)
(if-let $false (has_b)) (if-let $false (has_zbb))
(lower_rotr_shift $I32 rs amount)) (lower_rotr_shift $I32 rs amount))
(rule -1 (rule -1
@@ -1208,10 +1235,10 @@
(decl lower_popcnt (Reg Type) Reg) (decl lower_popcnt (Reg Type) Reg)
(rule 1 (lower_popcnt rs ty ) (rule 1 (lower_popcnt rs ty )
(if-let $true (has_b)) (if-let $true (has_zbb))
(alu_rr_funct12 (AluOPRRI.Cpop) (ext_int_if_need $false rs ty))) (alu_rr_funct12 (AluOPRRI.Cpop) (ext_int_if_need $false rs ty)))
(rule (lower_popcnt rs ty) (rule (lower_popcnt rs ty)
(if-let $false (has_b)) (if-let $false (has_zbb))
(gen_popcnt rs ty)) (gen_popcnt rs ty))
(decl lower_popcnt_i128 (ValueRegs) ValueRegs) (decl lower_popcnt_i128 (ValueRegs) ValueRegs)
@@ -1962,12 +1989,12 @@
(decl gen_rev8 (Reg) Reg) (decl gen_rev8 (Reg) Reg)
(rule 1 (rule 1
(gen_rev8 rs) (gen_rev8 rs)
(if-let $true (has_b)) (if-let $true (has_zbb))
(alu_rr_funct12 (AluOPRRI.Rev8) rs)) (alu_rr_funct12 (AluOPRRI.Rev8) rs))
(rule (rule
(gen_rev8 rs) (gen_rev8 rs)
(if-let $false (has_b)) (if-let $false (has_zbb))
(let (let
((rd WritableReg (temp_writable_reg $I64)) ((rd WritableReg (temp_writable_reg $I64))
(tmp WritableReg (temp_writable_reg $I64)) (tmp WritableReg (temp_writable_reg $I64))
@@ -1975,11 +2002,6 @@
(_ Unit (emit (MInst.Rev8 rs step tmp rd)))) (_ Unit (emit (MInst.Rev8 rs step tmp rd))))
(writable_reg_to_reg rd))) (writable_reg_to_reg rd)))
(decl pure has_zbkb () bool)
(extern constructor has_zbkb has_zbkb)
(decl pure has_zbb () bool)
(extern constructor has_zbb has_zbb)
(decl gen_brev8 (Reg Type) Reg) (decl gen_brev8 (Reg Type) Reg)
(rule 1 (rule 1

View File

@@ -209,19 +209,19 @@
;; forms early on. ;; forms early on.
(rule 3 (lower (has_type (fits_in_64 ty) (band x (bnot y)))) (rule 3 (lower (has_type (fits_in_64 ty) (band x (bnot y))))
(if-let $true (has_b)) (if-let $true (has_zbb))
(gen_andn x y)) (gen_andn x y))
(rule 4 (lower (has_type (fits_in_64 ty) (band (bnot y) x))) (rule 4 (lower (has_type (fits_in_64 ty) (band (bnot y) x)))
(if-let $true (has_b)) (if-let $true (has_zbb))
(gen_andn x y)) (gen_andn x y))
(rule 5 (lower (has_type $I128 (band x (bnot y)))) (rule 5 (lower (has_type $I128 (band x (bnot y))))
(if-let $true (has_b)) (if-let $true (has_zbb))
(let (let
((low Reg (gen_andn (value_regs_get x 0) (value_regs_get y 0))) ((low Reg (gen_andn (value_regs_get x 0) (value_regs_get y 0)))
(high Reg (gen_andn (value_regs_get x 1) (value_regs_get y 1)))) (high Reg (gen_andn (value_regs_get x 1) (value_regs_get y 1))))
(value_regs low high))) (value_regs low high)))
(rule 6 (lower (has_type $I128 (band (bnot y) x))) (rule 6 (lower (has_type $I128 (band (bnot y) x)))
(if-let $true (has_b)) (if-let $true (has_zbb))
(let (let
((low Reg (gen_andn (value_regs_get x 0) (value_regs_get y 0))) ((low Reg (gen_andn (value_regs_get x 0) (value_regs_get y 0)))
(high Reg (gen_andn (value_regs_get x 1) (value_regs_get y 1)))) (high Reg (gen_andn (value_regs_get x 1) (value_regs_get y 1))))
@@ -250,20 +250,20 @@
;; forms early on. ;; forms early on.
(rule 3 (lower (has_type (fits_in_64 ty) (bor x (bnot y)))) (rule 3 (lower (has_type (fits_in_64 ty) (bor x (bnot y))))
(if-let $true (has_b)) (if-let $true (has_zbb))
(gen_orn x y)) (gen_orn x y))
(rule 4 (lower (has_type (fits_in_64 ty) (bor (bnot y) x))) (rule 4 (lower (has_type (fits_in_64 ty) (bor (bnot y) x)))
(if-let $true (has_b)) (if-let $true (has_zbb))
(gen_orn x y)) (gen_orn x y))
(rule 5 (lower (has_type $I128 (bor x (bnot y)))) (rule 5 (lower (has_type $I128 (bor x (bnot y))))
(if-let $true (has_b)) (if-let $true (has_zbb))
(let (let
((low Reg (gen_orn (value_regs_get x 0) (value_regs_get y 0))) ((low Reg (gen_orn (value_regs_get x 0) (value_regs_get y 0)))
(high Reg (gen_orn (value_regs_get x 1) (value_regs_get y 1)))) (high Reg (gen_orn (value_regs_get x 1) (value_regs_get y 1))))
(value_regs low high))) (value_regs low high)))
(rule 6 (lower (has_type $I128 (bor (bnot y) x))) (rule 6 (lower (has_type $I128 (bor (bnot y) x)))
(if-let $true (has_b)) (if-let $true (has_zbb))
(let (let
((low Reg (gen_orn (value_regs_get x 0) (value_regs_get y 0))) ((low Reg (gen_orn (value_regs_get x 0) (value_regs_get y 0)))
(high Reg (gen_orn (value_regs_get x 1) (value_regs_get y 1)))) (high Reg (gen_orn (value_regs_get x 1) (value_regs_get y 1))))

View File

@@ -279,16 +279,26 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Riscv64Backend> {
ValueRegs::two(shamt, len_sub_shamt) ValueRegs::two(shamt, len_sub_shamt)
} }
fn has_b(&mut self) -> bool {
self.backend.isa_flags.has_b()
}
fn has_zbkb(&mut self) -> bool { fn has_zbkb(&mut self) -> bool {
self.backend.isa_flags.has_zbkb() self.backend.isa_flags.has_zbkb()
} }
fn has_zba(&mut self) -> bool {
self.backend.isa_flags.has_zba()
}
fn has_zbb(&mut self) -> bool { fn has_zbb(&mut self) -> bool {
self.backend.isa_flags.has_zbb() self.backend.isa_flags.has_zbb()
} }
fn has_zbc(&mut self) -> bool {
self.backend.isa_flags.has_zbc()
}
fn has_zbs(&mut self) -> bool {
self.backend.isa_flags.has_zbs()
}
fn inst_output_get(&mut self, x: InstOutput, index: u8) -> ValueRegs { fn inst_output_get(&mut self, x: InstOutput, index: u8) -> ValueRegs {
x[index as usize] x[index as usize]
} }

View File

@@ -1,6 +1,6 @@
test compile precise-output test compile precise-output
set opt_level=speed set opt_level=speed
target riscv64 has_b target riscv64 has_zbb
function %band_not_i32(i32, i32) -> i32 { function %band_not_i32(i32, i32) -> i32 {
block0(v0: i32, v1: i32): block0(v0: i32, v1: i32):

View File

@@ -213,8 +213,9 @@ pub fn builder_with_options(infer_native_flags: bool) -> Result<isa::Builder, &'
isa_builder.enable("has_v").unwrap(); isa_builder.enable("has_v").unwrap();
} }
// TODO: ZiFencei does not have a bit associated with it // In general extensions that are longer than one letter
// TODO: Zbkb does not have a bit associated with it // won't have a bit associated with them. The Linux kernel
// is currently working on a new way to query the extensions.
} }
// squelch warnings about unused mut/variables on some platforms. // squelch warnings about unused mut/variables on some platforms.