diff --git a/cranelift/codegen/meta/src/isa/riscv64.rs b/cranelift/codegen/meta/src/isa/riscv64.rs index 3b1cc6254836..00b3bd6c69d2 100644 --- a/cranelift/codegen/meta/src/isa/riscv64.rs +++ b/cranelift/codegen/meta/src/isa/riscv64.rs @@ -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() } diff --git a/cranelift/codegen/src/isa/riscv64/inst.isle b/cranelift/codegen/src/isa/riscv64/inst.isle index c7e63d8d96d9..46fbd8f4c1f3 100644 --- a/cranelift/codegen/src/isa/riscv64/inst.isle +++ b/cranelift/codegen/src/isa/riscv64/inst.isle @@ -531,39 +531,44 @@ (RemU) ;; RV64M Standard Extension (in addition to RV32M) - (Mulw) (Divw) (Divuw) (Remw) (Remuw) - ;; bitmapip + ;; Zba: Address Generation Instructions (Adduw) + (Sh1add) + (Sh1adduw) + (Sh2add) + (Sh2adduw) + (Sh3add) + (Sh3adduw) + + ;; Zbb: Bit Manipulation Instructions (Andn) - (Bclr) - (Bext) - (Binv) - (Bset) - (Clmul) - (Clmulh) - (Clmulr) + (Orn) + (Xnor) (Max) (Maxu) (Min) (Minu) - (Orn) (Rol) (Rolw) (Ror) (Rorw) - (Sh1add) - (Sh1adduw) - (Sh2add) - (Sh2adduw) - (Sh3add) - (Sh3adduw) - (Xnor) + + ;; 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) - (Bclri) - (Bexti) - (Binvi) - (Bseti) - (Rori) - (Roriw) + + ;; Zba: Address Generation Instructions (SlliUw) + + ;; Zbb: Bit Manipulation Instructions (Clz) (Clzw) - (Cpop) - (Cpopw) (Ctz) (Ctzw) - (Rev8) + (Cpop) + (Cpopw) (Sextb) (Sexth) (Zexth) - (Orcb) + (Rori) + (Roriw) + (Rev8) (Brev8) + (Orcb) + + ;; Zbs: Single-bit instructions + (Bclri) + (Bexti) + (Binvi) + (Bseti) )) @@ -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 diff --git a/cranelift/codegen/src/isa/riscv64/lower.isle b/cranelift/codegen/src/isa/riscv64/lower.isle index fdaa7102c4fe..9813c184f2d2 100644 --- a/cranelift/codegen/src/isa/riscv64/lower.isle +++ b/cranelift/codegen/src/isa/riscv64/lower.isle @@ -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)))) diff --git a/cranelift/codegen/src/isa/riscv64/lower/isle.rs b/cranelift/codegen/src/isa/riscv64/lower/isle.rs index 97852c0c446d..368e5959a8cd 100644 --- a/cranelift/codegen/src/isa/riscv64/lower/isle.rs +++ b/cranelift/codegen/src/isa/riscv64/lower/isle.rs @@ -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] } diff --git a/cranelift/filetests/filetests/isa/riscv64/bitops-optimized.clif b/cranelift/filetests/filetests/isa/riscv64/bitops-optimized.clif index 75c3863fe7a3..901161bb5da6 100644 --- a/cranelift/filetests/filetests/isa/riscv64/bitops-optimized.clif +++ b/cranelift/filetests/filetests/isa/riscv64/bitops-optimized.clif @@ -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): diff --git a/cranelift/native/src/lib.rs b/cranelift/native/src/lib.rs index 653b2dc3ab99..3becbeb1e639 100644 --- a/cranelift/native/src/lib.rs +++ b/cranelift/native/src/lib.rs @@ -213,8 +213,9 @@ pub fn builder_with_options(infer_native_flags: bool) -> Result