diff --git a/rpcs3/Emu/ARMv7/ARMv7Context.h b/rpcs3/Emu/ARMv7/ARMv7Context.h index bdfa8107e2..be06cc4a45 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Context.h +++ b/rpcs3/Emu/ARMv7/ARMv7Context.h @@ -50,7 +50,7 @@ struct ARMv7Context u32 C : 1; //Carry condition code flag u32 V : 1; //Overflow condition code flag u32 Q : 1; //Set to 1 if an SSAT or USAT instruction changes (saturates) the input value for the signed or unsigned range of the result - u32: 27; + u32 dummy : 27; }; u32 APSR; @@ -61,7 +61,7 @@ struct ARMv7Context { struct { - u32: 24; + u32 dummy : 24; u32 exception : 8; }; diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp index 3610925ecd..1ff87dd909 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp @@ -257,14 +257,12 @@ bool ARMv7_instrs::ConditionPassed(ARMv7Context& context, u32 cond) // instructions void ARMv7_instrs::UNK(ARMv7Context& context, const ARMv7Code code) { - LOG_ERROR(HLE, "Unknown/illegal opcode: 0x%04x 0x%04x", code.code1, code.code0); - Emu.Pause(); + throw fmt::format("Unknown/illegal opcode: 0x%04x 0x%04x", code.code1, code.code0); } void ARMv7_instrs::NULL_OP(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { - LOG_ERROR(HLE, "Null opcode found: 0x%04x 0x%04x", code.code1, code.code0); - Emu.Pause(); + throw fmt::format("Null opcode found: 0x%04x 0x%04x", code.code1, code.code0); } void ARMv7_instrs::HACK(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) @@ -294,6 +292,54 @@ void ARMv7_instrs::HACK(ARMv7Context& context, const ARMv7Code code, const ARMv7 } } +void ARMv7_instrs::MRC_(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) +{ + u32 cond = context.ITSTATE.advance(); + u32 t = 0; + u32 cp = 0; + u32 opc1 = 0; + u32 opc2 = 0; + u32 cn = 0; + u32 cm = 0; + + switch (type) + { + case T1: + case A1: + { + t = (code.data & 0xf000) >> 12; + cp = (code.data & 0xf00) >> 8; + opc1 = (code.data & 0xe00000) >> 21; + opc2 = (code.data & 0xe0) >> 5; + cn = (code.data & 0xf0000) >> 16; + cm = (code.data & 0xf); + + if (cp - 10 < 2) + { + throw "MRC_(T1/A1): Advanced SIMD and VFP"; + } + break; + } + default: throw __FUNCTION__; + } + + if (ConditionPassed(context, cond)) + { + if (cp == 15 && opc1 == 0 && cn == 13 && cm == 0 && opc2 == 3) + { + LOG_ERROR(ARMv7, "TODO: TLS requested"); + + if (t < 15) + { + context.GPR[t] = 0; + return; + } + } + + throw fmt::format("Bad instruction: mrc p%d,%d,r%d,c%d,c%d,%d", cp, opc1, t, cn, cm, opc2); + } +} + void ARMv7_instrs::ADC_IMM(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { switch (type) @@ -4755,34 +4801,3 @@ void ARMv7_instrs::YIELD(ARMv7Context& context, const ARMv7Code code, const ARMv default: throw __FUNCTION__; } } - - -void ARMv7_instrs::MRC_(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) -{ - u32 cond = context.ITSTATE.advance(); - u32 t = 0; - u32 cp = 0; - - switch (type) - { - case T1: - case A1: - { - t = (code.data & 0xf000) >> 12; - cp = (code.data & 0xf00) >> 8; - - if (cp - 10 < 2) - { - throw "MRC_(T1/A1): Advanced SIMD and VFP"; - } - break; - } - default: throw __FUNCTION__; - } - - if (ConditionPassed(context, cond)) - { - LOG_ERROR(ARMv7, "Bad instruction (MRC): 0x%04x 0x%04x", code.code1, code.code0); - throw __FUNCTION__; - } -} diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.h b/rpcs3/Emu/ARMv7/ARMv7Interpreter.h index 14b044ac63..c99958a35c 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.h +++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.h @@ -99,6 +99,8 @@ namespace ARMv7_instrs void HACK(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); + void MRC_(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); + void ADC_IMM(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); void ADC_REG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); void ADC_RSR(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); @@ -515,6 +517,4 @@ namespace ARMv7_instrs void WFE(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); void WFI(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); void YIELD(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); - - void MRC_(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type); }; diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp index 8bca615fcf..a81d82ac51 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp @@ -54,16 +54,9 @@ namespace sce_libc_func }); } - void printf(ARMv7Context& context, vm::psv::ptr fmt) // va_args... + std::string armv7_fmt(ARMv7Context& context, vm::psv::ptr fmt, u32 g_count, u32 f_count, u32 v_count) { - sceLibc.Error("printf(fmt=0x%x)", fmt); - - 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++) { @@ -105,7 +98,7 @@ namespace sce_libc_func } default: { - throw fmt::Format("printf(): unknown formatting: '%s'", start.get_ptr()); + throw fmt::Format("armv7_fmt(): unknown formatting: '%s'", start.get_ptr()); } } } @@ -114,7 +107,29 @@ namespace sce_libc_func result += c; } - LOG_NOTICE(TTY, result); + return result; + } + + void printf(ARMv7Context& context, vm::psv::ptr fmt) // va_args... + { + sceLibc.Error("printf(fmt=0x%x)", fmt); + + sceLibc.Notice("*** *fmt = '%s'", fmt.get_ptr()); + + LOG_NOTICE(TTY, armv7_fmt(context, fmt, 1, 0, 0)); + } + + void sprintf(ARMv7Context& context, vm::psv::ptr str, vm::psv::ptr fmt) // va_args... + { + sceLibc.Error("sprintf(str=0x%x, fmt=0x%x)", str, fmt); + + sceLibc.Notice("*** *fmt = '%s'", fmt.get_ptr()); + + const std::string& result = armv7_fmt(context, fmt, 2, 0, 0); + + sceLibc.Notice("*** res -> '%s'", result); + + ::memcpy(str.get_ptr(), result.c_str(), result.size() + 1); } void __cxa_set_dso_handle_main(vm::psv::ptr dso) @@ -247,7 +262,7 @@ psv_log_base sceLibc("SceLibc", []() //REG_FUNC(0x395490DA, setbuf); //REG_FUNC(0x2CA980A0, setvbuf); //REG_FUNC(0xA1BFF606, snprintf); - //REG_FUNC(0x7449B359, sprintf); + REG_FUNC(0x7449B359, sprintf); //REG_FUNC(0xEC585241, sscanf); //REG_FUNC(0x2BCB3F01, ungetc); //REG_FUNC(0xF7915685, vfprintf);