mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Keep track of VFPU prefixes and flush them in jit.
This commit is contained in:
parent
f6f2927526
commit
ccad259ae5
3 changed files with 68 additions and 25 deletions
|
@ -62,19 +62,17 @@ void Jit::Comp_VPFX(u32 op)
|
|||
switch (regnum) {
|
||||
case 0: // S
|
||||
js.prefixS = data;
|
||||
js.prefixSKnown = true;
|
||||
js.prefixSFlag = JitState::PREFIX_KNOWN_DIRTY;
|
||||
break;
|
||||
case 1: // T
|
||||
js.prefixT = data;
|
||||
js.prefixTKnown = true;
|
||||
js.prefixTFlag = JitState::PREFIX_KNOWN_DIRTY;
|
||||
break;
|
||||
case 2: // D
|
||||
js.prefixD = data;
|
||||
js.prefixDKnown = true;
|
||||
js.prefixDFlag = JitState::PREFIX_KNOWN_DIRTY;
|
||||
break;
|
||||
}
|
||||
// TODO: Defer this to end of block
|
||||
MOV(32, M((void *)&mips_->vfpuCtrl[VFPU_CTRL_SPREFIX + regnum]), Imm32(data));
|
||||
}
|
||||
|
||||
|
||||
|
@ -114,7 +112,7 @@ void Jit::ApplyPrefixST(u8 *vregs, u32 prefix, VectorSize sz) {
|
|||
}
|
||||
|
||||
void Jit::ApplyPrefixD(const u8 *vregs, u32 prefix, VectorSize sz, bool onlyWriteMask) {
|
||||
_assert_(js.prefixDKnown);
|
||||
_assert_(js.prefixDFlag & JitState::PREFIX_KNOWN);
|
||||
if (!prefix) return;
|
||||
|
||||
int n = GetNumVectorElements(sz);
|
||||
|
@ -345,6 +343,8 @@ void Jit::Comp_Mftv(u32 op) {
|
|||
gpr.BindToRegister(rt, false, true);
|
||||
MOV(32, gpr.R(rt), fpr.V(imm));
|
||||
} else if (imm < 128 + VFPU_CTRL_MAX) { //mtvc
|
||||
// In case we have a saved prefix.
|
||||
FlushAll();
|
||||
gpr.BindToRegister(rt, false, true);
|
||||
MOV(32, gpr.R(rt), M(¤tMIPS->vfpuCtrl[imm - 128]));
|
||||
} else {
|
||||
|
@ -366,11 +366,11 @@ void Jit::Comp_Mftv(u32 op) {
|
|||
|
||||
// TODO: Optimization if rt is Imm?
|
||||
if (imm - 128 == VFPU_CTRL_SPREFIX) {
|
||||
js.prefixSKnown = false;
|
||||
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
|
||||
} else if (imm - 128 == VFPU_CTRL_TPREFIX) {
|
||||
js.prefixTKnown = false;
|
||||
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
|
||||
} else if (imm - 128 == VFPU_CTRL_DPREFIX) {
|
||||
js.prefixDKnown = false;
|
||||
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
|
||||
}
|
||||
} else {
|
||||
//ERROR
|
||||
|
@ -393,11 +393,11 @@ void Jit::Comp_Vmtvc(u32 op) {
|
|||
fpr.ReleaseSpillLocks();
|
||||
|
||||
if (imm - 128 == VFPU_CTRL_SPREFIX) {
|
||||
js.prefixSKnown = false;
|
||||
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
|
||||
} else if (imm - 128 == VFPU_CTRL_TPREFIX) {
|
||||
js.prefixTKnown = false;
|
||||
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
|
||||
} else if (imm - 128 == VFPU_CTRL_DPREFIX) {
|
||||
js.prefixDKnown = false;
|
||||
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,6 +109,34 @@ void Jit::FlushAll()
|
|||
{
|
||||
gpr.Flush();
|
||||
fpr.Flush();
|
||||
FlushPrefixV();
|
||||
}
|
||||
|
||||
void Jit::FlushPrefixV()
|
||||
{
|
||||
if ((js.prefixSFlag & JitState::PREFIX_DIRTY) != 0)
|
||||
{
|
||||
MOV(32, M((void *)&mips_->vfpuCtrl[VFPU_CTRL_SPREFIX]), Imm32(js.prefixS));
|
||||
js.prefixSFlag = (JitState::PrefixState) (js.prefixSFlag & ~JitState::PREFIX_DIRTY);
|
||||
}
|
||||
|
||||
if ((js.prefixTFlag & JitState::PREFIX_DIRTY) != 0)
|
||||
{
|
||||
MOV(32, M((void *)&mips_->vfpuCtrl[VFPU_CTRL_TPREFIX]), Imm32(js.prefixT));
|
||||
js.prefixTFlag = (JitState::PrefixState) (js.prefixTFlag & ~JitState::PREFIX_DIRTY);
|
||||
}
|
||||
|
||||
if ((js.prefixDFlag & JitState::PREFIX_DIRTY) != 0)
|
||||
{
|
||||
MOV(32, M((void *)&mips_->vfpuCtrl[VFPU_CTRL_DPREFIX]), Imm32(js.prefixD));
|
||||
|
||||
_dbg_assert_msg_(JIT, sizeof(bool) <= 4, "Bools shouldn't be that big?");
|
||||
const size_t bool_stride = 4 / sizeof(bool);
|
||||
for (size_t i = 0; i < ARRAY_SIZE(mips_->vfpuWriteMask); i += bool_stride)
|
||||
MOV(32, M((void *)&mips_->vfpuWriteMask[i]), Imm32(*(u32 *)&js.writeMask[i]));
|
||||
|
||||
js.prefixDFlag = (JitState::PrefixState) (js.prefixDFlag & ~JitState::PREFIX_DIRTY);
|
||||
}
|
||||
}
|
||||
|
||||
void Jit::WriteDowncount(int offset)
|
||||
|
|
|
@ -48,6 +48,14 @@ struct JitOptions
|
|||
|
||||
struct JitState
|
||||
{
|
||||
enum PrefixState
|
||||
{
|
||||
PREFIX_UNKNOWN = 0x00,
|
||||
PREFIX_KNOWN = 0x01,
|
||||
PREFIX_DIRTY = 0x10,
|
||||
PREFIX_KNOWN_DIRTY = 0x11,
|
||||
};
|
||||
|
||||
u32 compilerPC;
|
||||
u32 blockStart;
|
||||
bool cancel;
|
||||
|
@ -62,22 +70,28 @@ struct JitState
|
|||
u32 prefixT;
|
||||
u32 prefixD;
|
||||
bool writeMask[4];
|
||||
bool prefixSKnown;
|
||||
bool prefixTKnown;
|
||||
bool prefixDKnown;
|
||||
PrefixState prefixSFlag;
|
||||
PrefixState prefixTFlag;
|
||||
PrefixState prefixDFlag;
|
||||
void PrefixStart() {
|
||||
prefixSKnown = false;
|
||||
prefixTKnown = false;
|
||||
prefixDKnown = false;
|
||||
prefixSFlag = PREFIX_UNKNOWN;
|
||||
prefixTFlag = PREFIX_UNKNOWN;
|
||||
prefixDFlag = PREFIX_UNKNOWN;
|
||||
}
|
||||
void EatPrefix() {
|
||||
prefixSKnown = true;
|
||||
prefixTKnown = true;
|
||||
prefixDKnown = true;
|
||||
prefixS = 0xE4;
|
||||
prefixT = 0xE4;
|
||||
prefixD = 0x0;
|
||||
writeMask[0] = writeMask[1] = writeMask[2] = writeMask[3] = false;
|
||||
if ((prefixSFlag & PREFIX_KNOWN) == 0 || prefixS != 0xE4) {
|
||||
prefixSFlag = PREFIX_KNOWN_DIRTY;
|
||||
prefixS = 0xE4;
|
||||
}
|
||||
if ((prefixTFlag & PREFIX_KNOWN) == 0 || prefixT != 0xE4) {
|
||||
prefixTFlag = PREFIX_KNOWN_DIRTY;
|
||||
prefixT = 0xE4;
|
||||
}
|
||||
if ((prefixDFlag & PREFIX_KNOWN) == 0 || prefixD != 0x0 || writeMask[0] || writeMask[1] || writeMask[2] || writeMask[3]) {
|
||||
prefixDFlag = PREFIX_KNOWN_DIRTY;
|
||||
prefixD = 0x0;
|
||||
writeMask[0] = writeMask[1] = writeMask[2] = writeMask[3] = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -155,6 +169,7 @@ public:
|
|||
void ClearCacheAt(u32 em_address);
|
||||
private:
|
||||
void FlushAll();
|
||||
void FlushPrefixV();
|
||||
void WriteDowncount(int offset = 0);
|
||||
|
||||
// See CompileDelaySlotFlags for flags.
|
||||
|
|
Loading…
Add table
Reference in a new issue