From 823fb1fecdcc47b5244708729a04d98a81ef4ea0 Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Tue, 18 Feb 2025 02:22:43 -0600 Subject: [PATCH] Interpreter: Accurate FTOI Plus some ITOF cleanup --- pcsx2/VUops.cpp | 112 ++++++++++++------------------------------------ pcsx2/VUops.h | 8 ---- 2 files changed, 27 insertions(+), 93 deletions(-) diff --git a/pcsx2/VUops.cpp b/pcsx2/VUops.cpp index f1ed263b25..0147f82b1d 100644 --- a/pcsx2/VUops.cpp +++ b/pcsx2/VUops.cpp @@ -1619,98 +1619,40 @@ static __fi void _vuNOP(VURegs* VU) { } -static __fi s32 float_to_int(float value) +template +static __fi u32 floatToInt(u32 uvalue) { - if (value >= 2147483647.0) - return 2147483647LL; - if (value <= -2147483648.0) - return -2147483648LL; - return value; + float fvalue = std::bit_cast(uvalue); + if (Offset) + fvalue *= std::bit_cast(0x3f800000 + (Offset << 23)); + s32 svalue = std::bit_cast(fvalue); + + if (svalue >= static_cast(0x4f000000)) + return 0x7fffffff; + else if (svalue <= static_cast(0xcf000000)) + return 0x80000000; + else + return static_cast(static_cast(fvalue)); } -static __fi void _vuFTOI0(VURegs* VU) { - if (_Ft_ == 0) return; +static __fi void _vuFTOI0 (VURegs* VU) { applyUnaryFunction>(VU); } +static __fi void _vuFTOI4 (VURegs* VU) { applyUnaryFunction>(VU); } +static __fi void _vuFTOI12(VURegs* VU) { applyUnaryFunction>(VU); } +static __fi void _vuFTOI15(VURegs* VU) { applyUnaryFunction>(VU); } - if (_X) VU->VF[_Ft_].SL[0] = float_to_int(vuDouble(VU->VF[_Fs_].i.x)); - if (_Y) VU->VF[_Ft_].SL[1] = float_to_int(vuDouble(VU->VF[_Fs_].i.y)); - if (_Z) VU->VF[_Ft_].SL[2] = float_to_int(vuDouble(VU->VF[_Fs_].i.z)); - if (_W) VU->VF[_Ft_].SL[3] = float_to_int(vuDouble(VU->VF[_Fs_].i.w)); -} - -static __fi void _vuFTOI4(VURegs* VU) { - if (_Ft_ == 0) return; - - if (_X) VU->VF[_Ft_].SL[0] = float_to_int(float_to_int4(vuDouble(VU->VF[_Fs_].i.x))); - if (_Y) VU->VF[_Ft_].SL[1] = float_to_int(float_to_int4(vuDouble(VU->VF[_Fs_].i.y))); - if (_Z) VU->VF[_Ft_].SL[2] = float_to_int(float_to_int4(vuDouble(VU->VF[_Fs_].i.z))); - if (_W) VU->VF[_Ft_].SL[3] = float_to_int(float_to_int4(vuDouble(VU->VF[_Fs_].i.w))); -} - -static __fi void _vuFTOI12(VURegs* VU) +template +static __fi u32 intToFloat(u32 uvalue) { - if (_Ft_ == 0) - return; - - if (_X) VU->VF[_Ft_].SL[0] = float_to_int(float_to_int12(vuDouble(VU->VF[_Fs_].i.x))); - if (_Y) VU->VF[_Ft_].SL[1] = float_to_int(float_to_int12(vuDouble(VU->VF[_Fs_].i.y))); - if (_Z) VU->VF[_Ft_].SL[2] = float_to_int(float_to_int12(vuDouble(VU->VF[_Fs_].i.z))); - if (_W) VU->VF[_Ft_].SL[3] = float_to_int(float_to_int12(vuDouble(VU->VF[_Fs_].i.w))); + float fvalue = static_cast(static_cast(uvalue)); + if (Offset) + fvalue *= std::bit_cast(0x3f800000 - (Offset << 23)); + return std::bit_cast(fvalue); } -static __fi void _vuFTOI15(VURegs* VU) -{ - if (_Ft_ == 0) - return; - - if (_X) VU->VF[_Ft_].SL[0] = float_to_int(float_to_int15(vuDouble(VU->VF[_Fs_].i.x))); - if (_Y) VU->VF[_Ft_].SL[1] = float_to_int(float_to_int15(vuDouble(VU->VF[_Fs_].i.y))); - if (_Z) VU->VF[_Ft_].SL[2] = float_to_int(float_to_int15(vuDouble(VU->VF[_Fs_].i.z))); - if (_W) VU->VF[_Ft_].SL[3] = float_to_int(float_to_int15(vuDouble(VU->VF[_Fs_].i.w))); -} - -static __fi void _vuITOF0(VURegs* VU) -{ - if (_Ft_ == 0) - return; - - if (_X) VU->VF[_Ft_].f.x = (float)VU->VF[_Fs_].SL[0]; - if (_Y) VU->VF[_Ft_].f.y = (float)VU->VF[_Fs_].SL[1]; - if (_Z) VU->VF[_Ft_].f.z = (float)VU->VF[_Fs_].SL[2]; - if (_W) VU->VF[_Ft_].f.w = (float)VU->VF[_Fs_].SL[3]; -} - -static __fi void _vuITOF4(VURegs* VU) -{ - if (_Ft_ == 0) - return; - - if (_X) VU->VF[_Ft_].f.x = int4_to_float(VU->VF[_Fs_].SL[0]); - if (_Y) VU->VF[_Ft_].f.y = int4_to_float(VU->VF[_Fs_].SL[1]); - if (_Z) VU->VF[_Ft_].f.z = int4_to_float(VU->VF[_Fs_].SL[2]); - if (_W) VU->VF[_Ft_].f.w = int4_to_float(VU->VF[_Fs_].SL[3]); -} - -static __fi void _vuITOF12(VURegs* VU) -{ - if (_Ft_ == 0) - return; - - if (_X) VU->VF[_Ft_].f.x = int12_to_float(VU->VF[_Fs_].SL[0]); - if (_Y) VU->VF[_Ft_].f.y = int12_to_float(VU->VF[_Fs_].SL[1]); - if (_Z) VU->VF[_Ft_].f.z = int12_to_float(VU->VF[_Fs_].SL[2]); - if (_W) VU->VF[_Ft_].f.w = int12_to_float(VU->VF[_Fs_].SL[3]); -} - -static __fi void _vuITOF15(VURegs* VU) -{ - if (_Ft_ == 0) - return; - - if (_X) VU->VF[_Ft_].f.x = int15_to_float(VU->VF[_Fs_].SL[0]); - if (_Y) VU->VF[_Ft_].f.y = int15_to_float(VU->VF[_Fs_].SL[1]); - if (_Z) VU->VF[_Ft_].f.z = int15_to_float(VU->VF[_Fs_].SL[2]); - if (_W) VU->VF[_Ft_].f.w = int15_to_float(VU->VF[_Fs_].SL[3]); -} +static __fi void _vuITOF0 (VURegs* VU) { applyUnaryFunction>(VU); } +static __fi void _vuITOF4 (VURegs* VU) { applyUnaryFunction>(VU); } +static __fi void _vuITOF12(VURegs* VU) { applyUnaryFunction>(VU); } +static __fi void _vuITOF15(VURegs* VU) { applyUnaryFunction>(VU); } static __fi void _vuCLIP(VURegs* VU) { diff --git a/pcsx2/VUops.h b/pcsx2/VUops.h index bebca654eb..37c2211cf0 100644 --- a/pcsx2/VUops.h +++ b/pcsx2/VUops.h @@ -5,14 +5,6 @@ #include "VU.h" #include "VUflags.h" -#define float_to_int4(x) ((float)x * (1.0f / 0.0625f)) -#define float_to_int12(x) ((float)x * (1.0f / 0.000244140625f)) -#define float_to_int15(x) ((float)x * (1.0f / 0.000030517578125)) - -#define int4_to_float(x) (float)((float)x * 0.0625f) -#define int12_to_float(x) (float)((float)x * 0.000244140625f) -#define int15_to_float(x) (float)((float)x * 0.000030517578125) - struct _VURegsNum { u8 pipe; // if 0xff, COP2 u8 VFwrite;