diff --git a/src/nouveau/compiler/nak_builder.rs b/src/nouveau/compiler/nak_builder.rs index 6c739b9bd53..a4862f267fa 100644 --- a/src/nouveau/compiler/nak_builder.rs +++ b/src/nouveau/compiler/nak_builder.rs @@ -21,6 +21,49 @@ pub trait Builder { pred: pred, } } + + fn lop2_to(&mut self, dst: Dst, op: LogicOp, x: Src, y: Src) { + /* Only uses x and y */ + assert!(!op.src_used(2)); + + 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.is_predicate() == is_predicate); + assert!(y.is_predicate() == is_predicate); + + if is_predicate { + self.push_op(OpPLop3 { + dsts: [dst.into(), Dst::None], + srcs: [x, y, Src::new_imm_bool(true)], + ops: [op, LogicOp::new_const(false)], + }); + } else { + self.push_op(OpLop3 { + dst: dst.into(), + srcs: [x, y, Src::new_zero()], + op: op, + }); + } + } + + fn mov_to(&mut self, dst: Dst, src: Src) { + self.push_op(OpMov { + dst: dst, + src: src, + quad_lanes: 0xf, + }); + } + + fn swap(&mut self, x: RegRef, y: RegRef) { + assert!(x.file() == y.file()); + self.push_op(OpSwap { + dsts: [x.into(), y.into()], + srcs: [y.into(), x.into()], + }); + } } pub trait SSABuilder: Builder { @@ -119,36 +162,19 @@ pub trait SSABuilder: Builder { } fn lop2(&mut self, op: LogicOp, x: Src, y: Src) -> SSARef { - /* Only uses x and y */ - assert!(op.eval(0x5, 0x3, 0x0) == op.eval(0x5, 0x3, 0xf)); - assert!(x.is_predicate() == y.is_predicate()); - if x.is_predicate() { - let dst = self.alloc_ssa(RegFile::Pred, 1); - self.push_op(OpPLop3 { - dsts: [dst.into(), Dst::None], - srcs: [x, y, Src::new_imm_bool(true)], - ops: [op, LogicOp::new_const(false)], - }); - dst + let dst = if x.is_predicate() { + self.alloc_ssa(RegFile::Pred, 1) } else { - let dst = self.alloc_ssa(RegFile::GPR, 1); - self.push_op(OpLop3 { - dst: dst.into(), - srcs: [x, y, Src::new_zero()], - op: op, - }); - dst - } + self.alloc_ssa(RegFile::GPR, 1) + }; + self.lop2_to(dst.into(), op, x, y); + dst } fn mov(&mut self, src: Src) -> SSARef { assert!(!src.is_predicate()); let dst = self.alloc_ssa(RegFile::GPR, 1); - self.push_op(OpMov { - dst: dst.into(), - src: src, - quad_lanes: 0xf, - }); + self.mov_to(dst.into(), src); dst } diff --git a/src/nouveau/compiler/nak_ir.rs b/src/nouveau/compiler/nak_ir.rs index 33e72ec31f7..ccdcf6eb41f 100644 --- a/src/nouveau/compiler/nak_ir.rs +++ b/src/nouveau/compiler/nak_ir.rs @@ -3242,58 +3242,6 @@ impl Instr { Box::new(Instr::new(op)) } - pub fn new_isetp( - dst: Dst, - cmp_type: IntCmpType, - cmp_op: IntCmpOp, - x: Src, - y: Src, - ) -> Instr { - OpISetP { - dst: dst, - set_op: PredSetOp::And, - cmp_op: cmp_op, - cmp_type: cmp_type, - srcs: [x, y], - accum: SrcRef::True.into(), - } - .into() - } - - 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 { - OpPLop3 { - dsts: [dst, Dst::None], - srcs: [x, y, Src::new_imm_bool(true)], - ops: [op, LogicOp::new_const(false)], - } - .into() - } else { - OpLop3 { - dst: dst, - srcs: [x, y, Src::new_zero()], - op: op, - } - .into() - } - } - - pub fn new_xor(dst: Dst, x: Src, y: Src) -> Instr { - let xor_lop = LogicOp::new_lut(&|x, y, _| x ^ y); - Instr::new_lop2(dst, xor_lop, x, y) - } - pub fn new_mov(dst: Dst, src: Src) -> Instr { OpMov { dst: dst, @@ -3303,25 +3251,6 @@ impl Instr { .into() } - pub fn new_plop3(dst: Dst, op: LogicOp, x: Src, y: Src, z: Src) -> Instr { - assert!(x.is_predicate() && y.is_predicate() && z.is_predicate()); - OpPLop3 { - dsts: [dst, Dst::None], - srcs: [x, y, z], - ops: [op, LogicOp::new_const(false)], - } - .into() - } - - pub fn new_swap(x: RegRef, y: RegRef) -> Instr { - assert!(x.file() == y.file()); - OpSwap { - dsts: [x.into(), y.into()], - srcs: [y.into(), x.into()], - } - .into() - } - pub fn dsts(&self) -> &[Dst] { self.op.dsts_as_slice() } @@ -3645,24 +3574,25 @@ impl Shader { assert!(swap.srcs[1].src_mod.is_none()); assert!(*swap.srcs[1].src_ref.as_reg().unwrap() == x); + let mut b = InstrBuilder::new(); if x == y { - MappedInstrs::None + /* Nothing to do */ } else if x.is_predicate() { - MappedInstrs::One(Instr::new_boxed(OpPLop3 { + b.push_op(OpPLop3 { dsts: [x.into(), y.into()], srcs: [x.into(), y.into(), Src::new_imm_bool(true)], ops: [ LogicOp::new_lut(&|_, y, _| y), LogicOp::new_lut(&|x, _, _| x), ], - })) + }) } else { - MappedInstrs::Many(vec![ - Instr::new_xor(x.into(), x.into(), y.into()).into(), - Instr::new_xor(y.into(), x.into(), y.into()).into(), - Instr::new_xor(x.into(), x.into(), y.into()).into(), - ]) + let xor = LogicOp::new_lut(&|x, y, _| x ^ y); + b.lop2_to(x.into(), xor, x.into(), y.into()); + b.lop2_to(y.into(), xor, x.into(), y.into()); + b.lop2_to(x.into(), xor, x.into(), y.into()); } + b.as_mapped_instrs() } _ => MappedInstrs::One(instr), } @@ -3675,38 +3605,36 @@ impl Shader { Op::Mov(mov) => { assert!(mov.src.src_mod.is_none()); match mov.src.src_ref { - SrcRef::True => MappedInstrs::One( - Instr::new_isetp( + SrcRef::True => { + let mut b = InstrBuilder::new(); + b.lop2_to( mov.dst, - IntCmpType::I32, - IntCmpOp::Eq, - Src::new_zero(), - Src::new_zero(), - ) - .into(), - ), - SrcRef::False => MappedInstrs::One( - Instr::new_isetp( + LogicOp::new_const(true), + Src::new_imm_bool(true), + Src::new_imm_bool(true), + ); + b.as_mapped_instrs() + } + SrcRef::False => { + let mut b = InstrBuilder::new(); + b.lop2_to( mov.dst, - IntCmpType::I32, - IntCmpOp::Ne, - Src::new_zero(), - Src::new_zero(), - ) - .into(), - ), + LogicOp::new_const(false), + Src::new_imm_bool(true), + Src::new_imm_bool(true), + ); + b.as_mapped_instrs() + } SrcRef::Reg(reg) => { if reg.is_predicate() { - MappedInstrs::One( - Instr::new_plop3( - mov.dst, - LogicOp::new_lut(&|x, _, _| x), - mov.src, - Src::new_imm_bool(true), - Src::new_imm_bool(true), - ) - .into(), - ) + let mut b = InstrBuilder::new(); + b.lop2_to( + mov.dst, + LogicOp::new_lut(&|x, _, _| x), + mov.src, + Src::new_imm_bool(true), + ); + b.as_mapped_instrs() } else { MappedInstrs::One(instr) } diff --git a/src/nouveau/compiler/nak_lower_par_copies.rs b/src/nouveau/compiler/nak_lower_par_copies.rs index 1b3dff68691..3645d4fd614 100644 --- a/src/nouveau/compiler/nak_lower_par_copies.rs +++ b/src/nouveau/compiler/nak_lower_par_copies.rs @@ -110,7 +110,7 @@ fn lower_par_copy(pc: OpParCopy) -> MappedInstrs { } } - let mut instrs = Vec::new(); + let mut b = InstrBuilder::new(); let mut ready = Vec::new(); for i in 0..pc.dsts.len() { @@ -123,7 +123,7 @@ fn lower_par_copy(pc: OpParCopy) -> MappedInstrs { if let Some(src_idx) = graph.src(dst_idx) { let dst = *vals[dst_idx].as_reg().unwrap(); let src = vals[src_idx]; - instrs.push(Instr::new_mov(dst.into(), src.into()).into()); + b.mov_to(dst.into(), src.into()); if graph.del_edge(dst_idx, src_idx) { ready.push(src_idx); } @@ -161,15 +161,7 @@ fn lower_par_copy(pc: OpParCopy) -> MappedInstrs { if let Some(j) = graph.src(i) { /* We're part of a cycle so j also has a source */ let k = graph.src(j).unwrap(); - - instrs.push( - Instr::new_swap( - *vals[j].as_reg().unwrap(), - *vals[k].as_reg().unwrap(), - ) - .into(), - ); - + b.swap(*vals[j].as_reg().unwrap(), *vals[k].as_reg().unwrap()); graph.del_edge(i, j); graph.del_edge(j, k); if i != k { @@ -183,7 +175,7 @@ fn lower_par_copy(pc: OpParCopy) -> MappedInstrs { } } - MappedInstrs::Many(instrs) + b.as_mapped_instrs() } impl Shader {