diff --git a/src/shader_recompiler/frontend/translate/scalar_alu.cpp b/src/shader_recompiler/frontend/translate/scalar_alu.cpp index e731e299aae..72297fa0110 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: @@ -412,6 +416,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])}; @@ -423,11 +435,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 8e575fcadf8..f153456df8e 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -90,8 +90,10 @@ class Translator { 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 2b32ca2ce3e..e581abe608f 100644 --- a/src/shader_recompiler/frontend/translate/vector_alu.cpp +++ b/src/shader_recompiler/frontend/translate/vector_alu.cpp @@ -1211,6 +1211,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"); }