From 61f5fb35bd8d7b8a67983ce5d446752c6b48ffb6 Mon Sep 17 00:00:00 2001 From: Sacha Date: Thu, 28 Feb 2013 19:46:07 +1000 Subject: [PATCH] ARMJIT: Implement cvt.w.s, cvt.s.w and trunc.w.s that are used heavily in Dragonball. May need to keep note of FCR to get correct rounding mode? Interpreter doesn't do this either. --- Common/ArmEmitter.cpp | 8 ++++++++ Common/ArmEmitter.h | 1 + Core/MIPS/ARM/ArmCompFPU.cpp | 22 ++++++++++++++++------ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/Common/ArmEmitter.cpp b/Common/ArmEmitter.cpp index 1da5f05b60..92c045b4a7 100644 --- a/Common/ArmEmitter.cpp +++ b/Common/ArmEmitter.cpp @@ -1032,4 +1032,12 @@ void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src) } } +void ARMXEmitter::VCVT(bool to_integer, bool is_signed, ARMReg Sd, ARMReg Sm) +{ + Sd = SubBase(Sd); + Sm = SubBase(Sm); + Write32(NO_COND | (0x1D << 23) | ((Sd & 0x1) << 22) | (0x7 << 19) | (to_integer << 18) | (is_signed << 16) \ + | ((Sd & 0x1E) << 11) | (0x2B << 6) | ((Sm & 0x1) << 5) | (Sm >> 1)); +} + } diff --git a/Common/ArmEmitter.h b/Common/ArmEmitter.h index 8813680f09..3edd824ec4 100644 --- a/Common/ArmEmitter.h +++ b/Common/ArmEmitter.h @@ -515,6 +515,7 @@ public: void VMUL(ARMReg Vd, ARMReg Vn, ARMReg Vm); void VMOV(ARMReg Dest, ARMReg Src, bool high); void VMOV(ARMReg Dest, ARMReg Src); + void VCVT(bool to_integer, bool is_signed, ARMReg Sd, ARMReg Sm); void QuickCallFunction(ARMReg scratchreg, void *func); // Utility functions diff --git a/Core/MIPS/ARM/ArmCompFPU.cpp b/Core/MIPS/ARM/ArmCompFPU.cpp index 38fdf73629..800dc5abf7 100644 --- a/Core/MIPS/ARM/ArmCompFPU.cpp +++ b/Core/MIPS/ARM/ArmCompFPU.cpp @@ -161,22 +161,34 @@ void Jit::Comp_FPU2op(u32 op) switch (op & 0x3f) { - case 4: //F(fd) = sqrtf(F(fs)); break; //sqrt + case 4: //F(fd) = sqrtf(F(fs)); break; //sqrt fpr.MapDirtyIn(fd, fs); VSQRT(fpr.R(fd), fpr.R(fs)); break; - case 5: //F(fd) = fabsf(F(fs)); break; //abs + 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 + 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 + case 7: //F(fd) = -F(fs); break; //neg fpr.MapDirtyIn(fd, fs); VNEG(fpr.R(fd), fpr.R(fs)); break; + case 13: //FsI(fd) = Rto0(F(fs))); break; //trunc.w.s + fpr.MapDirtyIn(fd, fs); + VCVT(true, true, fpr.R(fd), fpr.R(fs)); + break; + case 32: //F(fd) = (float)FsI(fs); break; //cvt.s.w + fpr.MapDirtyIn(fd, fs); + VCVT(false, false, fpr.R(fd), fpr.R(fs)); + break; + case 36: //FsI(fd) = (int) F(fs); break; //cvt.w.s + fpr.MapDirtyIn(fd, fs); + VCVT(true, false, fpr.R(fd), fpr.R(fs)); + break; /* case 12: //FsI(fd) = (int)floorf(F(fs)+0.5f); break; //round.w.s @@ -190,8 +202,6 @@ void Jit::Comp_FPU2op(u32 op) case 14: //FsI(fd) = (int)ceilf (F(fs)); break; //ceil.w.s case 15: //FsI(fd) = (int)floorf(F(fs)); break; //floor.w.s - case 32: //F(fd) = (float)FsI(fs); break; //cvt.s.w - case 36: //FsI(fd) = (int) F(fs); break; //cvt.w.s */ default: DISABLE;