diff options
| author | magumagu <magumagu9@gmail.com> | 2015-01-23 16:01:05 -0800 |
|---|---|---|
| committer | magumagu <magumagu9@gmail.com> | 2015-02-11 13:56:36 -0800 |
| commit | e136c8a066d5a1d9e593bfdf3296979a5a18a157 (patch) | |
| tree | d0bf0f87b6d6740ca1a2bf8ed043ef227b640d4f /Source/Core | |
| parent | ac54c6a4e2f6790f628f8a8112ff1940732f5068 (diff) | |
PowerPC: misc cleanup.
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp | 6 | ||||
| -rw-r--r-- | Source/Core/Core/PowerPC/PPCAnalyst.cpp | 222 |
2 files changed, 110 insertions, 118 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp index e7f03e6037..352a94a2cd 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp @@ -401,9 +401,9 @@ void JitArm64::lXX(UGeckoInstruction inst) if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle && inst.OPCD == 32 && (inst.hex & 0xFFFF0000) == 0x800D0000 && - (PowerPC::HostRead_U32(js.compilerPC + 4) == 0x28000000 || - (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && PowerPC::HostRead_U32(js.compilerPC + 4) == 0x2C000000)) && - PowerPC::HostRead_U32(js.compilerPC + 8) == 0x4182fff8) + (PowerPC::HostRead_U32(js.compilerPC + 4) == 0x28000000 || + (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && PowerPC::HostRead_U32(js.compilerPC + 4) == 0x2C000000)) && + PowerPC::HostRead_U32(js.compilerPC + 8) == 0x4182fff8) { // if it's still 0, we can wait until the next event FixupBranch noIdle = CBNZ(gpr.R(d)); diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/PowerPC/PPCAnalyst.cpp index 69c27ac314..739cf22b8e 100644 --- a/Source/Core/Core/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/PowerPC/PPCAnalyst.cpp @@ -668,145 +668,137 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock *block, CodeBuffer *buffer, u32 } UGeckoInstruction inst = result.hex; - if (inst.hex != 0) + // Slight hack: the JIT block cache currently assumes all blocks end at the same place, + // but broken blocks due to page faults break this assumption. Avoid this by just ending + // all virtual memory instruction blocks at page boundaries. + // FIXME: improve the JIT block cache so we don't need to do this. + if ((!result.from_bat || !prev_inst_from_bat) && i > 0 && (address & 0xfff) == 0) { - // Slight hack: the JIT block cache currently assumes all blocks end at the same place, - // but broken blocks due to page faults break this assumption. Avoid this by just ending - // all virtual memory instruction blocks at page boundaries. - // FIXME: improve the JIT block cache so we don't need to do this. - if ((!result.from_bat || !prev_inst_from_bat) && i > 0 && (address & 0xfff) == 0) - { - break; - } - prev_inst_from_bat = result.from_bat; + break; + } + prev_inst_from_bat = result.from_bat; - num_inst++; - memset(&code[i], 0, sizeof(CodeOp)); - GekkoOPInfo *opinfo = GetOpInfo(inst); - if (!opinfo) - { - PanicAlert("Invalid PowerPC opcode: %x.", inst.hex); - Crash(); - } + num_inst++; + memset(&code[i], 0, sizeof(CodeOp)); + GekkoOPInfo *opinfo = GetOpInfo(inst); + if (!opinfo) + { + PanicAlert("Invalid PowerPC opcode: %x.", inst.hex); + Crash(); + } - code[i].opinfo = opinfo; - code[i].address = address; - code[i].inst = inst; - code[i].branchTo = -1; - code[i].branchToIndex = -1; - code[i].skip = false; - block->m_stats->numCycles += opinfo->numCycles; + code[i].opinfo = opinfo; + code[i].address = address; + code[i].inst = inst; + code[i].branchTo = -1; + code[i].branchToIndex = -1; + code[i].skip = false; + block->m_stats->numCycles += opinfo->numCycles; - SetInstructionStats(block, &code[i], opinfo, i); + SetInstructionStats(block, &code[i], opinfo, i); - bool follow = false; - u32 destination = 0; + bool follow = false; + u32 destination = 0; - bool conditional_continue = false; + bool conditional_continue = false; - // Do we inline leaf functions? - if (HasOption(OPTION_LEAF_INLINE)) + // Do we inline leaf functions? + if (HasOption(OPTION_LEAF_INLINE)) + { + if (inst.OPCD == 18 && blockSize > 1) { - if (inst.OPCD == 18 && blockSize > 1) - { - //Is bx - should we inline? yes! - if (inst.AA) - destination = SignExt26(inst.LI << 2); - else - destination = address + SignExt26(inst.LI << 2); - if (destination != block->m_address) - follow = true; - } - else if (inst.OPCD == 19 && inst.SUBOP10 == 16 && - (inst.BO & (1 << 4)) && (inst.BO & (1 << 2)) && - return_address != 0) - { - // bclrx with unconditional branch = return + //Is bx - should we inline? yes! + if (inst.AA) + destination = SignExt26(inst.LI << 2); + else + destination = address + SignExt26(inst.LI << 2); + if (destination != block->m_address) follow = true; - destination = return_address; - return_address = 0; - - if (inst.LK) - return_address = address + 4; - } - else if (inst.OPCD == 31 && inst.SUBOP10 == 467) - { - // mtspr - const u32 index = (inst.SPRU << 5) | (inst.SPRL & 0x1F); - if (index == SPR_LR) - { - // We give up to follow the return address - // because we have to check the register usage. - return_address = 0; - } - } - - // TODO: Find the optimal value for FUNCTION_FOLLOWING_THRESHOLD. - // If it is small, the performance will be down. - // If it is big, the size of generated code will be big and - // cache clearning will happen many times. - // TODO: Investivate the reason why - // "0" is fastest in some games, MP2 for example. - if (numFollows > FUNCTION_FOLLOWING_THRESHOLD) - follow = false; } + else if (inst.OPCD == 19 && inst.SUBOP10 == 16 && + (inst.BO & (1 << 4)) && (inst.BO & (1 << 2)) && + return_address != 0) + { + // bclrx with unconditional branch = return + follow = true; + destination = return_address; + return_address = 0; - if (HasOption(OPTION_CONDITIONAL_CONTINUE)) + if (inst.LK) + return_address = address + 4; + } + else if (inst.OPCD == 31 && inst.SUBOP10 == 467) { - if (inst.OPCD == 16 && - ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0 || (inst.BO & BO_DONT_CHECK_CONDITION) == 0)) + // mtspr + const u32 index = (inst.SPRU << 5) | (inst.SPRL & 0x1F); + if (index == SPR_LR) { - // bcx with conditional branch - conditional_continue = true; - } - else if (inst.OPCD == 19 && inst.SUBOP10 == 16 && - ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0 || (inst.BO & BO_DONT_CHECK_CONDITION) == 0)) - { - // bclrx with conditional branch - conditional_continue = true; - } - else if (inst.OPCD == 3 || - (inst.OPCD == 31 && inst.SUBOP10 == 4)) - { - // tw/twi tests and raises an exception - conditional_continue = true; - } - else if (inst.OPCD == 19 && inst.SUBOP10 == 528 && - (inst.BO_2 & BO_DONT_CHECK_CONDITION) == 0) - { - // Rare bcctrx with conditional branch - // Seen in NES games - conditional_continue = true; + // We give up to follow the return address + // because we have to check the register usage. + return_address = 0; } } - if (!follow) + // TODO: Find the optimal value for FUNCTION_FOLLOWING_THRESHOLD. + // If it is small, the performance will be down. + // If it is big, the size of generated code will be big and + // cache clearning will happen many times. + // TODO: Investivate the reason why + // "0" is fastest in some games, MP2 for example. + if (numFollows > FUNCTION_FOLLOWING_THRESHOLD) + follow = false; + } + + if (HasOption(OPTION_CONDITIONAL_CONTINUE)) + { + if (inst.OPCD == 16 && + ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0 || (inst.BO & BO_DONT_CHECK_CONDITION) == 0)) { - address += 4; - if (!conditional_continue && opinfo->flags & FL_ENDBLOCK) //right now we stop early - { - found_exit = true; - break; - } + // bcx with conditional branch + conditional_continue = true; } - // XXX: We don't support inlining yet. -#if 0 - else + else if (inst.OPCD == 19 && inst.SUBOP10 == 16 && + ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0 || (inst.BO & BO_DONT_CHECK_CONDITION) == 0)) { - numFollows++; - // We don't "code[i].skip = true" here - // because bx may store a certain value to the link register. - // Instead, we skip a part of bx in Jit**::bx(). - address = destination; - merged_addresses[size_of_merged_addresses++] = address; + // bclrx with conditional branch + conditional_continue = true; + } + else if (inst.OPCD == 3 || + (inst.OPCD == 31 && inst.SUBOP10 == 4)) + { + // tw/twi tests and raises an exception + conditional_continue = true; + } + else if (inst.OPCD == 19 && inst.SUBOP10 == 528 && + (inst.BO_2 & BO_DONT_CHECK_CONDITION) == 0) + { + // Rare bcctrx with conditional branch + // Seen in NES games + conditional_continue = true; } -#endif } + + if (!follow) + { + address += 4; + if (!conditional_continue && opinfo->flags & FL_ENDBLOCK) //right now we stop early + { + found_exit = true; + break; + } + } + // XXX: We don't support inlining yet. +#if 0 else { - ERROR_LOG(DYNA_REC, "Instruction hex was 0!"); - break; + numFollows++; + // We don't "code[i].skip = true" here + // because bx may store a certain value to the link register. + // Instead, we skip a part of bx in Jit**::bx(). + address = destination; + merged_addresses[size_of_merged_addresses++] = address; } +#endif } block->m_num_instructions = num_inst; |
