mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
ARMv7Context used through multiple inheritance
Forgive me...
This commit is contained in:
parent
6c4148a949
commit
a7f77c27f7
9 changed files with 64 additions and 68 deletions
|
@ -1,7 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
class ARMv7Thread;
|
||||
|
||||
enum ARMv7InstructionSet
|
||||
{
|
||||
ARM,
|
||||
|
@ -122,13 +120,9 @@ struct ARMv7Context
|
|||
|
||||
std::array<perf_counter, 6> counters;
|
||||
|
||||
ARMv7Thread& thread;
|
||||
|
||||
u32 debug; // debug flags
|
||||
u32 debug;
|
||||
std::string debug_str;
|
||||
|
||||
ARMv7Context(ARMv7Thread& thread) : thread(thread), debug(/*DF_DISASM | DF_PRINT*/ 0) {}
|
||||
|
||||
void write_pc(u32 value);
|
||||
u32 read_pc();
|
||||
u32 get_stack_arg(u32 pos);
|
||||
|
|
|
@ -287,17 +287,19 @@ namespace ARMv7_instrs
|
|||
{
|
||||
if (context.debug & DF_PRINT)
|
||||
{
|
||||
ARMv7Thread& CPU = static_cast<ARMv7Thread&>(context);
|
||||
|
||||
auto pos = context.debug_str.find(' ');
|
||||
if (pos != std::string::npos && pos < 8)
|
||||
{
|
||||
context.debug_str.insert(pos, 8 - pos, ' ');
|
||||
}
|
||||
|
||||
context.fmt_debug_str("0x%08x: %s", context.thread.PC, context.debug_str);
|
||||
context.fmt_debug_str("0x%08x: %s", CPU.PC, context.debug_str);
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
auto found = g_armv7_dump.find(context.thread.PC);
|
||||
auto found = g_armv7_dump.find(CPU.PC);
|
||||
if (found != g_armv7_dump.end())
|
||||
{
|
||||
if (found->second != context.debug_str)
|
||||
|
@ -307,7 +309,7 @@ namespace ARMv7_instrs
|
|||
}
|
||||
else
|
||||
{
|
||||
g_armv7_dump[context.thread.PC] = context.debug_str;
|
||||
g_armv7_dump[CPU.PC] = context.debug_str;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1258,7 +1260,7 @@ void ARMv7_instrs::B(ARMv7Context& context, const ARMv7Code code, const ARMv7_en
|
|||
|
||||
if (ConditionPassed(context, cond))
|
||||
{
|
||||
context.thread.SetBranch(context.read_pc() + imm32);
|
||||
static_cast<ARMv7Thread&>(context).SetBranch(context.read_pc() + imm32);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1438,12 +1440,14 @@ void ARMv7_instrs::BL(ARMv7Context& context, const ARMv7Code code, const ARMv7_e
|
|||
if (ConditionPassed(context, cond))
|
||||
{
|
||||
context.LR = lr;
|
||||
context.thread.SetBranch(pc);
|
||||
static_cast<ARMv7Thread&>(context).SetBranch(pc);
|
||||
}
|
||||
}
|
||||
|
||||
void ARMv7_instrs::BLX(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
|
||||
{
|
||||
ARMv7Thread& thread = static_cast<ARMv7Thread&>(context);
|
||||
|
||||
u32 cond, target, newLR;
|
||||
|
||||
switch (type)
|
||||
|
@ -1451,7 +1455,7 @@ void ARMv7_instrs::BLX(ARMv7Context& context, const ARMv7Code code, const ARMv7_
|
|||
case T1:
|
||||
{
|
||||
cond = context.ITSTATE.advance();
|
||||
newLR = (context.thread.PC + 2) | 1;
|
||||
newLR = (thread.PC + 2) | 1;
|
||||
{
|
||||
const u32 m = (code.data >> 3) & 0xf;
|
||||
reject(m == 15, "UNPREDICTABLE");
|
||||
|
@ -1464,12 +1468,12 @@ void ARMv7_instrs::BLX(ARMv7Context& context, const ARMv7Code code, const ARMv7_
|
|||
case T2:
|
||||
{
|
||||
cond = context.ITSTATE.advance();
|
||||
newLR = (context.thread.PC + 4) | 1;
|
||||
newLR = (thread.PC + 4) | 1;
|
||||
{
|
||||
const u32 s = (code.data >> 26) & 0x1;
|
||||
const u32 i1 = (code.data >> 13) & 0x1 ^ s ^ 1;
|
||||
const u32 i2 = (code.data >> 11) & 0x1 ^ s ^ 1;
|
||||
target = ~3 & context.thread.PC + 4 + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (code.data & 0x3ff0000) >> 4 | (code.data & 0x7ff) << 1);
|
||||
target = ~3 & thread.PC + 4 + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (code.data & 0x3ff0000) >> 4 | (code.data & 0x7ff) << 1);
|
||||
}
|
||||
|
||||
reject(context.ITSTATE, "UNPREDICTABLE");
|
||||
|
@ -1478,15 +1482,15 @@ void ARMv7_instrs::BLX(ARMv7Context& context, const ARMv7Code code, const ARMv7_
|
|||
case A1:
|
||||
{
|
||||
cond = code.data >> 28;
|
||||
newLR = context.thread.PC + 4;
|
||||
newLR = thread.PC + 4;
|
||||
target = context.read_gpr(code.data & 0xf);
|
||||
break;
|
||||
}
|
||||
case A2:
|
||||
{
|
||||
cond = 0xe; // always true
|
||||
newLR = context.thread.PC + 4;
|
||||
target = 1 | context.thread.PC + 8 + sign<25, u32>((code.data & 0xffffff) << 2 | (code.data & 0x1000000) >> 23);
|
||||
newLR = thread.PC + 4;
|
||||
target = 1 | thread.PC + 8 + sign<25, u32>((code.data & 0xffffff) << 2 | (code.data & 0x1000000) >> 23);
|
||||
break;
|
||||
}
|
||||
default: throw __FUNCTION__;
|
||||
|
@ -1577,7 +1581,7 @@ void ARMv7_instrs::CB_Z(ARMv7Context& context, const ARMv7Code code, const ARMv7
|
|||
|
||||
if ((context.read_gpr(n) == 0) ^ nonzero)
|
||||
{
|
||||
context.thread.SetBranch(context.read_pc() + imm32);
|
||||
static_cast<ARMv7Thread&>(context).SetBranch(context.read_pc() + imm32);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,12 +12,16 @@
|
|||
|
||||
void ARMv7Context::write_pc(u32 value)
|
||||
{
|
||||
ARMv7Thread& thread = *static_cast<ARMv7Thread*>(this);
|
||||
|
||||
ISET = value & 1 ? Thumb : ARM;
|
||||
thread.SetBranch(value & ~1);
|
||||
}
|
||||
|
||||
u32 ARMv7Context::read_pc()
|
||||
{
|
||||
ARMv7Thread& thread = *static_cast<ARMv7Thread*>(this);
|
||||
|
||||
return ISET == ARM ? thread.PC + 8 : thread.PC + 4;
|
||||
}
|
||||
|
||||
|
@ -28,7 +32,7 @@ u32 ARMv7Context::get_stack_arg(u32 pos)
|
|||
|
||||
void ARMv7Context::fast_call(u32 addr)
|
||||
{
|
||||
return thread.FastCall(addr);
|
||||
return static_cast<ARMv7Thread*>(this)->FastCall(addr);
|
||||
}
|
||||
|
||||
#define TLS_MAX 128
|
||||
|
@ -96,7 +100,6 @@ void armv7_free_tls(u32 thread)
|
|||
|
||||
ARMv7Thread::ARMv7Thread()
|
||||
: CPUThread(CPU_THREAD_ARMv7)
|
||||
, context(*this)
|
||||
//, m_arg(0)
|
||||
//, m_last_instr_size(0)
|
||||
//, m_last_instr_name("UNK")
|
||||
|
@ -110,15 +113,15 @@ ARMv7Thread::~ARMv7Thread()
|
|||
|
||||
void ARMv7Thread::InitRegs()
|
||||
{
|
||||
memset(context.GPR, 0, sizeof(context.GPR));
|
||||
context.APSR.APSR = 0;
|
||||
context.IPSR.IPSR = 0;
|
||||
context.ISET = PC & 1 ? Thumb : ARM; // select instruction set
|
||||
context.thread.SetPc(PC & ~1); // and fix PC
|
||||
context.ITSTATE.IT = 0;
|
||||
context.SP = m_stack_addr + m_stack_size;
|
||||
context.TLS = armv7_get_tls(GetId());
|
||||
context.debug |= DF_DISASM | DF_PRINT;
|
||||
memset(GPR, 0, sizeof(GPR));
|
||||
APSR.APSR = 0;
|
||||
IPSR.IPSR = 0;
|
||||
ISET = PC & 1 ? Thumb : ARM; // select instruction set
|
||||
SetPc(PC & ~1); // and fix PC
|
||||
ITSTATE.IT = 0;
|
||||
SP = m_stack_addr + m_stack_size;
|
||||
TLS = armv7_get_tls(GetId());
|
||||
debug = DF_DISASM | DF_PRINT;
|
||||
}
|
||||
|
||||
void ARMv7Thread::InitStack()
|
||||
|
@ -144,16 +147,16 @@ std::string ARMv7Thread::RegsToString()
|
|||
std::string result = "Registers:\n=========\n";
|
||||
for(int i=0; i<15; ++i)
|
||||
{
|
||||
result += fmt::Format("%s\t= 0x%08x\n", g_arm_reg_name[i], context.GPR[i]);
|
||||
result += fmt::Format("%s\t= 0x%08x\n", g_arm_reg_name[i], GPR[i]);
|
||||
}
|
||||
|
||||
result += fmt::Format("APSR\t= 0x%08x [N: %d, Z: %d, C: %d, V: %d, Q: %d]\n",
|
||||
context.APSR.APSR,
|
||||
fmt::by_value(context.APSR.N),
|
||||
fmt::by_value(context.APSR.Z),
|
||||
fmt::by_value(context.APSR.C),
|
||||
fmt::by_value(context.APSR.V),
|
||||
fmt::by_value(context.APSR.Q));
|
||||
APSR.APSR,
|
||||
fmt::by_value(APSR.N),
|
||||
fmt::by_value(APSR.Z),
|
||||
fmt::by_value(APSR.C),
|
||||
fmt::by_value(APSR.V),
|
||||
fmt::by_value(APSR.Q));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -180,7 +183,7 @@ void ARMv7Thread::DoRun()
|
|||
{
|
||||
case 0:
|
||||
case 1:
|
||||
m_dec = new ARMv7Decoder(context);
|
||||
m_dec = new ARMv7Decoder(*this);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR(PPU, "Invalid CPU decoder mode: %d", Ini.CPUDecoderMode.GetValue());
|
||||
|
@ -208,21 +211,21 @@ void ARMv7Thread::FastCall(u32 addr)
|
|||
{
|
||||
auto old_status = m_status;
|
||||
auto old_PC = PC;
|
||||
auto old_stack = context.SP;
|
||||
auto old_LR = context.LR;
|
||||
auto old_stack = SP;
|
||||
auto old_LR = LR;
|
||||
auto old_thread = GetCurrentNamedThread();
|
||||
|
||||
m_status = Running;
|
||||
PC = addr;
|
||||
context.LR = Emu.GetCPUThreadStop();
|
||||
LR = Emu.GetCPUThreadStop();
|
||||
SetCurrentNamedThread(this);
|
||||
|
||||
CPUThread::Task();
|
||||
|
||||
m_status = old_status;
|
||||
PC = old_PC;
|
||||
context.SP = old_stack;
|
||||
context.LR = old_LR;
|
||||
SP = old_stack;
|
||||
LR = old_LR;
|
||||
SetCurrentNamedThread(old_thread);
|
||||
}
|
||||
|
||||
|
@ -284,8 +287,8 @@ cpu_thread& armv7_thread::run()
|
|||
armv7.Run();
|
||||
|
||||
// set arguments
|
||||
armv7.context.GPR[0] = argc;
|
||||
armv7.context.GPR[1] = argv;
|
||||
armv7.GPR[0] = argc;
|
||||
armv7.GPR[1] = argv;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -2,11 +2,9 @@
|
|||
#include "Emu/CPU/CPUThread.h"
|
||||
#include "ARMv7Context.h"
|
||||
|
||||
class ARMv7Thread : public CPUThread
|
||||
class ARMv7Thread : public CPUThread, public ARMv7Context
|
||||
{
|
||||
public:
|
||||
ARMv7Context context;
|
||||
|
||||
ARMv7Thread();
|
||||
~ARMv7Thread();
|
||||
|
||||
|
|
|
@ -79,12 +79,12 @@ s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::ptr<const void> pArgBloc
|
|||
ARMv7Thread& thread = static_cast<ARMv7Thread&>(*t);
|
||||
|
||||
// push arg block onto the stack
|
||||
const u32 pos = (thread.context.SP -= argSize);
|
||||
const u32 pos = (thread.SP -= argSize);
|
||||
memcpy(vm::get_ptr<void>(pos), pArgBlock.get_ptr(), argSize);
|
||||
|
||||
// set SceKernelThreadEntry function arguments
|
||||
thread.context.GPR[0] = argSize;
|
||||
thread.context.GPR[1] = pos;
|
||||
thread.GPR[0] = argSize;
|
||||
thread.GPR[1] = pos;
|
||||
|
||||
thread.Exec();
|
||||
return SCE_OK;
|
||||
|
@ -95,7 +95,7 @@ s32 sceKernelExitThread(ARMv7Context& context, s32 exitStatus)
|
|||
sceLibKernel.Warning("sceKernelExitThread(exitStatus=0x%x)", exitStatus);
|
||||
|
||||
// exit status is stored in r0
|
||||
context.thread.Stop();
|
||||
static_cast<ARMv7Thread&>(context).Stop();
|
||||
|
||||
return SCE_OK;
|
||||
}
|
||||
|
@ -127,10 +127,10 @@ s32 sceKernelExitDeleteThread(ARMv7Context& context, s32 exitStatus)
|
|||
sceLibKernel.Warning("sceKernelExitDeleteThread(exitStatus=0x%x)", exitStatus);
|
||||
|
||||
// exit status is stored in r0
|
||||
context.thread.Stop();
|
||||
static_cast<ARMv7Thread&>(context).Stop();
|
||||
|
||||
// current thread should be deleted
|
||||
const u32 id = context.thread.GetId();
|
||||
const u32 id = static_cast<ARMv7Thread&>(context).GetId();
|
||||
CallAfter([id]()
|
||||
{
|
||||
Emu.GetCPU().RemoveThread(id);
|
||||
|
@ -171,7 +171,7 @@ u32 sceKernelGetThreadId(ARMv7Context& context)
|
|||
{
|
||||
sceLibKernel.Log("sceKernelGetThreadId()");
|
||||
|
||||
return context.thread.GetId();
|
||||
return static_cast<ARMv7Thread&>(context).GetId();
|
||||
}
|
||||
|
||||
s32 sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr)
|
||||
|
@ -287,7 +287,7 @@ s32 sceKernelWaitThreadEnd(s32 threadId, vm::ptr<s32> pExitStatus, vm::ptr<u32>
|
|||
|
||||
if (pExitStatus)
|
||||
{
|
||||
*pExitStatus = thread.context.GPR[0];
|
||||
*pExitStatus = thread.GPR[0];
|
||||
}
|
||||
|
||||
return SCE_OK;
|
||||
|
|
|
@ -243,12 +243,11 @@ namespace sce_libc_func
|
|||
::memset(dst.get_ptr(), value, size);
|
||||
}
|
||||
|
||||
void _Assert(ARMv7Context& context, vm::cptr<char> text, vm::cptr<char> func)
|
||||
void _Assert(vm::cptr<char> text, vm::cptr<char> func)
|
||||
{
|
||||
sceLibc.Error("_Assert(text=*0x%x, func=*0x%x)", text, func);
|
||||
|
||||
LOG_ERROR(TTY, "%s : %s\n", func.get_ptr(), text.get_ptr());
|
||||
LOG_NOTICE(ARMv7, context.thread.RegsToString());
|
||||
Emu.Pause();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,8 +70,10 @@ void execute_psv_func_by_index(ARMv7Context& context, u32 index)
|
|||
{
|
||||
if (auto func = get_psv_func_by_index(index))
|
||||
{
|
||||
auto old_last_syscall = context.thread.m_last_syscall;
|
||||
context.thread.m_last_syscall = func->nid;
|
||||
ARMv7Thread& CPU = static_cast<ARMv7Thread&>(context);
|
||||
|
||||
auto old_last_syscall = CPU.m_last_syscall;
|
||||
CPU.m_last_syscall = func->nid;
|
||||
|
||||
if (func->func)
|
||||
{
|
||||
|
@ -88,7 +90,7 @@ void execute_psv_func_by_index(ARMv7Context& context, u32 index)
|
|||
func->module->on_error(context.GPR[0], func);
|
||||
}
|
||||
|
||||
context.thread.m_last_syscall = old_last_syscall;
|
||||
CPU.m_last_syscall = old_last_syscall;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -231,7 +233,7 @@ void initialize_psv_modules()
|
|||
hle_return.name = "HLE_RETURN";
|
||||
hle_return.func = [](ARMv7Context& context)
|
||||
{
|
||||
context.thread.FastStop();
|
||||
static_cast<ARMv7Thread&>(context).FastStop();
|
||||
};
|
||||
|
||||
// load functions
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
class SPUThread;
|
||||
|
||||
struct SPUContext
|
||||
{
|
||||
u128 gpr[128];
|
||||
|
||||
SPUThread& thread;
|
||||
};
|
||||
|
|
|
@ -659,7 +659,7 @@ namespace vm
|
|||
|
||||
case CPU_THREAD_ARMv7:
|
||||
{
|
||||
ARMv7Context& context = static_cast<ARMv7Thread&>(CPU).context;
|
||||
ARMv7Context& context = static_cast<ARMv7Thread&>(CPU);
|
||||
|
||||
old_pos = context.SP;
|
||||
context.SP -= align(size, 4); // room minimal possible size
|
||||
|
@ -711,7 +711,7 @@ namespace vm
|
|||
|
||||
case CPU_THREAD_ARMv7:
|
||||
{
|
||||
ARMv7Context& context = static_cast<ARMv7Thread&>(CPU).context;
|
||||
ARMv7Context& context = static_cast<ARMv7Thread&>(CPU);
|
||||
|
||||
if (context.SP != addr && !Emu.IsStopped())
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue