diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index 87fb248c1f..394c7bc86a 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -276,7 +276,7 @@ void Jit64::Cleanup() ABI_CallFunctionCCC((void *)&PowerPC::UpdatePerformanceMonitor, js.downcountAmount, jit->js.numLoadStoreInst, jit->js.numFloatingPointInst); } -void Jit64::WriteExit(u32 destination) +void Jit64::WriteExit(u32 destination, int exit_num) { Cleanup(); @@ -284,9 +284,8 @@ void Jit64::WriteExit(u32 destination) //If nobody has taken care of this yet (this can be removed when all branches are done) JitBlock *b = js.curBlock; - JitBlock::LinkData linkData; - linkData.exitAddress = destination; - linkData.exitPtrs = GetWritableCodePtr(); + b->exitAddress[exit_num] = destination; + b->exitPtrs[exit_num] = GetWritableCodePtr(); // Link opportunity! if (jo.enableBlocklink) @@ -296,14 +295,12 @@ void Jit64::WriteExit(u32 destination) { // It exists! Joy of joy! JMP(blocks.GetBlock(block)->checkedEntry, true); - linkData.linkStatus = true; + b->linkStatus[exit_num] = true; return; } } MOV(32, M(&PC), Imm32(destination)); JMP(asm_routines.dispatcher, true); - - b->linkData.push_back(linkData); } void Jit64::WriteExitDestInEAX() @@ -628,7 +625,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); FixupBranch noBreakpoint = J_CC(CC_Z); - WriteExit(ops[i].address); + WriteExit(ops[i].address, 0); SetJumpTarget(noBreakpoint); } @@ -710,7 +707,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc { gpr.Flush(FLUSH_ALL); fpr.Flush(FLUSH_ALL); - WriteExit(nextPC); + WriteExit(nextPC, 0); } b->flags = js.block_flags; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index 1adbdfaac4..139414a103 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -99,7 +99,7 @@ public: // Utilities for use by opcodes - void WriteExit(u32 destination); + void WriteExit(u32 destination, int exit_num); void WriteExitDestInEAX(); void WriteExceptionExit(); void WriteExternalExceptionExit(); diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp index a1e28ac6ea..b0f3f1cd18 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp @@ -91,7 +91,7 @@ void Jit64::bx(UGeckoInstruction inst) // make idle loops go faster js.downcountAmount += 8; } - WriteExit(destination); + WriteExit(destination, 0); } // TODO - optimize to hell and beyond @@ -136,13 +136,13 @@ void Jit64::bcx(UGeckoInstruction inst) destination = SignExt16(inst.BD << 2); else destination = js.compilerPC + SignExt16(inst.BD << 2); - WriteExit(destination); + WriteExit(destination, 0); if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) SetJumpTarget( pConditionDontBranch ); if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) SetJumpTarget( pCTRDontBranch ); - WriteExit(js.compilerPC + 4); + WriteExit(js.compilerPC + 4, 1); } void Jit64::bcctrx(UGeckoInstruction inst) @@ -190,7 +190,7 @@ void Jit64::bcctrx(UGeckoInstruction inst) WriteExitDestInEAX(); // Would really like to continue the block here, but it ends. TODO. SetJumpTarget(b); - WriteExit(js.compilerPC + 4); + WriteExit(js.compilerPC + 4, 1); } } @@ -245,5 +245,5 @@ void Jit64::bclrx(UGeckoInstruction inst) SetJumpTarget( pConditionDontBranch ); if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) SetJumpTarget( pCTRDontBranch ); - WriteExit(js.compilerPC + 4); + WriteExit(js.compilerPC + 4, 1); } diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp index 8299f2b044..244a051aaa 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp @@ -400,7 +400,7 @@ void Jit64::cmpXX(UGeckoInstruction inst) destination = SignExt16(js.next_inst.BD << 2); else destination = js.next_compilerPC + SignExt16(js.next_inst.BD << 2); - WriteExit(destination); + WriteExit(destination, 0); } else if ((js.next_inst.OPCD == 19) && (js.next_inst.SUBOP10 == 528)) // bcctrx { @@ -424,7 +424,7 @@ void Jit64::cmpXX(UGeckoInstruction inst) } else { - WriteExit(js.next_compilerPC + 4); + WriteExit(js.next_compilerPC + 4, 0); } js.cancel = true; @@ -507,7 +507,7 @@ void Jit64::cmpXX(UGeckoInstruction inst) destination = SignExt16(js.next_inst.BD << 2); else destination = js.next_compilerPC + SignExt16(js.next_inst.BD << 2); - WriteExit(destination); + WriteExit(destination, 0); } else if ((js.next_inst.OPCD == 19) && (js.next_inst.SUBOP10 == 528)) // bcctrx { @@ -534,7 +534,7 @@ void Jit64::cmpXX(UGeckoInstruction inst) if (!!(4 & test_bit) == condition) SetJumpTarget(continue2); if (!!(2 & test_bit) == condition) SetJumpTarget(continue1); - WriteExit(js.next_compilerPC + 4); + WriteExit(js.next_compilerPC + 4, 1); js.cancel = true; } @@ -2221,5 +2221,5 @@ void Jit64::twx(UGeckoInstruction inst) SetJumpTarget(exit3); SetJumpTarget(exit4); SetJumpTarget(exit5); - WriteExit(js.compilerPC + 4); + WriteExit(js.compilerPC + 4, 1); } diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp index 1b41c2f1e9..a1c3bd971c 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp @@ -480,5 +480,5 @@ void Jit64::stmw(UGeckoInstruction inst) void Jit64::icbi(UGeckoInstruction inst) { Default(inst); - WriteExit(js.compilerPC + 4); + WriteExit(js.compilerPC + 4, 0); } diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp index 8282758a74..573feb3756 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp @@ -137,7 +137,7 @@ void Jit64::mtmsr(UGeckoInstruction inst) SetJumpTarget(noExceptionsPending); SetJumpTarget(eeDisabled); - WriteExit(js.compilerPC + 4); + WriteExit(js.compilerPC + 4, 0); js.firstFPInstructionFound = false; } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp index ef1db98de1..7a37a1cb43 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp @@ -552,8 +552,7 @@ static void regEmitICmpInst(RegInfo& RI, InstLoc I, CCFlags flag) { static void regWriteExit(RegInfo& RI, InstLoc dest) { if (isImm(*dest)) { - RI.exitNumber++; - RI.Jit->WriteExit(RI.Build->GetImmValue(dest)); + RI.Jit->WriteExit(RI.Build->GetImmValue(dest), RI.exitNumber++); } else { RI.Jit->WriteExitDestInOpArg(regLocForInst(RI, dest)); } @@ -565,7 +564,7 @@ static bool checkIsSNAN() { return MathUtil::IsSNAN(isSNANTemp[0][0]) || MathUtil::IsSNAN(isSNANTemp[1][0]); } -static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) { +static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit) { //printf("Writing block: %x\n", js.blockStart); RegInfo RI(Jit, ibuild->getFirstInst(), ibuild->getNumInsts()); RI.Build = ibuild; @@ -1792,7 +1791,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) { Jit->ABI_CallFunction(reinterpret_cast(&PowerPC::CheckBreakPoints)); Jit->TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); FixupBranch noBreakpoint = Jit->J_CC(CC_Z); - Jit->WriteExit(InstLoc); + Jit->WriteExit(InstLoc, 0); Jit->SetJumpTarget(noBreakpoint); break; } @@ -1820,10 +1819,10 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) { } } - Jit->WriteExit(exitAddress); + Jit->WriteExit(jit->js.curBlock->exitAddress[0], 0); Jit->UD2(); } -void JitIL::WriteCode(u32 exitAddress) { - DoWriteCode(&ibuild, this, exitAddress); +void JitIL::WriteCode() { + DoWriteCode(&ibuild, this); } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp index 1518bc57bb..b15ffbacca 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp @@ -381,7 +381,7 @@ void JitIL::Cleanup() ABI_CallFunctionCCC((void *)&PowerPC::UpdatePerformanceMonitor, js.downcountAmount, jit->js.numLoadStoreInst, jit->js.numFloatingPointInst); } -void JitIL::WriteExit(u32 destination) +void JitIL::WriteExit(u32 destination, int exit_num) { Cleanup(); if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) { @@ -391,9 +391,8 @@ void JitIL::WriteExit(u32 destination) //If nobody has taken care of this yet (this can be removed when all branches are done) JitBlock *b = js.curBlock; - JitBlock::LinkData linkData; - linkData.exitAddress = destination; - linkData.exitPtrs = GetWritableCodePtr(); + b->exitAddress[exit_num] = destination; + b->exitPtrs[exit_num] = GetWritableCodePtr(); // Link opportunity! int block = blocks.GetBlockNumberFromStartAddress(destination); @@ -401,14 +400,13 @@ void JitIL::WriteExit(u32 destination) { // It exists! Joy of joy! JMP(blocks.GetBlock(block)->checkedEntry, true); - linkData.linkStatus = true; + b->linkStatus[exit_num] = true; } else { MOV(32, M(&PC), Imm32(destination)); JMP(asm_routines.dispatcher, true); } - b->linkData.push_back(linkData); } void JitIL::WriteExitDestInOpArg(const Gen::OpArg& arg) @@ -543,16 +541,14 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc // Analyze the block, collect all instructions it is made of (including inlining, // if that is enabled), reorder instructions for optimal performance, and join joinable instructions. - u32 exitAddress = em_address; - + b->exitAddress[0] = em_address; u32 merged_addresses[32]; const int capacity_of_merged_addresses = sizeof(merged_addresses) / sizeof(merged_addresses[0]); int size_of_merged_addresses = 0; if (!memory_exception) { // If there is a memory exception inside a block (broken_block==true), compile up to that instruction. - // TODO - exitAddress = PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, broken_block, code_buf, blockSize, merged_addresses, capacity_of_merged_addresses, size_of_merged_addresses); + b->exitAddress[0] = PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, broken_block, code_buf, blockSize, merged_addresses, capacity_of_merged_addresses, size_of_merged_addresses); } PPCAnalyst::CodeOp *ops = code_buf->codebuffer; @@ -711,7 +707,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc } // Perform actual code generation - WriteCode(exitAddress); + WriteCode(); b->codeSize = (u32)(GetCodePtr() - normalEntry); b->originalSize = size; diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h index 305a96015f..e56a56c815 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h @@ -105,7 +105,7 @@ public: // Utilities for use by opcodes - void WriteExit(u32 destination); + void WriteExit(u32 destination, int exit_num); void WriteExitDestInOpArg(const Gen::OpArg& arg); void WriteExceptionExit(); void WriteRfiExitDestInOpArg(const Gen::OpArg& arg); @@ -121,7 +121,7 @@ public: void regimmop(int d, int a, bool binary, u32 value, Operation doop, void (Gen::XEmitter::*op)(int, const Gen::OpArg&, const Gen::OpArg&), bool Rc = false, bool carry = false); void fp_tri_op(int d, int a, int b, bool reversible, bool dupe, void (Gen::XEmitter::*op)(Gen::X64Reg, Gen::OpArg)); - void WriteCode(u32 exitAddress); + void WriteCode(); // OPCODES void unknown_instruction(UGeckoInstruction _inst) override; diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp index eab7f3711a..4083a383e9 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp @@ -186,16 +186,15 @@ void JitArm::WriteExceptionExit() MOVI2R(A, (u32)asm_routines.testExceptions); B(A); } -void JitArm::WriteExit(u32 destination) +void JitArm::WriteExit(u32 destination, int exit_num) { Cleanup(); DoDownCount(); //If nobody has taken care of this yet (this can be removed when all branches are done) JitBlock *b = js.curBlock; - JitBlock::LinkData linkData; - linkData.exitAddress = destination; - linkData.exitPtrs = GetWritableCodePtr(); + b->exitAddress[exit_num] = destination; + b->exitPtrs[exit_num] = GetWritableCodePtr(); // Link opportunity! int block = blocks.GetBlockNumberFromStartAddress(destination); @@ -203,7 +202,7 @@ void JitArm::WriteExit(u32 destination) { // It exists! Joy of joy! B(blocks.GetBlock(block)->checkedEntry); - linkData.linkStatus = true; + b->linkStatus[exit_num] = true; } else { @@ -213,8 +212,6 @@ void JitArm::WriteExit(u32 destination) MOVI2R(A, (u32)asm_routines.dispatcher); B(A); } - - b->linkData.push_back(linkData); } void STACKALIGN JitArm::Run() @@ -499,7 +496,7 @@ const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlo if (broken_block) { printf("Broken Block going to 0x%08x\n", nextPC); - WriteExit(nextPC); + WriteExit(nextPC, 0); } b->flags = js.block_flags; diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h index 4d1d2d8a4e..fc1911c5bf 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h @@ -109,7 +109,7 @@ public: // Utilities for use by opcodes - void WriteExit(u32 destination); + void WriteExit(u32 destination, int exit_num); void WriteExitDestInR(ARMReg Reg); void WriteRfiExitDestInR(ARMReg Reg); void WriteExceptionExit(); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp index eac488a5b0..4e9101f7b2 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp @@ -154,7 +154,7 @@ void JitArm::bx(UGeckoInstruction inst) MOVI2R(R14, (u32)asm_routines.testExceptions); B(R14); } - WriteExit(destination); + WriteExit(destination, 0); } void JitArm::bcx(UGeckoInstruction inst) @@ -209,14 +209,14 @@ void JitArm::bcx(UGeckoInstruction inst) destination = SignExt16(inst.BD << 2); else destination = js.compilerPC + SignExt16(inst.BD << 2); - WriteExit(destination); + WriteExit(destination, 0); if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) SetJumpTarget( pConditionDontBranch ); if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) SetJumpTarget( pCTRDontBranch ); - WriteExit(js.compilerPC + 4); + WriteExit(js.compilerPC + 4, 1); } void JitArm::bcctrx(UGeckoInstruction inst) { @@ -278,7 +278,7 @@ void JitArm::bcctrx(UGeckoInstruction inst) WriteExitDestInR(rA); SetJumpTarget(b); - WriteExit(js.compilerPC + 4); + WriteExit(js.compilerPC + 4, 1); } } void JitArm::bclrx(UGeckoInstruction inst) @@ -355,5 +355,5 @@ void JitArm::bclrx(UGeckoInstruction inst) SetJumpTarget( pConditionDontBranch ); if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) SetJumpTarget( pCTRDontBranch ); - WriteExit(js.compilerPC + 4); + WriteExit(js.compilerPC + 4, 1); } diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp index 3983772aa6..f04c88d6c3 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp @@ -531,6 +531,6 @@ void JitArm::dcbst(UGeckoInstruction inst) void JitArm::icbi(UGeckoInstruction inst) { Default(inst); - WriteExit(js.compilerPC + 4); + WriteExit(js.compilerPC + 4, 0); } diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp index 62b15e1d5e..e4ab630fce 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp @@ -205,7 +205,7 @@ void JitArm::mtmsr(UGeckoInstruction inst) gpr.Flush(); fpr.Flush(); - WriteExit(js.compilerPC + 4); + WriteExit(js.compilerPC + 4, 0); } void JitArm::mfmsr(UGeckoInstruction inst) diff --git a/Source/Core/Core/Src/PowerPC/JitArmIL/IR_Arm.cpp b/Source/Core/Core/Src/PowerPC/JitArmIL/IR_Arm.cpp index c1bee507fc..10620d9183 100644 --- a/Source/Core/Core/Src/PowerPC/JitArmIL/IR_Arm.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArmIL/IR_Arm.cpp @@ -156,8 +156,7 @@ static ARMReg regEnsureInReg(RegInfo& RI, InstLoc I) { static void regWriteExit(RegInfo& RI, InstLoc dest) { if (isImm(*dest)) { - RI.exitNumber++; - RI.Jit->WriteExit(RI.Build->GetImmValue(dest)); + RI.Jit->WriteExit(RI.Build->GetImmValue(dest), RI.exitNumber++); } else { RI.Jit->WriteExitDestInReg(regLocForInst(RI, dest)); } @@ -282,7 +281,7 @@ static void regEmitCmp(RegInfo& RI, InstLoc I) { } } -static void DoWriteCode(IRBuilder* ibuild, JitArmIL* Jit, u32 exitAddress) { +static void DoWriteCode(IRBuilder* ibuild, JitArmIL* Jit) { RegInfo RI(Jit, ibuild->getFirstInst(), ibuild->getNumInsts()); RI.Build = ibuild; @@ -734,10 +733,10 @@ static void DoWriteCode(IRBuilder* ibuild, JitArmIL* Jit, u32 exitAddress) { } } - Jit->WriteExit(exitAddress); + Jit->WriteExit(jit->js.curBlock->exitAddress[0], 0); Jit->BKPT(0x111); } -void JitArmIL::WriteCode(u32 exitAddress) { - DoWriteCode(&ibuild, this, exitAddress); +void JitArmIL::WriteCode() { + DoWriteCode(&ibuild, this); } diff --git a/Source/Core/Core/Src/PowerPC/JitArmIL/JitIL.cpp b/Source/Core/Core/Src/PowerPC/JitArmIL/JitIL.cpp index 44ebc8b6eb..0aac4d6722 100644 --- a/Source/Core/Core/Src/PowerPC/JitArmIL/JitIL.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArmIL/JitIL.cpp @@ -117,14 +117,13 @@ void JitArmIL::WriteExceptionExit() MOVI2R(R14, (u32)asm_routines.testExceptions); B(R14); } -void JitArmIL::WriteExit(u32 destination) +void JitArmIL::WriteExit(u32 destination, int exit_num) { DoDownCount(); //If nobody has taken care of this yet (this can be removed when all branches are done) JitBlock *b = js.curBlock; - JitBlock::LinkData linkData; - linkData.exitAddress = destination; - linkData.exitPtrs = GetWritableCodePtr(); + b->exitAddress[exit_num] = destination; + b->exitPtrs[exit_num] = GetWritableCodePtr(); // Link opportunity! int block = blocks.GetBlockNumberFromStartAddress(destination); @@ -132,7 +131,7 @@ void JitArmIL::WriteExit(u32 destination) { // It exists! Joy of joy! B(blocks.GetBlock(block)->checkedEntry); - linkData.linkStatus = true; + b->linkStatus[exit_num] = true; } else { @@ -141,8 +140,6 @@ void JitArmIL::WriteExit(u32 destination) MOVI2R(R14, (u32)asm_routines.dispatcher); B(R14); } - - b->linkData.push_back(linkData); } void JitArmIL::PrintDebug(UGeckoInstruction inst, u32 level) { @@ -350,12 +347,12 @@ const u8* JitArmIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB if (broken_block) { printf("Broken Block going to 0x%08x\n", nextPC); - WriteExit(nextPC); + WriteExit(nextPC, 0); } // Perform actual code generation - WriteCode(nextPC); + WriteCode(); b->flags = js.block_flags; b->codeSize = (u32)(GetCodePtr() - normalEntry); b->originalSize = size; diff --git a/Source/Core/Core/Src/PowerPC/JitArmIL/JitIL.h b/Source/Core/Core/Src/PowerPC/JitArmIL/JitIL.h index 71b09a3251..4dec87ddeb 100644 --- a/Source/Core/Core/Src/PowerPC/JitArmIL/JitIL.h +++ b/Source/Core/Core/Src/PowerPC/JitArmIL/JitIL.h @@ -64,8 +64,8 @@ public: void Run(); void SingleStep(); // - void WriteCode(u32 exitAddress); - void WriteExit(u32 destination); + void WriteCode(); + void WriteExit(u32 destination, int exit_num); void WriteExitDestInReg(ARMReg Reg); void WriteRfiExitDestInR(ARMReg Reg); void WriteExceptionExit(); diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp index b81dadd394..d7c78d9d17 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp @@ -35,6 +35,8 @@ op_agent_t agent; using namespace Gen; +#define INVALID_EXIT 0xFFFFFFFF + bool JitBaseBlockCache::IsFull() const { return GetNumBlocks() >= MAX_NUM_BLOCKS - 1; @@ -165,6 +167,12 @@ using namespace Gen; JitBlock &b = blocks[num_blocks]; b.invalid = false; b.originalAddress = em_address; + b.exitAddress[0] = INVALID_EXIT; + b.exitAddress[1] = INVALID_EXIT; + b.exitPtrs[0] = 0; + b.exitPtrs[1] = 0; + b.linkStatus[0] = false; + b.linkStatus[1] = false; num_blocks++; //commit the current block return num_blocks - 1; } @@ -185,9 +193,10 @@ using namespace Gen; block_map[std::make_pair(pAddr + 4 * b.originalSize - 1, pAddr)] = block_num; if (block_link) { - for (const auto& e : b.linkData) + for (int i = 0; i < 2; i++) { - links_to.insert(std::pair(e.exitAddress, block_num)); + if (b.exitAddress[i] != INVALID_EXIT) + links_to.insert(std::pair(b.exitAddress[i], block_num)); } LinkBlock(block_num); @@ -266,15 +275,15 @@ using namespace Gen; // This block is dead. Don't relink it. return; } - for (auto& e : b.linkData) + for (int e = 0; e < 2; e++) { - if (!e.linkStatus) + if (b.exitAddress[e] != INVALID_EXIT && !b.linkStatus[e]) { - int destinationBlock = GetBlockNumberFromStartAddress(e.exitAddress); + int destinationBlock = GetBlockNumberFromStartAddress(b.exitAddress[e]); if (destinationBlock != -1) { - WriteLinkBlock(e.exitPtrs, blocks[destinationBlock].checkedEntry); - e.linkStatus = true; + WriteLinkBlock(b.exitPtrs[e], blocks[destinationBlock].checkedEntry); + b.linkStatus[e] = true; } } } @@ -307,10 +316,10 @@ using namespace Gen; return; for (multimap::iterator iter = ppp.first; iter != ppp.second; ++iter) { JitBlock &sourceBlock = blocks[iter->second]; - for (auto& e : sourceBlock.linkData) + for (int e = 0; e < 2; e++) { - if (e.exitAddress == b.originalAddress) - e.linkStatus = false; + if (sourceBlock.exitAddress[e] == b.originalAddress) + sourceBlock.linkStatus[e] = false; } } } diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h index ffbffaadb5..b81c5d837a 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h @@ -35,6 +35,9 @@ struct JitBlock const u8 *checkedEntry; const u8 *normalEntry; + u8 *exitPtrs[2]; // to be able to rewrite the exit jum + u32 exitAddress[2]; // 0xFFFFFFFF == unknown + u32 originalAddress; u32 codeSize; u32 originalSize; @@ -42,13 +45,7 @@ struct JitBlock int flags; bool invalid; - - struct LinkData { - u8 *exitPtrs; // to be able to rewrite the exit jum - u32 exitAddress; - bool linkStatus; // is it already linked? - }; - std::vector linkData; + bool linkStatus[2]; #ifdef _WIN32 // we don't really need to save start and stop