diff --git a/src/shader_recompiler/frontend/maxwell/decode.cpp b/src/shader_recompiler/frontend/maxwell/decode.cpp index b92863e4c7..92027e8ad5 100644 --- a/src/shader_recompiler/frontend/maxwell/decode.cpp +++ b/src/shader_recompiler/frontend/maxwell/decode.cpp @@ -10,6 +10,7 @@ #include #include +#include "common/assert.h" #include "common/common_types.h" #include "shader_recompiler/exception.h" #include "shader_recompiler/frontend/maxwell/decode.h" @@ -45,7 +46,8 @@ Opcode Decode(u64 insn) { return Opcode::name; #include "maxwell.inc" #undef INST - throw NotImplementedException("Invalid insn 0x{:016x}", insn); + ASSERT_MSG(false, "Invalid insn 0x{:016x}", insn); + return Opcode::NOP; } } // namespace Shader::Maxwell diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/barrier_operations.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/barrier_operations.cpp index fb5368c7bb..aa494e24cc 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/barrier_operations.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/barrier_operations.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -29,7 +32,7 @@ void TranslatorVisitor::MEMBAR(u64 inst) { } } -void TranslatorVisitor::DEPBAR() { +void TranslatorVisitor::DEPBAR(u64) { // DEPBAR is a no-op } diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/exit_program.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/exit_program.cpp index c1179d9aa5..44459b7366 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/exit_program.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/exit_program.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -32,7 +35,7 @@ void ExitFragment(TranslatorVisitor& v) { } } // Anonymous namespace -void TranslatorVisitor::EXIT() { +void TranslatorVisitor::EXIT(u64) { switch (env.ShaderStage()) { case Stage::Fragment: ExitFragment(*this); diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h index 33365f4814..5db4b9edf6 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h @@ -56,293 +56,14 @@ enum class FPCompareOp : u64 { T, }; -class TranslatorVisitor { -public: +struct TranslatorVisitor { explicit TranslatorVisitor(Environment& env_, IR::Block& block) : env{env_}, ir(block) {} - Environment& env; IR::IREmitter ir; - void AL2P(u64 insn); - void ALD(u64 insn); - void AST(u64 insn); - void ATOM_cas(u64 insn); - void ATOM(u64 insn); - void ATOMS_cas(u64 insn); - void ATOMS(u64 insn); - void B2R(u64 insn); - void BAR(u64 insn); - void BFE_reg(u64 insn); - void BFE_cbuf(u64 insn); - void BFE_imm(u64 insn); - void BFI_reg(u64 insn); - void BFI_rc(u64 insn); - void BFI_cr(u64 insn); - void BFI_imm(u64 insn); - void BPT(u64 insn); - void BRA(u64 insn); - void BRK(u64 insn); - void BRX(u64 insn); - void CAL(); - void CCTL(u64 insn); - void CCTLL(u64 insn); - void CCTLT(u64 insn); - void CONT(u64 insn); - void CS2R(u64 insn); - void CSET(u64 insn); - void CSETP(u64 insn); - void DADD_reg(u64 insn); - void DADD_cbuf(u64 insn); - void DADD_imm(u64 insn); - void DEPBAR(); - void DFMA_reg(u64 insn); - void DFMA_rc(u64 insn); - void DFMA_cr(u64 insn); - void DFMA_imm(u64 insn); - void DMNMX_reg(u64 insn); - void DMNMX_cbuf(u64 insn); - void DMNMX_imm(u64 insn); - void DMUL_reg(u64 insn); - void DMUL_cbuf(u64 insn); - void DMUL_imm(u64 insn); - void DSET_reg(u64 insn); - void DSET_cbuf(u64 insn); - void DSET_imm(u64 insn); - void DSETP_reg(u64 insn); - void DSETP_cbuf(u64 insn); - void DSETP_imm(u64 insn); - void EXIT(); - void F2F_reg(u64 insn); - void F2F_cbuf(u64 insn); - void F2F_imm(u64 insn); - void F2I_reg(u64 insn); - void F2I_cbuf(u64 insn); - void F2I_imm(u64 insn); - void FADD_reg(u64 insn); - void FADD_cbuf(u64 insn); - void FADD_imm(u64 insn); - void FADD32I(u64 insn); - void FCHK_reg(u64 insn); - void FCHK_cbuf(u64 insn); - void FCHK_imm(u64 insn); - void FCMP_reg(u64 insn); - void FCMP_rc(u64 insn); - void FCMP_cr(u64 insn); - void FCMP_imm(u64 insn); - void FFMA_reg(u64 insn); - void FFMA_rc(u64 insn); - void FFMA_cr(u64 insn); - void FFMA_imm(u64 insn); - void FFMA32I(u64 insn); - void FLO_reg(u64 insn); - void FLO_cbuf(u64 insn); - void FLO_imm(u64 insn); - void FMNMX_reg(u64 insn); - void FMNMX_cbuf(u64 insn); - void FMNMX_imm(u64 insn); - void FMUL_reg(u64 insn); - void FMUL_cbuf(u64 insn); - void FMUL_imm(u64 insn); - void FMUL32I(u64 insn); - void FSET_reg(u64 insn); - void FSET_cbuf(u64 insn); - void FSET_imm(u64 insn); - void FSETP_reg(u64 insn); - void FSETP_cbuf(u64 insn); - void FSETP_imm(u64 insn); - void FSWZADD(u64 insn); - void GETCRSPTR(u64 insn); - void GETLMEMBASE(u64 insn); - void HADD2_reg(u64 insn); - void HADD2_cbuf(u64 insn); - void HADD2_imm(u64 insn); - void HADD2_32I(u64 insn); - void HFMA2_reg(u64 insn); - void HFMA2_rc(u64 insn); - void HFMA2_cr(u64 insn); - void HFMA2_imm(u64 insn); - void HFMA2_32I(u64 insn); - void HMUL2_reg(u64 insn); - void HMUL2_cbuf(u64 insn); - void HMUL2_imm(u64 insn); - void HMUL2_32I(u64 insn); - void HSET2_reg(u64 insn); - void HSET2_cbuf(u64 insn); - void HSET2_imm(u64 insn); - void HSETP2_reg(u64 insn); - void HSETP2_cbuf(u64 insn); - void HSETP2_imm(u64 insn); - void I2F_reg(u64 insn); - void I2F_cbuf(u64 insn); - void I2F_imm(u64 insn); - void I2I_reg(u64 insn); - void I2I_cbuf(u64 insn); - void I2I_imm(u64 insn); - void IADD_reg(u64 insn); - void IADD_cbuf(u64 insn); - void IADD_imm(u64 insn); - void IADD3_reg(u64 insn); - void IADD3_cbuf(u64 insn); - void IADD3_imm(u64 insn); - void IADD32I(u64 insn); - void ICMP_reg(u64 insn); - void ICMP_rc(u64 insn); - void ICMP_cr(u64 insn); - void ICMP_imm(u64 insn); - void IDE(u64 insn); - void IDP_reg(u64 insn); - void IDP_imm(u64 insn); - void IMAD_reg(u64 insn); - void IMAD_rc(u64 insn); - void IMAD_cr(u64 insn); - void IMAD_imm(u64 insn); - void IMAD32I(u64 insn); - void IMADSP_reg(u64 insn); - void IMADSP_rc(u64 insn); - void IMADSP_cr(u64 insn); - void IMADSP_imm(u64 insn); - void IMNMX_reg(u64 insn); - void IMNMX_cbuf(u64 insn); - void IMNMX_imm(u64 insn); - void IMUL_reg(u64 insn); - void IMUL_cbuf(u64 insn); - void IMUL_imm(u64 insn); - void IMUL32I(u64 insn); - void IPA(u64 insn); - void ISBERD(u64 insn); - void ISCADD_reg(u64 insn); - void ISCADD_cbuf(u64 insn); - void ISCADD_imm(u64 insn); - void ISCADD32I(u64 insn); - void ISET_reg(u64 insn); - void ISET_cbuf(u64 insn); - void ISET_imm(u64 insn); - void ISETP_reg(u64 insn); - void ISETP_cbuf(u64 insn); - void ISETP_imm(u64 insn); - void JCAL(u64 insn); - void JMP(u64 insn); - void JMX(u64 insn); - void KIL(); - void LD(u64 insn); - void LDC(u64 insn); - void LDG(u64 insn); - void LDL(u64 insn); - void LDS(u64 insn); - void LEA_hi_reg(u64 insn); - void LEA_hi_cbuf(u64 insn); - void LEA_lo_reg(u64 insn); - void LEA_lo_cbuf(u64 insn); - void LEA_lo_imm(u64 insn); - void LEPC(u64 insn); - void LONGJMP(u64 insn); - void LOP_reg(u64 insn); - void LOP_cbuf(u64 insn); - void LOP_imm(u64 insn); - void LOP3_reg(u64 insn); - void LOP3_cbuf(u64 insn); - void LOP3_imm(u64 insn); - void LOP32I(u64 insn); - void MEMBAR(u64 insn); - void MOV_reg(u64 insn); - void MOV_cbuf(u64 insn); - void MOV_imm(u64 insn); - void MOV32I(u64 insn); - void MUFU(u64 insn); - void NOP(u64 insn); - void OUT_reg(u64 insn); - void OUT_cbuf(u64 insn); - void OUT_imm(u64 insn); - void P2R_reg(u64 insn); - void P2R_cbuf(u64 insn); - void P2R_imm(u64 insn); - void PBK(); - void PCNT(); - void PEXIT(u64 insn); - void PIXLD(u64 insn); - void PLONGJMP(u64 insn); - void POPC_reg(u64 insn); - void POPC_cbuf(u64 insn); - void POPC_imm(u64 insn); - void PRET(u64 insn); - void PRMT_reg(u64 insn); - void PRMT_rc(u64 insn); - void PRMT_cr(u64 insn); - void PRMT_imm(u64 insn); - void PSET(u64 insn); - void PSETP(u64 insn); - void R2B(u64 insn); - void R2P_reg(u64 insn); - void R2P_cbuf(u64 insn); - void R2P_imm(u64 insn); - void RAM(u64 insn); - void RED(u64 insn); - void RET(u64 insn); - void RRO_reg(u64 insn); - void RRO_cbuf(u64 insn); - void RRO_imm(u64 insn); - void RTT(u64 insn); - void S2R(u64 insn); - void SAM(u64 insn); - void SEL_reg(u64 insn); - void SEL_cbuf(u64 insn); - void SEL_imm(u64 insn); - void SETCRSPTR(u64 insn); - void SETLMEMBASE(u64 insn); - void SHF_l_reg(u64 insn); - void SHF_l_imm(u64 insn); - void SHF_r_reg(u64 insn); - void SHF_r_imm(u64 insn); - void SHFL(u64 insn); - void SHL_reg(u64 insn); - void SHL_cbuf(u64 insn); - void SHL_imm(u64 insn); - void SHR_reg(u64 insn); - void SHR_cbuf(u64 insn); - void SHR_imm(u64 insn); - void SSY(); - void ST(u64 insn); - void STG(u64 insn); - void STL(u64 insn); - void STP(u64 insn); - void STS(u64 insn); - void SUATOM(u64 insn); - void SUATOM_cas(u64 insn); - void SULD(u64 insn); - void SURED(u64 insn); - void SUST(u64 insn); - void SYNC(u64 insn); - void TEX(u64 insn); - void TEX_b(u64 insn); - void TEXS(u64 insn); - void TLD(u64 insn); - void TLD_b(u64 insn); - void TLD4(u64 insn); - void TLD4_b(u64 insn); - void TLD4S(u64 insn); - void TLDS(u64 insn); - void TMML(u64 insn); - void TMML_b(u64 insn); - void TXA(u64 insn); - void TXD(u64 insn); - void TXD_b(u64 insn); - void TXQ(u64 insn); - void TXQ_b(u64 insn); - void VABSDIFF(u64 insn); - void VABSDIFF4(u64 insn); - void VADD(u64 insn); - void VMAD(u64 insn); - void VMNMX(u64 insn); - void VOTE(u64 insn); - void VOTE_vtg(u64 insn); - void VSET(u64 insn); - void VSETP(u64 insn); - void VSHL(u64 insn); - void VSHR(u64 insn); - void XMAD_reg(u64 insn); - void XMAD_rc(u64 insn); - void XMAD_cr(u64 insn); - void XMAD_imm(u64 insn); +#define INST(name, cute, encode) void name(u64 insn); +#include "shader_recompiler/frontend/maxwell/maxwell.inc" +#undef INST [[nodiscard]] IR::U32 X(IR::Reg reg); [[nodiscard]] IR::U64 L(IR::Reg reg); diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp index 27074f7ea3..369af8e03a 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp @@ -39,7 +39,7 @@ void TranslatorVisitor::BRK(u64) { ThrowNotImplemented(Opcode::BRK); } -void TranslatorVisitor::CAL() { +void TranslatorVisitor::CAL(u64) { // CAL is a no-op } @@ -155,7 +155,7 @@ void TranslatorVisitor::JMP(u64) { ThrowNotImplemented(Opcode::JMP); } -void TranslatorVisitor::KIL() { +void TranslatorVisitor::KIL(u64) { // KIL is a no-op } @@ -172,14 +172,14 @@ void TranslatorVisitor::LONGJMP(u64) { } void TranslatorVisitor::NOP(u64) { - // NOP is No-Op. + // NOP is a no-op } -void TranslatorVisitor::PBK() { +void TranslatorVisitor::PBK(u64) { // PBK is a no-op } -void TranslatorVisitor::PCNT() { +void TranslatorVisitor::PCNT(u64) { // PCNT is a no-op } @@ -239,7 +239,7 @@ void TranslatorVisitor::SETLMEMBASE(u64) { ThrowNotImplemented(Opcode::SETLMEMBASE); } -void TranslatorVisitor::SSY() { +void TranslatorVisitor::SSY(u64) { // SSY is a no-op } diff --git a/src/shader_recompiler/frontend/maxwell/translate/translate.cpp b/src/shader_recompiler/frontend/maxwell/translate/translate.cpp index 6d68448269..1f5e621003 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/translate.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/translate.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -10,40 +13,17 @@ namespace Shader::Maxwell { -template -static void Invoke(TranslatorVisitor& visitor, Location pc, u64 insn) { - using MethodType = decltype(method); - if constexpr (std::is_invocable_r_v) { - (visitor.*method)(pc, insn); - } else if constexpr (std::is_invocable_r_v) { - (visitor.*method)(insn); - } else { - (visitor.*method)(); - } -} - void Translate(Environment& env, IR::Block* block, u32 location_begin, u32 location_end) { - if (location_begin == location_end) { - return; - } - TranslatorVisitor visitor{env, *block}; - for (Location pc = location_begin; pc != location_end; ++pc) { - const u64 insn{env.ReadInstruction(pc.Offset())}; - try { - const Opcode opcode{Decode(insn)}; + if (location_begin != location_end) { + TranslatorVisitor visitor{env, *block}; + for (Location pc = location_begin; pc != location_end; ++pc) { + u64 const insn = env.ReadInstruction(pc.Offset()); + Opcode const opcode = Decode(insn); switch (opcode) { -#define INST(name, cute, mask) \ - case Opcode::name: \ - Invoke<&TranslatorVisitor::name>(visitor, pc, insn); \ - break; +#define INST(name, cute, mask) case Opcode::name: visitor.name(insn); break; #include "shader_recompiler/frontend/maxwell/maxwell.inc" #undef OPCODE - default: - throw LogicError("Invalid opcode {}", opcode); } - } catch (Exception& exception) { - exception.Prepend(fmt::format("Translate {}: ", Decode(insn))); - throw; } } }