Fix SPU STOP instruction

Check thread state after STOP instruction
This commit is contained in:
Nekotekina 2018-11-05 14:24:08 +03:00
parent f06e6be2c1
commit 488928eca2
4 changed files with 32 additions and 3 deletions

View File

@ -1580,12 +1580,26 @@ void spu_recompiler::STOP(spu_opcode_t op)
c->align(kAlignCode, 16);
c->bind(ret);
c->mov(SPU_OFF_32(pc), m_pos + 4);
if (g_cfg.core.spu_block_size == spu_block_size_type::safe)
{
c->mov(SPU_OFF_32(pc), m_pos + 4);
c->ret();
m_pos = -1;
}
else
{
Label label_next = c->newLabel();
Label label_check = c->newLabel();
c->cmp(SPU_OFF_32(state), 0);
c->jnz(label_check);
c->jmp(label_next);
c->bind(label_check);
c->lea(*ls, x86::qword_ptr(label_next));
c->jmp(imm_ptr(&check_state));
c->align(kAlignCode, 16);
c->bind(label_next);
}
}
void spu_recompiler::LNOP(spu_opcode_t op)

View File

@ -117,7 +117,18 @@ void spu_interpreter::set_interrupt_status(spu_thread& spu, spu_opcode_t op)
bool spu_interpreter::STOP(spu_thread& spu, spu_opcode_t op)
{
return spu.stop_and_signal(op.opcode & 0x3fff);
if (!spu.stop_and_signal(op.opcode & 0x3fff))
{
return false;
}
if (spu.state)
{
spu.pc += 4;
return false;
}
return true;
}
bool spu_interpreter::LNOP(spu_thread& spu, spu_opcode_t op)

View File

@ -3056,6 +3056,10 @@ public:
m_ir->CreateStore(m_ir->getInt32(m_pos + 4), spu_ptr<u32>(&spu_thread::pc));
m_ir->CreateRetVoid();
}
else
{
check_state(m_pos + 4);
}
}
void STOPD(spu_opcode_t op) //

View File

@ -2066,7 +2066,7 @@ bool spu_thread::stop_and_signal(u32 code)
int_ctrl[2].set(SPU_INT2_STAT_SPU_STOP_AND_SIGNAL_INT);
state += cpu_flag::stop;
return true; // ???
return true;
}
switch (code)