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
This commit is contained in:
parent
0f8c866612
commit
a55e672493
|
@ -1233,6 +1233,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||||
case LoadCTR:
|
case LoadCTR:
|
||||||
case LoadMSR:
|
case LoadMSR:
|
||||||
case LoadFReg:
|
case LoadFReg:
|
||||||
|
case LoadGQR:
|
||||||
case BlockEnd:
|
case BlockEnd:
|
||||||
case BlockStart:
|
case BlockStart:
|
||||||
case InterpreterFallback:
|
case InterpreterFallback:
|
||||||
|
@ -1281,6 +1282,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||||
case StoreLink:
|
case StoreLink:
|
||||||
case StoreCTR:
|
case StoreCTR:
|
||||||
case StoreMSR:
|
case StoreMSR:
|
||||||
|
case StoreGQR:
|
||||||
case StoreFReg:
|
case StoreFReg:
|
||||||
if (!isImm(*getOp1(I)))
|
if (!isImm(*getOp1(I)))
|
||||||
regMarkUse(RI, I, getOp1(I), 1);
|
regMarkUse(RI, I, getOp1(I), 1);
|
||||||
|
@ -1414,6 +1416,14 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||||
RI.regs[reg] = I;
|
RI.regs[reg] = I;
|
||||||
break;
|
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: {
|
case LoadCarry: {
|
||||||
if (!thisUsed) break;
|
if (!thisUsed) break;
|
||||||
X64Reg reg = regFindFreeReg(RI);
|
X64Reg reg = regFindFreeReg(RI);
|
||||||
|
@ -1453,6 +1463,12 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) {
|
||||||
regNormalRegClear(RI, I);
|
regNormalRegClear(RI, I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case StoreGQR: {
|
||||||
|
unsigned gqr = *I >> 16;
|
||||||
|
regStoreInstToConstLoc(RI, 32, getOp1(I), &GQR(gqr));
|
||||||
|
regNormalRegClear(RI, I);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case StoreCarry: {
|
case StoreCarry: {
|
||||||
Jit->CMP(32, regLocForInst(RI, getOp1(I)), Imm8(0));
|
Jit->CMP(32, regLocForInst(RI, getOp1(I)), Imm8(0));
|
||||||
FixupBranch nocarry = Jit->J_CC(CC_Z);
|
FixupBranch nocarry = Jit->J_CC(CC_Z);
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace IREmitter {
|
||||||
LoadCarry,
|
LoadCarry,
|
||||||
LoadCTR,
|
LoadCTR,
|
||||||
LoadMSR,
|
LoadMSR,
|
||||||
|
LoadGQR,
|
||||||
|
|
||||||
// Unary operators
|
// Unary operators
|
||||||
// Integer unary operators
|
// Integer unary operators
|
||||||
|
@ -54,6 +55,7 @@ namespace IREmitter {
|
||||||
StoreCTR,
|
StoreCTR,
|
||||||
StoreMSR,
|
StoreMSR,
|
||||||
StoreFPRF,
|
StoreFPRF,
|
||||||
|
StoreGQR,
|
||||||
// Arbitrary interpreter instruction
|
// Arbitrary interpreter instruction
|
||||||
InterpreterFallback,
|
InterpreterFallback,
|
||||||
|
|
||||||
|
@ -481,6 +483,12 @@ namespace IREmitter {
|
||||||
InstLoc EmitFDCmpCR(InstLoc op1, InstLoc op2) {
|
InstLoc EmitFDCmpCR(InstLoc op1, InstLoc op2) {
|
||||||
return FoldBiOp(FDCmpCR, op1, 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 StartBackPass() { curReadPtr = &InstList[InstList.size()]; }
|
||||||
void StartForwardPass() { curReadPtr = &InstList[0]; }
|
void StartForwardPass() { curReadPtr = &InstList[0]; }
|
||||||
|
|
|
@ -76,13 +76,7 @@ using namespace Gen;
|
||||||
ibuild.EmitBranchUncond(ibuild.EmitIntConst(destination));
|
ibuild.EmitBranchUncond(ibuild.EmitIntConst(destination));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::bcx(UGeckoInstruction inst)
|
static IREmitter::InstLoc TestBranch(IREmitter::IRBuilder& ibuild, UGeckoInstruction inst) {
|
||||||
{
|
|
||||||
NORMALBRANCH_START
|
|
||||||
if (inst.LK)
|
|
||||||
ibuild.EmitStoreLink(
|
|
||||||
ibuild.EmitIntConst(js.compilerPC + 4));
|
|
||||||
|
|
||||||
IREmitter::InstLoc CRTest = 0, CTRTest = 0;
|
IREmitter::InstLoc CRTest = 0, CTRTest = 0;
|
||||||
if ((inst.BO & 16) == 0) // Test a CR bit
|
if ((inst.BO & 16) == 0) // Test a CR bit
|
||||||
{
|
{
|
||||||
|
@ -115,8 +109,18 @@ using namespace Gen;
|
||||||
|
|
||||||
if (!Test) {
|
if (!Test) {
|
||||||
Test = ibuild.EmitIntConst(1);
|
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;
|
u32 destination;
|
||||||
if(inst.AA)
|
if(inst.AA)
|
||||||
|
@ -131,9 +135,30 @@ using namespace Gen;
|
||||||
void Jit64::bcctrx(UGeckoInstruction inst)
|
void Jit64::bcctrx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
NORMALBRANCH_START
|
NORMALBRANCH_START
|
||||||
Default(inst);
|
if ((inst.BO & 4) == 0) {
|
||||||
ibuild.EmitInterpreterBranch();
|
IREmitter::InstLoc c = ibuild.EmitLoadCTR();
|
||||||
return;
|
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)
|
void Jit64::bclrx(UGeckoInstruction inst)
|
||||||
|
@ -143,8 +168,14 @@ using namespace Gen;
|
||||||
ibuild.EmitBranchUncond(ibuild.EmitLoadLink());
|
ibuild.EmitBranchUncond(ibuild.EmitLoadLink());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Default(inst);
|
IREmitter::InstLoc test = TestBranch(ibuild, inst);
|
||||||
ibuild.EmitInterpreterBranch();
|
test = ibuild.EmitICmpEq(test, ibuild.EmitIntConst(0));
|
||||||
return;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,16 @@
|
||||||
case SPR_CTR:
|
case SPR_CTR:
|
||||||
ibuild.EmitStoreCTR(ibuild.EmitLoadGReg(inst.RD));
|
ibuild.EmitStoreCTR(ibuild.EmitLoadGReg(inst.RD));
|
||||||
return;
|
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:
|
||||||
Default(inst);
|
Default(inst);
|
||||||
return;
|
return;
|
||||||
|
@ -64,6 +74,16 @@
|
||||||
case SPR_CTR:
|
case SPR_CTR:
|
||||||
ibuild.EmitStoreGReg(ibuild.EmitLoadCTR(), inst.RD);
|
ibuild.EmitStoreGReg(ibuild.EmitLoadCTR(), inst.RD);
|
||||||
return;
|
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:
|
||||||
Default(inst);
|
Default(inst);
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue