shader_recompiler: added MUL_HI VOP2 (896)

This commit is contained in:
psucien 2024-06-16 20:39:53 +02:00
parent 1fc86a6c9d
commit 54f8616d6a
10 changed files with 31 additions and 4 deletions

View File

@ -240,6 +240,8 @@ Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b);
Id EmitIAdd64(EmitContext& ctx, Id a, Id b); Id EmitIAdd64(EmitContext& ctx, Id a, Id b);
Id EmitISub32(EmitContext& ctx, Id a, Id b); Id EmitISub32(EmitContext& ctx, Id a, Id b);
Id EmitISub64(EmitContext& ctx, Id a, Id b); Id EmitISub64(EmitContext& ctx, Id a, Id b);
Id EmitSMulExt(EmitContext& ctx, Id a, Id b);
Id EmitUMulExt(EmitContext& ctx, Id a, Id b);
Id EmitIMul32(EmitContext& ctx, Id a, Id b); Id EmitIMul32(EmitContext& ctx, Id a, Id b);
Id EmitSDiv32(EmitContext& ctx, Id a, Id b); Id EmitSDiv32(EmitContext& ctx, Id a, Id b);
Id EmitUDiv32(EmitContext& ctx, Id a, Id b); Id EmitUDiv32(EmitContext& ctx, Id a, Id b);

View File

@ -68,6 +68,14 @@ Id EmitISub64(EmitContext& ctx, Id a, Id b) {
return ctx.OpISub(ctx.U64, a, b); return ctx.OpISub(ctx.U64, a, b);
} }
Id EmitSMulExt(EmitContext& ctx, Id a, Id b) {
return ctx.OpSMulExtended(ctx.full_result_i32x2, a, b);
}
Id EmitUMulExt(EmitContext& ctx, Id a, Id b) {
return ctx.OpUMulExtended(ctx.full_result_u32x2, a, b);
}
Id EmitIMul32(EmitContext& ctx, Id a, Id b) { Id EmitIMul32(EmitContext& ctx, Id a, Id b) {
return ctx.OpIMul(ctx.U32[1], a, b); return ctx.OpIMul(ctx.U32[1], a, b);
} }

View File

@ -104,6 +104,9 @@ void EmitContext::DefineArithmeticTypes() {
output_f32 = Name(TypePointer(spv::StorageClass::Output, F32[1]), "output_f32"); output_f32 = Name(TypePointer(spv::StorageClass::Output, F32[1]), "output_f32");
output_u32 = Name(TypePointer(spv::StorageClass::Output, U32[1]), "output_u32"); output_u32 = Name(TypePointer(spv::StorageClass::Output, U32[1]), "output_u32");
full_result_i32x2 = Name(TypeStruct(S32[1], S32[1]), "full_result_i32x2");
full_result_u32x2 = Name(TypeStruct(U32[1], U32[1]), "full_result_u32x2");
} }
void EmitContext::DefineInterfaces(const IR::Program& program) { void EmitContext::DefineInterfaces(const IR::Program& program) {

View File

@ -138,6 +138,9 @@ public:
VectorIds U32{}; VectorIds U32{};
VectorIds U1{}; VectorIds U1{};
Id full_result_i32x2;
Id full_result_u32x2;
Id true_value{}; Id true_value{};
Id false_value{}; Id false_value{};
Id u32_one_value{}; Id u32_one_value{};

View File

@ -584,8 +584,11 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
case Opcode::S_ADD_I32: case Opcode::S_ADD_I32:
translator.S_ADD_I32(inst); translator.S_ADD_I32(inst);
break; break;
case Opcode::V_MUL_HI_U32:
translator.V_MUL_HI_U32(false, inst);
break;
case Opcode::V_MUL_LO_I32: case Opcode::V_MUL_LO_I32:
translator.V_MUL_LO_I32(inst); translator.V_MUL_LO_U32(inst);
break; break;
case Opcode::V_SAD_U32: case Opcode::V_SAD_U32:
translator.V_SAD_U32(inst); translator.V_SAD_U32(inst);

View File

@ -97,7 +97,7 @@ public:
void V_SUBREV_I32(const GcnInst& inst); void V_SUBREV_I32(const GcnInst& inst);
void V_CMP_U32(ConditionOp op, bool is_signed, bool set_exec, const GcnInst& inst); void V_CMP_U32(ConditionOp op, bool is_signed, bool set_exec, const GcnInst& inst);
void V_LSHRREV_B32(const GcnInst& inst); void V_LSHRREV_B32(const GcnInst& inst);
void V_MUL_LO_I32(const GcnInst& inst); void V_MUL_HI_U32(bool is_signed, const GcnInst& inst);
void V_SAD_U32(const GcnInst& inst); void V_SAD_U32(const GcnInst& inst);
void V_BFE_U32(const GcnInst& inst); void V_BFE_U32(const GcnInst& inst);
void V_MAD_I32_I24(const GcnInst& inst); void V_MAD_I32_I24(const GcnInst& inst);

View File

@ -320,10 +320,11 @@ void Translator::V_LSHRREV_B32(const GcnInst& inst) {
SetDst(inst.dst[0], ir.ShiftRightLogical(src1, ir.BitwiseAnd(src0, ir.Imm32(0x1F)))); SetDst(inst.dst[0], ir.ShiftRightLogical(src1, ir.BitwiseAnd(src0, ir.Imm32(0x1F))));
} }
void Translator::V_MUL_LO_I32(const GcnInst& inst) { void Translator::V_MUL_HI_U32(bool is_signed, const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])}; const IR::U32 src1{GetSrc(inst.src[1])};
SetDst(inst.dst[0], ir.IMul(src0, src1)); const IR::U32 hi{ir.CompositeExtract(ir.IMulExt(src0, src1, is_signed), 1)};
SetDst(inst.dst[0], hi);
} }
void Translator::V_SAD_U32(const GcnInst& inst) { void Translator::V_SAD_U32(const GcnInst& inst) {

View File

@ -880,6 +880,10 @@ U32U64 IREmitter::ISub(const U32U64& a, const U32U64& b) {
} }
} }
IR::Value IREmitter::IMulExt(const U32& a, const U32& b, bool is_signed) {
return Inst(is_signed ? Opcode::SMulExt : Opcode::UMulExt, a, b);
}
U32 IREmitter::IMul(const U32& a, const U32& b) { U32 IREmitter::IMul(const U32& a, const U32& b) {
return Inst<U32>(Opcode::IMul32, a, b); return Inst<U32>(Opcode::IMul32, a, b);
} }

View File

@ -146,6 +146,7 @@ public:
[[nodiscard]] U32U64 IAdd(const U32U64& a, const U32U64& b); [[nodiscard]] U32U64 IAdd(const U32U64& a, const U32U64& b);
[[nodiscard]] U32U64 ISub(const U32U64& a, const U32U64& b); [[nodiscard]] U32U64 ISub(const U32U64& a, const U32U64& b);
[[nodiscard]] IR::Value IMulExt(const U32& a, const U32& b, bool is_signed = false);
[[nodiscard]] U32 IMul(const U32& a, const U32& b); [[nodiscard]] U32 IMul(const U32& a, const U32& b);
[[nodiscard]] U32 IDiv(const U32& a, const U32& b, bool is_signed = false); [[nodiscard]] U32 IDiv(const U32& a, const U32& b, bool is_signed = false);
[[nodiscard]] U32U64 INeg(const U32U64& value); [[nodiscard]] U32U64 INeg(const U32U64& value);

View File

@ -197,6 +197,8 @@ OPCODE(IAdd64, U64, U64,
OPCODE(ISub32, U32, U32, U32, ) OPCODE(ISub32, U32, U32, U32, )
OPCODE(ISub64, U64, U64, U64, ) OPCODE(ISub64, U64, U64, U64, )
OPCODE(IMul32, U32, U32, U32, ) OPCODE(IMul32, U32, U32, U32, )
OPCODE(SMulExt, U32x2, U32, U32, )
OPCODE(UMulExt, U32x2, U32, U32, )
OPCODE(SDiv32, U32, U32, U32, ) OPCODE(SDiv32, U32, U32, U32, )
OPCODE(UDiv32, U32, U32, U32, ) OPCODE(UDiv32, U32, U32, U32, )
OPCODE(INeg32, U32, U32, ) OPCODE(INeg32, U32, U32, )