kraid: Add the hardware MkVec ops

The hardware doesn't have MKVEC.v4i8 in it's current form.  Instead, it
has a MKVEC.v4i8 that takes two i8's and an i16 and you have to do two
of them in order to build a full MKVEC.v4i8.  It also has a MKVEC.v2i16
which does exactly what it says on the tin.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42200>
This commit is contained in:
Faith Ekstrand 2026-06-01 02:56:17 -04:00 committed by Marge Bot
parent b4a18ad2c7
commit 83a01dd382
2 changed files with 105 additions and 3 deletions

View file

@ -211,10 +211,9 @@ fn src_fau_page(src: &Src) -> Option<u8> {
}
}
fn op_encode_src(op: &impl Opcode, src: &Src) -> v9::EncodedSrc {
fn encode_typed_src(src: &Src, src_type: DataType) -> v9::EncodedSrc {
let encoded = encode_src_ref(&src.src_ref, src.last_use);
let src_type = op.src_type(src);
if src_type.bits() == 64 && !src.src_ref.is_small_const() {
assert_eq!(encoded & 0x01, 0);
}
@ -242,6 +241,10 @@ fn op_encode_src(op: &impl Opcode, src: &Src) -> v9::EncodedSrc {
}
}
fn op_encode_src(op: &impl Opcode, src: &Src) -> v9::EncodedSrc {
encode_typed_src(src, op.src_type(src))
}
fn op_encode_dst(op: &impl Opcode, dst: &Dst) -> v9::EncodedDst {
let DstRef::Reg(reg) = &dst.dst_ref else {
panic!("Destination must be a register");
@ -768,6 +771,53 @@ impl V9Instr for OpLoad {
}
}
impl V9Instr for OpMkVecV2I8I16 {
fn get_info(&self, arch: u8) -> Option<V9InstrInfo> {
V9InstrInfo::from_isa(
Mkvec::get_info(MkvecVariant::V2I8, arch),
src_map! {
src0: srcs[0],
src1: srcs[1],
},
)
}
fn encode(&self, e: V9Encoder) -> EncodedInstr {
e.encode(Mkvec {
variant: MkvecVariant::V2I8,
dst: op_encode_dst(self, &self.dst),
src0: op_encode_src(self, &self.srcs[0]),
src1: op_encode_src(self, &self.srcs[1]),
// This one is weird. It's labled i16 in ops.rs because that's
// really what it is but we need to use v2i8 to get it to encode
// correctly.
src2: Some(encode_typed_src(&self.accum, DataType::V2I8)),
})
}
}
impl V9Instr for OpMkVecV2I16 {
fn get_info(&self, arch: u8) -> Option<V9InstrInfo> {
V9InstrInfo::from_isa(
Mkvec::get_info(MkvecVariant::V2I16, arch),
src_map! {
src0: srcs[0],
src1: srcs[1],
},
)
}
fn encode(&self, e: V9Encoder) -> EncodedInstr {
e.encode(Mkvec {
variant: MkvecVariant::V2I16,
dst: op_encode_dst(self, &self.dst),
src0: op_encode_src(self, &self.srcs[0]),
src1: op_encode_src(self, &self.srcs[1]),
src2: None,
})
}
}
impl V9Instr for OpMov {
fn get_info(&self, arch: u8) -> Option<V9InstrInfo> {
V9InstrInfo::from_isa(
@ -1021,6 +1071,8 @@ macro_rules! v9_op_match_else {
Op::LdPka($x) => $y,
Op::LeaPka($x) => $y,
Op::Load($x) => $y,
Op::MkVecV2I8I16($x) => $y,
Op::MkVecV2I16($x) => $y,
Op::Mov($x) => $y,
Op::Nop($x) => $y,
Op::ShiftLop($x) => $y,

View file

@ -445,7 +445,55 @@ impl fmt::Display for OpMkVecV2I8 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{} = MKVEC.v4i8 {} {}",
"{} = MKVEC.v2i8 {} {}",
&self.dst,
self.fmt_src(&self.srcs[0]),
self.fmt_src(&self.srcs[1]),
)
}
}
#[repr(C)]
#[derive(Clone, Opcode)]
pub struct OpMkVecV2I8I16 {
#[dst_type(V4I8)]
pub dst: Dst,
#[src_type(I8)]
pub srcs: [Src; 2],
#[src_type(I16)]
pub accum: Src,
}
impl fmt::Display for OpMkVecV2I8I16 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{} = MKVEC.v2i8+i16 {} {} {}",
&self.dst,
self.fmt_src(&self.srcs[0]),
self.fmt_src(&self.srcs[1]),
self.fmt_src(&self.accum),
)
}
}
#[repr(C)]
#[derive(Clone, Opcode)]
pub struct OpMkVecV2I16 {
#[dst_type(V2I16)]
pub dst: Dst,
#[src_type(I16)]
pub srcs: [Src; 2],
}
impl fmt::Display for OpMkVecV2I16 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{} = MKVEC.v2i16 {} {}",
&self.dst,
self.fmt_src(&self.srcs[0]),
self.fmt_src(&self.srcs[1]),
@ -671,6 +719,8 @@ pub enum Op {
LdPka(Box<OpLdPka>),
Load(Box<OpLoad>),
MkVecV2I8(Box<OpMkVecV2I8>),
MkVecV2I8I16(Box<OpMkVecV2I8I16>),
MkVecV2I16(Box<OpMkVecV2I16>),
MkVecV4I8(Box<OpMkVecV4I8>),
Nop(OpNop),
Mov(Box<OpMov>),