mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-12 01:38:37 +12:00
Implement cpu_thread::suspend_all
Remove Accurate PUTLLC option. Implement fallback path for SPU transactions.
This commit is contained in:
parent
17d0dcb7a2
commit
5d45a3e47d
18 changed files with 843 additions and 362 deletions
|
@ -5125,34 +5125,30 @@ public:
|
|||
call("spu_unknown", &exec_unk, m_thread, m_ir->getInt32(op_unk.opcode));
|
||||
}
|
||||
|
||||
static bool exec_stop(spu_thread* _spu, u32 code)
|
||||
static void exec_stop(spu_thread* _spu, u32 code)
|
||||
{
|
||||
return _spu->stop_and_signal(code);
|
||||
if (!_spu->stop_and_signal(code))
|
||||
{
|
||||
spu_runtime::g_escape(_spu);
|
||||
}
|
||||
|
||||
if (_spu->test_stopped())
|
||||
{
|
||||
_spu->pc += 4;
|
||||
spu_runtime::g_escape(_spu);
|
||||
}
|
||||
}
|
||||
|
||||
void STOP(spu_opcode_t op) //
|
||||
{
|
||||
if (m_interp_magn)
|
||||
{
|
||||
const auto succ = call("spu_syscall", &exec_stop, m_thread, m_ir->CreateAnd(m_interp_op, m_ir->getInt32(0x3fff)));
|
||||
const auto next = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
const auto stop = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
m_ir->CreateCondBr(succ, next, stop);
|
||||
m_ir->SetInsertPoint(stop);
|
||||
m_ir->CreateRetVoid();
|
||||
m_ir->SetInsertPoint(next);
|
||||
call("spu_syscall", &exec_stop, m_thread, m_ir->CreateAnd(m_interp_op, m_ir->getInt32(0x3fff)));
|
||||
return;
|
||||
}
|
||||
|
||||
update_pc();
|
||||
const auto succ = call("spu_syscall", &exec_stop, m_thread, m_ir->getInt32(op.opcode & 0x3fff));
|
||||
const auto next = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
const auto stop = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
m_ir->CreateCondBr(succ, next, stop);
|
||||
m_ir->SetInsertPoint(stop);
|
||||
m_ir->CreateStore(m_ir->getFalse(), m_fake_global1, true);
|
||||
m_ir->CreateBr(next);
|
||||
m_ir->SetInsertPoint(next);
|
||||
call("spu_syscall", &exec_stop, m_thread, m_ir->getInt32(op.opcode & 0x3fff));
|
||||
|
||||
if (g_cfg.core.spu_block_size == spu_block_size_type::safe)
|
||||
{
|
||||
|
@ -5167,28 +5163,35 @@ public:
|
|||
{
|
||||
if (m_interp_magn)
|
||||
{
|
||||
const auto succ = call("spu_syscall", &exec_stop, m_thread, m_ir->getInt32(0x3fff));
|
||||
const auto next = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
const auto stop = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
m_ir->CreateCondBr(succ, next, stop);
|
||||
m_ir->SetInsertPoint(stop);
|
||||
m_ir->CreateRetVoid();
|
||||
m_ir->SetInsertPoint(next);
|
||||
call("spu_syscall", &exec_stop, m_thread, m_ir->getInt32(0x3fff));
|
||||
return;
|
||||
}
|
||||
|
||||
STOP(spu_opcode_t{0x3fff});
|
||||
}
|
||||
|
||||
static s64 exec_rdch(spu_thread* _spu, u32 ch)
|
||||
static u32 exec_rdch(spu_thread* _spu, u32 ch)
|
||||
{
|
||||
return _spu->get_ch_value(ch);
|
||||
const s64 result = _spu->get_ch_value(ch);
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
spu_runtime::g_escape(_spu);
|
||||
}
|
||||
|
||||
if (_spu->test_stopped())
|
||||
{
|
||||
_spu->pc += 4;
|
||||
spu_runtime::g_escape(_spu);
|
||||
}
|
||||
|
||||
return static_cast<u32>(result & 0xffffffff);
|
||||
}
|
||||
|
||||
static s64 exec_read_in_mbox(spu_thread* _spu)
|
||||
static u32 exec_read_in_mbox(spu_thread* _spu)
|
||||
{
|
||||
// TODO
|
||||
return _spu->get_ch_value(SPU_RdInMbox);
|
||||
return exec_rdch(_spu, SPU_RdInMbox);
|
||||
}
|
||||
|
||||
static u32 exec_read_dec(spu_thread* _spu)
|
||||
|
@ -5203,7 +5206,7 @@ public:
|
|||
return res;
|
||||
}
|
||||
|
||||
static s64 exec_read_events(spu_thread* _spu)
|
||||
static u32 exec_read_events(spu_thread* _spu)
|
||||
{
|
||||
if (const u32 events = _spu->get_events())
|
||||
{
|
||||
|
@ -5211,7 +5214,7 @@ public:
|
|||
}
|
||||
|
||||
// TODO
|
||||
return _spu->get_ch_value(SPU_RdEventStat);
|
||||
return exec_rdch(_spu, SPU_RdEventStat);
|
||||
}
|
||||
|
||||
llvm::Value* get_rdch(spu_opcode_t op, u32 off, bool atomic)
|
||||
|
@ -5234,20 +5237,17 @@ public:
|
|||
const auto _cur = m_ir->GetInsertBlock();
|
||||
const auto done = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
const auto wait = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
const auto stop = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
m_ir->CreateCondBr(m_ir->CreateICmpSLT(val0, m_ir->getInt64(0)), done, wait);
|
||||
const auto cond = m_ir->CreateICmpSLT(val0, m_ir->getInt64(0));
|
||||
val0 = m_ir->CreateTrunc(val0, get_type<u32>());
|
||||
m_ir->CreateCondBr(cond, done, wait);
|
||||
m_ir->SetInsertPoint(wait);
|
||||
const auto val1 = call("spu_read_channel", &exec_rdch, m_thread, m_ir->getInt32(op.ra));
|
||||
m_ir->CreateCondBr(m_ir->CreateICmpSLT(val1, m_ir->getInt64(0)), stop, done);
|
||||
m_ir->SetInsertPoint(stop);
|
||||
m_ir->CreateStore(m_ir->getFalse(), m_fake_global1, true);
|
||||
m_ir->CreateBr(done);
|
||||
m_ir->SetInsertPoint(done);
|
||||
const auto rval = m_ir->CreatePHI(get_type<u64>(), 2);
|
||||
const auto rval = m_ir->CreatePHI(get_type<u32>(), 2);
|
||||
rval->addIncoming(val0, _cur);
|
||||
rval->addIncoming(val1, wait);
|
||||
rval->addIncoming(m_ir->getInt64(0), stop);
|
||||
return m_ir->CreateTrunc(rval, get_type<u32>());
|
||||
return rval;
|
||||
}
|
||||
|
||||
void RDCH(spu_opcode_t op) //
|
||||
|
@ -5257,13 +5257,6 @@ public:
|
|||
if (m_interp_magn)
|
||||
{
|
||||
res.value = call("spu_read_channel", &exec_rdch, m_thread, get_imm<u32>(op.ra).value);
|
||||
const auto next = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
const auto stop = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
m_ir->CreateCondBr(m_ir->CreateICmpSLT(res.value, m_ir->getInt64(0)), stop, next);
|
||||
m_ir->SetInsertPoint(stop);
|
||||
m_ir->CreateRetVoid();
|
||||
m_ir->SetInsertPoint(next);
|
||||
res.value = m_ir->CreateTrunc(res.value, get_type<u32>());
|
||||
set_vr(op.rt, insert(splat<u32[4]>(0), 3, res));
|
||||
return;
|
||||
}
|
||||
|
@ -5279,14 +5272,6 @@ public:
|
|||
{
|
||||
update_pc();
|
||||
res.value = call("spu_read_in_mbox", &exec_read_in_mbox, m_thread);
|
||||
const auto next = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
const auto stop = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
m_ir->CreateCondBr(m_ir->CreateICmpSLT(res.value, m_ir->getInt64(0)), stop, next);
|
||||
m_ir->SetInsertPoint(stop);
|
||||
m_ir->CreateStore(m_ir->getFalse(), m_fake_global1, true);
|
||||
m_ir->CreateBr(next);
|
||||
m_ir->SetInsertPoint(next);
|
||||
res.value = m_ir->CreateTrunc(res.value, get_type<u32>());
|
||||
break;
|
||||
}
|
||||
case MFC_RdTagStat:
|
||||
|
@ -5333,14 +5318,6 @@ public:
|
|||
{
|
||||
update_pc();
|
||||
res.value = call("spu_read_events", &exec_read_events, m_thread);
|
||||
const auto next = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
const auto stop = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
m_ir->CreateCondBr(m_ir->CreateICmpSLT(res.value, m_ir->getInt64(0)), stop, next);
|
||||
m_ir->SetInsertPoint(stop);
|
||||
m_ir->CreateStore(m_ir->getFalse(), m_fake_global1, true);
|
||||
m_ir->CreateBr(next);
|
||||
m_ir->SetInsertPoint(next);
|
||||
res.value = m_ir->CreateTrunc(res.value, get_type<u32>());
|
||||
break;
|
||||
}
|
||||
case SPU_RdMachStat:
|
||||
|
@ -5353,14 +5330,6 @@ public:
|
|||
{
|
||||
update_pc();
|
||||
res.value = call("spu_read_channel", &exec_rdch, m_thread, m_ir->getInt32(op.ra));
|
||||
const auto next = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
const auto stop = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
m_ir->CreateCondBr(m_ir->CreateICmpSLT(res.value, m_ir->getInt64(0)), stop, next);
|
||||
m_ir->SetInsertPoint(stop);
|
||||
m_ir->CreateStore(m_ir->getFalse(), m_fake_global1, true);
|
||||
m_ir->CreateBr(next);
|
||||
m_ir->SetInsertPoint(next);
|
||||
res.value = m_ir->CreateTrunc(res.value, get_type<u32>());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -5471,14 +5440,18 @@ public:
|
|||
set_vr(op.rt, insert(splat<u32[4]>(0), 3, res));
|
||||
}
|
||||
|
||||
static bool exec_wrch(spu_thread* _spu, u32 ch, u32 value)
|
||||
static void exec_wrch(spu_thread* _spu, u32 ch, u32 value)
|
||||
{
|
||||
return _spu->set_ch_value(ch, value);
|
||||
}
|
||||
if (!_spu->set_ch_value(ch, value))
|
||||
{
|
||||
spu_runtime::g_escape(_spu);
|
||||
}
|
||||
|
||||
static void exec_mfc(spu_thread* _spu)
|
||||
{
|
||||
return _spu->do_mfc();
|
||||
if (_spu->test_stopped())
|
||||
{
|
||||
_spu->pc += 4;
|
||||
spu_runtime::g_escape(_spu);
|
||||
}
|
||||
}
|
||||
|
||||
static void exec_list_unstall(spu_thread* _spu, u32 tag)
|
||||
|
@ -5491,12 +5464,21 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
return exec_mfc(_spu);
|
||||
_spu->do_mfc();
|
||||
}
|
||||
|
||||
static bool exec_mfc_cmd(spu_thread* _spu)
|
||||
static void exec_mfc_cmd(spu_thread* _spu)
|
||||
{
|
||||
return _spu->process_mfc_cmd();
|
||||
if (!_spu->process_mfc_cmd())
|
||||
{
|
||||
spu_runtime::g_escape(_spu);
|
||||
}
|
||||
|
||||
if (_spu->test_stopped())
|
||||
{
|
||||
_spu->pc += 4;
|
||||
spu_runtime::g_escape(_spu);
|
||||
}
|
||||
}
|
||||
|
||||
void WRCH(spu_opcode_t op) //
|
||||
|
@ -5505,13 +5487,7 @@ public:
|
|||
|
||||
if (m_interp_magn)
|
||||
{
|
||||
const auto succ = call("spu_write_channel", &exec_wrch, m_thread, get_imm<u32>(op.ra).value, val.value);
|
||||
const auto next = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
const auto stop = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
m_ir->CreateCondBr(succ, next, stop);
|
||||
m_ir->SetInsertPoint(stop);
|
||||
m_ir->CreateRetVoid();
|
||||
m_ir->SetInsertPoint(next);
|
||||
call("spu_write_channel", &exec_wrch, m_thread, get_imm<u32>(op.ra).value, val.value);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5922,14 +5898,7 @@ public:
|
|||
}
|
||||
|
||||
update_pc();
|
||||
const auto succ = call("spu_write_channel", &exec_wrch, m_thread, m_ir->getInt32(op.ra), val.value);
|
||||
const auto next = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
const auto stop = llvm::BasicBlock::Create(m_context, "", m_function);
|
||||
m_ir->CreateCondBr(succ, next, stop);
|
||||
m_ir->SetInsertPoint(stop);
|
||||
m_ir->CreateStore(m_ir->getFalse(), m_fake_global1, true);
|
||||
m_ir->CreateBr(next);
|
||||
m_ir->SetInsertPoint(next);
|
||||
call("spu_write_channel", &exec_wrch, m_thread, m_ir->getInt32(op.ra), val.value);
|
||||
}
|
||||
|
||||
void LNOP(spu_opcode_t op) //
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue