mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 21:39:52 +00:00
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:
parent
a5a2af4892
commit
74e5e43fdc
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -77,6 +77,7 @@ namespace MIPSComp {
|
||||
|
||||
// VFPU prefix magic
|
||||
bool startDefaultPrefix = true;
|
||||
bool blockWrotePrefixes = false;
|
||||
u32 prefixS;
|
||||
u32 prefixT;
|
||||
u32 prefixD;
|
||||
|
@ -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,
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user