summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorLinesPrower <LinesPrower@gmail.com>2009-05-31 09:22:29 +0000
committerLinesPrower <LinesPrower@gmail.com>2009-05-31 09:22:29 +0000
commit4c19fa7e5f28d19a260721732f085a31d332b358 (patch)
tree9214518a13318d346d2e5d21ef743bfda9794ef6 /Source/Core
parent71e895ddf714b7c325dffaac1d8a5118f0147a0c (diff)
Implemented correct idle skipping in JIT IL
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3300 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp7
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp47
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64IL/IR.h13
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp16
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp15
-rw-r--r--Source/Core/Core/Src/PowerPC/PowerPC.cpp5
-rw-r--r--Source/Core/Core/Src/PowerPC/PowerPC.h1
7 files changed, 68 insertions, 36 deletions
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp
index c59e75fa94..7d01b617e5 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp
@@ -136,8 +136,7 @@
(Core::GetStartupParameter().bWii && Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x2C000000)) &&
Memory::ReadUnchecked_U32(js.compilerPC + 8) == 0x4182fff8)
{
- // TODO(LinesPrower):
- // - Fix idle skipping in JITIL!
+ // TODO(LinesPrower):
// - Rewrite this!
// It seems to be ugly and unefficient, but I don't know JIT stuff enough to make it right
// It only demonstrates the idea
@@ -164,8 +163,8 @@
ABI_CallFunctionC((void *)&PowerPC::OnIdle, PowerPC::ppcState.gpr[a] + (s32)(s16)inst.SIMM_16);
// ! we must continue executing of the loop after exception handling, maybe there is still 0 in r0
- //MOV(32, M(&PowerPC::ppcState.pc), Imm32(js.compilerPC + 12));
- JMP(asm_routines.testExceptions, true);
+ //MOV(32, M(&PowerPC::ppcState.pc), Imm32(js.compilerPC));
+ JMP(asm_routines.testExceptions, true);
SetJumpTarget(noIdle);
diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp
index 5f3c58dd3a..d1503f3b0e 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp
@@ -514,6 +514,14 @@ InstLoc IRBuilder::FoldBranchCond(InstLoc Op1, InstLoc Op2) {
return EmitBiOp(BranchCond, Op1, Op2);
}
+InstLoc IRBuilder::FoldIdleBranch(InstLoc Op1, InstLoc Op2) {
+ return EmitBiOp(
+ IdleBranch,
+ EmitICmpEq(getOp1(getOp1(Op1)),
+ getOp2(getOp1(Op1))), Op2
+ );
+}
+
InstLoc IRBuilder::FoldICmp(unsigned Opcode, InstLoc Op1, InstLoc Op2) {
if (isImm(*Op1)) {
if (isImm(*Op2)) {
@@ -659,6 +667,7 @@ InstLoc IRBuilder::FoldBiOp(unsigned Opcode, InstLoc Op1, InstLoc Op2, unsigned
case Shrl: return FoldShrl(Op1, Op2);
case Rol: return FoldRol(Op1, Op2);
case BranchCond: return FoldBranchCond(Op1, Op2);
+ case IdleBranch: return FoldIdleBranch(Op1, Op2);
case ICmpEq: case ICmpNe:
case ICmpUgt: case ICmpUlt: case ICmpUge: case ICmpUle:
case ICmpSgt: case ICmpSlt: case ICmpSge: case ICmpSle:
@@ -1310,9 +1319,8 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
case InterpreterFallback:
case SystemCall:
case RFIExit:
- case InterpreterBranch:
- case IdleLoop:
- case ShortIdleLoop:
+ case InterpreterBranch:
+ case ShortIdleLoop:
case Tramp:
// No liveness effects
break;
@@ -1419,6 +1427,9 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
if (!isImm(*getOp1(I)))
regMarkUse(RI, I, getOp1(I), 1);
break;
+ case IdleBranch:
+ regMarkUse(RI, I, getOp1(getOp1(I)), 1);
+ break;
case BranchCond: {
if (isICmp(*getOp1(I)) &&
isImm(*getOp2(getOp1(I)))) {
@@ -2112,6 +2123,26 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
case BlockStart:
case BlockEnd:
break;
+
+ case IdleBranch: {
+ Jit->CMP(32, regLocForInst(RI, getOp1(getOp1(I))),
+ Imm32(RI.Build->GetImmValue(getOp2(getOp1(I)))));
+ FixupBranch cont = Jit->J_CC(CC_NE);
+
+ RI.Jit->Cleanup(); // is it needed?
+ Jit->ABI_CallFunction((void *)&PowerPC::OnIdleIL);
+
+ Jit->MOV(32, M(&PC), Imm32(ibuild->GetImmValue( getOp2(I) )));
+ Jit->JMP(asm_routines.testExceptions, true);
+
+ Jit->SetJumpTarget(cont);
+ if (RI.IInfo[I - RI.FirstI] & 4)
+ regClearInst(RI, getOp1(getOp1(I)));
+ if (RI.IInfo[I - RI.FirstI] & 8)
+ regClearInst(RI, getOp2(I));
+ break;
+ }
+
case BranchCond: {
if (isICmp(*getOp1(I)) &&
isImm(*getOp2(getOp1(I)))) {
@@ -2151,15 +2182,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
regWriteExit(RI, getOp1(I));
regNormalRegClear(RI, I);
break;
- }
- case IdleLoop: {
- unsigned IdleParam = ibuild->GetImmValue(getOp1(I));
- unsigned InstLoc = ibuild->GetImmValue(getOp2(I));
- Jit->ABI_CallFunctionC((void *)&PowerPC::OnIdle, IdleParam);
- Jit->MOV(32, M(&PC), Imm32(InstLoc + 12));
- Jit->JMP(asm_routines.testExceptions, true);
- break;
- }
+ }
case ShortIdleLoop: {
unsigned InstLoc = ibuild->GetImmValue(getOp1(I));
Jit->ABI_CallFunction((void *)&CoreTiming::Idle);
diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h
index d29df47a44..6ed1118ab2 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h
+++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h
@@ -156,7 +156,9 @@ namespace IREmitter {
SystemCall,
RFIExit,
InterpreterBranch,
- IdleLoop, // The "usual" idle loop, load+compare+branch
+
+ //IdleLoop, // The "usual" idle loop, load+compare+branch
+ IdleBranch, // branch operation belonging to idle loop
ShortIdleLoop, // Idle loop seen in homebrew like wii mahjong,
// just a branch
@@ -220,6 +222,7 @@ namespace IREmitter {
InstLoc FoldShrl(InstLoc Op1, InstLoc Op2);
InstLoc FoldXor(InstLoc Op1, InstLoc Op2);
InstLoc FoldBranchCond(InstLoc Op1, InstLoc Op2);
+ InstLoc FoldIdleBranch(InstLoc Op1, InstLoc Op2);
InstLoc FoldICmp(unsigned Opcode, InstLoc Op1, InstLoc Op2);
InstLoc FoldICmpCRSigned(InstLoc Op1, InstLoc Op2);
InstLoc FoldICmpCRUnsigned(InstLoc Op1, InstLoc Op2);
@@ -246,6 +249,9 @@ namespace IREmitter {
InstLoc EmitBranchCond(InstLoc check, InstLoc dest) {
return FoldBiOp(BranchCond, check, dest);
}
+ InstLoc EmitIdleBranch(InstLoc check, InstLoc dest) {
+ return FoldBiOp(IdleBranch, check, dest);
+ }
InstLoc EmitLoadCR(unsigned crreg) {
return FoldZeroOp(LoadCR, crreg);
}
@@ -380,10 +386,7 @@ namespace IREmitter {
}
InstLoc EmitRFIExit() {
return FoldZeroOp(RFIExit, 0);
- }
- InstLoc EmitIdleLoop(InstLoc idleParam, InstLoc pc) {
- return FoldBiOp(IdleLoop, idleParam, pc);
- }
+ }
InstLoc EmitShortIdleLoop(InstLoc pc) {
return FoldUOp(ShortIdleLoop, pc);
}
diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp
index 4e05a54b5e..2bc5dd8db3 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp
@@ -27,6 +27,8 @@
#include "JitRegCache.h"
#include "JitAsm.h"
+#include "../../HW/Memmap.h"
+
// The branches are known good, or at least reasonably good.
// No need for a disable-mechanism.
@@ -127,7 +129,19 @@ using namespace Gen;
else
destination = js.compilerPC + SignExt16(inst.BD << 2);
- ibuild.EmitBranchCond(Test, ibuild.EmitIntConst(destination));
+ if (Core::GetStartupParameter().bSkipIdle &&
+ inst.hex == 0x4182fff8 &&
+ (Memory::ReadUnchecked_U32(js.compilerPC - 8) & 0xFFFF0000) == 0x800D0000 &&
+ (Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x28000000 ||
+ (Core::GetStartupParameter().bWii && Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x2C000000))
+ )
+ {
+ ibuild.EmitIdleBranch(Test, ibuild.EmitIntConst(destination));
+ }
+ else
+ {
+ ibuild.EmitBranchCond(Test, ibuild.EmitIntConst(destination));
+ }
ibuild.EmitBranchUncond(ibuild.EmitIntConst(js.compilerPC + 4));
}
diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp
index 851602040e..34bf12ec51 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp
@@ -53,20 +53,7 @@ void Jit64::lhax(UGeckoInstruction inst)
void Jit64::lXz(UGeckoInstruction inst)
{
INSTRUCTION_START
- JITDISABLE(LoadStore)
- if (Core::GetStartupParameter().bSkipIdle &&
- inst.OPCD == 32 &&
- (inst.hex & 0xFFFF0000) == 0x800D0000 &&
- (Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x28000000 ||
- (Core::GetStartupParameter().bWii && Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x2C000000)) &&
- Memory::ReadUnchecked_U32(js.compilerPC + 8) == 0x4182fff8)
- {
- ibuild.EmitIdleLoop(ibuild.EmitIntConst(PowerPC::ppcState.gpr[inst.RA] + (s32)(s16)inst.SIMM_16),
- ibuild.EmitIntConst(js.compilerPC));
- js.compilerPC += 8;
- return;
- }
-
+ JITDISABLE(LoadStore)
IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16);
if (inst.RA)
addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA));
diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.cpp b/Source/Core/Core/Src/PowerPC/PowerPC.cpp
index 7759b6a9fc..2e55b7f007 100644
--- a/Source/Core/Core/Src/PowerPC/PowerPC.cpp
+++ b/Source/Core/Core/Src/PowerPC/PowerPC.cpp
@@ -348,4 +348,9 @@ void OnIdle(u32 _uThreadAddr)
CoreTiming::Idle();
}
+void OnIdleIL()
+{
+ CoreTiming::Idle();
+}
+
} // namespace \ No newline at end of file
diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.h b/Source/Core/Core/Src/PowerPC/PowerPC.h
index 45455bfff3..c025660903 100644
--- a/Source/Core/Core/Src/PowerPC/PowerPC.h
+++ b/Source/Core/Core/Src/PowerPC/PowerPC.h
@@ -92,6 +92,7 @@ void CompactCR();
void ExpandCR();
void OnIdle(u32 _uThreadAddr);
+void OnIdleIL();
// Easy register access macros.
#define HID2 ((UReg_HID2&)PowerPC::ppcState.spr[SPR_HID2])