From 4b8a8b2a288ddbf3f6aeeb911b95cf548db93cef Mon Sep 17 00:00:00 2001 From: Benjamin Lee Date: Sat, 11 Nov 2023 15:58:02 -0800 Subject: [PATCH] nak: use carry register file for IADD2 This allows detecting dependencies between IADD.X and IADD.CC, which is necessary for SM50 sched and DCE. Part-of: --- src/nouveau/compiler/nak/builder.rs | 13 +++++++------ src/nouveau/compiler/nak/encode_sm50.rs | 19 +++++++++++++++---- src/nouveau/compiler/nak/ir.rs | 21 ++++++++------------- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/nouveau/compiler/nak/builder.rs b/src/nouveau/compiler/nak/builder.rs index 8e116d2c741..0f377799246 100644 --- a/src/nouveau/compiler/nak/builder.rs +++ b/src/nouveau/compiler/nak/builder.rs @@ -196,8 +196,8 @@ pub trait SSABuilder: Builder { self.push_op(OpIAdd2 { dst: dst.into(), srcs: [x, y], - carry_in: false, - carry_out: false, + carry_in: 0.into(), + carry_out: Dst::None, }); } dst @@ -221,17 +221,18 @@ pub trait SSABuilder: Builder { carry: [carry.into(), false.into()], }); } else { + let carry = self.alloc_ssa(RegFile::Carry, 1); self.push_op(OpIAdd2 { dst: dst[0].into(), srcs: [x[0].into(), y[0].into()], - carry_out: true, - carry_in: false, + carry_out: carry.into(), + carry_in: 0.into(), }); self.push_op(OpIAdd2 { dst: dst[1].into(), srcs: [x[1].into(), y[1].into()], - carry_out: false, - carry_in: true, + carry_out: Dst::None, + carry_in: carry.into(), }); } dst diff --git a/src/nouveau/compiler/nak/encode_sm50.rs b/src/nouveau/compiler/nak/encode_sm50.rs index fb54e0159d3..5ab25ae6cbd 100644 --- a/src/nouveau/compiler/nak/encode_sm50.rs +++ b/src/nouveau/compiler/nak/encode_sm50.rs @@ -1885,6 +1885,17 @@ impl SM50Instr { } fn encode_iadd2(&mut self, op: &OpIAdd2) { + let carry_in = match op.carry_in.src_ref { + SrcRef::Reg(reg) if reg.file() == RegFile::Carry => true, + SrcRef::Zero => false, + other => panic!("invalid carry_in src for IADD2 {other}"), + }; + let carry_out = match op.carry_out { + Dst::Reg(reg) if reg.file() == RegFile::Carry => true, + Dst::None => false, + other => panic!("invalid carry_out dst for IADD2 {other}"), + }; + if let Some(imm32) = op.srcs[1].as_imm_not_i20() { self.set_opcode(0x1c00); @@ -1892,8 +1903,8 @@ impl SM50Instr { self.set_reg_ineg_src(8..16, 56, op.srcs[0]); self.set_src_imm32(20..56, imm32); - self.set_bit(53, op.carry_in); - self.set_bit(52, op.carry_out); + self.set_bit(53, carry_in); + self.set_bit(52, carry_out); } else { match &op.srcs[1].src_ref { SrcRef::Zero | SrcRef::Reg(_) => { @@ -1914,8 +1925,8 @@ impl SM50Instr { self.set_dst(op.dst); self.set_reg_ineg_src(8..16, 49, op.srcs[0]); - self.set_bit(43, op.carry_in); - self.set_bit(47, op.carry_out); + self.set_bit(43, carry_in); + self.set_bit(47, carry_out); } } diff --git a/src/nouveau/compiler/nak/ir.rs b/src/nouveau/compiler/nak/ir.rs index b38f1d9938f..0077029d692 100644 --- a/src/nouveau/compiler/nak/ir.rs +++ b/src/nouveau/compiler/nak/ir.rs @@ -2491,25 +2491,20 @@ impl_display_for_op!(OpINeg); #[derive(SrcsAsSlice, DstsAsSlice)] pub struct OpIAdd2 { pub dst: Dst, + pub carry_out: Dst, #[src_type(ALU)] pub srcs: [Src; 2], - - // TODO: We should probably track this as an SSA value somehow - pub carry_out: bool, - pub carry_in: bool, + pub carry_in: Src, } impl DisplayOp for OpIAdd2 { fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "iadd")?; - if self.carry_in { - write!(f, ".x")?; + write!(f, "iadd2 {} {}", self.srcs[0], self.srcs[1])?; + if !self.carry_in.is_zero() { + write!(f, " {}", self.carry_in)?; } - if self.carry_out { - write!(f, ".cc")?; - } - write!(f, " {} {}", self.srcs[0], self.srcs[1]) + Ok(()) } } @@ -5498,8 +5493,8 @@ impl Shader { instr.op = Op::IAdd2(OpIAdd2 { dst: neg.dst, srcs: [0.into(), neg.src.ineg()], - carry_in: false, - carry_out: false, + carry_in: 0.into(), + carry_out: Dst::None, }); } MappedInstrs::One(instr)