diff --git a/Common/ArmEmitter.cpp b/Common/ArmEmitter.cpp index 3b0c02cf26..1da5f05b60 100644 --- a/Common/ArmEmitter.cpp +++ b/Common/ArmEmitter.cpp @@ -895,22 +895,47 @@ void ARMXEmitter::VMUL(ARMReg Vd, ARMReg Vn, ARMReg Vm) } else { - _assert_msg_(DYNA_REC, cpu_info.bNEON, "Trying to use VADD with Quad Reg without support!"); - //Write32((0xF2 << 24) | ((Vd & 0x10) << 18) | ((Vn & 0xF) << 16) - // | ((Vd & 0xF) << 12) | (0xD << 8) | ((Vn & 0x10) << 3) - // | (1 << 6) | ((Vm & 0x10) << 2) | (Vm & 0xF)); + _assert_msg_(DYNA_REC, cpu_info.bNEON, "Trying to use VMUL with Quad Reg without support!"); } } } -void ARMXEmitter::VABS(ARMReg Vd, ARMReg Vn) +void ARMXEmitter::VABS(ARMReg Vd, ARMReg Vm) { - _assert_msg_(DYNA_REC, 0, "VABS not implemented"); + bool single_reg = Vd < D0; + + Vd = SubBase(Vd); + Vm = SubBase(Vm); + + if (single_reg) + { + Write32(NO_COND | (0x1D << 23) | ((Vd & 0x1) << 22) | (0x30 << 16) \ + | ((Vd & 0x1E) << 11) | (0x2B << 6) | ((Vm & 0x1) << 5) | (Vm >> 1)); + } + else + { + Write32(NO_COND | (0x1D << 23) | ((Vd & 0x10) << 18) | (0x30 << 16) \ + | ((Vd & 0xF) << 12) | (0x2F << 6) | ((Vm & 0x10) << 2) | (Vm & 0xF)); + } } -void ARMXEmitter::VNEG(ARMReg Vd, ARMReg Vn) +void ARMXEmitter::VNEG(ARMReg Vd, ARMReg Vm) { - _assert_msg_(DYNA_REC, 0, "VNEG not implemented"); + bool single_reg = Vd < D0; + + Vd = SubBase(Vd); + Vm = SubBase(Vm); + + if (single_reg) + { + Write32(NO_COND | (0x1D << 23) | ((Vd & 0x1) << 22) | (0x31 << 16) \ + | ((Vd & 0x1E) << 11) | (0x29 << 6) | ((Vm & 0x1) << 5) | (Vm >> 1)); + } + else + { + Write32(NO_COND | (0x1D << 23) | ((Vd & 0x10) << 18) | (0x31 << 16) \ + | ((Vd & 0xF) << 12) | (0x2D << 6) | ((Vm & 0x10) << 2) | (Vm & 0xF)); + } } void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src, bool high) diff --git a/Common/ArmEmitter.h b/Common/ArmEmitter.h index a9319c8dd6..8813680f09 100644 --- a/Common/ArmEmitter.h +++ b/Common/ArmEmitter.h @@ -510,8 +510,8 @@ public: // NEON and VFP void VADD(ARMReg Vd, ARMReg Vn, ARMReg Vm); void VSUB(ARMReg Vd, ARMReg Vn, ARMReg Vm); - void VABS(ARMReg Vd, ARMReg Vn); - void VNEG(ARMReg Vd, ARMReg Vn); + void VABS(ARMReg Vd, ARMReg Vm); + void VNEG(ARMReg Vd, ARMReg Vm); void VMUL(ARMReg Vd, ARMReg Vn, ARMReg Vm); void VMOV(ARMReg Dest, ARMReg Src, bool high); void VMOV(ARMReg Dest, ARMReg Src); diff --git a/Core/MIPS/ARM/ArmCompFPU.cpp b/Core/MIPS/ARM/ArmCompFPU.cpp index ce88687ffe..38fdf73629 100644 --- a/Core/MIPS/ARM/ArmCompFPU.cpp +++ b/Core/MIPS/ARM/ArmCompFPU.cpp @@ -161,36 +161,23 @@ void Jit::Comp_FPU2op(u32 op) switch (op & 0x3f) { - /* - case 5: //F(fd) = fabsf(F(fs)); break; //abs - fpr.Lock(fd, fs); - fpr.BindToRegister(fd, fd == fs, true); - MOVSS(fpr.R(fd), fpr.R(fs)); - PAND(fpr.R(fd), M((void *)ssNoSignMask)); - fpr.UnlockAll(); - break; - */ - case 4: //F(fd) = sqrtf(F(fs)); break; //sqrt fpr.MapDirtyIn(fd, fs); VSQRT(fpr.R(fd), fpr.R(fs)); - return; - - - case 6: //F(fd) = F(fs); break; //mov + break; + case 5: //F(fd) = fabsf(F(fs)); break; //abs + fpr.MapDirtyIn(fd, fs); + VABS(fpr.R(fd), fpr.R(fs)); + break; + case 6: //F(fd) = F(fs); break; //mov fpr.MapDirtyIn(fd, fs); VMOV(fpr.R(fd), fpr.R(fs)); break; - - /* - case 7: //F(fd) = -F(fs); break; //neg - fpr.Lock(fd, fs); - fpr.BindToRegister(fd, fd == fs, true); - MOVSS(fpr.R(fd), fpr.R(fs)); - PXOR(fpr.R(fd), M((void *)ssSignBits2)); - fpr.UnlockAll(); + case 7: //F(fd) = -F(fs); break; //neg + fpr.MapDirtyIn(fd, fs); + VNEG(fpr.R(fd), fpr.R(fs)); break; - + /* case 12: //FsI(fd) = (int)floorf(F(fs)+0.5f); break; //round.w.s case 13: //FsI(fd) = F(fs)>=0 ? (int)floorf(F(fs)) : (int)ceilf(F(fs)); break;//trunc.w.s