mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 17:49:29 +01:00
Merge pull request #14365 from unknownbrackets/cpu-cycles
Increase the cycle cost of VFPU ops and div.s
This commit is contained in:
9 files changed
+52
-33
No files matched your search
@@ -113,6 +113,7 @@ void ArmJit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely)
|
||||
}
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rt, rs);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
|
||||
@@ -231,6 +232,7 @@ void ArmJit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool like
|
||||
}
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
|
||||
@@ -334,6 +336,7 @@ void ArmJit::BranchFPFlag(MIPSOpcode op, CCFlags cc, bool likely)
|
||||
u32 targetAddr = GetCompilerPC() + offset + 4;
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceFPU(op, delaySlotOp);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
if (!likely && delaySlotIsNice)
|
||||
@@ -392,6 +395,7 @@ void ArmJit::BranchVFPUFlag(MIPSOpcode op, CCFlags cc, bool likely)
|
||||
u32 targetAddr = GetCompilerPC() + offset + 4;
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
|
||||
// Sometimes there's a VFPU branch in a delay slot (Disgaea 2: Dark Hero Days, Zettai Hero Project, La Pucelle)
|
||||
// The behavior is undefined - the CPU may take the second branch even if the first one passes.
|
||||
@@ -530,6 +534,7 @@ void ArmJit::Comp_JumpReg(MIPSOpcode op)
|
||||
bool andLink = (op & 0x3f) == 9 && rd != MIPS_REG_ZERO;
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);
|
||||
if (andLink && rs == rd)
|
||||
delaySlotIsNice = false;
|
||||
|
||||
@@ -2206,7 +2206,7 @@ namespace MIPSComp
|
||||
u8 dregs[4];
|
||||
u8 dregs2[4];
|
||||
|
||||
u32 nextOp = GetOffsetInstruction(1).encoding;
|
||||
MIPSOpcode nextOp = GetOffsetInstruction(1);
|
||||
int vd2 = -1;
|
||||
int imm2 = -1;
|
||||
if ((nextOp >> 26) == 60 && ((nextOp >> 21) & 0x1F) == 29 && _VS == MIPS_GET_VS(nextOp)) {
|
||||
@@ -2246,7 +2246,7 @@ namespace MIPSComp
|
||||
// If the negsin setting differs between the two joint invocations, we need to flip the second one.
|
||||
bool negSin2 = (imm2 & 0x10) ? true : false;
|
||||
CompVrotShuffle(dregs2, imm2, sz, negSin1 != negSin2);
|
||||
js.compilerPC += 4;
|
||||
EatInstruction(nextOp);
|
||||
}
|
||||
|
||||
fpr.ReleaseSpillLocksAndDiscardTemps();
|
||||
|
||||
@@ -113,6 +113,7 @@ void Arm64Jit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely)
|
||||
}
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rt, rs);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
|
||||
@@ -249,6 +250,7 @@ void Arm64Jit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool li
|
||||
}
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
|
||||
@@ -351,6 +353,7 @@ void Arm64Jit::BranchFPFlag(MIPSOpcode op, CCFlags cc, bool likely) {
|
||||
u32 targetAddr = GetCompilerPC() + offset + 4;
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceFPU(op, delaySlotOp);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
if (!likely && delaySlotIsNice)
|
||||
@@ -408,6 +411,7 @@ void Arm64Jit::BranchVFPUFlag(MIPSOpcode op, CCFlags cc, bool likely) {
|
||||
u32 targetAddr = GetCompilerPC() + offset + 4;
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
|
||||
// Sometimes there's a VFPU branch in a delay slot (Disgaea 2: Dark Hero Days, Zettai Hero Project, La Pucelle)
|
||||
// The behavior is undefined - the CPU may take the second branch even if the first one passes.
|
||||
@@ -545,6 +549,7 @@ void Arm64Jit::Comp_JumpReg(MIPSOpcode op)
|
||||
bool andLink = (op & 0x3f) == 9 && rd != MIPS_REG_ZERO;
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);
|
||||
if (andLink && rs == rd)
|
||||
delaySlotIsNice = false;
|
||||
|
||||
@@ -1922,7 +1922,7 @@ namespace MIPSComp {
|
||||
u8 dregs[4];
|
||||
u8 dregs2[4];
|
||||
|
||||
u32 nextOp = GetOffsetInstruction(1).encoding;
|
||||
MIPSOpcode nextOp = GetOffsetInstruction(1);
|
||||
int vd2 = -1;
|
||||
int imm2 = -1;
|
||||
if ((nextOp >> 26) == 60 && ((nextOp >> 21) & 0x1F) == 29 && _VS == MIPS_GET_VS(nextOp)) {
|
||||
@@ -1958,7 +1958,7 @@ namespace MIPSComp {
|
||||
// If the negsin setting differs between the two joint invocations, we need to flip the second one.
|
||||
bool negSin2 = (imm2 & 0x10) ? true : false;
|
||||
CompVrotShuffle(dregs2, imm2, sz, negSin1 != negSin2);
|
||||
js.compilerPC += 4;
|
||||
EatInstruction(nextOp);
|
||||
}
|
||||
|
||||
fpr.ReleaseSpillLocksAndDiscardTemps();
|
||||
|
||||
@@ -65,6 +65,7 @@ void IRFrontend::BranchRSRTComp(MIPSOpcode op, IRComparison cc, bool likely) {
|
||||
u32 targetAddr = GetCompilerPC() + offset + 4;
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rt, rs);
|
||||
|
||||
// Often, div/divu are followed by a likely "break" if the divisor was zero.
|
||||
@@ -121,6 +122,7 @@ void IRFrontend::BranchRSZeroComp(MIPSOpcode op, IRComparison cc, bool andLink,
|
||||
u32 targetAddr = GetCompilerPC() + offset + 4;
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);
|
||||
|
||||
MIPSGPReg lhs = rs;
|
||||
@@ -241,6 +243,7 @@ void IRFrontend::BranchVFPUFlag(MIPSOpcode op, IRComparison cc, bool likely) {
|
||||
u32 targetAddr = GetCompilerPC() + offset + 4;
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
ir.Write(IROp::VfpuCtrlToReg, IRTEMP_LHS, VFPU_CTRL_CC);
|
||||
|
||||
// Sometimes there's a VFPU branch in a delay slot (Disgaea 2: Dark Hero Days, Zettai Hero Project, La Pucelle)
|
||||
@@ -343,6 +346,7 @@ void IRFrontend::Comp_JumpReg(MIPSOpcode op) {
|
||||
bool andLink = (op & 0x3f) == 9 && rd != MIPS_REG_ZERO;
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);
|
||||
if (andLink && rs == rd)
|
||||
delaySlotIsNice = false;
|
||||
|
||||
@@ -452,7 +452,7 @@ const MIPSInstruction tableCop1S[64] = // 010001 10000 ..... ..... ..... xxxxxx
|
||||
INSTR("add.s", JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, OUT_FD|IN_FS|IN_FT|IS_FPU),
|
||||
INSTR("sub.s", JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, OUT_FD|IN_FS|IN_FT|IS_FPU),
|
||||
INSTR("mul.s", JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, OUT_FD|IN_FS|IN_FT|IS_FPU),
|
||||
INSTR("div.s", JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, OUT_FD|IN_FS|IN_FT|IS_FPU),
|
||||
INSTR("div.s", JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, MIPSInfo(OUT_FD|IN_FS|IN_FT|IS_FPU, 29)),
|
||||
INSTR("sqrt.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
|
||||
INSTR("abs.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
|
||||
INSTR("mov.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),
|
||||
@@ -521,8 +521,8 @@ const MIPSInstruction tableCop1W[64] = // 010001 10100 ..... ..... ..... xxxxxx
|
||||
|
||||
const MIPSInstruction tableVFPU0[8] = // 011000 xxx ....... . ....... . .......
|
||||
{
|
||||
INSTR("vadd", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
|
||||
INSTR("vsub", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
|
||||
INSTR("vadd", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, MIPSInfo(IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX, 2)),
|
||||
INSTR("vsub", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, MIPSInfo(IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX, 2)),
|
||||
// TODO: Disasm is wrong.
|
||||
INSTR("vsbn", JITFUNC(Comp_Generic), Dis_VectorSet3, Int_Vsbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
@@ -991,10 +991,10 @@ int MIPSInterpret_RunUntil(u64 globalTicks)
|
||||
|
||||
bool wasInDelaySlot = curMips->inDelaySlot;
|
||||
MIPSInterpret(op);
|
||||
curMips->downcount -= MIPSGetInstructionCycleEstimate(op);
|
||||
|
||||
if (curMips->inDelaySlot)
|
||||
{
|
||||
curMips->downcount -= 1;
|
||||
// The reason we have to check this is the delay slot hack in Int_Syscall.
|
||||
if (wasInDelaySlot)
|
||||
{
|
||||
@@ -1006,7 +1006,6 @@ int MIPSInterpret_RunUntil(u64 globalTicks)
|
||||
}
|
||||
}
|
||||
|
||||
curMips->downcount -= 1;
|
||||
if (CoreTiming::GetTicks() > globalTicks)
|
||||
{
|
||||
// DEBUG_LOG(CPU, "Hit the max ticks, bailing 1 : %llu, %llu", globalTicks, CoreTiming::GetTicks());
|
||||
@@ -1051,10 +1050,7 @@ MIPSInterpretFunc MIPSGetInterpretFunc(MIPSOpcode op)
|
||||
int MIPSGetInstructionCycleEstimate(MIPSOpcode op)
|
||||
{
|
||||
MIPSInfo info = MIPSGetInfo(op);
|
||||
if (info & DELAYSLOT)
|
||||
return 2;
|
||||
else
|
||||
return 1;
|
||||
return info.cycles;
|
||||
}
|
||||
|
||||
const char *MIPSDisasmAt(u32 compilerPC) {
|
||||
|
||||
+22
-18
@@ -20,21 +20,6 @@
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/MIPS/MIPS.h"
|
||||
|
||||
struct MIPSInfo {
|
||||
MIPSInfo() {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
explicit MIPSInfo(u64 v) : value(v) {
|
||||
}
|
||||
|
||||
u64 operator & (const u64 &arg) const {
|
||||
return value & arg;
|
||||
}
|
||||
|
||||
u64 value;
|
||||
};
|
||||
|
||||
#define CONDTYPE_MASK 0x00000007
|
||||
#define CONDTYPE_EQ 0x00000001
|
||||
#define CONDTYPE_NE 0x00000002
|
||||
@@ -108,6 +93,28 @@ struct MIPSInfo {
|
||||
#define CDECL
|
||||
#endif
|
||||
|
||||
struct MIPSInfo {
|
||||
MIPSInfo() {
|
||||
value = 0;
|
||||
cycles = 0;
|
||||
}
|
||||
|
||||
explicit MIPSInfo(u64 v, u16 c = 0) : value(v), cycles(c) {
|
||||
if (c == 0) {
|
||||
cycles = 1;
|
||||
if (v & IS_VFPU)
|
||||
cycles++;
|
||||
}
|
||||
}
|
||||
|
||||
u64 operator & (const u64 &arg) const {
|
||||
return value & arg;
|
||||
}
|
||||
|
||||
u64 value : 48;
|
||||
u64 cycles : 16;
|
||||
};
|
||||
|
||||
typedef void (CDECL *MIPSDisFunc)(MIPSOpcode opcode, char *out);
|
||||
typedef void (CDECL *MIPSInterpretFunc)(MIPSOpcode opcode);
|
||||
|
||||
@@ -125,6 +132,3 @@ MIPSInterpretFunc MIPSGetInterpretFunc(MIPSOpcode op);
|
||||
int MIPSGetInstructionCycleEstimate(MIPSOpcode op);
|
||||
const char *MIPSGetName(MIPSOpcode op);
|
||||
const char *MIPSDisasmAt(u32 compilerPC);
|
||||
|
||||
void FillMIPSTables();
|
||||
|
||||
@@ -365,6 +365,7 @@ void Jit::BranchRSRTComp(MIPSOpcode op, Gen::CCFlags cc, bool likely)
|
||||
}
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rt, rs);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
|
||||
@@ -446,6 +447,7 @@ void Jit::BranchRSZeroComp(MIPSOpcode op, Gen::CCFlags cc, bool andLink, bool li
|
||||
}
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
|
||||
@@ -517,6 +519,7 @@ void Jit::BranchFPFlag(MIPSOpcode op, Gen::CCFlags cc, bool likely)
|
||||
u32 targetAddr = GetCompilerPC() + offset + 4;
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceFPU(op, delaySlotOp);
|
||||
CONDITIONAL_NICE_DELAYSLOT;
|
||||
if (!likely && delaySlotIsNice)
|
||||
@@ -557,6 +560,7 @@ void Jit::BranchVFPUFlag(MIPSOpcode op, Gen::CCFlags cc, bool likely)
|
||||
u32 targetAddr = GetCompilerPC() + offset + 4;
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
|
||||
// Sometimes there's a VFPU branch in a delay slot (Disgaea 2: Dark Hero Days, Zettai Hero Project, La Pucelle)
|
||||
// The behavior is undefined - the CPU may take the second branch even if the first one passes.
|
||||
@@ -685,6 +689,7 @@ void Jit::Comp_JumpReg(MIPSOpcode op)
|
||||
bool andLink = (op & 0x3f) == 9 && rd != MIPS_REG_ZERO;
|
||||
|
||||
MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(delaySlotOp);
|
||||
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);
|
||||
if (andLink && rs == rd)
|
||||
delaySlotIsNice = false;
|
||||
|
||||
@@ -3540,7 +3540,7 @@ void Jit::Comp_VRot(MIPSOpcode op) {
|
||||
u8 dregs[4];
|
||||
u8 dregs2[4];
|
||||
|
||||
u32 nextOp = GetOffsetInstruction(1).encoding;
|
||||
MIPSOpcode nextOp = GetOffsetInstruction(1);
|
||||
int vd2 = -1;
|
||||
int imm2 = -1;
|
||||
if ((nextOp >> 26) == 60 && ((nextOp >> 21) & 0x1F) == 29 && _VS == MIPS_GET_VS(nextOp)) {
|
||||
@@ -3587,7 +3587,7 @@ void Jit::Comp_VRot(MIPSOpcode op) {
|
||||
// If the negsin setting differs between the two joint invocations, we need to flip the second one.
|
||||
bool negSin2 = (imm2 & 0x10) ? true : false;
|
||||
CompVrotShuffle(dregs2, imm2, n, negSin1 != negSin2);
|
||||
js.compilerPC += 4;
|
||||
EatInstruction(nextOp);
|
||||
}
|
||||
fpr.ReleaseSpillLocks();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user