summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-11-23 23:31:04 -0500
committerGravatar GitHub2018-11-23 23:31:04 -0500
commitb6b78203ccbbf5e7f3306e84203448583c3394e6 (patch)
tree4d1aeceb566594e3f396bf686524b29d06b62c42 /src
parentMerge pull request #1744 from degasus/shader_cache (diff)
parentgl_shader_decompiler: Add a message for unimplemented cc generation (diff)
downloadyuzu-b6b78203ccbbf5e7f3306e84203448583c3394e6.tar.gz
yuzu-b6b78203ccbbf5e7f3306e84203448583c3394e6.tar.xz
yuzu-b6b78203ccbbf5e7f3306e84203448583c3394e6.zip
Merge pull request #1769 from ReinUsesLisp/cc
gl_shader_decompiler: Rename cc to condition code and name internal flags
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h7
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp144
2 files changed, 81 insertions, 70 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index c5f502ce1..7e8449bc4 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -262,7 +262,7 @@ enum class FlowCondition : u64 {
262 Fcsm_Tr = 0x1C, // TODO(bunnei): What is this used for? 262 Fcsm_Tr = 0x1C, // TODO(bunnei): What is this used for?
263}; 263};
264 264
265enum class ControlCode : u64 { 265enum class ConditionCode : u64 {
266 F = 0, 266 F = 0,
267 LT = 1, 267 LT = 1,
268 EQ = 2, 268 EQ = 2,
@@ -570,7 +570,6 @@ union Instruction {
570 BitField<39, 2, u64> tab5cb8_2; 570 BitField<39, 2, u64> tab5cb8_2;
571 BitField<41, 3, u64> tab5c68_1; 571 BitField<41, 3, u64> tab5c68_1;
572 BitField<44, 2, u64> tab5c68_0; 572 BitField<44, 2, u64> tab5c68_0;
573 BitField<47, 1, u64> cc;
574 BitField<48, 1, u64> negate_b; 573 BitField<48, 1, u64> negate_b;
575 } fmul; 574 } fmul;
576 575
@@ -832,7 +831,7 @@ union Instruction {
832 union { 831 union {
833 BitField<0, 3, u64> pred0; 832 BitField<0, 3, u64> pred0;
834 BitField<3, 3, u64> pred3; 833 BitField<3, 3, u64> pred3;
835 BitField<8, 5, ControlCode> cc; // flag in cc 834 BitField<8, 5, ConditionCode> cc; // flag in cc
836 BitField<39, 3, u64> pred39; 835 BitField<39, 3, u64> pred39;
837 BitField<42, 1, u64> neg_pred39; 836 BitField<42, 1, u64> neg_pred39;
838 BitField<45, 4, PredOperation> op; // op with pred39 837 BitField<45, 4, PredOperation> op; // op with pred39
@@ -1236,7 +1235,7 @@ union Instruction {
1236 BitField<60, 1, u64> is_b_gpr; 1235 BitField<60, 1, u64> is_b_gpr;
1237 BitField<59, 1, u64> is_c_gpr; 1236 BitField<59, 1, u64> is_c_gpr;
1238 BitField<20, 24, s64> smem_imm; 1237 BitField<20, 24, s64> smem_imm;
1239 BitField<0, 5, ControlCode> flow_control_code; 1238 BitField<0, 5, ConditionCode> flow_condition_code;
1240 1239
1241 Attribute attribute; 1240 Attribute attribute;
1242 Sampler sampler; 1241 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 9cd95dadc..97b9028c5 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);
34constexpr u32 MAX_GEOMETRY_BUFFERS = 6; 34constexpr u32 MAX_GEOMETRY_BUFFERS = 6;
35constexpr u32 MAX_ATTRIBUTES = 0x100; // Size in vec4s, this value is untested 35constexpr u32 MAX_ATTRIBUTES = 0x100; // Size in vec4s, this value is untested
36 36
37static const char* INTERNAL_FLAG_NAMES[] = {"zero_flag", "sign_flag", "carry_flag",
38 "overflow_flag"};
39
40enum class InternalFlag : u64 {
41 ZeroFlag = 0,
42 SignFlag = 1,
43 CarryFlag = 2,
44 OverflowFlag = 3,
45 Amount
46};
47
37class DecompileFail : public std::runtime_error { 48class DecompileFail : public std::runtime_error {
38public: 49public:
39 using std::runtime_error::runtime_error; 50 using std::runtime_error::runtime_error;
@@ -267,14 +278,6 @@ private:
267 const std::string& suffix; 278 const std::string& suffix;
268}; 279};
269 280
270enum class InternalFlag : u64 {
271 ZeroFlag = 0,
272 CarryFlag = 1,
273 OverflowFlag = 2,
274 NaNFlag = 3,
275 Amount
276};
277
278/** 281/**
279 * Used to manage shader registers that are emulated with GLSL. This class keeps track of the state 282 * Used to manage shader registers that are emulated with GLSL. This class keeps track of the state
280 * of all registers (e.g. whether they are currently being used as Floats or Integers), and 283 * of all registers (e.g. whether they are currently being used as Floats or Integers), and
@@ -381,7 +384,7 @@ public:
381 if (sets_cc) { 384 if (sets_cc) {
382 const std::string zero_condition = "( " + ConvertIntegerSize(value, size) + " == 0 )"; 385 const std::string zero_condition = "( " + ConvertIntegerSize(value, size) + " == 0 )";
383 SetInternalFlag(InternalFlag::ZeroFlag, zero_condition); 386 SetInternalFlag(InternalFlag::ZeroFlag, zero_condition);
384 LOG_WARNING(HW_GPU, "Control Codes Imcomplete."); 387 LOG_WARNING(HW_GPU, "Condition codes implementation is incomplete.");
385 } 388 }
386 } 389 }
387 390
@@ -464,23 +467,25 @@ public:
464 shader.AddLine("lmem[" + index + "] = " + func + '(' + value + ");"); 467 shader.AddLine("lmem[" + index + "] = " + func + '(' + value + ");");
465 } 468 }
466 469
467 std::string GetControlCode(const Tegra::Shader::ControlCode cc) const { 470 std::string GetConditionCode(const Tegra::Shader::ConditionCode cc) const {
468 switch (cc) { 471 switch (cc) {
469 case Tegra::Shader::ControlCode::NEU: 472 case Tegra::Shader::ConditionCode::NEU:
470 return "!(" + GetInternalFlag(InternalFlag::ZeroFlag) + ')'; 473 return "!(" + GetInternalFlag(InternalFlag::ZeroFlag) + ')';
471 default: 474 default:
472 UNIMPLEMENTED_MSG("Unimplemented Control Code: {}", static_cast<u32>(cc)); 475 UNIMPLEMENTED_MSG("Unimplemented condition code: {}", static_cast<u32>(cc));
473 return "false"; 476 return "false";
474 } 477 }
475 } 478 }
476 479
477 std::string GetInternalFlag(const InternalFlag ii) const { 480 std::string GetInternalFlag(const InternalFlag flag) const {
478 const u32 code = static_cast<u32>(ii); 481 const auto index = static_cast<u32>(flag);
479 return "internalFlag_" + std::to_string(code) + suffix; 482 ASSERT(index < static_cast<u32>(InternalFlag::Amount));
483
484 return std::string(INTERNAL_FLAG_NAMES[index]) + '_' + suffix;
480 } 485 }
481 486
482 void SetInternalFlag(const InternalFlag ii, const std::string& value) const { 487 void SetInternalFlag(const InternalFlag flag, const std::string& value) const {
483 shader.AddLine(GetInternalFlag(ii) + " = " + value + ';'); 488 shader.AddLine(GetInternalFlag(flag) + " = " + value + ';');
484 } 489 }
485 490
486 /** 491 /**
@@ -631,8 +636,8 @@ private:
631 636
632 /// Generates declarations for internal flags. 637 /// Generates declarations for internal flags.
633 void GenerateInternalFlags() { 638 void GenerateInternalFlags() {
634 for (u32 ii = 0; ii < static_cast<u64>(InternalFlag::Amount); ii++) { 639 for (u32 flag = 0; flag < static_cast<u32>(InternalFlag::Amount); flag++) {
635 const InternalFlag code = static_cast<InternalFlag>(ii); 640 const InternalFlag code = static_cast<InternalFlag>(flag);
636 declarations.AddLine("bool " + GetInternalFlag(code) + " = false;"); 641 declarations.AddLine("bool " + GetInternalFlag(code) + " = false;");
637 } 642 }
638 declarations.AddNewLine(); 643 declarations.AddNewLine();
@@ -1516,9 +1521,8 @@ private:
1516 instr.fmul.tab5c68_0 != 1, "FMUL tab5cb8_0({}) is not implemented", 1521 instr.fmul.tab5c68_0 != 1, "FMUL tab5cb8_0({}) is not implemented",
1517 instr.fmul.tab5c68_0 1522 instr.fmul.tab5c68_0
1518 .Value()); // SMO typical sends 1 here which seems to be the default 1523 .Value()); // SMO typical sends 1 here which seems to be the default
1519 UNIMPLEMENTED_IF_MSG(instr.fmul.cc != 0, "FMUL cc is not implemented");
1520 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 1524 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1521 "FMUL Generates an unhandled Control Code"); 1525 "Condition codes generation in FMUL is not implemented");
1522 1526
1523 op_b = GetOperandAbsNeg(op_b, false, instr.fmul.negate_b); 1527 op_b = GetOperandAbsNeg(op_b, false, instr.fmul.negate_b);
1524 1528
@@ -1530,7 +1534,7 @@ private:
1530 case OpCode::Id::FADD_R: 1534 case OpCode::Id::FADD_R:
1531 case OpCode::Id::FADD_IMM: { 1535 case OpCode::Id::FADD_IMM: {
1532 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 1536 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1533 "FADD Generates an unhandled Control Code"); 1537 "Condition codes generation in FADD is not implemented");
1534 1538
1535 op_a = GetOperandAbsNeg(op_a, instr.alu.abs_a, instr.alu.negate_a); 1539 op_a = GetOperandAbsNeg(op_a, instr.alu.abs_a, instr.alu.negate_a);
1536 op_b = GetOperandAbsNeg(op_b, instr.alu.abs_b, instr.alu.negate_b); 1540 op_b = GetOperandAbsNeg(op_b, instr.alu.abs_b, instr.alu.negate_b);
@@ -1580,7 +1584,7 @@ private:
1580 case OpCode::Id::FMNMX_R: 1584 case OpCode::Id::FMNMX_R:
1581 case OpCode::Id::FMNMX_IMM: { 1585 case OpCode::Id::FMNMX_IMM: {
1582 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 1586 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1583 "FMNMX Generates an unhandled Control Code"); 1587 "Condition codes generation in FMNMX is not implemented");
1584 1588
1585 op_a = GetOperandAbsNeg(op_a, instr.alu.abs_a, instr.alu.negate_a); 1589 op_a = GetOperandAbsNeg(op_a, instr.alu.abs_a, instr.alu.negate_a);
1586 op_b = GetOperandAbsNeg(op_b, instr.alu.abs_b, instr.alu.negate_b); 1590 op_b = GetOperandAbsNeg(op_b, instr.alu.abs_b, instr.alu.negate_b);
@@ -1617,7 +1621,7 @@ private:
1617 } 1621 }
1618 case OpCode::Id::FMUL32_IMM: { 1622 case OpCode::Id::FMUL32_IMM: {
1619 UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc, 1623 UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc,
1620 "FMUL32 Generates an unhandled Control Code"); 1624 "Condition codes generation in FMUL32 is not implemented");
1621 1625
1622 regs.SetRegisterToFloat(instr.gpr0, 0, 1626 regs.SetRegisterToFloat(instr.gpr0, 0,
1623 regs.GetRegisterAsFloat(instr.gpr8) + " * " + 1627 regs.GetRegisterAsFloat(instr.gpr8) + " * " +
@@ -1627,7 +1631,7 @@ private:
1627 } 1631 }
1628 case OpCode::Id::FADD32I: { 1632 case OpCode::Id::FADD32I: {
1629 UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc, 1633 UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc,
1630 "FADD32 Generates an unhandled Control Code"); 1634 "Condition codes generation in FADD32I is not implemented");
1631 1635
1632 std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); 1636 std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
1633 std::string op_b = GetImmediate32(instr); 1637 std::string op_b = GetImmediate32(instr);
@@ -1662,7 +1666,8 @@ private:
1662 1666
1663 switch (opcode->get().GetId()) { 1667 switch (opcode->get().GetId()) {
1664 case OpCode::Id::BFE_IMM: { 1668 case OpCode::Id::BFE_IMM: {
1665 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "BFE Generates an unhandled Control Code"); 1669 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1670 "Condition codes generation in BFE is not implemented");
1666 1671
1667 std::string inner_shift = 1672 std::string inner_shift =
1668 '(' + op_a + " << " + std::to_string(instr.bfe.GetLeftShiftValue()) + ')'; 1673 '(' + op_a + " << " + std::to_string(instr.bfe.GetLeftShiftValue()) + ')';
@@ -1699,7 +1704,8 @@ private:
1699 case OpCode::Id::SHR_C: 1704 case OpCode::Id::SHR_C:
1700 case OpCode::Id::SHR_R: 1705 case OpCode::Id::SHR_R:
1701 case OpCode::Id::SHR_IMM: { 1706 case OpCode::Id::SHR_IMM: {
1702 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "SHR Generates an unhandled Control Code"); 1707 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1708 "Condition codes generation in SHR is not implemented");
1703 1709
1704 if (!instr.shift.is_signed) { 1710 if (!instr.shift.is_signed) {
1705 // Logical shift right 1711 // Logical shift right
@@ -1714,8 +1720,8 @@ private:
1714 case OpCode::Id::SHL_C: 1720 case OpCode::Id::SHL_C:
1715 case OpCode::Id::SHL_R: 1721 case OpCode::Id::SHL_R:
1716 case OpCode::Id::SHL_IMM: 1722 case OpCode::Id::SHL_IMM:
1717 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "SHL Generates an unhandled Control Code"); 1723 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1718 1724 "Condition codes generation in SHL is not implemented");
1719 regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " << " + op_b, 1, 1); 1725 regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " << " + op_b, 1, 1);
1720 break; 1726 break;
1721 default: { 1727 default: {
@@ -1731,7 +1737,7 @@ private:
1731 switch (opcode->get().GetId()) { 1737 switch (opcode->get().GetId()) {
1732 case OpCode::Id::IADD32I: 1738 case OpCode::Id::IADD32I:
1733 UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc, 1739 UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc,
1734 "IADD32 Generates an unhandled Control Code"); 1740 "Condition codes generation in IADD32I is not implemented");
1735 1741
1736 if (instr.iadd32i.negate_a) 1742 if (instr.iadd32i.negate_a)
1737 op_a = "-(" + op_a + ')'; 1743 op_a = "-(" + op_a + ')';
@@ -1741,7 +1747,7 @@ private:
1741 break; 1747 break;
1742 case OpCode::Id::LOP32I: { 1748 case OpCode::Id::LOP32I: {
1743 UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc, 1749 UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc,
1744 "LOP32I Generates an unhandled Control Code"); 1750 "Condition codes generation in LOP32I is not implemented");
1745 1751
1746 if (instr.alu.lop32i.invert_a) 1752 if (instr.alu.lop32i.invert_a)
1747 op_a = "~(" + op_a + ')'; 1753 op_a = "~(" + op_a + ')';
@@ -1780,7 +1786,7 @@ private:
1780 case OpCode::Id::IADD_R: 1786 case OpCode::Id::IADD_R:
1781 case OpCode::Id::IADD_IMM: { 1787 case OpCode::Id::IADD_IMM: {
1782 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 1788 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1783 "IADD Generates an unhandled Control Code"); 1789 "Condition codes generation in IADD is not implemented");
1784 1790
1785 if (instr.alu_integer.negate_a) 1791 if (instr.alu_integer.negate_a)
1786 op_a = "-(" + op_a + ')'; 1792 op_a = "-(" + op_a + ')';
@@ -1796,7 +1802,7 @@ private:
1796 case OpCode::Id::IADD3_R: 1802 case OpCode::Id::IADD3_R:
1797 case OpCode::Id::IADD3_IMM: { 1803 case OpCode::Id::IADD3_IMM: {
1798 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 1804 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1799 "IADD3 Generates an unhandled Control Code"); 1805 "Condition codes generation in IADD3 is not implemented");
1800 1806
1801 std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); 1807 std::string op_c = regs.GetRegisterAsInteger(instr.gpr39);
1802 1808
@@ -1859,7 +1865,7 @@ private:
1859 case OpCode::Id::ISCADD_R: 1865 case OpCode::Id::ISCADD_R:
1860 case OpCode::Id::ISCADD_IMM: { 1866 case OpCode::Id::ISCADD_IMM: {
1861 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 1867 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1862 "ISCADD Generates an unhandled Control Code"); 1868 "Condition codes generation in ISCADD is not implemented");
1863 1869
1864 if (instr.alu_integer.negate_a) 1870 if (instr.alu_integer.negate_a)
1865 op_a = "-(" + op_a + ')'; 1871 op_a = "-(" + op_a + ')';
@@ -1894,7 +1900,8 @@ private:
1894 case OpCode::Id::LOP_C: 1900 case OpCode::Id::LOP_C:
1895 case OpCode::Id::LOP_R: 1901 case OpCode::Id::LOP_R:
1896 case OpCode::Id::LOP_IMM: { 1902 case OpCode::Id::LOP_IMM: {
1897 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "LOP Generates an unhandled Control Code"); 1903 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1904 "Condition codes generation in LOP is not implemented");
1898 1905
1899 if (instr.alu.lop.invert_a) 1906 if (instr.alu.lop.invert_a)
1900 op_a = "~(" + op_a + ')'; 1907 op_a = "~(" + op_a + ')';
@@ -1910,7 +1917,7 @@ private:
1910 case OpCode::Id::LOP3_R: 1917 case OpCode::Id::LOP3_R:
1911 case OpCode::Id::LOP3_IMM: { 1918 case OpCode::Id::LOP3_IMM: {
1912 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 1919 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1913 "LOP3 Generates an unhandled Control Code"); 1920 "Condition codes generation in LOP3 is not implemented");
1914 1921
1915 const std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); 1922 const std::string op_c = regs.GetRegisterAsInteger(instr.gpr39);
1916 std::string lut; 1923 std::string lut;
@@ -1929,7 +1936,7 @@ private:
1929 case OpCode::Id::IMNMX_IMM: { 1936 case OpCode::Id::IMNMX_IMM: {
1930 UNIMPLEMENTED_IF(instr.imnmx.exchange != Tegra::Shader::IMinMaxExchange::None); 1937 UNIMPLEMENTED_IF(instr.imnmx.exchange != Tegra::Shader::IMinMaxExchange::None);
1931 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 1938 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1932 "IMNMX Generates an unhandled Control Code"); 1939 "Condition codes generation in IMNMX is not implemented");
1933 1940
1934 const std::string condition = 1941 const std::string condition =
1935 GetPredicateCondition(instr.imnmx.pred, instr.imnmx.negate_pred != 0); 1942 GetPredicateCondition(instr.imnmx.pred, instr.imnmx.negate_pred != 0);
@@ -2102,7 +2109,8 @@ private:
2102 instr.ffma.tab5980_0.Value()); // Seems to be 1 by default based on SMO 2109 instr.ffma.tab5980_0.Value()); // Seems to be 1 by default based on SMO
2103 UNIMPLEMENTED_IF_MSG(instr.ffma.tab5980_1 != 0, "FFMA tab5980_1({}) not implemented", 2110 UNIMPLEMENTED_IF_MSG(instr.ffma.tab5980_1 != 0, "FFMA tab5980_1({}) not implemented",
2104 instr.ffma.tab5980_1.Value()); 2111 instr.ffma.tab5980_1.Value());
2105 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "FFMA Generates an unhandled Control Code"); 2112 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
2113 "Condition codes generation in FFMA is not implemented");
2106 2114
2107 switch (opcode->get().GetId()) { 2115 switch (opcode->get().GetId()) {
2108 case OpCode::Id::FFMA_CR: { 2116 case OpCode::Id::FFMA_CR: {
@@ -2212,7 +2220,8 @@ private:
2212 case OpCode::Id::I2F_C: { 2220 case OpCode::Id::I2F_C: {
2213 UNIMPLEMENTED_IF(instr.conversion.dest_size != Register::Size::Word); 2221 UNIMPLEMENTED_IF(instr.conversion.dest_size != Register::Size::Word);
2214 UNIMPLEMENTED_IF(instr.conversion.selector); 2222 UNIMPLEMENTED_IF(instr.conversion.selector);
2215 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "I2F Generates an unhandled Control Code"); 2223 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
2224 "Condition codes generation in I2F is not implemented");
2216 2225
2217 std::string op_a{}; 2226 std::string op_a{};
2218 2227
@@ -2242,7 +2251,8 @@ private:
2242 case OpCode::Id::F2F_R: { 2251 case OpCode::Id::F2F_R: {
2243 UNIMPLEMENTED_IF(instr.conversion.dest_size != Register::Size::Word); 2252 UNIMPLEMENTED_IF(instr.conversion.dest_size != Register::Size::Word);
2244 UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word); 2253 UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word);
2245 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "F2F Generates an unhandled Control Code"); 2254 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
2255 "Condition codes generation in F2F is not implemented");
2246 std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); 2256 std::string op_a = regs.GetRegisterAsFloat(instr.gpr20);
2247 2257
2248 if (instr.conversion.abs_a) { 2258 if (instr.conversion.abs_a) {
@@ -2280,7 +2290,8 @@ private:
2280 case OpCode::Id::F2I_R: 2290 case OpCode::Id::F2I_R:
2281 case OpCode::Id::F2I_C: { 2291 case OpCode::Id::F2I_C: {
2282 UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word); 2292 UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word);
2283 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "F2I Generates an unhandled Control Code"); 2293 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
2294 "Condition codes generation in F2I is not implemented");
2284 std::string op_a{}; 2295 std::string op_a{};
2285 2296
2286 if (instr.is_b_gpr) { 2297 if (instr.is_b_gpr) {
@@ -3129,7 +3140,8 @@ private:
3129 break; 3140 break;
3130 } 3141 }
3131 case OpCode::Type::PredicateSetRegister: { 3142 case OpCode::Type::PredicateSetRegister: {
3132 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "PSET Generates an unhandled Control Code"); 3143 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
3144 "Condition codes generation in PSET is not implemented");
3133 3145
3134 const std::string op_a = 3146 const std::string op_a =
3135 GetPredicateCondition(instr.pset.pred12, instr.pset.neg_pred12 != 0); 3147 GetPredicateCondition(instr.pset.pred12, instr.pset.neg_pred12 != 0);
@@ -3188,14 +3200,14 @@ private:
3188 const std::string pred = 3200 const std::string pred =
3189 GetPredicateCondition(instr.csetp.pred39, instr.csetp.neg_pred39 != 0); 3201 GetPredicateCondition(instr.csetp.pred39, instr.csetp.neg_pred39 != 0);
3190 const std::string combiner = GetPredicateCombiner(instr.csetp.op); 3202 const std::string combiner = GetPredicateCombiner(instr.csetp.op);
3191 const std::string control_code = regs.GetControlCode(instr.csetp.cc); 3203 const std::string condition_code = regs.GetConditionCode(instr.csetp.cc);
3192 if (instr.csetp.pred3 != static_cast<u64>(Pred::UnusedIndex)) { 3204 if (instr.csetp.pred3 != static_cast<u64>(Pred::UnusedIndex)) {
3193 SetPredicate(instr.csetp.pred3, 3205 SetPredicate(instr.csetp.pred3,
3194 '(' + control_code + ") " + combiner + " (" + pred + ')'); 3206 '(' + condition_code + ") " + combiner + " (" + pred + ')');
3195 } 3207 }
3196 if (instr.csetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) { 3208 if (instr.csetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) {
3197 SetPredicate(instr.csetp.pred0, 3209 SetPredicate(instr.csetp.pred0,
3198 "!(" + control_code + ") " + combiner + " (" + pred + ')'); 3210 "!(" + condition_code + ") " + combiner + " (" + pred + ')');
3199 } 3211 }
3200 break; 3212 break;
3201 } 3213 }
@@ -3326,7 +3338,8 @@ private:
3326 case OpCode::Type::Xmad: { 3338 case OpCode::Type::Xmad: {
3327 UNIMPLEMENTED_IF(instr.xmad.sign_a); 3339 UNIMPLEMENTED_IF(instr.xmad.sign_a);
3328 UNIMPLEMENTED_IF(instr.xmad.sign_b); 3340 UNIMPLEMENTED_IF(instr.xmad.sign_b);
3329 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "XMAD Generates an unhandled Control Code"); 3341 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
3342 "Condition codes generation in XMAD is not implemented");
3330 3343
3331 std::string op_a{regs.GetRegisterAsInteger(instr.gpr8, 0, instr.xmad.sign_a)}; 3344 std::string op_a{regs.GetRegisterAsInteger(instr.gpr8, 0, instr.xmad.sign_a)};
3332 std::string op_b; 3345 std::string op_b;
@@ -3418,9 +3431,9 @@ private:
3418 default: { 3431 default: {
3419 switch (opcode->get().GetId()) { 3432 switch (opcode->get().GetId()) {
3420 case OpCode::Id::EXIT: { 3433 case OpCode::Id::EXIT: {
3421 const Tegra::Shader::ControlCode cc = instr.flow_control_code; 3434 const Tegra::Shader::ConditionCode cc = instr.flow_condition_code;
3422 UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ControlCode::T, 3435 UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T,
3423 "EXIT Control Code used: {}", static_cast<u32>(cc)); 3436 "EXIT condition code used: {}", static_cast<u32>(cc));
3424 3437
3425 if (stage == Maxwell3D::Regs::ShaderStage::Fragment) { 3438 if (stage == Maxwell3D::Regs::ShaderStage::Fragment) {
3426 EmitFragmentOutputsWrite(); 3439 EmitFragmentOutputsWrite();
@@ -3452,9 +3465,9 @@ private:
3452 case OpCode::Id::KIL: { 3465 case OpCode::Id::KIL: {
3453 UNIMPLEMENTED_IF(instr.flow.cond != Tegra::Shader::FlowCondition::Always); 3466 UNIMPLEMENTED_IF(instr.flow.cond != Tegra::Shader::FlowCondition::Always);
3454 3467
3455 const Tegra::Shader::ControlCode cc = instr.flow_control_code; 3468 const Tegra::Shader::ConditionCode cc = instr.flow_condition_code;
3456 UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ControlCode::T, 3469 UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T,
3457 "KIL Control Code used: {}", static_cast<u32>(cc)); 3470 "KIL condition code used: {}", static_cast<u32>(cc));
3458 3471
3459 // Enclose "discard" in a conditional, so that GLSL compilation does not complain 3472 // Enclose "discard" in a conditional, so that GLSL compilation does not complain
3460 // about unexecuted instructions that may follow this. 3473 // about unexecuted instructions that may follow this.
@@ -3516,9 +3529,9 @@ private:
3516 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, 3529 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0,
3517 "BRA with constant buffers are not implemented"); 3530 "BRA with constant buffers are not implemented");
3518 3531
3519 const Tegra::Shader::ControlCode cc = instr.flow_control_code; 3532 const Tegra::Shader::ConditionCode cc = instr.flow_condition_code;
3520 UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ControlCode::T, 3533 UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T,
3521 "BRA Control Code used: {}", static_cast<u32>(cc)); 3534 "BRA condition code used: {}", static_cast<u32>(cc));
3522 3535
3523 const u32 target = offset + instr.bra.GetBranchTarget(); 3536 const u32 target = offset + instr.bra.GetBranchTarget();
3524 shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }"); 3537 shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }");
@@ -3561,9 +3574,9 @@ private:
3561 break; 3574 break;
3562 } 3575 }
3563 case OpCode::Id::SYNC: { 3576 case OpCode::Id::SYNC: {
3564 const Tegra::Shader::ControlCode cc = instr.flow_control_code; 3577 const Tegra::Shader::ConditionCode cc = instr.flow_condition_code;
3565 UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ControlCode::T, 3578 UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T,
3566 "SYNC Control Code used: {}", static_cast<u32>(cc)); 3579 "SYNC condition code used: {}", static_cast<u32>(cc));
3567 3580
3568 // The SYNC opcode jumps to the address previously set by the SSY opcode 3581 // The SYNC opcode jumps to the address previously set by the SSY opcode
3569 EmitPopFromFlowStack(); 3582 EmitPopFromFlowStack();
@@ -3571,10 +3584,10 @@ private:
3571 } 3584 }
3572 case OpCode::Id::BRK: { 3585 case OpCode::Id::BRK: {
3573 // The BRK opcode jumps to the address previously set by the PBK opcode 3586 // The BRK opcode jumps to the address previously set by the PBK opcode
3574 const Tegra::Shader::ControlCode cc = instr.flow_control_code; 3587 const Tegra::Shader::ConditionCode cc = instr.flow_condition_code;
3575 if (cc != Tegra::Shader::ControlCode::T) { 3588 UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T,
3576 UNIMPLEMENTED_MSG("BRK Control Code used: {}", static_cast<u32>(cc)); 3589 "BRK condition code used: {}", static_cast<u32>(cc));
3577 } 3590
3578 EmitPopFromFlowStack(); 3591 EmitPopFromFlowStack();
3579 break; 3592 break;
3580 } 3593 }
@@ -3585,6 +3598,9 @@ private:
3585 break; 3598 break;
3586 } 3599 }
3587 case OpCode::Id::VMAD: { 3600 case OpCode::Id::VMAD: {
3601 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
3602 "Condition codes generation in VMAD is not implemented");
3603
3588 const bool result_signed = instr.video.signed_a == 1 || instr.video.signed_b == 1; 3604 const bool result_signed = instr.video.signed_a == 1 || instr.video.signed_b == 1;
3589 const std::string op_a = GetVideoOperandA(instr); 3605 const std::string op_a = GetVideoOperandA(instr);
3590 const std::string op_b = GetVideoOperandB(instr); 3606 const std::string op_b = GetVideoOperandB(instr);
@@ -3604,10 +3620,6 @@ private:
3604 regs.SetRegisterToInteger(instr.gpr0, result_signed, 1, result, 1, 1, 3620 regs.SetRegisterToInteger(instr.gpr0, result_signed, 1, result, 1, 1,
3605 instr.vmad.saturate == 1, 0, Register::Size::Word, 3621 instr.vmad.saturate == 1, 0, Register::Size::Word,
3606 instr.vmad.cc); 3622 instr.vmad.cc);
3607 if (instr.generates_cc) {
3608 UNIMPLEMENTED_MSG("VMAD Generates an unhandled Control Code");
3609 }
3610
3611 break; 3623 break;
3612 } 3624 }
3613 case OpCode::Id::VSETP: { 3625 case OpCode::Id::VSETP: {