Merge pull request #572 from Nekotekina/master

Update
This commit is contained in:
Alexandro Sánchez Bach 2014-07-15 01:06:53 +02:00
commit 75e81bc969
23 changed files with 439 additions and 334 deletions

View file

@ -6,6 +6,12 @@
#define thread_local __thread #define thread_local __thread
#endif #endif
#ifdef _WIN32
#define noinline __declspec(noinline)
#else
#define noinline __attribute__((noinline))
#endif
template<size_t size> template<size_t size>
void strcpy_trunc(char (&dst)[size], const std::string& src) void strcpy_trunc(char (&dst)[size], const std::string& src)
{ {

2
asmjit

@ -1 +1 @@
Subproject commit a66efd54609aab7dd98e34c069937f34aa7c8f95 Subproject commit 3363e4138b003be36dfb63cf8c63cf360f04276f

View file

@ -23,31 +23,55 @@
<ClCompile Include="..\asmjit\src\asmjit\base\codegen.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\codegen.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\compiler.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\compiler.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\constpool.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\constpool.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\containers.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\context.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\context.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\cpuinfo.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\cpuinfo.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\cputicks.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\cputicks.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\error.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\error.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\globals.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\globals.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\intutil.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\logger.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\logger.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\operand.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\operand.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\podvector.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\runtime.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\runtime.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\string.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\string.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\vmem.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\vmem.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\zone.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\zone.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\contrib\winremoteruntime.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86assembler.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\x86\x86assembler.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86compiler.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\x86\x86compiler.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86context.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\x86\x86context.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86cpuinfo.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\x86\x86cpuinfo.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86func.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86inst.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\x86\x86inst.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86operand.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\x86\x86operand.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86regs.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\x86\x86operand_regs.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86util.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\x86\x86scheduler.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\asmjit\src\asmjit\base\assembler.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\codegen.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\compiler.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\constpool.h" /> <ClInclude Include="..\asmjit\src\asmjit\base\constpool.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\containers.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\context_p.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\cpuinfo.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\cputicks.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\error.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\globals.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\intutil.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\lock.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\logger.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\operand.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\runtime.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\string.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\vectypes.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\vmem.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\zone.h" />
<ClInclude Include="..\asmjit\src\asmjit\x86\x86assembler.h" />
<ClInclude Include="..\asmjit\src\asmjit\x86\x86compiler.h" />
<ClInclude Include="..\asmjit\src\asmjit\x86\x86context_p.h" />
<ClInclude Include="..\asmjit\src\asmjit\x86\x86cpuinfo.h" />
<ClInclude Include="..\asmjit\src\asmjit\x86\x86inst.h" />
<ClInclude Include="..\asmjit\src\asmjit\x86\x86operand.h" />
<ClInclude Include="..\asmjit\src\asmjit\x86\x86scheduler_p.h" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{AC40FF01-426E-4838-A317-66354CEFAE88}</ProjectGuid> <ProjectGuid>{AC40FF01-426E-4838-A317-66354CEFAE88}</ProjectGuid>

View file

@ -1,34 +1,58 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup> <ItemGroup>
<ClCompile Include="..\asmjit\src\asmjit\x86\x86assembler.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86compiler.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86context.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86cpuinfo.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86func.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\contrib\winremoteruntime.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\assembler.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\assembler.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\codegen.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\codegen.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\compiler.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\compiler.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\constpool.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\containers.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\context.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\context.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\cpuinfo.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\cpuinfo.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\cputicks.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\cputicks.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\error.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\error.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\globals.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\globals.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\intutil.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\logger.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\logger.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\podvector.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\operand.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\runtime.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\runtime.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\string.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\string.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\vmem.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\vmem.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\zone.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\base\zone.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\constpool.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\x86\x86assembler.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\base\operand.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\x86\x86compiler.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86context.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86cpuinfo.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86inst.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\x86\x86inst.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86operand.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\x86\x86operand.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86regs.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\x86\x86operand_regs.cpp" />
<ClCompile Include="..\asmjit\src\asmjit\x86\x86util.cpp" /> <ClCompile Include="..\asmjit\src\asmjit\x86\x86scheduler.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\asmjit\src\asmjit\x86\x86assembler.h" />
<ClInclude Include="..\asmjit\src\asmjit\x86\x86compiler.h" />
<ClInclude Include="..\asmjit\src\asmjit\x86\x86context_p.h" />
<ClInclude Include="..\asmjit\src\asmjit\x86\x86cpuinfo.h" />
<ClInclude Include="..\asmjit\src\asmjit\x86\x86inst.h" />
<ClInclude Include="..\asmjit\src\asmjit\x86\x86operand.h" />
<ClInclude Include="..\asmjit\src\asmjit\x86\x86scheduler_p.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\assembler.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\codegen.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\compiler.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\constpool.h" /> <ClInclude Include="..\asmjit\src\asmjit\base\constpool.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\containers.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\context_p.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\cpuinfo.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\cputicks.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\error.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\globals.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\intutil.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\lock.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\logger.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\operand.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\runtime.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\string.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\vectypes.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\vmem.h" />
<ClInclude Include="..\asmjit\src\asmjit\base\zone.h" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -21,8 +21,8 @@ public:
virtual u8 DecodeMemory(const u64 address) virtual u8 DecodeMemory(const u64 address)
{ {
using namespace ARMv7_opcodes; using namespace ARMv7_opcodes;
const u16 code0 = Memory.Read16(address); const u16 code0 = Memory.PSV.Read16(address);
const u16 code1 = Memory.Read16(address + 2); const u16 code1 = Memory.PSV.Read16(address + 2);
switch(code0 >> 12) //15 - 12 switch(code0 >> 12) //15 - 12
{ {

View file

@ -275,7 +275,7 @@ protected:
if(regs_list & mask) if(regs_list & mask)
{ {
CPU.SP -= 4; CPU.SP -= 4;
Memory.Write32(CPU.SP, CPU.read_gpr(i)); Memory.PSV.Write32(CPU.SP, CPU.read_gpr(i));
} }
} }
} }
@ -286,7 +286,7 @@ protected:
{ {
if(regs_list & mask) if(regs_list & mask)
{ {
CPU.write_gpr(i, Memory.Read32(CPU.SP)); CPU.write_gpr(i, Memory.PSV.Read32(CPU.SP));
CPU.SP += 4; CPU.SP += 4;
} }
} }

View file

@ -285,7 +285,7 @@ void CPUThread::ExecOnce()
void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp) void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp)
{ {
const u64 addr = (u64)pExp->ExceptionRecord->ExceptionInformation[1] - (u64)Memory.GetBaseAddr(); const u64 addr = (u64)pExp->ExceptionRecord->ExceptionInformation[1] - (u64)Memory.GetBaseAddr();
if (addr < 0x100000000 && u == EXCEPTION_ACCESS_VIOLATION) if (u == EXCEPTION_ACCESS_VIOLATION && addr < 0x100000000)
{ {
// TODO: allow recovering from a page fault // TODO: allow recovering from a page fault
//GetCurrentPPUThread().Stop(); //GetCurrentPPUThread().Stop();
@ -317,6 +317,8 @@ void CPUThread::Task()
} }
} }
std::vector<u64> trace;
#ifdef _WIN32 #ifdef _WIN32
_set_se_translator(_se_translator); _set_se_translator(_se_translator);
#else #else
@ -339,6 +341,7 @@ void CPUThread::Task()
} }
Step(); Step();
//if (PC - 0x13ED4 < 0x288) trace.push_back(PC);
NextPc(m_dec->DecodeMemory(PC + m_offset)); NextPc(m_dec->DecodeMemory(PC + m_offset));
if (status == CPUThread_Step) if (status == CPUThread_Step)
@ -357,6 +360,8 @@ void CPUThread::Task()
} }
} }
for (auto& v : trace) LOG_NOTICE(PPU, "PC = 0x%llx", v);
if (Ini.HLELogging.GetValue()) LOG_NOTICE(PPU, "%s leave", CPUThread::GetFName().c_str()); if (Ini.HLELogging.GetValue()) LOG_NOTICE(PPU, "%s leave", CPUThread::GetFName().c_str());
} }

View file

@ -148,7 +148,7 @@ public:
if (#a1[0] == 'r') XmmInvalidate(a1); \ if (#a1[0] == 'r') XmmInvalidate(a1); \
if (#a2[0] == 'r') XmmInvalidate(a2); \ if (#a2[0] == 'r') XmmInvalidate(a2); \
if (#a3[0] == 'r') XmmInvalidate(a3); \ if (#a3[0] == 'r') XmmInvalidate(a3); \
X86X64CallNode* call##a0 = c.call(imm_ptr(reinterpret_cast<void*>(&opwr_##a0::opcode)), kFuncConvHost, FuncBuilder4<FnVoid, u32, u32, u32, u32>()); \ X86CallNode* call##a0 = c.call(imm_ptr(reinterpret_cast<void*>(&opwr_##a0::opcode)), kFuncConvHost, FuncBuilder4<void, u32, u32, u32, u32>()); \
call##a0->setArg(0, imm_u(a0)); \ call##a0->setArg(0, imm_u(a0)); \
call##a0->setArg(1, imm_u(a1)); \ call##a0->setArg(1, imm_u(a1)); \
call##a0->setArg(2, imm_u(a2)); \ call##a0->setArg(2, imm_u(a2)); \
@ -163,24 +163,24 @@ private:
SPURecompilerCore& rec; SPURecompilerCore& rec;
public: public:
Compiler* compiler; X86Compiler* compiler;
bool do_finalize; bool do_finalize;
// input: // input:
GpVar* cpu_var; X86GpVar* cpu_var;
GpVar* ls_var; X86GpVar* ls_var;
GpVar* imm_var; X86GpVar* imm_var;
GpVar* g_imm_var; X86GpVar* g_imm_var;
// output: // output:
GpVar* pos_var; X86GpVar* pos_var;
// temporary: // temporary:
GpVar* addr; X86GpVar* addr;
GpVar* qw0; X86GpVar* qw0;
GpVar* qw1; X86GpVar* qw1;
GpVar* qw2; X86GpVar* qw2;
struct XmmLink struct XmmLink
{ {
XmmVar* data; X86XmmVar* data;
s8 reg; s8 reg;
bool taken; bool taken;
mutable bool got; mutable bool got;
@ -443,7 +443,7 @@ private:
} }
}; };
c.mov(cpu_qword(PC), (u32)CPU.PC); c.mov(cpu_qword(PC), (u32)CPU.PC);
X86X64CallNode* call = c.call(imm_ptr(reinterpret_cast<void*>(&STOP_wrapper::STOP)), kFuncConvHost, FuncBuilder1<FnVoid, u32>()); X86CallNode* call = c.call(imm_ptr(reinterpret_cast<void*>(&STOP_wrapper::STOP)), kFuncConvHost, FuncBuilder1<void, u32>());
call->setArg(0, imm_u(code)); call->setArg(0, imm_u(code));
c.mov(*pos_var, (CPU.PC >> 2) + 1); c.mov(*pos_var, (CPU.PC >> 2) + 1);
do_finalize = true; do_finalize = true;
@ -1114,7 +1114,7 @@ private:
/*XmmInvalidate(rt); /*XmmInvalidate(rt);
GpVar v(c, kVarTypeUInt32); X86GpVar v(c, kVarTypeUInt32);
c.mov(v, cpu_dword(GPR[rt]._u32[3])); c.mov(v, cpu_dword(GPR[rt]._u32[3]));
switch (ra) switch (ra)
{ {

View file

@ -13,12 +13,19 @@
static const g_imm_table_struct g_imm_table; static const g_imm_table_struct g_imm_table;
SPURecompilerCore::SPURecompilerCore(SPUThread& cpu) SPURecompilerCore::SPURecompilerCore(SPUThread& cpu)
: m_enc(new SPURecompiler(cpu, *this)) : m_enc(new SPURecompiler(cpu, *this))
, inter(new SPUInterpreter(cpu)) , inter(new SPUInterpreter(cpu))
, CPU(cpu) , CPU(cpu)
, first(true) , first(true)
{ {
memset(entry, 0, sizeof(entry)); memset(entry, 0, sizeof(entry));
X86CpuInfo inf;
X86CpuUtil::detect(&inf);
if (!inf.hasFeature(kX86CpuFeatureSse41))
{
LOG_ERROR(SPU, "SPU Recompiler requires SSE4.1 instruction set support");
Emu.Pause();
}
} }
SPURecompilerCore::~SPURecompilerCore() SPURecompilerCore::~SPURecompilerCore()
@ -42,7 +49,7 @@ void SPURecompilerCore::Compile(u16 pos)
StringLogger stringLogger; StringLogger stringLogger;
stringLogger.setOption(kLoggerOptionBinaryForm, true); stringLogger.setOption(kLoggerOptionBinaryForm, true);
Compiler compiler(&runtime); X86Compiler compiler(&runtime);
m_enc->compiler = &compiler; m_enc->compiler = &compiler;
compiler.setLogger(&stringLogger); compiler.setLogger(&stringLogger);
@ -51,40 +58,40 @@ void SPURecompilerCore::Compile(u16 pos)
u32 excess = 0; u32 excess = 0;
entry[start].count = 0; entry[start].count = 0;
GpVar cpu_var(compiler, kVarTypeIntPtr, "cpu"); X86GpVar cpu_var(compiler, kVarTypeIntPtr, "cpu");
compiler.setArg(0, cpu_var); compiler.setArg(0, cpu_var);
compiler.alloc(cpu_var); compiler.alloc(cpu_var);
m_enc->cpu_var = &cpu_var; m_enc->cpu_var = &cpu_var;
GpVar ls_var(compiler, kVarTypeIntPtr, "ls"); X86GpVar ls_var(compiler, kVarTypeIntPtr, "ls");
compiler.setArg(1, ls_var); compiler.setArg(1, ls_var);
compiler.alloc(ls_var); compiler.alloc(ls_var);
m_enc->ls_var = &ls_var; m_enc->ls_var = &ls_var;
GpVar imm_var(compiler, kVarTypeIntPtr, "imm"); X86GpVar imm_var(compiler, kVarTypeIntPtr, "imm");
compiler.setArg(2, imm_var); compiler.setArg(2, imm_var);
compiler.alloc(imm_var); compiler.alloc(imm_var);
m_enc->imm_var = &imm_var; m_enc->imm_var = &imm_var;
GpVar g_imm_var(compiler, kVarTypeIntPtr, "g_imm"); X86GpVar g_imm_var(compiler, kVarTypeIntPtr, "g_imm");
compiler.setArg(3, g_imm_var); compiler.setArg(3, g_imm_var);
compiler.alloc(g_imm_var); compiler.alloc(g_imm_var);
m_enc->g_imm_var = &g_imm_var; m_enc->g_imm_var = &g_imm_var;
GpVar pos_var(compiler, kVarTypeUInt32, "pos"); X86GpVar pos_var(compiler, kVarTypeUInt32, "pos");
m_enc->pos_var = &pos_var; m_enc->pos_var = &pos_var;
GpVar addr_var(compiler, kVarTypeUInt32, "addr"); X86GpVar addr_var(compiler, kVarTypeUInt32, "addr");
m_enc->addr = &addr_var; m_enc->addr = &addr_var;
GpVar qw0_var(compiler, kVarTypeUInt64, "qw0"); X86GpVar qw0_var(compiler, kVarTypeUInt64, "qw0");
m_enc->qw0 = &qw0_var; m_enc->qw0 = &qw0_var;
GpVar qw1_var(compiler, kVarTypeUInt64, "qw1"); X86GpVar qw1_var(compiler, kVarTypeUInt64, "qw1");
m_enc->qw1 = &qw1_var; m_enc->qw1 = &qw1_var;
GpVar qw2_var(compiler, kVarTypeUInt64, "qw2"); X86GpVar qw2_var(compiler, kVarTypeUInt64, "qw2");
m_enc->qw2 = &qw2_var; m_enc->qw2 = &qw2_var;
for (u32 i = 0; i < 16; i++) for (u32 i = 0; i < 16; i++)
{ {
m_enc->xmm_var[i].data = new XmmVar(compiler, kVarTypeXmm, fmt::Format("reg_%d", i).c_str()); m_enc->xmm_var[i].data = new X86XmmVar(compiler, kX86VarTypeXmm, fmt::Format("reg_%d", i).c_str());
} }
compiler.xor_(pos_var, pos_var); compiler.xor_(pos_var, pos_var);

View file

@ -362,7 +362,7 @@ public:
void Init() void Init()
{ {
m_index = 0; m_indval = 0;
} }
__forceinline bool Pop(u32& res) __forceinline bool Pop(u32& res)

View file

@ -364,193 +364,7 @@ bool MemoryBlockLE::Write128(const u64 addr, const u128 value)
return true; return true;
} }
//MemoryBase // MemoryBase
void MemoryBase::Write8(u64 addr, const u8 data)
{
if ((u32)addr == addr)
{
*(u8*)((u64)GetBaseAddr() + addr) = data;
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
}
}
void MemoryBase::Write16(u64 addr, const u16 data)
{
if ((u32)addr == addr)
{
*(u16*)((u64)GetBaseAddr() + addr) = re16(data);
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
}
}
void MemoryBase::Write32(u64 addr, const u32 data)
{
if ((u32)addr == addr)
{
if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET])
{
*(u32*)((u64)GetBaseAddr() + addr) = re32(data);
}
else
{
RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Write32(addr, data);
}
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
}
}
void MemoryBase::Write64(u64 addr, const u64 data)
{
if ((u32)addr == addr)
{
*(u64*)((u64)GetBaseAddr() + addr) = re64(data);
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
}
}
void MemoryBase::Write128(u64 addr, const u128 data)
{
if ((u32)addr == addr)
{
*(u128*)((u64)GetBaseAddr() + addr) = re128(data);
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
}
}
bool MemoryBase::Write8NN(u64 addr, const u8 data)
{
if(!IsGoodAddr(addr)) return false;
Write8(addr, data);
return true;
}
bool MemoryBase::Write16NN(u64 addr, const u16 data)
{
if(!IsGoodAddr(addr, 2)) return false;
Write16(addr, data);
return true;
}
bool MemoryBase::Write32NN(u64 addr, const u32 data)
{
if(!IsGoodAddr(addr, 4)) return false;
Write32(addr, data);
return true;
}
bool MemoryBase::Write64NN(u64 addr, const u64 data)
{
if(!IsGoodAddr(addr, 8)) return false;
Write64(addr, data);
return true;
}
bool MemoryBase::Write128NN(u64 addr, const u128 data)
{
if(!IsGoodAddr(addr, 16)) return false;
Write128(addr, data);
return true;
}
u8 MemoryBase::Read8(u64 addr)
{
if ((u32)addr == addr)
{
return *(u8*)((u64)GetBaseAddr() + addr);
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
return 0;
}
}
u16 MemoryBase::Read16(u64 addr)
{
if ((u32)addr == addr)
{
return re16(*(u16*)((u64)GetBaseAddr() + addr));
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
return 0;
}
}
u32 MemoryBase::Read32(u64 addr)
{
if ((u32)addr == addr)
{
if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET])
{
return re32(*(u32*)((u64)GetBaseAddr() + addr));
}
else
{
u32 res;
RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Read32(addr, &res);
return res;
}
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
return 0;
}
}
u64 MemoryBase::Read64(u64 addr)
{
if ((u32)addr == addr)
{
return re64(*(u64*)((u64)GetBaseAddr() + addr));
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
return 0;
}
}
u128 MemoryBase::Read128(u64 addr)
{
if ((u32)addr == addr)
{
return re128(*(u128*)((u64)GetBaseAddr() + addr));
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
return u128::From128(0, 0);
}
}
template<> __forceinline u64 MemoryBase::ReverseData<1>(u64 val) { return val; } template<> __forceinline u64 MemoryBase::ReverseData<1>(u64 val) { return val; }
template<> __forceinline u64 MemoryBase::ReverseData<2>(u64 val) { return Reverse16(val); } template<> __forceinline u64 MemoryBase::ReverseData<2>(u64 val) { return Reverse16(val); }
template<> __forceinline u64 MemoryBase::ReverseData<4>(u64 val) { return Reverse32(val); } template<> __forceinline u64 MemoryBase::ReverseData<4>(u64 val) { return Reverse32(val); }

View file

@ -52,20 +52,43 @@ public:
MemoryBlock* RawSPUMem[(0x100000000 - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]; MemoryBlock* RawSPUMem[(0x100000000 - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET];
VirtualMemoryBlock RSXIOMem; VirtualMemoryBlock RSXIOMem;
struct struct Wrapper32LE
{
private:
void* m_base_addr;
public:
Wrapper32LE() : m_base_addr(nullptr) {}
void Write8(const u32 addr, const u8 data) { *(u8*)((u8*)m_base_addr + addr) = data; }
void Write16(const u32 addr, const u16 data) { *(u16*)((u8*)m_base_addr + addr) = data; }
void Write32(const u32 addr, const u32 data) { *(u32*)((u8*)m_base_addr + addr) = data; }
void Write64(const u32 addr, const u64 data) { *(u64*)((u8*)m_base_addr + addr) = data; }
void Write128(const u32 addr, const u128 data) { *(u128*)((u8*)m_base_addr + addr) = data; }
u8 Read8(const u32 addr) { return *(u8*)((u8*)m_base_addr + addr); }
u16 Read16(const u32 addr) { return *(u16*)((u8*)m_base_addr + addr); }
u32 Read32(const u32 addr) { return *(u32*)((u8*)m_base_addr + addr); }
u64 Read64(const u32 addr) { return *(u64*)((u8*)m_base_addr + addr); }
u128 Read128(const u32 addr) { return *(u128*)((u8*)m_base_addr + addr); }
void Init(void* real_addr) { m_base_addr = real_addr; }
};
struct : Wrapper32LE
{ {
DynamicMemoryBlockLE RAM; DynamicMemoryBlockLE RAM;
DynamicMemoryBlockLE Userspace; DynamicMemoryBlockLE Userspace;
} PSVMemory; } PSV;
struct struct : Wrapper32LE
{ {
DynamicMemoryBlockLE Scratchpad; DynamicMemoryBlockLE Scratchpad;
DynamicMemoryBlockLE VRAM; DynamicMemoryBlockLE VRAM;
DynamicMemoryBlockLE RAM; DynamicMemoryBlockLE RAM;
DynamicMemoryBlockLE Kernel; DynamicMemoryBlockLE Kernel;
DynamicMemoryBlockLE Userspace; DynamicMemoryBlockLE Userspace;
} PSPMemory; } PSP;
bool m_inited; bool m_inited;
@ -84,17 +107,26 @@ public:
return m_base_addr; return m_base_addr;
} }
noinline void InvalidAddress(const char* func, const u64 addr)
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", func, addr);
}
void RegisterPages(u64 addr, u32 size) void RegisterPages(u64 addr, u32 size)
{ {
std::lock_guard<std::recursive_mutex> lock(m_mutex); std::lock_guard<std::recursive_mutex> lock(m_mutex);
//LOG_NOTICE(MEMORY, "RegisterPages(addr=0x%llx, size=0x%x)", addr, size); //LOG_NOTICE(MEMORY, "RegisterPages(addr=0x%llx, size=0x%x)", addr, size);
for (u32 i = addr / 4096; i < (addr + size) / 4096; i++) for (u64 i = addr / 4096; i < (addr + size) / 4096; i++)
{ {
if (i >= sizeof(m_pages) / sizeof(m_pages[0])) break; if (i >= sizeof(m_pages) / sizeof(m_pages[0]))
{
InvalidAddress(__FUNCTION__, i * 4096);
break;
}
if (m_pages[i]) if (m_pages[i])
{ {
LOG_ERROR(MEMORY, "Page already registered (page=0x%x)", i * 4096); LOG_ERROR(MEMORY, "Page already registered (addr=0x%llx)", i * 4096);
} }
m_pages[i] = 1; // TODO: define page parameters m_pages[i] = 1; // TODO: define page parameters
} }
@ -105,12 +137,16 @@ public:
std::lock_guard<std::recursive_mutex> lock(m_mutex); std::lock_guard<std::recursive_mutex> lock(m_mutex);
//LOG_NOTICE(MEMORY, "UnregisterPages(addr=0x%llx, size=0x%x)", addr, size); //LOG_NOTICE(MEMORY, "UnregisterPages(addr=0x%llx, size=0x%x)", addr, size);
for (u32 i = addr / 4096; i < (addr + size) / 4096; i++) for (u64 i = addr / 4096; i < (addr + size) / 4096; i++)
{ {
if (i >= sizeof(m_pages) / sizeof(m_pages[0])) break; if (i >= sizeof(m_pages) / sizeof(m_pages[0]))
{
InvalidAddress(__FUNCTION__, i * 4096);
break;
}
if (!m_pages[i]) if (!m_pages[i])
{ {
LOG_ERROR(MEMORY, "Page not registered (page=0x%x)", i * 4096); LOG_ERROR(MEMORY, "Page not registered (addr=0x%llx)", i * 4096);
} }
m_pages[i] = 0; // TODO: define page parameters m_pages[i] = 0; // TODO: define page parameters
} }
@ -146,17 +182,25 @@ public:
return (T)ReverseData<sizeof(T)>(val); return (T)ReverseData<sizeof(T)>(val);
}; };
u8* GetMemFromAddr(const u64 addr) template<typename T> u8* GetMemFromAddr(const T addr)
{
if ((u32)addr == addr)
{ {
return (u8*)GetBaseAddr() + addr; return (u8*)GetBaseAddr() + addr;
} }
else
void* VirtualToRealAddr(const u64 vaddr)
{ {
return GetMemFromAddr(vaddr); InvalidAddress(__FUNCTION__, addr);
return (u8*)GetBaseAddr();
}
} }
u64 RealToVirtualAddr(const void* addr) template<typename T> void* VirtualToRealAddr(const T vaddr)
{
return GetMemFromAddr<T>(vaddr);
}
u32 RealToVirtualAddr(const void* addr)
{ {
const u64 res = (u64)addr - (u64)GetBaseAddr(); const u64 res = (u64)addr - (u64)GetBaseAddr();
@ -233,25 +277,27 @@ public:
break; break;
case Memory_PSV: case Memory_PSV:
MemoryBlocks.push_back(PSVMemory.RAM.SetRange(0x81000000, 0x10000000)); MemoryBlocks.push_back(PSV.RAM.SetRange(0x81000000, 0x10000000));
MemoryBlocks.push_back(UserMemory = PSVMemory.Userspace.SetRange(0x91000000, 0x10000000)); MemoryBlocks.push_back(UserMemory = PSV.Userspace.SetRange(0x91000000, 0x10000000));
PSV.Init(GetBaseAddr());
break; break;
case Memory_PSP: case Memory_PSP:
MemoryBlocks.push_back(PSPMemory.Scratchpad.SetRange(0x00010000, 0x00004000)); MemoryBlocks.push_back(PSP.Scratchpad.SetRange(0x00010000, 0x00004000));
MemoryBlocks.push_back(PSPMemory.VRAM.SetRange(0x04000000, 0x00200000)); MemoryBlocks.push_back(PSP.VRAM.SetRange(0x04000000, 0x00200000));
MemoryBlocks.push_back(PSPMemory.RAM.SetRange(0x08000000, 0x02000000)); MemoryBlocks.push_back(PSP.RAM.SetRange(0x08000000, 0x02000000));
MemoryBlocks.push_back(PSPMemory.Kernel.SetRange(0x88000000, 0x00800000)); MemoryBlocks.push_back(PSP.Kernel.SetRange(0x88000000, 0x00800000));
MemoryBlocks.push_back(UserMemory = PSPMemory.Userspace.SetRange(0x08800000, 0x01800000)); MemoryBlocks.push_back(UserMemory = PSP.Userspace.SetRange(0x08800000, 0x01800000));
PSP.Init(GetBaseAddr());
break; break;
} }
LOG_NOTICE(MEMORY, "Memory initialized."); LOG_NOTICE(MEMORY, "Memory initialized.");
} }
bool IsGoodAddr(const u64 addr) template<typename T> bool IsGoodAddr(const T addr)
{ {
if (addr >= 0x100000000 || !m_pages[addr / 4096]) // TODO: define page parameters if ((u32)addr != addr || !m_pages[addr / 4096]) // TODO: define page parameters
{ {
return false; return false;
} }
@ -261,9 +307,9 @@ public:
} }
} }
bool IsGoodAddr(const u64 addr, const u32 size) template<typename T> bool IsGoodAddr(const T addr, const u32 size)
{ {
if (addr + size > 0x100000000) if ((u32)addr != addr || (u64)addr + (u64)size > 0x100000000ull)
{ {
return false; return false;
} }
@ -308,23 +354,152 @@ public:
#endif #endif
} }
void Write8(const u64 addr, const u8 data); //MemoryBase
void Write16(const u64 addr, const u16 data); template<typename T> void Write8(T addr, const u8 data)
void Write32(const u64 addr, const u32 data); {
void Write64(const u64 addr, const u64 data); if ((u32)addr == addr)
void Write128(const u64 addr, const u128 data); {
*(u8*)((u8*)GetBaseAddr() + addr) = data;
}
else
{
InvalidAddress(__FUNCTION__, addr);
*(u8*)GetBaseAddr() = data;
}
}
bool Write8NN(const u64 addr, const u8 data); template<typename T> void Write16(T addr, const u16 data)
bool Write16NN(const u64 addr, const u16 data); {
bool Write32NN(const u64 addr, const u32 data); if ((u32)addr == addr)
bool Write64NN(const u64 addr, const u64 data); {
bool Write128NN(const u64 addr, const u128 data); *(u16*)((u8*)GetBaseAddr() + addr) = re16(data);
}
else
{
InvalidAddress(__FUNCTION__, addr);
*(u16*)GetBaseAddr() = data;
}
}
u8 Read8(const u64 addr); template<typename T> void Write32(T addr, const u32 data)
u16 Read16(const u64 addr); {
u32 Read32(const u64 addr); if ((u32)addr == addr)
u64 Read64(const u64 addr); {
u128 Read128(const u64 addr); if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET])
{
*(u32*)((u8*)GetBaseAddr() + addr) = re32(data);
}
else
{
RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Write32(addr, data);
}
}
else
{
InvalidAddress(__FUNCTION__, addr);
*(u32*)GetBaseAddr() = data;
}
}
template<typename T> void Write64(T addr, const u64 data)
{
if ((u32)addr == addr)
{
*(u64*)((u8*)GetBaseAddr() + addr) = re64(data);
}
else
{
InvalidAddress(__FUNCTION__, addr);
*(u64*)GetBaseAddr() = data;
}
}
template<typename T> void Write128(T addr, const u128 data)
{
if ((u32)addr == addr)
{
*(u128*)((u8*)GetBaseAddr() + addr) = re128(data);
}
else
{
InvalidAddress(__FUNCTION__, addr);
*(u128*)GetBaseAddr() = data;
}
}
template<typename T> u8 Read8(T addr)
{
if ((u32)addr == addr)
{
return *(u8*)((u8*)GetBaseAddr() + addr);
}
else
{
InvalidAddress(__FUNCTION__, addr);
return *(u8*)GetBaseAddr();
}
}
template<typename T> u16 Read16(T addr)
{
if ((u32)addr == addr)
{
return re16(*(u16*)((u8*)GetBaseAddr() + addr));
}
else
{
InvalidAddress(__FUNCTION__, addr);
return *(u16*)GetBaseAddr();
}
}
template<typename T> u32 Read32(T addr)
{
if ((u32)addr == addr)
{
if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET])
{
return re32(*(u32*)((u8*)GetBaseAddr() + addr));
}
else
{
u32 res;
RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Read32(addr, &res);
return res;
}
}
else
{
InvalidAddress(__FUNCTION__, addr);
return *(u32*)GetBaseAddr();
}
}
template<typename T> u64 Read64(T addr)
{
if ((u32)addr == addr)
{
return re64(*(u64*)((u8*)GetBaseAddr() + addr));
}
else
{
InvalidAddress(__FUNCTION__, addr);
return *(u64*)GetBaseAddr();
}
}
template<typename T> u128 Read128(T addr)
{
if ((u32)addr == addr)
{
return re128(*(u128*)((u8*)GetBaseAddr() + addr));
}
else
{
InvalidAddress(__FUNCTION__, addr);
return *(u128*)GetBaseAddr();
}
}
bool CopyToReal(void* real, u64 from, u32 count) bool CopyToReal(void* real, u64 from, u32 count)
{ {
@ -469,13 +644,13 @@ public:
return false; return false;
} }
u8* operator + (const u64 vaddr) template<typename T> u8* operator + (const T vaddr)
{ {
u8* ret = GetMemFromAddr(vaddr); u8* ret = GetMemFromAddr<T>(vaddr);
return ret; return ret;
} }
u8& operator[] (const u64 vaddr) template<typename T> u8& operator[] (const T vaddr)
{ {
return *(*this + vaddr); return *(*this + vaddr);
} }

View file

@ -4,6 +4,7 @@
#include "Emu/System.h" #include "Emu/System.h"
#include "Callback.h" #include "Callback.h"
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/PPCThread.h" #include "Emu/Cell/PPCThread.h"
Callback::Callback(u32 slot, u64 addr) Callback::Callback(u32 slot, u64 addr)
@ -13,6 +14,7 @@ Callback::Callback(u32 slot, u64 addr)
, a2(0) , a2(0)
, a3(0) , a3(0)
, a4(0) , a4(0)
, a5(0)
, m_has_data(false) , m_has_data(false)
, m_name("Callback") , m_name("Callback")
{ {
@ -43,12 +45,13 @@ bool Callback::HasData() const
return m_has_data; return m_has_data;
} }
void Callback::Handle(u64 _a1, u64 _a2, u64 _a3, u64 _a4) void Callback::Handle(u64 _a1, u64 _a2, u64 _a3, u64 _a4, u64 _a5)
{ {
a1 = _a1; a1 = _a1;
a2 = _a2; a2 = _a2;
a3 = _a3; a3 = _a3;
a4 = _a4; a4 = _a4;
a5 = _a5;
m_has_data = true; m_has_data = true;
} }
@ -97,6 +100,7 @@ again:
thr.SetArg(2, a3); thr.SetArg(2, a3);
thr.SetArg(3, a4); thr.SetArg(3, a4);
thr.Run(); thr.Run();
((PPUThread&)thr).GPR[7] = a5;
thr.Exec(); thr.Exec();

View file

@ -15,6 +15,7 @@ public:
u64 a2; u64 a2;
u64 a3; u64 a3;
u64 a4; u64 a4;
u64 a5;
u32 GetSlot() const; u32 GetSlot() const;
u64 GetAddr() const; u64 GetAddr() const;
@ -23,7 +24,7 @@ public:
bool HasData() const; bool HasData() const;
Callback(u32 slot = 0, u64 addr = 0); Callback(u32 slot = 0, u64 addr = 0);
void Handle(u64 a1 = 0, u64 a2 = 0, u64 a3 = 0, u64 a4 = 0); void Handle(u64 a1 = 0, u64 a2 = 0, u64 a3 = 0, u64 a4 = 0, u64 a5 = 0);
u64 Branch(bool wait); u64 Branch(bool wait);
void SetName(const std::string& name); void SetName(const std::string& name);

View file

@ -44,7 +44,7 @@ int UTF16stoUTF8s(mem16_ptr_t utf16, mem64_t utf16_len, mem8_ptr_t utf8, mem64_t
if (!utf16.IsGood() || !utf16_len.IsGood() || !utf8_len.IsGood()) if (!utf16.IsGood() || !utf16_len.IsGood() || !utf8_len.IsGood())
return SRCIllegal; return SRCIllegal;
std::u16string wstr =(char16_t*)Memory.VirtualToRealAddr(utf16); std::u16string wstr =(char16_t*)Memory.VirtualToRealAddr(utf16.GetAddr());
wstr.resize(utf16_len.GetValue()); // TODO: Is this really the role of utf16_len in this function? wstr.resize(utf16_len.GetValue()); // TODO: Is this really the role of utf16_len in this function?
#ifdef _MSC_VER #ifdef _MSC_VER
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> convert; std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> convert;

View file

@ -361,7 +361,7 @@ int cellSurMixerCreate(const mem_ptr_t<CellSurMixerConfig> config)
break; break;
} }
if (mixcount > (port.tag + 14)) // preemptive buffer filling (probably hack) if (mixcount > (port.tag + 0)) // adding positive value (1-15): preemptive buffer filling (hack)
{ {
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue; continue;
@ -531,7 +531,8 @@ int cellSurMixerStart()
int cellSurMixerSetParameter(u32 param, float value) int cellSurMixerSetParameter(u32 param, float value)
{ {
libmixer->Error("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value); declCPU();
libmixer->Error("cellSurMixerSetParameter(param=0x%x, value=%f, FPR[1]=%f, FPR[2]=%f)", param, value, (float&)CPU.FPR[1], (float&)CPU.FPR[2]);
return CELL_OK; return CELL_OK;
} }
@ -559,8 +560,7 @@ int cellSurMixerSurBusAddData(u32 busNo, u32 offset, u32 addr, u32 samples)
} }
else else
{ {
libmixer->Error("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples); libmixer->Error("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d): unknown parameters", busNo, offset, addr, samples);
Emu.Pause();
return CELL_OK; return CELL_OK;
} }

View file

@ -205,20 +205,19 @@ s32 sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, s32 prio, u32 s
return CELL_OK; return CELL_OK;
} }
void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry) void sys_ppu_thread_once(mem_ptr_t<std::atomic<be_t<u32>>> once_ctrl, u32 entry)
{ {
sysPrxForUser->Warning("sys_ppu_thread_once(once_ctrl_addr=0x%x, entry=0x%x)", once_ctrl_addr, entry); sysPrxForUser->Warning("sys_ppu_thread_once(once_ctrl_addr=0x%x, entry=0x%x)", once_ctrl.GetAddr(), entry);
if(Memory.IsGoodAddr(once_ctrl_addr, 4) && Memory.Read32(once_ctrl_addr) == SYS_PPU_THREAD_ONCE_INIT) be_t<u32> old = SYS_PPU_THREAD_ONCE_INIT;
if (once_ctrl->compare_exchange_weak(old, SYS_PPU_THREAD_DONE_INIT))
{ {
Memory.Write32(once_ctrl_addr, SYS_PPU_THREAD_DONE_INIT);
CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU);
new_thread.SetEntry(entry); new_thread.SetEntry(entry);
new_thread.Run(); new_thread.Run();
new_thread.Exec(); new_thread.Exec();
//GetCurrentPPUThread().Wait(new_thread); while (new_thread.IsAlive()) SM_Sleep();
} }
} }

View file

@ -24,5 +24,5 @@ s32 sys_ppu_thread_get_stack_information(u32 info_addr);
s32 sys_ppu_thread_stop(u64 thread_id); s32 sys_ppu_thread_stop(u64 thread_id);
s32 sys_ppu_thread_restart(u64 thread_id); s32 sys_ppu_thread_restart(u64 thread_id);
s32 sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, u32 threadname_addr); s32 sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, u32 threadname_addr);
void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry); void sys_ppu_thread_once(mem_ptr_t<std::atomic<be_t<u32>>> once_ctrl, u32 entry);
s32 sys_ppu_thread_get_id(const u32 id_addr); s32 sys_ppu_thread_get_id(const u32 id_addr);

View file

@ -597,7 +597,7 @@ s32 sys_spu_thread_connect_event(u32 id, u32 eq_id, u32 et, u8 spup)
return CELL_EINVAL; return CELL_EINVAL;
} }
// TODO: check if can receive this events // TODO: check if can receive these events
SPUThread& spu = *(SPUThread*)thr; SPUThread& spu = *(SPUThread*)thr;
@ -706,51 +706,82 @@ s32 sys_spu_thread_unbind_queue(u32 id, u32 spuq_num)
return CELL_OK; return CELL_OK;
} }
s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32 spup_addr) s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq_id, u64 req, mem8_t spup)
{ {
sc_spu.Error("sys_spu_thread_group_connect_event_all_threads(id=%d, eq=%d, req=0x%llx, spup_addr=0x%x)", sc_spu.Warning("sys_spu_thread_group_connect_event_all_threads(id=%d, eq_id=%d, req=0x%llx, spup_addr=0x%x)",
id, eq, req, spup_addr); id, eq_id, req, spup.GetAddr());
EventQueue* equeue; if (!spup.IsGood())
if(!sys_event.CheckId(eq, equeue)) {
return CELL_EFAULT;
}
EventQueue* eq;
if (!Emu.GetIdManager().GetIDData(eq_id, eq))
{ {
return CELL_ESRCH; return CELL_ESRCH;
} }
if(!req) if (!req)
{ {
return CELL_EINVAL; return CELL_EINVAL;
} }
SpuGroupInfo* group; SpuGroupInfo* group;
if(!Emu.GetIdManager().GetIDData(id, group)) if (!Emu.GetIdManager().GetIDData(id, group))
{ {
return CELL_ESRCH; return CELL_ESRCH;
} }
/* std::vector<SPUThread*> threads;
for(u32 i=0; i<group->list.size(); ++i) for (auto& v : group->list)
{ {
CPUThread* t; if (!v) continue;
if(t = Emu.GetCPU().GetThread(group->list[i])) CPUThread* thr = Emu.GetCPU().GetThread(v);
if (thr->GetType() != CPU_THREAD_SPU)
{ {
bool finded_port = false; sc_spu.Error("sys_spu_thread_group_connect_event_all_threads(): CELL_ESTAT (wrong thread type)");
for(int j=0; j<equeue->pos; ++j) return CELL_ESTAT;
{
if(!equeue->ports[j]->thread)
{
finded_port = true;
equeue->ports[j]->thread = t;
} }
threads.push_back((SPUThread*)thr);
} }
if(!finded_port) if (threads.size() != group->m_count)
{ {
sc_spu.Error("sys_spu_thread_group_connect_event_all_threads(): CELL_ESTAT (%d from %d)", (u32)threads.size(), group->m_count);
return CELL_ESTAT;
}
for (u32 i = 0; i < 64; i++) // port number
{
bool found = true;
if (req & (1ull << i))
{
for (auto& t : threads) t->SPUPs[i].m_mutex.lock();
for (auto& t : threads) if (t->SPUPs[i].eq) found = false;
if (found)
{
for (auto& t : threads)
{
eq->ports.add(&(t->SPUPs[i]));
t->SPUPs[i].eq = eq;
}
spup = (u8)i;
}
for (auto& t : threads) t->SPUPs[i].m_mutex.unlock();
}
else
{
found = false;
}
if (found) return CELL_OK;
}
return CELL_EISCONN; return CELL_EISCONN;
}
}
}*/
return CELL_OK;
} }
s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup) s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup)

View file

@ -64,6 +64,7 @@ struct SpuGroupInfo
int m_prio; int m_prio;
int m_type; int m_type;
int m_ct; int m_ct;
u32 m_count;
SpuGroupInfo(const std::string& name, u32 num, int prio, int type, u32 ct) SpuGroupInfo(const std::string& name, u32 num, int prio, int type, u32 ct)
: m_name(name) : m_name(name)
@ -71,13 +72,10 @@ struct SpuGroupInfo
, m_type(type) , m_type(type)
, m_ct(ct) , m_ct(ct)
, lock(0) , lock(0)
, m_count(num)
{ {
num = 256; list.resize(256);
list.resize(num); for (auto& v : list) v = 0;
for (u32 i = 0; i < num; i++)
{
list[i] = 0;
}
} }
}; };
@ -95,7 +93,7 @@ s32 sys_spu_thread_create(mem32_t thread_id, mem32_t entry, u64 arg, int prio, u
s32 sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status); s32 sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status);
s32 sys_spu_thread_group_connect_event(u32 id, u32 eq, u32 et); s32 sys_spu_thread_group_connect_event(u32 id, u32 eq, u32 et);
s32 sys_spu_thread_group_disconnect_event(u32 id, u32 et); s32 sys_spu_thread_group_disconnect_event(u32 id, u32 et);
s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32 spup_addr); s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq_id, u64 req, mem8_t spup);
s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup); s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup);
s32 sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type); s32 sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type);
s32 sys_spu_thread_read_ls(u32 id, u32 address, mem64_t value, u32 type); s32 sys_spu_thread_read_ls(u32 id, u32 address, mem64_t value, u32 type);

View file

@ -103,8 +103,16 @@ s32 sys_timer_disconnect_event_queue(u32 timer_id)
s32 sys_timer_sleep(u32 sleep_time) s32 sys_timer_sleep(u32 sleep_time)
{ {
sys_timer.Warning("sys_timer_sleep(sleep_time=%d)", sleep_time); sys_timer.Log("sys_timer_sleep(sleep_time=%d)", sleep_time);
std::this_thread::sleep_for(std::chrono::seconds(sleep_time)); for (u32 i = 0; i < sleep_time; i++)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
if (Emu.IsStopped())
{
sys_timer.Warning("sys_timer_sleep(sleep_time=%d) aborted", sleep_time);
return CELL_OK;
}
}
return CELL_OK; return CELL_OK;
} }
@ -112,6 +120,15 @@ s32 sys_timer_usleep(u64 sleep_time)
{ {
sys_timer.Log("sys_timer_usleep(sleep_time=%lld)", sleep_time); sys_timer.Log("sys_timer_usleep(sleep_time=%lld)", sleep_time);
if (sleep_time > 0xFFFFFFFFFFFF) sleep_time = 0xFFFFFFFFFFFF; //2^48-1 if (sleep_time > 0xFFFFFFFFFFFF) sleep_time = 0xFFFFFFFFFFFF; //2^48-1
std::this_thread::sleep_for(std::chrono::microseconds(sleep_time)); for (u32 i = 0; i < sleep_time / 1000000; i++)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
if (Emu.IsStopped())
{
sys_timer.Warning("sys_timer_usleep(sleep_time=%lld) aborted", sleep_time);
return CELL_OK;
}
}
std::this_thread::sleep_for(std::chrono::microseconds(sleep_time % 1000000));
return CELL_OK; return CELL_OK;
} }

View file

@ -9,7 +9,7 @@ s32 sys_tty_read(u32 ch, u64 buf_addr, u32 len, u64 preadlen_addr)
{ {
// We currently do not support reading from the Console // We currently do not support reading from the Console
LOG_WARNING(HLE, "sys_tty_read: ch: %d, buf addr: %llx, len: %d", ch, buf_addr, len); LOG_WARNING(HLE, "sys_tty_read: ch: %d, buf addr: %llx, len: %d", ch, buf_addr, len);
Memory.Write32NN(preadlen_addr, len); Memory.Write32(preadlen_addr, len);
Emu.Pause(); Emu.Pause();
return CELL_OK; return CELL_OK;

View file

@ -237,8 +237,8 @@ bool ELF32Loader::LoadPhdrData(u64 _offset)
switch(machine) switch(machine)
{ {
case MACHINE_SPU: break; case MACHINE_SPU: break;
case MACHINE_MIPS: Memory.PSPMemory.RAM.AllocFixed(phdr_arr[i].p_vaddr + offset, phdr_arr[i].p_memsz); break; case MACHINE_MIPS: Memory.PSP.RAM.AllocFixed(phdr_arr[i].p_vaddr + offset, phdr_arr[i].p_memsz); break;
case MACHINE_ARM: Memory.PSVMemory.RAM.AllocFixed(phdr_arr[i].p_vaddr + offset, phdr_arr[i].p_memsz); break; case MACHINE_ARM: Memory.PSV.RAM.AllocFixed(phdr_arr[i].p_vaddr + offset, phdr_arr[i].p_memsz); break;
default: default:
continue; continue;