mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 16:32:39 +00:00
shader_recompiler: Implement more opcodes
This commit is contained in:
parent
2f1d2e54c6
commit
ed84d7460c
@ -92,8 +92,12 @@ void Translator::EmitScalarAlu(const GcnInst& inst) {
|
|||||||
break;
|
break;
|
||||||
case Opcode::S_BREV_B32:
|
case Opcode::S_BREV_B32:
|
||||||
return S_BREV_B32(inst);
|
return S_BREV_B32(inst);
|
||||||
|
case Opcode::S_BCNT1_I32_B64:
|
||||||
|
return S_BCNT1_I32_B64(inst);
|
||||||
case Opcode::S_AND_SAVEEXEC_B64:
|
case Opcode::S_AND_SAVEEXEC_B64:
|
||||||
return S_AND_SAVEEXEC_B64(inst);
|
return S_SAVEEXEC_B64(NegateMode::None, false, inst);
|
||||||
|
case Opcode::S_ORN2_SAVEEXEC_B64:
|
||||||
|
return S_SAVEEXEC_B64(NegateMode::Src1, true, inst);
|
||||||
default:
|
default:
|
||||||
LogMissingOpcode(inst);
|
LogMissingOpcode(inst);
|
||||||
}
|
}
|
||||||
@ -540,11 +544,17 @@ void Translator::S_BREV_B32(const GcnInst& inst) {
|
|||||||
SetDst(inst.dst[0], ir.BitReverse(GetSrc(inst.src[0])));
|
SetDst(inst.dst[0], ir.BitReverse(GetSrc(inst.src[0])));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::S_AND_SAVEEXEC_B64(const GcnInst& inst) {
|
void Translator::S_BCNT1_I32_B64(const GcnInst& inst) {
|
||||||
|
const IR::U32 result = ir.BitCount(GetSrc(inst.src[0]));
|
||||||
|
SetDst(inst.dst[0], result);
|
||||||
|
ir.SetScc(ir.INotEqual(result, ir.Imm32(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::S_SAVEEXEC_B64(NegateMode negate, bool is_or, const GcnInst& inst) {
|
||||||
// This instruction normally operates on 64-bit data (EXEC, VCC, SGPRs)
|
// This instruction normally operates on 64-bit data (EXEC, VCC, SGPRs)
|
||||||
// However here we flatten it to 1-bit EXEC and 1-bit VCC. For the destination
|
// However here we flatten it to 1-bit EXEC and 1-bit VCC. For the destination
|
||||||
// SGPR we have a special IR opcode for SPGRs that act as thread masks.
|
// SGPR we have a special IR opcode for SPGRs that act as thread masks.
|
||||||
const IR::U1 exec{ir.GetExec()};
|
IR::U1 exec{ir.GetExec()};
|
||||||
const IR::U1 src = [&] {
|
const IR::U1 src = [&] {
|
||||||
switch (inst.src[0].field) {
|
switch (inst.src[0].field) {
|
||||||
case OperandField::VccLo:
|
case OperandField::VccLo:
|
||||||
@ -568,7 +578,13 @@ void Translator::S_AND_SAVEEXEC_B64(const GcnInst& inst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update EXEC.
|
// Update EXEC.
|
||||||
const IR::U1 result = ir.LogicalAnd(exec, src);
|
if (negate == NegateMode::Src1) {
|
||||||
|
exec = ir.LogicalNot(exec);
|
||||||
|
}
|
||||||
|
IR::U1 result = is_or ? ir.LogicalOr(exec, src) : ir.LogicalAnd(exec, src);
|
||||||
|
if (negate == NegateMode::Result) {
|
||||||
|
result = ir.LogicalNot(result);
|
||||||
|
}
|
||||||
ir.SetExec(result);
|
ir.SetExec(result);
|
||||||
ir.SetScc(result);
|
ir.SetScc(result);
|
||||||
}
|
}
|
||||||
|
@ -108,8 +108,9 @@ public:
|
|||||||
void S_MOV_B64(const GcnInst& inst);
|
void S_MOV_B64(const GcnInst& inst);
|
||||||
void S_NOT_B64(const GcnInst& inst);
|
void S_NOT_B64(const GcnInst& inst);
|
||||||
void S_BREV_B32(const GcnInst& inst);
|
void S_BREV_B32(const GcnInst& inst);
|
||||||
|
void S_BCNT1_I32_B64(const GcnInst& inst);
|
||||||
void S_GETPC_B64(u32 pc, const GcnInst& inst);
|
void S_GETPC_B64(u32 pc, const GcnInst& inst);
|
||||||
void S_AND_SAVEEXEC_B64(const GcnInst& inst);
|
void S_SAVEEXEC_B64(NegateMode negate, bool is_or, const GcnInst& inst);
|
||||||
|
|
||||||
// SOPC
|
// SOPC
|
||||||
void S_CMP(ConditionOp cond, bool is_signed, const GcnInst& inst);
|
void S_CMP(ConditionOp cond, bool is_signed, const GcnInst& inst);
|
||||||
|
Loading…
Reference in New Issue
Block a user