nak: Implement right-shifts

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Faith Ekstrand 2023-04-10 17:23:31 -05:00 committed by Marge Bot
parent 90a05b5591
commit 1825f54d79
3 changed files with 78 additions and 24 deletions

View file

@ -617,19 +617,28 @@ impl SM75Instr {
self.set_bit(90, true);
}
fn encode_shl(&mut self, op: &OpShl) {
fn encode_shf(&mut self, op: &OpShf) {
self.encode_alu(
0x019,
Some(op.dst),
ALUSrc::from_src(&op.srcs[0].into()),
ALUSrc::from_src(&op.srcs[1].into()),
ALUSrc::None,
ALUSrc::from_src(&op.low),
ALUSrc::from_src(&op.shift),
ALUSrc::from_src(&op.high),
);
self.set_field(73..75, 3_u32 /* U32 */);
self.set_bit(75, true /* W? */);
self.set_bit(76, false /* Left */);
self.set_bit(80, false /* HI */);
self.set_field(
73..75,
match op.data_type {
IntType::I64 => 0_u8,
IntType::U64 => 1_u8,
IntType::I32 => 2_u8,
IntType::U32 => 3_u8,
_ => panic!("Invalid shift data type"),
},
);
self.set_bit(75, op.wrap);
self.set_bit(76, op.right);
self.set_bit(80, op.dst_high);
}
fn encode_f2i(&mut self, op: &OpF2I) {
@ -891,7 +900,7 @@ impl SM75Instr {
Op::IMnMx(op) => si.encode_imnmx(&op),
Op::ISetP(op) => si.encode_isetp(&op),
Op::Lop3(op) => si.encode_lop3(&op),
Op::Shl(op) => si.encode_shl(&op),
Op::Shf(op) => si.encode_shf(&op),
Op::F2I(op) => si.encode_f2i(&op),
Op::I2F(op) => si.encode_i2f(&op),
Op::Mov(op) => si.encode_mov(&op),

View file

@ -469,7 +469,28 @@ impl<'a> ShaderFromNir<'a> {
}
}
nir_op_ishl => {
self.instrs.push(Instr::new_shl(dst, srcs[0], srcs[1]));
self.instrs.push(Instr::new(Op::Shf(OpShf {
dst: dst,
low: srcs[0],
high: Src::new_zero(),
shift: srcs[1],
right: false,
wrap: true,
data_type: IntType::U32,
dst_high: false,
})));
}
nir_op_ishr => {
self.instrs.push(Instr::new(Op::Shf(OpShf {
dst: dst,
low: Src::new_zero(),
high: srcs[0],
shift: srcs[1],
right: true,
wrap: true,
data_type: IntType::I32,
dst_high: true,
})));
}
nir_op_mov => {
self.instrs.push(Instr::new_mov(dst, srcs[0]));
@ -506,6 +527,18 @@ impl<'a> ShaderFromNir<'a> {
self.instrs
.push(Instr::new_split(&[Dst::None, dst], srcs[0]));
}
nir_op_ushr => {
self.instrs.push(Instr::new(Op::Shf(OpShf {
dst: dst,
low: srcs[0],
high: Src::new_zero(),
shift: srcs[1],
right: true,
wrap: true,
data_type: IntType::U32,
dst_high: false,
})));
}
nir_op_vec2 | nir_op_vec3 | nir_op_vec4 => {
self.instrs.push(Instr::new_vec(dst, &srcs));
}

View file

@ -1331,17 +1331,36 @@ impl fmt::Display for OpLop3 {
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpShl {
pub struct OpShf {
pub dst: Dst,
pub srcs: [Src; 2],
pub low: Src,
pub high: Src,
pub shift: Src,
pub right: bool,
pub wrap: bool,
pub data_type: IntType,
pub dst_high: bool,
}
impl fmt::Display for OpShl {
impl fmt::Display for OpShf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "SHF")?;
if self.right {
write!(f, ".R")?;
} else {
write!(f, ".L")?;
}
if self.wrap {
write!(f, ".W")?;
}
write!(f, ".{}", self.data_type)?;
if self.dst_high {
write!(f, ".HI")?;
}
write!(
f,
"SHL {} {{ {}, {} }}",
self.dst, self.srcs[0], self.srcs[1],
" {} {{ {}, {} }} {}",
self.dst, self.low, self.high, self.shift
)
}
}
@ -1890,7 +1909,7 @@ pub enum Op {
IMnMx(OpIMnMx),
ISetP(OpISetP),
Lop3(OpLop3),
Shl(OpShl),
Shf(OpShf),
F2I(OpF2I),
I2F(OpI2F),
Mov(OpMov),
@ -2182,13 +2201,6 @@ impl Instr {
Instr::new_lop3(dst, xor_lop, x, y, Src::new_zero())
}
pub fn new_shl(dst: Dst, x: Src, shift: Src) -> Instr {
Instr::new(Op::Shl(OpShl {
dst: dst,
srcs: [x, shift],
}))
}
pub fn new_mov(dst: Dst, src: Src) -> Instr {
Instr::new(Op::Mov(OpMov {
dst: dst,
@ -2360,7 +2372,7 @@ impl Instr {
| Op::Lop3(_)
| Op::PLop3(_)
| Op::ISetP(_)
| Op::Shl(_) => Some(6),
| Op::Shf(_) => Some(6),
Op::F2I(_) | Op::I2F(_) | Op::Mov(_) => Some(15),
Op::MuFu(_) => None,
Op::Sel(_) => Some(15),