|
1 | 1 | #include "stdafx.h" |
2 | 2 | #include "ProgramStateCache.h" |
| 3 | +#include "FragmentProgramDecompiler.h" |
3 | 4 | #include "Emu/system_config.h" |
4 | 5 | #include "Emu/RSX/Core/RSXDriverState.h" |
5 | 6 | #include "util/sysinfo.hpp" |
@@ -637,58 +638,51 @@ fragment_program_utils::fragment_program_metadata fragment_program_utils::analys |
637 | 638 | while (true) |
638 | 639 | { |
639 | 640 | const auto inst = v128::loadu(instBuffer, index); |
| 641 | + const auto d0 = OPDEST::from_be32(inst._u32[0]); |
| 642 | + const auto opcode = static_cast<rsx::assembler::FP_opcode>(d0.opcode); |
640 | 643 |
|
641 | | - // Check for opcode high bit which indicates a branch instructions (opcode 0x40...0x45) |
642 | | - if (inst._u32[2] & (1 << 23)) |
| 644 | + switch (opcode) |
643 | 645 | { |
| 646 | + case RSX_FP_OPCODE_TEX: |
| 647 | + case RSX_FP_OPCODE_TEXBEM: |
| 648 | + case RSX_FP_OPCODE_TXP: |
| 649 | + case RSX_FP_OPCODE_TXPBEM: |
| 650 | + case RSX_FP_OPCODE_TXD: |
| 651 | + case RSX_FP_OPCODE_TXB: |
| 652 | + case RSX_FP_OPCODE_TXL: |
| 653 | + result.referenced_textures_mask |= (1 << d0.tex_num); |
| 654 | + result.has_tex_bx2_conv |= !!d0.exp_tex; |
| 655 | + break; |
| 656 | + case RSX_FP_OPCODE_PK4: |
| 657 | + case RSX_FP_OPCODE_UP4: |
| 658 | + case RSX_FP_OPCODE_PK2: |
| 659 | + case RSX_FP_OPCODE_UP2: |
| 660 | + case RSX_FP_OPCODE_PKB: |
| 661 | + case RSX_FP_OPCODE_UPB: |
| 662 | + case RSX_FP_OPCODE_PK16: |
| 663 | + case RSX_FP_OPCODE_UP16: |
| 664 | + case RSX_FP_OPCODE_PKG: |
| 665 | + case RSX_FP_OPCODE_UPG: |
| 666 | + result.has_pack_instructions = true; |
| 667 | + break; |
| 668 | + case RSX_FP_OPCODE_BRK: |
| 669 | + case RSX_FP_OPCODE_CAL: |
| 670 | + case RSX_FP_OPCODE_IFE: |
| 671 | + case RSX_FP_OPCODE_LOOP: |
| 672 | + case RSX_FP_OPCODE_REP: |
| 673 | + case RSX_FP_OPCODE_RET: |
644 | 674 | // NOTE: Jump instructions are not yet proved to work outside of loops and if/else blocks |
645 | 675 | // Otherwise we would need to follow the execution chain |
646 | 676 | result.has_branch_instructions = true; |
| 677 | + break; |
647 | 678 | } |
648 | | - else |
649 | | - { |
650 | | - const u32 opcode = (inst._u32[0] >> 16) & 0x3F; |
651 | | - if (opcode) |
652 | | - { |
653 | | - switch (opcode) |
654 | | - { |
655 | | - case RSX_FP_OPCODE_TEX: |
656 | | - case RSX_FP_OPCODE_TEXBEM: |
657 | | - case RSX_FP_OPCODE_TXP: |
658 | | - case RSX_FP_OPCODE_TXPBEM: |
659 | | - case RSX_FP_OPCODE_TXD: |
660 | | - case RSX_FP_OPCODE_TXB: |
661 | | - case RSX_FP_OPCODE_TXL: |
662 | | - { |
663 | | - //Bits 17-20 of word 1, swapped within u16 sections |
664 | | - //Bits 16-23 are swapped into the upper 8 bits (24-31) |
665 | | - const u32 tex_num = (inst._u32[0] >> 25) & 15; |
666 | | - result.referenced_textures_mask |= (1 << tex_num); |
667 | | - break; |
668 | | - } |
669 | | - case RSX_FP_OPCODE_PK4: |
670 | | - case RSX_FP_OPCODE_UP4: |
671 | | - case RSX_FP_OPCODE_PK2: |
672 | | - case RSX_FP_OPCODE_UP2: |
673 | | - case RSX_FP_OPCODE_PKB: |
674 | | - case RSX_FP_OPCODE_UPB: |
675 | | - case RSX_FP_OPCODE_PK16: |
676 | | - case RSX_FP_OPCODE_UP16: |
677 | | - case RSX_FP_OPCODE_PKG: |
678 | | - case RSX_FP_OPCODE_UPG: |
679 | | - { |
680 | | - result.has_pack_instructions = true; |
681 | | - break; |
682 | | - } |
683 | | - } |
684 | | - } |
685 | 679 |
|
686 | | - if (is_any_src_constant(inst)) |
687 | | - { |
688 | | - //Instruction references constant, skip one slot occupied by data |
689 | | - index++; |
690 | | - result.program_constants_buffer_length += 16; |
691 | | - } |
| 680 | + if (rsx::assembler::FP::get_operand_count(opcode) > 0 && |
| 681 | + is_any_src_constant(inst)) |
| 682 | + { |
| 683 | + // Instruction references constant, skip one slot occupied by data |
| 684 | + index++; |
| 685 | + result.program_constants_buffer_length += 16; |
692 | 686 | } |
693 | 687 |
|
694 | 688 | index++; |
|
0 commit comments