summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/engines/shader_bytecode.h152
1 files changed, 79 insertions, 73 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 1640207a7..37d17efdc 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -34,29 +34,29 @@ struct Register {
34 34
35 constexpr Register(u64 value_) : value(value_) {} 35 constexpr Register(u64 value_) : value(value_) {}
36 36
37 constexpr operator u64() const { 37 [[nodiscard]] constexpr operator u64() const {
38 return value; 38 return value;
39 } 39 }
40 40
41 template <typename T> 41 template <typename T>
42 constexpr u64 operator-(const T& oth) const { 42 [[nodiscard]] constexpr u64 operator-(const T& oth) const {
43 return value - oth; 43 return value - oth;
44 } 44 }
45 45
46 template <typename T> 46 template <typename T>
47 constexpr u64 operator&(const T& oth) const { 47 [[nodiscard]] constexpr u64 operator&(const T& oth) const {
48 return value & oth; 48 return value & oth;
49 } 49 }
50 50
51 constexpr u64 operator&(const Register& oth) const { 51 [[nodiscard]] constexpr u64 operator&(const Register& oth) const {
52 return value & oth.value; 52 return value & oth.value;
53 } 53 }
54 54
55 constexpr u64 operator~() const { 55 [[nodiscard]] constexpr u64 operator~() const {
56 return ~value; 56 return ~value;
57 } 57 }
58 58
59 u64 GetSwizzledIndex(u64 elem) const { 59 [[nodiscard]] u64 GetSwizzledIndex(u64 elem) const {
60 elem = (value + elem) & 3; 60 elem = (value + elem) & 3;
61 return (value & ~3) + elem; 61 return (value & ~3) + elem;
62 } 62 }
@@ -107,7 +107,7 @@ union Attribute {
107 BitField<31, 1, u64> patch; 107 BitField<31, 1, u64> patch;
108 BitField<47, 3, AttributeSize> size; 108 BitField<47, 3, AttributeSize> size;
109 109
110 bool IsPhysical() const { 110 [[nodiscard]] bool IsPhysical() const {
111 return patch == 0 && element == 0 && static_cast<u64>(index.Value()) == 0; 111 return patch == 0 && element == 0 && static_cast<u64>(index.Value()) == 0;
112 } 112 }
113 } fmt20; 113 } fmt20;
@@ -505,14 +505,14 @@ struct IpaMode {
505 IpaInterpMode interpolation_mode; 505 IpaInterpMode interpolation_mode;
506 IpaSampleMode sampling_mode; 506 IpaSampleMode sampling_mode;
507 507
508 bool operator==(const IpaMode& a) const { 508 [[nodiscard]] bool operator==(const IpaMode& a) const {
509 return std::tie(interpolation_mode, sampling_mode) == 509 return std::tie(interpolation_mode, sampling_mode) ==
510 std::tie(a.interpolation_mode, a.sampling_mode); 510 std::tie(a.interpolation_mode, a.sampling_mode);
511 } 511 }
512 bool operator!=(const IpaMode& a) const { 512 [[nodiscard]] bool operator!=(const IpaMode& a) const {
513 return !operator==(a); 513 return !operator==(a);
514 } 514 }
515 bool operator<(const IpaMode& a) const { 515 [[nodiscard]] bool operator<(const IpaMode& a) const {
516 return std::tie(interpolation_mode, sampling_mode) < 516 return std::tie(interpolation_mode, sampling_mode) <
517 std::tie(a.interpolation_mode, a.sampling_mode); 517 std::tie(a.interpolation_mode, a.sampling_mode);
518 } 518 }
@@ -661,7 +661,7 @@ union Instruction {
661 constexpr Instruction(u64 value_) : value{value_} {} 661 constexpr Instruction(u64 value_) : value{value_} {}
662 constexpr Instruction(const Instruction& instr) : value(instr.value) {} 662 constexpr Instruction(const Instruction& instr) : value(instr.value) {}
663 663
664 constexpr bool Bit(u64 offset) const { 664 [[nodiscard]] constexpr bool Bit(u64 offset) const {
665 return ((value >> offset) & 1) != 0; 665 return ((value >> offset) & 1) != 0;
666 } 666 }
667 667
@@ -746,34 +746,34 @@ union Instruction {
746 BitField<28, 8, u64> imm_lut28; 746 BitField<28, 8, u64> imm_lut28;
747 BitField<48, 8, u64> imm_lut48; 747 BitField<48, 8, u64> imm_lut48;
748 748
749 u32 GetImmLut28() const { 749 [[nodiscard]] u32 GetImmLut28() const {
750 return static_cast<u32>(imm_lut28); 750 return static_cast<u32>(imm_lut28);
751 } 751 }
752 752
753 u32 GetImmLut48() const { 753 [[nodiscard]] u32 GetImmLut48() const {
754 return static_cast<u32>(imm_lut48); 754 return static_cast<u32>(imm_lut48);
755 } 755 }
756 } lop3; 756 } lop3;
757 757
758 u16 GetImm20_16() const { 758 [[nodiscard]] u16 GetImm20_16() const {
759 return static_cast<u16>(imm20_16); 759 return static_cast<u16>(imm20_16);
760 } 760 }
761 761
762 u32 GetImm20_19() const { 762 [[nodiscard]] u32 GetImm20_19() const {
763 u32 imm{static_cast<u32>(imm20_19)}; 763 u32 imm{static_cast<u32>(imm20_19)};
764 imm <<= 12; 764 imm <<= 12;
765 imm |= negate_imm ? 0x80000000 : 0; 765 imm |= negate_imm ? 0x80000000 : 0;
766 return imm; 766 return imm;
767 } 767 }
768 768
769 u32 GetImm20_32() const { 769 [[nodiscard]] u32 GetImm20_32() const {
770 return static_cast<u32>(imm20_32); 770 return static_cast<u32>(imm20_32);
771 } 771 }
772 772
773 s32 GetSignedImm20_20() const { 773 [[nodiscard]] s32 GetSignedImm20_20() const {
774 u32 immediate = static_cast<u32>(imm20_19 | (negate_imm << 19)); 774 const auto immediate = static_cast<u32>(imm20_19 | (negate_imm << 19));
775 // Sign extend the 20-bit value. 775 // Sign extend the 20-bit value.
776 u32 mask = 1U << (20 - 1); 776 const auto mask = 1U << (20 - 1);
777 return static_cast<s32>((immediate ^ mask) - mask); 777 return static_cast<s32>((immediate ^ mask) - mask);
778 } 778 }
779 } alu; 779 } alu;
@@ -857,7 +857,7 @@ union Instruction {
857 BitField<56, 1, u64> second_negate; 857 BitField<56, 1, u64> second_negate;
858 BitField<30, 9, u64> second; 858 BitField<30, 9, u64> second;
859 859
860 u32 PackImmediates() const { 860 [[nodiscard]] u32 PackImmediates() const {
861 // Immediates are half floats shifted. 861 // Immediates are half floats shifted.
862 constexpr u32 imm_shift = 6; 862 constexpr u32 imm_shift = 6;
863 return static_cast<u32>((first << imm_shift) | (second << (16 + imm_shift))); 863 return static_cast<u32>((first << imm_shift) | (second << (16 + imm_shift)));
@@ -1033,7 +1033,7 @@ union Instruction {
1033 BitField<28, 2, AtomicType> type; 1033 BitField<28, 2, AtomicType> type;
1034 BitField<30, 22, s64> offset; 1034 BitField<30, 22, s64> offset;
1035 1035
1036 s32 GetImmediateOffset() const { 1036 [[nodiscard]] s32 GetImmediateOffset() const {
1037 return static_cast<s32>(offset << 2); 1037 return static_cast<s32>(offset << 2);
1038 } 1038 }
1039 } atoms; 1039 } atoms;
@@ -1215,7 +1215,7 @@ union Instruction {
1215 BitField<39, 4, u64> rounding; 1215 BitField<39, 4, u64> rounding;
1216 // H0, H1 extract for F16 missing 1216 // H0, H1 extract for F16 missing
1217 BitField<41, 1, u64> selector; // Guessed as some games set it, TODO: reverse this value 1217 BitField<41, 1, u64> selector; // Guessed as some games set it, TODO: reverse this value
1218 F2fRoundingOp GetRoundingMode() const { 1218 [[nodiscard]] F2fRoundingOp GetRoundingMode() const {
1219 constexpr u64 rounding_mask = 0x0B; 1219 constexpr u64 rounding_mask = 0x0B;
1220 return static_cast<F2fRoundingOp>(rounding.Value() & rounding_mask); 1220 return static_cast<F2fRoundingOp>(rounding.Value() & rounding_mask);
1221 } 1221 }
@@ -1239,15 +1239,15 @@ union Instruction {
1239 BitField<54, 1, u64> aoffi_flag; 1239 BitField<54, 1, u64> aoffi_flag;
1240 BitField<55, 3, TextureProcessMode> process_mode; 1240 BitField<55, 3, TextureProcessMode> process_mode;
1241 1241
1242 bool IsComponentEnabled(std::size_t component) const { 1242 [[nodiscard]] bool IsComponentEnabled(std::size_t component) const {
1243 return ((1ull << component) & component_mask) != 0; 1243 return ((1ULL << component) & component_mask) != 0;
1244 } 1244 }
1245 1245
1246 TextureProcessMode GetTextureProcessMode() const { 1246 [[nodiscard]] TextureProcessMode GetTextureProcessMode() const {
1247 return process_mode; 1247 return process_mode;
1248 } 1248 }
1249 1249
1250 bool UsesMiscMode(TextureMiscMode mode) const { 1250 [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const {
1251 switch (mode) { 1251 switch (mode) {
1252 case TextureMiscMode::DC: 1252 case TextureMiscMode::DC:
1253 return dc_flag != 0; 1253 return dc_flag != 0;
@@ -1271,15 +1271,15 @@ union Instruction {
1271 BitField<36, 1, u64> aoffi_flag; 1271 BitField<36, 1, u64> aoffi_flag;
1272 BitField<37, 3, TextureProcessMode> process_mode; 1272 BitField<37, 3, TextureProcessMode> process_mode;
1273 1273
1274 bool IsComponentEnabled(std::size_t component) const { 1274 [[nodiscard]] bool IsComponentEnabled(std::size_t component) const {
1275 return ((1ULL << component) & component_mask) != 0; 1275 return ((1ULL << component) & component_mask) != 0;
1276 } 1276 }
1277 1277
1278 TextureProcessMode GetTextureProcessMode() const { 1278 [[nodiscard]] TextureProcessMode GetTextureProcessMode() const {
1279 return process_mode; 1279 return process_mode;
1280 } 1280 }
1281 1281
1282 bool UsesMiscMode(TextureMiscMode mode) const { 1282 [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const {
1283 switch (mode) { 1283 switch (mode) {
1284 case TextureMiscMode::DC: 1284 case TextureMiscMode::DC:
1285 return dc_flag != 0; 1285 return dc_flag != 0;
@@ -1299,7 +1299,7 @@ union Instruction {
1299 BitField<31, 4, u64> component_mask; 1299 BitField<31, 4, u64> component_mask;
1300 BitField<49, 1, u64> nodep_flag; 1300 BitField<49, 1, u64> nodep_flag;
1301 1301
1302 bool UsesMiscMode(TextureMiscMode mode) const { 1302 [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const {
1303 switch (mode) { 1303 switch (mode) {
1304 case TextureMiscMode::NODEP: 1304 case TextureMiscMode::NODEP:
1305 return nodep_flag != 0; 1305 return nodep_flag != 0;
@@ -1309,7 +1309,7 @@ union Instruction {
1309 return false; 1309 return false;
1310 } 1310 }
1311 1311
1312 bool IsComponentEnabled(std::size_t component) const { 1312 [[nodiscard]] bool IsComponentEnabled(std::size_t component) const {
1313 return ((1ULL << component) & component_mask) != 0; 1313 return ((1ULL << component) & component_mask) != 0;
1314 } 1314 }
1315 } txq; 1315 } txq;
@@ -1321,11 +1321,11 @@ union Instruction {
1321 BitField<35, 1, u64> ndv_flag; 1321 BitField<35, 1, u64> ndv_flag;
1322 BitField<49, 1, u64> nodep_flag; 1322 BitField<49, 1, u64> nodep_flag;
1323 1323
1324 bool IsComponentEnabled(std::size_t component) const { 1324 [[nodiscard]] bool IsComponentEnabled(std::size_t component) const {
1325 return ((1ull << component) & component_mask) != 0; 1325 return ((1ULL << component) & component_mask) != 0;
1326 } 1326 }
1327 1327
1328 bool UsesMiscMode(TextureMiscMode mode) const { 1328 [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const {
1329 switch (mode) { 1329 switch (mode) {
1330 case TextureMiscMode::NDV: 1330 case TextureMiscMode::NDV:
1331 return (ndv_flag != 0); 1331 return (ndv_flag != 0);
@@ -1347,7 +1347,7 @@ union Instruction {
1347 BitField<54, 2, u64> offset_mode; 1347 BitField<54, 2, u64> offset_mode;
1348 BitField<56, 2, u64> component; 1348 BitField<56, 2, u64> component;
1349 1349
1350 bool UsesMiscMode(TextureMiscMode mode) const { 1350 [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const {
1351 switch (mode) { 1351 switch (mode) {
1352 case TextureMiscMode::NDV: 1352 case TextureMiscMode::NDV:
1353 return ndv_flag != 0; 1353 return ndv_flag != 0;
@@ -1373,7 +1373,7 @@ union Instruction {
1373 BitField<33, 2, u64> offset_mode; 1373 BitField<33, 2, u64> offset_mode;
1374 BitField<37, 2, u64> component; 1374 BitField<37, 2, u64> component;
1375 1375
1376 bool UsesMiscMode(TextureMiscMode mode) const { 1376 [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const {
1377 switch (mode) { 1377 switch (mode) {
1378 case TextureMiscMode::NDV: 1378 case TextureMiscMode::NDV:
1379 return ndv_flag != 0; 1379 return ndv_flag != 0;
@@ -1399,7 +1399,7 @@ union Instruction {
1399 BitField<52, 2, u64> component; 1399 BitField<52, 2, u64> component;
1400 BitField<55, 1, u64> fp16_flag; 1400 BitField<55, 1, u64> fp16_flag;
1401 1401
1402 bool UsesMiscMode(TextureMiscMode mode) const { 1402 [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const {
1403 switch (mode) { 1403 switch (mode) {
1404 case TextureMiscMode::DC: 1404 case TextureMiscMode::DC:
1405 return dc_flag != 0; 1405 return dc_flag != 0;
@@ -1422,16 +1422,20 @@ union Instruction {
1422 BitField<53, 4, u64> texture_info; 1422 BitField<53, 4, u64> texture_info;
1423 BitField<59, 1, u64> fp32_flag; 1423 BitField<59, 1, u64> fp32_flag;
1424 1424
1425 TextureType GetTextureType() const { 1425 [[nodiscard]] TextureType GetTextureType() const {
1426 // The TEXS instruction has a weird encoding for the texture type. 1426 // The TEXS instruction has a weird encoding for the texture type.
1427 if (texture_info == 0) 1427 if (texture_info == 0) {
1428 return TextureType::Texture1D; 1428 return TextureType::Texture1D;
1429 if (texture_info >= 1 && texture_info <= 9) 1429 }
1430 if (texture_info >= 1 && texture_info <= 9) {
1430 return TextureType::Texture2D; 1431 return TextureType::Texture2D;
1431 if (texture_info >= 10 && texture_info <= 11) 1432 }
1433 if (texture_info >= 10 && texture_info <= 11) {
1432 return TextureType::Texture3D; 1434 return TextureType::Texture3D;
1433 if (texture_info >= 12 && texture_info <= 13) 1435 }
1436 if (texture_info >= 12 && texture_info <= 13) {
1434 return TextureType::TextureCube; 1437 return TextureType::TextureCube;
1438 }
1435 1439
1436 LOG_CRITICAL(HW_GPU, "Unhandled texture_info: {}", 1440 LOG_CRITICAL(HW_GPU, "Unhandled texture_info: {}",
1437 static_cast<u32>(texture_info.Value())); 1441 static_cast<u32>(texture_info.Value()));
@@ -1439,7 +1443,7 @@ union Instruction {
1439 return TextureType::Texture1D; 1443 return TextureType::Texture1D;
1440 } 1444 }
1441 1445
1442 TextureProcessMode GetTextureProcessMode() const { 1446 [[nodiscard]] TextureProcessMode GetTextureProcessMode() const {
1443 switch (texture_info) { 1447 switch (texture_info) {
1444 case 0: 1448 case 0:
1445 case 2: 1449 case 2:
@@ -1458,7 +1462,7 @@ union Instruction {
1458 return TextureProcessMode::None; 1462 return TextureProcessMode::None;
1459 } 1463 }
1460 1464
1461 bool UsesMiscMode(TextureMiscMode mode) const { 1465 [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const {
1462 switch (mode) { 1466 switch (mode) {
1463 case TextureMiscMode::DC: 1467 case TextureMiscMode::DC:
1464 return (texture_info >= 4 && texture_info <= 6) || texture_info == 9; 1468 return (texture_info >= 4 && texture_info <= 6) || texture_info == 9;
@@ -1470,16 +1474,16 @@ union Instruction {
1470 return false; 1474 return false;
1471 } 1475 }
1472 1476
1473 bool IsArrayTexture() const { 1477 [[nodiscard]] bool IsArrayTexture() const {
1474 // TEXS only supports Texture2D arrays. 1478 // TEXS only supports Texture2D arrays.
1475 return texture_info >= 7 && texture_info <= 9; 1479 return texture_info >= 7 && texture_info <= 9;
1476 } 1480 }
1477 1481
1478 bool HasTwoDestinations() const { 1482 [[nodiscard]] bool HasTwoDestinations() const {
1479 return gpr28.Value() != Register::ZeroIndex; 1483 return gpr28.Value() != Register::ZeroIndex;
1480 } 1484 }
1481 1485
1482 bool IsComponentEnabled(std::size_t component) const { 1486 [[nodiscard]] bool IsComponentEnabled(std::size_t component) const {
1483 static constexpr std::array<std::array<u32, 8>, 4> mask_lut{{ 1487 static constexpr std::array<std::array<u32, 8>, 4> mask_lut{{
1484 {}, 1488 {},
1485 {0x1, 0x2, 0x4, 0x8, 0x3, 0x9, 0xa, 0xc}, 1489 {0x1, 0x2, 0x4, 0x8, 0x3, 0x9, 0xa, 0xc},
@@ -1506,7 +1510,7 @@ union Instruction {
1506 BitField<54, 1, u64> cl; 1510 BitField<54, 1, u64> cl;
1507 BitField<55, 1, u64> process_mode; 1511 BitField<55, 1, u64> process_mode;
1508 1512
1509 TextureProcessMode GetTextureProcessMode() const { 1513 [[nodiscard]] TextureProcessMode GetTextureProcessMode() const {
1510 return process_mode == 0 ? TextureProcessMode::LZ : TextureProcessMode::LL; 1514 return process_mode == 0 ? TextureProcessMode::LZ : TextureProcessMode::LL;
1511 } 1515 }
1512 } tld; 1516 } tld;
@@ -1516,7 +1520,7 @@ union Instruction {
1516 BitField<53, 4, u64> texture_info; 1520 BitField<53, 4, u64> texture_info;
1517 BitField<59, 1, u64> fp32_flag; 1521 BitField<59, 1, u64> fp32_flag;
1518 1522
1519 TextureType GetTextureType() const { 1523 [[nodiscard]] TextureType GetTextureType() const {
1520 // The TLDS instruction has a weird encoding for the texture type. 1524 // The TLDS instruction has a weird encoding for the texture type.
1521 if (texture_info <= 1) { 1525 if (texture_info <= 1) {
1522 return TextureType::Texture1D; 1526 return TextureType::Texture1D;
@@ -1535,13 +1539,14 @@ union Instruction {
1535 return TextureType::Texture1D; 1539 return TextureType::Texture1D;
1536 } 1540 }
1537 1541
1538 TextureProcessMode GetTextureProcessMode() const { 1542 [[nodiscard]] TextureProcessMode GetTextureProcessMode() const {
1539 if (texture_info == 1 || texture_info == 5 || texture_info == 12) 1543 if (texture_info == 1 || texture_info == 5 || texture_info == 12) {
1540 return TextureProcessMode::LL; 1544 return TextureProcessMode::LL;
1545 }
1541 return TextureProcessMode::LZ; 1546 return TextureProcessMode::LZ;
1542 } 1547 }
1543 1548
1544 bool UsesMiscMode(TextureMiscMode mode) const { 1549 [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const {
1545 switch (mode) { 1550 switch (mode) {
1546 case TextureMiscMode::AOFFI: 1551 case TextureMiscMode::AOFFI:
1547 return texture_info == 12 || texture_info == 4; 1552 return texture_info == 12 || texture_info == 4;
@@ -1555,7 +1560,7 @@ union Instruction {
1555 return false; 1560 return false;
1556 } 1561 }
1557 1562
1558 bool IsArrayTexture() const { 1563 [[nodiscard]] bool IsArrayTexture() const {
1559 // TEXS only supports Texture2D arrays. 1564 // TEXS only supports Texture2D arrays.
1560 return texture_info == 8; 1565 return texture_info == 8;
1561 } 1566 }
@@ -1567,7 +1572,7 @@ union Instruction {
1567 BitField<35, 1, u64> aoffi_flag; 1572 BitField<35, 1, u64> aoffi_flag;
1568 BitField<49, 1, u64> nodep_flag; 1573 BitField<49, 1, u64> nodep_flag;
1569 1574
1570 bool UsesMiscMode(TextureMiscMode mode) const { 1575 [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const {
1571 switch (mode) { 1576 switch (mode) {
1572 case TextureMiscMode::AOFFI: 1577 case TextureMiscMode::AOFFI:
1573 return aoffi_flag != 0; 1578 return aoffi_flag != 0;
@@ -1591,7 +1596,7 @@ union Instruction {
1591 BitField<20, 3, StoreType> store_data_layout; 1596 BitField<20, 3, StoreType> store_data_layout;
1592 BitField<20, 4, u64> component_mask_selector; 1597 BitField<20, 4, u64> component_mask_selector;
1593 1598
1594 bool IsComponentEnabled(std::size_t component) const { 1599 [[nodiscard]] bool IsComponentEnabled(std::size_t component) const {
1595 ASSERT(mode == SurfaceDataMode::P); 1600 ASSERT(mode == SurfaceDataMode::P);
1596 constexpr u8 R = 0b0001; 1601 constexpr u8 R = 0b0001;
1597 constexpr u8 G = 0b0010; 1602 constexpr u8 G = 0b0010;
@@ -1604,7 +1609,7 @@ union Instruction {
1604 return std::bitset<4>{mask.at(component_mask_selector)}.test(component); 1609 return std::bitset<4>{mask.at(component_mask_selector)}.test(component);
1605 } 1610 }
1606 1611
1607 StoreType GetStoreDataLayout() const { 1612 [[nodiscard]] StoreType GetStoreDataLayout() const {
1608 ASSERT(mode == SurfaceDataMode::D_BA); 1613 ASSERT(mode == SurfaceDataMode::D_BA);
1609 return store_data_layout; 1614 return store_data_layout;
1610 } 1615 }
@@ -1622,7 +1627,7 @@ union Instruction {
1622 BitField<20, 24, u64> target; 1627 BitField<20, 24, u64> target;
1623 BitField<5, 1, u64> constant_buffer; 1628 BitField<5, 1, u64> constant_buffer;
1624 1629
1625 s32 GetBranchTarget() const { 1630 [[nodiscard]] s32 GetBranchTarget() const {
1626 // Sign extend the branch target offset 1631 // Sign extend the branch target offset
1627 const auto mask = 1U << (24 - 1); 1632 const auto mask = 1U << (24 - 1);
1628 const auto target_value = static_cast<u32>(target); 1633 const auto target_value = static_cast<u32>(target);
@@ -1638,7 +1643,7 @@ union Instruction {
1638 BitField<20, 24, u64> target; 1643 BitField<20, 24, u64> target;
1639 BitField<5, 1, u64> constant_buffer; 1644 BitField<5, 1, u64> constant_buffer;
1640 1645
1641 s32 GetBranchExtend() const { 1646 [[nodiscard]] s32 GetBranchExtend() const {
1642 // Sign extend the branch target offset 1647 // Sign extend the branch target offset
1643 const auto mask = 1U << (24 - 1); 1648 const auto mask = 1U << (24 - 1);
1644 const auto target_value = static_cast<u32>(target); 1649 const auto target_value = static_cast<u32>(target);
@@ -1699,7 +1704,7 @@ union Instruction {
1699 BitField<50, 1, u64> is_op_b_register; 1704 BitField<50, 1, u64> is_op_b_register;
1700 BitField<51, 3, VmnmxOperation> operation; 1705 BitField<51, 3, VmnmxOperation> operation;
1701 1706
1702 VmnmxType SourceFormatA() const { 1707 [[nodiscard]] VmnmxType SourceFormatA() const {
1703 switch (src_format_a) { 1708 switch (src_format_a) {
1704 case 0b11: 1709 case 0b11:
1705 return VmnmxType::Bits32; 1710 return VmnmxType::Bits32;
@@ -1710,7 +1715,7 @@ union Instruction {
1710 } 1715 }
1711 } 1716 }
1712 1717
1713 VmnmxType SourceFormatB() const { 1718 [[nodiscard]] VmnmxType SourceFormatB() const {
1714 switch (src_format_b) { 1719 switch (src_format_b) {
1715 case 0b11: 1720 case 0b11:
1716 return VmnmxType::Bits32; 1721 return VmnmxType::Bits32;
@@ -1741,7 +1746,7 @@ union Instruction {
1741 BitField<20, 14, u64> shifted_offset; 1746 BitField<20, 14, u64> shifted_offset;
1742 BitField<34, 5, u64> index; 1747 BitField<34, 5, u64> index;
1743 1748
1744 u64 GetOffset() const { 1749 [[nodiscard]] u64 GetOffset() const {
1745 return shifted_offset * 4; 1750 return shifted_offset * 4;
1746 } 1751 }
1747 } cbuf34; 1752 } cbuf34;
@@ -1750,7 +1755,7 @@ union Instruction {
1750 BitField<20, 16, s64> offset; 1755 BitField<20, 16, s64> offset;
1751 BitField<36, 5, u64> index; 1756 BitField<36, 5, u64> index;
1752 1757
1753 s64 GetOffset() const { 1758 [[nodiscard]] s64 GetOffset() const {
1754 return offset; 1759 return offset;
1755 } 1760 }
1756 } cbuf36; 1761 } cbuf36;
@@ -1999,7 +2004,7 @@ public:
1999 2004
2000 /// Returns whether an opcode has an execution predicate field or not (ie, whether it can be 2005 /// Returns whether an opcode has an execution predicate field or not (ie, whether it can be
2001 /// conditionally executed). 2006 /// conditionally executed).
2002 static bool IsPredicatedInstruction(Id opcode) { 2007 [[nodiscard]] static bool IsPredicatedInstruction(Id opcode) {
2003 // TODO(Subv): Add the rest of unpredicated instructions. 2008 // TODO(Subv): Add the rest of unpredicated instructions.
2004 return opcode != Id::SSY && opcode != Id::PBK; 2009 return opcode != Id::SSY && opcode != Id::PBK;
2005 } 2010 }
@@ -2009,19 +2014,19 @@ public:
2009 constexpr Matcher(const char* const name_, u16 mask_, u16 expected_, Id id_, Type type_) 2014 constexpr Matcher(const char* const name_, u16 mask_, u16 expected_, Id id_, Type type_)
2010 : name{name_}, mask{mask_}, expected{expected_}, id{id_}, type{type_} {} 2015 : name{name_}, mask{mask_}, expected{expected_}, id{id_}, type{type_} {}
2011 2016
2012 constexpr const char* GetName() const { 2017 [[nodiscard]] constexpr const char* GetName() const {
2013 return name; 2018 return name;
2014 } 2019 }
2015 2020
2016 constexpr u16 GetMask() const { 2021 [[nodiscard]] constexpr u16 GetMask() const {
2017 return mask; 2022 return mask;
2018 } 2023 }
2019 2024
2020 constexpr Id GetId() const { 2025 [[nodiscard]] constexpr Id GetId() const {
2021 return id; 2026 return id;
2022 } 2027 }
2023 2028
2024 constexpr Type GetType() const { 2029 [[nodiscard]] constexpr Type GetType() const {
2025 return type; 2030 return type;
2026 } 2031 }
2027 2032
@@ -2030,7 +2035,7 @@ public:
2030 * @param instruction The instruction to test 2035 * @param instruction The instruction to test
2031 * @returns true if the given instruction matches. 2036 * @returns true if the given instruction matches.
2032 */ 2037 */
2033 constexpr bool Matches(u16 instruction) const { 2038 [[nodiscard]] constexpr bool Matches(u16 instruction) const {
2034 return (instruction & mask) == expected; 2039 return (instruction & mask) == expected;
2035 } 2040 }
2036 2041
@@ -2042,7 +2047,8 @@ public:
2042 Type type; 2047 Type type;
2043 }; 2048 };
2044 2049
2045 static std::optional<std::reference_wrapper<const Matcher>> Decode(Instruction instr) { 2050 using DecodeResult = std::optional<std::reference_wrapper<const Matcher>>;
2051 [[nodiscard]] static DecodeResult Decode(Instruction instr) {
2046 static const auto table{GetDecodeTable()}; 2052 static const auto table{GetDecodeTable()};
2047 2053
2048 const auto matches_instruction = [instr](const auto& matcher) { 2054 const auto matches_instruction = [instr](const auto& matcher) {
@@ -2064,7 +2070,7 @@ private:
2064 * A '0' in a bitstring indicates that a zero must be present at that bit position. 2070 * A '0' in a bitstring indicates that a zero must be present at that bit position.
2065 * A '1' in a bitstring indicates that a one must be present at that bit position. 2071 * A '1' in a bitstring indicates that a one must be present at that bit position.
2066 */ 2072 */
2067 static constexpr auto GetMaskAndExpect(const char* const bitstring) { 2073 [[nodiscard]] static constexpr auto GetMaskAndExpect(const char* const bitstring) {
2068 u16 mask = 0, expect = 0; 2074 u16 mask = 0, expect = 0;
2069 for (std::size_t i = 0; i < opcode_bitsize; i++) { 2075 for (std::size_t i = 0; i < opcode_bitsize; i++) {
2070 const std::size_t bit_position = opcode_bitsize - i - 1; 2076 const std::size_t bit_position = opcode_bitsize - i - 1;
@@ -2086,14 +2092,14 @@ private:
2086 2092
2087 public: 2093 public:
2088 /// Creates a matcher that can match and parse instructions based on bitstring. 2094 /// Creates a matcher that can match and parse instructions based on bitstring.
2089 static constexpr auto GetMatcher(const char* const bitstring, Id op, Type type, 2095 [[nodiscard]] static constexpr auto GetMatcher(const char* const bitstring, Id op,
2090 const char* const name) { 2096 Type type, const char* const name) {
2091 const auto [mask, expected] = GetMaskAndExpect(bitstring); 2097 const auto [mask, expected] = GetMaskAndExpect(bitstring);
2092 return Matcher(name, mask, expected, op, type); 2098 return Matcher(name, mask, expected, op, type);
2093 } 2099 }
2094 }; 2100 };
2095 2101
2096 static std::vector<Matcher> GetDecodeTable() { 2102 [[nodiscard]] static std::vector<Matcher> GetDecodeTable() {
2097 std::vector<Matcher> table = { 2103 std::vector<Matcher> table = {
2098#define INST(bitstring, op, type, name) Detail::GetMatcher(bitstring, op, type, name) 2104#define INST(bitstring, op, type, name) Detail::GetMatcher(bitstring, op, type, name)
2099 INST("111000110011----", Id::KIL, Type::Flow, "KIL"), 2105 INST("111000110011----", Id::KIL, Type::Flow, "KIL"),