cpu_type removed, system_type added

cpu_state -> cpu_flag
vm::stack_allocator template improved
ppu_cmd type changed to enum, cmd64 type added
This commit is contained in:
Nekotekina 2016-08-09 17:14:41 +03:00
parent 009ac37a7d
commit bdeccd889f
39 changed files with 449 additions and 492 deletions

View file

@ -817,127 +817,6 @@ namespace vm
g_locations.clear();
}
u32 stack_push(u32 size, u32 align_v)
{
if (auto cpu = get_current_cpu_thread()) switch (cpu->type)
{
case cpu_type::ppu:
{
ppu_thread& context = static_cast<ppu_thread&>(*cpu);
const u32 old_pos = vm::cast(context.gpr[1], HERE);
context.gpr[1] -= align(size + 4, 8); // room minimal possible size
context.gpr[1] &= ~(align_v - 1); // fix stack alignment
if (context.gpr[1] < context.stack_addr)
{
fmt::throw_exception("Stack overflow (size=0x%x, align=0x%x, SP=0x%llx, stack=*0x%x)" HERE, size, align_v, old_pos, context.stack_addr);
}
else
{
const u32 addr = static_cast<u32>(context.gpr[1]);
vm::ps3::_ref<nse_t<u32>>(addr + size) = old_pos;
std::memset(vm::base(addr), 0, size);
return addr;
}
}
case cpu_type::spu:
{
SPUThread& context = static_cast<SPUThread&>(*cpu);
const u32 old_pos = context.gpr[1]._u32[3];
context.gpr[1]._u32[3] -= align(size + 4, 16);
context.gpr[1]._u32[3] &= ~(align_v - 1);
if (context.gpr[1]._u32[3] >= 0x40000) // extremely rough
{
fmt::throw_exception("Stack overflow (size=0x%x, align=0x%x, SP=LS:0x%05x)" HERE, size, align_v, old_pos);
}
else
{
const u32 addr = context.gpr[1]._u32[3] + context.offset;
vm::ps3::_ref<nse_t<u32>>(addr + size) = old_pos;
return addr;
}
}
case cpu_type::arm:
{
ARMv7Thread& context = static_cast<ARMv7Thread&>(*cpu);
const u32 old_pos = context.SP;
context.SP -= align(size + 4, 4); // room minimal possible size
context.SP &= ~(align_v - 1); // fix stack alignment
if (context.SP < context.stack_addr)
{
fmt::throw_exception("Stack overflow (size=0x%x, align=0x%x, SP=0x%x, stack=*0x%x)" HERE, size, align_v, context.SP, context.stack_addr);
}
else
{
vm::psv::_ref<nse_t<u32>>(context.SP + size) = old_pos;
return context.SP;
}
}
default:
{
fmt::throw_exception("Invalid thread type (%u)" HERE, cpu->type);
}
}
fmt::throw_exception("Invalid thread" HERE);
}
void stack_pop_verbose(u32 addr, u32 size) noexcept
{
if (auto cpu = get_current_cpu_thread()) switch (cpu->type)
{
case cpu_type::ppu:
{
ppu_thread& context = static_cast<ppu_thread&>(*cpu);
if (context.gpr[1] != addr)
{
LOG_ERROR(MEMORY, "Stack inconsistency (addr=0x%x, SP=0x%llx, size=0x%x)", addr, context.gpr[1], size);
return;
}
context.gpr[1] = vm::ps3::_ref<nse_t<u32>>(context.gpr[1] + size);
return;
}
case cpu_type::spu:
{
SPUThread& context = static_cast<SPUThread&>(*cpu);
if (context.gpr[1]._u32[3] + context.offset != addr)
{
LOG_ERROR(MEMORY, "Stack inconsistency (addr=0x%x, SP=LS:0x%05x, size=0x%x)", addr, context.gpr[1]._u32[3], size);
return;
}
context.gpr[1]._u32[3] = vm::ps3::_ref<nse_t<u32>>(context.gpr[1]._u32[3] + context.offset + size);
return;
}
case cpu_type::arm:
{
ARMv7Thread& context = static_cast<ARMv7Thread&>(*cpu);
if (context.SP != addr)
{
LOG_ERROR(MEMORY, "Stack inconsistency (addr=0x%x, SP=0x%x, size=0x%x)", addr, context.SP, size);
return;
}
context.SP = vm::psv::_ref<nse_t<u32>>(context.SP + size);
return;
}
}
}
[[noreturn]] void throw_access_violation(u64 addr, const char* cause)
{
throw access_violation(addr, cause);