diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp index d1503f3b0e..ff31c83c1e 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp @@ -257,6 +257,10 @@ InstLoc IRBuilder::FoldZeroOp(unsigned Opcode, unsigned extra) { FRegCache[extra] = EmitZeroOp(LoadFReg, extra); return FRegCache[extra]; } + if (Opcode == LoadFRegDENToZero) { + // cant use cache here + return EmitZeroOp(LoadFRegDENToZero, extra); + } if (Opcode == LoadCarry) { if (!CarryCache) CarryCache = EmitZeroOp(LoadCarry, extra); @@ -1313,6 +1317,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { case LoadCTR: case LoadMSR: case LoadFReg: + case LoadFRegDENToZero: case LoadGQR: case BlockEnd: case BlockStart: @@ -1981,6 +1986,22 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { Jit->MOVAPD(reg, M(&PowerPC::ppcState.ps[ppcreg])); RI.fregs[reg] = I; break; + } + case LoadFRegDENToZero: { + if (!thisUsed) break; + X64Reg reg = fregFindFreeReg(RI); + unsigned ppcreg = *I >> 8; + char *p = (char*)&(PowerPC::ppcState.ps[ppcreg][0]); + Jit->MOV(32, R(ECX), M(p+4)); + Jit->AND(32, R(ECX), Imm32(0x7ff00000)); + Jit->CMP(32, R(ECX), Imm32(0x38000000)); + FixupBranch ok = Jit->J_CC(CC_AE); + Jit->AND(32, M(p+4), Imm32(0x80000000)); + Jit->MOV(32, M(p), Imm32(0)); + Jit->SetJumpTarget(ok); + Jit->MOVAPD(reg, M(&PowerPC::ppcState.ps[ppcreg])); + RI.fregs[reg] = I; + break; } case StoreFReg: { unsigned ppcreg = *I >> 16; diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h index 6ed1118ab2..e3f335228e 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h @@ -119,6 +119,7 @@ namespace IREmitter { ExpandPackedToMReg, CompactMRegToPacked, LoadFReg, + LoadFRegDENToZero, FSMul, FSAdd, FSSub, @@ -411,6 +412,9 @@ namespace IREmitter { InstLoc EmitLoadFReg(unsigned freg) { return FoldZeroOp(LoadFReg, freg); } + InstLoc EmitLoadFRegDENToZero(unsigned freg) { + return FoldZeroOp(LoadFRegDENToZero, freg); + } InstLoc EmitStoreFReg(InstLoc val, unsigned freg) { return FoldUOp(StoreFReg, val, freg); } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp index 30d3a749fb..9fe28e2dd9 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp @@ -102,14 +102,11 @@ void Jit64::fcmpx(UGeckoInstruction inst) { - // @TODO: conform this to the new fcmpo - Default(inst); return; - INSTRUCTION_START JITDISABLE(FloatingPoint) IREmitter::InstLoc lhs, rhs, res; - lhs = ibuild.EmitLoadFReg(inst.FA); - rhs = ibuild.EmitLoadFReg(inst.FB); + lhs = ibuild.EmitLoadFRegDENToZero(inst.FA); + rhs = ibuild.EmitLoadFRegDENToZero(inst.FB); res = ibuild.EmitFDCmpCR(lhs, rhs); ibuild.EmitStoreFPRF(res); ibuild.EmitStoreCR(res, inst.CRFD);