diff --git a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp index fd0a8c33bf..4e8c044113 100644 --- a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp @@ -3011,7 +3011,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s bool is_no_return = false; - if (pos_next >= lsa && pos_next < limit) + if (sl && pos_next >= lsa && pos_next < limit) { const u32 data_next = ls[pos_next / 4]; const auto type_next = g_spu_itype.decode(data_next); @@ -3274,11 +3274,17 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s spu_log.notice("[0x%x] At 0x%x: ignoring indirect branch (SYNC)", entry_point, pos); } + if (!(af & vf::is_const)) + { + // Possible unknown target + m_targets[pos].emplace_back(SPU_LS_SIZE); + } + if (type == spu_itype::BI || sl || is_no_return) { if (type == spu_itype::BI || g_cfg.core.spu_block_size == spu_block_size_type::safe || is_no_return) { - m_targets[pos].push_back(SPU_LS_SIZE); + m_targets[pos]; } else { @@ -3291,7 +3297,6 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s else { m_targets[pos].push_back(pos + 4); - m_targets[pos].push_back(SPU_LS_SIZE); add_block(pos + 4); } @@ -3884,6 +3889,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s it->second.emplace_back(SPU_LS_SIZE); } + std::sort(it->second.begin(), it->second.end()); it++; } @@ -6313,10 +6319,6 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s case spu_itype::BI: case spu_itype::BISL: case spu_itype::BISLED: - case spu_itype::BIZ: - case spu_itype::BINZ: - case spu_itype::BIHZ: - case spu_itype::BIHNZ: { if (op.e || op.d) { @@ -6417,12 +6419,23 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s } case spu_itype::BRHZ: case spu_itype::BRHNZ: - { - const u32 next_pc = spu_branch_target(pos, 1); - const u32 target = spu_branch_target(pos, op.i16); - const bool is_u16_jump = type == spu_itype::BRHZ || type == spu_itype::BRHNZ; - const bool is_jump_zero = (type == spu_itype::BRZ || type == spu_itype::BRHZ) ^ reduced_loop->is_two_block_loop; + case spu_itype::BIZ: + case spu_itype::BINZ: + case spu_itype::BIHZ: + case spu_itype::BIHNZ: + { + if (type == spu_itype::spu_itype::BIZ || type == spu_itype::BINZ || type == spu_itype::BIHZ || type == spu_itype::BIHNZ) + { + if (op.e || op.d) + { + break_all_patterns(27); + break; + } + } + + const bool is_u16_jump = type == spu_itype::BRHZ || type == spu_itype::BRHNZ || type == spu_itype::BIHZ || type == spu_itype::BIHNZ; + const bool is_jump_zero = (type == spu_itype::BRZ || type == spu_itype::BRHZ || type == spu_itype::BIZ || type == spu_itype::BIHZ) ^ reduced_loop->is_two_block_loop; while (reduced_loop->active) { @@ -6729,8 +6742,8 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s { reduced_loop->cond_val_incr_is_immediate = false; - const u32 op_ra = spu_opcode_t{reg->IMM}.ra; - const u32 op_rb = spu_opcode_t{reg->IMM}.rb; + const u32 op_ra = spu_opcode_t{reg_org->IMM}.ra; + const u32 op_rb = spu_opcode_t{reg_org->IMM}.rb; if (!(op_ra == reg_index || op_rb == reg_index)) {