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_d = setting.add_bool("has_d", "has extension D?", "", 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_zbkb = setting.add_bool("has_zbkb", "has extension zbkb?", "", false);
let _has_zbb = setting.add_bool("has_zbb", "has extension zbb?", "", false);
let _has_zbkb = setting.add_bool(
"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_zifencei = setting.add_bool("has_zifencei", "has extension zifencei?", "", false);
let _has_zicsr = setting.add_bool(
"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()
}

View File

@@ -531,39 +531,44 @@
(RemU)
;; RV64M Standard Extension (in addition to RV32M)
(Mulw)
(Divw)
(Divuw)
(Remw)
(Remuw)
;; bitmapip
;; Zba: Address Generation Instructions
(Adduw)
(Andn)
(Bclr)
(Bext)
(Binv)
(Bset)
(Clmul)
(Clmulh)
(Clmulr)
(Max)
(Maxu)
(Min)
(Minu)
(Orn)
(Rol)
(Rolw)
(Ror)
(Rorw)
(Sh1add)
(Sh1adduw)
(Sh2add)
(Sh2adduw)
(Sh3add)
(Sh3adduw)
;; Zbb: Bit Manipulation Instructions
(Andn)
(Orn)
(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
;; Base ISA
(Addi)
(Slti)
(SltiU)
@@ -614,25 +620,31 @@
(Slliw)
(SrliW)
(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)
(Bexti)
(Binvi)
(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 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.
(decl zero_reg () Reg)
(extern constructor zero_reg zero_reg)
@@ -908,22 +937,24 @@
(decl lower_ctz (Type Reg) Reg)
(rule
(lower_ctz ty x)
(if-let $false (has_b))
(if-let $false (has_zbb))
(gen_cltz $false x ty))
(rule 2
(lower_ctz $I64 x)
(if-let $true (has_b))
(if-let $true (has_zbb))
(alu_rr_funct12 (AluOPRRI.Ctz) x))
(rule 2
(lower_ctz $I32 x)
(if-let $true (has_b))
(if-let $true (has_zbb))
(alu_rr_funct12 (AluOPRRI.Ctzw) x))
;;;; for I8 and I16
(rule 1
(lower_ctz ty x)
(if-let $true (has_b))
(if-let $true (has_zbb))
(if-let $true (has_zbs))
(let
((tmp Reg (alu_rr_imm12 (AluOPRRI.Bseti) x (imm12_const (ty_bits ty)))))
(alu_rr_funct12 (AluOPRRI.Ctzw) x)))
@@ -954,21 +985,21 @@
(decl lower_clz (Type Reg) Reg)
(rule
(lower_clz ty rs)
(if-let $false (has_b))
(if-let $false (has_zbb))
(gen_cltz $true rs ty))
(rule 2
(lower_clz $I64 r)
(if-let $true (has_b))
(if-let $true (has_zbb))
(alu_rr_funct12 (AluOPRRI.Clz) r))
(rule 2
(lower_clz $I32 r)
(if-let $true (has_b))
(if-let $true (has_zbb))
(alu_rr_funct12 (AluOPRRI.Clzw) r))
;;; for I8 and I16
(rule 1
(lower_clz ty r)
(if-let $true (has_b))
(if-let $true (has_zbb))
(let
( ;; narrow int make all upper bits are zeros.
(tmp Reg (ext_int_if_need $false r ty ))
@@ -1078,30 +1109,26 @@
(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)
(rule 1
(lower_rotl $I64 rs amount)
(if-let $true (has_b))
(if-let $true (has_zbb))
(alu_rrr (AluOPRRR.Rol) rs amount))
(rule
(lower_rotl $I64 rs amount)
(if-let $false (has_b))
(if-let $false (has_zbb))
(lower_rotl_shift $I64 rs amount))
(rule 1
(lower_rotl $I32 rs amount)
(if-let $true (has_b))
(if-let $true (has_zbb))
(alu_rrr (AluOPRRR.Rolw) rs amount))
(rule
(lower_rotl $I32 rs amount)
(if-let $false (has_b))
(if-let $false (has_zbb))
(lower_rotl_shift $I32 rs amount))
(rule -1
@@ -1136,21 +1163,21 @@
(rule 1
(lower_rotr $I64 rs amount)
(if-let $true (has_b))
(if-let $true (has_zbb))
(alu_rrr (AluOPRRR.Ror) rs amount))
(rule
(lower_rotr $I64 rs amount)
(if-let $false (has_b))
(if-let $false (has_zbb))
(lower_rotr_shift $I64 rs amount))
(rule 1
(lower_rotr $I32 rs amount)
(if-let $true (has_b))
(if-let $true (has_zbb))
(alu_rrr (AluOPRRR.Rorw) rs amount))
(rule
(lower_rotr $I32 rs amount)
(if-let $false (has_b))
(if-let $false (has_zbb))
(lower_rotr_shift $I32 rs amount))
(rule -1
@@ -1208,10 +1235,10 @@
(decl lower_popcnt (Reg Type) Reg)
(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)))
(rule (lower_popcnt rs ty)
(if-let $false (has_b))
(if-let $false (has_zbb))
(gen_popcnt rs ty))
(decl lower_popcnt_i128 (ValueRegs) ValueRegs)
@@ -1962,12 +1989,12 @@
(decl gen_rev8 (Reg) Reg)
(rule 1
(gen_rev8 rs)
(if-let $true (has_b))
(if-let $true (has_zbb))
(alu_rr_funct12 (AluOPRRI.Rev8) rs))
(rule
(gen_rev8 rs)
(if-let $false (has_b))
(if-let $false (has_zbb))
(let
((rd WritableReg (temp_writable_reg $I64))
(tmp WritableReg (temp_writable_reg $I64))
@@ -1975,11 +2002,6 @@
(_ Unit (emit (MInst.Rev8 rs step tmp 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)
(rule 1

View File

@@ -209,19 +209,19 @@
;; forms early on.
(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))
(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))
(rule 5 (lower (has_type $I128 (band x (bnot y))))
(if-let $true (has_b))
(if-let $true (has_zbb))
(let
((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))))
(value_regs low high)))
(rule 6 (lower (has_type $I128 (band (bnot y) x)))
(if-let $true (has_b))
(if-let $true (has_zbb))
(let
((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))))
@@ -250,20 +250,20 @@
;; forms early on.
(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))
(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))
(rule 5 (lower (has_type $I128 (bor x (bnot y))))
(if-let $true (has_b))
(if-let $true (has_zbb))
(let
((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))))
(value_regs low high)))
(rule 6 (lower (has_type $I128 (bor (bnot y) x)))
(if-let $true (has_b))
(if-let $true (has_zbb))
(let
((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))))

View File

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

View File

@@ -1,6 +1,6 @@
test compile precise-output
set opt_level=speed
target riscv64 has_b
target riscv64 has_zbb
function %band_not_i32(i32, i32) -> 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();
}
// TODO: ZiFencei does not have a bit associated with it
// TODO: Zbkb does not have a bit associated with it
// In general extensions that are longer than one letter
// 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.