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.
This commit is contained in:
Sacha committed 2013-02-28 19:46:07 +10:00
1 parent fe90d5cd06
commit 61f5fb35bd
3 files changed
+25 -6

No files matched your search

+8
View File
@@ -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));
}
}
+1
View File
@@ -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
+16 -6
View File
@@ -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;