Skip to content

Commit

Permalink
riscv64: Add bitmanip extension flags (bytecodealliance#5847)
Browse files Browse the repository at this point in the history
  • Loading branch information
afonso360 authored Feb 21, 2023
1 parent bd3dcd3 commit 6e6a103
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 75 deletions.
47 changes: 42 additions & 5 deletions cranelift/codegen/meta/src/isa/riscv64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
134 changes: 78 additions & 56 deletions cranelift/codegen/src/isa/riscv64/inst.isle
Original file line number Diff line number Diff line change
Expand Up @@ -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)
))


Expand Down Expand Up @@ -601,6 +606,7 @@


(type AluOPRRI (enum
;; Base ISA
(Addi)
(Slti)
(SltiU)
Expand All @@ -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)
))


Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)))
Expand Down Expand Up @@ -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 ))
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -1962,24 +1989,19 @@
(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))
(step WritableReg (temp_writable_reg $I64))
(_ 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
Expand Down
16 changes: 8 additions & 8 deletions cranelift/codegen/src/isa/riscv64/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -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))))
Expand Down Expand Up @@ -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))))
Expand Down
Loading

0 comments on commit 6e6a103

Please sign in to comment.