diff --git a/Core/MIPS/ARM/ArmCompVFPU.cpp b/Core/MIPS/ARM/ArmCompVFPU.cpp index b0ba0001b0..d602a1ec15 100644 --- a/Core/MIPS/ARM/ArmCompVFPU.cpp +++ b/Core/MIPS/ARM/ArmCompVFPU.cpp @@ -1558,7 +1558,7 @@ namespace MIPSComp fpr.MapRegsAndSpillLockV(tregs, sz, 0); if (sz == V_Triple) { - int temp3 = fpr.GetTempV(); + MIPSReg temp3 = fpr.GetTempV(); fpr.MapRegV(temp3, MAP_DIRTY | MAP_NOINIT); // Cross product vcrsp.t @@ -1574,13 +1574,46 @@ namespace MIPSComp VMUL(fpr.V(temp3), fpr.V(sregs[0]), fpr.V(tregs[1])); VMLS(fpr.V(temp3), fpr.V(sregs[1]), fpr.V(tregs[0])); - fpr.MapRegsAndSpillLockV(dregs, V_Triple, MAP_DIRTY | MAP_NOINIT); + fpr.MapRegsAndSpillLockV(dregs, sz, MAP_DIRTY | MAP_NOINIT); VMOV(fpr.V(dregs[0]), S0); VMOV(fpr.V(dregs[1]), S1); VMOV(fpr.V(dregs[2]), fpr.V(temp3)); } else if (sz == V_Quad) { + MIPSReg temp3 = fpr.GetTempV(); + MIPSReg temp4 = fpr.GetTempV(); + fpr.MapRegV(temp3, MAP_DIRTY | MAP_NOINIT); + fpr.MapRegV(temp4, MAP_DIRTY | MAP_NOINIT); + // Quaternion product vqmul.q untested - DISABLE; + // d[0] = s[0] * t[3] + s[1] * t[2] - s[2] * t[1] + s[3] * t[0]; + VMUL(S0, fpr.V(sregs[0]), fpr.V(tregs[3])); + VMLA(S0, fpr.V(sregs[1]), fpr.V(tregs[2])); + VMLS(S0, fpr.V(sregs[2]), fpr.V(tregs[1])); + VMLA(S0, fpr.V(sregs[3]), fpr.V(tregs[0])); + + //d[1] = -s[0] * t[2] + s[1] * t[3] + s[2] * t[0] + s[3] * t[1]; + VNMUL(S1, fpr.V(sregs[0]), fpr.V(tregs[2])); + VMLA(S1, fpr.V(sregs[1]), fpr.V(tregs[3])); + VMLA(S1, fpr.V(sregs[2]), fpr.V(tregs[0])); + VMLA(S1, fpr.V(sregs[3]), fpr.V(tregs[1])); + + //d[2] = s[0] * t[1] - s[1] * t[0] + s[2] * t[3] + s[3] * t[2]; + VMUL(fpr.V(temp3), fpr.V(sregs[0]), fpr.V(tregs[1])); + VMLS(fpr.V(temp3), fpr.V(sregs[1]), fpr.V(tregs[0])); + VMLA(fpr.V(temp3), fpr.V(sregs[2]), fpr.V(tregs[3])); + VMLA(fpr.V(temp3), fpr.V(sregs[3]), fpr.V(tregs[2])); + + //d[3] = -s[0] * t[0] - s[1] * t[1] - s[2] * t[2] + s[3] * t[3]; + VNMUL(fpr.V(temp4), fpr.V(sregs[0]), fpr.V(tregs[0])); + VMLS(fpr.V(temp4), fpr.V(sregs[1]), fpr.V(tregs[1])); + VMLS(fpr.V(temp4), fpr.V(sregs[2]), fpr.V(tregs[2])); + VMLA(fpr.V(temp4), fpr.V(sregs[3]), fpr.V(tregs[3])); + + fpr.MapRegsAndSpillLockV(dregs, sz, MAP_DIRTY | MAP_NOINIT); + VMOV(fpr.V(dregs[0]), S0); + VMOV(fpr.V(dregs[1]), S1); + VMOV(fpr.V(dregs[2]), fpr.V(temp3)); + VMOV(fpr.V(dregs[3]), fpr.V(temp4)); } fpr.ReleaseSpillLocksAndDiscardTemps();