diff --git a/Core/MIPS/x86/X64IRAsm.cpp b/Core/MIPS/x86/X64IRAsm.cpp index cbbfff09dc..c69eb49341 100644 --- a/Core/MIPS/x86/X64IRAsm.cpp +++ b/Core/MIPS/x86/X64IRAsm.cpp @@ -52,16 +52,31 @@ void X64JitBackend::GenerateFixedCode(MIPSState *mipsState) { BeginWrite(GetMemoryProtectPageSize()); const u8 *start = AlignCodePage(); + jo.downcountInRegister = false; +#if PPSSPP_ARCH(AMD64) + bool jitbaseInR15 = false; + uintptr_t jitbase = (uintptr_t)GetBasePtr(); + if (jitbase > 0x7FFFFFFFULL) { + jo.reserveR15ForAsm = true; + jitbaseInR15 = true; + } else { + jo.downcountInRegister = true; + jo.reserveR15ForAsm = true; + } +#endif + if (jo.useStaticAlloc && false) { saveStaticRegisters_ = AlignCode16(); - //MOV(32, MDisp(CTXREG, downcountOffset), R(DOWNCOUNTREG)); + if (jo.downcountInRegister) + MOV(32, MDisp(CTXREG, downcountOffset), R(DOWNCOUNTREG)); //regs_.EmitSaveStaticRegisters(); RET(); // Note: needs to not modify EAX, or to save it if it does. loadStaticRegisters_ = AlignCode16(); //regs_.EmitLoadStaticRegisters(); - //MOV(32, R(DOWNCOUNTREG), MDisp(CTXREG, downcountOffset)); + if (jo.downcountInRegister) + MOV(32, R(DOWNCOUNTREG), MDisp(CTXREG, downcountOffset)); RET(); start = saveStaticRegisters_; @@ -119,11 +134,8 @@ void X64JitBackend::GenerateFixedCode(MIPSState *mipsState) { #if PPSSPP_ARCH(AMD64) // Two x64-specific statically allocated registers. MOV(64, R(MEMBASEREG), ImmPtr(Memory::base)); - uintptr_t jitbase = (uintptr_t)GetBasePtr(); - if (jitbase > 0x7FFFFFFFULL) { + if (jitbaseInR15) MOV(64, R(JITBASEREG), ImmPtr(GetBasePtr())); - jo.reserveR15ForAsm = true; - } #endif // From the start of the FP reg, a single byte offset can reach all GPR + all FPR (but not VFPR.) MOV(PTRBITS, R(CTXREG), ImmPtr(&mipsState->f[0])); @@ -151,8 +163,11 @@ void X64JitBackend::GenerateFixedCode(MIPSState *mipsState) { } FixupBranch badCoreState = J_CC(CC_NZ, true); - //CMP(32, R(DOWNCOUNTREG), Imm32(0)); - CMP(32, MDisp(CTXREG, downcountOffset), Imm32(0)); + if (jo.downcountInRegister) { + TEST(32, R(DOWNCOUNTREG), R(DOWNCOUNTREG)); + } else { + CMP(32, MDisp(CTXREG, downcountOffset), Imm32(0)); + } J_CC(CC_S, outerLoop_); FixupBranch skipToRealDispatch = J(); @@ -162,8 +177,11 @@ void X64JitBackend::GenerateFixedCode(MIPSState *mipsState) { hooks_.dispatcher = GetCodePtr(); // TODO: See if we can get the slice decrement to line up with IR. - //CMP(32, R(DOWNCOUNTREG), Imm32(0)); - CMP(32, MDisp(CTXREG, downcountOffset), Imm32(0)); + if (jo.downcountInRegister) { + TEST(32, R(DOWNCOUNTREG), R(DOWNCOUNTREG)); + } else { + CMP(32, MDisp(CTXREG, downcountOffset), Imm32(0)); + } FixupBranch bail = J_CC(CC_S, true); SetJumpTarget(skipToRealDispatch); @@ -172,7 +190,7 @@ void X64JitBackend::GenerateFixedCode(MIPSState *mipsState) { // Debug if (enableDebug) { #if PPSSPP_ARCH(AMD64) - if (jo.reserveR15ForAsm) + if (jitbaseInR15) ABI_CallFunctionAA(reinterpret_cast(&ShowPC), R(MEMBASEREG), R(JITBASEREG)); else ABI_CallFunctionAC(reinterpret_cast(&ShowPC), R(MEMBASEREG), (u32)jitbase); @@ -202,7 +220,7 @@ void X64JitBackend::GenerateFixedCode(MIPSState *mipsState) { #if PPSSPP_ARCH(X86) ADD(32, R(SCRATCH1), ImmPtr(GetBasePtr())); #elif PPSSPP_ARCH(AMD64) - if (jo.reserveR15ForAsm) { + if (jitbaseInR15) { ADD(64, R(SCRATCH1), R(JITBASEREG)); } else { // See above, reserveR15ForAsm is used when above 0x7FFFFFFF. diff --git a/Core/MIPS/x86/X64IRCompSystem.cpp b/Core/MIPS/x86/X64IRCompSystem.cpp index 2b4122df9b..50264e768b 100644 --- a/Core/MIPS/x86/X64IRCompSystem.cpp +++ b/Core/MIPS/x86/X64IRCompSystem.cpp @@ -46,8 +46,11 @@ void X64JitBackend::CompIR_Basic(IRInst inst) { switch (inst.op) { case IROp::Downcount: - //SUB(32, R(DOWNCOUNTREG), R(DOWNCOUNTREG), Imm32((s32)inst.constant)); - SUB(32, MDisp(CTXREG, downcountOffset), Imm32((s32)inst.constant)); + // As long as we don't care about flags, just use LEA. + if (jo.downcountInRegister) + LEA(32, DOWNCOUNTREG, MDisp(DOWNCOUNTREG, -(s32)inst.constant)); + else + SUB(32, MDisp(CTXREG, downcountOffset), SImmAuto((s32)inst.constant)); break; case IROp::SetConst: diff --git a/Core/MIPS/x86/X64IRJit.cpp b/Core/MIPS/x86/X64IRJit.cpp index b2e6b40056..d905dadb92 100644 --- a/Core/MIPS/x86/X64IRJit.cpp +++ b/Core/MIPS/x86/X64IRJit.cpp @@ -63,8 +63,11 @@ bool X64JitBackend::CompileBlock(IRBlock *block, int block_num, bool preload) { wroteCheckedOffset = true; // TODO: See if we can get flags to always have the downcount compare. - //CMP(32, R(DOWNCOUNTREG), Imm32(0)); - CMP(32, MDisp(CTXREG, downcountOffset), Imm32(0)); + if (jo.downcountInRegister) { + TEST(32, R(DOWNCOUNTREG), R(DOWNCOUNTREG)); + } else { + CMP(32, MDisp(CTXREG, downcountOffset), Imm32(0)); + } FixupBranch normalEntry = J_CC(CC_NS); MOV(32, R(SCRATCH1), Imm32(startPC)); JMP(outerLoopPCInSCRATCH1_, true); @@ -116,8 +119,11 @@ bool X64JitBackend::CompileBlock(IRBlock *block, int block_num, bool preload) { } if (jo.enableBlocklink && jo.useBackJump) { - //CMP(32, R(DOWNCOUNTREG), Imm32(0)); - CMP(32, MDisp(CTXREG, downcountOffset), Imm32(0)); + if (jo.downcountInRegister) { + TEST(32, R(DOWNCOUNTREG), R(DOWNCOUNTREG)); + } else { + CMP(32, MDisp(CTXREG, downcountOffset), Imm32(0)); + } J_CC(CC_NS, blockStart, true); MOV(32, R(SCRATCH1), Imm32(startPC)); @@ -317,17 +323,17 @@ void X64JitBackend::MovToPC(X64Reg r) { void X64JitBackend::SaveStaticRegisters() { if (jo.useStaticAlloc) { //CALL(saveStaticRegisters_); - } else { + } else if (jo.downcountInRegister) { // Inline the single operation - //MOV(32, MDisp(CTXREG, downcountOffset), R(DOWNCOUNTREG)); + MOV(32, MDisp(CTXREG, downcountOffset), R(DOWNCOUNTREG)); } } void X64JitBackend::LoadStaticRegisters() { if (jo.useStaticAlloc) { //CALL(loadStaticRegisters_); - } else { - //MOV(32, R(DOWNCOUNTREG), MDisp(CTXREG, downcountOffset)); + } else if (jo.downcountInRegister) { + MOV(32, R(DOWNCOUNTREG), MDisp(CTXREG, downcountOffset)); } } diff --git a/Core/MIPS/x86/X64IRRegCache.h b/Core/MIPS/x86/X64IRRegCache.h index 023d31fe70..d36463d876 100644 --- a/Core/MIPS/x86/X64IRRegCache.h +++ b/Core/MIPS/x86/X64IRRegCache.h @@ -31,8 +31,10 @@ namespace X64IRJitConstants { const Gen::X64Reg MEMBASEREG = Gen::RBX; const Gen::X64Reg CTXREG = Gen::R14; const Gen::X64Reg JITBASEREG = Gen::R15; +const Gen::X64Reg DOWNCOUNTREG = Gen::R15; #else const Gen::X64Reg CTXREG = Gen::EBP; +const Gen::X64Reg DOWNCOUNTREG = Gen::INVALID_REG; #endif const Gen::X64Reg SCRATCH1 = Gen::EAX;