jit: Skip known prefix writes.

If we already know what's in memory and it's default, we can skip
overwriting with default values.  This is common, actually.
This commit is contained in:
Unknown W. Brackets 2023-08-22 21:45:49 -07:00
parent a5a2af4892
commit 74e5e43fdc
12 changed files with 106 additions and 8 deletions

View File

@ -1310,10 +1310,13 @@ namespace MIPSComp
// Set these BEFORE disable!
if (imm - 128 == VFPU_CTRL_SPREFIX) {
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm - 128 == VFPU_CTRL_TPREFIX) {
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm - 128 == VFPU_CTRL_DPREFIX) {
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
}
} else {
//ERROR
@ -1369,10 +1372,13 @@ namespace MIPSComp
if (imm == VFPU_CTRL_SPREFIX) {
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm == VFPU_CTRL_TPREFIX) {
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm == VFPU_CTRL_DPREFIX) {
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
}
}
}

View File

@ -722,10 +722,13 @@ void ArmJit::CompNEON_Mftv(MIPSOpcode op) {
// Set these BEFORE disable!
if (imm - 128 == VFPU_CTRL_SPREFIX) {
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm - 128 == VFPU_CTRL_TPREFIX) {
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm - 128 == VFPU_CTRL_DPREFIX) {
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
}
} else {
//ERROR
@ -757,10 +760,13 @@ void ArmJit::CompNEON_Vmtvc(MIPSOpcode op) {
if (imm - 128 == VFPU_CTRL_SPREFIX) {
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm - 128 == VFPU_CTRL_TPREFIX) {
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm - 128 == VFPU_CTRL_DPREFIX) {
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
}
}
}

View File

@ -160,8 +160,16 @@ void ArmJit::FlushAll()
FlushPrefixV();
}
void ArmJit::FlushPrefixV()
{
void ArmJit::FlushPrefixV() {
if (js.startDefaultPrefix && !js.blockWrotePrefixes && js.HasNoPrefix()) {
// They started default, we never modified in memory, and they're default now.
// No reason to modify memory. This is common at end of blocks. Just clear dirty.
js.prefixSFlag = (JitState::PrefixState)(js.prefixSFlag & ~JitState::PREFIX_DIRTY);
js.prefixTFlag = (JitState::PrefixState)(js.prefixTFlag & ~JitState::PREFIX_DIRTY);
js.prefixDFlag = (JitState::PrefixState)(js.prefixDFlag & ~JitState::PREFIX_DIRTY);
return;
}
if ((js.prefixSFlag & JitState::PREFIX_DIRTY) != 0) {
gpr.SetRegImm(SCRATCHREG1, js.prefixS);
STR(SCRATCHREG1, CTXREG, offsetof(MIPSState, vfpuCtrl[VFPU_CTRL_SPREFIX]));
@ -179,6 +187,9 @@ void ArmJit::FlushPrefixV()
STR(SCRATCHREG1, CTXREG, offsetof(MIPSState, vfpuCtrl[VFPU_CTRL_DPREFIX]));
js.prefixDFlag = (JitState::PrefixState) (js.prefixDFlag & ~JitState::PREFIX_DIRTY);
}
// If we got here, we must've written prefixes to memory in this block.
js.blockWrotePrefixes = true;
}
void ArmJit::ClearCache()
@ -298,6 +309,7 @@ const u8 *ArmJit::DoJit(u32 em_address, JitBlock *b)
js.curBlock = b;
js.compiling = true;
js.inDelaySlot = false;
js.blockWrotePrefixes = false;
js.PrefixStart();
// We add a downcount flag check before the block, used when entering from a linked block.
@ -636,6 +648,10 @@ void ArmJit::Comp_Generic(MIPSOpcode op)
// If it does eat them, it'll happen in MIPSCompileOp().
if ((info & OUT_EAT_PREFIX) == 0)
js.PrefixUnknown();
// Even if DISABLE'd, we want to set this flag so we overwrite.
if ((info & OUT_VFPU_PREFIX) != 0)
js.blockWrotePrefixes = true;
}
}

View File

@ -1062,10 +1062,13 @@ namespace MIPSComp {
// Set these BEFORE disable!
if (imm - 128 == VFPU_CTRL_SPREFIX) {
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm - 128 == VFPU_CTRL_TPREFIX) {
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm - 128 == VFPU_CTRL_DPREFIX) {
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
}
} else {
//ERROR
@ -1119,10 +1122,13 @@ namespace MIPSComp {
if (imm == VFPU_CTRL_SPREFIX) {
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm == VFPU_CTRL_TPREFIX) {
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm == VFPU_CTRL_DPREFIX) {
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
}
}
}

View File

@ -159,6 +159,15 @@ void Arm64Jit::FlushAll() {
}
void Arm64Jit::FlushPrefixV() {
if (js.startDefaultPrefix && !js.blockWrotePrefixes && js.HasNoPrefix()) {
// They started default, we never modified in memory, and they're default now.
// No reason to modify memory. This is common at end of blocks. Just clear dirty.
js.prefixSFlag = (JitState::PrefixState)(js.prefixSFlag & ~JitState::PREFIX_DIRTY);
js.prefixTFlag = (JitState::PrefixState)(js.prefixTFlag & ~JitState::PREFIX_DIRTY);
js.prefixDFlag = (JitState::PrefixState)(js.prefixDFlag & ~JitState::PREFIX_DIRTY);
return;
}
if ((js.prefixSFlag & JitState::PREFIX_DIRTY) != 0) {
gpr.SetRegImm(SCRATCH1, js.prefixS);
STR(INDEX_UNSIGNED, SCRATCH1, CTXREG, offsetof(MIPSState, vfpuCtrl[VFPU_CTRL_SPREFIX]));
@ -176,6 +185,9 @@ void Arm64Jit::FlushPrefixV() {
STR(INDEX_UNSIGNED, SCRATCH1, CTXREG, offsetof(MIPSState, vfpuCtrl[VFPU_CTRL_DPREFIX]));
js.prefixDFlag = (JitState::PrefixState) (js.prefixDFlag & ~JitState::PREFIX_DIRTY);
}
// If we got here, we must've written prefixes to memory in this block.
js.blockWrotePrefixes = true;
}
void Arm64Jit::ClearCache() {
@ -298,6 +310,7 @@ const u8 *Arm64Jit::DoJit(u32 em_address, JitBlock *b) {
js.curBlock = b;
js.compiling = true;
js.inDelaySlot = false;
js.blockWrotePrefixes = false;
js.PrefixStart();
// We add a downcount flag check before the block, used when entering from a linked block.
@ -629,6 +642,10 @@ void Arm64Jit::Comp_Generic(MIPSOpcode op) {
// If it does eat them, it'll happen in MIPSCompileOp().
if ((info & OUT_EAT_PREFIX) == 0)
js.PrefixUnknown();
// Even if DISABLE'd, we want to set this flag so we overwrite.
if ((info & OUT_VFPU_PREFIX) != 0)
js.blockWrotePrefixes = true;
}
}

View File

@ -1264,10 +1264,13 @@ namespace MIPSComp {
if (imm - 128 == VFPU_CTRL_SPREFIX) {
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm - 128 == VFPU_CTRL_TPREFIX) {
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm - 128 == VFPU_CTRL_DPREFIX) {
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
}
} else {
INVALIDOP;
@ -1316,10 +1319,13 @@ namespace MIPSComp {
}
if (imm == VFPU_CTRL_SPREFIX) {
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm == VFPU_CTRL_TPREFIX) {
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm == VFPU_CTRL_DPREFIX) {
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
}
} else {
INVALIDOP;

View File

@ -64,6 +64,15 @@ void IRFrontend::FlushAll() {
}
void IRFrontend::FlushPrefixV() {
if (js.startDefaultPrefix && !js.blockWrotePrefixes && js.HasNoPrefix()) {
// They started default, we never modified in memory, and they're default now.
// No reason to modify memory. This is common at end of blocks. Just clear dirty.
js.prefixSFlag = (JitState::PrefixState)(js.prefixSFlag & ~JitState::PREFIX_DIRTY);
js.prefixTFlag = (JitState::PrefixState)(js.prefixTFlag & ~JitState::PREFIX_DIRTY);
js.prefixDFlag = (JitState::PrefixState)(js.prefixDFlag & ~JitState::PREFIX_DIRTY);
return;
}
if ((js.prefixSFlag & JitState::PREFIX_DIRTY) != 0) {
ir.Write(IROp::SetCtrlVFPU, VFPU_CTRL_SPREFIX, ir.AddConstant(js.prefixS));
js.prefixSFlag = (JitState::PrefixState) (js.prefixSFlag & ~JitState::PREFIX_DIRTY);
@ -78,6 +87,9 @@ void IRFrontend::FlushPrefixV() {
ir.Write(IROp::SetCtrlVFPU, VFPU_CTRL_DPREFIX, ir.AddConstant(js.prefixD));
js.prefixDFlag = (JitState::PrefixState) (js.prefixDFlag & ~JitState::PREFIX_DIRTY);
}
// If we got here, we must've written prefixes to memory in this block.
js.blockWrotePrefixes = true;
}
void IRFrontend::EatInstruction(MIPSOpcode op) {
@ -120,8 +132,7 @@ bool IRFrontend::CheckRounding(u32 blockAddress) {
// Let's try that one more time. We won't get back here because we toggled the value.
js.startDefaultPrefix = false;
// TODO: Make sure this works.
// cleanSlate = true;
cleanSlate = true;
}
return cleanSlate;
@ -179,6 +190,10 @@ void IRFrontend::Comp_Generic(MIPSOpcode op) {
// If it does eat them, it'll happen in MIPSCompileOp().
if ((info & OUT_EAT_PREFIX) == 0)
js.PrefixUnknown();
// Even if DISABLE'd, we want to set this flag so we overwrite.
if ((info & OUT_VFPU_PREFIX) != 0)
js.blockWrotePrefixes = true;
}
}
@ -233,6 +248,7 @@ void IRFrontend::DoJit(u32 em_address, std::vector<IRInst> &instructions, u32 &m
js.curBlock = nullptr;
js.compiling = true;
js.hadBreakpoints = false;
js.blockWrotePrefixes = false;
js.inDelaySlot = false;
js.PrefixStart();
ir.Clear();

View File

@ -77,6 +77,7 @@ namespace MIPSComp {
// VFPU prefix magic
bool startDefaultPrefix = true;
bool blockWrotePrefixes = false;
u32 prefixS;
u32 prefixT;
u32 prefixD;

View File

@ -340,7 +340,7 @@ static const MIPSInstruction tableCop2[32] = // 010010 xxxxx ..... .............
INSTR("mtc2", JITFUNC(Comp_Generic), Dis_Generic, 0, IN_RT),
INVALID,
INSTR("ctc2", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
INSTR("mtv", JITFUNC(Comp_Mftv), Dis_Mftv, Int_Mftv, IN_RT|OUT_VFPU_CC|OUT_OTHER|IS_VFPU),
INSTR("mtv", JITFUNC(Comp_Mftv), Dis_Mftv, Int_Mftv, IN_RT|OUT_VFPU_CC|OUT_OTHER|IS_VFPU|OUT_VFPU_PREFIX),
//8
ENCODING(Cop2BC2),
INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),
@ -749,7 +749,7 @@ static const MIPSInstruction tableVFPU9[32] = // 110100 00010 xxxxx . ....... .
//16
INSTR("vmfvc", JITFUNC(Comp_Vmfvc), Dis_Vmfvc, Int_Vmfvc, IN_OTHER|IN_VFPU_CC|OUT_OTHER|IS_VFPU),
INSTR("vmtvc", JITFUNC(Comp_Vmtvc), Dis_Vmtvc, Int_Vmtvc, IN_OTHER|OUT_VFPU_CC|OUT_OTHER|IS_VFPU),
INSTR("vmtvc", JITFUNC(Comp_Vmtvc), Dis_Vmtvc, Int_Vmtvc, IN_OTHER|OUT_VFPU_CC|OUT_OTHER|IS_VFPU|OUT_VFPU_PREFIX),
INVALID,
INVALID,

View File

@ -71,8 +71,9 @@
#define OUT_EAT_PREFIX 0x08000000ULL
#define VFPU_NO_PREFIX 0x10000000ULL
#define IS_VFPU 0x20000000ULL
#define IS_FPU 0x40000000ULL
#define OUT_VFPU_PREFIX 0x20000000ULL
#define IS_VFPU 0x40000000ULL
#define IS_FPU 0x80000000ULL
#define IN_FS 0x000100000000ULL
#define IN_FT 0x000200000000ULL

View File

@ -2544,10 +2544,13 @@ void Jit::Comp_Mftv(MIPSOpcode op) {
// TODO: Optimization if rt is Imm?
if (imm - 128 == VFPU_CTRL_SPREFIX) {
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm - 128 == VFPU_CTRL_TPREFIX) {
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm - 128 == VFPU_CTRL_DPREFIX) {
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
}
} else {
//ERROR
@ -2596,10 +2599,13 @@ void Jit::Comp_Vmtvc(MIPSOpcode op) {
if (imm == VFPU_CTRL_SPREFIX) {
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm == VFPU_CTRL_TPREFIX) {
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
} else if (imm == VFPU_CTRL_DPREFIX) {
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
js.blockWrotePrefixes = true;
}
}
}

View File

@ -182,6 +182,15 @@ void Jit::FlushAll() {
}
void Jit::FlushPrefixV() {
if (js.startDefaultPrefix && !js.blockWrotePrefixes && js.HasNoPrefix()) {
// They started default, we never modified in memory, and they're default now.
// No reason to modify memory. This is common at end of blocks. Just clear dirty.
js.prefixSFlag = (JitState::PrefixState)(js.prefixSFlag & ~JitState::PREFIX_DIRTY);
js.prefixTFlag = (JitState::PrefixState)(js.prefixTFlag & ~JitState::PREFIX_DIRTY);
js.prefixDFlag = (JitState::PrefixState)(js.prefixDFlag & ~JitState::PREFIX_DIRTY);
return;
}
if ((js.prefixSFlag & JitState::PREFIX_DIRTY) != 0) {
MOV(32, MIPSSTATE_VAR(vfpuCtrl[VFPU_CTRL_SPREFIX]), Imm32(js.prefixS));
js.prefixSFlag = (JitState::PrefixState) (js.prefixSFlag & ~JitState::PREFIX_DIRTY);
@ -196,6 +205,9 @@ void Jit::FlushPrefixV() {
MOV(32, MIPSSTATE_VAR(vfpuCtrl[VFPU_CTRL_DPREFIX]), Imm32(js.prefixD));
js.prefixDFlag = (JitState::PrefixState) (js.prefixDFlag & ~JitState::PREFIX_DIRTY);
}
// If we got here, we must've written prefixes to memory in this block.
js.blockWrotePrefixes = true;
}
void Jit::WriteDowncount(int offset) {
@ -356,6 +368,7 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b) {
js.curBlock = b;
js.compiling = true;
js.inDelaySlot = false;
js.blockWrotePrefixes = false;
js.afterOp = JitState::AFTER_NONE;
js.PrefixStart();
@ -681,6 +694,10 @@ void Jit::Comp_Generic(MIPSOpcode op) {
// If it does eat them, it'll happen in MIPSCompileOp().
if ((info & OUT_EAT_PREFIX) == 0)
js.PrefixUnknown();
// Even if DISABLE'd, we want to set this flag so we overwrite.
if ((info & OUT_VFPU_PREFIX) != 0)
js.blockWrotePrefixes = true;
}
}