From 101aeb920dd2a20c0f0997853984a20e46c3ab57 Mon Sep 17 00:00:00 2001 From: baggins183 Date: Sun, 1 Sep 2024 12:20:42 -0700 Subject: [PATCH] Implement V_BFM_B32 and V_FFBH_U32 (#663) * Implement V_BFM_B32 * Render.Recompiler: Implement V_FFBH_U32 * fix clang-format --- .../frontend/translate/translate.h | 2 ++ .../frontend/translate/vector_alu.cpp | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index 8d418421c..f1619e810 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -189,6 +189,8 @@ public: void V_CMP_CLASS_F32(const GcnInst& inst); void V_FFBL_B32(const GcnInst& inst); void V_MBCNT_U32_B32(bool is_low, const GcnInst& inst); + void V_BFM_B32(const GcnInst& inst); + void V_FFBH_U32(const GcnInst& inst); // Vector Memory void BUFFER_LOAD(u32 num_dwords, bool is_typed, const GcnInst& inst); diff --git a/src/shader_recompiler/frontend/translate/vector_alu.cpp b/src/shader_recompiler/frontend/translate/vector_alu.cpp index 13a8342d3..7fef91377 100644 --- a/src/shader_recompiler/frontend/translate/vector_alu.cpp +++ b/src/shader_recompiler/frontend/translate/vector_alu.cpp @@ -311,6 +311,11 @@ void Translator::EmitVectorAlu(const GcnInst& inst) { return V_MBCNT_U32_B32(false, inst); case Opcode::V_NOP: return; + + case Opcode::V_BFM_B32: + return V_BFM_B32(inst); + case Opcode::V_FFBH_U32: + return V_FFBH_U32(inst); default: LogMissingOpcode(inst); } @@ -964,4 +969,24 @@ void Translator::V_MBCNT_U32_B32(bool is_low, const GcnInst& inst) { SetDst(inst.dst[0], ir.LaneId()); } +void Translator::V_BFM_B32(const GcnInst& inst) { + // bitmask width + const IR::U32 src0{ir.BitFieldExtract(GetSrc(inst.src[0]), ir.Imm32(0), ir.Imm32(4))}; + // bitmask offset + const IR::U32 src1{ir.BitFieldExtract(GetSrc(inst.src[1]), ir.Imm32(0), ir.Imm32(4))}; + const IR::U32 ones = ir.ISub(ir.ShiftLeftLogical(ir.Imm32(1), src0), ir.Imm32(1)); + SetDst(inst.dst[0], ir.ShiftLeftLogical(ones, src1)); +} + +void Translator::V_FFBH_U32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + // Gcn wants the MSB position counting from the left, but SPIR-V counts from the rightmost (LSB) + // position + const IR::U32 msb_pos = ir.FindUMsb(src0); + const IR::U32 pos_from_left = ir.ISub(ir.Imm32(31), msb_pos); + // Select 0xFFFFFFFF if src0 was 0 + const IR::U1 cond = ir.INotEqual(src0, ir.Imm32(0)); + SetDst(inst.dst[0], IR::U32{ir.Select(cond, pos_from_left, ir.Imm32(~0U))}); +} + } // namespace Shader::Gcn