shader_recompiler: Remove exec contexts, fix S_MOV_B64

This commit is contained in:
IndecisiveTurtle 2024-07-29 19:14:07 +03:00
parent df02bbeef0
commit d9125b4397
3 changed files with 31 additions and 27 deletions

View File

@ -65,12 +65,9 @@ void Translator::S_AND_SAVEEXEC_B64(const GcnInst& inst) {
// Mark destination SPGR as an EXEC context. This means we will use 1-bit // Mark destination SPGR as an EXEC context. This means we will use 1-bit
// IR instruction whenever it's loaded. // IR instruction whenever it's loaded.
switch (inst.dst[0].field) { switch (inst.dst[0].field) {
case OperandField::ScalarGPR: { case OperandField::ScalarGPR:
const u32 reg = inst.dst[0].code; ir.SetThreadBitScalarReg(IR::ScalarReg(inst.dst[0].code), exec);
exec_contexts[reg] = true;
ir.SetThreadBitScalarReg(IR::ScalarReg(reg), exec);
break; break;
}
case OperandField::VccLo: case OperandField::VccLo:
ir.SetVcc(exec); ir.SetVcc(exec);
break; break;
@ -79,27 +76,37 @@ void Translator::S_AND_SAVEEXEC_B64(const GcnInst& inst) {
} }
// Update EXEC. // Update EXEC.
ir.SetExec(ir.LogicalAnd(exec, src)); const IR::U1 result = ir.LogicalAnd(exec, src);
ir.SetExec(result);
ir.SetScc(result);
} }
void Translator::S_MOV_B64(const GcnInst& inst) { void Translator::S_MOV_B64(const GcnInst& inst) {
// TODO: Using VCC as EXEC context. const IR::U1 src = [&] {
if (inst.src[0].field == OperandField::VccLo || inst.dst[0].field == OperandField::VccLo) { switch (inst.src[0].field) {
return; case OperandField::VccLo:
} return ir.GetVcc();
if (inst.dst[0].field == OperandField::ScalarGPR && inst.src[0].field == OperandField::ExecLo) { case OperandField::ExecLo:
// Exec context push return ir.GetExec();
exec_contexts[inst.dst[0].code] = true; case OperandField::ScalarGPR:
ir.SetThreadBitScalarReg(IR::ScalarReg(inst.dst[0].code), ir.GetExec()); return ir.GetThreadBitScalarReg(IR::ScalarReg(inst.src[0].code));
} else if (inst.dst[0].field == OperandField::ExecLo && case OperandField::ConstZero:
inst.src[0].field == OperandField::ScalarGPR) { return ir.Imm1(false);
// Exec context pop default:
exec_contexts[inst.src[0].code] = false; UNREACHABLE();
ir.SetExec(ir.GetThreadBitScalarReg(IR::ScalarReg(inst.src[0].code))); }
} else if (inst.dst[0].field == OperandField::ExecLo && }();
inst.src[0].field == OperandField::ConstZero) { switch (inst.dst[0].field) {
ir.SetExec(ir.Imm1(false)); case OperandField::ScalarGPR:
} else { ir.SetThreadBitScalarReg(IR::ScalarReg(inst.dst[0].code), src);
break;
case OperandField::ExecLo:
ir.SetExec(src);
break;
case OperandField::VccLo:
ir.SetVcc(src);
break;
default:
UNREACHABLE(); UNREACHABLE();
} }
} }

View File

@ -16,13 +16,10 @@
namespace Shader::Gcn { namespace Shader::Gcn {
std::array<bool, IR::NumScalarRegs> Translator::exec_contexts{};
Translator::Translator(IR::Block* block_, Info& info_) Translator::Translator(IR::Block* block_, Info& info_)
: ir{*block_, block_->begin()}, info{info_} {} : ir{*block_, block_->begin()}, info{info_} {}
void Translator::EmitPrologue() { void Translator::EmitPrologue() {
exec_contexts.fill(false);
ir.Prologue(); ir.Prologue();
ir.SetExec(ir.Imm1(true)); ir.SetExec(ir.Imm1(true));

View File

@ -57,6 +57,7 @@ public:
void EmitPrologue(); void EmitPrologue();
void EmitFetch(const GcnInst& inst); void EmitFetch(const GcnInst& inst);
void EmitDataShare(const GcnInst& inst);
// Scalar ALU // Scalar ALU
void S_MOVK(const GcnInst& inst); void S_MOVK(const GcnInst& inst);
@ -201,7 +202,6 @@ private:
private: private:
IR::IREmitter ir; IR::IREmitter ir;
Info& info; Info& info;
static std::array<bool, IR::NumScalarRegs> exec_contexts;
}; };
void Translate(IR::Block* block, u32 block_base, std::span<const GcnInst> inst_list, Info& info); void Translate(IR::Block* block, u32 block_base, std::span<const GcnInst> inst_list, Info& info);