Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

riscv64: Implement SIMD bitwise operations #6419

Merged
merged 8 commits into from
May 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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