nak: Add a smarter new_lop2 helper

The new helper automatically detects whether you're working with
predicates or GPRs.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Faith Ekstrand 2023-04-21 21:26:19 -05:00 committed by Marge Bot
parent a36a614583
commit 3c7a837c51
2 changed files with 59 additions and 75 deletions

View file

@ -355,23 +355,12 @@ impl<'a> ShaderFromNir<'a> {
}
}
nir_op_iand => {
if alu.def.bit_size() == 1 {
self.instrs.push(Instr::new_plop3(
dst,
LogicOp::new_lut(&|x, y, _| x & y),
srcs[0],
srcs[1],
Src::new_imm_bool(true),
));
} else {
self.instrs.push(Instr::new_lop3(
dst,
LogicOp::new_lut(&|x, y, _| x & y),
srcs[0],
srcs[1],
Src::new_zero(),
));
}
self.instrs.push(Instr::new_lop2(
dst,
LogicOp::new_lut(&|x, y, _| x & y),
srcs[0],
srcs[1],
));
}
nir_op_ieq => {
if alu.get_src(0).bit_size() == 1 {
@ -474,42 +463,20 @@ impl<'a> ShaderFromNir<'a> {
})));
}
nir_op_inot => {
if alu.def.bit_size() == 1 {
self.instrs.push(Instr::new_plop3(
dst,
LogicOp::new_lut(&|x, _, _| !x),
srcs[0],
Src::new_imm_bool(true),
Src::new_imm_bool(true),
));
} else {
self.instrs.push(Instr::new_lop3(
dst,
LogicOp::new_lut(&|x, _, _| !x),
srcs[0],
Src::new_zero(),
Src::new_zero(),
));
}
self.instrs.push(Instr::new_lop2(
dst,
LogicOp::new_lut(&|x, _, _| !x),
srcs[0],
Src::new_imm_bool(true),
));
}
nir_op_ior => {
if alu.def.bit_size() == 1 {
self.instrs.push(Instr::new_plop3(
dst,
LogicOp::new_lut(&|x, y, _| x | y),
srcs[0],
srcs[1],
Src::new_imm_bool(true),
));
} else {
self.instrs.push(Instr::new_lop3(
dst,
LogicOp::new_lut(&|x, y, _| x | y),
srcs[0],
srcs[1],
Src::new_zero(),
));
}
self.instrs.push(Instr::new_lop2(
dst,
LogicOp::new_lut(&|x, y, _| x | y),
srcs[0],
srcs[1],
));
}
nir_op_ishl => {
self.instrs.push(Instr::new(Op::Shf(OpShf {
@ -536,23 +503,12 @@ impl<'a> ShaderFromNir<'a> {
})));
}
nir_op_ixor => {
if alu.def.bit_size() == 1 {
self.instrs.push(Instr::new_plop3(
dst,
LogicOp::new_lut(&|x, y, _| x ^ y),
srcs[0],
srcs[1],
Src::new_imm_bool(true),
));
} else {
self.instrs.push(Instr::new_lop3(
dst,
LogicOp::new_lut(&|x, y, _| x ^ y),
srcs[0],
srcs[1],
Src::new_zero(),
));
}
self.instrs.push(Instr::new_lop2(
dst,
LogicOp::new_lut(&|x, y, _| x ^ y),
srcs[0],
srcs[1],
));
}
nir_op_mov => {
self.instrs.push(Instr::new_mov(dst, srcs[0]));

View file

@ -425,6 +425,15 @@ pub enum SrcRef {
}
impl SrcRef {
pub fn is_predicate(&self) -> bool {
match self {
SrcRef::Zero | SrcRef::Imm32(_) | SrcRef::CBuf(_) => false,
SrcRef::True | SrcRef::False => true,
SrcRef::SSA(ssa) => ssa.is_predicate(),
SrcRef::Reg(reg) => reg.is_predicate(),
}
}
pub fn as_reg(&self) -> Option<&RegRef> {
match self {
SrcRef::Reg(r) => Some(r),
@ -2671,17 +2680,36 @@ impl Instr {
}))
}
pub fn new_lop3(dst: Dst, op: LogicOp, x: Src, y: Src, z: Src) -> Instr {
Instr::new(Op::Lop3(OpLop3 {
dst: dst,
srcs: [x, y, z],
op: op,
}))
pub fn new_lop2(dst: Dst, op: LogicOp, x: Src, y: Src) -> Instr {
/* Only uses x and y */
assert!(op.eval(0x5, 0x3, 0x0) == op.eval(0x5, 0x3, 0xf));
let is_predicate = match dst {
Dst::None => panic!("No LOP destination"),
Dst::SSA(ssa) => ssa.is_predicate(),
Dst::Reg(reg) => reg.is_predicate(),
};
assert!(x.src_ref.is_predicate() == is_predicate);
assert!(x.src_ref.is_predicate() == is_predicate);
if is_predicate {
Instr::new(OpPLop3 {
dsts: [dst, Dst::None],
srcs: [x, y, Src::new_imm_bool(true)],
ops: [op, LogicOp::new_const(false)],
})
} else {
Instr::new(OpLop3 {
dst: dst,
srcs: [x, y, Src::new_zero()],
op: op,
})
}
}
pub fn new_xor(dst: Dst, x: Src, y: Src) -> Instr {
let xor_lop = LogicOp::new_lut(&|x, y, _| x ^ y);
Instr::new_lop3(dst, xor_lop, x, y, Src::new_zero())
Instr::new_lop2(dst, xor_lop, x, y)
}
pub fn new_mov(dst: Dst, src: Src) -> Instr {