diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp index c87bc2422f..4987993927 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp @@ -326,6 +326,19 @@ InstLoc IRBuilder::FoldUOp(unsigned Opcode, InstLoc Op1, unsigned extra) { if (Opcode == DoubleToSingle) { if (getOpcode(*Op1) == DupSingleToMReg) return getOp1(Op1); + if (getOpcode(*Op1) >= FDMul || getOpcode(*Op1) <= FDSub) { + InstLoc OOp1 = getOp1(Op1), OOp2 = getOp2(Op1); + if (getOpcode(*OOp1) == DupSingleToMReg && + getOpcode(*OOp2) == DupSingleToMReg) { + if (getOpcode(*Op1) == FDMul) { + return FoldBiOp(FSMul, getOp1(OOp1), getOp2(OOp2)); + } else if (getOpcode(*Op1) == FDAdd) { + return FoldBiOp(FSAdd, getOp1(OOp1), getOp2(OOp2)); + } else if (getOpcode(*Op1) == FDSub) { + return FoldBiOp(FSSub, getOp1(OOp1), getOp2(OOp2)); + } + } + } } return EmitUOp(Opcode, Op1, extra); @@ -1340,7 +1353,8 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { case StoreLink: case StoreCTR: case StoreMSR: - case StoreGQR: + case StoreGQR: + case StoreSRR: case StoreFReg: if (!isImm(*getOp1(I))) regMarkUse(RI, I, getOp1(I), 1); @@ -1526,6 +1540,13 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { regStoreInstToConstLoc(RI, 32, getOp1(I), &GQR(gqr)); regNormalRegClear(RI, I); break; + } + case StoreSRR: { + unsigned srr = *I >> 16; + regStoreInstToConstLoc(RI, 32, getOp1(I), + &PowerPC::ppcState.spr[SPR_SRR0+srr]); + 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 ac39047cb8..f41f322f8e 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h @@ -56,6 +56,7 @@ namespace IREmitter { StoreMSR, StoreFPRF, StoreGQR, + StoreSRR, // Arbitrary interpreter instruction InterpreterFallback, @@ -491,6 +492,9 @@ namespace IREmitter { InstLoc EmitStoreGQR(InstLoc op1, unsigned gqr) { return FoldUOp(StoreGQR, op1, gqr); } + InstLoc EmitStoreSRR(InstLoc op1, unsigned srr) { + return FoldUOp(StoreSRR, op1, srr); + } void StartBackPass() { curReadPtr = &InstList[InstList.size()]; } void StartForwardPass() { curReadPtr = &InstList[0]; } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp index d3d19022ab..b3508925ba 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_SystemRegisters.cpp @@ -55,6 +55,10 @@ case SPR_GQR0 + 7: ibuild.EmitStoreGQR(ibuild.EmitLoadGReg(inst.RD), iIndex - SPR_GQR0); return; + case SPR_SRR0: + case SPR_SRR1: + ibuild.EmitStoreSRR(ibuild.EmitLoadGReg(inst.RD), iIndex - SPR_SRR0); + return; default: Default(inst); return;