diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index 0e231951df..4e62400e14 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -336,12 +336,9 @@ void Jit64::WriteRfiExitDestInEAX() MOV(32, M(&NPC), R(EAX)); Cleanup(); - SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount)); ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions)); - MOV(32, R(EAX), M(&NPC)); - MOV(32, M(&PC), R(EAX)); - + SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount)); TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); J_CC(CC_Z, asm_routines.outerLoop, true); @@ -352,14 +349,11 @@ void Jit64::WriteRfiExitDestInEAX() void Jit64::WriteExceptionExit() { Cleanup(); - SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount)); MOV(32, R(EAX), M(&PC)); MOV(32, M(&NPC), R(EAX)); ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions)); - MOV(32, R(EAX), M(&NPC)); - MOV(32, M(&PC), R(EAX)); - + SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount)); TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); J_CC(CC_Z, asm_routines.outerLoop, true); @@ -370,13 +364,10 @@ void Jit64::WriteExceptionExit() void Jit64::WriteExternalExceptionExit() { Cleanup(); - SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount)); MOV(32, R(EAX), M(&PC)); MOV(32, M(&NPC), R(EAX)); ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExternalExceptions)); - MOV(32, R(EAX), M(&NPC)); - MOV(32, M(&PC), R(EAX)); - + SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount)); TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); J_CC(CC_Z, asm_routines.outerLoop, true); @@ -600,9 +591,6 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc // If a FPU exception occurs, the exception handler will read // from PC. Update PC with the latest value in case that happens. MOV(32, M(&PC), Imm32(ops[i].address)); - SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount)); - - LOCK(); OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE)); WriteExceptionExit(); @@ -690,8 +678,6 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc // Address of instruction could not be translated MOV(32, M(&NPC), Imm32(js.compilerPC)); - SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount)); - LOCK(); OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_ISI)); // Remove the invalid instruction from the icache, forcing a recompile diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp index 13c4b02f4d..2a830a03cf 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp @@ -1268,8 +1268,8 @@ static const unsigned alwaysUsedList[] = { StoreGQR, StoreSRR, StoreCarry, StoreFPRF, Load8, Load16, Load32, Store8, Store16, Store32, StoreSingle, StoreDouble, StorePaired, StoreFReg, FDCmpCR, BlockStart, BlockEnd, IdleBranch, BranchCond, BranchUncond, ShortIdleLoop, - SystemCall, InterpreterBranch, RFIExit, FPExceptionCheckStart, - FPExceptionCheckEnd, ISIException, ExtExceptionCheck, BreakPointCheck, + SystemCall, InterpreterBranch, RFIExit, FPExceptionCheck, + DSIExceptionCheck, ISIException, ExtExceptionCheck, BreakPointCheck, Int3, Tramp, Nop }; static const unsigned extra8RegList[] = { diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h index f41742b01c..77f7d6977b 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h @@ -167,7 +167,7 @@ enum Opcode { // used for exception checking, at least until someone // has a better idea of integrating it - FPExceptionCheckStart, FPExceptionCheckEnd, + FPExceptionCheck, DSIExceptionCheck, ISIException, ExtExceptionCheck, BreakPointCheck, // "Opcode" representing a register too far away to // reference directly; this is a size optimization @@ -402,11 +402,11 @@ public: InstLoc EmitSystemCall(InstLoc pc) { return FoldUOp(SystemCall, pc); } - InstLoc EmitFPExceptionCheckStart(InstLoc pc) { - return EmitUOp(FPExceptionCheckStart, pc); + InstLoc EmitFPExceptionCheck(InstLoc pc) { + return EmitUOp(FPExceptionCheck, pc); } - InstLoc EmitFPExceptionCheckEnd(InstLoc pc) { - return EmitUOp(FPExceptionCheckEnd, pc); + InstLoc EmitDSIExceptionCheck(InstLoc pc) { + return EmitUOp(DSIExceptionCheck, pc); } InstLoc EmitISIException(InstLoc dest) { return EmitUOp(ISIException, dest); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp index 7579c69a03..0df155758f 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp @@ -759,8 +759,8 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak case RFIExit: case InterpreterBranch: case ShortIdleLoop: - case FPExceptionCheckStart: - case FPExceptionCheckEnd: + case FPExceptionCheck: + case DSIExceptionCheck: case ISIException: case ExtExceptionCheck: case BreakPointCheck: @@ -1869,7 +1869,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak Jit->WriteRfiExitDestInOpArg(R(EAX)); break; } - case FPExceptionCheckStart: { + case FPExceptionCheck: { unsigned InstLoc = ibuild->GetImmValue(getOp1(I)); //This instruction uses FPU - needs to add FP exception bailout Jit->TEST(32, M(&PowerPC::ppcState.msr), Imm32(1 << 13)); // Test FP enabled bit @@ -1883,7 +1883,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak Jit->SetJumpTarget(b1); break; } - case FPExceptionCheckEnd: { + case DSIExceptionCheck: { unsigned InstLoc = ibuild->GetImmValue(getOp1(I)); Jit->TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_DSI)); FixupBranch noMemException = Jit->J_CC(CC_Z); @@ -1926,13 +1926,13 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak case ExtExceptionCheck: { unsigned InstLoc = ibuild->GetImmValue(getOp1(I)); - Jit->TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_ISI | EXCEPTION_PROGRAM | EXCEPTION_SYSCALL | EXCEPTION_FPU_UNAVAILABLE | EXCEPTION_DSI | EXCEPTION_ALIGNMENT | EXCEPTION_DECREMENTER)); + Jit->TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_ISI | EXCEPTION_PROGRAM | EXCEPTION_SYSCALL | EXCEPTION_FPU_UNAVAILABLE | EXCEPTION_DSI | EXCEPTION_ALIGNMENT)); FixupBranch clearInt = Jit->J_CC(CC_NZ); Jit->TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_EXTERNAL_INT)); FixupBranch noExtException = Jit->J_CC(CC_Z); Jit->TEST(32, M((void *)&PowerPC::ppcState.msr), Imm32(0x0008000)); FixupBranch noExtIntEnable = Jit->J_CC(CC_Z); - Jit->TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP || ProcessorInterface::INT_CAUSE_PE_TOKEN || ProcessorInterface::INT_CAUSE_PE_FINISH)); + Jit->TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP | ProcessorInterface::INT_CAUSE_PE_TOKEN | ProcessorInterface::INT_CAUSE_PE_FINISH)); FixupBranch noCPInt = Jit->J_CC(CC_Z); Jit->MOV(32, M(&PC), Imm32(InstLoc)); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp index d462ff8a35..ee209527bf 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp @@ -527,7 +527,10 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc } if (em_address == 0) - PanicAlert("ERROR : Trying to compile at 0. LR=%08x", LR); + { + // Memory exception occurred during instruction fetch + memory_exception = true; + } if (Core::g_CoreStartupParameter.bMMU && (em_address & JIT_ICACHE_VMEM_BIT)) { @@ -644,7 +647,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc { if (js.memcheck && (opinfo->flags & FL_USE_FPU)) { - ibuild.EmitFPExceptionCheckStart(ibuild.EmitIntConst(ops[i].address)); + ibuild.EmitFPExceptionCheck(ibuild.EmitIntConst(ops[i].address)); } if (jit->js.fifoWriteAddresses.find(js.compilerPC) != jit->js.fifoWriteAddresses.end()) @@ -661,7 +664,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc if (js.memcheck && (opinfo->flags & FL_LOADSTORE)) { - ibuild.EmitFPExceptionCheckEnd(ibuild.EmitIntConst(ops[i].address)); + ibuild.EmitDSIExceptionCheck(ibuild.EmitIntConst(ops[i].address)); } } } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp index ac533dd473..d04c58b143 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp @@ -211,14 +211,14 @@ void JitILAsmRoutineManager::Generate() doTiming = GetCodePtr(); ABI_CallFunction(reinterpret_cast(&CoreTiming::Advance)); - + testExceptions = GetCodePtr(); MOV(32, R(EAX), M(&PC)); MOV(32, M(&NPC), R(EAX)); ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions)); MOV(32, R(EAX), M(&NPC)); MOV(32, M(&PC), R(EAX)); - + TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); J_CC(CC_Z, outerLoop, true); //Landing pad for drec space diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.cpp b/Source/Core/Core/Src/PowerPC/PowerPC.cpp index 542ada6013..c9ced2385a 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/Src/PowerPC/PowerPC.cpp @@ -308,7 +308,7 @@ void CheckExceptions() // clear MSR as specified //MSR &= ~0x04EF36; // 0x04FF36 also clears ME (only for machine check exception) // set to exception type entry point - //NPC = 0x80000x00; + //NPC = 0x00000x00; if (exceptions & EXCEPTION_ISI) { @@ -317,7 +317,7 @@ void CheckExceptions() SRR1 = (MSR & 0x87C0FFFF) | (1 << 30); MSR |= (MSR >> 16) & 1; MSR &= ~0x04EF36; - NPC = 0x00000400; + PC = NPC = 0x00000400; INFO_LOG(POWERPC, "EXCEPTION_ISI"); Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_ISI); @@ -329,7 +329,7 @@ void CheckExceptions() SRR1 = (MSR & 0x87C0FFFF) | 0x20000; MSR |= (MSR >> 16) & 1; MSR &= ~0x04EF36; - NPC = 0x00000700; + PC = NPC = 0x00000700; INFO_LOG(POWERPC, "EXCEPTION_PROGRAM"); Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_PROGRAM); @@ -340,7 +340,7 @@ void CheckExceptions() SRR1 = MSR & 0x87C0FFFF; MSR |= (MSR >> 16) & 1; MSR &= ~0x04EF36; - NPC = 0x00000C00; + PC = NPC = 0x00000C00; INFO_LOG(POWERPC, "EXCEPTION_SYSCALL (PC=%08x)", PC); Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_SYSCALL); @@ -352,7 +352,7 @@ void CheckExceptions() SRR1 = MSR & 0x87C0FFFF; MSR |= (MSR >> 16) & 1; MSR &= ~0x04EF36; - NPC = 0x00000800; + PC = NPC = 0x00000800; INFO_LOG(POWERPC, "EXCEPTION_FPU_UNAVAILABLE"); Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_FPU_UNAVAILABLE); @@ -363,7 +363,7 @@ void CheckExceptions() SRR1 = MSR & 0x87C0FFFF; MSR |= (MSR >> 16) & 1; MSR &= ~0x04EF36; - NPC = 0x00000300; + PC = NPC = 0x00000300; //DSISR and DAR regs are changed in GenerateDSIException() INFO_LOG(POWERPC, "EXCEPTION_DSI"); @@ -377,7 +377,7 @@ void CheckExceptions() SRR1 = MSR & 0x87C0FFFF; MSR |= (MSR >> 16) & 1; MSR &= ~0x04EF36; - NPC = 0x00000600; + PC = NPC = 0x00000600; //TODO crazy amount of DSISR options to check out @@ -395,7 +395,7 @@ void CheckExceptions() SRR1 = MSR & 0x87C0FFFF; MSR |= (MSR >> 16) & 1; MSR &= ~0x04EF36; - NPC = 0x00000500; + PC = NPC = 0x00000500; INFO_LOG(POWERPC, "EXCEPTION_EXTERNAL_INT"); Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_EXTERNAL_INT); @@ -408,7 +408,7 @@ void CheckExceptions() SRR1 = MSR & 0x87C0FFFF; MSR |= (MSR >> 16) & 1; MSR &= ~0x04EF36; - NPC = 0x00000900; + PC = NPC = 0x00000900; INFO_LOG(POWERPC, "EXCEPTION_DECREMENTER"); Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_DECREMENTER); @@ -446,7 +446,7 @@ void CheckExternalExceptions() SRR1 = MSR & 0x87C0FFFF; MSR |= (MSR >> 16) & 1; MSR &= ~0x04EF36; - NPC = 0x00000500; + PC = NPC = 0x00000500; INFO_LOG(POWERPC, "EXCEPTION_EXTERNAL_INT"); Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_EXTERNAL_INT); @@ -459,7 +459,7 @@ void CheckExternalExceptions() SRR1 = MSR & 0x87C0FFFF; MSR |= (MSR >> 16) & 1; MSR &= ~0x04EF36; - NPC = 0x00000900; + PC = NPC = 0x00000900; INFO_LOG(POWERPC, "EXCEPTION_DECREMENTER"); Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_DECREMENTER);