From 1a373edfc576f81885fa2685d95edc27d50e7022 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Mon, 21 Apr 2025 18:14:29 -0500 Subject: [PATCH] nak/sm20: Fix legalization of IAdd and IMul They were both missing subtle cases. While we're here, fix a bunch of SrcTypes. They shouldn't matter in practice since it's just used to determine how many GPRs to allocate but we may as well get them right. Fixes: 078ffb860b43 ("nak/sm20: Add initial SM20 encoding") Part-of: --- src/nouveau/compiler/nak/sm20.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/nouveau/compiler/nak/sm20.rs b/src/nouveau/compiler/nak/sm20.rs index 204294e46e4..89c1082ac1e 100644 --- a/src/nouveau/compiler/nak/sm20.rs +++ b/src/nouveau/compiler/nak/sm20.rs @@ -1044,7 +1044,7 @@ impl SM20Op for OpDSetP { impl SM20Op for OpBfe { fn legalize(&mut self, b: &mut LegalizeBuilder) { use RegFile::GPR; - b.copy_alu_src_if_not_reg(&mut self.base, GPR, SrcType::I32); + b.copy_alu_src_if_not_reg(&mut self.base, GPR, SrcType::ALU); if let SrcRef::Imm32(imm32) = &mut self.range.src_ref { // Only the bottom 16 bits of the immediate matter *imm32 &= 0xffff; @@ -1089,6 +1089,9 @@ impl SM20Op for OpIAdd2 { b.copy_alu_src_and_lower_ineg(src0, GPR, SrcType::I32); } b.copy_alu_src_if_not_reg(src0, GPR, SrcType::I32); + if !self.carry_out.is_none() { + b.copy_alu_src_if_ineg_imm(src1, GPR, SrcType::I32); + } } fn encode(&self, e: &mut SM20Encoder<'_>) { @@ -1127,7 +1130,7 @@ impl SM20Op for OpIAdd2X { use RegFile::GPR; let [src0, src1] = &mut self.srcs; swap_srcs_if_not_reg(src0, src1, GPR); - b.copy_alu_src_if_not_reg(src0, GPR, SrcType::I32); + b.copy_alu_src_if_not_reg(src0, GPR, SrcType::B32); } fn encode(&self, e: &mut SM20Encoder<'_>) { @@ -1167,18 +1170,18 @@ impl SM20Op for OpIMad { use RegFile::GPR; let [src0, src1, src2] = &mut self.srcs; swap_srcs_if_not_reg(src0, src1, GPR); - b.copy_alu_src_if_not_reg(src0, GPR, SrcType::I32); - b.copy_alu_src_if_i20_overflow(src1, GPR, SrcType::I32); + b.copy_alu_src_if_not_reg(src0, GPR, SrcType::ALU); + b.copy_alu_src_if_i20_overflow(src1, GPR, SrcType::ALU); let neg_ab = src0.src_mod.is_ineg() ^ src1.src_mod.is_ineg(); let neg_c = src2.src_mod.is_ineg(); if neg_ab && neg_c { - b.copy_alu_src_and_lower_ineg(src2, GPR, SrcType::I32); + b.copy_alu_src_and_lower_ineg(src2, GPR, SrcType::ALU); } if src_is_reg(src1, GPR) { b.copy_alu_src_if_imm(src2, GPR, SrcType::ALU); } else { - b.copy_alu_src_if_not_reg(src2, GPR, SrcType::I32); + b.copy_alu_src_if_not_reg(src2, GPR, SrcType::ALU); } } @@ -1210,8 +1213,10 @@ impl SM20Op for OpIMul { fn legalize(&mut self, b: &mut LegalizeBuilder) { use RegFile::GPR; let [src0, src1] = &mut self.srcs; - swap_srcs_if_not_reg(src0, src1, GPR); - b.copy_alu_src_if_not_reg(src0, GPR, SrcType::I32); + if swap_srcs_if_not_reg(src0, src1, GPR) { + self.signed.swap(0, 1); + } + b.copy_alu_src_if_not_reg(src0, GPR, SrcType::ALU); } fn encode(&self, e: &mut SM20Encoder<'_>) {