nak: add support for findmsb,findlsb

These all map into OpBFind, which is sourced from PTX and NV50.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Daniel Almeida 2023-07-24 12:16:16 -03:00 committed by Marge Bot
parent e887c4d07a
commit 1f10cdbbbe
4 changed files with 67 additions and 2 deletions

View file

@ -1504,6 +1504,21 @@ impl SM75Instr {
);
}
fn encode_bfind(&mut self, op: &OpBFind) {
self.encode_alu(
0x100,
Some(op.dst),
ALUSrc::None,
ALUSrc::from_src(&op.src),
ALUSrc::None,
);
self.set_pred_dst(81..84, Dst::None);
self.set_field(74..75, op.return_shift_amount as u8);
self.set_field(73..74, op.signed as u8);
let not_mod = matches!(op.src.src_mod, SrcMod::BNot);
self.set_field(63..64, not_mod)
}
pub fn encode(
instr: &Instr,
sm: u8,
@ -1564,6 +1579,7 @@ impl SM75Instr {
Op::S2R(op) => si.encode_s2r(&op),
Op::PopC(op) => si.encode_popc(&op),
Op::Brev(op) => si.encode_brev(&op),
Op::BFind(op) => si.encode_bfind(&op),
_ => panic!("Unhandled instruction"),
}

View file

@ -224,6 +224,21 @@ impl<'a> ShaderFromNir<'a> {
});
dst
}
nir_op_find_lsb => {
let tmp = b.alloc_ssa(RegFile::GPR, 1);
b.push_op(OpBrev {
dst: tmp.into(),
src: srcs[0],
});
let dst = b.alloc_ssa(RegFile::GPR, 1);
b.push_op(OpBFind {
dst: dst.into(),
src: tmp.into(),
signed: alu.op == nir_op_ifind_msb,
return_shift_amount: true,
});
dst
}
nir_op_f2i32 | nir_op_f2u32 => {
let src_bits = usize::from(alu.get_src(0).bit_size());
let dst_bits = alu.def.bit_size();
@ -450,6 +465,16 @@ impl<'a> ShaderFromNir<'a> {
b.isetp(IntCmpType::I32, IntCmpOp::Eq, srcs[0], srcs[1])
}
}
nir_op_ifind_msb | nir_op_ufind_msb => {
let dst = b.alloc_ssa(RegFile::GPR, 1);
b.push_op(OpBFind {
dst: dst.into(),
src: srcs[0],
signed: alu.op == nir_op_ifind_msb,
return_shift_amount: false,
});
dst
}
nir_op_ige => {
b.isetp(IntCmpType::I32, IntCmpOp::Ge, srcs[0], srcs[1])
}

View file

@ -3165,6 +3165,28 @@ impl fmt::Display for OpBrev {
}
}
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpBFind {
pub dst: Dst,
#[src_type(ALU)]
pub src: Src,
pub signed: bool,
pub return_shift_amount: bool,
}
impl fmt::Display for OpBFind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "BFIND")?;
if self.return_shift_amount {
write!(f, ".SAMT")?;
}
write!(f, " {} {}", self.dst, self.src)
}
}
#[derive(Display, DstsAsSlice, SrcsAsSlice, FromVariants)]
pub enum Op {
FAdd(OpFAdd),
@ -3221,6 +3243,7 @@ pub enum Op {
FSOut(OpFSOut),
PopC(OpPopC),
Brev(OpBrev),
BFind(OpBFind),
}
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
@ -3537,7 +3560,7 @@ impl Instr {
| Op::FSOut(_) => {
panic!("Not a hardware opcode")
}
Op::PopC(_) | Op::Brev(_) => Some(15),
Op::PopC(_) | Op::Brev(_) | Op::BFind(_) => Some(15),
}
}
}

View file

@ -188,7 +188,8 @@ impl<'a> LegalizeInstr<'a> {
| Op::Mov(_)
| Op::FRnd(_)
| Op::PopC(_)
| Op::Brev(_) => (),
| Op::Brev(_)
| Op::BFind(_) => (),
Op::Sel(op) => {
let [ref mut src0, ref mut src1] = op.srcs;
if !src_is_reg(src0) && src_is_reg(src1) {