diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index bbc14a74a..6803cda25 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -238,14 +238,11 @@ public: void V_FMA_F32(const GcnInst& inst); void V_FMA_F64(const GcnInst& inst); void V_MIN3_F32(const GcnInst& inst); - void V_MIN3_I32(const GcnInst& inst); - void V_MIN3_U32(const GcnInst& inst); + void V_MIN3_U32(bool is_signed, const GcnInst& inst); void V_MAX3_F32(const GcnInst& inst); - void V_MAX3_I32(const GcnInst& inst); - void V_MAX3_U32(const GcnInst& inst); + void V_MAX3_U32(bool is_signed, const GcnInst& inst); void V_MED3_F32(const GcnInst& inst); - void V_MED3_I32(const GcnInst& inst); - void V_MED3_U32(const GcnInst& inst); + void V_MED3_U32(bool is_signed, const GcnInst& inst); void V_SAD(const GcnInst& inst); void V_SAD_U32(const GcnInst& inst); void V_CVT_PK_U16_U32(const GcnInst& inst); diff --git a/src/shader_recompiler/frontend/translate/vector_alu.cpp b/src/shader_recompiler/frontend/translate/vector_alu.cpp index 3c587cc54..22020d59f 100644 --- a/src/shader_recompiler/frontend/translate/vector_alu.cpp +++ b/src/shader_recompiler/frontend/translate/vector_alu.cpp @@ -359,21 +359,21 @@ void Translator::EmitVectorAlu(const GcnInst& inst) { case Opcode::V_MIN3_F32: return V_MIN3_F32(inst); case Opcode::V_MIN3_I32: - return V_MIN3_I32(inst); + return V_MIN3_U32(true, inst); case Opcode::V_MIN3_U32: - return V_MIN3_U32(inst); + return V_MIN3_U32(false, inst); case Opcode::V_MAX3_F32: return V_MAX3_F32(inst); case Opcode::V_MAX3_I32: - return V_MAX3_I32(inst); + return V_MAX3_U32(true, inst); case Opcode::V_MAX3_U32: - return V_MAX3_U32(inst); + return V_MAX3_U32(false, inst); case Opcode::V_MED3_F32: return V_MED3_F32(inst); case Opcode::V_MED3_I32: - return V_MED3_I32(inst); + return V_MED3_U32(true, inst); case Opcode::V_MED3_U32: - return V_MED3_U32(inst); + return V_MED3_U32(false, inst); case Opcode::V_SAD_U32: return V_SAD_U32(inst); case Opcode::V_CVT_PK_U16_U32: @@ -1169,18 +1169,11 @@ void Translator::V_MIN3_F32(const GcnInst& inst) { SetDst(inst.dst[0], ir.FPMinTri(src0, src1, src2)); } -void Translator::V_MIN3_I32(const GcnInst& inst) { +void Translator::V_MIN3_U32(bool is_signed, const GcnInst& inst) { const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src1{GetSrc(inst.src[1])}; const IR::U32 src2{GetSrc(inst.src[2])}; - SetDst(inst.dst[0], ir.SMinTri(src0, src1, src2)); -} - -void Translator::V_MIN3_U32(const GcnInst& inst) { - const IR::U32 src0{GetSrc(inst.src[0])}; - const IR::U32 src1{GetSrc(inst.src[1])}; - const IR::U32 src2{GetSrc(inst.src[2])}; - SetDst(inst.dst[0], ir.UMinTri(src0, src1, src2)); + SetDst(inst.dst[0], ir.IMinTri(src0, src1, src2, is_signed)); } void Translator::V_MAX3_F32(const GcnInst& inst) { @@ -1190,18 +1183,11 @@ void Translator::V_MAX3_F32(const GcnInst& inst) { SetDst(inst.dst[0], ir.FPMaxTri(src0, src1, src2)); } -void Translator::V_MAX3_I32(const GcnInst& inst) { +void Translator::V_MAX3_U32(bool is_signed, const GcnInst& inst) { const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src1{GetSrc(inst.src[1])}; const IR::U32 src2{GetSrc(inst.src[2])}; - SetDst(inst.dst[0], ir.SMaxTri(src0, src1, src2)); -} - -void Translator::V_MAX3_U32(const GcnInst& inst) { - const IR::U32 src0{GetSrc(inst.src[0])}; - const IR::U32 src1{GetSrc(inst.src[1])}; - const IR::U32 src2{GetSrc(inst.src[2])}; - SetDst(inst.dst[0], ir.UMaxTri(src0, src1, src2)); + SetDst(inst.dst[0], ir.IMaxTri(src0, src1, src2, is_signed)); } void Translator::V_MED3_F32(const GcnInst& inst) { @@ -1211,18 +1197,11 @@ void Translator::V_MED3_F32(const GcnInst& inst) { SetDst(inst.dst[0], ir.FPMedTri(src0, src1, src2)); } -void Translator::V_MED3_I32(const GcnInst& inst) { +void Translator::V_MED3_U32(bool is_signed, const GcnInst& inst) { const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src1{GetSrc(inst.src[1])}; const IR::U32 src2{GetSrc(inst.src[2])}; - SetDst(inst.dst[0], ir.SMedTri(src0, src1, src2)); -} - -void Translator::V_MED3_U32(const GcnInst& inst) { - const IR::U32 src0{GetSrc(inst.src[0])}; - const IR::U32 src1{GetSrc(inst.src[1])}; - const IR::U32 src2{GetSrc(inst.src[2])}; - SetDst(inst.dst[0], ir.UMedTri(src0, src1, src2)); + SetDst(inst.dst[0], ir.IMedTri(src0, src1, src2, is_signed)); } void Translator::V_SAD(const GcnInst& inst) { diff --git a/src/shader_recompiler/ir/ir_emitter.cpp b/src/shader_recompiler/ir/ir_emitter.cpp index ad20e2cd7..a171d32a2 100644 --- a/src/shader_recompiler/ir/ir_emitter.cpp +++ b/src/shader_recompiler/ir/ir_emitter.cpp @@ -1587,6 +1587,10 @@ U32 IREmitter::UMinTri(const U32& a, const U32& b, const U32& c) { return Inst(Opcode::UMinTri32, a, b, c); } +U32 IREmitter::IMinTri(const U32& a, const U32& b, const U32& c, bool is_signed) { + return is_signed ? SMinTri(a, b, c) : UMinTri(a, b, c); +} + U32 IREmitter::SMaxTri(const U32& a, const U32& b, const U32& c) { return Inst(Opcode::SMaxTri32, a, b, c); } @@ -1595,6 +1599,10 @@ U32 IREmitter::UMaxTri(const U32& a, const U32& b, const U32& c) { return Inst(Opcode::UMaxTri32, a, b, c); } +U32 IREmitter::IMaxTri(const U32& a, const U32& b, const U32& c, bool is_signed) { + return is_signed ? SMaxTri(a, b, c) : UMaxTri(a, b, c); +} + U32 IREmitter::SMedTri(const U32& a, const U32& b, const U32& c) { return Inst(Opcode::SMedTri32, a, b, c); } @@ -1603,6 +1611,10 @@ U32 IREmitter::UMedTri(const U32& a, const U32& b, const U32& c) { return Inst(Opcode::UMedTri32, a, b, c); } +U32 IREmitter::IMedTri(const U32& a, const U32& b, const U32& c, bool is_signed) { + return is_signed ? SMedTri(a, b, c) : UMedTri(a, b, c); +} + U32 IREmitter::SClamp(const U32& value, const U32& min, const U32& max) { return Inst(Opcode::SClamp32, value, min, max); } diff --git a/src/shader_recompiler/ir/ir_emitter.h b/src/shader_recompiler/ir/ir_emitter.h index 052de3c1f..48cc02725 100644 --- a/src/shader_recompiler/ir/ir_emitter.h +++ b/src/shader_recompiler/ir/ir_emitter.h @@ -271,10 +271,13 @@ public: [[nodiscard]] U32 IMax(const U32& a, const U32& b, bool is_signed); [[nodiscard]] U32 SMinTri(const U32& a, const U32& b, const U32& c); [[nodiscard]] U32 UMinTri(const U32& a, const U32& b, const U32& c); + [[nodiscard]] U32 IMinTri(const U32& a, const U32& b, const U32& c, bool is_signed); [[nodiscard]] U32 SMaxTri(const U32& a, const U32& b, const U32& c); [[nodiscard]] U32 UMaxTri(const U32& a, const U32& b, const U32& c); + [[nodiscard]] U32 IMaxTri(const U32& a, const U32& b, const U32& c, bool is_signed); [[nodiscard]] U32 SMedTri(const U32& a, const U32& b, const U32& c); [[nodiscard]] U32 UMedTri(const U32& a, const U32& b, const U32& c); + [[nodiscard]] U32 IMedTri(const U32& a, const U32& b, const U32& c, bool is_signed); [[nodiscard]] U32 SClamp(const U32& value, const U32& min, const U32& max); [[nodiscard]] U32 UClamp(const U32& value, const U32& min, const U32& max);