use crate::Reg;
use crate::isa::riscv64::lower::isle::generated_code::VecAluOpRRRR;
use crate::isa::riscv64::lower::isle::generated_code::{
VecAMode, VecAluOpRImm5, VecAluOpRR, VecAluOpRRImm5, VecAluOpRRR, VecAluOpRRRImm5, VecAvl,
VecElementWidth, VecLmul, VecMaskMode, VecOpCategory, VecOpMasking, VecTailMode,
};
use crate::machinst::{OperandVisitor, RegClass};
use core::fmt;
use super::{Type, UImm5};
impl VecAvl {
pub fn _static(size: u32) -> Self {
VecAvl::Static {
size: UImm5::maybe_from_u8(size as u8).expect("Invalid size for AVL"),
}
}
pub fn is_static(&self) -> bool {
match self {
VecAvl::Static { .. } => true,
}
}
pub fn unwrap_static(&self) -> UImm5 {
match self {
VecAvl::Static { size } => *size,
}
}
}
impl Copy for VecAvl {}
impl PartialEq for VecAvl {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(VecAvl::Static { size: lhs }, VecAvl::Static { size: rhs }) => lhs == rhs,
}
}
}
impl fmt::Display for VecAvl {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
VecAvl::Static { size } => write!(f, "{size}"),
}
}
}
impl VecElementWidth {
pub fn from_type(ty: Type) -> Self {
Self::from_bits(ty.lane_bits())
}
pub fn from_bits(bits: u32) -> Self {
match bits {
8 => VecElementWidth::E8,
16 => VecElementWidth::E16,
32 => VecElementWidth::E32,
64 => VecElementWidth::E64,
_ => panic!("Invalid number of bits for VecElementWidth: {bits}"),
}
}
pub fn bits(&self) -> u32 {
match self {
VecElementWidth::E8 => 8,
VecElementWidth::E16 => 16,
VecElementWidth::E32 => 32,
VecElementWidth::E64 => 64,
}
}
pub fn encode(&self) -> u32 {
match self {
VecElementWidth::E8 => 0b000,
VecElementWidth::E16 => 0b001,
VecElementWidth::E32 => 0b010,
VecElementWidth::E64 => 0b011,
}
}
}
impl fmt::Display for VecElementWidth {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "e{}", self.bits())
}
}
impl VecLmul {
pub fn encode(&self) -> u32 {
match self {
VecLmul::LmulF8 => 0b101,
VecLmul::LmulF4 => 0b110,
VecLmul::LmulF2 => 0b111,
VecLmul::Lmul1 => 0b000,
VecLmul::Lmul2 => 0b001,
VecLmul::Lmul4 => 0b010,
VecLmul::Lmul8 => 0b011,
}
}
}
impl fmt::Display for VecLmul {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
VecLmul::LmulF8 => write!(f, "mf8"),
VecLmul::LmulF4 => write!(f, "mf4"),
VecLmul::LmulF2 => write!(f, "mf2"),
VecLmul::Lmul1 => write!(f, "m1"),
VecLmul::Lmul2 => write!(f, "m2"),
VecLmul::Lmul4 => write!(f, "m4"),
VecLmul::Lmul8 => write!(f, "m8"),
}
}
}
impl VecTailMode {
pub fn encode(&self) -> u32 {
match self {
VecTailMode::Agnostic => 1,
VecTailMode::Undisturbed => 0,
}
}
}
impl fmt::Display for VecTailMode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
VecTailMode::Agnostic => write!(f, "ta"),
VecTailMode::Undisturbed => write!(f, "tu"),
}
}
}
impl VecMaskMode {
pub fn encode(&self) -> u32 {
match self {
VecMaskMode::Agnostic => 1,
VecMaskMode::Undisturbed => 0,
}
}
}
impl fmt::Display for VecMaskMode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
VecMaskMode::Agnostic => write!(f, "ma"),
VecMaskMode::Undisturbed => write!(f, "mu"),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct VType {
pub sew: VecElementWidth,
pub lmul: VecLmul,
pub tail_mode: VecTailMode,
pub mask_mode: VecMaskMode,
}
impl VType {
pub fn encode(&self) -> u32 {
let mut bits = 0;
bits |= self.lmul.encode();
bits |= self.sew.encode() << 3;
bits |= self.tail_mode.encode() << 6;
bits |= self.mask_mode.encode() << 7;
bits
}
}
impl fmt::Display for VType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}, {}, {}, {}",
self.sew, self.lmul, self.tail_mode, self.mask_mode
)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct VState {
pub avl: VecAvl,
pub vtype: VType,
}
impl VState {
pub fn from_type(ty: Type) -> Self {
VState {
avl: VecAvl::_static(ty.lane_count()),
vtype: VType {
sew: VecElementWidth::from_type(ty),
lmul: VecLmul::Lmul1,
tail_mode: VecTailMode::Agnostic,
mask_mode: VecMaskMode::Agnostic,
},
}
}
}
impl fmt::Display for VState {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "#avl={}, #vtype=({})", self.avl, self.vtype)
}
}
impl VecOpCategory {
pub fn encode(&self) -> u32 {
match self {
VecOpCategory::OPIVV => 0b000,
VecOpCategory::OPFVV => 0b001,
VecOpCategory::OPMVV => 0b010,
VecOpCategory::OPIVI => 0b011,
VecOpCategory::OPIVX => 0b100,
VecOpCategory::OPFVF => 0b101,
VecOpCategory::OPMVX => 0b110,
VecOpCategory::OPCFG => 0b111,
}
}
}
impl Copy for VecOpMasking {}
impl VecOpMasking {
pub fn is_enabled(&self) -> bool {
match self {
VecOpMasking::Enabled { .. } => true,
VecOpMasking::Disabled => false,
}
}
pub fn encode(&self) -> u32 {
match self {
VecOpMasking::Enabled { .. } => 0,
VecOpMasking::Disabled => 1,
}
}
}
impl VecAluOpRRRR {
pub fn opcode(&self) -> u32 {
0x57
}
pub fn funct3(&self) -> u32 {
self.category().encode()
}
pub fn funct6(&self) -> u32 {
match self {
VecAluOpRRRR::VmaccVV | VecAluOpRRRR::VmaccVX => 0b101101,
VecAluOpRRRR::VnmsacVV | VecAluOpRRRR::VnmsacVX => 0b101111,
VecAluOpRRRR::VfmaccVV | VecAluOpRRRR::VfmaccVF => 0b101100,
VecAluOpRRRR::VfnmaccVV | VecAluOpRRRR::VfnmaccVF => 0b101101,
VecAluOpRRRR::VfmsacVV | VecAluOpRRRR::VfmsacVF => 0b101110,
VecAluOpRRRR::VfnmsacVV | VecAluOpRRRR::VfnmsacVF => 0b101111,
VecAluOpRRRR::Vslide1upVX => 0b001110,
}
}
pub fn category(&self) -> VecOpCategory {
match self {
VecAluOpRRRR::VmaccVV | VecAluOpRRRR::VnmsacVV => VecOpCategory::OPMVV,
VecAluOpRRRR::VmaccVX | VecAluOpRRRR::VnmsacVX | VecAluOpRRRR::Vslide1upVX => {
VecOpCategory::OPMVX
}
VecAluOpRRRR::VfmaccVV
| VecAluOpRRRR::VfnmaccVV
| VecAluOpRRRR::VfmsacVV
| VecAluOpRRRR::VfnmsacVV => VecOpCategory::OPFVV,
VecAluOpRRRR::VfmaccVF
| VecAluOpRRRR::VfnmaccVF
| VecAluOpRRRR::VfmsacVF
| VecAluOpRRRR::VfnmsacVF => VecOpCategory::OPFVF,
}
}
pub fn vs1_regclass(&self) -> RegClass {
match self.category() {
VecOpCategory::OPMVV | VecOpCategory::OPFVV => RegClass::Vector,
VecOpCategory::OPMVX => RegClass::Int,
VecOpCategory::OPFVF => RegClass::Float,
_ => unreachable!(),
}
}
}
impl VecInstOverlapInfo for VecAluOpRRRR {
fn forbids_src_dst_overlaps(&self) -> bool {
match self {
VecAluOpRRRR::Vslide1upVX => true,
_ => false,
}
}
}
impl fmt::Display for VecAluOpRRRR {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut s = format!("{self:?}");
s.make_ascii_lowercase();
let (opcode, category) = s.split_at(s.len() - 2);
f.write_str(&format!("{opcode}.{category}"))
}
}
impl VecAluOpRRRImm5 {
pub fn opcode(&self) -> u32 {
0x57
}
pub fn funct3(&self) -> u32 {
self.category().encode()
}
pub fn funct6(&self) -> u32 {
match self {
VecAluOpRRRImm5::VslideupVI => 0b001110,
}
}
pub fn category(&self) -> VecOpCategory {
match self {
VecAluOpRRRImm5::VslideupVI => VecOpCategory::OPIVI,
}
}
pub fn imm_is_unsigned(&self) -> bool {
match self {
VecAluOpRRRImm5::VslideupVI => true,
}
}
}
impl VecInstOverlapInfo for VecAluOpRRRImm5 {
fn forbids_src_dst_overlaps(&self) -> bool {
match self {
VecAluOpRRRImm5::VslideupVI => true,
}
}
}
impl fmt::Display for VecAluOpRRRImm5 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut s = format!("{self:?}");
s.make_ascii_lowercase();
let (opcode, category) = s.split_at(s.len() - 2);
f.write_str(&format!("{opcode}.{category}"))
}
}
impl VecAluOpRRR {
pub fn opcode(&self) -> u32 {
0x57
}
pub fn funct3(&self) -> u32 {
self.category().encode()
}
pub fn funct6(&self) -> u32 {
match self {
VecAluOpRRR::VaddVV
| VecAluOpRRR::VaddVX
| VecAluOpRRR::VfaddVV
| VecAluOpRRR::VfaddVF => 0b000000,
VecAluOpRRR::VsubVV
| VecAluOpRRR::VsubVX
| VecAluOpRRR::VfsubVV
| VecAluOpRRR::VfsubVF => 0b000010,
VecAluOpRRR::VrsubVX => 0b000011,
VecAluOpRRR::VmulVV | VecAluOpRRR::VmulVX => 0b100101,
VecAluOpRRR::VmulhVV | VecAluOpRRR::VmulhVX => 0b100111,
VecAluOpRRR::VmulhuVV
| VecAluOpRRR::VmulhuVX
| VecAluOpRRR::VfmulVV
| VecAluOpRRR::VfmulVF => 0b100100,
VecAluOpRRR::VsmulVV | VecAluOpRRR::VsmulVX => 0b100111,
VecAluOpRRR::VsllVV | VecAluOpRRR::VsllVX => 0b100101,
VecAluOpRRR::VsrlVV | VecAluOpRRR::VsrlVX => 0b101000,
VecAluOpRRR::VsraVV | VecAluOpRRR::VsraVX => 0b101001,
VecAluOpRRR::VandVV | VecAluOpRRR::VandVX => 0b001001,
VecAluOpRRR::VorVV | VecAluOpRRR::VorVX => 0b001010,
VecAluOpRRR::VxorVV | VecAluOpRRR::VxorVX => 0b001011,
VecAluOpRRR::VminuVV | VecAluOpRRR::VminuVX | VecAluOpRRR::VredminuVS => 0b000100,
VecAluOpRRR::VminVV | VecAluOpRRR::VminVX => 0b000101,
VecAluOpRRR::VmaxuVV | VecAluOpRRR::VmaxuVX | VecAluOpRRR::VredmaxuVS => 0b000110,
VecAluOpRRR::VmaxVV | VecAluOpRRR::VmaxVX => 0b000111,
VecAluOpRRR::VslidedownVX => 0b001111,
VecAluOpRRR::VfrsubVF => 0b100111,
VecAluOpRRR::VmergeVVM
| VecAluOpRRR::VmergeVXM
| VecAluOpRRR::VfmergeVFM
| VecAluOpRRR::VcompressVM => 0b010111,
VecAluOpRRR::VfdivVV
| VecAluOpRRR::VfdivVF
| VecAluOpRRR::VsadduVV
| VecAluOpRRR::VsadduVX => 0b100000,
VecAluOpRRR::VfrdivVF | VecAluOpRRR::VsaddVV | VecAluOpRRR::VsaddVX => 0b100001,
VecAluOpRRR::VfminVV => 0b000100,
VecAluOpRRR::VfmaxVV => 0b000110,
VecAluOpRRR::VssubuVV | VecAluOpRRR::VssubuVX => 0b100010,
VecAluOpRRR::VssubVV | VecAluOpRRR::VssubVX => 0b100011,
VecAluOpRRR::VfsgnjVV | VecAluOpRRR::VfsgnjVF => 0b001000,
VecAluOpRRR::VfsgnjnVV => 0b001001,
VecAluOpRRR::VfsgnjxVV => 0b001010,
VecAluOpRRR::VrgatherVV | VecAluOpRRR::VrgatherVX => 0b001100,
VecAluOpRRR::VwadduVV | VecAluOpRRR::VwadduVX => 0b110000,
VecAluOpRRR::VwaddVV | VecAluOpRRR::VwaddVX => 0b110001,
VecAluOpRRR::VwsubuVV | VecAluOpRRR::VwsubuVX => 0b110010,
VecAluOpRRR::VwsubVV | VecAluOpRRR::VwsubVX => 0b110011,
VecAluOpRRR::VwadduWV | VecAluOpRRR::VwadduWX => 0b110100,
VecAluOpRRR::VwaddWV | VecAluOpRRR::VwaddWX => 0b110101,
VecAluOpRRR::VwsubuWV | VecAluOpRRR::VwsubuWX => 0b110110,
VecAluOpRRR::VwsubWV | VecAluOpRRR::VwsubWX => 0b110111,
VecAluOpRRR::VmseqVV
| VecAluOpRRR::VmseqVX
| VecAluOpRRR::VmfeqVV
| VecAluOpRRR::VmfeqVF => 0b011000,
VecAluOpRRR::VmsneVV
| VecAluOpRRR::VmsneVX
| VecAluOpRRR::VmfleVV
| VecAluOpRRR::VmfleVF
| VecAluOpRRR::VmandMM => 0b011001,
VecAluOpRRR::VmsltuVV | VecAluOpRRR::VmsltuVX | VecAluOpRRR::VmorMM => 0b011010,
VecAluOpRRR::VmsltVV
| VecAluOpRRR::VmsltVX
| VecAluOpRRR::VmfltVV
| VecAluOpRRR::VmfltVF => 0b011011,
VecAluOpRRR::VmsleuVV
| VecAluOpRRR::VmsleuVX
| VecAluOpRRR::VmfneVV
| VecAluOpRRR::VmfneVF => 0b011100,
VecAluOpRRR::VmsleVV
| VecAluOpRRR::VmsleVX
| VecAluOpRRR::VmfgtVF
| VecAluOpRRR::VmnandMM => 0b011101,
VecAluOpRRR::VmsgtuVX | VecAluOpRRR::VmnorMM => 0b011110,
VecAluOpRRR::VmsgtVX | VecAluOpRRR::VmfgeVF => 0b011111,
}
}
pub fn category(&self) -> VecOpCategory {
match self {
VecAluOpRRR::VaddVV
| VecAluOpRRR::VsaddVV
| VecAluOpRRR::VsadduVV
| VecAluOpRRR::VsubVV
| VecAluOpRRR::VssubVV
| VecAluOpRRR::VssubuVV
| VecAluOpRRR::VsmulVV
| VecAluOpRRR::VsllVV
| VecAluOpRRR::VsrlVV
| VecAluOpRRR::VsraVV
| VecAluOpRRR::VandVV
| VecAluOpRRR::VorVV
| VecAluOpRRR::VxorVV
| VecAluOpRRR::VminuVV
| VecAluOpRRR::VminVV
| VecAluOpRRR::VmaxuVV
| VecAluOpRRR::VmaxVV
| VecAluOpRRR::VmergeVVM
| VecAluOpRRR::VrgatherVV
| VecAluOpRRR::VmseqVV
| VecAluOpRRR::VmsneVV
| VecAluOpRRR::VmsltuVV
| VecAluOpRRR::VmsltVV
| VecAluOpRRR::VmsleuVV
| VecAluOpRRR::VmsleVV => VecOpCategory::OPIVV,
VecAluOpRRR::VwaddVV
| VecAluOpRRR::VwaddWV
| VecAluOpRRR::VwadduVV
| VecAluOpRRR::VwadduWV
| VecAluOpRRR::VwsubVV
| VecAluOpRRR::VwsubWV
| VecAluOpRRR::VwsubuVV
| VecAluOpRRR::VwsubuWV
| VecAluOpRRR::VmulVV
| VecAluOpRRR::VmulhVV
| VecAluOpRRR::VmulhuVV
| VecAluOpRRR::VredmaxuVS
| VecAluOpRRR::VredminuVS
| VecAluOpRRR::VcompressVM
| VecAluOpRRR::VmandMM
| VecAluOpRRR::VmorMM
| VecAluOpRRR::VmnandMM
| VecAluOpRRR::VmnorMM => VecOpCategory::OPMVV,
VecAluOpRRR::VwaddVX
| VecAluOpRRR::VwadduVX
| VecAluOpRRR::VwadduWX
| VecAluOpRRR::VwaddWX
| VecAluOpRRR::VwsubVX
| VecAluOpRRR::VwsubuVX
| VecAluOpRRR::VwsubuWX
| VecAluOpRRR::VwsubWX
| VecAluOpRRR::VmulVX
| VecAluOpRRR::VmulhVX
| VecAluOpRRR::VmulhuVX => VecOpCategory::OPMVX,
VecAluOpRRR::VaddVX
| VecAluOpRRR::VsaddVX
| VecAluOpRRR::VsadduVX
| VecAluOpRRR::VsubVX
| VecAluOpRRR::VssubVX
| VecAluOpRRR::VssubuVX
| VecAluOpRRR::VrsubVX
| VecAluOpRRR::VsmulVX
| VecAluOpRRR::VsllVX
| VecAluOpRRR::VsrlVX
| VecAluOpRRR::VsraVX
| VecAluOpRRR::VandVX
| VecAluOpRRR::VorVX
| VecAluOpRRR::VxorVX
| VecAluOpRRR::VminuVX
| VecAluOpRRR::VminVX
| VecAluOpRRR::VmaxuVX
| VecAluOpRRR::VmaxVX
| VecAluOpRRR::VslidedownVX
| VecAluOpRRR::VmergeVXM
| VecAluOpRRR::VrgatherVX
| VecAluOpRRR::VmseqVX
| VecAluOpRRR::VmsneVX
| VecAluOpRRR::VmsltuVX
| VecAluOpRRR::VmsltVX
| VecAluOpRRR::VmsleuVX
| VecAluOpRRR::VmsleVX
| VecAluOpRRR::VmsgtuVX
| VecAluOpRRR::VmsgtVX => VecOpCategory::OPIVX,
VecAluOpRRR::VfaddVV
| VecAluOpRRR::VfsubVV
| VecAluOpRRR::VfmulVV
| VecAluOpRRR::VfdivVV
| VecAluOpRRR::VfmaxVV
| VecAluOpRRR::VfminVV
| VecAluOpRRR::VfsgnjVV
| VecAluOpRRR::VfsgnjnVV
| VecAluOpRRR::VfsgnjxVV
| VecAluOpRRR::VmfeqVV
| VecAluOpRRR::VmfneVV
| VecAluOpRRR::VmfltVV
| VecAluOpRRR::VmfleVV => VecOpCategory::OPFVV,
VecAluOpRRR::VfaddVF
| VecAluOpRRR::VfsubVF
| VecAluOpRRR::VfrsubVF
| VecAluOpRRR::VfmulVF
| VecAluOpRRR::VfdivVF
| VecAluOpRRR::VfrdivVF
| VecAluOpRRR::VfmergeVFM
| VecAluOpRRR::VfsgnjVF
| VecAluOpRRR::VmfeqVF
| VecAluOpRRR::VmfneVF
| VecAluOpRRR::VmfltVF
| VecAluOpRRR::VmfleVF
| VecAluOpRRR::VmfgtVF
| VecAluOpRRR::VmfgeVF => VecOpCategory::OPFVF,
}
}
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!(),
}
}
}
impl VecInstOverlapInfo for VecAluOpRRR {
fn forbids_src_dst_overlaps(&self) -> bool {
match self {
VecAluOpRRR::VrgatherVV
| VecAluOpRRR::VrgatherVX
| VecAluOpRRR::VcompressVM
| VecAluOpRRR::VwadduVV
| VecAluOpRRR::VwadduVX
| VecAluOpRRR::VwaddVV
| VecAluOpRRR::VwaddVX
| VecAluOpRRR::VwadduWV
| VecAluOpRRR::VwadduWX
| VecAluOpRRR::VwaddWV
| VecAluOpRRR::VwaddWX
| VecAluOpRRR::VwsubuVV
| VecAluOpRRR::VwsubuVX
| VecAluOpRRR::VwsubVV
| VecAluOpRRR::VwsubVX
| VecAluOpRRR::VwsubuWV
| VecAluOpRRR::VwsubuWX
| VecAluOpRRR::VwsubWV
| VecAluOpRRR::VwsubWX => true,
_ => false,
}
}
fn forbids_mask_dst_overlaps(&self) -> bool {
match self {
VecAluOpRRR::VredmaxuVS
| VecAluOpRRR::VredminuVS
| VecAluOpRRR::VmandMM
| VecAluOpRRR::VmorMM
| VecAluOpRRR::VmnandMM
| VecAluOpRRR::VmnorMM
| VecAluOpRRR::VmseqVX
| VecAluOpRRR::VmsneVX
| VecAluOpRRR::VmsltuVX
| VecAluOpRRR::VmsltVX
| VecAluOpRRR::VmsleuVX
| VecAluOpRRR::VmsleVX
| VecAluOpRRR::VmsgtuVX
| VecAluOpRRR::VmsgtVX
| VecAluOpRRR::VmfeqVV
| VecAluOpRRR::VmfneVV
| VecAluOpRRR::VmfltVV
| VecAluOpRRR::VmfleVV
| VecAluOpRRR::VmfeqVF
| VecAluOpRRR::VmfneVF
| VecAluOpRRR::VmfltVF
| VecAluOpRRR::VmfleVF
| VecAluOpRRR::VmfgtVF
| VecAluOpRRR::VmfgeVF => false,
_ => true,
}
}
}
impl fmt::Display for VecAluOpRRR {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let suffix_length = match self {
VecAluOpRRR::VmergeVVM | VecAluOpRRR::VmergeVXM | VecAluOpRRR::VfmergeVFM => 3,
_ => 2,
};
let mut s = format!("{self:?}");
s.make_ascii_lowercase();
let (opcode, category) = s.split_at(s.len() - suffix_length);
f.write_str(&format!("{opcode}.{category}"))
}
}
impl VecAluOpRRImm5 {
pub fn opcode(&self) -> u32 {
0x57
}
pub fn funct3(&self) -> u32 {
self.category().encode()
}
pub fn funct6(&self) -> u32 {
match self {
VecAluOpRRImm5::VaddVI => 0b000000,
VecAluOpRRImm5::VrsubVI => 0b000011,
VecAluOpRRImm5::VsllVI => 0b100101,
VecAluOpRRImm5::VsrlVI => 0b101000,
VecAluOpRRImm5::VsraVI => 0b101001,
VecAluOpRRImm5::VandVI => 0b001001,
VecAluOpRRImm5::VorVI => 0b001010,
VecAluOpRRImm5::VxorVI => 0b001011,
VecAluOpRRImm5::VslidedownVI => 0b001111,
VecAluOpRRImm5::VssrlVI => 0b101010,
VecAluOpRRImm5::VmergeVIM => 0b010111,
VecAluOpRRImm5::VsadduVI => 0b100000,
VecAluOpRRImm5::VsaddVI => 0b100001,
VecAluOpRRImm5::VrgatherVI => 0b001100,
VecAluOpRRImm5::VmvrV => 0b100111,
VecAluOpRRImm5::VnclipWI => 0b101111,
VecAluOpRRImm5::VnclipuWI => 0b101110,
VecAluOpRRImm5::VmseqVI => 0b011000,
VecAluOpRRImm5::VmsneVI => 0b011001,
VecAluOpRRImm5::VmsleuVI => 0b011100,
VecAluOpRRImm5::VmsleVI => 0b011101,
VecAluOpRRImm5::VmsgtuVI => 0b011110,
VecAluOpRRImm5::VmsgtVI => 0b011111,
}
}
pub fn category(&self) -> VecOpCategory {
match self {
VecAluOpRRImm5::VaddVI
| VecAluOpRRImm5::VrsubVI
| VecAluOpRRImm5::VsllVI
| VecAluOpRRImm5::VsrlVI
| VecAluOpRRImm5::VsraVI
| VecAluOpRRImm5::VandVI
| VecAluOpRRImm5::VorVI
| VecAluOpRRImm5::VxorVI
| VecAluOpRRImm5::VssrlVI
| VecAluOpRRImm5::VslidedownVI
| VecAluOpRRImm5::VmergeVIM
| VecAluOpRRImm5::VsadduVI
| VecAluOpRRImm5::VsaddVI
| VecAluOpRRImm5::VrgatherVI
| VecAluOpRRImm5::VmvrV
| VecAluOpRRImm5::VnclipWI
| VecAluOpRRImm5::VnclipuWI
| VecAluOpRRImm5::VmseqVI
| VecAluOpRRImm5::VmsneVI
| VecAluOpRRImm5::VmsleuVI
| VecAluOpRRImm5::VmsleVI
| VecAluOpRRImm5::VmsgtuVI
| VecAluOpRRImm5::VmsgtVI => VecOpCategory::OPIVI,
}
}
pub fn imm_is_unsigned(&self) -> bool {
match self {
VecAluOpRRImm5::VsllVI
| VecAluOpRRImm5::VsrlVI
| VecAluOpRRImm5::VssrlVI
| VecAluOpRRImm5::VsraVI
| VecAluOpRRImm5::VslidedownVI
| VecAluOpRRImm5::VrgatherVI
| VecAluOpRRImm5::VmvrV
| VecAluOpRRImm5::VnclipWI
| VecAluOpRRImm5::VnclipuWI => true,
VecAluOpRRImm5::VaddVI
| VecAluOpRRImm5::VrsubVI
| VecAluOpRRImm5::VandVI
| VecAluOpRRImm5::VorVI
| VecAluOpRRImm5::VxorVI
| VecAluOpRRImm5::VmergeVIM
| VecAluOpRRImm5::VsadduVI
| VecAluOpRRImm5::VsaddVI
| VecAluOpRRImm5::VmseqVI
| VecAluOpRRImm5::VmsneVI
| VecAluOpRRImm5::VmsleuVI
| VecAluOpRRImm5::VmsleVI
| VecAluOpRRImm5::VmsgtuVI
| VecAluOpRRImm5::VmsgtVI => false,
}
}
}
impl VecInstOverlapInfo for VecAluOpRRImm5 {
fn forbids_src_dst_overlaps(&self) -> bool {
match self {
VecAluOpRRImm5::VrgatherVI => true,
_ => false,
}
}
fn forbids_mask_dst_overlaps(&self) -> bool {
match self {
VecAluOpRRImm5::VmseqVI
| VecAluOpRRImm5::VmsneVI
| VecAluOpRRImm5::VmsleuVI
| VecAluOpRRImm5::VmsleVI
| VecAluOpRRImm5::VmsgtuVI
| VecAluOpRRImm5::VmsgtVI => false,
_ => true,
}
}
}
impl fmt::Display for VecAluOpRRImm5 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let suffix_length = match self {
VecAluOpRRImm5::VmergeVIM => 3,
_ => 2,
};
let mut s = format!("{self:?}");
s.make_ascii_lowercase();
let (opcode, category) = s.split_at(s.len() - suffix_length);
f.write_str(&format!("{opcode}.{category}"))
}
}
impl VecAluOpRR {
pub fn opcode(&self) -> u32 {
0x57
}
pub fn funct3(&self) -> u32 {
self.category().encode()
}
pub fn funct6(&self) -> u32 {
match self {
VecAluOpRR::VmvSX | VecAluOpRR::VmvXS | VecAluOpRR::VfmvSF | VecAluOpRR::VfmvFS => {
0b010000
}
VecAluOpRR::VzextVF2
| VecAluOpRR::VzextVF4
| VecAluOpRR::VzextVF8
| VecAluOpRR::VsextVF2
| VecAluOpRR::VsextVF4
| VecAluOpRR::VsextVF8 => 0b010010,
VecAluOpRR::VfsqrtV => 0b010011,
VecAluOpRR::VmvVV | VecAluOpRR::VmvVX | VecAluOpRR::VfmvVF => 0b010111,
VecAluOpRR::VfcvtxufV
| VecAluOpRR::VfcvtxfV
| VecAluOpRR::VfcvtrtzxufV
| VecAluOpRR::VfcvtrtzxfV
| VecAluOpRR::VfcvtfxuV
| VecAluOpRR::VfcvtfxV
| VecAluOpRR::VfwcvtffV
| VecAluOpRR::VfncvtffW => 0b010010,
}
}
pub fn category(&self) -> VecOpCategory {
match self {
VecAluOpRR::VmvSX => VecOpCategory::OPMVX,
VecAluOpRR::VmvXS
| VecAluOpRR::VzextVF2
| VecAluOpRR::VzextVF4
| VecAluOpRR::VzextVF8
| VecAluOpRR::VsextVF2
| VecAluOpRR::VsextVF4
| VecAluOpRR::VsextVF8 => VecOpCategory::OPMVV,
VecAluOpRR::VfmvSF | VecAluOpRR::VfmvVF => VecOpCategory::OPFVF,
VecAluOpRR::VfmvFS
| VecAluOpRR::VfsqrtV
| VecAluOpRR::VfcvtxufV
| VecAluOpRR::VfcvtxfV
| VecAluOpRR::VfcvtrtzxufV
| VecAluOpRR::VfcvtrtzxfV
| VecAluOpRR::VfcvtfxuV
| VecAluOpRR::VfcvtfxV
| VecAluOpRR::VfwcvtffV
| VecAluOpRR::VfncvtffW => VecOpCategory::OPFVV,
VecAluOpRR::VmvVV => VecOpCategory::OPIVV,
VecAluOpRR::VmvVX => VecOpCategory::OPIVX,
}
}
pub fn aux_encoding(&self) -> u32 {
match self {
VecAluOpRR::VmvSX => 0b00000,
VecAluOpRR::VmvXS => 0b00000,
VecAluOpRR::VfmvSF => 0b00000,
VecAluOpRR::VfmvFS => 0b00000,
VecAluOpRR::VfsqrtV => 0b00000,
VecAluOpRR::VzextVF8 => 0b00010,
VecAluOpRR::VsextVF8 => 0b00011,
VecAluOpRR::VzextVF4 => 0b00100,
VecAluOpRR::VsextVF4 => 0b00101,
VecAluOpRR::VzextVF2 => 0b00110,
VecAluOpRR::VsextVF2 => 0b00111,
VecAluOpRR::VfcvtxufV => 0b00000,
VecAluOpRR::VfcvtxfV => 0b00001,
VecAluOpRR::VfcvtrtzxufV => 0b00110,
VecAluOpRR::VfcvtrtzxfV => 0b00111,
VecAluOpRR::VfcvtfxuV => 0b00010,
VecAluOpRR::VfcvtfxV => 0b00011,
VecAluOpRR::VfwcvtffV => 0b01100,
VecAluOpRR::VfncvtffW => 0b10100,
VecAluOpRR::VmvVV | VecAluOpRR::VmvVX | VecAluOpRR::VfmvVF => 0,
}
}
pub fn vs_is_vs2_encoded(&self) -> bool {
match self {
VecAluOpRR::VmvXS
| VecAluOpRR::VfmvFS
| VecAluOpRR::VfsqrtV
| VecAluOpRR::VzextVF2
| VecAluOpRR::VzextVF4
| VecAluOpRR::VzextVF8
| VecAluOpRR::VsextVF2
| VecAluOpRR::VsextVF4
| VecAluOpRR::VsextVF8
| VecAluOpRR::VfcvtxufV
| VecAluOpRR::VfcvtxfV
| VecAluOpRR::VfcvtrtzxufV
| VecAluOpRR::VfcvtrtzxfV
| VecAluOpRR::VfcvtfxuV
| VecAluOpRR::VfcvtfxV
| VecAluOpRR::VfwcvtffV
| VecAluOpRR::VfncvtffW => true,
VecAluOpRR::VmvSX
| VecAluOpRR::VfmvSF
| VecAluOpRR::VmvVV
| VecAluOpRR::VmvVX
| VecAluOpRR::VfmvVF => false,
}
}
pub fn dst_regclass(&self) -> RegClass {
match self {
VecAluOpRR::VfmvSF
| VecAluOpRR::VmvSX
| VecAluOpRR::VmvVV
| VecAluOpRR::VmvVX
| VecAluOpRR::VfmvVF
| VecAluOpRR::VfsqrtV
| VecAluOpRR::VzextVF2
| VecAluOpRR::VzextVF4
| VecAluOpRR::VzextVF8
| VecAluOpRR::VsextVF2
| VecAluOpRR::VsextVF4
| VecAluOpRR::VsextVF8
| VecAluOpRR::VfcvtxufV
| VecAluOpRR::VfcvtxfV
| VecAluOpRR::VfcvtrtzxufV
| VecAluOpRR::VfcvtrtzxfV
| VecAluOpRR::VfcvtfxuV
| VecAluOpRR::VfcvtfxV
| VecAluOpRR::VfwcvtffV
| VecAluOpRR::VfncvtffW => RegClass::Vector,
VecAluOpRR::VmvXS => RegClass::Int,
VecAluOpRR::VfmvFS => RegClass::Float,
}
}
pub fn src_regclass(&self) -> RegClass {
match self {
VecAluOpRR::VmvXS
| VecAluOpRR::VfmvFS
| VecAluOpRR::VmvVV
| VecAluOpRR::VfsqrtV
| VecAluOpRR::VzextVF2
| VecAluOpRR::VzextVF4
| VecAluOpRR::VzextVF8
| VecAluOpRR::VsextVF2
| VecAluOpRR::VsextVF4
| VecAluOpRR::VsextVF8
| VecAluOpRR::VfcvtxufV
| VecAluOpRR::VfcvtxfV
| VecAluOpRR::VfcvtrtzxufV
| VecAluOpRR::VfcvtrtzxfV
| VecAluOpRR::VfcvtfxuV
| VecAluOpRR::VfcvtfxV
| VecAluOpRR::VfwcvtffV
| VecAluOpRR::VfncvtffW => RegClass::Vector,
VecAluOpRR::VfmvSF | VecAluOpRR::VfmvVF => RegClass::Float,
VecAluOpRR::VmvSX | VecAluOpRR::VmvVX => RegClass::Int,
}
}
}
impl VecInstOverlapInfo for VecAluOpRR {
fn forbids_src_dst_overlaps(&self) -> bool {
match self {
VecAluOpRR::VzextVF2
| VecAluOpRR::VzextVF4
| VecAluOpRR::VzextVF8
| VecAluOpRR::VsextVF2
| VecAluOpRR::VsextVF4
| VecAluOpRR::VsextVF8
| VecAluOpRR::VfwcvtffV
| VecAluOpRR::VfncvtffW => true,
_ => false,
}
}
}
impl fmt::Display for VecAluOpRR {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
VecAluOpRR::VmvSX => "vmv.s.x",
VecAluOpRR::VmvXS => "vmv.x.s",
VecAluOpRR::VfmvSF => "vfmv.s.f",
VecAluOpRR::VfmvFS => "vfmv.f.s",
VecAluOpRR::VfsqrtV => "vfsqrt.v",
VecAluOpRR::VzextVF2 => "vzext.vf2",
VecAluOpRR::VzextVF4 => "vzext.vf4",
VecAluOpRR::VzextVF8 => "vzext.vf8",
VecAluOpRR::VsextVF2 => "vsext.vf2",
VecAluOpRR::VsextVF4 => "vsext.vf4",
VecAluOpRR::VsextVF8 => "vsext.vf8",
VecAluOpRR::VmvVV => "vmv.v.v",
VecAluOpRR::VmvVX => "vmv.v.x",
VecAluOpRR::VfmvVF => "vfmv.v.f",
VecAluOpRR::VfcvtxufV => "vfcvt.xu.f.v",
VecAluOpRR::VfcvtxfV => "vfcvt.x.f.v",
VecAluOpRR::VfcvtrtzxufV => "vfcvt.rtz.xu.f.v",
VecAluOpRR::VfcvtrtzxfV => "vfcvt.rtz.x.f.v",
VecAluOpRR::VfcvtfxuV => "vfcvt.f.xu.v",
VecAluOpRR::VfcvtfxV => "vfcvt.f.x.v",
VecAluOpRR::VfwcvtffV => "vfwcvt.f.f.v",
VecAluOpRR::VfncvtffW => "vfncvt.f.f.w",
})
}
}
impl VecAluOpRImm5 {
pub fn opcode(&self) -> u32 {
0x57
}
pub fn funct3(&self) -> u32 {
self.category().encode()
}
pub fn funct6(&self) -> u32 {
match self {
VecAluOpRImm5::VmvVI => 0b010111,
}
}
pub fn category(&self) -> VecOpCategory {
match self {
VecAluOpRImm5::VmvVI => VecOpCategory::OPIVI,
}
}
pub fn aux_encoding(&self) -> u32 {
match self {
VecAluOpRImm5::VmvVI => 0,
}
}
}
impl VecInstOverlapInfo for VecAluOpRImm5 {
fn forbids_src_dst_overlaps(&self) -> bool {
match self {
VecAluOpRImm5::VmvVI => false,
}
}
}
impl fmt::Display for VecAluOpRImm5 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
VecAluOpRImm5::VmvVI => "vmv.v.i",
})
}
}
impl VecAMode {
pub fn get_base_register(&self) -> Option<Reg> {
match self {
VecAMode::UnitStride { base, .. } => base.get_base_register(),
}
}
pub fn get_operands(&mut self, collector: &mut impl OperandVisitor) {
match self {
VecAMode::UnitStride { base, .. } => base.get_operands(collector),
}
}
pub fn mop(&self) -> u32 {
match self {
VecAMode::UnitStride { .. } => 0b00,
}
}
pub fn lumop(&self) -> u32 {
match self {
VecAMode::UnitStride { .. } => 0b00000,
}
}
pub fn sumop(&self) -> u32 {
match self {
VecAMode::UnitStride { .. } => 0b00000,
}
}
pub fn nf(&self) -> u32 {
match self {
VecAMode::UnitStride { .. } => 0b000,
}
}
}
pub trait VecInstOverlapInfo {
fn forbids_src_dst_overlaps(&self) -> bool;
fn forbids_mask_dst_overlaps(&self) -> bool {
true
}
fn forbids_overlaps(&self, mask: &VecOpMasking) -> bool {
self.forbids_src_dst_overlaps() || (mask.is_enabled() && self.forbids_mask_dst_overlaps())
}
}