From a55e672493956e9b6f36c91b5ae3b8aba1d16774 Mon Sep 17 00:00:00 2001 From: magumagu9 Date: Fri, 13 Feb 2009 10:28:28 +0000 Subject: [PATCH] JitIL: a few more functions. Partially addresses interpreter hotspots in Metroid Prime; not really noticably faster, though. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2232 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp | 20 ++++++- Source/Core/Core/Src/PowerPC/Jit64IL/IR.h | 8 +++ .../Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp | 59 ++++++++++++++----- .../PowerPC/Jit64IL/Jit_SystemRegisters.cpp | 38 +++++++++--- 4 files changed, 100 insertions(+), 25 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp index 33c01909ed..4bbb62df03 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp @@ -1232,7 +1232,8 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { case LoadCarry: case LoadCTR: case LoadMSR: - case LoadFReg: + case LoadFReg: + case LoadGQR: case BlockEnd: case BlockStart: case InterpreterFallback: @@ -1280,7 +1281,8 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { case StoreGReg: case StoreLink: case StoreCTR: - case StoreMSR: + case StoreMSR: + case StoreGQR: case StoreFReg: if (!isImm(*getOp1(I))) regMarkUse(RI, I, getOp1(I), 1); @@ -1414,6 +1416,14 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { RI.regs[reg] = I; break; } + case LoadGQR: { + if (!thisUsed) break; + X64Reg reg = regFindFreeReg(RI); + unsigned gqr = *I >> 8; + Jit->MOV(32, R(reg), M(&GQR(gqr))); + RI.regs[reg] = I; + break; + } case LoadCarry: { if (!thisUsed) break; X64Reg reg = regFindFreeReg(RI); @@ -1452,6 +1462,12 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { regStoreInstToConstLoc(RI, 32, getOp1(I), &MSR); regNormalRegClear(RI, I); break; + } + case StoreGQR: { + unsigned gqr = *I >> 16; + regStoreInstToConstLoc(RI, 32, getOp1(I), &GQR(gqr)); + regNormalRegClear(RI, I); + break; } case StoreCarry: { Jit->CMP(32, regLocForInst(RI, getOp1(I)), Imm8(0)); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h index 6a33d5d270..8c2a8f2429 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h @@ -33,6 +33,7 @@ namespace IREmitter { LoadCarry, LoadCTR, LoadMSR, + LoadGQR, // Unary operators // Integer unary operators @@ -54,6 +55,7 @@ namespace IREmitter { StoreCTR, StoreMSR, StoreFPRF, + StoreGQR, // Arbitrary interpreter instruction InterpreterFallback, @@ -481,6 +483,12 @@ namespace IREmitter { InstLoc EmitFDCmpCR(InstLoc op1, InstLoc op2) { return FoldBiOp(FDCmpCR, op1, op2); } + InstLoc EmitLoadGQR(unsigned gqr) { + return FoldZeroOp(LoadGQR, gqr); + } + InstLoc EmitStoreGQR(InstLoc op1, unsigned gqr) { + return FoldUOp(StoreGQR, op1, gqr); + } void StartBackPass() { curReadPtr = &InstList[InstList.size()]; } void StartForwardPass() { curReadPtr = &InstList[0]; } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp index fa5e885507..3fe7840354 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp @@ -76,13 +76,7 @@ using namespace Gen; ibuild.EmitBranchUncond(ibuild.EmitIntConst(destination)); } - void Jit64::bcx(UGeckoInstruction inst) - { - NORMALBRANCH_START - if (inst.LK) - ibuild.EmitStoreLink( - ibuild.EmitIntConst(js.compilerPC + 4)); - + static IREmitter::InstLoc TestBranch(IREmitter::IRBuilder& ibuild, UGeckoInstruction inst) { IREmitter::InstLoc CRTest = 0, CTRTest = 0; if ((inst.BO & 16) == 0) // Test a CR bit { @@ -115,8 +109,18 @@ using namespace Gen; if (!Test) { Test = ibuild.EmitIntConst(1); - //PanicAlert("Unconditional conditional branch?!"); } + return Test; + } + + void Jit64::bcx(UGeckoInstruction inst) + { + NORMALBRANCH_START + if (inst.LK) + ibuild.EmitStoreLink( + ibuild.EmitIntConst(js.compilerPC + 4)); + + IREmitter::InstLoc Test = TestBranch(ibuild, inst); u32 destination; if(inst.AA) @@ -131,9 +135,30 @@ using namespace Gen; void Jit64::bcctrx(UGeckoInstruction inst) { NORMALBRANCH_START - Default(inst); - ibuild.EmitInterpreterBranch(); - return; + if ((inst.BO & 4) == 0) { + IREmitter::InstLoc c = ibuild.EmitLoadCTR(); + c = ibuild.EmitSub(c, ibuild.EmitIntConst(1)); + ibuild.EmitStoreCTR(c); + } + IREmitter::InstLoc test; + if ((inst.BO & 16) == 0) // Test a CR bit + { + IREmitter::InstLoc CRReg = ibuild.EmitLoadCR(inst.BI >> 2); + IREmitter::InstLoc CRCmp = ibuild.EmitIntConst(8 >> (inst.BI & 3)); + test = ibuild.EmitAnd(CRReg, CRCmp); + if (!(inst.BO & 8)) + test = ibuild.EmitXor(test, CRCmp); + } else { + test = ibuild.EmitIntConst(1); + } + test = ibuild.EmitICmpEq(test, ibuild.EmitIntConst(0)); + ibuild.EmitBranchCond(test, ibuild.EmitIntConst(js.compilerPC + 4)); + + IREmitter::InstLoc destination = ibuild.EmitLoadCTR(); + destination = ibuild.EmitAnd(destination, ibuild.EmitIntConst(-4)); + if (inst.LK) + ibuild.EmitStoreLink(ibuild.EmitIntConst(js.compilerPC + 4)); + ibuild.EmitBranchUncond(destination); } void Jit64::bclrx(UGeckoInstruction inst) @@ -143,8 +168,14 @@ using namespace Gen; ibuild.EmitBranchUncond(ibuild.EmitLoadLink()); return; } - Default(inst); - ibuild.EmitInterpreterBranch(); - return; + IREmitter::InstLoc test = TestBranch(ibuild, inst); + test = ibuild.EmitICmpEq(test, ibuild.EmitIntConst(0)); + ibuild.EmitBranchCond(test, ibuild.EmitIntConst(js.compilerPC + 4)); + + IREmitter::InstLoc destination = ibuild.EmitLoadLink(); + destination = ibuild.EmitAnd(destination, ibuild.EmitIntConst(-4)); + if (inst.LK) + ibuild.EmitStoreLink(ibuild.EmitIntConst(js.compilerPC + 4)); + ibuild.EmitBranchUncond(destination); } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp index 7fe624d00f..d3d19022ab 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp @@ -39,15 +39,25 @@ JITDISABLE(SystemRegisters) u32 iIndex = (inst.SPRU << 5) | (inst.SPRL & 0x1F); switch(iIndex) { - case SPR_LR: - ibuild.EmitStoreLink(ibuild.EmitLoadGReg(inst.RD)); - return; - case SPR_CTR: - ibuild.EmitStoreCTR(ibuild.EmitLoadGReg(inst.RD)); - return; - default: - Default(inst); - return; + case SPR_LR: + ibuild.EmitStoreLink(ibuild.EmitLoadGReg(inst.RD)); + return; + case SPR_CTR: + ibuild.EmitStoreCTR(ibuild.EmitLoadGReg(inst.RD)); + return; + case SPR_GQR0: + case SPR_GQR0 + 1: + case SPR_GQR0 + 2: + case SPR_GQR0 + 3: + case SPR_GQR0 + 4: + case SPR_GQR0 + 5: + case SPR_GQR0 + 6: + case SPR_GQR0 + 7: + ibuild.EmitStoreGQR(ibuild.EmitLoadGReg(inst.RD), iIndex - SPR_GQR0); + return; + default: + Default(inst); + return; } } @@ -64,6 +74,16 @@ case SPR_CTR: ibuild.EmitStoreGReg(ibuild.EmitLoadCTR(), inst.RD); return; + case SPR_GQR0: + case SPR_GQR0 + 1: + case SPR_GQR0 + 2: + case SPR_GQR0 + 3: + case SPR_GQR0 + 4: + case SPR_GQR0 + 5: + case SPR_GQR0 + 6: + case SPR_GQR0 + 7: + ibuild.EmitStoreGReg(ibuild.EmitLoadGQR(iIndex - SPR_GQR0), inst.RD); + return; default: Default(inst); return;