From 6416fee9866a6dc253654ea2c67ca0f594a52248 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 17 May 2019 22:26:33 +0300 Subject: [PATCH] SPU ASMJIT: fix indirect branch target order Check stack mirror first, as in SPU LLVM. --- rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp b/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp index 01198c8ca0..9c7493fd7a 100644 --- a/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp @@ -1076,6 +1076,20 @@ void spu_recompiler::branch_indirect(spu_opcode_t op, bool jt, bool ret) c->cmp(SPU_OFF_32(state), 0); c->jnz(label_stop); + if (g_cfg.core.spu_block_size != spu_block_size_type::safe && ret) + { + // Get stack pointer, try to use native return address (check SPU return address) + Label fail = c->newLabel(); + c->mov(qw1->r32(), SPU_OFF_32(gpr, 1, &v128::_u32, 3)); + c->and_(qw1->r32(), 0x3fff0); + c->lea(*qw1, x86::qword_ptr(*cpu, *qw1, 0, ::offset32(&spu_thread::stack_mirror))); + c->cmp(x86::dword_ptr(*qw1, 8), *addr); + c->jne(fail); + c->mov(pc0->r32(), x86::dword_ptr(*qw1, 12)); + c->jmp(x86::qword_ptr(*qw1)); + c->bind(fail); + } + if (jt || g_cfg.core.spu_block_size == spu_block_size_type::giga) { if (!instr_table.isValid()) @@ -1100,20 +1114,6 @@ void spu_recompiler::branch_indirect(spu_opcode_t op, bool jt, bool ret) c->bind(fail); } - if (g_cfg.core.spu_block_size != spu_block_size_type::safe && ret) - { - // Get stack pointer, try to use native return address (check SPU return address) - Label fail = c->newLabel(); - c->mov(qw1->r32(), SPU_OFF_32(gpr, 1, &v128::_u32, 3)); - c->and_(qw1->r32(), 0x3fff0); - c->lea(*qw1, x86::qword_ptr(*cpu, *qw1, 0, ::offset32(&spu_thread::stack_mirror))); - c->cmp(x86::dword_ptr(*qw1, 8), *addr); - c->jne(fail); - c->mov(pc0->r32(), x86::dword_ptr(*qw1, 12)); - c->jmp(x86::qword_ptr(*qw1)); - c->bind(fail); - } - // Simply external call (return or indirect call) const auto ppptr = !g_cfg.core.spu_verification ? nullptr : m_spurt->make_branch_patchpoint();