diff --git a/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp b/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp index 179e461aed..521b62502d 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp @@ -25,8 +25,8 @@ const ARMv7_opcode_t ARMv7_opcode_table[] = { ARMv7_OP2(0xffff, 0x0000, T1, NULL_OP), // ??? - ARMv7_OP4(0xffff, 0x0000, 0xf870, 0x0000, T1, HACK), // "Undefined" Thumb opcode - ARMv7_OP4(0x0ff0, 0x00f0, 0x0070, 0x0090, A1, HACK), // "Undefined" ARM opcode + ARMv7_OP4(0xffff, 0x0000, 0xf870, 0x0000, T1, HACK), // "Undefined" Thumb opcode used + ARMv7_OP4(0x0ff0, 0x00f0, 0x0070, 0x0090, A1, HACK), // "Undefined" ARM opcode used ARMv7_OP4(0xfbe0, 0x8000, 0xf140, 0x0000, T1, ADC_IMM), ARMv7_OP4(0x0fe0, 0x0000, 0x02a0, 0x0000, A1, ADC_IMM), @@ -594,6 +594,11 @@ const ARMv7_opcode_t ARMv7_opcode_table[] = ARMv7_OP2(0xffff, 0xbf10, T1, YIELD), ARMv7_OP4(0xffff, 0xffff, 0xf3af, 0x8001, T2, YIELD), ARMv7_OP4(0x0fff, 0xffff, 0x0320, 0xf001, A1, YIELD), + + ARMv7_OP4(0xff10, 0x0010, 0xee10, 0x0010, T1, MRC_), + ARMv7_OP4(0x0f10, 0x0010, 0x0e10, 0x0010, A1, MRC_), + ARMv7_OP4(0xff10, 0x0010, 0xfe10, 0x0010, T2, MRC_), + ARMv7_OP4(0xff10, 0x0010, 0xfe10, 0x0010, A2, MRC_), }; struct ARMv7_op2_table_t diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp index c03c963075..e9e865f6c6 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp @@ -257,13 +257,13 @@ 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.data >> 16, code.data & 0xffff); + LOG_ERROR(HLE, "Unknown/illegal opcode: 0x%04x 0x%04x", code.code1, code.code0); Emu.Pause(); } void ARMv7_instrs::NULL_OP(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { - LOG_ERROR(HLE, "Null opcode found: data = 0x%x", code.data); + LOG_ERROR(HLE, "Null opcode found: 0x%04x 0x%04x", code.code1, code.code0); Emu.Pause(); } @@ -687,7 +687,7 @@ void ARMv7_instrs::B(ARMv7Context& context, const ARMv7Code code, const ARMv7_en } case T3: { - cond = (code.data >> 6) & 0xf; + cond = (code.data >> 22) & 0xf; if (cond >= 0xe) { throw "B_T3: Related encodings"; @@ -4854,3 +4854,34 @@ 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 "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 4f187e379b..88306e053f 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.h +++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.h @@ -526,4 +526,6 @@ 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/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index 80906f88ca..520fb8f991 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -215,6 +215,7 @@ namespace loader const u32 addr = *++code; vm::psv::write16(addr + 0, 0xf240 | (data & 0x800) >> 1 | (data & 0xf000) >> 12); // MOVW vm::psv::write16(addr + 2, 0x0c00 | (data & 0x700) << 4 | (data & 0xff)); + LOG_NOTICE(LOADER, "sceRefs: movw written at 0x%x (data=0x%x)", addr, data); break; } case 0x00000030: @@ -223,16 +224,18 @@ namespace loader const u32 addr = *++code; vm::psv::write16(addr + 0, 0xf2c0 | (data & 0x8000000) >> 17 | (data & 0xf0000000) >> 28); // MOVT vm::psv::write16(addr + 2, 0x0c00 | (data & 0x7000000) >> 12 | (data & 0xff0000) >> 16); + LOG_NOTICE(LOADER, "sceRefs: movt written at 0x%x (data=0x%x)", addr, data); break; } case 0x00000000: { // probably, no operation + LOG_NOTICE(LOADER, "sceRefs: zero code"); break; } default: { - LOG_NOTICE(LOADER, "sceRefs: unknown code found (0x%08x)", *code); + LOG_ERROR(LOADER, "sceRefs: unknown code found (0x%08x)", *code); } } }