From b331f241645fce74a4377863baa3a2135854c457 Mon Sep 17 00:00:00 2001 From: offtkp Date: Mon, 2 Sep 2024 04:47:11 +0300 Subject: [PATCH] Implement S_SUB_I32 and flags for S_SUB_U32 --- .../frontend/translate/scalar_alu.cpp | 18 +++++++++++++++--- .../frontend/translate/translate.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/shader_recompiler/frontend/translate/scalar_alu.cpp b/src/shader_recompiler/frontend/translate/scalar_alu.cpp index 8193193a1..8e25790bc 100644 --- a/src/shader_recompiler/frontend/translate/scalar_alu.cpp +++ b/src/shader_recompiler/frontend/translate/scalar_alu.cpp @@ -70,8 +70,9 @@ void Translator::EmitScalarAlu(const GcnInst& inst) { case Opcode::S_ADDC_U32: return S_ADDC_U32(inst); case Opcode::S_SUB_U32: - case Opcode::S_SUB_I32: return S_SUB_U32(inst); + case Opcode::S_SUB_I32: + return S_SUB_I32(inst); case Opcode::S_MIN_U32: return S_MIN_U32(inst); case Opcode::S_MAX_U32: @@ -519,8 +520,19 @@ void Translator::S_SUB_U32(const GcnInst& inst) { const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src1{GetSrc(inst.src[1])}; SetDst(inst.dst[0], ir.ISub(src0, src1)); - // TODO: Carry out - ir.SetScc(ir.Imm1(false)); + ir.SetScc(ir.IGreaterThan(src1, src0, false)); +} + +void Translator::S_SUB_I32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 result = ir.ISub(src0, src1); + SetDst(inst.dst[0], result); + const IR::U32 sign_mask = ir.Imm32(1 << 31); + const IR::U32 sign0 = ir.BitwiseAnd(src0, sign_mask); + const IR::U32 sign1 = ir.BitwiseAnd(src1, sign_mask); + const IR::U32 signr = ir.BitwiseAnd(result, sign_mask); + ir.SetScc(ir.LogicalAnd(ir.INotEqual(sign0, sign1), ir.INotEqual(sign0, signr))); } void Translator::S_GETPC_B64(u32 pc, const GcnInst& inst) { diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index f1619e810..e29f98384 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -95,6 +95,7 @@ public: void S_NOT_B64(const GcnInst& inst); void S_BREV_B32(const GcnInst& inst); void S_ADD_U32(const GcnInst& inst); + void S_SUB_I32(const GcnInst& inst); void S_SUB_U32(const GcnInst& inst); void S_GETPC_B64(u32 pc, const GcnInst& inst); void S_ADDC_U32(const GcnInst& inst);