From a53cb9f55ccb4560cd1c7cdccb7d4a5ffe1a6b09 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Thu, 11 Jun 2026 16:08:36 -0400 Subject: [PATCH] kraid/v9: Fold swizzles and modifiers on imm1w sources Part-of: --- src/panfrost/compiler/kraid/encode_v9.rs | 30 +++++++++++++++++------- src/panfrost/compiler/kraid/ir.rs | 18 ++++++++++++++ 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/panfrost/compiler/kraid/encode_v9.rs b/src/panfrost/compiler/kraid/encode_v9.rs index d1a6a27b421..38166f6607e 100644 --- a/src/panfrost/compiler/kraid/encode_v9.rs +++ b/src/panfrost/compiler/kraid/encode_v9.rs @@ -167,6 +167,20 @@ fn ptr_eq(a: &T, b: &T) -> bool { (a as *const T) == (b as *const T) } +fn typed_src_as_imm1w(src: &Src, src_type: DataType) -> Option { + let SrcRef::Imm32(imm) = &src.src_ref else { + return None; + }; + + let imm = src.swizzle.fold_u32(imm.get()).unwrap(); + let imm = src.src_mod.fold_u32(src_type, imm).unwrap(); + Some(imm) +} + +fn op_src_as_imm1w(op: &impl Opcode, src: &Src) -> Option { + typed_src_as_imm1w(src, op.src_type(src)) +} + fn encode_src_ref(src: &SrcRef, last_use: bool) -> u8 { match src { SrcRef::Zero => 0b1100_0000, @@ -601,12 +615,12 @@ impl V9Instr for OpFAdd { } fn encode(&self, e: V9Encoder) -> EncodedInstr { - if let SrcRef::Imm32(imm) = &self.srcs[1].src_ref { + if let Some(imm1w) = op_src_as_imm1w(self, &self.srcs[1]) { e.encode(FaddImm { variant: self.dst_type.try_into().unwrap(), dst: op_encode_dst(self, &self.dst), src0: op_encode_src(self, &self.srcs[0]), - imm1w: (*imm).into(), + imm1w, }) } else { e.encode(Fadd { @@ -661,12 +675,12 @@ impl V9Instr for OpIAdd { } fn encode(&self, e: V9Encoder) -> EncodedInstr { - if let SrcRef::Imm32(imm) = &self.srcs[1].src_ref { + if let Some(imm1w) = op_src_as_imm1w(self, &self.srcs[1]) { e.encode(IaddImm { variant: self.dst_type.try_into().unwrap(), dst: op_encode_dst(self, &self.dst), src0: op_encode_src(self, &self.srcs[0]), - imm1w: (*imm).into(), + imm1w, }) } else { e.encode(Iadd { @@ -833,11 +847,11 @@ impl V9Instr for OpMov { } fn encode(&self, e: V9Encoder) -> EncodedInstr { - if let SrcRef::Imm32(imm) = &self.src.src_ref { + if let Some(imm1w) = op_src_as_imm1w(self, &self.src) { e.encode(MovImm { variant: self.dst_type.try_into().unwrap(), dst: op_encode_dst(self, &self.dst), - imm1w: (*imm).into(), + imm1w, }) } else { e.encode(Mov { @@ -862,13 +876,13 @@ impl V9Instr for OpNop { macro_rules! encode_lop { ($e:expr, $op:expr, $Instr:ident) => { paste! { - if let SrcRef::Imm32(imm) = &$op.src2.src_ref { + if let Some(imm1w) = op_src_as_imm1w($op, &$op.src2) { assert!(!$op.not_result); $e.encode(v9::[<$Instr Imm>] { variant: $op.dst_type.try_into().unwrap(), dst: op_encode_dst($op, &$op.dst), src0: op_encode_src($op, &$op.src0), - imm1w: (*imm).into(), + imm1w, }) } else { $e.encode(v9::$Instr { diff --git a/src/panfrost/compiler/kraid/ir.rs b/src/panfrost/compiler/kraid/ir.rs index c6b3d129532..f0c197c8d16 100644 --- a/src/panfrost/compiler/kraid/ir.rs +++ b/src/panfrost/compiler/kraid/ir.rs @@ -269,6 +269,14 @@ impl fmt::Display for SrcMod { } } +fn float_sign_bits(data_type: DataType) -> Option { + match data_type { + DataType::F16 | DataType::V2F16 => Some(0x80008000), + DataType::F32 => Some(0x80000000), + _ => None, + } +} + impl SrcMod { pub fn bnot(self) -> SrcMod { use SrcMod::*; @@ -310,6 +318,16 @@ impl SrcMod { BNot => self.bnot(), } } + + pub fn fold_u32(self, data_type: DataType, u: u32) -> Option { + match self { + SrcMod::None => Some(u), + SrcMod::FAbs => Some(u & !float_sign_bits(data_type)?), + SrcMod::FNeg => Some(u ^ float_sign_bits(data_type)?), + SrcMod::FNegAbs => Some(u | float_sign_bits(data_type)?), + SrcMod::BNot => Some(!u), + } + } } #[derive(Clone)]