summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2018-11-20 21:20:41 -0300
committerGravatar ReinUsesLisp2018-11-20 22:00:13 -0300
commitbb893188ebf460c769750dbc67fe9dfcec80219d (patch)
tree301b1d7ba83fb26239887d04b59a36d08533d85f /src
parentMerge pull request #1734 from lioncash/shared (diff)
downloadyuzu-bb893188ebf460c769750dbc67fe9dfcec80219d.tar.gz
yuzu-bb893188ebf460c769750dbc67fe9dfcec80219d.tar.xz
yuzu-bb893188ebf460c769750dbc67fe9dfcec80219d.zip
gl_shader_decompiler: Use UNIMPLEMENTED instead of LOG+UNREACHABLE when applicable
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp629
1 files changed, 258 insertions, 371 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 5fde22ad4..ca36b9393 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -49,8 +49,7 @@ static std::string GetTopologyName(Tegra::Shader::OutputTopology topology) {
49 case Tegra::Shader::OutputTopology::TriangleStrip: 49 case Tegra::Shader::OutputTopology::TriangleStrip:
50 return "triangle_strip"; 50 return "triangle_strip";
51 default: 51 default:
52 LOG_CRITICAL(Render_OpenGL, "Unknown output topology {}", static_cast<u32>(topology)); 52 UNIMPLEMENTED_MSG("Unknown output topology: {}", static_cast<u32>(topology));
53 UNREACHABLE();
54 return "points"; 53 return "points";
55 } 54 }
56} 55}
@@ -167,8 +166,8 @@ private:
167 case OpCode::Id::SSY: 166 case OpCode::Id::SSY:
168 case OpCode::Id::PBK: { 167 case OpCode::Id::PBK: {
169 // The SSY and PBK use a similar encoding as the BRA instruction. 168 // The SSY and PBK use a similar encoding as the BRA instruction.
170 ASSERT_MSG(instr.bra.constant_buffer == 0, 169 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0,
171 "Constant buffer branching is not supported"); 170 "Constant buffer branching is not supported");
172 const u32 target = offset + instr.bra.GetBranchTarget(); 171 const u32 target = offset + instr.bra.GetBranchTarget();
173 labels.insert(target); 172 labels.insert(target);
174 // Continue scanning for an exit method. 173 // Continue scanning for an exit method.
@@ -299,8 +298,7 @@ public:
299 // Default - do nothing 298 // Default - do nothing
300 return value; 299 return value;
301 default: 300 default:
302 LOG_CRITICAL(HW_GPU, "Unimplemented conversion size {}", static_cast<u32>(size)); 301 UNIMPLEMENTED_MSG("Unimplemented conversion size: {}", static_cast<u32>(size));
303 UNREACHABLE();
304 } 302 }
305 } 303 }
306 304
@@ -363,7 +361,7 @@ public:
363 u64 value_num_components, bool is_saturated = false, 361 u64 value_num_components, bool is_saturated = false,
364 u64 dest_elem = 0, Register::Size size = Register::Size::Word, 362 u64 dest_elem = 0, Register::Size size = Register::Size::Word,
365 bool sets_cc = false) { 363 bool sets_cc = false) {
366 ASSERT_MSG(!is_saturated, "Unimplemented"); 364 UNIMPLEMENTED_IF(is_saturated);
367 365
368 const std::string func{is_signed ? "intBitsToFloat" : "uintBitsToFloat"}; 366 const std::string func{is_signed ? "intBitsToFloat" : "uintBitsToFloat"};
369 367
@@ -392,7 +390,7 @@ public:
392 Tegra::Shader::HalfMerge merge, u64 dest_num_components, 390 Tegra::Shader::HalfMerge merge, u64 dest_num_components,
393 u64 value_num_components, bool is_saturated = false, 391 u64 value_num_components, bool is_saturated = false,
394 u64 dest_elem = 0) { 392 u64 dest_elem = 0) {
395 ASSERT_MSG(!is_saturated, "Unimplemented"); 393 UNIMPLEMENTED_IF(is_saturated);
396 394
397 const std::string result = [&]() { 395 const std::string result = [&]() {
398 switch (merge) { 396 switch (merge) {
@@ -461,8 +459,7 @@ public:
461 case Tegra::Shader::ControlCode::NEU: 459 case Tegra::Shader::ControlCode::NEU:
462 return "!(" + GetInternalFlag(InternalFlag::ZeroFlag) + ')'; 460 return "!(" + GetInternalFlag(InternalFlag::ZeroFlag) + ')';
463 default: 461 default:
464 LOG_CRITICAL(HW_GPU, "Unimplemented Control Code {}", static_cast<u32>(cc)); 462 UNIMPLEMENTED_MSG("Unimplemented Control Code: {}", static_cast<u32>(cc));
465 UNREACHABLE();
466 return "false"; 463 return "false";
467 } 464 }
468 } 465 }
@@ -847,16 +844,13 @@ private:
847 if (declr_input_attribute.count(attribute) == 0) { 844 if (declr_input_attribute.count(attribute) == 0) {
848 declr_input_attribute[attribute] = input_mode; 845 declr_input_attribute[attribute] = input_mode;
849 } else { 846 } else {
850 if (declr_input_attribute[attribute] != input_mode) { 847 UNIMPLEMENTED_IF_MSG(declr_input_attribute[attribute] != input_mode,
851 LOG_CRITICAL(HW_GPU, "Same Input multiple input modes"); 848 "Multiple input modes for the same attribute");
852 UNREACHABLE();
853 }
854 } 849 }
855 return GeometryPass("input_attribute_" + std::to_string(index)); 850 return GeometryPass("input_attribute_" + std::to_string(index));
856 } 851 }
857 852
858 LOG_CRITICAL(HW_GPU, "Unhandled input attribute: {}", static_cast<u32>(attribute)); 853 UNIMPLEMENTED_MSG("Unhandled input attribute: {}", static_cast<u32>(attribute));
859 UNREACHABLE();
860 } 854 }
861 855
862 return "vec4(0, 0, 0, 0)"; 856 return "vec4(0, 0, 0, 0)";
@@ -882,24 +876,20 @@ private:
882 break; 876 break;
883 } 877 }
884 default: { 878 default: {
885 LOG_CRITICAL(HW_GPU, "Unhandled Ipa InterpMode: {}", static_cast<u32>(interp_mode)); 879 UNIMPLEMENTED_MSG("Unhandled IPA interp mode: {}", static_cast<u32>(interp_mode));
886 UNREACHABLE();
887 } 880 }
888 } 881 }
889 switch (sample_mode) { 882 switch (sample_mode) {
890 case Tegra::Shader::IpaSampleMode::Centroid: { 883 case Tegra::Shader::IpaSampleMode::Centroid:
891 // Note not implemented, it can be implemented with the "centroid " keyword in glsl; 884 // It can be implemented with the "centroid " keyword in glsl
892 LOG_CRITICAL(HW_GPU, "Ipa Sampler Mode: centroid, not implemented"); 885 UNIMPLEMENTED_MSG("Unimplemented IPA sampler mode centroid");
893 UNREACHABLE();
894 break; 886 break;
895 } 887 case Tegra::Shader::IpaSampleMode::Default:
896 case Tegra::Shader::IpaSampleMode::Default: {
897 // Default, n/a 888 // Default, n/a
898 break; 889 break;
899 }
900 default: { 890 default: {
901 LOG_CRITICAL(HW_GPU, "Unhandled Ipa SampleMode: {}", static_cast<u32>(sample_mode)); 891 UNIMPLEMENTED_MSG("Unimplemented IPA sampler mode: {}", static_cast<u32>(sample_mode));
902 UNREACHABLE(); 892 break;
903 } 893 }
904 } 894 }
905 return out; 895 return out;
@@ -920,8 +910,7 @@ private:
920 return "output_attribute_" + std::to_string(index); 910 return "output_attribute_" + std::to_string(index);
921 } 911 }
922 912
923 LOG_CRITICAL(HW_GPU, "Unhandled output attribute: {}", index); 913 UNIMPLEMENTED_MSG("Unhandled output attribute={}", index);
924 UNREACHABLE();
925 return {}; 914 return {};
926 } 915 }
927 } 916 }
@@ -1078,8 +1067,8 @@ private:
1078 {PredCondition::GreaterThanWithNan, ">"}, {PredCondition::GreaterEqualWithNan, ">="}}; 1067 {PredCondition::GreaterThanWithNan, ">"}, {PredCondition::GreaterEqualWithNan, ">="}};
1079 1068
1080 const auto& comparison{PredicateComparisonStrings.find(condition)}; 1069 const auto& comparison{PredicateComparisonStrings.find(condition)};
1081 ASSERT_MSG(comparison != PredicateComparisonStrings.end(), 1070 UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonStrings.end(),
1082 "Unknown predicate comparison operation"); 1071 "Unknown predicate comparison operation");
1083 1072
1084 std::string predicate{'(' + op_a + ") " + comparison->second + " (" + op_b + ')'}; 1073 std::string predicate{'(' + op_a + ") " + comparison->second + " (" + op_b + ')'};
1085 if (condition == PredCondition::LessThanWithNan || 1074 if (condition == PredCondition::LessThanWithNan ||
@@ -1107,7 +1096,7 @@ private:
1107 }; 1096 };
1108 1097
1109 auto op = PredicateOperationStrings.find(operation); 1098 auto op = PredicateOperationStrings.find(operation);
1110 ASSERT_MSG(op != PredicateOperationStrings.end(), "Unknown predicate operation"); 1099 UNIMPLEMENTED_IF_MSG(op == PredicateOperationStrings.end(), "Unknown predicate operation");
1111 return op->second; 1100 return op->second;
1112 } 1101 }
1113 1102
@@ -1205,8 +1194,7 @@ private:
1205 break; 1194 break;
1206 } 1195 }
1207 default: 1196 default:
1208 LOG_CRITICAL(HW_GPU, "Unimplemented logic operation: {}", static_cast<u32>(logic_op)); 1197 UNIMPLEMENTED_MSG("Unimplemented logic operation={}", static_cast<u32>(logic_op));
1209 UNREACHABLE();
1210 } 1198 }
1211 1199
1212 if (dest != Tegra::Shader::Register::ZeroIndex) { 1200 if (dest != Tegra::Shader::Register::ZeroIndex) {
@@ -1224,9 +1212,8 @@ private:
1224 SetPredicate(static_cast<u64>(predicate), '(' + result + ") != 0"); 1212 SetPredicate(static_cast<u64>(predicate), '(' + result + ") != 0");
1225 break; 1213 break;
1226 default: 1214 default:
1227 LOG_CRITICAL(HW_GPU, "Unimplemented predicate result mode: {}", 1215 UNIMPLEMENTED_MSG("Unimplemented predicate result mode: {}",
1228 static_cast<u32>(predicate_mode)); 1216 static_cast<u32>(predicate_mode));
1229 UNREACHABLE();
1230 } 1217 }
1231 } 1218 }
1232 1219
@@ -1294,19 +1281,15 @@ private:
1294 1281
1295 static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { 1282 static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) {
1296 switch (texture_type) { 1283 switch (texture_type) {
1297 case Tegra::Shader::TextureType::Texture1D: { 1284 case Tegra::Shader::TextureType::Texture1D:
1298 return 1; 1285 return 1;
1299 } 1286 case Tegra::Shader::TextureType::Texture2D:
1300 case Tegra::Shader::TextureType::Texture2D: {
1301 return 2; 1287 return 2;
1302 }
1303 case Tegra::Shader::TextureType::Texture3D: 1288 case Tegra::Shader::TextureType::Texture3D:
1304 case Tegra::Shader::TextureType::TextureCube: { 1289 case Tegra::Shader::TextureType::TextureCube:
1305 return 3; 1290 return 3;
1306 }
1307 default: 1291 default:
1308 LOG_CRITICAL(HW_GPU, "Unhandled texture type {}", static_cast<u32>(texture_type)); 1292 UNIMPLEMENTED_MSG("Unhandled texture type: {}", static_cast<u32>(texture_type));
1309 UNREACHABLE();
1310 return 0; 1293 return 0;
1311 } 1294 }
1312 } 1295 }
@@ -1342,7 +1325,7 @@ private:
1342 void EmitFragmentOutputsWrite() { 1325 void EmitFragmentOutputsWrite() {
1343 ASSERT(stage == Maxwell3D::Regs::ShaderStage::Fragment); 1326 ASSERT(stage == Maxwell3D::Regs::ShaderStage::Fragment);
1344 1327
1345 ASSERT_MSG(header.ps.omap.sample_mask == 0, "Samplemask write is unimplemented"); 1328 UNIMPLEMENTED_IF_MSG(header.ps.omap.sample_mask != 0, "Samplemask write is unimplemented");
1346 1329
1347 shader.AddLine("if (alpha_test[0] != 0) {"); 1330 shader.AddLine("if (alpha_test[0] != 0) {");
1348 ++shader.scope; 1331 ++shader.scope;
@@ -1408,7 +1391,7 @@ private:
1408 case Tegra::Shader::VideoType::Size32: 1391 case Tegra::Shader::VideoType::Size32:
1409 // TODO(Rodrigo): From my hardware tests it becomes a bit "mad" when 1392 // TODO(Rodrigo): From my hardware tests it becomes a bit "mad" when
1410 // this type is used (1 * 1 + 0 == 0x5b800000). Until a better 1393 // this type is used (1 * 1 + 0 == 0x5b800000). Until a better
1411 // explanation is found: assert. 1394 // explanation is found: abort.
1412 UNIMPLEMENTED(); 1395 UNIMPLEMENTED();
1413 return zero; 1396 return zero;
1414 case Tegra::Shader::VideoType::Invalid: 1397 case Tegra::Shader::VideoType::Invalid:
@@ -1464,8 +1447,7 @@ private:
1464 1447
1465 // Decoding failure 1448 // Decoding failure
1466 if (!opcode) { 1449 if (!opcode) {
1467 LOG_CRITICAL(HW_GPU, "Unhandled instruction: {0:x}", instr.value); 1450 UNIMPLEMENTED_MSG("Unhandled instruction: {0:x}", instr.value);
1468 UNREACHABLE();
1469 return offset + 1; 1451 return offset + 1;
1470 } 1452 }
1471 1453
@@ -1473,8 +1455,8 @@ private:
1473 fmt::format("// {}: {} (0x{:016x})", offset, opcode->get().GetName(), instr.value)); 1455 fmt::format("// {}: {} (0x{:016x})", offset, opcode->get().GetName(), instr.value));
1474 1456
1475 using Tegra::Shader::Pred; 1457 using Tegra::Shader::Pred;
1476 ASSERT_MSG(instr.pred.full_pred != Pred::NeverExecute, 1458 UNIMPLEMENTED_IF_MSG(instr.pred.full_pred == Pred::NeverExecute,
1477 "NeverExecute predicate not implemented"); 1459 "NeverExecute predicate not implemented");
1478 1460
1479 // Some instructions (like SSY) don't have a predicate field, they are always 1461 // Some instructions (like SSY) don't have a predicate field, they are always
1480 // unconditionally executed. 1462 // unconditionally executed.
@@ -1517,37 +1499,37 @@ private:
1517 case OpCode::Id::FMUL_R: 1499 case OpCode::Id::FMUL_R:
1518 case OpCode::Id::FMUL_IMM: { 1500 case OpCode::Id::FMUL_IMM: {
1519 // FMUL does not have 'abs' bits and only the second operand has a 'neg' bit. 1501 // FMUL does not have 'abs' bits and only the second operand has a 'neg' bit.
1520 ASSERT_MSG(instr.fmul.tab5cb8_2 == 0, "FMUL tab5cb8_2({}) is not implemented", 1502 UNIMPLEMENTED_IF_MSG(instr.fmul.tab5cb8_2 != 0,
1521 instr.fmul.tab5cb8_2.Value()); 1503 "FMUL tab5cb8_2({}) is not implemented",
1522 ASSERT_MSG(instr.fmul.tab5c68_1 == 0, "FMUL tab5cb8_1({}) is not implemented", 1504 instr.fmul.tab5cb8_2.Value());
1523 instr.fmul.tab5c68_1.Value()); 1505 UNIMPLEMENTED_IF_MSG(instr.fmul.tab5c68_1 != 0,
1524 ASSERT_MSG(instr.fmul.tab5c68_0 == 1, "FMUL tab5cb8_0({}) is not implemented", 1506 "FMUL tab5cb8_1({}) is not implemented",
1525 instr.fmul.tab5c68_0 1507 instr.fmul.tab5c68_1.Value());
1526 .Value()); // SMO typical sends 1 here which seems to be the default 1508 UNIMPLEMENTED_IF_MSG(
1527 ASSERT_MSG(instr.fmul.cc == 0, "FMUL cc is not implemented"); 1509 instr.fmul.tab5c68_0 != 1, "FMUL tab5cb8_0({}) is not implemented",
1510 instr.fmul.tab5c68_0
1511 .Value()); // SMO typical sends 1 here which seems to be the default
1512 UNIMPLEMENTED_IF_MSG(instr.fmul.cc != 0, "FMUL cc is not implemented");
1513 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1514 "FMUL Generates an unhandled Control Code");
1528 1515
1529 op_b = GetOperandAbsNeg(op_b, false, instr.fmul.negate_b); 1516 op_b = GetOperandAbsNeg(op_b, false, instr.fmul.negate_b);
1530 1517
1531 regs.SetRegisterToFloat(instr.gpr0, 0, op_a + " * " + op_b, 1, 1, 1518 regs.SetRegisterToFloat(instr.gpr0, 0, op_a + " * " + op_b, 1, 1,
1532 instr.alu.saturate_d, 0, true); 1519 instr.alu.saturate_d, 0, true);
1533 if (instr.generates_cc) {
1534 LOG_CRITICAL(HW_GPU, "FMUL Generates an unhandled Control Code");
1535 UNREACHABLE();
1536 }
1537 break; 1520 break;
1538 } 1521 }
1539 case OpCode::Id::FADD_C: 1522 case OpCode::Id::FADD_C:
1540 case OpCode::Id::FADD_R: 1523 case OpCode::Id::FADD_R:
1541 case OpCode::Id::FADD_IMM: { 1524 case OpCode::Id::FADD_IMM: {
1525 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1526 "FADD Generates an unhandled Control Code");
1527
1542 op_a = GetOperandAbsNeg(op_a, instr.alu.abs_a, instr.alu.negate_a); 1528 op_a = GetOperandAbsNeg(op_a, instr.alu.abs_a, instr.alu.negate_a);
1543 op_b = GetOperandAbsNeg(op_b, instr.alu.abs_b, instr.alu.negate_b); 1529 op_b = GetOperandAbsNeg(op_b, instr.alu.abs_b, instr.alu.negate_b);
1544 1530
1545 regs.SetRegisterToFloat(instr.gpr0, 0, op_a + " + " + op_b, 1, 1, 1531 regs.SetRegisterToFloat(instr.gpr0, 0, op_a + " + " + op_b, 1, 1,
1546 instr.alu.saturate_d, 0, true); 1532 instr.alu.saturate_d, 0, true);
1547 if (instr.generates_cc) {
1548 LOG_CRITICAL(HW_GPU, "FADD Generates an unhandled Control Code");
1549 UNREACHABLE();
1550 }
1551 break; 1533 break;
1552 } 1534 }
1553 case OpCode::Id::MUFU: { 1535 case OpCode::Id::MUFU: {
@@ -1582,15 +1564,17 @@ private:
1582 instr.alu.saturate_d, 0, true); 1564 instr.alu.saturate_d, 0, true);
1583 break; 1565 break;
1584 default: 1566 default:
1585 LOG_CRITICAL(HW_GPU, "Unhandled MUFU sub op: {0:x}", 1567 UNIMPLEMENTED_MSG("Unhandled MUFU sub op={0:x}",
1586 static_cast<unsigned>(instr.sub_op.Value())); 1568 static_cast<unsigned>(instr.sub_op.Value()));
1587 UNREACHABLE();
1588 } 1569 }
1589 break; 1570 break;
1590 } 1571 }
1591 case OpCode::Id::FMNMX_C: 1572 case OpCode::Id::FMNMX_C:
1592 case OpCode::Id::FMNMX_R: 1573 case OpCode::Id::FMNMX_R:
1593 case OpCode::Id::FMNMX_IMM: { 1574 case OpCode::Id::FMNMX_IMM: {
1575 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1576 "FMNMX Generates an unhandled Control Code");
1577
1594 op_a = GetOperandAbsNeg(op_a, instr.alu.abs_a, instr.alu.negate_a); 1578 op_a = GetOperandAbsNeg(op_a, instr.alu.abs_a, instr.alu.negate_a);
1595 op_b = GetOperandAbsNeg(op_b, instr.alu.abs_b, instr.alu.negate_b); 1579 op_b = GetOperandAbsNeg(op_b, instr.alu.abs_b, instr.alu.negate_b);
1596 1580
@@ -1601,10 +1585,6 @@ private:
1601 '(' + condition + ") ? min(" + parameters + ") : max(" + 1585 '(' + condition + ") ? min(" + parameters + ") : max(" +
1602 parameters + ')', 1586 parameters + ')',
1603 1, 1, false, 0, true); 1587 1, 1, false, 0, true);
1604 if (instr.generates_cc) {
1605 LOG_CRITICAL(HW_GPU, "FMNMX Generates an unhandled Control Code");
1606 UNREACHABLE();
1607 }
1608 break; 1588 break;
1609 } 1589 }
1610 case OpCode::Id::RRO_C: 1590 case OpCode::Id::RRO_C:
@@ -1617,9 +1597,7 @@ private:
1617 break; 1597 break;
1618 } 1598 }
1619 default: { 1599 default: {
1620 LOG_CRITICAL(HW_GPU, "Unhandled arithmetic instruction: {}", 1600 UNIMPLEMENTED_MSG("Unhandled arithmetic instruction: {}", opcode->get().GetName());
1621 opcode->get().GetName());
1622 UNREACHABLE();
1623 } 1601 }
1624 } 1602 }
1625 break; 1603 break;
@@ -1631,17 +1609,19 @@ private:
1631 break; 1609 break;
1632 } 1610 }
1633 case OpCode::Id::FMUL32_IMM: { 1611 case OpCode::Id::FMUL32_IMM: {
1612 UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc,
1613 "FMUL32 Generates an unhandled Control Code");
1614
1634 regs.SetRegisterToFloat(instr.gpr0, 0, 1615 regs.SetRegisterToFloat(instr.gpr0, 0,
1635 regs.GetRegisterAsFloat(instr.gpr8) + " * " + 1616 regs.GetRegisterAsFloat(instr.gpr8) + " * " +
1636 GetImmediate32(instr), 1617 GetImmediate32(instr),
1637 1, 1, instr.fmul32.saturate, 0, true); 1618 1, 1, instr.fmul32.saturate, 0, true);
1638 if (instr.op_32.generates_cc) {
1639 LOG_CRITICAL(HW_GPU, "FMUL32 Generates an unhandled Control Code");
1640 UNREACHABLE();
1641 }
1642 break; 1619 break;
1643 } 1620 }
1644 case OpCode::Id::FADD32I: { 1621 case OpCode::Id::FADD32I: {
1622 UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc,
1623 "FADD32 Generates an unhandled Control Code");
1624
1645 std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); 1625 std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
1646 std::string op_b = GetImmediate32(instr); 1626 std::string op_b = GetImmediate32(instr);
1647 1627
@@ -1662,23 +1642,21 @@ private:
1662 } 1642 }
1663 1643
1664 regs.SetRegisterToFloat(instr.gpr0, 0, op_a + " + " + op_b, 1, 1, false, 0, true); 1644 regs.SetRegisterToFloat(instr.gpr0, 0, op_a + " + " + op_b, 1, 1, false, 0, true);
1665 if (instr.op_32.generates_cc) {
1666 LOG_CRITICAL(HW_GPU, "FADD32 Generates an unhandled Control Code");
1667 UNREACHABLE();
1668 }
1669 break; 1645 break;
1670 } 1646 }
1671 } 1647 }
1672 break; 1648 break;
1673 } 1649 }
1674 case OpCode::Type::Bfe: { 1650 case OpCode::Type::Bfe: {
1675 ASSERT_MSG(!instr.bfe.negate_b, "Unimplemented"); 1651 UNIMPLEMENTED_IF(instr.bfe.negate_b);
1676 1652
1677 std::string op_a = instr.bfe.negate_a ? "-" : ""; 1653 std::string op_a = instr.bfe.negate_a ? "-" : "";
1678 op_a += regs.GetRegisterAsInteger(instr.gpr8); 1654 op_a += regs.GetRegisterAsInteger(instr.gpr8);
1679 1655
1680 switch (opcode->get().GetId()) { 1656 switch (opcode->get().GetId()) {
1681 case OpCode::Id::BFE_IMM: { 1657 case OpCode::Id::BFE_IMM: {
1658 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "BFE Generates an unhandled Control Code");
1659
1682 std::string inner_shift = 1660 std::string inner_shift =
1683 '(' + op_a + " << " + std::to_string(instr.bfe.GetLeftShiftValue()) + ')'; 1661 '(' + op_a + " << " + std::to_string(instr.bfe.GetLeftShiftValue()) + ')';
1684 std::string outer_shift = 1662 std::string outer_shift =
@@ -1686,15 +1664,10 @@ private:
1686 std::to_string(instr.bfe.GetLeftShiftValue() + instr.bfe.shift_position) + ')'; 1664 std::to_string(instr.bfe.GetLeftShiftValue() + instr.bfe.shift_position) + ')';
1687 1665
1688 regs.SetRegisterToInteger(instr.gpr0, true, 0, outer_shift, 1, 1); 1666 regs.SetRegisterToInteger(instr.gpr0, true, 0, outer_shift, 1, 1);
1689 if (instr.generates_cc) {
1690 LOG_CRITICAL(HW_GPU, "BFE Generates an unhandled Control Code");
1691 UNREACHABLE();
1692 }
1693 break; 1667 break;
1694 } 1668 }
1695 default: { 1669 default: {
1696 LOG_CRITICAL(HW_GPU, "Unhandled BFE instruction: {}", opcode->get().GetName()); 1670 UNIMPLEMENTED_MSG("Unhandled BFE instruction: {}", opcode->get().GetName());
1697 UNREACHABLE();
1698 } 1671 }
1699 } 1672 }
1700 1673
@@ -1719,6 +1692,8 @@ private:
1719 case OpCode::Id::SHR_C: 1692 case OpCode::Id::SHR_C:
1720 case OpCode::Id::SHR_R: 1693 case OpCode::Id::SHR_R:
1721 case OpCode::Id::SHR_IMM: { 1694 case OpCode::Id::SHR_IMM: {
1695 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "SHR Generates an unhandled Control Code");
1696
1722 if (!instr.shift.is_signed) { 1697 if (!instr.shift.is_signed) {
1723 // Logical shift right 1698 // Logical shift right
1724 op_a = "uint(" + op_a + ')'; 1699 op_a = "uint(" + op_a + ')';
@@ -1727,24 +1702,17 @@ private:
1727 // Cast to int is superfluous for arithmetic shift, it's only for a logical shift 1702 // Cast to int is superfluous for arithmetic shift, it's only for a logical shift
1728 regs.SetRegisterToInteger(instr.gpr0, true, 0, "int(" + op_a + " >> " + op_b + ')', 1703 regs.SetRegisterToInteger(instr.gpr0, true, 0, "int(" + op_a + " >> " + op_b + ')',
1729 1, 1); 1704 1, 1);
1730 if (instr.generates_cc) {
1731 LOG_CRITICAL(HW_GPU, "SHR Generates an unhandled Control Code");
1732 UNREACHABLE();
1733 }
1734 break; 1705 break;
1735 } 1706 }
1736 case OpCode::Id::SHL_C: 1707 case OpCode::Id::SHL_C:
1737 case OpCode::Id::SHL_R: 1708 case OpCode::Id::SHL_R:
1738 case OpCode::Id::SHL_IMM: 1709 case OpCode::Id::SHL_IMM:
1710 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "SHL Generates an unhandled Control Code");
1711
1739 regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " << " + op_b, 1, 1); 1712 regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " << " + op_b, 1, 1);
1740 if (instr.generates_cc) {
1741 LOG_CRITICAL(HW_GPU, "SHL Generates an unhandled Control Code");
1742 UNREACHABLE();
1743 }
1744 break; 1713 break;
1745 default: { 1714 default: {
1746 LOG_CRITICAL(HW_GPU, "Unhandled shift instruction: {}", opcode->get().GetName()); 1715 UNIMPLEMENTED_MSG("Unhandled shift instruction: {}", opcode->get().GetName());
1747 UNREACHABLE();
1748 } 1716 }
1749 } 1717 }
1750 break; 1718 break;
@@ -1755,17 +1723,19 @@ private:
1755 1723
1756 switch (opcode->get().GetId()) { 1724 switch (opcode->get().GetId()) {
1757 case OpCode::Id::IADD32I: 1725 case OpCode::Id::IADD32I:
1726 UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc,
1727 "IADD32 Generates an unhandled Control Code");
1728
1758 if (instr.iadd32i.negate_a) 1729 if (instr.iadd32i.negate_a)
1759 op_a = "-(" + op_a + ')'; 1730 op_a = "-(" + op_a + ')';
1760 1731
1761 regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " + " + op_b, 1, 1, 1732 regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " + " + op_b, 1, 1,
1762 instr.iadd32i.saturate != 0); 1733 instr.iadd32i.saturate != 0);
1763 if (instr.op_32.generates_cc) {
1764 LOG_CRITICAL(HW_GPU, "IADD32 Generates an unhandled Control Code");
1765 UNREACHABLE();
1766 }
1767 break; 1734 break;
1768 case OpCode::Id::LOP32I: { 1735 case OpCode::Id::LOP32I: {
1736 UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc,
1737 "LOP32I Generates an unhandled Control Code");
1738
1769 if (instr.alu.lop32i.invert_a) 1739 if (instr.alu.lop32i.invert_a)
1770 op_a = "~(" + op_a + ')'; 1740 op_a = "~(" + op_a + ')';
1771 1741
@@ -1775,16 +1745,11 @@ private:
1775 WriteLogicOperation(instr.gpr0, instr.alu.lop32i.operation, op_a, op_b, 1745 WriteLogicOperation(instr.gpr0, instr.alu.lop32i.operation, op_a, op_b,
1776 Tegra::Shader::PredicateResultMode::None, 1746 Tegra::Shader::PredicateResultMode::None,
1777 Tegra::Shader::Pred::UnusedIndex); 1747 Tegra::Shader::Pred::UnusedIndex);
1778 if (instr.op_32.generates_cc) {
1779 LOG_CRITICAL(HW_GPU, "LOP32I Generates an unhandled Control Code");
1780 UNREACHABLE();
1781 }
1782 break; 1748 break;
1783 } 1749 }
1784 default: { 1750 default: {
1785 LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticIntegerImmediate instruction: {}", 1751 UNIMPLEMENTED_MSG("Unhandled ArithmeticIntegerImmediate instruction: {}",
1786 opcode->get().GetName()); 1752 opcode->get().GetName());
1787 UNREACHABLE();
1788 } 1753 }
1789 } 1754 }
1790 break; 1755 break;
@@ -1807,6 +1772,9 @@ private:
1807 case OpCode::Id::IADD_C: 1772 case OpCode::Id::IADD_C:
1808 case OpCode::Id::IADD_R: 1773 case OpCode::Id::IADD_R:
1809 case OpCode::Id::IADD_IMM: { 1774 case OpCode::Id::IADD_IMM: {
1775 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1776 "IADD Generates an unhandled Control Code");
1777
1810 if (instr.alu_integer.negate_a) 1778 if (instr.alu_integer.negate_a)
1811 op_a = "-(" + op_a + ')'; 1779 op_a = "-(" + op_a + ')';
1812 1780
@@ -1815,15 +1783,14 @@ private:
1815 1783
1816 regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " + " + op_b, 1, 1, 1784 regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " + " + op_b, 1, 1,
1817 instr.alu.saturate_d); 1785 instr.alu.saturate_d);
1818 if (instr.generates_cc) {
1819 LOG_CRITICAL(HW_GPU, "IADD Generates an unhandled Control Code");
1820 UNREACHABLE();
1821 }
1822 break; 1786 break;
1823 } 1787 }
1824 case OpCode::Id::IADD3_C: 1788 case OpCode::Id::IADD3_C:
1825 case OpCode::Id::IADD3_R: 1789 case OpCode::Id::IADD3_R:
1826 case OpCode::Id::IADD3_IMM: { 1790 case OpCode::Id::IADD3_IMM: {
1791 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1792 "IADD3 Generates an unhandled Control Code");
1793
1827 std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); 1794 std::string op_c = regs.GetRegisterAsInteger(instr.gpr39);
1828 1795
1829 auto apply_height = [](auto height, auto& oprand) { 1796 auto apply_height = [](auto height, auto& oprand) {
@@ -1837,9 +1804,8 @@ private:
1837 oprand = "((" + oprand + ") >> 16)"; 1804 oprand = "((" + oprand + ") >> 16)";
1838 break; 1805 break;
1839 default: 1806 default:
1840 LOG_CRITICAL(HW_GPU, "Unhandled IADD3 height: {}", 1807 UNIMPLEMENTED_MSG("Unhandled IADD3 height: {}",
1841 static_cast<u32>(height.Value())); 1808 static_cast<u32>(height.Value()));
1842 UNREACHABLE();
1843 } 1809 }
1844 }; 1810 };
1845 1811
@@ -1880,16 +1846,14 @@ private:
1880 } 1846 }
1881 1847
1882 regs.SetRegisterToInteger(instr.gpr0, true, 0, result, 1, 1); 1848 regs.SetRegisterToInteger(instr.gpr0, true, 0, result, 1, 1);
1883
1884 if (instr.generates_cc) {
1885 LOG_CRITICAL(HW_GPU, "IADD3 Generates an unhandled Control Code");
1886 UNREACHABLE();
1887 }
1888 break; 1849 break;
1889 } 1850 }
1890 case OpCode::Id::ISCADD_C: 1851 case OpCode::Id::ISCADD_C:
1891 case OpCode::Id::ISCADD_R: 1852 case OpCode::Id::ISCADD_R:
1892 case OpCode::Id::ISCADD_IMM: { 1853 case OpCode::Id::ISCADD_IMM: {
1854 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1855 "ISCADD Generates an unhandled Control Code");
1856
1893 if (instr.alu_integer.negate_a) 1857 if (instr.alu_integer.negate_a)
1894 op_a = "-(" + op_a + ')'; 1858 op_a = "-(" + op_a + ')';
1895 1859
@@ -1900,10 +1864,6 @@ private:
1900 1864
1901 regs.SetRegisterToInteger(instr.gpr0, true, 0, 1865 regs.SetRegisterToInteger(instr.gpr0, true, 0,
1902 "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1); 1866 "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1);
1903 if (instr.generates_cc) {
1904 LOG_CRITICAL(HW_GPU, "ISCADD Generates an unhandled Control Code");
1905 UNREACHABLE();
1906 }
1907 break; 1867 break;
1908 } 1868 }
1909 case OpCode::Id::POPC_C: 1869 case OpCode::Id::POPC_C:
@@ -1927,6 +1887,8 @@ private:
1927 case OpCode::Id::LOP_C: 1887 case OpCode::Id::LOP_C:
1928 case OpCode::Id::LOP_R: 1888 case OpCode::Id::LOP_R:
1929 case OpCode::Id::LOP_IMM: { 1889 case OpCode::Id::LOP_IMM: {
1890 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "LOP Generates an unhandled Control Code");
1891
1930 if (instr.alu.lop.invert_a) 1892 if (instr.alu.lop.invert_a)
1931 op_a = "~(" + op_a + ')'; 1893 op_a = "~(" + op_a + ')';
1932 1894
@@ -1935,15 +1897,14 @@ private:
1935 1897
1936 WriteLogicOperation(instr.gpr0, instr.alu.lop.operation, op_a, op_b, 1898 WriteLogicOperation(instr.gpr0, instr.alu.lop.operation, op_a, op_b,
1937 instr.alu.lop.pred_result_mode, instr.alu.lop.pred48); 1899 instr.alu.lop.pred_result_mode, instr.alu.lop.pred48);
1938 if (instr.generates_cc) {
1939 LOG_CRITICAL(HW_GPU, "LOP Generates an unhandled Control Code");
1940 UNREACHABLE();
1941 }
1942 break; 1900 break;
1943 } 1901 }
1944 case OpCode::Id::LOP3_C: 1902 case OpCode::Id::LOP3_C:
1945 case OpCode::Id::LOP3_R: 1903 case OpCode::Id::LOP3_R:
1946 case OpCode::Id::LOP3_IMM: { 1904 case OpCode::Id::LOP3_IMM: {
1905 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1906 "LOP3 Generates an unhandled Control Code");
1907
1947 const std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); 1908 const std::string op_c = regs.GetRegisterAsInteger(instr.gpr39);
1948 std::string lut; 1909 std::string lut;
1949 1910
@@ -1954,17 +1915,15 @@ private:
1954 } 1915 }
1955 1916
1956 WriteLop3Instruction(instr.gpr0, op_a, op_b, op_c, lut); 1917 WriteLop3Instruction(instr.gpr0, op_a, op_b, op_c, lut);
1957 if (instr.generates_cc) {
1958 LOG_CRITICAL(HW_GPU, "LOP3 Generates an unhandled Control Code");
1959 UNREACHABLE();
1960 }
1961 break; 1918 break;
1962 } 1919 }
1963 case OpCode::Id::IMNMX_C: 1920 case OpCode::Id::IMNMX_C:
1964 case OpCode::Id::IMNMX_R: 1921 case OpCode::Id::IMNMX_R:
1965 case OpCode::Id::IMNMX_IMM: { 1922 case OpCode::Id::IMNMX_IMM: {
1966 ASSERT_MSG(instr.imnmx.exchange == Tegra::Shader::IMinMaxExchange::None, 1923 UNIMPLEMENTED_IF(instr.imnmx.exchange != Tegra::Shader::IMinMaxExchange::None);
1967 "Unimplemented"); 1924 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
1925 "IMNMX Generates an unhandled Control Code");
1926
1968 const std::string condition = 1927 const std::string condition =
1969 GetPredicateCondition(instr.imnmx.pred, instr.imnmx.negate_pred != 0); 1928 GetPredicateCondition(instr.imnmx.pred, instr.imnmx.negate_pred != 0);
1970 const std::string parameters = op_a + ',' + op_b; 1929 const std::string parameters = op_a + ',' + op_b;
@@ -1972,10 +1931,6 @@ private:
1972 '(' + condition + ") ? min(" + parameters + ") : max(" + 1931 '(' + condition + ") ? min(" + parameters + ") : max(" +
1973 parameters + ')', 1932 parameters + ')',
1974 1, 1); 1933 1, 1);
1975 if (instr.generates_cc) {
1976 LOG_CRITICAL(HW_GPU, "IMNMX Generates an unhandled Control Code");
1977 UNREACHABLE();
1978 }
1979 break; 1934 break;
1980 } 1935 }
1981 case OpCode::Id::LEA_R2: 1936 case OpCode::Id::LEA_R2:
@@ -2030,24 +1985,19 @@ private:
2030 op_b = regs.GetRegisterAsInteger(instr.gpr8); 1985 op_b = regs.GetRegisterAsInteger(instr.gpr8);
2031 op_a = std::to_string(instr.lea.imm.entry_a); 1986 op_a = std::to_string(instr.lea.imm.entry_a);
2032 op_c = std::to_string(instr.lea.imm.entry_b); 1987 op_c = std::to_string(instr.lea.imm.entry_b);
2033 LOG_CRITICAL(HW_GPU, "Unhandled LEA subinstruction: {}", 1988 UNIMPLEMENTED_MSG("Unhandled LEA subinstruction: {}", opcode->get().GetName());
2034 opcode->get().GetName());
2035 UNREACHABLE();
2036 } 1989 }
2037 } 1990 }
2038 if (instr.lea.pred48 != static_cast<u64>(Pred::UnusedIndex)) { 1991 UNIMPLEMENTED_IF_MSG(instr.lea.pred48 != static_cast<u64>(Pred::UnusedIndex),
2039 LOG_ERROR(HW_GPU, "Unhandled LEA Predicate"); 1992 "Unhandled LEA Predicate");
2040 UNREACHABLE();
2041 }
2042 const std::string value = '(' + op_a + " + (" + op_b + "*(1 << " + op_c + ")))"; 1993 const std::string value = '(' + op_a + " + (" + op_b + "*(1 << " + op_c + ")))";
2043 regs.SetRegisterToInteger(instr.gpr0, true, 0, value, 1, 1); 1994 regs.SetRegisterToInteger(instr.gpr0, true, 0, value, 1, 1);
2044 1995
2045 break; 1996 break;
2046 } 1997 }
2047 default: { 1998 default: {
2048 LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}", 1999 UNIMPLEMENTED_MSG("Unhandled ArithmeticInteger instruction: {}",
2049 opcode->get().GetName()); 2000 opcode->get().GetName());
2050 UNREACHABLE();
2051 } 2001 }
2052 } 2002 }
2053 2003
@@ -2056,7 +2006,7 @@ private:
2056 case OpCode::Type::ArithmeticHalf: { 2006 case OpCode::Type::ArithmeticHalf: {
2057 if (opcode->get().GetId() == OpCode::Id::HADD2_C || 2007 if (opcode->get().GetId() == OpCode::Id::HADD2_C ||
2058 opcode->get().GetId() == OpCode::Id::HADD2_R) { 2008 opcode->get().GetId() == OpCode::Id::HADD2_R) {
2059 ASSERT_MSG(instr.alu_half.ftz == 0, "Unimplemented"); 2009 UNIMPLEMENTED_IF(instr.alu_half.ftz != 0);
2060 } 2010 }
2061 const bool negate_a = 2011 const bool negate_a =
2062 opcode->get().GetId() != OpCode::Id::HMUL2_R && instr.alu_half.negate_a != 0; 2012 opcode->get().GetId() != OpCode::Id::HMUL2_R && instr.alu_half.negate_a != 0;
@@ -2094,9 +2044,8 @@ private:
2094 case OpCode::Id::HMUL2_R: 2044 case OpCode::Id::HMUL2_R:
2095 return '(' + op_a + " * " + op_b + ')'; 2045 return '(' + op_a + " * " + op_b + ')';
2096 default: 2046 default:
2097 LOG_CRITICAL(HW_GPU, "Unhandled half float instruction: {}", 2047 UNIMPLEMENTED_MSG("Unhandled half float instruction: {}",
2098 opcode->get().GetName()); 2048 opcode->get().GetName());
2099 UNREACHABLE();
2100 return std::string("0"); 2049 return std::string("0");
2101 } 2050 }
2102 }(); 2051 }();
@@ -2107,10 +2056,10 @@ private:
2107 } 2056 }
2108 case OpCode::Type::ArithmeticHalfImmediate: { 2057 case OpCode::Type::ArithmeticHalfImmediate: {
2109 if (opcode->get().GetId() == OpCode::Id::HADD2_IMM) { 2058 if (opcode->get().GetId() == OpCode::Id::HADD2_IMM) {
2110 ASSERT_MSG(instr.alu_half_imm.ftz == 0, "Unimplemented"); 2059 UNIMPLEMENTED_IF(instr.alu_half_imm.ftz != 0);
2111 } else { 2060 } else {
2112 ASSERT_MSG(instr.alu_half_imm.precision == Tegra::Shader::HalfPrecision::None, 2061 UNIMPLEMENTED_IF(instr.alu_half_imm.precision !=
2113 "Unimplemented"); 2062 Tegra::Shader::HalfPrecision::None);
2114 } 2063 }
2115 2064
2116 const std::string op_a = GetHalfFloat( 2065 const std::string op_a = GetHalfFloat(
@@ -2140,11 +2089,13 @@ private:
2140 std::string op_b = instr.ffma.negate_b ? "-" : ""; 2089 std::string op_b = instr.ffma.negate_b ? "-" : "";
2141 std::string op_c = instr.ffma.negate_c ? "-" : ""; 2090 std::string op_c = instr.ffma.negate_c ? "-" : "";
2142 2091
2143 ASSERT_MSG(instr.ffma.cc == 0, "FFMA cc not implemented"); 2092 UNIMPLEMENTED_IF_MSG(instr.ffma.cc != 0, "FFMA cc not implemented");
2144 ASSERT_MSG(instr.ffma.tab5980_0 == 1, "FFMA tab5980_0({}) not implemented", 2093 UNIMPLEMENTED_IF_MSG(
2145 instr.ffma.tab5980_0.Value()); // Seems to be 1 by default based on SMO 2094 instr.ffma.tab5980_0 != 1, "FFMA tab5980_0({}) not implemented",
2146 ASSERT_MSG(instr.ffma.tab5980_1 == 0, "FFMA tab5980_1({}) not implemented", 2095 instr.ffma.tab5980_0.Value()); // Seems to be 1 by default based on SMO
2147 instr.ffma.tab5980_1.Value()); 2096 UNIMPLEMENTED_IF_MSG(instr.ffma.tab5980_1 != 0, "FFMA tab5980_1({}) not implemented",
2097 instr.ffma.tab5980_1.Value());
2098 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "FFMA Generates an unhandled Control Code");
2148 2099
2149 switch (opcode->get().GetId()) { 2100 switch (opcode->get().GetId()) {
2150 case OpCode::Id::FFMA_CR: { 2101 case OpCode::Id::FFMA_CR: {
@@ -2170,27 +2121,19 @@ private:
2170 break; 2121 break;
2171 } 2122 }
2172 default: { 2123 default: {
2173 LOG_CRITICAL(HW_GPU, "Unhandled FFMA instruction: {}", opcode->get().GetName()); 2124 UNIMPLEMENTED_MSG("Unhandled FFMA instruction: {}", opcode->get().GetName());
2174 UNREACHABLE();
2175 } 2125 }
2176 } 2126 }
2177 2127
2178 regs.SetRegisterToFloat(instr.gpr0, 0, "fma(" + op_a + ", " + op_b + ", " + op_c + ')', 2128 regs.SetRegisterToFloat(instr.gpr0, 0, "fma(" + op_a + ", " + op_b + ", " + op_c + ')',
2179 1, 1, instr.alu.saturate_d, 0, true); 2129 1, 1, instr.alu.saturate_d, 0, true);
2180 if (instr.generates_cc) {
2181 LOG_CRITICAL(HW_GPU, "FFMA Generates an unhandled Control Code");
2182 UNREACHABLE();
2183 }
2184
2185 break; 2130 break;
2186 } 2131 }
2187 case OpCode::Type::Hfma2: { 2132 case OpCode::Type::Hfma2: {
2188 if (opcode->get().GetId() == OpCode::Id::HFMA2_RR) { 2133 if (opcode->get().GetId() == OpCode::Id::HFMA2_RR) {
2189 ASSERT_MSG(instr.hfma2.rr.precision == Tegra::Shader::HalfPrecision::None, 2134 UNIMPLEMENTED_IF(instr.hfma2.rr.precision != Tegra::Shader::HalfPrecision::None);
2190 "Unimplemented");
2191 } else { 2135 } else {
2192 ASSERT_MSG(instr.hfma2.precision == Tegra::Shader::HalfPrecision::None, 2136 UNIMPLEMENTED_IF(instr.hfma2.precision != Tegra::Shader::HalfPrecision::None);
2193 "Unimplemented");
2194 } 2137 }
2195 const bool saturate = opcode->get().GetId() == OpCode::Id::HFMA2_RR 2138 const bool saturate = opcode->get().GetId() == OpCode::Id::HFMA2_RR
2196 ? instr.hfma2.rr.saturate != 0 2139 ? instr.hfma2.rr.saturate != 0
@@ -2240,7 +2183,7 @@ private:
2240 case OpCode::Type::Conversion: { 2183 case OpCode::Type::Conversion: {
2241 switch (opcode->get().GetId()) { 2184 switch (opcode->get().GetId()) {
2242 case OpCode::Id::I2I_R: { 2185 case OpCode::Id::I2I_R: {
2243 ASSERT_MSG(!instr.conversion.selector, "Unimplemented"); 2186 UNIMPLEMENTED_IF(instr.conversion.selector);
2244 2187
2245 std::string op_a = regs.GetRegisterAsInteger( 2188 std::string op_a = regs.GetRegisterAsInteger(
2246 instr.gpr20, 0, instr.conversion.is_input_signed, instr.conversion.src_size); 2189 instr.gpr20, 0, instr.conversion.is_input_signed, instr.conversion.src_size);
@@ -2260,8 +2203,9 @@ private:
2260 } 2203 }
2261 case OpCode::Id::I2F_R: 2204 case OpCode::Id::I2F_R:
2262 case OpCode::Id::I2F_C: { 2205 case OpCode::Id::I2F_C: {
2263 ASSERT_MSG(instr.conversion.dest_size == Register::Size::Word, "Unimplemented"); 2206 UNIMPLEMENTED_IF(instr.conversion.dest_size != Register::Size::Word);
2264 ASSERT_MSG(!instr.conversion.selector, "Unimplemented"); 2207 UNIMPLEMENTED_IF(instr.conversion.selector);
2208 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "I2F Generates an unhandled Control Code");
2265 2209
2266 std::string op_a{}; 2210 std::string op_a{};
2267 2211
@@ -2286,16 +2230,12 @@ private:
2286 } 2230 }
2287 2231
2288 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); 2232 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1);
2289
2290 if (instr.generates_cc) {
2291 LOG_CRITICAL(HW_GPU, "I2F Generates an unhandled Control Code");
2292 UNREACHABLE();
2293 }
2294 break; 2233 break;
2295 } 2234 }
2296 case OpCode::Id::F2F_R: { 2235 case OpCode::Id::F2F_R: {
2297 ASSERT_MSG(instr.conversion.dest_size == Register::Size::Word, "Unimplemented"); 2236 UNIMPLEMENTED_IF(instr.conversion.dest_size != Register::Size::Word);
2298 ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented"); 2237 UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word);
2238 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "F2F Generates an unhandled Control Code");
2299 std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); 2239 std::string op_a = regs.GetRegisterAsFloat(instr.gpr20);
2300 2240
2301 if (instr.conversion.abs_a) { 2241 if (instr.conversion.abs_a) {
@@ -2322,23 +2262,18 @@ private:
2322 op_a = "trunc(" + op_a + ')'; 2262 op_a = "trunc(" + op_a + ')';
2323 break; 2263 break;
2324 default: 2264 default:
2325 LOG_CRITICAL(HW_GPU, "Unimplemented f2f rounding mode {}", 2265 UNIMPLEMENTED_MSG("Unimplemented F2F rounding mode {}",
2326 static_cast<u32>(instr.conversion.f2f.rounding.Value())); 2266 static_cast<u32>(instr.conversion.f2f.rounding.Value()));
2327 UNREACHABLE();
2328 break; 2267 break;
2329 } 2268 }
2330 2269
2331 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1, instr.alu.saturate_d); 2270 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1, instr.alu.saturate_d);
2332
2333 if (instr.generates_cc) {
2334 LOG_CRITICAL(HW_GPU, "F2F Generates an unhandled Control Code");
2335 UNREACHABLE();
2336 }
2337 break; 2271 break;
2338 } 2272 }
2339 case OpCode::Id::F2I_R: 2273 case OpCode::Id::F2I_R:
2340 case OpCode::Id::F2I_C: { 2274 case OpCode::Id::F2I_C: {
2341 ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented"); 2275 UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word);
2276 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "F2I Generates an unhandled Control Code");
2342 std::string op_a{}; 2277 std::string op_a{};
2343 2278
2344 if (instr.is_b_gpr) { 2279 if (instr.is_b_gpr) {
@@ -2369,9 +2304,8 @@ private:
2369 op_a = "trunc(" + op_a + ')'; 2304 op_a = "trunc(" + op_a + ')';
2370 break; 2305 break;
2371 default: 2306 default:
2372 LOG_CRITICAL(HW_GPU, "Unimplemented f2i rounding mode {}", 2307 UNIMPLEMENTED_MSG("Unimplemented F2I rounding mode {}",
2373 static_cast<u32>(instr.conversion.f2i.rounding.Value())); 2308 static_cast<u32>(instr.conversion.f2i.rounding.Value()));
2374 UNREACHABLE();
2375 break; 2309 break;
2376 } 2310 }
2377 2311
@@ -2383,16 +2317,10 @@ private:
2383 2317
2384 regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1, 2318 regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1,
2385 1, false, 0, instr.conversion.dest_size); 2319 1, false, 0, instr.conversion.dest_size);
2386 if (instr.generates_cc) {
2387 LOG_CRITICAL(HW_GPU, "F2I Generates an unhandled Control Code");
2388 UNREACHABLE();
2389 }
2390 break; 2320 break;
2391 } 2321 }
2392 default: { 2322 default: {
2393 LOG_CRITICAL(HW_GPU, "Unhandled conversion instruction: {}", 2323 UNIMPLEMENTED_MSG("Unhandled conversion instruction: {}", opcode->get().GetName());
2394 opcode->get().GetName());
2395 UNREACHABLE();
2396 } 2324 }
2397 } 2325 }
2398 break; 2326 break;
@@ -2401,10 +2329,10 @@ private:
2401 switch (opcode->get().GetId()) { 2329 switch (opcode->get().GetId()) {
2402 case OpCode::Id::LD_A: { 2330 case OpCode::Id::LD_A: {
2403 // Note: Shouldn't this be interp mode flat? As in no interpolation made. 2331 // Note: Shouldn't this be interp mode flat? As in no interpolation made.
2404 ASSERT_MSG(instr.gpr8.Value() == Register::ZeroIndex, 2332 UNIMPLEMENTED_IF_MSG(instr.gpr8.Value() != Register::ZeroIndex,
2405 "Indirect attribute loads are not supported"); 2333 "Indirect attribute loads are not supported");
2406 ASSERT_MSG((instr.attribute.fmt20.immediate.Value() % sizeof(u32)) == 0, 2334 UNIMPLEMENTED_IF_MSG((instr.attribute.fmt20.immediate.Value() % sizeof(u32)) != 0,
2407 "Unaligned attribute loads are not supported"); 2335 "Unaligned attribute loads are not supported");
2408 2336
2409 Tegra::Shader::IpaMode input_mode{Tegra::Shader::IpaInterpMode::Perspective, 2337 Tegra::Shader::IpaMode input_mode{Tegra::Shader::IpaInterpMode::Perspective,
2410 Tegra::Shader::IpaSampleMode::Default}; 2338 Tegra::Shader::IpaSampleMode::Default};
@@ -2431,7 +2359,7 @@ private:
2431 break; 2359 break;
2432 } 2360 }
2433 case OpCode::Id::LD_C: { 2361 case OpCode::Id::LD_C: {
2434 ASSERT_MSG(instr.ld_c.unknown == 0, "Unimplemented"); 2362 UNIMPLEMENTED_IF(instr.ld_c.unknown != 0);
2435 2363
2436 // Add an extra scope and declare the index register inside to prevent 2364 // Add an extra scope and declare the index register inside to prevent
2437 // overwriting it in case it is used as an output of the LD instruction. 2365 // overwriting it in case it is used as an output of the LD instruction.
@@ -2459,9 +2387,8 @@ private:
2459 break; 2387 break;
2460 } 2388 }
2461 default: 2389 default:
2462 LOG_CRITICAL(HW_GPU, "Unhandled type: {}", 2390 UNIMPLEMENTED_MSG("Unhandled type: {}",
2463 static_cast<unsigned>(instr.ld_c.type.Value())); 2391 static_cast<unsigned>(instr.ld_c.type.Value()));
2464 UNREACHABLE();
2465 } 2392 }
2466 2393
2467 --shader.scope; 2394 --shader.scope;
@@ -2469,6 +2396,9 @@ private:
2469 break; 2396 break;
2470 } 2397 }
2471 case OpCode::Id::LD_L: { 2398 case OpCode::Id::LD_L: {
2399 UNIMPLEMENTED_IF_MSG(instr.ld_l.unknown == 1, "LD_L Unhandled mode: {}",
2400 static_cast<unsigned>(instr.ld_l.unknown.Value()));
2401
2472 // Add an extra scope and declare the index register inside to prevent 2402 // Add an extra scope and declare the index register inside to prevent
2473 // overwriting it in case it is used as an output of the LD instruction. 2403 // overwriting it in case it is used as an output of the LD instruction.
2474 shader.AddLine('{'); 2404 shader.AddLine('{');
@@ -2481,20 +2411,13 @@ private:
2481 2411
2482 const std::string op_a = regs.GetLocalMemoryAsFloat("index"); 2412 const std::string op_a = regs.GetLocalMemoryAsFloat("index");
2483 2413
2484 if (instr.ld_l.unknown != 1) {
2485 LOG_CRITICAL(HW_GPU, "LD_L Unhandled mode: {}",
2486 static_cast<unsigned>(instr.ld_l.unknown.Value()));
2487 UNREACHABLE();
2488 }
2489
2490 switch (instr.ldst_sl.type.Value()) { 2414 switch (instr.ldst_sl.type.Value()) {
2491 case Tegra::Shader::StoreType::Bytes32: 2415 case Tegra::Shader::StoreType::Bytes32:
2492 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); 2416 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1);
2493 break; 2417 break;
2494 default: 2418 default:
2495 LOG_CRITICAL(HW_GPU, "LD_L Unhandled type: {}", 2419 UNIMPLEMENTED_MSG("LD_L Unhandled type: {}",
2496 static_cast<unsigned>(instr.ldst_sl.type.Value())); 2420 static_cast<unsigned>(instr.ldst_sl.type.Value()));
2497 UNREACHABLE();
2498 } 2421 }
2499 2422
2500 --shader.scope; 2423 --shader.scope;
@@ -2502,10 +2425,10 @@ private:
2502 break; 2425 break;
2503 } 2426 }
2504 case OpCode::Id::ST_A: { 2427 case OpCode::Id::ST_A: {
2505 ASSERT_MSG(instr.gpr8.Value() == Register::ZeroIndex, 2428 UNIMPLEMENTED_IF_MSG(instr.gpr8.Value() != Register::ZeroIndex,
2506 "Indirect attribute loads are not supported"); 2429 "Indirect attribute loads are not supported");
2507 ASSERT_MSG((instr.attribute.fmt20.immediate.Value() % sizeof(u32)) == 0, 2430 UNIMPLEMENTED_IF_MSG((instr.attribute.fmt20.immediate.Value() % sizeof(u32)) != 0,
2508 "Unaligned attribute loads are not supported"); 2431 "Unaligned attribute loads are not supported");
2509 2432
2510 u64 next_element = instr.attribute.fmt20.element; 2433 u64 next_element = instr.attribute.fmt20.element;
2511 u64 next_index = static_cast<u64>(instr.attribute.fmt20.index.Value()); 2434 u64 next_index = static_cast<u64>(instr.attribute.fmt20.index.Value());
@@ -2530,6 +2453,9 @@ private:
2530 break; 2453 break;
2531 } 2454 }
2532 case OpCode::Id::ST_L: { 2455 case OpCode::Id::ST_L: {
2456 UNIMPLEMENTED_IF_MSG(instr.st_l.unknown == 0, "ST_L Unhandled mode: {}",
2457 static_cast<unsigned>(instr.st_l.unknown.Value()));
2458
2533 // Add an extra scope and declare the index register inside to prevent 2459 // Add an extra scope and declare the index register inside to prevent
2534 // overwriting it in case it is used as an output of the LD instruction. 2460 // overwriting it in case it is used as an output of the LD instruction.
2535 shader.AddLine('{'); 2461 shader.AddLine('{');
@@ -2540,20 +2466,13 @@ private:
2540 2466
2541 shader.AddLine("uint index = (" + op + " / 4);"); 2467 shader.AddLine("uint index = (" + op + " / 4);");
2542 2468
2543 if (instr.st_l.unknown != 0) {
2544 LOG_CRITICAL(HW_GPU, "ST_L Unhandled mode: {}",
2545 static_cast<unsigned>(instr.st_l.unknown.Value()));
2546 UNREACHABLE();
2547 }
2548
2549 switch (instr.ldst_sl.type.Value()) { 2469 switch (instr.ldst_sl.type.Value()) {
2550 case Tegra::Shader::StoreType::Bytes32: 2470 case Tegra::Shader::StoreType::Bytes32:
2551 regs.SetLocalMemoryAsFloat("index", regs.GetRegisterAsFloat(instr.gpr0)); 2471 regs.SetLocalMemoryAsFloat("index", regs.GetRegisterAsFloat(instr.gpr0));
2552 break; 2472 break;
2553 default: 2473 default:
2554 LOG_CRITICAL(HW_GPU, "ST_L Unhandled type: {}", 2474 UNIMPLEMENTED_MSG("ST_L Unhandled type: {}",
2555 static_cast<unsigned>(instr.ldst_sl.type.Value())); 2475 static_cast<unsigned>(instr.ldst_sl.type.Value()));
2556 UNREACHABLE();
2557 } 2476 }
2558 2477
2559 --shader.scope; 2478 --shader.scope;
@@ -2565,10 +2484,10 @@ private:
2565 std::string coord; 2484 std::string coord;
2566 const bool is_array = instr.tex.array != 0; 2485 const bool is_array = instr.tex.array != 0;
2567 2486
2568 ASSERT_MSG(!instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2487 UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
2569 "NODEP is not implemented"); 2488 "NODEP is not implemented");
2570 ASSERT_MSG(!instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), 2489 UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI),
2571 "AOFFI is not implemented"); 2490 "AOFFI is not implemented");
2572 2491
2573 const bool depth_compare = 2492 const bool depth_compare =
2574 instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); 2493 instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC);
@@ -2634,9 +2553,8 @@ private:
2634 break; 2553 break;
2635 } 2554 }
2636 default: 2555 default:
2637 LOG_CRITICAL(HW_GPU, "Unhandled coordinates number {}", 2556 UNIMPLEMENTED_MSG("Unhandled coordinates number {}",
2638 static_cast<u32>(num_coordinates)); 2557 static_cast<u32>(num_coordinates));
2639 UNREACHABLE();
2640 2558
2641 // Fallback to interpreting as a 2D texture for now 2559 // Fallback to interpreting as a 2D texture for now
2642 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); 2560 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
@@ -2694,9 +2612,8 @@ private:
2694 } 2612 }
2695 default: { 2613 default: {
2696 texture = "texture(" + sampler + ", coords)"; 2614 texture = "texture(" + sampler + ", coords)";
2697 LOG_CRITICAL(HW_GPU, "Unhandled texture process mode {}", 2615 UNIMPLEMENTED_MSG("Unhandled texture process mode {}",
2698 static_cast<u32>(instr.tex.GetTextureProcessMode())); 2616 static_cast<u32>(instr.tex.GetTextureProcessMode()));
2699 UNREACHABLE();
2700 } 2617 }
2701 } 2618 }
2702 if (!depth_compare) { 2619 if (!depth_compare) {
@@ -2721,8 +2638,8 @@ private:
2721 Tegra::Shader::TextureType texture_type{instr.texs.GetTextureType()}; 2638 Tegra::Shader::TextureType texture_type{instr.texs.GetTextureType()};
2722 bool is_array{instr.texs.IsArrayTexture()}; 2639 bool is_array{instr.texs.IsArrayTexture()};
2723 2640
2724 ASSERT_MSG(!instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2641 UNIMPLEMENTED_IF_MSG(instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
2725 "NODEP is not implemented"); 2642 "NODEP is not implemented");
2726 2643
2727 const bool depth_compare = 2644 const bool depth_compare =
2728 instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); 2645 instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC);
@@ -2761,9 +2678,8 @@ private:
2761 break; 2678 break;
2762 } 2679 }
2763 default: 2680 default:
2764 LOG_CRITICAL(HW_GPU, "Unhandled coordinates number {}", 2681 UNIMPLEMENTED_MSG("Unhandled coordinates number {}",
2765 static_cast<u32>(num_coordinates)); 2682 static_cast<u32>(num_coordinates));
2766 UNREACHABLE();
2767 2683
2768 // Fallback to interpreting as a 2D texture for now 2684 // Fallback to interpreting as a 2D texture for now
2769 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); 2685 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
@@ -2795,9 +2711,8 @@ private:
2795 } 2711 }
2796 default: { 2712 default: {
2797 texture = "texture(" + sampler + ", coords)"; 2713 texture = "texture(" + sampler + ", coords)";
2798 LOG_CRITICAL(HW_GPU, "Unhandled texture process mode {}", 2714 UNIMPLEMENTED_MSG("Unhandled texture process mode {}",
2799 static_cast<u32>(instr.texs.GetTextureProcessMode())); 2715 static_cast<u32>(instr.texs.GetTextureProcessMode()));
2800 UNREACHABLE();
2801 } 2716 }
2802 } 2717 }
2803 if (!depth_compare) { 2718 if (!depth_compare) {
@@ -2815,12 +2730,12 @@ private:
2815 ASSERT(texture_type == Tegra::Shader::TextureType::Texture2D); 2730 ASSERT(texture_type == Tegra::Shader::TextureType::Texture2D);
2816 ASSERT(is_array == false); 2731 ASSERT(is_array == false);
2817 2732
2818 ASSERT_MSG(!instr.tlds.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2733 UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
2819 "NODEP is not implemented"); 2734 "NODEP is not implemented");
2820 ASSERT_MSG(!instr.tlds.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), 2735 UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI),
2821 "AOFFI is not implemented"); 2736 "AOFFI is not implemented");
2822 ASSERT_MSG(!instr.tlds.UsesMiscMode(Tegra::Shader::TextureMiscMode::MZ), 2737 UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(Tegra::Shader::TextureMiscMode::MZ),
2823 "MZ is not implemented"); 2738 "MZ is not implemented");
2824 2739
2825 u32 op_c_offset = 0; 2740 u32 op_c_offset = 0;
2826 2741
@@ -2831,21 +2746,16 @@ private:
2831 break; 2746 break;
2832 } 2747 }
2833 case Tegra::Shader::TextureType::Texture2D: { 2748 case Tegra::Shader::TextureType::Texture2D: {
2834 if (is_array) { 2749 UNIMPLEMENTED_IF_MSG(is_array, "Unhandled 2d array texture");
2835 LOG_CRITICAL(HW_GPU, "Unhandled 2d array texture"); 2750
2836 UNREACHABLE(); 2751 const std::string x = regs.GetRegisterAsInteger(instr.gpr8);
2837 } else { 2752 const std::string y = regs.GetRegisterAsInteger(instr.gpr20);
2838 const std::string x = regs.GetRegisterAsInteger(instr.gpr8); 2753 coord = "ivec2 coords = ivec2(" + x + ", " + y + ");";
2839 const std::string y = regs.GetRegisterAsInteger(instr.gpr20); 2754 op_c_offset = 1;
2840 coord = "ivec2 coords = ivec2(" + x + ", " + y + ");";
2841 op_c_offset = 1;
2842 }
2843 break; 2755 break;
2844 } 2756 }
2845 default: 2757 default:
2846 LOG_CRITICAL(HW_GPU, "Unhandled texture type {}", 2758 UNIMPLEMENTED_MSG("Unhandled texture type {}", static_cast<u32>(texture_type));
2847 static_cast<u32>(texture_type));
2848 UNREACHABLE();
2849 } 2759 }
2850 const std::string sampler = 2760 const std::string sampler =
2851 GetSampler(instr.sampler, texture_type, is_array, false); 2761 GetSampler(instr.sampler, texture_type, is_array, false);
@@ -2863,9 +2773,8 @@ private:
2863 } 2773 }
2864 default: { 2774 default: {
2865 texture = "texelFetch(" + sampler + ", coords, 0)"; 2775 texture = "texelFetch(" + sampler + ", coords, 0)";
2866 LOG_CRITICAL(HW_GPU, "Unhandled texture process mode {}", 2776 UNIMPLEMENTED_MSG("Unhandled texture process mode {}",
2867 static_cast<u32>(instr.tlds.GetTextureProcessMode())); 2777 static_cast<u32>(instr.tlds.GetTextureProcessMode()));
2868 UNREACHABLE();
2869 } 2778 }
2870 } 2779 }
2871 WriteTexsInstruction(instr, coord, texture); 2780 WriteTexsInstruction(instr, coord, texture);
@@ -2876,14 +2785,14 @@ private:
2876 ASSERT(instr.tld4.array == 0); 2785 ASSERT(instr.tld4.array == 0);
2877 std::string coord; 2786 std::string coord;
2878 2787
2879 ASSERT_MSG(!instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2788 UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
2880 "NODEP is not implemented"); 2789 "NODEP is not implemented");
2881 ASSERT_MSG(!instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), 2790 UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI),
2882 "AOFFI is not implemented"); 2791 "AOFFI is not implemented");
2883 ASSERT_MSG(!instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::NDV), 2792 UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::NDV),
2884 "NDV is not implemented"); 2793 "NDV is not implemented");
2885 ASSERT_MSG(!instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::PTP), 2794 UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::PTP),
2886 "PTP is not implemented"); 2795 "PTP is not implemented");
2887 const bool depth_compare = 2796 const bool depth_compare =
2888 instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); 2797 instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC);
2889 auto texture_type = instr.tld4.texture_type.Value(); 2798 auto texture_type = instr.tld4.texture_type.Value();
@@ -2906,9 +2815,8 @@ private:
2906 break; 2815 break;
2907 } 2816 }
2908 default: 2817 default:
2909 LOG_CRITICAL(HW_GPU, "Unhandled coordinates number {}", 2818 UNIMPLEMENTED_MSG("Unhandled coordinates number {}",
2910 static_cast<u32>(num_coordinates)); 2819 static_cast<u32>(num_coordinates));
2911 UNREACHABLE();
2912 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); 2820 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2913 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2821 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2914 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 2822 coord = "vec2 coords = vec2(" + x + ", " + y + ");";
@@ -2942,10 +2850,12 @@ private:
2942 break; 2850 break;
2943 } 2851 }
2944 case OpCode::Id::TLD4S: { 2852 case OpCode::Id::TLD4S: {
2945 ASSERT_MSG(!instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2853 UNIMPLEMENTED_IF_MSG(
2946 "NODEP is not implemented"); 2854 instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
2947 ASSERT_MSG(!instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), 2855 "NODEP is not implemented");
2948 "AOFFI is not implemented"); 2856 UNIMPLEMENTED_IF_MSG(
2857 instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI),
2858 "AOFFI is not implemented");
2949 2859
2950 const bool depth_compare = 2860 const bool depth_compare =
2951 instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); 2861 instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC);
@@ -2973,8 +2883,8 @@ private:
2973 break; 2883 break;
2974 } 2884 }
2975 case OpCode::Id::TXQ: { 2885 case OpCode::Id::TXQ: {
2976 ASSERT_MSG(!instr.txq.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2886 UNIMPLEMENTED_IF_MSG(instr.txq.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
2977 "NODEP is not implemented"); 2887 "NODEP is not implemented");
2978 2888
2979 // TODO: the new commits on the texture refactor, change the way samplers work. 2889 // TODO: the new commits on the texture refactor, change the way samplers work.
2980 // Sadly, not all texture instructions specify the type of texture their sampler 2890 // Sadly, not all texture instructions specify the type of texture their sampler
@@ -2988,18 +2898,17 @@ private:
2988 break; 2898 break;
2989 } 2899 }
2990 default: { 2900 default: {
2991 LOG_CRITICAL(HW_GPU, "Unhandled texture query type: {}", 2901 UNIMPLEMENTED_MSG("Unhandled texture query type: {}",
2992 static_cast<u32>(instr.txq.query_type.Value())); 2902 static_cast<u32>(instr.txq.query_type.Value()));
2993 UNREACHABLE();
2994 } 2903 }
2995 } 2904 }
2996 break; 2905 break;
2997 } 2906 }
2998 case OpCode::Id::TMML: { 2907 case OpCode::Id::TMML: {
2999 ASSERT_MSG(!instr.tmml.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), 2908 UNIMPLEMENTED_IF_MSG(instr.tmml.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
3000 "NODEP is not implemented"); 2909 "NODEP is not implemented");
3001 ASSERT_MSG(!instr.tmml.UsesMiscMode(Tegra::Shader::TextureMiscMode::NDV), 2910 UNIMPLEMENTED_IF_MSG(instr.tmml.UsesMiscMode(Tegra::Shader::TextureMiscMode::NDV),
3002 "NDV is not implemented"); 2911 "NDV is not implemented");
3003 2912
3004 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); 2913 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
3005 const bool is_array = instr.tmml.array != 0; 2914 const bool is_array = instr.tmml.array != 0;
@@ -3021,9 +2930,7 @@ private:
3021 break; 2930 break;
3022 } 2931 }
3023 default: 2932 default:
3024 LOG_CRITICAL(HW_GPU, "Unhandled texture type {}", 2933 UNIMPLEMENTED_MSG("Unhandled texture type {}", static_cast<u32>(texture_type));
3025 static_cast<u32>(texture_type));
3026 UNREACHABLE();
3027 2934
3028 // Fallback to interpreting as a 2D texture for now 2935 // Fallback to interpreting as a 2D texture for now
3029 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2936 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
@@ -3046,8 +2953,7 @@ private:
3046 break; 2953 break;
3047 } 2954 }
3048 default: { 2955 default: {
3049 LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->get().GetName()); 2956 UNIMPLEMENTED_MSG("Unhandled memory instruction: {}", opcode->get().GetName());
3050 UNREACHABLE();
3051 } 2957 }
3052 } 2958 }
3053 break; 2959 break;
@@ -3133,7 +3039,7 @@ private:
3133 break; 3039 break;
3134 } 3040 }
3135 case OpCode::Type::HalfSetPredicate: { 3041 case OpCode::Type::HalfSetPredicate: {
3136 ASSERT_MSG(instr.hsetp2.ftz == 0, "Unimplemented"); 3042 UNIMPLEMENTED_IF(instr.hsetp2.ftz != 0);
3137 3043
3138 const std::string op_a = 3044 const std::string op_a =
3139 GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.hsetp2.type_a, 3045 GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.hsetp2.type_a,
@@ -3178,6 +3084,8 @@ private:
3178 break; 3084 break;
3179 } 3085 }
3180 case OpCode::Type::PredicateSetRegister: { 3086 case OpCode::Type::PredicateSetRegister: {
3087 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "PSET Generates an unhandled Control Code");
3088
3181 const std::string op_a = 3089 const std::string op_a =
3182 GetPredicateCondition(instr.pset.pred12, instr.pset.neg_pred12 != 0); 3090 GetPredicateCondition(instr.pset.pred12, instr.pset.neg_pred12 != 0);
3183 const std::string op_b = 3091 const std::string op_b =
@@ -3198,12 +3106,6 @@ private:
3198 const std::string value = '(' + result + ") ? 1.0 : 0.0"; 3106 const std::string value = '(' + result + ") ? 1.0 : 0.0";
3199 regs.SetRegisterToFloat(instr.gpr0, 0, value, 1, 1); 3107 regs.SetRegisterToFloat(instr.gpr0, 0, value, 1, 1);
3200 } 3108 }
3201
3202 if (instr.generates_cc) {
3203 LOG_CRITICAL(HW_GPU, "PSET Generates an unhandled Control Code");
3204 UNREACHABLE();
3205 }
3206
3207 break; 3109 break;
3208 } 3110 }
3209 case OpCode::Type::PredicateSetPredicate: { 3111 case OpCode::Type::PredicateSetPredicate: {
@@ -3253,9 +3155,7 @@ private:
3253 break; 3155 break;
3254 } 3156 }
3255 default: { 3157 default: {
3256 LOG_CRITICAL(HW_GPU, "Unhandled predicate instruction: {}", 3158 UNIMPLEMENTED_MSG("Unhandled predicate instruction: {}", opcode->get().GetName());
3257 opcode->get().GetName());
3258 UNREACHABLE();
3259 } 3159 }
3260 } 3160 }
3261 break; 3161 break;
@@ -3335,7 +3235,7 @@ private:
3335 break; 3235 break;
3336 } 3236 }
3337 case OpCode::Type::HalfSet: { 3237 case OpCode::Type::HalfSet: {
3338 ASSERT_MSG(instr.hset2.ftz == 0, "Unimplemented"); 3238 UNIMPLEMENTED_IF(instr.hset2.ftz != 0);
3339 3239
3340 const std::string op_a = 3240 const std::string op_a =
3341 GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.hset2.type_a, 3241 GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.hset2.type_a,
@@ -3379,15 +3279,16 @@ private:
3379 break; 3279 break;
3380 } 3280 }
3381 case OpCode::Type::Xmad: { 3281 case OpCode::Type::Xmad: {
3382 ASSERT_MSG(!instr.xmad.sign_a, "Unimplemented"); 3282 UNIMPLEMENTED_IF(instr.xmad.sign_a);
3383 ASSERT_MSG(!instr.xmad.sign_b, "Unimplemented"); 3283 UNIMPLEMENTED_IF(instr.xmad.sign_b);
3284 UNIMPLEMENTED_IF_MSG(instr.generates_cc, "XMAD Generates an unhandled Control Code");
3384 3285
3385 std::string op_a{regs.GetRegisterAsInteger(instr.gpr8, 0, instr.xmad.sign_a)}; 3286 std::string op_a{regs.GetRegisterAsInteger(instr.gpr8, 0, instr.xmad.sign_a)};
3386 std::string op_b; 3287 std::string op_b;
3387 std::string op_c; 3288 std::string op_c;
3388 3289
3389 // TODO(bunnei): Needs to be fixed once op_a or op_b is signed 3290 // TODO(bunnei): Needs to be fixed once op_a or op_b is signed
3390 ASSERT_MSG(instr.xmad.sign_a == instr.xmad.sign_b, "Unimplemented"); 3291 UNIMPLEMENTED_IF(instr.xmad.sign_a != instr.xmad.sign_b);
3391 const bool is_signed{instr.xmad.sign_a == 1}; 3292 const bool is_signed{instr.xmad.sign_a == 1};
3392 3293
3393 bool is_merge{}; 3294 bool is_merge{};
@@ -3420,8 +3321,7 @@ private:
3420 break; 3321 break;
3421 } 3322 }
3422 default: { 3323 default: {
3423 LOG_CRITICAL(HW_GPU, "Unhandled XMAD instruction: {}", opcode->get().GetName()); 3324 UNIMPLEMENTED_MSG("Unhandled XMAD instruction: {}", opcode->get().GetName());
3424 UNREACHABLE();
3425 } 3325 }
3426 } 3326 }
3427 3327
@@ -3457,9 +3357,8 @@ private:
3457 op_c = "((" + op_c + ") + (" + src2 + "<< 16))"; 3357 op_c = "((" + op_c + ") + (" + src2 + "<< 16))";
3458 break; 3358 break;
3459 default: { 3359 default: {
3460 LOG_CRITICAL(HW_GPU, "Unhandled XMAD mode: {}", 3360 UNIMPLEMENTED_MSG("Unhandled XMAD mode: {}",
3461 static_cast<u32>(instr.xmad.mode.Value())); 3361 static_cast<u32>(instr.xmad.mode.Value()));
3462 UNREACHABLE();
3463 } 3362 }
3464 } 3363 }
3465 3364
@@ -3469,25 +3368,19 @@ private:
3469 } 3368 }
3470 3369
3471 regs.SetRegisterToInteger(instr.gpr0, is_signed, 0, sum, 1, 1); 3370 regs.SetRegisterToInteger(instr.gpr0, is_signed, 0, sum, 1, 1);
3472 if (instr.generates_cc) {
3473 LOG_CRITICAL(HW_GPU, "XMAD Generates an unhandled Control Code");
3474 UNREACHABLE();
3475 }
3476 break; 3371 break;
3477 } 3372 }
3478 default: { 3373 default: {
3479 switch (opcode->get().GetId()) { 3374 switch (opcode->get().GetId()) {
3480 case OpCode::Id::EXIT: { 3375 case OpCode::Id::EXIT: {
3376 const Tegra::Shader::ControlCode cc = instr.flow_control_code;
3377 UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ControlCode::T,
3378 "EXIT Control Code used: {}", static_cast<u32>(cc));
3379
3481 if (stage == Maxwell3D::Regs::ShaderStage::Fragment) { 3380 if (stage == Maxwell3D::Regs::ShaderStage::Fragment) {
3482 EmitFragmentOutputsWrite(); 3381 EmitFragmentOutputsWrite();
3483 } 3382 }
3484 3383
3485 const Tegra::Shader::ControlCode cc = instr.flow_control_code;
3486 if (cc != Tegra::Shader::ControlCode::T) {
3487 LOG_CRITICAL(HW_GPU, "EXIT Control Code used: {}", static_cast<u32>(cc));
3488 UNREACHABLE();
3489 }
3490
3491 switch (instr.flow.cond) { 3384 switch (instr.flow.cond) {
3492 case Tegra::Shader::FlowCondition::Always: 3385 case Tegra::Shader::FlowCondition::Always:
3493 shader.AddLine("return true;"); 3386 shader.AddLine("return true;");
@@ -3502,26 +3395,24 @@ private:
3502 case Tegra::Shader::FlowCondition::Fcsm_Tr: 3395 case Tegra::Shader::FlowCondition::Fcsm_Tr:
3503 // TODO(bunnei): What is this used for? If we assume this conditon is not 3396 // TODO(bunnei): What is this used for? If we assume this conditon is not
3504 // satisifed, dual vertex shaders in Farming Simulator make more sense 3397 // satisifed, dual vertex shaders in Farming Simulator make more sense
3505 LOG_CRITICAL(HW_GPU, "Skipping unknown FlowCondition::Fcsm_Tr"); 3398 UNIMPLEMENTED_MSG("Skipping unknown FlowCondition::Fcsm_Tr");
3506 break; 3399 break;
3507 3400
3508 default: 3401 default:
3509 LOG_CRITICAL(HW_GPU, "Unhandled flow condition: {}", 3402 UNIMPLEMENTED_MSG("Unhandled flow condition: {}",
3510 static_cast<u32>(instr.flow.cond.Value())); 3403 static_cast<u32>(instr.flow.cond.Value()));
3511 UNREACHABLE();
3512 } 3404 }
3513 break; 3405 break;
3514 } 3406 }
3515 case OpCode::Id::KIL: { 3407 case OpCode::Id::KIL: {
3516 ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); 3408 UNIMPLEMENTED_IF(instr.flow.cond != Tegra::Shader::FlowCondition::Always);
3409
3410 const Tegra::Shader::ControlCode cc = instr.flow_control_code;
3411 UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ControlCode::T,
3412 "KIL Control Code used: {}", static_cast<u32>(cc));
3517 3413
3518 // Enclose "discard" in a conditional, so that GLSL compilation does not complain 3414 // Enclose "discard" in a conditional, so that GLSL compilation does not complain
3519 // about unexecuted instructions that may follow this. 3415 // about unexecuted instructions that may follow this.
3520 const Tegra::Shader::ControlCode cc = instr.flow_control_code;
3521 if (cc != Tegra::Shader::ControlCode::T) {
3522 LOG_CRITICAL(HW_GPU, "KIL Control Code used: {}", static_cast<u32>(cc));
3523 UNREACHABLE();
3524 }
3525 shader.AddLine("if (true) {"); 3416 shader.AddLine("if (true) {");
3526 ++shader.scope; 3417 ++shader.scope;
3527 shader.AddLine("discard;"); 3418 shader.AddLine("discard;");
@@ -3531,7 +3422,8 @@ private:
3531 break; 3422 break;
3532 } 3423 }
3533 case OpCode::Id::OUT_R: { 3424 case OpCode::Id::OUT_R: {
3534 ASSERT(instr.gpr20.Value() == Register::ZeroIndex); 3425 UNIMPLEMENTED_IF_MSG(instr.gpr20.Value() != Register::ZeroIndex,
3426 "Stream buffer is not supported");
3535 ASSERT_MSG(stage == Maxwell3D::Regs::ShaderStage::Geometry, 3427 ASSERT_MSG(stage == Maxwell3D::Regs::ShaderStage::Geometry,
3536 "OUT is expected to be used in a geometry shader."); 3428 "OUT is expected to be used in a geometry shader.");
3537 3429
@@ -3558,18 +3450,17 @@ private:
3558 break; 3450 break;
3559 } 3451 }
3560 default: { 3452 default: {
3561 LOG_CRITICAL(HW_GPU, "Unhandled system move: {}", 3453 UNIMPLEMENTED_MSG("Unhandled system move: {}",
3562 static_cast<u32>(instr.sys20.Value())); 3454 static_cast<u32>(instr.sys20.Value()));
3563 UNREACHABLE();
3564 } 3455 }
3565 } 3456 }
3566 break; 3457 break;
3567 } 3458 }
3568 case OpCode::Id::ISBERD: { 3459 case OpCode::Id::ISBERD: {
3569 ASSERT(instr.isberd.o == 0); 3460 UNIMPLEMENTED_IF(instr.isberd.o != 0);
3570 ASSERT(instr.isberd.skew == 0); 3461 UNIMPLEMENTED_IF(instr.isberd.skew != 0);
3571 ASSERT(instr.isberd.shift == Tegra::Shader::IsberdShift::None); 3462 UNIMPLEMENTED_IF(instr.isberd.shift != Tegra::Shader::IsberdShift::None);
3572 ASSERT(instr.isberd.mode == Tegra::Shader::IsberdMode::None); 3463 UNIMPLEMENTED_IF(instr.isberd.mode != Tegra::Shader::IsberdMode::None);
3573 ASSERT_MSG(stage == Maxwell3D::Regs::ShaderStage::Geometry, 3464 ASSERT_MSG(stage == Maxwell3D::Regs::ShaderStage::Geometry,
3574 "ISBERD is expected to be used in a geometry shader."); 3465 "ISBERD is expected to be used in a geometry shader.");
3575 LOG_WARNING(HW_GPU, "ISBERD instruction is incomplete"); 3466 LOG_WARNING(HW_GPU, "ISBERD instruction is incomplete");
@@ -3577,13 +3468,13 @@ private:
3577 break; 3468 break;
3578 } 3469 }
3579 case OpCode::Id::BRA: { 3470 case OpCode::Id::BRA: {
3580 ASSERT_MSG(instr.bra.constant_buffer == 0, 3471 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0,
3581 "BRA with constant buffers are not implemented"); 3472 "BRA with constant buffers are not implemented");
3473
3582 const Tegra::Shader::ControlCode cc = instr.flow_control_code; 3474 const Tegra::Shader::ControlCode cc = instr.flow_control_code;
3583 if (cc != Tegra::Shader::ControlCode::T) { 3475 UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ControlCode::T,
3584 LOG_CRITICAL(HW_GPU, "BRA Control Code used: {}", static_cast<u32>(cc)); 3476 "BRA Control Code used: {}", static_cast<u32>(cc));
3585 UNREACHABLE(); 3477
3586 }
3587 const u32 target = offset + instr.bra.GetBranchTarget(); 3478 const u32 target = offset + instr.bra.GetBranchTarget();
3588 shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }"); 3479 shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }");
3589 break; 3480 break;
@@ -3606,7 +3497,8 @@ private:
3606 // The SSY opcode tells the GPU where to re-converge divergent execution paths, it 3497 // The SSY opcode tells the GPU where to re-converge divergent execution paths, it
3607 // sets the target of the jump that the SYNC instruction will make. The SSY opcode 3498 // sets the target of the jump that the SYNC instruction will make. The SSY opcode
3608 // has a similar structure to the BRA opcode. 3499 // has a similar structure to the BRA opcode.
3609 ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer flow is not supported"); 3500 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0,
3501 "Constant buffer flow is not supported");
3610 3502
3611 const u32 target = offset + instr.bra.GetBranchTarget(); 3503 const u32 target = offset + instr.bra.GetBranchTarget();
3612 EmitPushToFlowStack(target); 3504 EmitPushToFlowStack(target);
@@ -3616,19 +3508,19 @@ private:
3616 // PBK pushes to a stack the address where BRK will jump to. This shares stack with 3508 // PBK pushes to a stack the address where BRK will jump to. This shares stack with
3617 // SSY but using SYNC on a PBK address will kill the shader execution. We don't 3509 // SSY but using SYNC on a PBK address will kill the shader execution. We don't
3618 // emulate this because it's very unlikely a driver will emit such invalid shader. 3510 // emulate this because it's very unlikely a driver will emit such invalid shader.
3619 ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer PBK is not supported"); 3511 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0,
3512 "Constant buffer PBK is not supported");
3620 3513
3621 const u32 target = offset + instr.bra.GetBranchTarget(); 3514 const u32 target = offset + instr.bra.GetBranchTarget();
3622 EmitPushToFlowStack(target); 3515 EmitPushToFlowStack(target);
3623 break; 3516 break;
3624 } 3517 }
3625 case OpCode::Id::SYNC: { 3518 case OpCode::Id::SYNC: {
3626 // The SYNC opcode jumps to the address previously set by the SSY opcode
3627 const Tegra::Shader::ControlCode cc = instr.flow_control_code; 3519 const Tegra::Shader::ControlCode cc = instr.flow_control_code;
3628 if (cc != Tegra::Shader::ControlCode::T) { 3520 UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ControlCode::T,
3629 LOG_CRITICAL(HW_GPU, "SYNC Control Code used: {}", static_cast<u32>(cc)); 3521 "SYNC Control Code used: {}", static_cast<u32>(cc));
3630 UNREACHABLE(); 3522
3631 } 3523 // The SYNC opcode jumps to the address previously set by the SSY opcode
3632 EmitPopFromFlowStack(); 3524 EmitPopFromFlowStack();
3633 break; 3525 break;
3634 } 3526 }
@@ -3636,8 +3528,7 @@ private:
3636 // The BRK opcode jumps to the address previously set by the PBK opcode 3528 // The BRK opcode jumps to the address previously set by the PBK opcode
3637 const Tegra::Shader::ControlCode cc = instr.flow_control_code; 3529 const Tegra::Shader::ControlCode cc = instr.flow_control_code;
3638 if (cc != Tegra::Shader::ControlCode::T) { 3530 if (cc != Tegra::Shader::ControlCode::T) {
3639 LOG_CRITICAL(HW_GPU, "BRK Control Code used: {}", static_cast<u32>(cc)); 3531 UNIMPLEMENTED_MSG("BRK Control Code used: {}", static_cast<u32>(cc));
3640 UNREACHABLE();
3641 } 3532 }
3642 EmitPopFromFlowStack(); 3533 EmitPopFromFlowStack();
3643 break; 3534 break;
@@ -3669,8 +3560,7 @@ private:
3669 instr.vmad.saturate == 1, 0, Register::Size::Word, 3560 instr.vmad.saturate == 1, 0, Register::Size::Word,
3670 instr.vmad.cc); 3561 instr.vmad.cc);
3671 if (instr.generates_cc) { 3562 if (instr.generates_cc) {
3672 LOG_CRITICAL(HW_GPU, "VMAD Generates an unhandled Control Code"); 3563 UNIMPLEMENTED_MSG("VMAD Generates an unhandled Control Code");
3673 UNREACHABLE();
3674 } 3564 }
3675 3565
3676 break; 3566 break;
@@ -3699,10 +3589,7 @@ private:
3699 } 3589 }
3700 break; 3590 break;
3701 } 3591 }
3702 default: { 3592 default: { UNIMPLEMENTED_MSG("Unhandled instruction: {}", opcode->get().GetName()); }
3703 LOG_CRITICAL(HW_GPU, "Unhandled instruction: {}", opcode->get().GetName());
3704 UNREACHABLE();
3705 }
3706 } 3593 }
3707 3594
3708 break; 3595 break;