summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authormagumagu <magumagu9@gmail.com>2015-01-23 16:01:05 -0800
committermagumagu <magumagu9@gmail.com>2015-02-11 13:56:36 -0800
commite136c8a066d5a1d9e593bfdf3296979a5a18a157 (patch)
treed0bf0f87b6d6740ca1a2bf8ed043ef227b640d4f /Source/Core
parentac54c6a4e2f6790f628f8a8112ff1940732f5068 (diff)
PowerPC: misc cleanup.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp6
-rw-r--r--Source/Core/Core/PowerPC/PPCAnalyst.cpp222
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;