From 5225ca8fc2154c506cb91bdfdb56cf38087fdef2 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 3 Feb 2015 00:00:05 +0300 Subject: [PATCH] ARMv7: branch instrs fixed, new instructions BIC_IMM, BIC_REG, RSB_IMM, LDR_LIT, STRB_REG, STRH_REG Fixed initial stack size --- rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp | 290 ++++++++++++++++++++--- rpcs3/Emu/ARMv7/ARMv7Thread.cpp | 8 +- rpcs3/Emu/ARMv7/ARMv7Thread.h | 2 +- rpcs3/Emu/ARMv7/Modules/psv_event_flag.h | 1 + rpcs3/Emu/ARMv7/Modules/psv_sema.h | 1 + rpcs3/Emu/ARMv7/Modules/sceLibc.cpp | 126 +++++----- rpcs3/Emu/ARMv7/PSVObjectList.h | 34 ++- rpcs3/Emu/Memory/vm.cpp | 6 +- rpcs3/Loader/ELF32.cpp | 4 +- 9 files changed, 367 insertions(+), 105 deletions(-) diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp index d7b1c9adf8..6ec1bbebf1 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp @@ -228,9 +228,9 @@ namespace ARMv7_instrs } } - u32 ThumbExpandImm(ARMv7Context& context, u32 imm12) + u32 ThumbExpandImm(u32 imm12) { - bool carry = context.APSR.C; + bool carry; return ThumbExpandImm_C(imm12, carry, carry); } @@ -418,7 +418,7 @@ void ARMv7_instrs::ADD_IMM(ARMv7Context& context, const ARMv7Code code, const AR d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; set_flags = (code.data & 0x100000); - imm32 = ThumbExpandImm(context, (code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); + imm32 = ThumbExpandImm((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); reject(d == 15 && set_flags, "CMN (immediate)"); reject(n == 13, "ADD (SP plus immediate)"); @@ -567,7 +567,7 @@ void ARMv7_instrs::ADD_SPI(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; set_flags = (code.data & 0x100000); - imm32 = ThumbExpandImm(context, (code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); + imm32 = ThumbExpandImm((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); reject(d == 15 && set_flags, "CMN (immediate)"); reject(d == 15, "UNPREDICTABLE"); @@ -770,14 +770,14 @@ void ARMv7_instrs::ASR_REG(ARMv7Context& context, const ARMv7Code code, const AR void ARMv7_instrs::B(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { - u32 cond, jump; + u32 cond, imm32; switch (type) { case T1: { cond = (code.data >> 8) & 0xf; - jump = 4 + sign<9, u32>((code.data & 0xff) << 1); + imm32 = sign<9, u32>((code.data & 0xff) << 1); reject(cond == 14, "UNDEFINED"); reject(cond == 15, "SVC"); @@ -787,7 +787,7 @@ void ARMv7_instrs::B(ARMv7Context& context, const ARMv7Code code, const ARMv7_en case T2: { cond = context.ITSTATE.advance(); - jump = 4 + sign<12, u32>((code.data & 0x7ff) << 1); + imm32 = sign<12, u32>((code.data & 0x7ff) << 1); reject(context.ITSTATE, "UNPREDICTABLE"); break; @@ -799,7 +799,7 @@ void ARMv7_instrs::B(ARMv7Context& context, const ARMv7Code code, const ARMv7_en const u32 s = (code.data >> 26) & 0x1; const u32 j1 = (code.data >> 13) & 0x1; const u32 j2 = (code.data >> 11) & 0x1; - jump = 4 + sign<21, u32>(s << 20 | j2 << 19 | j1 << 18 | (code.data & 0x3f0000) >> 4 | (code.data & 0x7ff) << 1); + imm32 = sign<21, u32>(s << 20 | j2 << 19 | j1 << 18 | (code.data & 0x3f0000) >> 4 | (code.data & 0x7ff) << 1); } reject(cond >= 14, "Related encodings"); @@ -813,7 +813,7 @@ void ARMv7_instrs::B(ARMv7Context& context, const ARMv7Code code, const ARMv7_en 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; - jump = 4 + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (code.data & 0x3ff0000) >> 4 | (code.data & 0x7ff) << 1); + imm32 = sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (code.data & 0x3ff0000) >> 4 | (code.data & 0x7ff) << 1); } reject(context.ITSTATE, "UNPREDICTABLE"); @@ -822,7 +822,7 @@ void ARMv7_instrs::B(ARMv7Context& context, const ARMv7Code code, const ARMv7_en case A1: { cond = code.data >> 28; - jump = 1 + 4 + sign<26, u32>((code.data & 0xffffff) << 2); + imm32 = sign<26, u32>((code.data & 0xffffff) << 2); break; } default: throw __FUNCTION__; @@ -830,8 +830,7 @@ void ARMv7_instrs::B(ARMv7Context& context, const ARMv7Code code, const ARMv7_en if (ConditionPassed(context, cond)) { - //LOG_NOTICE(ARMv7, "Branch to 0x%x (cond=0x%x)", context.thread.PC + jump, cond); - context.thread.SetBranch(context.thread.PC + jump); + context.thread.SetBranch(context.read_pc() + imm32); } } @@ -857,20 +856,86 @@ void ARMv7_instrs::BFI(ARMv7Context& context, const ARMv7Code code, const ARMv7_ void ARMv7_instrs::BIC_IMM(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { + bool set_flags, carry = context.APSR.C; + u32 cond, d, n, imm32; + switch (type) { + case T1: + { + cond = context.ITSTATE.advance(); + d = (code.data & 0xf00) >> 8; + n = (code.data & 0xf0000) >> 16; + set_flags = (code.data & 0x100000); + imm32 = ThumbExpandImm_C((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff), carry, carry); + + reject(d == 13 || d == 15 || n == 13 || n == 15, "UNPREDICTABLE"); + break; + } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } + + if (ConditionPassed(context, cond)) + { + const u32 result = context.read_gpr(n) & ~imm32; + context.write_gpr(d, result); + + if (set_flags) + { + context.APSR.N = result >> 31; + context.APSR.Z = result == 0; + context.APSR.C = carry; + } + } } void ARMv7_instrs::BIC_REG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { + bool set_flags = !context.ITSTATE; + u32 cond, d, n, m, shift_t, shift_n; + switch (type) { + case T1: + { + cond = context.ITSTATE.advance(); + d = n = (code.data & 0x7); + m = (code.data & 0x38) >> 3; + shift_t = SRType_LSL; + shift_n = 0; + break; + } + case T2: + { + cond = context.ITSTATE.advance(); + d = (code.data & 0xf00) >> 8; + n = (code.data & 0xf0000) >> 16; + m = (code.data & 0xf); + set_flags = (code.data & 0x100000); + shift_t = DecodeImmShift((code.data & 0x30) >> 4, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); + + reject(d == 13 || d == 15 || n == 13 || n == 15 || m == 13 || m == 15, "UNPREDICTABLE"); + break; + } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } + + if (ConditionPassed(context, cond)) + { + bool carry; + const u32 shifted = Shift_C(context.read_gpr(m), shift_t, shift_n, context.APSR.C, carry); + const u32 result = context.read_gpr(n) & ~shifted; + context.write_gpr(d, result); + + if (set_flags) + { + context.APSR.N = result >> 31; + context.APSR.Z = result == 0; + context.APSR.C = carry; + } + } } void ARMv7_instrs::BIC_RSR(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) @@ -895,19 +960,18 @@ void ARMv7_instrs::BKPT(ARMv7Context& context, const ARMv7Code code, const ARMv7 void ARMv7_instrs::BL(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { - u32 cond, imm32, newLR; + u32 cond, imm32; switch (type) { case T1: { cond = context.ITSTATE.advance(); - newLR = (context.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; - imm32 = 4 + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (code.data & 0x3ff0000) >> 4 | (code.data & 0x7ff) << 1); + imm32 = sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (code.data & 0x3ff0000) >> 4 | (code.data & 0x7ff) << 1); } reject(context.ITSTATE, "UNPREDICTABLE"); @@ -916,8 +980,7 @@ void ARMv7_instrs::BL(ARMv7Context& context, const ARMv7Code code, const ARMv7_e case A1: { cond = code.data >> 28; - newLR = (context.thread.PC + 4) - 4; - imm32 = 4 + sign<26, u32>((code.data & 0xffffff) << 2); + imm32 = sign<26, u32>((code.data & 0xffffff) << 2); break; } default: throw __FUNCTION__; @@ -925,8 +988,16 @@ void ARMv7_instrs::BL(ARMv7Context& context, const ARMv7Code code, const ARMv7_e if (ConditionPassed(context, cond)) { - context.LR = newLR; - context.thread.SetBranch(context.thread.PC + imm32); + if (context.ISET == ARM) + { + context.LR = context.read_pc() - 4; + context.thread.SetBranch((context.read_pc() & ~3) + imm32); + } + else + { + context.LR = context.read_pc() | 1; + context.thread.SetBranch(context.read_pc() + imm32); + } } } @@ -939,7 +1010,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 = (context.thread.PC + 2) | 1; { const u32 m = (code.data >> 3) & 0xf; reject(m == 15, "UNPREDICTABLE"); @@ -957,7 +1028,7 @@ void ARMv7_instrs::BLX(ARMv7Context& context, const ARMv7Code code, const ARMv7_ 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 = (context.thread.PC + 4 & ~3) + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (code.data & 0x3ff0000) >> 4 | (code.data & 0x7ff) << 1); + target = ~3 & context.thread.PC + 4 + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (code.data & 0x3ff0000) >> 4 | (code.data & 0x7ff) << 1); } reject(context.ITSTATE, "UNPREDICTABLE"); @@ -966,15 +1037,15 @@ void ARMv7_instrs::BLX(ARMv7Context& context, const ARMv7Code code, const ARMv7_ case A1: { cond = code.data >> 28; - newLR = (context.thread.PC + 4) - 4; + newLR = context.thread.PC + 4; target = context.read_gpr(code.data & 0xf); break; } case A2: { cond = 0xe; // always true - newLR = (context.thread.PC + 4) - 4; - target = (context.thread.PC + 4 | 1) + sign<25, u32>((code.data & 0xffffff) << 2 | (code.data & 0x1000000) >> 23); + newLR = context.thread.PC + 4; + target = 1 | context.thread.PC + 8 + sign<25, u32>((code.data & 0xffffff) << 2 | (code.data & 0x1000000) >> 23); break; } default: throw __FUNCTION__; @@ -1038,7 +1109,7 @@ void ARMv7_instrs::CB_Z(ARMv7Context& context, const ARMv7Code code, const ARMv7 if ((context.read_gpr(n) == 0) ^ nonzero) { - context.thread.SetBranch(context.thread.PC + 2 + imm32); + context.thread.SetBranch(context.read_pc() + imm32); } } @@ -1115,7 +1186,7 @@ void ARMv7_instrs::CMP_IMM(ARMv7Context& context, const ARMv7Code code, const AR { cond = context.ITSTATE.advance(); n = (code.data & 0xf0000) >> 16; - imm32 = ThumbExpandImm(context, (code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); + imm32 = ThumbExpandImm((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); reject(n == 15, "UNPREDICTABLE"); break; @@ -1127,11 +1198,14 @@ void ARMv7_instrs::CMP_IMM(ARMv7Context& context, const ARMv7Code code, const AR if (ConditionPassed(context, cond)) { bool carry, overflow; - const u32 res = AddWithCarry(context.read_gpr(n), ~imm32, true, carry, overflow); + const u32 n_value = context.read_gpr(n); + const u32 res = AddWithCarry(n_value, ~imm32, true, carry, overflow); context.APSR.N = res >> 31; context.APSR.Z = res == 0; context.APSR.C = carry; context.APSR.V = overflow; + + //LOG_NOTICE(ARMv7, "CMP: r%d=0x%08x <> 0x%08x, res=0x%08x", n, n_value, imm32, res); } } @@ -1369,11 +1443,40 @@ void ARMv7_instrs::LDR_IMM(ARMv7Context& context, const ARMv7Code code, const AR void ARMv7_instrs::LDR_LIT(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { + u32 cond, t, imm32; + bool add; + switch (type) { + case T1: + { + cond = context.ITSTATE.advance(); + t = (code.data & 0x700) >> 8; + imm32 = (code.data & 0xff) << 2; + add = true; + break; + } + case T2: + { + cond = context.ITSTATE.advance(); + t = (code.data & 0xf000) >> 12; + imm32 = (code.data & 0xfff); + add = (code.data & 0x800000); + + reject(t == 15 && context.ITSTATE, "UNPREDICTABLE"); + break; + } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } + + if (ConditionPassed(context, cond)) + { + const u32 base = context.read_pc() & ~3; + const u32 addr = add ? base + imm32 : base - imm32; + const u32 data = vm::psv::read32(addr); + context.write_gpr(t, data); + } } void ARMv7_instrs::LDR_REG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) @@ -2544,11 +2647,48 @@ void ARMv7_instrs::RRX(ARMv7Context& context, const ARMv7Code code, const ARMv7_ void ARMv7_instrs::RSB_IMM(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { + bool set_flags = !context.ITSTATE; + u32 cond, d, n, imm32; + switch (type) { + case T1: + { + cond = context.ITSTATE.advance(); + d = (code.data & 0x7); + n = (code.data & 0x38) >> 3; + imm32 = 0; + break; + } + case T2: + { + cond = context.ITSTATE.advance(); + d = (code.data & 0xf00) >> 8; + n = (code.data & 0xf0000) >> 16; + set_flags = (code.data & 0x100000); + imm32 = ThumbExpandImm((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); + + reject(d == 13 || d == 15 || n == 13 || n == 15, "UNPREDICTABLE"); + break; + } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } + + if (ConditionPassed(context, cond)) + { + bool carry, overflow; + const u32 result = AddWithCarry(~context.read_gpr(n), imm32, true, carry, overflow); + context.write_gpr(d, result); + + if (set_flags) + { + context.APSR.N = result >> 31; + context.APSR.Z = result == 0; + context.APSR.C = carry; + context.APSR.V = overflow; + } + } } void ARMv7_instrs::RSB_REG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) @@ -3167,11 +3307,57 @@ void ARMv7_instrs::STRB_IMM(ARMv7Context& context, const ARMv7Code code, const A void ARMv7_instrs::STRB_REG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { + u32 cond, t, n, m, shift_t, shift_n; + bool index, add, wback; + switch (type) { + case T1: + { + cond = context.ITSTATE.advance(); + t = (code.data & 0x7); + n = (code.data & 0x38) >> 3; + m = (code.data & 0x1c0) >> 6; + index = true; + add = true; + wback = false; + shift_t = SRType_LSL; + shift_n = 0; + break; + } + case T2: + { + cond = context.ITSTATE.advance(); + t = (code.data & 0xf000) >> 12; + n = (code.data & 0xf0000) >> 16; + m = (code.data & 0xf); + index = true; + add = true; + wback = false; + shift_t = SRType_LSL; + shift_n = (code.data & 0x30) >> 4; + + reject(n == 15, "UNDEFINED"); + reject(t == 13 || t == 15 || m == 13 || m == 15, "UNPREDICTABLE"); + 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); + + vm::psv::write8(addr, (u8)context.read_gpr(t)); + + if (wback) + { + context.write_gpr(n, offset_addr); + } + } } @@ -3205,11 +3391,57 @@ void ARMv7_instrs::STRH_IMM(ARMv7Context& context, const ARMv7Code code, const A void ARMv7_instrs::STRH_REG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { + u32 cond, t, n, m, shift_t, shift_n; + bool index, add, wback; + switch (type) { + case T1: + { + cond = context.ITSTATE.advance(); + t = (code.data & 0x7); + n = (code.data & 0x38) >> 3; + m = (code.data & 0x1c0) >> 6; + index = true; + add = true; + wback = false; + shift_t = SRType_LSL; + shift_n = 0; + break; + } + case T2: + { + cond = context.ITSTATE.advance(); + t = (code.data & 0xf000) >> 12; + n = (code.data & 0xf0000) >> 16; + m = (code.data & 0xf); + index = true; + add = true; + wback = false; + shift_t = SRType_LSL; + shift_n = (code.data & 0x30) >> 4; + + reject(n == 15, "UNDEFINED"); + reject(t == 13 || t == 15 || m == 13 || m == 15, "UNPREDICTABLE"); + 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); + + vm::psv::write16(addr, (u16)context.read_gpr(t)); + + if (wback) + { + context.write_gpr(n, offset_addr); + } + } } @@ -3302,7 +3534,7 @@ void ARMv7_instrs::SUB_IMM(ARMv7Context& context, const ARMv7Code code, const AR d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; set_flags = (code.data & 0x100000); - imm32 = ThumbExpandImm(context, (code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); + imm32 = ThumbExpandImm((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); reject(d == 15 && set_flags, "CMP (immediate)"); reject(n == 13, "SUB (SP minus immediate)"); @@ -3429,7 +3661,7 @@ void ARMv7_instrs::SUB_SPI(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; set_flags = (code.data & 0x100000); - imm32 = ThumbExpandImm(context, (code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); + imm32 = ThumbExpandImm((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); reject(d == 15 && set_flags, "CMP (immediate)"); reject(d == 15, "UNPREDICTABLE"); diff --git a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp index 9fe72a3d49..12b7c7b0b3 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp @@ -18,7 +18,7 @@ void ARMv7Context::write_pc(u32 value) u32 ARMv7Context::read_pc() { - return thread.PC; + return ISET == ARM ? thread.PC + 8 : thread.PC + 4; } u32 ARMv7Context::get_stack_arg(u32 pos) @@ -230,14 +230,14 @@ void ARMv7Thread::FastStop() m_status = Stopped; } -armv7_thread::armv7_thread(u32 entry, const std::string& name, u32 stack_size, u32 prio) +armv7_thread::armv7_thread(u32 entry, const std::string& name, u32 stack_size, s32 prio) { thread = &Emu.GetCPU().AddThread(CPU_THREAD_ARMv7); thread->SetName(name); thread->SetEntry(entry); - thread->SetStackSize(stack_size ? stack_size : Emu.GetInfo().GetProcParam().primary_stacksize); - thread->SetPrio(prio ? prio : Emu.GetInfo().GetProcParam().primary_prio); + thread->SetStackSize(stack_size); + thread->SetPrio(prio); argc = 0; } diff --git a/rpcs3/Emu/ARMv7/ARMv7Thread.h b/rpcs3/Emu/ARMv7/ARMv7Thread.h index a8a0f75311..5bbc4a564c 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Thread.h +++ b/rpcs3/Emu/ARMv7/ARMv7Thread.h @@ -39,7 +39,7 @@ class armv7_thread : cpu_thread u32 argc; public: - armv7_thread(u32 entry, const std::string& name = "", u32 stack_size = 0, u32 prio = 0); + armv7_thread(u32 entry, const std::string& name, u32 stack_size, s32 prio); cpu_thread& args(std::initializer_list values) override; diff --git a/rpcs3/Emu/ARMv7/Modules/psv_event_flag.h b/rpcs3/Emu/ARMv7/Modules/psv_event_flag.h index bc1cb2d4e9..ad69269a1a 100644 --- a/rpcs3/Emu/ARMv7/Modules/psv_event_flag.h +++ b/rpcs3/Emu/ARMv7/Modules/psv_event_flag.h @@ -2,6 +2,7 @@ struct psv_event_flag_t { + s32 id; char name[32]; u32 attr; u32 pattern; diff --git a/rpcs3/Emu/ARMv7/Modules/psv_sema.h b/rpcs3/Emu/ARMv7/Modules/psv_sema.h index 30b3fa6c4c..83b3b99b24 100644 --- a/rpcs3/Emu/ARMv7/Modules/psv_sema.h +++ b/rpcs3/Emu/ARMv7/Modules/psv_sema.h @@ -2,6 +2,7 @@ struct psv_sema_t { + s32 id; char name[32]; u32 attr; s32 value; diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp index d280e3dc24..cf3725a3f9 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp @@ -2,6 +2,7 @@ #include "Utilities/Log.h" #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" +#include "Emu/ARMv7/ARMv7Thread.h" #include "Emu/ARMv7/ARMv7Callback.h" extern psv_log_base sceLibc; @@ -12,6 +13,70 @@ typedef void(atexit_func_t)(vm::psv::ptr); std::vector> g_atexit; +std::string armv7_fmt(ARMv7Context& context, vm::psv::ptr fmt, u32 g_count, u32 f_count, u32 v_count) +{ + std::string result; + + for (char c = *fmt++; c; c = *fmt++) + { + switch (c) + { + case '%': + { + const auto start = fmt - 1; + const bool number_sign = *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 (number_sign && value) + { + result += "0x"; + } + + result += fmt::to_hex(value); + continue; + } + case 's': + { + // string + auto string = vm::psv::ptr::make(context.get_next_gpr_arg(g_count, f_count, v_count)); + + result += string.get_ptr(); + continue; + } + default: + { + throw fmt::Format("armv7_fmt(): unknown formatting: '%s'", start.get_ptr()); + } + } + } + } + + result += c; + } + + return result; +} + namespace sce_libc_func { void __cxa_atexit(vm::psv::ptr func, vm::psv::ptr arg, vm::psv::ptr dso) @@ -59,62 +124,6 @@ namespace sce_libc_func }); } - std::string armv7_fmt(ARMv7Context& context, vm::psv::ptr fmt, u32 g_count, u32 f_count, u32 v_count) - { - std::string result; - - for (char c = *fmt++; c; c = *fmt++) - { - switch (c) - { - case '%': - { - const auto start = fmt - 1; - const bool number_sign = *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 (number_sign && value) - { - result += "0x"; - } - - result += fmt::to_hex(value); - continue; - } - default: - { - throw fmt::Format("armv7_fmt(): unknown formatting: '%s'", start.get_ptr()); - } - } - } - } - - result += c; - } - - return result; - } - void printf(ARMv7Context& context, vm::psv::ptr fmt) // va_args... { sceLibc.Warning("printf(fmt=0x%x)", fmt); @@ -158,11 +167,12 @@ namespace sce_libc_func ::memset(dst.get_ptr(), value, size); } - void _Assert(vm::psv::ptr text, vm::psv::ptr func) + void _Assert(ARMv7Context& context, vm::psv::ptr text, vm::psv::ptr func) { - sceLibc.Warning("_Assert(text=0x%x, func=0x%x)", text, 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(); } } diff --git a/rpcs3/Emu/ARMv7/PSVObjectList.h b/rpcs3/Emu/ARMv7/PSVObjectList.h index d25c6e39ce..278bc521dd 100644 --- a/rpcs3/Emu/ARMv7/PSVObjectList.h +++ b/rpcs3/Emu/ARMv7/PSVObjectList.h @@ -25,8 +25,18 @@ template class psv_object_list_t // Class for managing object data { std::array, 0x8000> m_data; + std::atomic m_hint; // guessing next free position std::mutex m_mutex; // TODO: remove it when shared_ptr atomic ops are fully available +public: + psv_object_list_t() : m_hint(0) {} + + psv_object_list_t(const psv_object_list_t&) = delete; + psv_object_list_t(psv_object_list_t&&) = delete; + + psv_object_list_t& operator =(const psv_object_list_t&) = delete; + psv_object_list_t& operator =(psv_object_list_t&&) = delete; + public: static const u32 uid_class = type; @@ -60,18 +70,18 @@ public: { std::lock_guard lock(m_mutex); - for (auto& value : m_data) + for (u32 i = 0, j = m_hint % m_data.size(); i < m_data.size(); i++, j = (j + 1) % m_data.size()) { - // find an empty position and move the pointer - //std::shared_ptr old_ptr = nullptr; - //if (std::atomic_compare_exchange_strong(&value, &old_ptr, data)) - if (!value) + // find an empty position and copy the pointer + if (!m_data[j]) { - value = data; + m_data[j] = data; + m_hint = j + 1; // guess next position psv_uid_t id = psv_uid_t::make(1); // odd number id.type = uid_class; // set type - id.number = &value - m_data.data(); // set position - return id.uid; + id.number = j; // set position + data->id = id.uid; // save UID + return id.uid; // return UID } } @@ -86,12 +96,14 @@ public: return nullptr; } + const u32 pos = psv_uid_t::make(uid).number; + std::lock_guard lock(m_mutex); std::shared_ptr old_ptr = nullptr; - m_data[psv_uid_t::make(uid).number].swap(old_ptr); + m_data[pos].swap(old_ptr); + m_hint = pos; return old_ptr; - //return std::atomic_exchange>(&m_data[psv_uid_t::make(uid).number], nullptr); } // remove all objects @@ -103,6 +115,8 @@ public: { value = nullptr; } + + m_hint = 0; } }; diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 04d3a0f90a..9a5f9eec9e 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -63,7 +63,11 @@ namespace vm return res; } - assert(!real_pointer); + if (real_pointer) + { + throw fmt::format("vm::get_addr(0x%016llx) failed: not a part of virtual memory", (u64)real_pointer); + } + return 0; } diff --git a/rpcs3/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index 89112c8692..1d0ea7a16e 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -401,8 +401,8 @@ namespace loader armv7_decoder_initialize(code_start, code_end); const std::string& thread_name = proc_param->sceUserMainThreadName ? proc_param->sceUserMainThreadName.get_ptr() : "main_thread"; - const u32 stack_size = proc_param->sceUserMainThreadStackSize ? *proc_param->sceUserMainThreadStackSize : 0; - const u32 priority = proc_param->sceUserMainThreadPriority ? *proc_param->sceUserMainThreadPriority : 0; + const u32 stack_size = proc_param->sceUserMainThreadStackSize ? *proc_param->sceUserMainThreadStackSize : 256 * 1024; + const u32 priority = proc_param->sceUserMainThreadPriority ? *proc_param->sceUserMainThreadPriority : 160; armv7_thread(entry, thread_name, stack_size, priority).args({ Emu.GetPath(), "-emu" }).run(); break;