diff --git a/src/shader_recompiler/frontend/translate/scalar_alu.cpp b/src/shader_recompiler/frontend/translate/scalar_alu.cpp index a20e91ca1..076145bb6 100644 --- a/src/shader_recompiler/frontend/translate/scalar_alu.cpp +++ b/src/shader_recompiler/frontend/translate/scalar_alu.cpp @@ -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 // IR instruction whenever it's loaded. switch (inst.dst[0].field) { - case OperandField::ScalarGPR: { - const u32 reg = inst.dst[0].code; - exec_contexts[reg] = true; - ir.SetThreadBitScalarReg(IR::ScalarReg(reg), exec); + case OperandField::ScalarGPR: + ir.SetThreadBitScalarReg(IR::ScalarReg(inst.dst[0].code), exec); break; - } case OperandField::VccLo: ir.SetVcc(exec); break; @@ -79,27 +76,37 @@ void Translator::S_AND_SAVEEXEC_B64(const GcnInst& inst) { } // 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) { - // TODO: Using VCC as EXEC context. - if (inst.src[0].field == OperandField::VccLo || inst.dst[0].field == OperandField::VccLo) { - return; - } - if (inst.dst[0].field == OperandField::ScalarGPR && inst.src[0].field == OperandField::ExecLo) { - // Exec context push - exec_contexts[inst.dst[0].code] = true; - ir.SetThreadBitScalarReg(IR::ScalarReg(inst.dst[0].code), ir.GetExec()); - } else if (inst.dst[0].field == OperandField::ExecLo && - inst.src[0].field == OperandField::ScalarGPR) { - // Exec context pop - exec_contexts[inst.src[0].code] = false; - ir.SetExec(ir.GetThreadBitScalarReg(IR::ScalarReg(inst.src[0].code))); - } else if (inst.dst[0].field == OperandField::ExecLo && - inst.src[0].field == OperandField::ConstZero) { - ir.SetExec(ir.Imm1(false)); - } else { + const IR::U1 src = [&] { + switch (inst.src[0].field) { + case OperandField::VccLo: + return ir.GetVcc(); + case OperandField::ExecLo: + return ir.GetExec(); + case OperandField::ScalarGPR: + return ir.GetThreadBitScalarReg(IR::ScalarReg(inst.src[0].code)); + case OperandField::ConstZero: + return ir.Imm1(false); + default: + UNREACHABLE(); + } + }(); + switch (inst.dst[0].field) { + case OperandField::ScalarGPR: + 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(); } } diff --git a/src/shader_recompiler/frontend/translate/translate.cpp b/src/shader_recompiler/frontend/translate/translate.cpp index 51e60eeb8..edd592697 100644 --- a/src/shader_recompiler/frontend/translate/translate.cpp +++ b/src/shader_recompiler/frontend/translate/translate.cpp @@ -16,13 +16,10 @@ namespace Shader::Gcn { -std::array Translator::exec_contexts{}; - Translator::Translator(IR::Block* block_, Info& info_) : ir{*block_, block_->begin()}, info{info_} {} void Translator::EmitPrologue() { - exec_contexts.fill(false); ir.Prologue(); ir.SetExec(ir.Imm1(true)); diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index 812e4c7e3..365e43a45 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -57,6 +57,7 @@ public: void EmitPrologue(); void EmitFetch(const GcnInst& inst); + void EmitDataShare(const GcnInst& inst); // Scalar ALU void S_MOVK(const GcnInst& inst); @@ -201,7 +202,6 @@ private: private: IR::IREmitter ir; Info& info; - static std::array exec_contexts; }; void Translate(IR::Block* block, u32 block_base, std::span inst_list, Info& info);