mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-18 17:00:30 +02:00
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:
1 parent
fe90d5cd06
commit
61f5fb35bd
3 files changed
+25
-6
No files matched your search
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user