Skip to content

Commit

Permalink
riscv64: Implement SIMD bitwise operations (bytecodealliance#6419)
Browse files Browse the repository at this point in the history
* riscv64: Implement SIMD `bitselect`

* riscv64: Add SIMD ` bnot`

* riscv64: Add `bxor` splat rules

* riscv64: Add SIMD `bor` optimizations

* riscv64: Add SIMD `band` splat rules

* riscv64: Fix tests

* riscv64: Restrict `.vx` rules to integer arguments

* riscv64: Add `splat` note
  • Loading branch information
afonso360 authored May 22, 2023
1 parent ac96ebb commit 2bbae47
Show file tree
Hide file tree
Showing 22 changed files with 2,316 additions and 75 deletions.
1 change: 0 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ fn ignore(testsuite: &str, testname: &str, strategy: &str) -> bool {
"load_splat_out_of_bounds",
"simd_align",
"simd_bit_shift",
"simd_bitwise",
"simd_boolean",
"simd_conversions",
"simd_f32x4",
Expand Down
17 changes: 4 additions & 13 deletions cranelift/codegen/src/isa/riscv64/inst.isle
Original file line number Diff line number Diff line change
Expand Up @@ -1365,6 +1365,10 @@
(decl imm5_from_u64 (Imm5) u64)
(extern extractor imm5_from_u64 imm5_from_u64)

;; Construct a Imm5 from an i8
(decl pure partial imm5_from_i8 (i8) Imm5)
(extern constructor imm5_from_i8 imm5_from_i8)

;; Extractor that matches a `Value` equivalent to a replicated Imm5 on all lanes.
;; TODO: Try matching vconst here as well
(decl replicated_imm5 (Imm5) Value)
Expand Down Expand Up @@ -2215,19 +2219,6 @@
(decl alloc_vec_writable (Type) VecWritableReg)
(extern constructor alloc_vec_writable alloc_vec_writable)

(decl gen_bitselect (Type Reg Reg Reg) Reg)
(rule
(gen_bitselect ty c x y)
(let
((tmp_x Reg (rv_and c x))
;;;inverse condition
(c_inverse Reg (rv_not c))
;;;get all y part.
(tmp_y Reg (rv_and c_inverse y))
;;;get reuslt.
(result Reg (rv_or tmp_x tmp_y)))
result))

(decl gen_int_select (Type IntSelectOP ValueRegs ValueRegs) ValueRegs)
(rule
(gen_int_select ty op x y)
Expand Down
9 changes: 7 additions & 2 deletions cranelift/codegen/src/isa/riscv64/inst/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub use crate::isa::riscv64::lower::isle::generated_code::{
AluOPRRI, AluOPRRR, AtomicOP, FClassResult, FFlagsException, FloatRoundOP, FloatSelectOP,
FpuOPRR, FpuOPRRR, FpuOPRRRR, IntSelectOP, LoadOP, MInst as Inst, StoreOP, FRM,
};
use crate::isa::riscv64::lower::isle::generated_code::{MInst, VecAluOpRRR};
use crate::isa::riscv64::lower::isle::generated_code::{MInst, VecAluOpRRImm5, VecAluOpRRR};

type BoxCallInfo = Box<CallInfo>;
type BoxCallIndInfo = Box<CallIndInfo>;
Expand Down Expand Up @@ -1663,7 +1663,12 @@ impl Inst {
format!("{}", imm)
};

format!("{op} {vd_s},{vs2_s},{imm_s}{mask} {vstate}")
match (op, imm) {
(VecAluOpRRImm5::VxorVI, imm) if imm == Imm5::maybe_from_i8(-1).unwrap() => {
format!("vnot.v {vd_s},{vs2_s}{mask} {vstate}")
}
_ => format!("{op} {vd_s},{vs2_s},{imm_s}{mask} {vstate}"),
}
}
&Inst::VecAluRR {
op,
Expand Down
29 changes: 23 additions & 6 deletions cranelift/codegen/src/isa/riscv64/inst/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ impl VecAvl {
}
}

// TODO: Can we tell ISLE to derive this?
impl Copy for VecAvl {}

// TODO: Can we tell ISLE to derive this?
impl PartialEq for VecAvl {
fn eq(&self, other: &Self) -> bool {
Expand Down Expand Up @@ -154,7 +157,7 @@ impl fmt::Display for VecMaskMode {
/// Vector Type (VType)
///
/// vtype provides the default type used to interpret the contents of the vector register file.
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct VType {
pub sew: VecElementWidth,
pub lmul: VecLmul,
Expand Down Expand Up @@ -189,7 +192,7 @@ impl fmt::Display for VType {
/// VState represents the state of the vector unit that each instruction expects before execution.
/// Unlike VType or any of the other types here, VState is not a part of the RISC-V ISA. It is
/// used by our instruction emission code to ensure that the vector unit is in the correct state.
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct VState {
pub avl: VecAvl,
pub vtype: VType,
Expand Down Expand Up @@ -272,9 +275,9 @@ impl VecAluOpRRR {
VecAluOpRRR::VmulVV => 0b100101,
VecAluOpRRR::VmulhVV => 0b100111,
VecAluOpRRR::VmulhuVV | VecAluOpRRR::VfmulVV | VecAluOpRRR::VfmulVF => 0b100100,
VecAluOpRRR::VandVV => 0b001001,
VecAluOpRRR::VorVV => 0b001010,
VecAluOpRRR::VxorVV => 0b001011,
VecAluOpRRR::VandVV | VecAluOpRRR::VandVX => 0b001001,
VecAluOpRRR::VorVV | VecAluOpRRR::VorVX => 0b001010,
VecAluOpRRR::VxorVV | VecAluOpRRR::VxorVX => 0b001011,
VecAluOpRRR::VslidedownVX => 0b001111,
VecAluOpRRR::VfrsubVF => 0b100111,
VecAluOpRRR::VmergeVVM | VecAluOpRRR::VmergeVXM | VecAluOpRRR::VfmergeVFM => 0b010111,
Expand All @@ -298,6 +301,9 @@ impl VecAluOpRRR {
VecAluOpRRR::VaddVX
| VecAluOpRRR::VsubVX
| VecAluOpRRR::VrsubVX
| VecAluOpRRR::VandVX
| VecAluOpRRR::VorVX
| VecAluOpRRR::VxorVX
| VecAluOpRRR::VslidedownVX
| VecAluOpRRR::VmergeVXM => VecOpCategory::OPIVX,
VecAluOpRRR::VfaddVV
Expand Down Expand Up @@ -354,6 +360,9 @@ impl VecAluOpRRImm5 {
match self {
VecAluOpRRImm5::VaddVI => 0b000000,
VecAluOpRRImm5::VrsubVI => 0b000011,
VecAluOpRRImm5::VandVI => 0b001001,
VecAluOpRRImm5::VorVI => 0b001010,
VecAluOpRRImm5::VxorVI => 0b001011,
VecAluOpRRImm5::VslidedownVI => 0b001111,
VecAluOpRRImm5::VmergeVIM => 0b010111,
}
Expand All @@ -363,6 +372,9 @@ impl VecAluOpRRImm5 {
match self {
VecAluOpRRImm5::VaddVI
| VecAluOpRRImm5::VrsubVI
| VecAluOpRRImm5::VandVI
| VecAluOpRRImm5::VorVI
| VecAluOpRRImm5::VxorVI
| VecAluOpRRImm5::VslidedownVI
| VecAluOpRRImm5::VmergeVIM => VecOpCategory::OPIVI,
}
Expand All @@ -371,7 +383,12 @@ impl VecAluOpRRImm5 {
pub fn imm_is_unsigned(&self) -> bool {
match self {
VecAluOpRRImm5::VslidedownVI => true,
VecAluOpRRImm5::VaddVI | VecAluOpRRImm5::VrsubVI | VecAluOpRRImm5::VmergeVIM => false,
VecAluOpRRImm5::VaddVI
| VecAluOpRRImm5::VrsubVI
| VecAluOpRRImm5::VandVI
| VecAluOpRRImm5::VorVI
| VecAluOpRRImm5::VxorVI
| VecAluOpRRImm5::VmergeVIM => false,
}
}
}
Expand Down
43 changes: 43 additions & 0 deletions cranelift/codegen/src/isa/riscv64/inst_vector.isle
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@
(VaddVX)
(VsubVX)
(VrsubVX)
(VandVX)
(VorVX)
(VxorVX)
(VslidedownVX)
(VfaddVF)
(VfsubVF)
Expand All @@ -125,6 +128,9 @@
;; Regular VI Opcodes
(VaddVI)
(VrsubVI)
(VandVI)
(VorVI)
(VxorVI)
(VslidedownVI)
(VmergeVIM)
))
Expand Down Expand Up @@ -319,16 +325,53 @@
(rule (rv_vand_vv vs2 vs1 mask vstate)
(vec_alu_rrr (VecAluOpRRR.VandVV) vs2 vs1 mask vstate))

;; Helper for emitting the `vand.vx` instruction.
(decl rv_vand_vx (Reg Reg VecOpMasking VState) Reg)
(rule (rv_vand_vx vs2 vs1 mask vstate)
(vec_alu_rrr (VecAluOpRRR.VandVX) vs2 vs1 mask vstate))

;; Helper for emitting the `vand.vi` instruction.
(decl rv_vand_vi (Reg Imm5 VecOpMasking VState) Reg)
(rule (rv_vand_vi vs2 imm mask vstate)
(vec_alu_rr_imm5 (VecAluOpRRImm5.VandVI) vs2 imm mask vstate))

;; Helper for emitting the `vor.vv` instruction.
(decl rv_vor_vv (Reg Reg VecOpMasking VState) Reg)
(rule (rv_vor_vv vs2 vs1 mask vstate)
(vec_alu_rrr (VecAluOpRRR.VorVV) vs2 vs1 mask vstate))

;; Helper for emitting the `vor.vx` instruction.
(decl rv_vor_vx (Reg Reg VecOpMasking VState) Reg)
(rule (rv_vor_vx vs2 vs1 mask vstate)
(vec_alu_rrr (VecAluOpRRR.VorVX) vs2 vs1 mask vstate))

;; Helper for emitting the `vor.vi` instruction.
(decl rv_vor_vi (Reg Imm5 VecOpMasking VState) Reg)
(rule (rv_vor_vi vs2 imm mask vstate)
(vec_alu_rr_imm5 (VecAluOpRRImm5.VorVI) vs2 imm mask vstate))

;; Helper for emitting the `vxor.vv` instruction.
(decl rv_vxor_vv (Reg Reg VecOpMasking VState) Reg)
(rule (rv_vxor_vv vs2 vs1 mask vstate)
(vec_alu_rrr (VecAluOpRRR.VxorVV) vs2 vs1 mask vstate))

;; Helper for emitting the `vxor.vx` instruction.
(decl rv_vxor_vx (Reg Reg VecOpMasking VState) Reg)
(rule (rv_vxor_vx vs2 vs1 mask vstate)
(vec_alu_rrr (VecAluOpRRR.VxorVX) vs2 vs1 mask vstate))

;; Helper for emitting the `vxor.vi` instruction.
(decl rv_vxor_vi (Reg Imm5 VecOpMasking VState) Reg)
(rule (rv_vxor_vi vs2 imm mask vstate)
(vec_alu_rr_imm5 (VecAluOpRRImm5.VxorVI) vs2 imm mask vstate))

;; Helper for emitting the `vnot.v` instruction.
;; This is just a mnemonic for `vxor.vi vd, vs, -1`
(decl rv_vnot_v (Reg VecOpMasking VState) Reg)
(rule (rv_vnot_v vs2 mask vstate)
(if-let neg1 (imm5_from_i8 -1))
(rv_vxor_vi vs2 neg1 mask vstate))

;; Helper for emitting the `vfadd.vv` instruction.
(decl rv_vfadd_vv (Reg Reg VecOpMasking VState) Reg)
(rule (rv_vfadd_vv vs2 vs1 mask vstate)
Expand Down
Loading

0 comments on commit 2bbae47

Please sign in to comment.