mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-19 19:14:48 +00:00
shader_recompiler: Implement S_FLBIT_I32_B32 and V_MUL_HI_I32.
This commit is contained in:
parent
247e935353
commit
9274552e39
8 changed files with 33 additions and 12 deletions
|
@ -338,8 +338,8 @@ Id EmitIAdd64(EmitContext& ctx, Id a, Id b);
|
|||
Id EmitIAddCary32(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitISub32(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 EmitSMulHi(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitUMulHi(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitIMul32(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitIMul64(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitSDiv32(EmitContext& ctx, Id a, Id b);
|
||||
|
|
|
@ -72,12 +72,17 @@ Id EmitISub64(EmitContext& ctx, Id a, Id 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 EmitSMulHi(EmitContext& ctx, Id a, Id b) {
|
||||
const auto signed_a{ctx.OpBitcast(ctx.S32[1], a)};
|
||||
const auto signed_b{ctx.OpBitcast(ctx.S32[1], b)};
|
||||
const auto mul_ext{ctx.OpSMulExtended(ctx.full_result_i32x2, signed_a, signed_b)};
|
||||
const auto signed_hi{ctx.OpCompositeExtract(ctx.S32[1], mul_ext, 1)};
|
||||
return ctx.OpBitcast(ctx.U32[1], signed_hi);
|
||||
}
|
||||
|
||||
Id EmitUMulExt(EmitContext& ctx, Id a, Id b) {
|
||||
return ctx.OpUMulExtended(ctx.full_result_u32x2, a, b);
|
||||
Id EmitUMulHi(EmitContext& ctx, Id a, Id b) {
|
||||
const auto mul_ext{ctx.OpUMulExtended(ctx.full_result_u32x2, a, b)};
|
||||
return ctx.OpCompositeExtract(ctx.U32[1], mul_ext, 1);
|
||||
}
|
||||
|
||||
Id EmitIMul32(EmitContext& ctx, Id a, Id b) {
|
||||
|
|
|
@ -110,6 +110,8 @@ void Translator::EmitScalarAlu(const GcnInst& inst) {
|
|||
return S_FF1_I32_B32(inst);
|
||||
case Opcode::S_FF1_I32_B64:
|
||||
return S_FF1_I32_B64(inst);
|
||||
case Opcode::S_FLBIT_I32_B32:
|
||||
return S_FLBIT_I32_B32(inst);
|
||||
case Opcode::S_BITSET0_B32:
|
||||
return S_BITSET_B32(inst, 0);
|
||||
case Opcode::S_BITSET1_B32:
|
||||
|
@ -660,6 +662,17 @@ void Translator::S_FF1_I32_B64(const GcnInst& inst) {
|
|||
SetDst(inst.dst[0], result);
|
||||
}
|
||||
|
||||
void Translator::S_FLBIT_I32_B32(const GcnInst& inst) {
|
||||
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||
// Gcn wants the MSB position counting from the left, but SPIR-V counts from the rightmost (LSB)
|
||||
// position
|
||||
const IR::U32 msb_pos = ir.FindUMsb(src0);
|
||||
const IR::U32 pos_from_left = ir.ISub(ir.Imm32(31), msb_pos);
|
||||
// Select 0xFFFFFFFF if src0 was 0
|
||||
const IR::U1 cond = ir.INotEqual(src0, ir.Imm32(0));
|
||||
SetDst(inst.dst[0], IR::U32{ir.Select(cond, pos_from_left, ir.Imm32(~0U))});
|
||||
}
|
||||
|
||||
void Translator::S_BITSET_B32(const GcnInst& inst, u32 bit_value) {
|
||||
const IR::U32 old_value{GetSrc(inst.dst[0])};
|
||||
const IR::U32 offset{ir.BitFieldExtract(GetSrc(inst.src[0]), ir.Imm32(0U), ir.Imm32(5U))};
|
||||
|
|
|
@ -119,6 +119,7 @@ public:
|
|||
void S_BCNT1_I32_B64(const GcnInst& inst);
|
||||
void S_FF1_I32_B32(const GcnInst& inst);
|
||||
void S_FF1_I32_B64(const GcnInst& inst);
|
||||
void S_FLBIT_I32_B32(const GcnInst& inst);
|
||||
void S_BITSET_B32(const GcnInst& inst, u32 bit_value);
|
||||
void S_GETPC_B64(u32 pc, const GcnInst& inst);
|
||||
void S_SAVEEXEC_B64(NegateMode negate, bool is_or, const GcnInst& inst);
|
||||
|
|
|
@ -394,6 +394,8 @@ void Translator::EmitVectorAlu(const GcnInst& inst) {
|
|||
return V_MUL_HI_U32(false, inst);
|
||||
case Opcode::V_MUL_LO_I32:
|
||||
return V_MUL_LO_U32(inst);
|
||||
case Opcode::V_MUL_HI_I32:
|
||||
return V_MUL_HI_U32(true, inst);
|
||||
case Opcode::V_MAD_U64_U32:
|
||||
return V_MAD_U64_U32(inst);
|
||||
case Opcode::V_NOP:
|
||||
|
@ -1279,7 +1281,7 @@ void Translator::V_MUL_LO_U32(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 src1{GetSrc(inst.src[1])};
|
||||
const IR::U32 hi{ir.CompositeExtract(ir.IMulExt(src0, src1, is_signed), 1)};
|
||||
const IR::U32 hi{ir.IMulHi(src0, src1, is_signed)};
|
||||
SetDst(inst.dst[0], hi);
|
||||
}
|
||||
|
||||
|
|
|
@ -1388,8 +1388,8 @@ 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::IMulHi(const U32& a, const U32& b, bool is_signed) {
|
||||
return Inst<U32>(is_signed ? Opcode::SMulHi : Opcode::UMulHi, a, b);
|
||||
}
|
||||
|
||||
U32U64 IREmitter::IMul(const U32U64& a, const U32U64& b) {
|
||||
|
|
|
@ -240,7 +240,7 @@ public:
|
|||
[[nodiscard]] U32U64 IAdd(const U32U64& a, const U32U64& b);
|
||||
[[nodiscard]] Value IAddCary(const U32& a, const U32& b);
|
||||
[[nodiscard]] U32U64 ISub(const U32U64& a, const U32U64& b);
|
||||
[[nodiscard]] Value IMulExt(const U32& a, const U32& b, bool is_signed = false);
|
||||
[[nodiscard]] U32 IMulHi(const U32& a, const U32& b, bool is_signed = false);
|
||||
[[nodiscard]] U32U64 IMul(const U32U64& a, const U32U64& b);
|
||||
[[nodiscard]] U32 IDiv(const U32& a, const U32& b, bool is_signed = false);
|
||||
[[nodiscard]] U32 IMod(const U32& a, const U32& b, bool is_signed = false);
|
||||
|
|
|
@ -317,8 +317,8 @@ OPCODE(ISub32, U32, U32,
|
|||
OPCODE(ISub64, U64, U64, U64, )
|
||||
OPCODE(IMul32, U32, U32, U32, )
|
||||
OPCODE(IMul64, U64, U64, U64, )
|
||||
OPCODE(SMulExt, U32x2, U32, U32, )
|
||||
OPCODE(UMulExt, U32x2, U32, U32, )
|
||||
OPCODE(SMulHi, U32, U32, U32, )
|
||||
OPCODE(UMulHi, U32, U32, U32, )
|
||||
OPCODE(SDiv32, U32, U32, U32, )
|
||||
OPCODE(UDiv32, U32, U32, U32, )
|
||||
OPCODE(SMod32, U32, U32, U32, )
|
||||
|
|
Loading…
Add table
Reference in a new issue