| 68 | } |
| 69 | |
| 70 | u32 GetSureBranchTarget(u32 addr, MemoryInterface& reader) |
| 71 | { |
| 72 | u32 op = reader.Read32(addr); |
| 73 | const R5900::OPCODE& opcode = R5900::GetInstruction(op); |
| 74 | |
| 75 | if ((opcode.flags & IS_BRANCH) && (opcode.flags & BRANCHTYPE_MASK) == BRANCHTYPE_BRANCH) |
| 76 | { |
| 77 | bool sure = false; |
| 78 | bool takeBranch = false; |
| 79 | switch (opcode.flags & CONDTYPE_MASK) |
| 80 | { |
| 81 | case CONDTYPE_EQ: |
| 82 | sure = _RS == _RT; |
| 83 | takeBranch = true; |
| 84 | break; |
| 85 | |
| 86 | case CONDTYPE_NE: |
| 87 | sure = _RS == _RT; |
| 88 | takeBranch = false; |
| 89 | break; |
| 90 | |
| 91 | case CONDTYPE_LEZ: |
| 92 | case CONDTYPE_GEZ: |
| 93 | sure = _RS == 0; |
| 94 | takeBranch = true; |
| 95 | break; |
| 96 | |
| 97 | case CONDTYPE_LTZ: |
| 98 | case CONDTYPE_GTZ: |
| 99 | sure = _RS == 0; |
| 100 | takeBranch = false; |
| 101 | break; |
| 102 | |
| 103 | default: |
| 104 | break; |
| 105 | } |
| 106 | |
| 107 | if (sure && takeBranch) |
| 108 | return addr + 4 + ((signed short)(op&0xFFFF)<<2); |
| 109 | else if (sure && !takeBranch) |
| 110 | return addr + 8; |
| 111 | else |
| 112 | return INVALIDTARGET; |
| 113 | } |
| 114 | else |
| 115 | return INVALIDTARGET; |
| 116 | } |
| 117 | |
| 118 | static u32 ScanAheadForJumpback(u32 fromAddr, u32 knownStart, u32 knownEnd, MemoryInterface& reader) { |
| 119 | static const u32 MAX_AHEAD_SCAN = 0x1000; |
no test coverage detected