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: Add .vx format opcodes #6367

Merged
merged 8 commits into from
May 16, 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
22 changes: 18 additions & 4 deletions cranelift/codegen/src/isa/riscv64/inst/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{settings, CodegenError, CodegenResult};
pub use crate::ir::condcodes::FloatCC;

use alloc::vec::Vec;
use regalloc2::{PRegSet, VReg};
use regalloc2::{PRegSet, RegClass, VReg};
use smallvec::{smallvec, SmallVec};
use std::boxed::Box;
use std::string::{String, ToString};
Expand Down Expand Up @@ -53,11 +53,11 @@ pub(crate) type VecWritableReg = Vec<Writable<Reg>>;
//=============================================================================
// Instructions (top level): definition

use crate::isa::riscv64::lower::isle::generated_code::MInst;
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};

type BoxCallInfo = Box<CallInfo>;
type BoxCallIndInfo = Box<CallIndInfo>;
Expand Down Expand Up @@ -624,12 +624,21 @@ fn riscv64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut Operan
// gen_prologue is called at emit stage.
// no need let reg alloc know.
}
&Inst::VecAluRRR { vd, vs1, vs2, .. } => {
&Inst::VecAluRRR {
op, vd, vs1, vs2, ..
} => {
debug_assert_eq!(vd.to_reg().class(), RegClass::Vector);
debug_assert_eq!(vs2.class(), RegClass::Vector);
debug_assert_eq!(vs1.class(), op.vs1_regclass());

collector.reg_use(vs1);
collector.reg_use(vs2);
collector.reg_def(vd);
}
&Inst::VecAluRRImm5 { vd, vs2, .. } => {
debug_assert_eq!(vd.to_reg().class(), RegClass::Vector);
debug_assert_eq!(vs2.class(), RegClass::Vector);

collector.reg_use(vs2);
collector.reg_def(vd);
}
Expand Down Expand Up @@ -1559,7 +1568,12 @@ impl Inst {

// Note: vs2 and vs1 here are opposite to the standard scalar ordering.
// This is noted in Section 10.1 of the RISC-V Vector spec.
format!("{} {},{},{} {}", op, vd_s, vs2_s, vs1_s, vstate)
match (op, vs1) {
(VecAluOpRRR::VrsubVX, vs1) if vs1 == zero_reg() => {
format!("vneg.v {},{} {}", vd_s, vs2_s, vstate)
}
_ => format!("{} {},{},{} {}", op, vd_s, vs2_s, vs1_s, vstate),
}
}
&Inst::VecAluRRImm5 {
op,
Expand Down
65 changes: 43 additions & 22 deletions cranelift/codegen/src/isa/riscv64/inst/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::isa::riscv64::lower::isle::generated_code::{
VecAMode, VecAluOpRRImm5, VecAluOpRRR, VecAvl, VecElementWidth, VecLmul, VecMaskMode,
VecOpCategory, VecOpMasking, VecTailMode,
};
use crate::machinst::RegClass;
use crate::Reg;
use core::fmt;

Expand Down Expand Up @@ -245,27 +246,46 @@ impl VecAluOpRRR {
0x57
}
pub fn funct3(&self) -> u32 {
match self {
VecAluOpRRR::Vadd
| VecAluOpRRR::Vsub
| VecAluOpRRR::Vand
| VecAluOpRRR::Vor
| VecAluOpRRR::Vxor => VecOpCategory::OPIVV,
VecAluOpRRR::Vmul | VecAluOpRRR::Vmulh | VecAluOpRRR::Vmulhu => VecOpCategory::OPMVV,
}
.encode()
self.category().encode()
}
pub fn funct6(&self) -> u32 {
// See: https://github.com/riscv/riscv-v-spec/blob/master/inst-table.adoc
match self {
VecAluOpRRR::Vadd => 0b000000,
VecAluOpRRR::Vsub => 0b000010,
VecAluOpRRR::Vmul => 0b100101,
VecAluOpRRR::Vmulh => 0b100111,
VecAluOpRRR::Vmulhu => 0b100100,
VecAluOpRRR::Vand => 0b001001,
VecAluOpRRR::Vor => 0b001010,
VecAluOpRRR::Vxor => 0b001011,
VecAluOpRRR::VaddVV | VecAluOpRRR::VaddVX => 0b000000,
VecAluOpRRR::VsubVV | VecAluOpRRR::VsubVX => 0b000010,
elliottt marked this conversation as resolved.
Show resolved Hide resolved
VecAluOpRRR::VrsubVX => 0b000011,
VecAluOpRRR::VmulVV => 0b100101,
VecAluOpRRR::VmulhVV => 0b100111,
VecAluOpRRR::VmulhuVV => 0b100100,
VecAluOpRRR::VandVV => 0b001001,
VecAluOpRRR::VorVV => 0b001010,
VecAluOpRRR::VxorVV => 0b001011,
}
}

pub fn category(&self) -> VecOpCategory {
match self {
VecAluOpRRR::VaddVV
| VecAluOpRRR::VsubVV
| VecAluOpRRR::VandVV
| VecAluOpRRR::VorVV
| VecAluOpRRR::VxorVV => VecOpCategory::OPIVV,
VecAluOpRRR::VmulVV | VecAluOpRRR::VmulhVV | VecAluOpRRR::VmulhuVV => {
VecOpCategory::OPMVV
}
VecAluOpRRR::VaddVX | VecAluOpRRR::VsubVX | VecAluOpRRR::VrsubVX => {
VecOpCategory::OPIVX
}
}
}

// vs1 is the only variable source, vs2 is fixed.
pub fn vs1_regclass(&self) -> RegClass {
match self.category() {
VecOpCategory::OPIVV | VecOpCategory::OPFVV | VecOpCategory::OPMVV => RegClass::Vector,
VecOpCategory::OPIVX | VecOpCategory::OPMVX => RegClass::Int,
VecOpCategory::OPFVF => RegClass::Float,
_ => unreachable!(),
}
}
}
Expand All @@ -274,8 +294,8 @@ impl fmt::Display for VecAluOpRRR {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut s = format!("{self:?}");
s.make_ascii_lowercase();
s.push_str(".vv");
f.write_str(&s)
let (opcode, category) = s.split_at(s.len() - 2);
f.write_str(&format!("{}.{}", opcode, category))
}
}

Expand All @@ -290,7 +310,8 @@ impl VecAluOpRRImm5 {
pub fn funct6(&self) -> u32 {
// See: https://github.com/riscv/riscv-v-spec/blob/master/inst-table.adoc
match self {
VecAluOpRRImm5::Vadd => 0b000000,
VecAluOpRRImm5::VaddVI => 0b000000,
VecAluOpRRImm5::VrsubVI => 0b000011,
}
}
}
Expand All @@ -299,8 +320,8 @@ impl fmt::Display for VecAluOpRRImm5 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut s = format!("{self:?}");
s.make_ascii_lowercase();
s.push_str(".vi");
f.write_str(&s)
let (opcode, category) = s.split_at(s.len() - 2);
f.write_str(&format!("{}.{}", opcode, category))
}
}

Expand Down
68 changes: 50 additions & 18 deletions cranelift/codegen/src/isa/riscv64/inst_vector.isle
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,26 @@

;; Register to Register ALU Ops
(type VecAluOpRRR (enum
(Vadd)
(Vsub)
(Vmul)
(Vmulh)
(Vmulhu)
(Vand)
(Vor)
(Vxor)
;; Vector-Vector Opcodes
(VaddVV)
(VsubVV)
(VmulVV)
(VmulhVV)
(VmulhuVV)
(VandVV)
(VorVV)
(VxorVV)

;; Vector-Scalar Opcodes
(VaddVX)
(VsubVX)
(VrsubVX)
))

;; Register-Imm ALU Ops
(type VecAluOpRRImm5 (enum
(Vadd)
(VaddVI)
(VrsubVI)
))


Expand Down Expand Up @@ -181,44 +188,69 @@
;; Helper for emitting the `vadd.vv` instruction.
(decl rv_vadd_vv (Reg Reg VState) Reg)
(rule (rv_vadd_vv vs2 vs1 vstate)
(vec_alu_rrr (VecAluOpRRR.Vadd) vs2 vs1 vstate))
(vec_alu_rrr (VecAluOpRRR.VaddVV) vs2 vs1 vstate))

;; Helper for emitting the `vadd.vx` instruction.
(decl rv_vadd_vx (Reg Reg VState) Reg)
(rule (rv_vadd_vx vs2 vs1 vstate)
(vec_alu_rrr (VecAluOpRRR.VaddVX) vs2 vs1 vstate))

;; Helper for emitting the `vadd.vi` instruction.
(decl rv_vadd_vi (Reg Imm5 VState) Reg)
(rule (rv_vadd_vi vs2 imm vstate)
(vec_alu_rr_imm5 (VecAluOpRRImm5.Vadd) vs2 imm vstate))
(vec_alu_rr_imm5 (VecAluOpRRImm5.VaddVI) vs2 imm vstate))

;; Helper for emitting the `vsub.vv` instruction.
(decl rv_vsub_vv (Reg Reg VState) Reg)
(rule (rv_vsub_vv vs2 vs1 vstate)
(vec_alu_rrr (VecAluOpRRR.Vsub) vs2 vs1 vstate))
(vec_alu_rrr (VecAluOpRRR.VsubVV) vs2 vs1 vstate))

;; Helper for emitting the `vsub.vx` instruction.
(decl rv_vsub_vx (Reg Reg VState) Reg)
(rule (rv_vsub_vx vs2 vs1 vstate)
(vec_alu_rrr (VecAluOpRRR.VsubVX) vs2 vs1 vstate))

;; Helper for emitting the `vrsub.vx` instruction.
(decl rv_vrsub_vx (Reg Reg VState) Reg)
(rule (rv_vrsub_vx vs2 vs1 vstate)
(vec_alu_rrr (VecAluOpRRR.VrsubVX) vs2 vs1 vstate))

;; Helper for emitting the `vneg.v` pseudo-instruction.
(decl rv_vneg_v (Reg VState) Reg)
(rule (rv_vneg_v vs2 vstate)
(vec_alu_rrr (VecAluOpRRR.VrsubVX) vs2 (zero_reg) vstate))

;; Helper for emitting the `vrsub.vi` instruction.
(decl rv_vrsub_vi (Reg Imm5 VState) Reg)
(rule (rv_vrsub_vi vs2 imm vstate)
(vec_alu_rr_imm5 (VecAluOpRRImm5.VrsubVI) vs2 imm vstate))

;; Helper for emitting the `vmul.vv` instruction.
(decl rv_vmul_vv (Reg Reg VState) Reg)
(rule (rv_vmul_vv vs2 vs1 vstate)
(vec_alu_rrr (VecAluOpRRR.Vmul) vs2 vs1 vstate))
(vec_alu_rrr (VecAluOpRRR.VmulVV) vs2 vs1 vstate))

;; Helper for emitting the `vmulh.vv` instruction.
(decl rv_vmulh_vv (Reg Reg VState) Reg)
(rule (rv_vmulh_vv vs2 vs1 vstate)
(vec_alu_rrr (VecAluOpRRR.Vmulh) vs2 vs1 vstate))
(vec_alu_rrr (VecAluOpRRR.VmulhVV) vs2 vs1 vstate))

;; Helper for emitting the `vmulhu.vv` instruction.
(decl rv_vmulhu_vv (Reg Reg VState) Reg)
(rule (rv_vmulhu_vv vs2 vs1 vstate)
(vec_alu_rrr (VecAluOpRRR.Vmulhu) vs2 vs1 vstate))
(vec_alu_rrr (VecAluOpRRR.VmulhuVV) vs2 vs1 vstate))

;; Helper for emitting the `vand.vv` instruction.
(decl rv_vand_vv (Reg Reg VState) Reg)
(rule (rv_vand_vv vs2 vs1 vstate)
(vec_alu_rrr (VecAluOpRRR.Vand) vs2 vs1 vstate))
(vec_alu_rrr (VecAluOpRRR.VandVV) vs2 vs1 vstate))

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

;; Helper for emitting the `vxor.vv` instruction.
(decl rv_vxor_vv (Reg Reg VState) Reg)
(rule (rv_vxor_vv vs2 vs1 vstate)
(vec_alu_rrr (VecAluOpRRR.Vxor) vs2 vs1 vstate))
(vec_alu_rrr (VecAluOpRRR.VxorVV) vs2 vs1 vstate))
27 changes: 23 additions & 4 deletions cranelift/codegen/src/isa/riscv64/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,16 @@
(rule 8 (lower (has_type (ty_vec_fits_in_register ty) (iadd x y)))
(rv_vadd_vv x y ty))

(rule 9 (lower (has_type (ty_vec_fits_in_register ty) (iadd x (replicated_imm5 y))))
(rule 9 (lower (has_type (ty_vec_fits_in_register ty) (iadd x (splat y))))
(rv_vadd_vx x y ty))

(rule 10 (lower (has_type (ty_vec_fits_in_register ty) (iadd (splat x) y)))
(rv_vadd_vx y x ty))

(rule 11 (lower (has_type (ty_vec_fits_in_register ty) (iadd x (replicated_imm5 y))))
(rv_vadd_vi x y ty))

(rule 10 (lower (has_type (ty_vec_fits_in_register ty) (iadd (replicated_imm5 x) y)))
(rule 12 (lower (has_type (ty_vec_fits_in_register ty) (iadd (replicated_imm5 x) y)))
(rv_vadd_vi y x ty))

;;; Rules for `uadd_overflow_trap` ;;;;;;;;;;;;;
Expand All @@ -140,12 +146,25 @@
(rule 3 (lower (has_type (ty_vec_fits_in_register ty) (isub x y)))
(rv_vsub_vv x y ty))

(rule 4 (lower (has_type (ty_vec_fits_in_register ty) (isub x (splat y))))
(rv_vsub_vx x y ty))

(rule 5 (lower (has_type (ty_vec_fits_in_register ty) (isub (splat x) y)))
(rv_vrsub_vx y x ty))

(rule 6 (lower (has_type (ty_vec_fits_in_register ty) (isub (replicated_imm5 x) y)))
(rv_vrsub_vi y x ty))


;;;; Rules for `ineg` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; `i64` and smaller.
(rule (lower (has_type ty (ineg val)))
(rule (lower (has_type (ty_int ty) (ineg val)))
(neg ty val))

(rule 1 (lower (has_type (ty_vec_fits_in_register ty) (ineg x)))
(rv_vneg_v x ty))


;;;; Rules for `imul` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule 0 (lower (has_type (ty_int_ref_scalar_64 ty) (imul x y)))
Expand Down
Loading