mirror of
https://github.com/libretro/ppsspp.git
synced 2024-12-13 11:38:34 +00:00
Preserve orig regs when applying vfpu prefixes.
This commit is contained in:
parent
d63548799b
commit
08a42a1aaf
@ -75,9 +75,6 @@ void Jit::Comp_VPFX(u32 op)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: Got register value ownership issues. We need to be sure that if we modify input
|
||||
// like this, it does NOT get written back!
|
||||
void Jit::ApplyPrefixST(u8 *vregs, u32 prefix, VectorSize sz) {
|
||||
if (prefix == 0xE4) return;
|
||||
|
||||
@ -86,10 +83,7 @@ void Jit::ApplyPrefixST(u8 *vregs, u32 prefix, VectorSize sz) {
|
||||
static const float constantArray[8] = {0.f, 1.f, 2.f, 0.5f, 3.f, 1.f/3.f, 0.25f, 1.f/6.f};
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
// TODO: This needs to be the original values, not the original regs. (e.g. [-x, |x|, x])
|
||||
origV[i] = vregs[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
@ -98,22 +92,33 @@ void Jit::ApplyPrefixST(u8 *vregs, u32 prefix, VectorSize sz) {
|
||||
int negate = (prefix >> (16+i)) & 1;
|
||||
int constants = (prefix >> (12+i)) & 1;
|
||||
|
||||
// Unchanged, hurray.
|
||||
if (!constants && regnum == i && !abs && !negate)
|
||||
continue;
|
||||
|
||||
// This puts the value into a temp reg, so we won't write the modified value back.
|
||||
vregs[i] = fpr.GetTempV();
|
||||
fpr.MapRegV(vregs[i], MAP_NOINIT | MAP_DIRTY);
|
||||
|
||||
if (!constants) {
|
||||
// Prefix may say "z, z, z, z" but if this is a pair, we force to x.
|
||||
// TODO: But some ops seem to use const 0 instead?
|
||||
if (regnum > n) {
|
||||
regnum = 0;
|
||||
}
|
||||
vregs[i] = origV[regnum];
|
||||
MOVSS(fpr.VX(vregs[i]), fpr.V(origV[regnum]));
|
||||
if (abs) {
|
||||
ANDPS(fpr.VX(vregs[i]), M((void *)&noSignMask));
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
MOVSS(fpr.VX(vregs[i]), M((void *)&constantArray[regnum + (abs<<2)]));
|
||||
}
|
||||
|
||||
if (negate)
|
||||
XORPS(fpr.VX(vregs[i]), M((void *)&signBitLower));
|
||||
|
||||
// TODO: This probably means it will swap out soon, inefficiently...
|
||||
fpr.ReleaseSpillLockV(vregs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ struct JitState
|
||||
prefixDFlag = PREFIX_UNKNOWN;
|
||||
}
|
||||
bool MayHavePrefix() const {
|
||||
if (!(prefixSFlag & PREFIX_KNOWN) || !(prefixTFlag & PREFIX_KNOWN) || !(prefixDFlag & PREFIX_KNOWN)) {
|
||||
if (HasUnknownPrefix()) {
|
||||
return true;
|
||||
} else if (prefixS != 0xE4 || prefixT != 0xE4 || prefixD != 0) {
|
||||
return true;
|
||||
@ -89,6 +89,12 @@ struct JitState
|
||||
|
||||
return false;
|
||||
}
|
||||
bool HasUnknownPrefix() const {
|
||||
if (!(prefixSFlag & PREFIX_KNOWN) || !(prefixTFlag & PREFIX_KNOWN) || !(prefixDFlag & PREFIX_KNOWN)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void EatPrefix() {
|
||||
if ((prefixSFlag & PREFIX_KNOWN) == 0 || prefixS != 0xE4) {
|
||||
prefixSFlag = PREFIX_KNOWN_DIRTY;
|
||||
|
@ -148,10 +148,21 @@ void FPURegCache::DiscardR(int i) {
|
||||
}
|
||||
}
|
||||
|
||||
bool FPURegCache::IsTemp(X64Reg xr) {
|
||||
bool FPURegCache::IsTempX(X64Reg xr) {
|
||||
return xregs[xr].mipsReg >= TEMP0;
|
||||
}
|
||||
|
||||
int FPURegCache::GetTempR() {
|
||||
for (int r = TEMP0; r < TEMP0 + NUM_TEMPS; ++r) {
|
||||
if (!regs[r].away) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
_assert_msg_(DYNA_REC, 0, "Regcache ran out of temp regs, might need to DiscardR() some.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void FPURegCache::Flush() {
|
||||
for (int i = 0; i < NUM_MIPS_FPRS; i++) {
|
||||
if (regs[i].locked) {
|
||||
|
@ -88,7 +88,11 @@ public:
|
||||
void DiscardV(int vreg) {
|
||||
DiscardR(vreg + 32);
|
||||
}
|
||||
bool IsTemp(X64Reg xreg);
|
||||
bool IsTempX(X64Reg xreg);
|
||||
int GetTempR();
|
||||
int GetTempV() {
|
||||
return GetTempR() - 32;
|
||||
}
|
||||
|
||||
void SetEmitter(XEmitter *emitter) {emit = emitter;}
|
||||
|
||||
@ -127,6 +131,9 @@ public:
|
||||
}
|
||||
void SpillLockV(const u8 *v, VectorSize vsz);
|
||||
void SpillLockV(int vec, VectorSize vsz);
|
||||
void ReleaseSpillLockV(int vreg) {
|
||||
ReleaseSpillLock(vreg + 32);
|
||||
}
|
||||
|
||||
MIPSState *mips;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user