diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index 8d418421..4522231e 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -189,6 +189,7 @@ 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); // 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 13a8342d..36fab906 100644 --- a/src/shader_recompiler/frontend/translate/vector_alu.cpp +++ b/src/shader_recompiler/frontend/translate/vector_alu.cpp @@ -311,6 +311,9 @@ 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); default: LogMissingOpcode(inst); } @@ -964,4 +967,13 @@ 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)); +} + } // namespace Shader::Gcn