From 520ad0f4a7816d69114ef5db3b8f377adbb78f17 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Mon, 30 Jan 2023 20:53:19 -0600 Subject: [PATCH] nak: Implement iadd64 Part-of: --- src/nouveau/compiler/nak.rs | 2 +- src/nouveau/compiler/nak_from_nir.rs | 37 +++++++++++++++++++++++++++- src/nouveau/compiler/nak_ir.rs | 8 ++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/nouveau/compiler/nak.rs b/src/nouveau/compiler/nak.rs index ac544e7e04f..f5602e530fe 100644 --- a/src/nouveau/compiler/nak.rs +++ b/src/nouveau/compiler/nak.rs @@ -50,7 +50,7 @@ fn nir_options(dev: &nv_device_info) -> nir_shader_compiler_options { op.lower_iadd_sat = true; // TODO op.use_interpolated_input_intrinsics = true; op.lower_mul_2x32_64 = true; // TODO - op.lower_int64_options = !0; + op.lower_int64_options = !nir_lower_iadd64; op } diff --git a/src/nouveau/compiler/nak_from_nir.rs b/src/nouveau/compiler/nak_from_nir.rs index 4294d0e6a9e..d80c88a08fb 100644 --- a/src/nouveau/compiler/nak_from_nir.rs +++ b/src/nouveau/compiler/nak_from_nir.rs @@ -81,6 +81,15 @@ impl<'a> ShaderFromNir<'a> { } } + fn split64(&mut self, ssa: SSAValue) -> [SSAValue; 2] { + assert!(ssa.comps() == 2); + let split = + [self.alloc_ssa(ssa.file(), 1), self.alloc_ssa(ssa.file(), 1)]; + let dsts = [split[0].into(), split[1].into()]; + self.instrs.push(Instr::new_split(&dsts, ssa.into())); + split + } + fn parse_alu(&mut self, alu: &nir_alu_instr) { let mut srcs = Vec::new(); for alu_src in alu.srcs_as_slice() { @@ -198,7 +207,33 @@ impl<'a> ShaderFromNir<'a> { }))); } nir_op_iadd => { - self.instrs.push(Instr::new_iadd(dst, srcs[0], srcs[1])); + if alu.def.bit_size() == 64 { + let x = self.split64(*srcs[0].as_ssa().unwrap()); + let y = self.split64(*srcs[1].as_ssa().unwrap()); + let carry = self.alloc_ssa(RegFile::Pred, 1); + + let sum = [ + self.alloc_ssa(dst.as_ssa().unwrap().file(), 1), + self.alloc_ssa(dst.as_ssa().unwrap().file(), 1), + ]; + self.instrs.push(Instr::new(Op::IAdd3(OpIAdd3 { + dst: sum[0].into(), + overflow: carry.into(), + srcs: [x[0].into(), y[0].into(), Src::new_zero()], + carry: Src::new_zero(), + }))); + self.instrs.push(Instr::new(Op::IAdd3(OpIAdd3 { + dst: sum[1].into(), + overflow: Dst::None, + srcs: [x[1].into(), y[1].into(), Src::new_zero()], + carry: carry.into(), + }))); + + let sum = [sum[0].into(), sum[1].into()]; + self.instrs.push(Instr::new_vec(dst, &sum)); + } else { + self.instrs.push(Instr::new_iadd(dst, srcs[0], srcs[1])); + } } nir_op_iand => { if alu.def.bit_size() == 1 { diff --git a/src/nouveau/compiler/nak_ir.rs b/src/nouveau/compiler/nak_ir.rs index ec70dee3c6b..7bab4d8ca3b 100644 --- a/src/nouveau/compiler/nak_ir.rs +++ b/src/nouveau/compiler/nak_ir.rs @@ -467,6 +467,14 @@ impl Src { } } + pub fn as_ssa(&self) -> Option<&SSAValue> { + if self.src_mod.is_none() { + self.src_ref.as_ssa() + } else { + None + } + } + pub fn get_reg(&self) -> Option<&RegRef> { self.src_ref.get_reg() }