From 9dcf40e261c6775a997b92d26a4bd8113821c6ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Miko=C5=82ajczyk?= Date: Fri, 24 Jan 2025 11:07:36 +0000 Subject: [PATCH] Handle more 64bit shifts in Translator (#1825) --- .../frontend/translate/scalar_alu.cpp | 22 ++++++++++++++++++- .../frontend/translate/translate.h | 2 ++ .../frontend/translate/vector_alu.cpp | 4 ++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/shader_recompiler/frontend/translate/scalar_alu.cpp b/src/shader_recompiler/frontend/translate/scalar_alu.cpp index 7f34126f5..b1b260fde 100644 --- a/src/shader_recompiler/frontend/translate/scalar_alu.cpp +++ b/src/shader_recompiler/frontend/translate/scalar_alu.cpp @@ -72,10 +72,14 @@ void Translator::EmitScalarAlu(const GcnInst& inst) { return S_OR_B64(NegateMode::Result, true, inst); case Opcode::S_LSHL_B32: return S_LSHL_B32(inst); + case Opcode::S_LSHL_B64: + return S_LSHL_B64(inst); case Opcode::S_LSHR_B32: return S_LSHR_B32(inst); case Opcode::S_ASHR_I32: return S_ASHR_I32(inst); + case Opcode::S_ASHR_I64: + return S_ASHR_I64(inst); case Opcode::S_BFM_B32: return S_BFM_B32(inst); case Opcode::S_MUL_I32: @@ -420,6 +424,14 @@ void Translator::S_LSHL_B32(const GcnInst& inst) { ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); } +void Translator::S_LSHL_B64(const GcnInst& inst) { + const IR::U64 src0{GetSrc64(inst.src[0])}; + const IR::U64 src1{GetSrc64(inst.src[1])}; + const IR::U64 result = ir.ShiftLeftLogical(src0, ir.BitwiseAnd(src1, ir.Imm64(u64(0x3F)))); + SetDst64(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm64(u64(0)))); +} + void Translator::S_LSHR_B32(const GcnInst& inst) { const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src1{GetSrc(inst.src[1])}; @@ -431,11 +443,19 @@ void Translator::S_LSHR_B32(const GcnInst& inst) { void Translator::S_ASHR_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.ShiftRightArithmetic(src0, src1)}; + const IR::U32 result{ir.ShiftRightArithmetic(src0, ir.BitwiseAnd(src1, ir.Imm32(0x1F)))}; SetDst(inst.dst[0], result); ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); } +void Translator::S_ASHR_I64(const GcnInst& inst) { + const IR::U64 src0{GetSrc64(inst.src[0])}; + const IR::U64 src1{GetSrc64(inst.src[1])}; + const IR::U64 result{ir.ShiftRightArithmetic(src0, ir.BitwiseAnd(src1, ir.Imm64(u64(0x3F))))}; + SetDst64(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm64(u64(0)))); +} + void Translator::S_BFM_B32(const GcnInst& inst) { const IR::U32 src0{ir.BitwiseAnd(GetSrc(inst.src[0]), ir.Imm32(0x1F))}; const IR::U32 src1{ir.BitwiseAnd(GetSrc(inst.src[1]), ir.Imm32(0x1F))}; diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index bef61f997..496455b50 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -90,8 +90,10 @@ public: void S_OR_B64(NegateMode negate, bool is_xor, const GcnInst& inst); void S_XOR_B32(const GcnInst& inst); void S_LSHL_B32(const GcnInst& inst); + void S_LSHL_B64(const GcnInst& inst); void S_LSHR_B32(const GcnInst& inst); void S_ASHR_I32(const GcnInst& inst); + void S_ASHR_I64(const GcnInst& inst); void S_BFM_B32(const GcnInst& inst); void S_MUL_I32(const GcnInst& inst); void S_BFE(const GcnInst& inst, bool is_signed); diff --git a/src/shader_recompiler/frontend/translate/vector_alu.cpp b/src/shader_recompiler/frontend/translate/vector_alu.cpp index b2863f6a8..ac72293e4 100644 --- a/src/shader_recompiler/frontend/translate/vector_alu.cpp +++ b/src/shader_recompiler/frontend/translate/vector_alu.cpp @@ -1273,6 +1273,10 @@ void Translator::V_LSHL_B64(const GcnInst& inst) { ir.SetVectorReg(dst_reg + 1, ir.Imm32(static_cast(result >> 32))); return; } + + const IR::U64 result = ir.ShiftLeftLogical(src0, ir.BitwiseAnd(src1, ir.Imm64(u64(0x3F)))); + SetDst64(inst.dst[0], result); + return; } UNREACHABLE_MSG("Unimplemented V_LSHL_B64 arguments"); }