From 8a5e6fce072227edcf1c8af19c3749d695f483ac Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 21 Nov 2018 22:06:01 -0300 Subject: [PATCH 1/3] gl_shader_decompiler: Rename control codes to condition codes --- src/video_core/engines/shader_bytecode.h | 7 +- .../renderer_opengl/gl_shader_decompiler.cpp | 110 ++++++++---------- 2 files changed, 50 insertions(+), 67 deletions(-) diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 83a6fd8757..ee1710e8a9 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -261,7 +261,7 @@ enum class FlowCondition : u64 { Fcsm_Tr = 0x1C, // TODO(bunnei): What is this used for? }; -enum class ControlCode : u64 { +enum class ConditionCode : u64 { F = 0, LT = 1, EQ = 2, @@ -569,7 +569,6 @@ union Instruction { BitField<39, 2, u64> tab5cb8_2; BitField<41, 3, u64> tab5c68_1; BitField<44, 2, u64> tab5c68_0; - BitField<47, 1, u64> cc; BitField<48, 1, u64> negate_b; } fmul; @@ -831,7 +830,7 @@ union Instruction { union { BitField<0, 3, u64> pred0; BitField<3, 3, u64> pred3; - BitField<8, 5, ControlCode> cc; // flag in cc + BitField<8, 5, ConditionCode> cc; // flag in cc BitField<39, 3, u64> pred39; BitField<42, 1, u64> neg_pred39; BitField<45, 4, PredOperation> op; // op with pred39 @@ -1235,7 +1234,7 @@ union Instruction { BitField<60, 1, u64> is_b_gpr; BitField<59, 1, u64> is_c_gpr; BitField<20, 24, s64> smem_imm; - BitField<0, 5, ControlCode> flow_control_code; + BitField<0, 5, ConditionCode> flow_condition_code; Attribute attribute; Sampler sampler; diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 90a88b91a9..91e8449601 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -371,7 +371,7 @@ public: if (sets_cc) { const std::string zero_condition = "( " + ConvertIntegerSize(value, size) + " == 0 )"; SetInternalFlag(InternalFlag::ZeroFlag, zero_condition); - LOG_WARNING(HW_GPU, "Control Codes Imcomplete."); + LOG_WARNING(HW_GPU, "Condition codes implementation is incomplete."); } } @@ -454,12 +454,12 @@ public: shader.AddLine("lmem[" + index + "] = " + func + '(' + value + ");"); } - std::string GetControlCode(const Tegra::Shader::ControlCode cc) const { + std::string GetConditionCode(const Tegra::Shader::ConditionCode cc) const { switch (cc) { - case Tegra::Shader::ControlCode::NEU: + case Tegra::Shader::ConditionCode::NEU: return "!(" + GetInternalFlag(InternalFlag::ZeroFlag) + ')'; default: - UNIMPLEMENTED_MSG("Unimplemented Control Code: {}", static_cast(cc)); + UNIMPLEMENTED_MSG("Unimplemented condition code: {}", static_cast(cc)); return "false"; } } @@ -1508,9 +1508,7 @@ private: instr.fmul.tab5c68_0 != 1, "FMUL tab5cb8_0({}) is not implemented", instr.fmul.tab5c68_0 .Value()); // SMO typical sends 1 here which seems to be the default - UNIMPLEMENTED_IF_MSG(instr.fmul.cc != 0, "FMUL cc is not implemented"); - UNIMPLEMENTED_IF_MSG(instr.generates_cc, - "FMUL Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); op_b = GetOperandAbsNeg(op_b, false, instr.fmul.negate_b); @@ -1521,8 +1519,7 @@ private: case OpCode::Id::FADD_C: case OpCode::Id::FADD_R: case OpCode::Id::FADD_IMM: { - UNIMPLEMENTED_IF_MSG(instr.generates_cc, - "FADD Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); op_a = GetOperandAbsNeg(op_a, instr.alu.abs_a, instr.alu.negate_a); op_b = GetOperandAbsNeg(op_b, instr.alu.abs_b, instr.alu.negate_b); @@ -1571,8 +1568,7 @@ private: case OpCode::Id::FMNMX_C: case OpCode::Id::FMNMX_R: case OpCode::Id::FMNMX_IMM: { - UNIMPLEMENTED_IF_MSG(instr.generates_cc, - "FMNMX Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); op_a = GetOperandAbsNeg(op_a, instr.alu.abs_a, instr.alu.negate_a); op_b = GetOperandAbsNeg(op_b, instr.alu.abs_b, instr.alu.negate_b); @@ -1608,8 +1604,7 @@ private: break; } case OpCode::Id::FMUL32_IMM: { - UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc, - "FMUL32 Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.op_32.generates_cc); regs.SetRegisterToFloat(instr.gpr0, 0, regs.GetRegisterAsFloat(instr.gpr8) + " * " + @@ -1618,8 +1613,7 @@ private: break; } case OpCode::Id::FADD32I: { - UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc, - "FADD32 Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.op_32.generates_cc); std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); std::string op_b = GetImmediate32(instr); @@ -1654,7 +1648,7 @@ private: switch (opcode->get().GetId()) { case OpCode::Id::BFE_IMM: { - UNIMPLEMENTED_IF_MSG(instr.generates_cc, "BFE Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); std::string inner_shift = '(' + op_a + " << " + std::to_string(instr.bfe.GetLeftShiftValue()) + ')'; @@ -1691,7 +1685,7 @@ private: case OpCode::Id::SHR_C: case OpCode::Id::SHR_R: case OpCode::Id::SHR_IMM: { - UNIMPLEMENTED_IF_MSG(instr.generates_cc, "SHR Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); if (!instr.shift.is_signed) { // Logical shift right @@ -1706,8 +1700,7 @@ private: case OpCode::Id::SHL_C: case OpCode::Id::SHL_R: case OpCode::Id::SHL_IMM: - UNIMPLEMENTED_IF_MSG(instr.generates_cc, "SHL Generates an unhandled Control Code"); - + UNIMPLEMENTED_IF(instr.generates_cc); regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " << " + op_b, 1, 1); break; default: { @@ -1722,8 +1715,7 @@ private: switch (opcode->get().GetId()) { case OpCode::Id::IADD32I: - UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc, - "IADD32 Generates an unhandled Control Code"); + UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc); if (instr.iadd32i.negate_a) op_a = "-(" + op_a + ')'; @@ -1732,8 +1724,7 @@ private: instr.iadd32i.saturate != 0); break; case OpCode::Id::LOP32I: { - UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc, - "LOP32I Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.op_32.generates_cc); if (instr.alu.lop32i.invert_a) op_a = "~(" + op_a + ')'; @@ -1771,8 +1762,7 @@ private: case OpCode::Id::IADD_C: case OpCode::Id::IADD_R: case OpCode::Id::IADD_IMM: { - UNIMPLEMENTED_IF_MSG(instr.generates_cc, - "IADD Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); if (instr.alu_integer.negate_a) op_a = "-(" + op_a + ')'; @@ -1787,8 +1777,7 @@ private: case OpCode::Id::IADD3_C: case OpCode::Id::IADD3_R: case OpCode::Id::IADD3_IMM: { - UNIMPLEMENTED_IF_MSG(instr.generates_cc, - "IADD3 Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); @@ -1850,8 +1839,7 @@ private: case OpCode::Id::ISCADD_C: case OpCode::Id::ISCADD_R: case OpCode::Id::ISCADD_IMM: { - UNIMPLEMENTED_IF_MSG(instr.generates_cc, - "ISCADD Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); if (instr.alu_integer.negate_a) op_a = "-(" + op_a + ')'; @@ -1886,7 +1874,7 @@ private: case OpCode::Id::LOP_C: case OpCode::Id::LOP_R: case OpCode::Id::LOP_IMM: { - UNIMPLEMENTED_IF_MSG(instr.generates_cc, "LOP Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); if (instr.alu.lop.invert_a) op_a = "~(" + op_a + ')'; @@ -1901,8 +1889,7 @@ private: case OpCode::Id::LOP3_C: case OpCode::Id::LOP3_R: case OpCode::Id::LOP3_IMM: { - UNIMPLEMENTED_IF_MSG(instr.generates_cc, - "LOP3 Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); const std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); std::string lut; @@ -1920,8 +1907,7 @@ private: case OpCode::Id::IMNMX_R: case OpCode::Id::IMNMX_IMM: { UNIMPLEMENTED_IF(instr.imnmx.exchange != Tegra::Shader::IMinMaxExchange::None); - UNIMPLEMENTED_IF_MSG(instr.generates_cc, - "IMNMX Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); const std::string condition = GetPredicateCondition(instr.imnmx.pred, instr.imnmx.negate_pred != 0); @@ -2094,7 +2080,7 @@ private: instr.ffma.tab5980_0.Value()); // Seems to be 1 by default based on SMO UNIMPLEMENTED_IF_MSG(instr.ffma.tab5980_1 != 0, "FFMA tab5980_1({}) not implemented", instr.ffma.tab5980_1.Value()); - UNIMPLEMENTED_IF_MSG(instr.generates_cc, "FFMA Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); switch (opcode->get().GetId()) { case OpCode::Id::FFMA_CR: { @@ -2204,7 +2190,7 @@ private: case OpCode::Id::I2F_C: { UNIMPLEMENTED_IF(instr.conversion.dest_size != Register::Size::Word); UNIMPLEMENTED_IF(instr.conversion.selector); - UNIMPLEMENTED_IF_MSG(instr.generates_cc, "I2F Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); std::string op_a{}; @@ -2234,7 +2220,7 @@ private: case OpCode::Id::F2F_R: { UNIMPLEMENTED_IF(instr.conversion.dest_size != Register::Size::Word); UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word); - UNIMPLEMENTED_IF_MSG(instr.generates_cc, "F2F Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); if (instr.conversion.abs_a) { @@ -2272,7 +2258,7 @@ private: case OpCode::Id::F2I_R: case OpCode::Id::F2I_C: { UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word); - UNIMPLEMENTED_IF_MSG(instr.generates_cc, "F2I Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); std::string op_a{}; if (instr.is_b_gpr) { @@ -3083,7 +3069,7 @@ private: break; } case OpCode::Type::PredicateSetRegister: { - UNIMPLEMENTED_IF_MSG(instr.generates_cc, "PSET Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); const std::string op_a = GetPredicateCondition(instr.pset.pred12, instr.pset.neg_pred12 != 0); @@ -3142,14 +3128,14 @@ private: const std::string pred = GetPredicateCondition(instr.csetp.pred39, instr.csetp.neg_pred39 != 0); const std::string combiner = GetPredicateCombiner(instr.csetp.op); - const std::string control_code = regs.GetControlCode(instr.csetp.cc); + const std::string condition_code = regs.GetConditionCode(instr.csetp.cc); if (instr.csetp.pred3 != static_cast(Pred::UnusedIndex)) { SetPredicate(instr.csetp.pred3, - '(' + control_code + ") " + combiner + " (" + pred + ')'); + '(' + condition_code + ") " + combiner + " (" + pred + ')'); } if (instr.csetp.pred0 != static_cast(Pred::UnusedIndex)) { SetPredicate(instr.csetp.pred0, - "!(" + control_code + ") " + combiner + " (" + pred + ')'); + "!(" + condition_code + ") " + combiner + " (" + pred + ')'); } break; } @@ -3280,7 +3266,7 @@ private: case OpCode::Type::Xmad: { UNIMPLEMENTED_IF(instr.xmad.sign_a); UNIMPLEMENTED_IF(instr.xmad.sign_b); - UNIMPLEMENTED_IF_MSG(instr.generates_cc, "XMAD Generates an unhandled Control Code"); + UNIMPLEMENTED_IF(instr.generates_cc); std::string op_a{regs.GetRegisterAsInteger(instr.gpr8, 0, instr.xmad.sign_a)}; std::string op_b; @@ -3372,9 +3358,9 @@ private: default: { switch (opcode->get().GetId()) { case OpCode::Id::EXIT: { - const Tegra::Shader::ControlCode cc = instr.flow_control_code; - UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ControlCode::T, - "EXIT Control Code used: {}", static_cast(cc)); + const Tegra::Shader::ConditionCode cc = instr.flow_condition_code; + UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T, + "EXIT condition code used: {}", static_cast(cc)); if (stage == Maxwell3D::Regs::ShaderStage::Fragment) { EmitFragmentOutputsWrite(); @@ -3406,9 +3392,9 @@ private: case OpCode::Id::KIL: { UNIMPLEMENTED_IF(instr.flow.cond != Tegra::Shader::FlowCondition::Always); - const Tegra::Shader::ControlCode cc = instr.flow_control_code; - UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ControlCode::T, - "KIL Control Code used: {}", static_cast(cc)); + const Tegra::Shader::ConditionCode cc = instr.flow_condition_code; + UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T, + "KIL condition code used: {}", static_cast(cc)); // Enclose "discard" in a conditional, so that GLSL compilation does not complain // about unexecuted instructions that may follow this. @@ -3470,9 +3456,9 @@ private: UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, "BRA with constant buffers are not implemented"); - const Tegra::Shader::ControlCode cc = instr.flow_control_code; - UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ControlCode::T, - "BRA Control Code used: {}", static_cast(cc)); + const Tegra::Shader::ConditionCode cc = instr.flow_condition_code; + UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T, + "BRA condition code used: {}", static_cast(cc)); const u32 target = offset + instr.bra.GetBranchTarget(); shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }"); @@ -3515,9 +3501,9 @@ private: break; } case OpCode::Id::SYNC: { - const Tegra::Shader::ControlCode cc = instr.flow_control_code; - UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ControlCode::T, - "SYNC Control Code used: {}", static_cast(cc)); + const Tegra::Shader::ConditionCode cc = instr.flow_condition_code; + UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T, + "SYNC condition code used: {}", static_cast(cc)); // The SYNC opcode jumps to the address previously set by the SSY opcode EmitPopFromFlowStack(); @@ -3525,10 +3511,10 @@ private: } case OpCode::Id::BRK: { // The BRK opcode jumps to the address previously set by the PBK opcode - const Tegra::Shader::ControlCode cc = instr.flow_control_code; - if (cc != Tegra::Shader::ControlCode::T) { - UNIMPLEMENTED_MSG("BRK Control Code used: {}", static_cast(cc)); - } + const Tegra::Shader::ConditionCode cc = instr.flow_condition_code; + UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T, + "BRK condition code used: {}", static_cast(cc)); + EmitPopFromFlowStack(); break; } @@ -3539,6 +3525,8 @@ private: break; } case OpCode::Id::VMAD: { + UNIMPLEMENTED_IF(instr.generates_cc); + const bool result_signed = instr.video.signed_a == 1 || instr.video.signed_b == 1; const std::string op_a = GetVideoOperandA(instr); const std::string op_b = GetVideoOperandB(instr); @@ -3558,10 +3546,6 @@ private: regs.SetRegisterToInteger(instr.gpr0, result_signed, 1, result, 1, 1, instr.vmad.saturate == 1, 0, Register::Size::Word, instr.vmad.cc); - if (instr.generates_cc) { - UNIMPLEMENTED_MSG("VMAD Generates an unhandled Control Code"); - } - break; } case OpCode::Id::VSETP: { From 74eb16521fe812934f74e61b84d44cde9af08f96 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 21 Nov 2018 22:17:15 -0300 Subject: [PATCH 2/3] gl_shader_decompiler: Rename internal flag strings --- .../renderer_opengl/gl_shader_decompiler.cpp | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 91e8449601..e1ecabb2d1 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -34,6 +34,17 @@ constexpr u32 PROGRAM_HEADER_SIZE = sizeof(Tegra::Shader::Header); constexpr u32 MAX_GEOMETRY_BUFFERS = 6; constexpr u32 MAX_ATTRIBUTES = 0x100; // Size in vec4s, this value is untested +static const char* INTERNAL_FLAG_NAMES[] = {"zero_flag", "sign_flag", "carry_flag", + "overflow_flag"}; + +enum class InternalFlag : u64 { + ZeroFlag = 0, + SignFlag = 1, + CarryFlag = 2, + OverflowFlag = 3, + Amount +}; + class DecompileFail : public std::runtime_error { public: using std::runtime_error::runtime_error; @@ -257,14 +268,6 @@ private: const std::string& suffix; }; -enum class InternalFlag : u64 { - ZeroFlag = 0, - CarryFlag = 1, - OverflowFlag = 2, - NaNFlag = 3, - Amount -}; - /** * Used to manage shader registers that are emulated with GLSL. This class keeps track of the state * of all registers (e.g. whether they are currently being used as Floats or Integers), and @@ -464,13 +467,15 @@ public: } } - std::string GetInternalFlag(const InternalFlag ii) const { - const u32 code = static_cast(ii); - return "internalFlag_" + std::to_string(code) + suffix; + std::string GetInternalFlag(const InternalFlag flag) const { + const auto index = static_cast(flag); + ASSERT(index < static_cast(InternalFlag::Amount)); + + return std::string(INTERNAL_FLAG_NAMES[index]) + '_' + suffix; } - void SetInternalFlag(const InternalFlag ii, const std::string& value) const { - shader.AddLine(GetInternalFlag(ii) + " = " + value + ';'); + void SetInternalFlag(const InternalFlag flag, const std::string& value) const { + shader.AddLine(GetInternalFlag(flag) + " = " + value + ';'); } /** @@ -621,8 +626,8 @@ private: /// Generates declarations for internal flags. void GenerateInternalFlags() { - for (u32 ii = 0; ii < static_cast(InternalFlag::Amount); ii++) { - const InternalFlag code = static_cast(ii); + for (u32 flag = 0; flag < static_cast(InternalFlag::Amount); flag++) { + const InternalFlag code = static_cast(flag); declarations.AddLine("bool " + GetInternalFlag(code) + " = false;"); } declarations.AddNewLine(); From c9ac23683b90fa097374d47d7f47ccdb050d8b2b Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 22 Nov 2018 05:35:00 -0300 Subject: [PATCH 3/3] gl_shader_decompiler: Add a message for unimplemented cc generation --- .../renderer_opengl/gl_shader_decompiler.cpp | 69 ++++++++++++------- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index e1ecabb2d1..95d8e87c16 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -1513,7 +1513,8 @@ private: instr.fmul.tab5c68_0 != 1, "FMUL tab5cb8_0({}) is not implemented", instr.fmul.tab5c68_0 .Value()); // SMO typical sends 1 here which seems to be the default - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in FMUL is not implemented"); op_b = GetOperandAbsNeg(op_b, false, instr.fmul.negate_b); @@ -1524,7 +1525,8 @@ private: case OpCode::Id::FADD_C: case OpCode::Id::FADD_R: case OpCode::Id::FADD_IMM: { - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in FADD is not implemented"); op_a = GetOperandAbsNeg(op_a, instr.alu.abs_a, instr.alu.negate_a); op_b = GetOperandAbsNeg(op_b, instr.alu.abs_b, instr.alu.negate_b); @@ -1573,7 +1575,8 @@ private: case OpCode::Id::FMNMX_C: case OpCode::Id::FMNMX_R: case OpCode::Id::FMNMX_IMM: { - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in FMNMX is not implemented"); op_a = GetOperandAbsNeg(op_a, instr.alu.abs_a, instr.alu.negate_a); op_b = GetOperandAbsNeg(op_b, instr.alu.abs_b, instr.alu.negate_b); @@ -1609,7 +1612,8 @@ private: break; } case OpCode::Id::FMUL32_IMM: { - UNIMPLEMENTED_IF(instr.op_32.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc, + "Condition codes generation in FMUL32 is not implemented"); regs.SetRegisterToFloat(instr.gpr0, 0, regs.GetRegisterAsFloat(instr.gpr8) + " * " + @@ -1618,7 +1622,8 @@ private: break; } case OpCode::Id::FADD32I: { - UNIMPLEMENTED_IF(instr.op_32.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc, + "Condition codes generation in FADD32I is not implemented"); std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); std::string op_b = GetImmediate32(instr); @@ -1653,7 +1658,8 @@ private: switch (opcode->get().GetId()) { case OpCode::Id::BFE_IMM: { - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in BFE is not implemented"); std::string inner_shift = '(' + op_a + " << " + std::to_string(instr.bfe.GetLeftShiftValue()) + ')'; @@ -1690,7 +1696,8 @@ private: case OpCode::Id::SHR_C: case OpCode::Id::SHR_R: case OpCode::Id::SHR_IMM: { - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in SHR is not implemented"); if (!instr.shift.is_signed) { // Logical shift right @@ -1705,7 +1712,8 @@ private: case OpCode::Id::SHL_C: case OpCode::Id::SHL_R: case OpCode::Id::SHL_IMM: - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in SHL is not implemented"); regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " << " + op_b, 1, 1); break; default: { @@ -1720,7 +1728,8 @@ private: switch (opcode->get().GetId()) { case OpCode::Id::IADD32I: - UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc, + "Condition codes generation in IADD32I is not implemented"); if (instr.iadd32i.negate_a) op_a = "-(" + op_a + ')'; @@ -1729,7 +1738,8 @@ private: instr.iadd32i.saturate != 0); break; case OpCode::Id::LOP32I: { - UNIMPLEMENTED_IF(instr.op_32.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc, + "Condition codes generation in LOP32I is not implemented"); if (instr.alu.lop32i.invert_a) op_a = "~(" + op_a + ')'; @@ -1767,7 +1777,8 @@ private: case OpCode::Id::IADD_C: case OpCode::Id::IADD_R: case OpCode::Id::IADD_IMM: { - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in IADD is not implemented"); if (instr.alu_integer.negate_a) op_a = "-(" + op_a + ')'; @@ -1782,7 +1793,8 @@ private: case OpCode::Id::IADD3_C: case OpCode::Id::IADD3_R: case OpCode::Id::IADD3_IMM: { - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in IADD3 is not implemented"); std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); @@ -1844,7 +1856,8 @@ private: case OpCode::Id::ISCADD_C: case OpCode::Id::ISCADD_R: case OpCode::Id::ISCADD_IMM: { - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in ISCADD is not implemented"); if (instr.alu_integer.negate_a) op_a = "-(" + op_a + ')'; @@ -1879,7 +1892,8 @@ private: case OpCode::Id::LOP_C: case OpCode::Id::LOP_R: case OpCode::Id::LOP_IMM: { - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in LOP is not implemented"); if (instr.alu.lop.invert_a) op_a = "~(" + op_a + ')'; @@ -1894,7 +1908,8 @@ private: case OpCode::Id::LOP3_C: case OpCode::Id::LOP3_R: case OpCode::Id::LOP3_IMM: { - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in LOP3 is not implemented"); const std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); std::string lut; @@ -1912,7 +1927,8 @@ private: case OpCode::Id::IMNMX_R: case OpCode::Id::IMNMX_IMM: { UNIMPLEMENTED_IF(instr.imnmx.exchange != Tegra::Shader::IMinMaxExchange::None); - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in IMNMX is not implemented"); const std::string condition = GetPredicateCondition(instr.imnmx.pred, instr.imnmx.negate_pred != 0); @@ -2085,7 +2101,8 @@ private: instr.ffma.tab5980_0.Value()); // Seems to be 1 by default based on SMO UNIMPLEMENTED_IF_MSG(instr.ffma.tab5980_1 != 0, "FFMA tab5980_1({}) not implemented", instr.ffma.tab5980_1.Value()); - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in FFMA is not implemented"); switch (opcode->get().GetId()) { case OpCode::Id::FFMA_CR: { @@ -2195,7 +2212,8 @@ private: case OpCode::Id::I2F_C: { UNIMPLEMENTED_IF(instr.conversion.dest_size != Register::Size::Word); UNIMPLEMENTED_IF(instr.conversion.selector); - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in I2F is not implemented"); std::string op_a{}; @@ -2225,7 +2243,8 @@ private: case OpCode::Id::F2F_R: { UNIMPLEMENTED_IF(instr.conversion.dest_size != Register::Size::Word); UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word); - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in F2F is not implemented"); std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); if (instr.conversion.abs_a) { @@ -2263,7 +2282,8 @@ private: case OpCode::Id::F2I_R: case OpCode::Id::F2I_C: { UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word); - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in F2I is not implemented"); std::string op_a{}; if (instr.is_b_gpr) { @@ -3074,7 +3094,8 @@ private: break; } case OpCode::Type::PredicateSetRegister: { - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in PSET is not implemented"); const std::string op_a = GetPredicateCondition(instr.pset.pred12, instr.pset.neg_pred12 != 0); @@ -3271,7 +3292,8 @@ private: case OpCode::Type::Xmad: { UNIMPLEMENTED_IF(instr.xmad.sign_a); UNIMPLEMENTED_IF(instr.xmad.sign_b); - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in XMAD is not implemented"); std::string op_a{regs.GetRegisterAsInteger(instr.gpr8, 0, instr.xmad.sign_a)}; std::string op_b; @@ -3530,7 +3552,8 @@ private: break; } case OpCode::Id::VMAD: { - UNIMPLEMENTED_IF(instr.generates_cc); + UNIMPLEMENTED_IF_MSG(instr.generates_cc, + "Condition codes generation in VMAD is not implemented"); const bool result_signed = instr.video.signed_a == 1 || instr.video.signed_b == 1; const std::string op_a = GetVideoOperandA(instr);