From f542a60686f88d6dafd65ab0dfe4fa0aa5de8f7a Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Mon, 12 May 2025 18:36:31 -0400 Subject: [PATCH] nak: Add a helper to reduce OpPrmt sel immediates Only the bottom 16 bits matter of the select source matter so we can throw away the top 16 bits and avoid any i20 encoding issues. All of the back-ends were already doing this except SM70 which has 32-bit immediates anyway. However, doing it in a common place where it's documented is better than skattering it everywhere. Also, doing it as part of legalization ensures that we see the same thing in the post-legalize IR as gets encoded. Part-of: --- src/nouveau/compiler/nak/ir.rs | 9 +++++++++ src/nouveau/compiler/nak/sm20.rs | 5 +---- src/nouveau/compiler/nak/sm32.rs | 6 +----- src/nouveau/compiler/nak/sm50.rs | 3 ++- src/nouveau/compiler/nak/sm70_encode.rs | 1 + 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/nouveau/compiler/nak/ir.rs b/src/nouveau/compiler/nak/ir.rs index 58ef4bdb741..ebb67364852 100644 --- a/src/nouveau/compiler/nak/ir.rs +++ b/src/nouveau/compiler/nak/ir.rs @@ -4617,6 +4617,15 @@ impl OpPrmt { } } + /// Reduces the sel immediate, if any. + pub fn reduce_sel_imm(&mut self) { + assert!(self.sel.src_mod.is_none()); + if let SrcRef::Imm32(sel) = &mut self.sel.src_ref { + // Only the bottom 16 bits matter anyway + *sel &= 0xffff; + } + } + pub fn as_u32(&self) -> Option { let Some(sel) = self.get_sel() else { return None; diff --git a/src/nouveau/compiler/nak/sm20.rs b/src/nouveau/compiler/nak/sm20.rs index 723b3aa8094..d68060c045e 100644 --- a/src/nouveau/compiler/nak/sm20.rs +++ b/src/nouveau/compiler/nak/sm20.rs @@ -1531,10 +1531,7 @@ impl SM20Op for OpPrmt { let [src0, src1] = &mut self.srcs; b.copy_alu_src_if_not_reg(src0, GPR, SrcType::ALU); b.copy_alu_src_if_not_reg(src1, GPR, SrcType::ALU); - if let SrcRef::Imm32(imm32) = &mut self.sel.src_ref { - // Only the bottom 16 bits matter anyway - *imm32 = *imm32 & 0xffff; - } + self.reduce_sel_imm(); } fn encode(&self, e: &mut SM20Encoder<'_>) { diff --git a/src/nouveau/compiler/nak/sm32.rs b/src/nouveau/compiler/nak/sm32.rs index 81a408f57d6..4de0eab4f97 100644 --- a/src/nouveau/compiler/nak/sm32.rs +++ b/src/nouveau/compiler/nak/sm32.rs @@ -1778,11 +1778,7 @@ impl SM32Op for OpPrmt { use RegFile::GPR; b.copy_alu_src_if_not_reg(&mut self.srcs[0], GPR, SrcType::GPR); b.copy_alu_src_if_not_reg(&mut self.srcs[1], GPR, SrcType::GPR); - - if let SrcRef::Imm32(imm32) = &mut self.sel.src_ref { - // Only the bottom 16 bits matter anyway - *imm32 = *imm32 & 0xffff; - } + self.reduce_sel_imm(); } fn encode(&self, e: &mut SM32Encoder<'_>) { diff --git a/src/nouveau/compiler/nak/sm50.rs b/src/nouveau/compiler/nak/sm50.rs index 74533e3a347..cfd88d6496f 100644 --- a/src/nouveau/compiler/nak/sm50.rs +++ b/src/nouveau/compiler/nak/sm50.rs @@ -1959,6 +1959,7 @@ impl SM50Op for OpPrmt { use RegFile::GPR; b.copy_alu_src_if_not_reg(&mut self.srcs[0], GPR, SrcType::GPR); b.copy_alu_src_if_not_reg(&mut self.srcs[1], GPR, SrcType::GPR); + self.reduce_sel_imm(); } fn encode(&self, e: &mut SM50Encoder<'_>) { @@ -1970,7 +1971,7 @@ impl SM50Op for OpPrmt { SrcRef::Imm32(imm32) => { e.set_opcode(0x36c0); // Only the bottom 16 bits matter - e.set_src_imm_i20(20..39, 56, *imm32 & 0xffff); + e.set_src_imm_i20(20..39, 56, *imm32); } SrcRef::CBuf(cb) => { e.set_opcode(0x4bc0); diff --git a/src/nouveau/compiler/nak/sm70_encode.rs b/src/nouveau/compiler/nak/sm70_encode.rs index 333e2d27228..7ea7ef30b60 100644 --- a/src/nouveau/compiler/nak/sm70_encode.rs +++ b/src/nouveau/compiler/nak/sm70_encode.rs @@ -2043,6 +2043,7 @@ impl SM70Op for OpPrmt { let [src0, src1] = &mut self.srcs; b.copy_alu_src_if_not_reg(src0, gpr, SrcType::ALU); b.copy_alu_src_if_not_reg(src1, gpr, SrcType::ALU); + self.reduce_sel_imm(); } fn encode(&self, e: &mut SM70Encoder<'_>) {