mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 12:32:43 +00:00
ARMv7: LDR_REG, LDRD_IMM, LDREX, STREX
sceLibc: printf() improved sceLibKernel: sceKernelGetThreadId(), sceKernelWaitThreadEnd()
This commit is contained in:
parent
5dd3437da9
commit
2d7bf06dea
@ -110,6 +110,9 @@ struct ARMv7Context
|
||||
|
||||
} ITSTATE;
|
||||
|
||||
u32 R_ADDR;
|
||||
u64 R_DATA;
|
||||
|
||||
void write_gpr(u32 n, u32 value)
|
||||
{
|
||||
assert(n < 16);
|
||||
@ -135,6 +138,21 @@ struct ARMv7Context
|
||||
|
||||
return read_pc();
|
||||
}
|
||||
|
||||
// function for processing va_args in printf-like functions
|
||||
u32 get_next_gpr_arg(u32& g_count, u32& f_count, u32& v_count)
|
||||
{
|
||||
assert(!f_count && !v_count); // not supported
|
||||
|
||||
if (g_count < 4)
|
||||
{
|
||||
return GPR[g_count++];
|
||||
}
|
||||
else
|
||||
{
|
||||
return get_stack_arg(g_count++);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, bool is_enum = std::is_enum<T>::value>
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
code.code1 = vm::psv::read16(address + 2 & ~1);
|
||||
u32 arg = address & 0x1 ? code.data : (u32)code.code0 << 16 | code.code1;
|
||||
|
||||
LOG_NOTICE(GENERAL, "code0 = 0x%04x, code1 = 0x%04x, data = 0x%08x, arg = 0x%08x", code.code0, code.code1, code.data, arg);
|
||||
//LOG_NOTICE(GENERAL, "code0 = 0x%04x, code1 = 0x%04x, data = 0x%08x, arg = 0x%08x", code.code0, code.code1, code.data, arg);
|
||||
|
||||
// old decoding algorithm
|
||||
|
||||
@ -32,7 +32,7 @@ public:
|
||||
{
|
||||
code.data = opcode.length == 2 ? code.code0 : arg;
|
||||
(*opcode.func)(m_thr.context, code, opcode.type);
|
||||
// LOG_NOTICE(GENERAL, "%s, %d \n\n", opcode.name, opcode.length);
|
||||
//LOG_NOTICE(ARMv7, "%s, %s", opcode.name, m_thr.RegsToString());
|
||||
return opcode.length;
|
||||
}
|
||||
}
|
||||
|
@ -1204,12 +1204,12 @@ void ARMv7_instrs::LDR_IMM(ARMv7Context& context, const ARMv7Code code, const AR
|
||||
const u32 offset_addr = add ? context.read_gpr(n) + imm32 : context.read_gpr(n) - imm32;
|
||||
const u32 addr = index ? offset_addr : context.read_gpr(n);
|
||||
|
||||
context.write_gpr(t, vm::psv::read32(addr));
|
||||
|
||||
if (wback)
|
||||
{
|
||||
context.write_gpr(n, offset_addr);
|
||||
}
|
||||
|
||||
context.write_gpr(t, vm::psv::read32(addr));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1224,11 +1224,56 @@ void ARMv7_instrs::LDR_LIT(ARMv7Context& context, const ARMv7Code code, const AR
|
||||
|
||||
void ARMv7_instrs::LDR_REG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
|
||||
{
|
||||
u32 cond = context.ITSTATE.advance();
|
||||
u32 t = 0;
|
||||
u32 n = 0;
|
||||
u32 m = 0;
|
||||
bool index = true;
|
||||
bool add = true;
|
||||
bool wback = false;
|
||||
auto shift_t = SRType_LSL;
|
||||
u32 shift_n = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case T1:
|
||||
{
|
||||
t = (code.data & 0x7);
|
||||
n = (code.data & 0x38) >> 3;
|
||||
m = (code.data & 0x1c0) >> 6;
|
||||
break;
|
||||
}
|
||||
case T2:
|
||||
{
|
||||
t = (code.data & 0xf000) >> 12;
|
||||
n = (code.data & 0xf0000) >> 16;
|
||||
m = (code.data & 0xf);
|
||||
shift_n = (code.data & 0x30) >> 4;
|
||||
|
||||
if (n == 15)
|
||||
{
|
||||
throw "LDR (literal)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case A1: throw __FUNCTION__;
|
||||
default: throw __FUNCTION__;
|
||||
}
|
||||
|
||||
if (ConditionPassed(context, cond))
|
||||
{
|
||||
const u32 offset = Shift(context.read_gpr(m), shift_t, shift_n, context.APSR.C);
|
||||
const u32 offset_addr = add ? context.read_gpr(n) + offset : context.read_gpr(n) - offset;
|
||||
const u32 addr = index ? offset_addr : context.read_gpr(n);
|
||||
const u32 data = vm::psv::read32(addr);
|
||||
|
||||
if (wback)
|
||||
{
|
||||
context.write_gpr(n, offset_addr);
|
||||
}
|
||||
|
||||
context.write_gpr(t, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1262,11 +1307,55 @@ void ARMv7_instrs::LDRB_REG(ARMv7Context& context, const ARMv7Code code, const A
|
||||
|
||||
void ARMv7_instrs::LDRD_IMM(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
|
||||
{
|
||||
u32 cond = context.ITSTATE.advance();
|
||||
u32 t = 0;
|
||||
u32 t2 = 0;
|
||||
u32 n = 13;
|
||||
u32 imm32 = 0;
|
||||
bool index = true;
|
||||
bool add = true;
|
||||
bool wback = false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case T1:
|
||||
{
|
||||
t = (code.data & 0xf000) >> 12;
|
||||
t2 = (code.data & 0xf00) >> 8;
|
||||
n = (code.data & 0xf0000) >> 16;
|
||||
imm32 = (code.data & 0xff) << 2;
|
||||
index = (code.data & 0x1000000);
|
||||
add = (code.data & 0x800000);
|
||||
wback = (code.data & 0x200000);
|
||||
|
||||
if (!index && !wback)
|
||||
{
|
||||
throw "LDRD_IMM_T1: Related encodings";
|
||||
}
|
||||
if (n == 15)
|
||||
{
|
||||
throw "LDRD (literal)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case A1: throw __FUNCTION__;
|
||||
default: throw __FUNCTION__;
|
||||
}
|
||||
|
||||
if (ConditionPassed(context, cond))
|
||||
{
|
||||
const u32 offset_addr = add ? context.read_gpr(n) + imm32 : context.read_gpr(n) - imm32;
|
||||
const u32 addr = index ? offset_addr : context.read_gpr(n);
|
||||
const u64 value = vm::psv::read64(addr);
|
||||
|
||||
context.write_gpr(t, (u32)(value));
|
||||
context.write_gpr(t2, (u32)(value >> 32));
|
||||
|
||||
if (wback)
|
||||
{
|
||||
context.write_gpr(n, offset_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ARMv7_instrs::LDRD_LIT(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
|
||||
@ -1374,11 +1463,33 @@ void ARMv7_instrs::LDRSH_REG(ARMv7Context& context, const ARMv7Code code, const
|
||||
|
||||
void ARMv7_instrs::LDREX(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
|
||||
{
|
||||
u32 cond = context.ITSTATE.advance();
|
||||
u32 t = 0;
|
||||
u32 n = 0;
|
||||
u32 imm32 = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case T1:
|
||||
{
|
||||
t = (code.data & 0xf000) >> 12;
|
||||
n = (code.data & 0xf0000) >> 16;
|
||||
imm32 = (code.data & 0xff) << 2;
|
||||
break;
|
||||
}
|
||||
case A1: throw __FUNCTION__;
|
||||
default: throw __FUNCTION__;
|
||||
}
|
||||
|
||||
if (ConditionPassed(context, cond))
|
||||
{
|
||||
const u32 addr = context.read_gpr(n) + imm32;
|
||||
const u32 value = vm::psv::read32(addr);
|
||||
|
||||
context.R_ADDR = addr;
|
||||
context.R_DATA = value;
|
||||
context.write_gpr(t, value);
|
||||
}
|
||||
}
|
||||
|
||||
void ARMv7_instrs::LDREXB(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
|
||||
@ -1853,14 +1964,17 @@ void ARMv7_instrs::POP(ARMv7Context& context, const ARMv7Code code, const ARMv7_
|
||||
|
||||
if (ConditionPassed(context, cond))
|
||||
{
|
||||
u32 written = 0;
|
||||
for (u16 mask = 1, i = 0; mask; mask <<= 1, i++)
|
||||
{
|
||||
if (reg_list & mask)
|
||||
{
|
||||
context.write_gpr(i, vm::psv::read32(context.SP));
|
||||
context.SP += 4;
|
||||
context.write_gpr(i, vm::psv::read32(context.SP + written));
|
||||
written += 4;
|
||||
}
|
||||
}
|
||||
|
||||
context.SP += written;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1907,14 +2021,17 @@ void ARMv7_instrs::PUSH(ARMv7Context& context, const ARMv7Code code, const ARMv7
|
||||
|
||||
if (ConditionPassed(context, cond))
|
||||
{
|
||||
u32 read = 0;
|
||||
for (u16 mask = 1 << 15, i = 15; mask; mask >>= 1, i--)
|
||||
{
|
||||
if (reg_list & mask)
|
||||
{
|
||||
context.SP -= 4;
|
||||
vm::psv::write32(context.SP, context.read_gpr(i));
|
||||
read += 4;
|
||||
vm::psv::write32(context.SP - read, context.read_gpr(i));
|
||||
}
|
||||
}
|
||||
|
||||
context.SP -= read;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2692,11 +2809,35 @@ void ARMv7_instrs::STRH_REG(ARMv7Context& context, const ARMv7Code code, const A
|
||||
|
||||
void ARMv7_instrs::STREX(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
|
||||
{
|
||||
u32 cond = context.ITSTATE.advance();
|
||||
u32 d = 0;
|
||||
u32 t = 0;
|
||||
u32 n = 0;
|
||||
u32 imm32 = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case T1:
|
||||
{
|
||||
d = (code.data & 0xf00) >> 8;
|
||||
t = (code.data & 0xf000) >> 12;
|
||||
n = (code.data & 0xf0000) >> 16;
|
||||
imm32 = (code.data & 0xff) << 2;
|
||||
break;
|
||||
}
|
||||
case A1: throw __FUNCTION__;
|
||||
default: throw __FUNCTION__;
|
||||
}
|
||||
|
||||
if (ConditionPassed(context, cond))
|
||||
{
|
||||
const u32 addr = context.read_gpr(n) + imm32;
|
||||
const u32 value = context.read_gpr(t);
|
||||
|
||||
auto& sync_obj = vm::get_ref<atomic_le_t<u32>>(addr);
|
||||
context.write_gpr(d, addr != context.R_ADDR || sync_obj.compare_and_swap((u32)context.R_DATA, value) != context.R_DATA);
|
||||
context.R_ADDR = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ARMv7_instrs::STREXB(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
|
||||
|
@ -500,6 +500,15 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] =
|
||||
|
||||
ARMv7_OP2(0xff00, 0xbf00, T1, IT),
|
||||
|
||||
ARMv7_OP4(0xfff0, 0x0f00, 0xe850, 0x0f00, T1, LDREX),
|
||||
ARMv7_OP4(0x0ff0, 0x0fff, 0x0190, 0x0f9f, A1, LDREX),
|
||||
ARMv7_OP4(0xfff0, 0x0fff, 0xe8d0, 0x0f4f, T1, LDREXB),
|
||||
ARMv7_OP4(0x0ff0, 0x0fff, 0x01d0, 0x0f9f, A1, LDREXB),
|
||||
ARMv7_OP4(0xfff0, 0x00ff, 0xe8d0, 0x007f, T1, LDREXD),
|
||||
ARMv7_OP4(0x0ff0, 0x0fff, 0x01b0, 0x0f9f, A1, LDREXD),
|
||||
ARMv7_OP4(0xfff0, 0x0fff, 0xe8d0, 0x0f5f, T1, LDREXH),
|
||||
ARMv7_OP4(0x0ff0, 0x0fff, 0x01f0, 0x0f9f, A1, LDREXH),
|
||||
|
||||
ARMv7_OP2(0xf800, 0xc800, T1, LDM),
|
||||
ARMv7_OP4(0xffd0, 0x2000, 0xe890, 0x0000, T2, LDM),
|
||||
ARMv7_OP4(0x0fd0, 0x0000, 0x0890, 0x0000, A1, LDM),
|
||||
@ -554,15 +563,6 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] =
|
||||
ARMv7_OP4(0xfff0, 0x0fc0, 0xf930, 0x0000, T2, LDRSH_REG),
|
||||
ARMv7_OP4(0x0e50, 0x0ff0, 0x0010, 0x00f0, A1, LDRSH_REG),
|
||||
|
||||
ARMv7_OP4(0xfff0, 0x0f00, 0xe850, 0x0f00, T1, LDREX),
|
||||
ARMv7_OP4(0x0ff0, 0x0fff, 0x0190, 0x0f9f, A1, LDREX),
|
||||
ARMv7_OP4(0xfff0, 0x0fff, 0xe8d0, 0x0f4f, T1, LDREXB),
|
||||
ARMv7_OP4(0x0ff0, 0x0fff, 0x01d0, 0x0f9f, A1, LDREXB),
|
||||
ARMv7_OP4(0xfff0, 0x00ff, 0xe8d0, 0x007f, T1, LDREXD),
|
||||
ARMv7_OP4(0x0ff0, 0x0fff, 0x01b0, 0x0f9f, A1, LDREXD),
|
||||
ARMv7_OP4(0xfff0, 0x0fff, 0xe8d0, 0x0f5f, T1, LDREXH),
|
||||
ARMv7_OP4(0x0ff0, 0x0fff, 0x01f0, 0x0f9f, A1, LDREXH),
|
||||
|
||||
ARMv7_OP2(0xf800, 0x0000, T1, LSL_IMM),
|
||||
ARMv7_OP4(0xffef, 0x8030, 0xea4f, 0x0000, T2, LSL_IMM),
|
||||
ARMv7_OP4(0x0fef, 0x0070, 0x01a0, 0x0000, A1, LSL_IMM),
|
||||
@ -773,6 +773,15 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] =
|
||||
ARMv7_OP4(0xfff0, 0xf0f0, 0xfac0, 0xf000, T1, SSUB8),
|
||||
ARMv7_OP4(0x0ff0, 0x0ff0, 0x0610, 0x0ff0, A1, SSUB8),
|
||||
|
||||
ARMv7_OP4(0xfff0, 0x0000, 0xe840, 0x0000, T1, STREX),
|
||||
ARMv7_OP4(0x0ff0, 0x0ff0, 0x0180, 0x0f90, A1, STREX),
|
||||
ARMv7_OP4(0xfff0, 0x0ff0, 0xe8c0, 0x0f40, T1, STREXB),
|
||||
ARMv7_OP4(0x0ff0, 0x0ff0, 0x01c0, 0x0f90, A1, STREXB),
|
||||
ARMv7_OP4(0xfff0, 0x00f0, 0xe8c0, 0x0070, T1, STREXD),
|
||||
ARMv7_OP4(0x0ff0, 0x0ff0, 0x01a0, 0x0f90, A1, STREXD),
|
||||
ARMv7_OP4(0xfff0, 0x0ff0, 0xe8c0, 0x0f50, T1, STREXH),
|
||||
ARMv7_OP4(0x0ff0, 0x0ff0, 0x01e0, 0x0f90, A1, STREXH),
|
||||
|
||||
ARMv7_OP2(0xf800, 0xc000, T1, STM),
|
||||
ARMv7_OP4(0xffd0, 0xa000, 0xe880, 0x0000, T2, STM),
|
||||
ARMv7_OP4(0x0fd0, 0x0000, 0x0880, 0x0000, A1, STM),
|
||||
@ -810,15 +819,6 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] =
|
||||
ARMv7_OP4(0xfff0, 0x0fc0, 0xf820, 0x0000, T2, STRH_REG),
|
||||
ARMv7_OP4(0x0e50, 0x0ff0, 0x0000, 0x00b0, A1, STRH_REG),
|
||||
|
||||
ARMv7_OP4(0xfff0, 0x0000, 0xe840, 0x0000, T1, STREX),
|
||||
ARMv7_OP4(0x0ff0, 0x0ff0, 0x0180, 0x0f90, A1, STREX),
|
||||
ARMv7_OP4(0xfff0, 0x0ff0, 0xe8c0, 0x0f40, T1, STREXB),
|
||||
ARMv7_OP4(0x0ff0, 0x0ff0, 0x01c0, 0x0f90, A1, STREXB),
|
||||
ARMv7_OP4(0xfff0, 0x00f0, 0xe8c0, 0x0070, T1, STREXD),
|
||||
ARMv7_OP4(0x0ff0, 0x0ff0, 0x01a0, 0x0f90, A1, STREXD),
|
||||
ARMv7_OP4(0xfff0, 0x0ff0, 0xe8c0, 0x0f50, T1, STREXH),
|
||||
ARMv7_OP4(0x0ff0, 0x0ff0, 0x01e0, 0x0f90, A1, STREXH),
|
||||
|
||||
ARMv7_OP2(0xff80, 0xb080, T1, SUB_SPI),
|
||||
ARMv7_OP4(0xfbef, 0x8000, 0xf1ad, 0x0000, T2, SUB_SPI),
|
||||
ARMv7_OP4(0xfbff, 0x8000, 0xf2ad, 0x0000, T3, SUB_SPI),
|
||||
|
@ -87,7 +87,7 @@ struct SceKernelSystemInfo
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
s32 sceKernelCreateThread(
|
||||
u32 sceKernelCreateThread(
|
||||
vm::psv::ptr<const char> pName,
|
||||
vm::psv::ptr<SceKernelThreadEntry> entry,
|
||||
s32 initPriority,
|
||||
@ -101,24 +101,21 @@ s32 sceKernelCreateThread(
|
||||
|
||||
ARMv7Thread& new_thread = static_cast<ARMv7Thread&>(Emu.GetCPU().AddThread(CPU_THREAD_ARMv7));
|
||||
|
||||
u32 id = new_thread.GetId();
|
||||
const auto id = new_thread.GetId();
|
||||
new_thread.SetEntry(entry.addr() ^ 1);
|
||||
new_thread.SetPrio(initPriority);
|
||||
new_thread.SetStackSize(stackSize);
|
||||
new_thread.SetName(pName.get_ptr());
|
||||
|
||||
sceLibKernel.Error("*** New ARMv7 Thread [%s] (entry=0x%x)^1: id = %d", pName.get_ptr(), entry, id);
|
||||
sceLibKernel.Error("*** New ARMv7 Thread [%s] (entry=0x%x)^1: id -> 0x%x", pName.get_ptr(), entry, id);
|
||||
|
||||
new_thread.Run();
|
||||
|
||||
Emu.Pause();
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::psv::ptr<const void> pArgBlock)
|
||||
s32 sceKernelStartThread(u32 threadId, u32 argSize, vm::psv::ptr<const void> pArgBlock)
|
||||
{
|
||||
sceLibKernel.Error("sceKernelStartThread(threadId=%d, argSize=%d, pArgBlock=0x%x)", threadId, argSize, pArgBlock);
|
||||
sceLibKernel.Error("sceKernelStartThread(threadId=0x%x, argSize=0x%x, pArgBlock=0x%x)", threadId, argSize, pArgBlock);
|
||||
|
||||
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(threadId);
|
||||
|
||||
@ -134,8 +131,8 @@ s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::psv::ptr<const void> pAr
|
||||
memcpy(vm::get_ptr<void>(pos), pArgBlock.get_ptr(), argSize);
|
||||
|
||||
// set SceKernelThreadEntry function arguments
|
||||
thread.context.write_gpr(0, argSize);
|
||||
thread.context.write_gpr(1, pos);
|
||||
thread.context.GPR[0] = argSize;
|
||||
thread.context.GPR[1] = pos;
|
||||
|
||||
thread.Exec();
|
||||
return SCE_OK;
|
||||
@ -151,9 +148,9 @@ s32 sceKernelExitThread(ARMv7Context& context, s32 exitStatus)
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
s32 sceKernelDeleteThread(s32 threadId)
|
||||
s32 sceKernelDeleteThread(u32 threadId)
|
||||
{
|
||||
sceLibKernel.Todo("sceKernelDeleteThread(threadId=%d)", threadId);
|
||||
sceLibKernel.Todo("sceKernelDeleteThread(threadId=0x%x)", threadId);
|
||||
|
||||
return SCE_OK;
|
||||
}
|
||||
@ -165,21 +162,21 @@ s32 sceKernelExitDeleteThread(s32 exitStatus)
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
s32 sceKernelChangeThreadCpuAffinityMask(s32 threadId, s32 cpuAffinityMask)
|
||||
s32 sceKernelChangeThreadCpuAffinityMask(u32 threadId, s32 cpuAffinityMask)
|
||||
{
|
||||
sceLibKernel.Todo("sceKernelChangeThreadCpuAffinityMask(threadId=%d, cpuAffinityMask=0x%x)", threadId, cpuAffinityMask);
|
||||
sceLibKernel.Todo("sceKernelChangeThreadCpuAffinityMask(threadId=0x%x, cpuAffinityMask=0x%x)", threadId, cpuAffinityMask);
|
||||
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
s32 sceKernelGetThreadCpuAffinityMask(s32 threadId)
|
||||
s32 sceKernelGetThreadCpuAffinityMask(u32 threadId)
|
||||
{
|
||||
sceLibKernel.Todo("sceKernelGetThreadCpuAffinityMask(threadId=0x%x)", threadId);
|
||||
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
s32 sceKernelChangeThreadPriority(s32 threadId, s32 priority)
|
||||
s32 sceKernelChangeThreadPriority(u32 threadId, s32 priority)
|
||||
{
|
||||
sceLibKernel.Todo("sceKernelChangeThreadPriority(threadId=0x%x, priority=%d)", threadId, priority);
|
||||
|
||||
@ -193,11 +190,11 @@ s32 sceKernelGetThreadCurrentPriority()
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
s32 sceKernelGetThreadId()
|
||||
u32 sceKernelGetThreadId(ARMv7Context& context)
|
||||
{
|
||||
sceLibKernel.Todo("sceKernelGetThreadId()");
|
||||
sceLibKernel.Log("sceKernelGetThreadId()");
|
||||
|
||||
return SCE_OK;
|
||||
return context.thread.GetId();
|
||||
}
|
||||
|
||||
s32 sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr)
|
||||
@ -207,9 +204,9 @@ s32 sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr)
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
s32 sceKernelGetThreadExitStatus(s32 threadId, vm::psv::ptr<s32> pExitStatus)
|
||||
s32 sceKernelGetThreadExitStatus(u32 threadId, vm::psv::ptr<s32> pExitStatus)
|
||||
{
|
||||
sceLibKernel.Todo("sceKernelGetThreadExitStatus(threadId=%d, pExitStatus=0x%x)", threadId, pExitStatus);
|
||||
sceLibKernel.Todo("sceKernelGetThreadExitStatus(threadId=0x%x, pExitStatus=0x%x)", threadId, pExitStatus);
|
||||
|
||||
return SCE_OK;
|
||||
}
|
||||
@ -228,9 +225,9 @@ s32 sceKernelCheckWaitableStatus()
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
s32 sceKernelGetThreadInfo(s32 threadId, vm::psv::ptr<SceKernelThreadInfo> pInfo)
|
||||
s32 sceKernelGetThreadInfo(u32 threadId, vm::psv::ptr<SceKernelThreadInfo> pInfo)
|
||||
{
|
||||
sceLibKernel.Todo("sceKernelGetThreadInfo(threadId=%d, pInfo=0x%x)", threadId, pInfo);
|
||||
sceLibKernel.Todo("sceKernelGetThreadInfo(threadId=0x%x, pInfo=0x%x)", threadId, pInfo);
|
||||
|
||||
return SCE_OK;
|
||||
}
|
||||
@ -251,7 +248,7 @@ s32 sceKernelGetSystemInfo(vm::psv::ptr<SceKernelSystemInfo> pInfo)
|
||||
|
||||
s32 sceKernelGetThreadmgrUIDClass(s32 uid)
|
||||
{
|
||||
sceLibKernel.Todo("sceKernelGetThreadmgrUIDClass(uid=%d)", uid);
|
||||
sceLibKernel.Todo("sceKernelGetThreadmgrUIDClass(uid=0x%x)", uid);
|
||||
|
||||
return SCE_OK;
|
||||
}
|
||||
@ -284,16 +281,44 @@ s32 sceKernelDelayThreadCB(u32 usec)
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
s32 sceKernelWaitThreadEnd(s32 threadId, vm::psv::ptr<s32> pExitStatus, vm::psv::ptr<u32> pTimeout)
|
||||
s32 sceKernelWaitThreadEnd(u32 threadId, vm::psv::ptr<s32> pExitStatus, vm::psv::ptr<u32> pTimeout)
|
||||
{
|
||||
sceLibKernel.Todo("sceKernelWaitThreadEnd(threadId=%d, pExitStatus=0x%x, pTimeout=0x%x)", threadId, pExitStatus, pTimeout);
|
||||
sceLibKernel.Error("sceKernelWaitThreadEnd(threadId=0x%x, pExitStatus=0x%x, pTimeout=0x%x)", threadId, pExitStatus, pTimeout);
|
||||
|
||||
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(threadId);
|
||||
|
||||
if (!t || t->GetType() != CPU_THREAD_ARMv7)
|
||||
{
|
||||
RETURN_ERROR(SCE_KERNEL_ERROR_INVALID_UID);
|
||||
}
|
||||
|
||||
ARMv7Thread& thread = static_cast<ARMv7Thread&>(*t);
|
||||
|
||||
if (pTimeout)
|
||||
{
|
||||
}
|
||||
|
||||
while (thread.IsAlive())
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
sceLibKernel.Warning("sceKernelWaitThreadEnd(0x%x) aborted", threadId);
|
||||
return SCE_OK;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
}
|
||||
|
||||
if (pExitStatus)
|
||||
{
|
||||
*pExitStatus = thread.context.GPR[0];
|
||||
}
|
||||
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
s32 sceKernelWaitThreadEndCB(s32 threadId, vm::psv::ptr<s32> pExitStatus, vm::psv::ptr<u32> pTimeout)
|
||||
s32 sceKernelWaitThreadEndCB(u32 threadId, vm::psv::ptr<s32> pExitStatus, vm::psv::ptr<u32> pTimeout)
|
||||
{
|
||||
sceLibKernel.Todo("sceKernelWaitThreadEndCB(threadId=%d, pExitStatus=0x%x, pTimeout=0x%x)", threadId, pExitStatus, pTimeout);
|
||||
sceLibKernel.Todo("sceKernelWaitThreadEndCB(threadId=0x%x, pExitStatus=0x%x, pTimeout=0x%x)", threadId, pExitStatus, pTimeout);
|
||||
|
||||
return SCE_OK;
|
||||
}
|
||||
|
@ -26,11 +26,67 @@ namespace sce_libc_func
|
||||
});
|
||||
}
|
||||
|
||||
void printf(vm::psv::ptr<const char> fmt) // va_args...
|
||||
void printf(ARMv7Context& context, vm::psv::ptr<const char> fmt) // va_args...
|
||||
{
|
||||
sceLibc.Error("printf(fmt=0x%x)", fmt);
|
||||
|
||||
LOG_NOTICE(TTY, "%s", fmt.get_ptr());
|
||||
sceLibc.Notice("*** *fmt = '%s'", fmt.get_ptr());
|
||||
|
||||
std::string result;
|
||||
u32 g_count = 1;
|
||||
u32 f_count = 0;
|
||||
u32 v_count = 0;
|
||||
|
||||
for (char c = *fmt++; c; c = *fmt++)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '%':
|
||||
{
|
||||
const auto start = fmt - 1;
|
||||
const bool <EFBFBD>” = *fmt == '#' ? fmt++, true : false;
|
||||
|
||||
switch (*fmt++)
|
||||
{
|
||||
case '%':
|
||||
{
|
||||
result += '%';
|
||||
continue;
|
||||
}
|
||||
case 'd':
|
||||
case 'i':
|
||||
{
|
||||
// signed decimal
|
||||
const s64 value = context.get_next_gpr_arg(g_count, f_count, v_count);
|
||||
|
||||
result += fmt::to_sdec(value);
|
||||
continue;
|
||||
}
|
||||
case 'x':
|
||||
{
|
||||
// hexadecimal
|
||||
const u64 value = context.get_next_gpr_arg(g_count, f_count, v_count);
|
||||
|
||||
if (<EFBFBD>” && value)
|
||||
{
|
||||
result += "0x";
|
||||
}
|
||||
|
||||
result += fmt::to_hex(value);
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw fmt::Format("printf(): unknown formatting: '%s'", start.get_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result += c;
|
||||
}
|
||||
|
||||
LOG_NOTICE(TTY, result);
|
||||
}
|
||||
|
||||
void __cxa_set_dso_handle_main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user