shader_recompiler: added MUL_HI VOP2 (896)
This commit is contained in:
parent
1fc86a6c9d
commit
54f8616d6a
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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{};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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, )
|
||||||
|
|
Loading…
Reference in New Issue