mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-10 19:12:12 +00:00
Implement vasin (fastasin5 from unittest) in ARM jit, add a sanity check.
This commit is contained in:
parent
7edfa284d9
commit
f696650437
@ -782,6 +782,20 @@ namespace MIPSComp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get some extra temps, used by vasin only.
|
||||||
|
ARMReg t2 = INVALID_REG, t3 = INVALID_REG, t4 = INVALID_REG;
|
||||||
|
if (((op >> 16) & 0x1f) == 23) {
|
||||||
|
int t[3] = { fpr.GetTempV(), fpr.GetTempV(), fpr.GetTempV() };
|
||||||
|
fpr.MapRegV(t[0], MAP_NOINIT);
|
||||||
|
fpr.MapRegV(t[1], MAP_NOINIT);
|
||||||
|
fpr.MapRegV(t[2], MAP_NOINIT);
|
||||||
|
t2 = fpr.V(t[0]);
|
||||||
|
t3 = fpr.V(t[1]);
|
||||||
|
t4 = fpr.V(t[2]);
|
||||||
|
INFO_LOG(JIT, "t2 %i t3 %i t4 %i", t2, t3, t4);
|
||||||
|
logBlocks = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Warning: sregs[i] and tempxregs[i] may be the same reg.
|
// Warning: sregs[i] and tempxregs[i] may be the same reg.
|
||||||
// Helps for vmov, hurts for vrcp, etc.
|
// Helps for vmov, hurts for vrcp, etc.
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
@ -849,7 +863,35 @@ namespace MIPSComp
|
|||||||
VABS(fpr.V(tempregs[i]), fpr.V(tempregs[i]));
|
VABS(fpr.V(tempregs[i]), fpr.V(tempregs[i]));
|
||||||
break;
|
break;
|
||||||
case 23: // d[i] = asinf(s[i] * (float)M_2_PI); break; //vasin
|
case 23: // d[i] = asinf(s[i] * (float)M_2_PI); break; //vasin
|
||||||
DISABLE;
|
// DISABLE;
|
||||||
|
// Seems to work well enough but can disable if it becomes a problem.
|
||||||
|
// Should be easy enough to translate to NEON. There we can load all the constants
|
||||||
|
// in one go of course.
|
||||||
|
fpr.MapDirtyInV(tempregs[i], sregs[i]);
|
||||||
|
MOVI2F(S0, 0.0f, R0);
|
||||||
|
VCMP(fpr.V(sregs[i]), S0); // flags = sign(sregs[i])
|
||||||
|
VMRS_APSR();
|
||||||
|
MOVI2F(S0, 1.0f, R0);
|
||||||
|
VABS(t4, fpr.V(sregs[i])); // t4 = |sregs[i]|
|
||||||
|
VSUB(t3, S0, t4);
|
||||||
|
VSQRT(t3, t3); // t3 = sqrt(1 - |sregs[i]|)
|
||||||
|
MOVI2F(S1, -0.0187293f, R0);
|
||||||
|
MOVI2F(t2, 0.0742610f, R0);
|
||||||
|
VMLA(t2, t4, S1);
|
||||||
|
MOVI2F(S1, -0.2121144f, R0);
|
||||||
|
VMLA(S1, t4, t2);
|
||||||
|
MOVI2F(t2, 1.5707288f, R0);
|
||||||
|
VMLA(t2, t4, S1);
|
||||||
|
MOVI2F(fpr.V(tempregs[i]), M_PI / 2, R0);
|
||||||
|
VMLS(fpr.V(tempregs[i]), t2, t3); // tr[i] = M_PI / 2 - t2 * t3
|
||||||
|
{
|
||||||
|
FixupBranch br = B_CC(CC_GE);
|
||||||
|
VNEG(fpr.V(tempregs[i]), fpr.V(tempregs[i]));
|
||||||
|
SetJumpTarget(br);
|
||||||
|
}
|
||||||
|
// Correction factor for PSP range. Could be baked into the calculation above?
|
||||||
|
MOVI2F(S1, 1.0f / (M_PI / 2), R0);
|
||||||
|
VMUL(fpr.V(tempregs[i]), fpr.V(tempregs[i]), S1);
|
||||||
break;
|
break;
|
||||||
case 24: // d[i] = -1.0f / s[i]; break; // vnrcp
|
case 24: // d[i] = -1.0f / s[i]; break; // vnrcp
|
||||||
fpr.MapDirtyInV(tempregs[i], sregs[i]);
|
fpr.MapDirtyInV(tempregs[i], sregs[i]);
|
||||||
|
@ -223,6 +223,11 @@ int JitBlockCache::GetBlockNumberFromEmuHackOp(MIPSOpcode inst) const {
|
|||||||
int off = (inst & MIPS_EMUHACK_VALUE_MASK);
|
int off = (inst & MIPS_EMUHACK_VALUE_MASK);
|
||||||
|
|
||||||
const u8 *baseoff = codeBlock_->GetBasePtr() + off;
|
const u8 *baseoff = codeBlock_->GetBasePtr() + off;
|
||||||
|
if (baseoff < codeBlock_->GetBasePtr() || baseoff >= codeBlock_->GetCodePtr()) {
|
||||||
|
ERROR_LOG(JIT, "JitBlockCache: Invalid Emuhack Op %08x", inst.encoding);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int bl = binary_search(blocks, baseoff, 0, num_blocks-1);
|
int bl = binary_search(blocks, baseoff, 0, num_blocks-1);
|
||||||
if (blocks[bl].invalid)
|
if (blocks[bl].invalid)
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user