From 5c501e1e13c944939087fbba190d329028d44394 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Thu, 5 Jun 2025 05:38:57 +0200 Subject: [PATCH 1/7] Test C++ code replacement for assembly. --- Core/Libraries/Source/WWVegas/WWMath/wwmath.h | 58 +++++++++++++++---- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WWMath/wwmath.h b/Core/Libraries/Source/WWVegas/WWMath/wwmath.h index 831afdeb6ea..b0a856a3a1a 100644 --- a/Core/Libraries/Source/WWVegas/WWMath/wwmath.h +++ b/Core/Libraries/Source/WWVegas/WWMath/wwmath.h @@ -43,10 +43,12 @@ #define WWMATH_H #include "always.h" +//#include +//#include #include #include #include -#include +//#include /* ** Some global constants. @@ -124,16 +126,19 @@ static WWINLINE int Float_To_Int_Floor(const float& f); static WWINLINE float Cos(float val); static WWINLINE float Sin(float val); static WWINLINE float Sqrt(float val); -static float __fastcall Inv_Sqrt(float a); // Some 30% faster inverse square root than regular C++ compiled, from Intel's math library static WWINLINE long Float_To_Long(float f); #else static float Cos(float val); static float Sin(float val); static float Sqrt(float val); -static float Inv_Sqrt(float a); static long Float_To_Long(float f); #endif +#if defined(_MSC_VER) && _MSC_VER < 1300 && 0 +static WWINLINE float __fastcall Inv_Sqrt(float val); // Some 30% faster inverse square root than regular C++ compiled, from Intel's math library +#else +static WWINLINE float __fastcall Inv_Sqrt(float val); +#endif static WWINLINE float Fast_Sin(float val); static WWINLINE float Fast_Inv_Sin(float val); @@ -601,14 +606,14 @@ WWINLINE int WWMath::Float_To_Int_Floor (const float& f) // Inverse square root // ---------------------------------------------------------------------------- -#if defined(_MSC_VER) && defined(_M_IX86) -WWINLINE __declspec(naked) float __fastcall WWMath::Inv_Sqrt(float a) +#if defined(_MSC_VER) && _MSC_VER < 1300 && 0 +WWINLINE __declspec(naked) float __fastcall WWMath::Inv_Sqrt(float val) { __asm { mov eax, 0be6eb508h mov DWORD PTR [esp-12],03fc00000h ; 1.5 on the stack - sub eax, DWORD PTR [esp+4]; a - sub DWORD PTR [esp+4], 800000h ; a/2 a=Y0 + sub eax, DWORD PTR [esp+4]; val + sub DWORD PTR [esp+4], 800000h ; val/2 a=Y0 shr eax, 1 ; firs approx in eax=R0 mov DWORD PTR [esp-8], eax @@ -616,7 +621,7 @@ WWINLINE __declspec(naked) float __fastcall WWMath::Inv_Sqrt(float a) fmul st, st ;r*r fld DWORD PTR [esp-8] ;r fxch st(1) - fmul DWORD PTR [esp+4];a ;r*r*y0 + fmul DWORD PTR [esp+4];val ;r*r*y0 fld DWORD PTR [esp-12];load 1.5 fld st(0) fsub st,st(2) ;r1 = 1.5 - y1 @@ -648,9 +653,42 @@ WWINLINE __declspec(naked) float __fastcall WWMath::Inv_Sqrt(float a) } } #else -WWINLINE float WWMath::Inv_Sqrt(float val) +WWINLINE float __fastcall WWMath::Inv_Sqrt(float val) { - return 1.0f / (float)sqrt(val); + //static_assert(std::endian::native == std::endian::little); + //static_assert(std::numeric_limits::is_iec559 && std::numeric_limits::is_iec559); + + uint32_t input_bits; + memcpy(&input_bits, &val, sizeof(input_bits)); + + const uint32_t half_input_bits = input_bits - 0x800000; + const uint32_t approx_bits = (0xBE6EB508 - input_bits) >> 1; + + float half_input; + float approx_float; + memcpy(&half_input, &half_input_bits, sizeof(half_input)); + memcpy(&approx_float, &approx_bits, sizeof(approx_float)); + + const double d00 = approx_float; + const double d01 = half_input; + + const double d02 = static_cast(d00 * d00); + const double d03 = static_cast(d01 * d02); + const double d04 = static_cast(1.5 - d03); + + const double d05 = static_cast(d03 * d04); + const double d06 = static_cast(d04 * d05); + const double d07 = static_cast(1.5 - d06); + + const double d08 = static_cast(d06 * d07); + const double d09 = static_cast(d07 * d08); + const double d10 = static_cast(1.5 - d09); + + const double mul1 = static_cast(d00 * d04); + const double mul2 = static_cast(mul1 * d07); + const double mul3 = static_cast(mul2 * d10); + + return static_cast(mul3); } #endif From d8c626bcc2cc5b6a7e969e512b8bcea7ff5d0979 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Thu, 5 Jun 2025 05:46:30 +0200 Subject: [PATCH 2/7] Added included for memcpy. --- Core/Libraries/Source/WWVegas/WWMath/wwmath.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/Libraries/Source/WWVegas/WWMath/wwmath.h b/Core/Libraries/Source/WWVegas/WWMath/wwmath.h index b0a856a3a1a..80f206047a1 100644 --- a/Core/Libraries/Source/WWVegas/WWMath/wwmath.h +++ b/Core/Libraries/Source/WWVegas/WWMath/wwmath.h @@ -45,6 +45,7 @@ #include "always.h" //#include //#include +#include #include #include #include From 2ef339cbcc0820f8c1422cb2eb440d07184efbb1 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Thu, 5 Jun 2025 06:16:37 +0200 Subject: [PATCH 3/7] Test non-naked function. --- Core/Libraries/Source/WWVegas/WWMath/wwmath.h | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WWMath/wwmath.h b/Core/Libraries/Source/WWVegas/WWMath/wwmath.h index 80f206047a1..7fb702ab982 100644 --- a/Core/Libraries/Source/WWVegas/WWMath/wwmath.h +++ b/Core/Libraries/Source/WWVegas/WWMath/wwmath.h @@ -135,7 +135,7 @@ static float Sqrt(float val); static long Float_To_Long(float f); #endif -#if defined(_MSC_VER) && _MSC_VER < 1300 && 0 +#if defined(_MSC_VER) && _MSC_VER < 1300 static WWINLINE float __fastcall Inv_Sqrt(float val); // Some 30% faster inverse square root than regular C++ compiled, from Intel's math library #else static WWINLINE float __fastcall Inv_Sqrt(float val); @@ -607,14 +607,16 @@ WWINLINE int WWMath::Float_To_Int_Floor (const float& f) // Inverse square root // ---------------------------------------------------------------------------- -#if defined(_MSC_VER) && _MSC_VER < 1300 && 0 -WWINLINE __declspec(naked) float __fastcall WWMath::Inv_Sqrt(float val) +#if defined(_MSC_VER) && _MSC_VER < 1300 +WWINLINE float __fastcall WWMath::Inv_Sqrt(float val) { + float result; + __asm { mov eax, 0be6eb508h mov DWORD PTR [esp-12],03fc00000h ; 1.5 on the stack - sub eax, DWORD PTR [esp+4]; val - sub DWORD PTR [esp+4], 800000h ; val/2 a=Y0 + sub eax, DWORD PTR [val]; val + sub DWORD PTR [val], 800000h ; val/2 a=Y0 shr eax, 1 ; firs approx in eax=R0 mov DWORD PTR [esp-8], eax @@ -622,7 +624,7 @@ WWINLINE __declspec(naked) float __fastcall WWMath::Inv_Sqrt(float val) fmul st, st ;r*r fld DWORD PTR [esp-8] ;r fxch st(1) - fmul DWORD PTR [esp+4];val ;r*r*y0 + fmul DWORD PTR [val];val ;r*r*y0 fld DWORD PTR [esp-12];load 1.5 fld st(0) fsub st,st(2) ;r1 = 1.5 - y1 @@ -650,8 +652,10 @@ WWINLINE __declspec(naked) float __fastcall WWMath::Inv_Sqrt(float val) ;x3 = st(1) ;r3 = st(0) fmulp st(1), st - ret 4 + fstp result } + + return result; } #else WWINLINE float __fastcall WWMath::Inv_Sqrt(float val) From e608c512b8d2167d13f084eccb7d7ddd2398938a Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Thu, 5 Jun 2025 17:29:12 +0200 Subject: [PATCH 4/7] Reverted changes. --- Core/Libraries/Source/WWVegas/WWMath/wwmath.h | 64 ++++--------------- 1 file changed, 14 insertions(+), 50 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WWMath/wwmath.h b/Core/Libraries/Source/WWVegas/WWMath/wwmath.h index 7fb702ab982..9e8b3cdda74 100644 --- a/Core/Libraries/Source/WWVegas/WWMath/wwmath.h +++ b/Core/Libraries/Source/WWVegas/WWMath/wwmath.h @@ -127,18 +127,14 @@ static WWINLINE int Float_To_Int_Floor(const float& f); static WWINLINE float Cos(float val); static WWINLINE float Sin(float val); static WWINLINE float Sqrt(float val); +static WWINLINE float Inv_Sqrt(float a); // Some 30% faster inverse square root than regular C++ compiled, from Intel's math library static WWINLINE long Float_To_Long(float f); #else -static float Cos(float val); -static float Sin(float val); -static float Sqrt(float val); -static long Float_To_Long(float f); -#endif - -#if defined(_MSC_VER) && _MSC_VER < 1300 -static WWINLINE float __fastcall Inv_Sqrt(float val); // Some 30% faster inverse square root than regular C++ compiled, from Intel's math library -#else -static WWINLINE float __fastcall Inv_Sqrt(float val); +static WWINLINE float Cos(float val); +static WWINLINE float Sin(float val); +static WWINLINE float Sqrt(float val); +static WWINLINE float Inv_Sqrt(float a); +static WWINLINE long Float_To_Long(float f); #endif static WWINLINE float Fast_Sin(float val); @@ -607,16 +603,16 @@ WWINLINE int WWMath::Float_To_Int_Floor (const float& f) // Inverse square root // ---------------------------------------------------------------------------- -#if defined(_MSC_VER) && _MSC_VER < 1300 -WWINLINE float __fastcall WWMath::Inv_Sqrt(float val) +#if defined(_MSC_VER) && defined(_M_IX86) +WWINLINE float WWMath::Inv_Sqrt(float a) { float result; __asm { mov eax, 0be6eb508h mov DWORD PTR [esp-12],03fc00000h ; 1.5 on the stack - sub eax, DWORD PTR [val]; val - sub DWORD PTR [val], 800000h ; val/2 a=Y0 + sub eax, DWORD PTR [a]; a + sub DWORD PTR [a], 800000h ; a/2 a=Y0 shr eax, 1 ; firs approx in eax=R0 mov DWORD PTR [esp-8], eax @@ -624,7 +620,7 @@ WWINLINE float __fastcall WWMath::Inv_Sqrt(float val) fmul st, st ;r*r fld DWORD PTR [esp-8] ;r fxch st(1) - fmul DWORD PTR [val];val ;r*r*y0 + fmul DWORD PTR [a];a ;r*r*y0 fld DWORD PTR [esp-12];load 1.5 fld st(0) fsub st,st(2) ;r1 = 1.5 - y1 @@ -652,48 +648,16 @@ WWINLINE float __fastcall WWMath::Inv_Sqrt(float val) ;x3 = st(1) ;r3 = st(0) fmulp st(1), st + fstp result } return result; } #else -WWINLINE float __fastcall WWMath::Inv_Sqrt(float val) +WWINLINE float WWMath::Inv_Sqrt(float val) { - //static_assert(std::endian::native == std::endian::little); - //static_assert(std::numeric_limits::is_iec559 && std::numeric_limits::is_iec559); - - uint32_t input_bits; - memcpy(&input_bits, &val, sizeof(input_bits)); - - const uint32_t half_input_bits = input_bits - 0x800000; - const uint32_t approx_bits = (0xBE6EB508 - input_bits) >> 1; - - float half_input; - float approx_float; - memcpy(&half_input, &half_input_bits, sizeof(half_input)); - memcpy(&approx_float, &approx_bits, sizeof(approx_float)); - - const double d00 = approx_float; - const double d01 = half_input; - - const double d02 = static_cast(d00 * d00); - const double d03 = static_cast(d01 * d02); - const double d04 = static_cast(1.5 - d03); - - const double d05 = static_cast(d03 * d04); - const double d06 = static_cast(d04 * d05); - const double d07 = static_cast(1.5 - d06); - - const double d08 = static_cast(d06 * d07); - const double d09 = static_cast(d07 * d08); - const double d10 = static_cast(1.5 - d09); - - const double mul1 = static_cast(d00 * d04); - const double mul2 = static_cast(mul1 * d07); - const double mul3 = static_cast(mul2 * d10); - - return static_cast(mul3); + return 1.0f / (float)sqrt(val); } #endif From c48ab7adcc7a7b17437b0f49e01cf14013f55c0c Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Thu, 5 Jun 2025 17:31:02 +0200 Subject: [PATCH 5/7] Removed unused includes. --- Core/Libraries/Source/WWVegas/WWMath/wwmath.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WWMath/wwmath.h b/Core/Libraries/Source/WWVegas/WWMath/wwmath.h index 9e8b3cdda74..7ed750e4a84 100644 --- a/Core/Libraries/Source/WWVegas/WWMath/wwmath.h +++ b/Core/Libraries/Source/WWVegas/WWMath/wwmath.h @@ -43,13 +43,10 @@ #define WWMATH_H #include "always.h" -//#include -//#include #include #include #include #include -//#include /* ** Some global constants. From 406fd6193f8d9553d4eaf8937fa15537b0aefc44 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Thu, 5 Jun 2025 17:31:39 +0200 Subject: [PATCH 6/7] Removed unused include. --- Core/Libraries/Source/WWVegas/WWMath/wwmath.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/Libraries/Source/WWVegas/WWMath/wwmath.h b/Core/Libraries/Source/WWVegas/WWMath/wwmath.h index 7ed750e4a84..bc324e55395 100644 --- a/Core/Libraries/Source/WWVegas/WWMath/wwmath.h +++ b/Core/Libraries/Source/WWVegas/WWMath/wwmath.h @@ -43,7 +43,6 @@ #define WWMATH_H #include "always.h" -#include #include #include #include From 70af85af0d7206d7ac9f98fd7b100dd406e3dff0 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Thu, 5 Jun 2025 19:24:26 +0200 Subject: [PATCH 7/7] Revert most changes except removal of naked function declaration. --- Core/Libraries/Source/WWVegas/WWMath/wwmath.h | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WWMath/wwmath.h b/Core/Libraries/Source/WWVegas/WWMath/wwmath.h index bc324e55395..573d3bf32eb 100644 --- a/Core/Libraries/Source/WWVegas/WWMath/wwmath.h +++ b/Core/Libraries/Source/WWVegas/WWMath/wwmath.h @@ -46,6 +46,7 @@ #include #include #include +#include /* ** Some global constants. @@ -123,16 +124,17 @@ static WWINLINE int Float_To_Int_Floor(const float& f); static WWINLINE float Cos(float val); static WWINLINE float Sin(float val); static WWINLINE float Sqrt(float val); -static WWINLINE float Inv_Sqrt(float a); // Some 30% faster inverse square root than regular C++ compiled, from Intel's math library +static float __fastcall Inv_Sqrt(float a); // Some 30% faster inverse square root than regular C++ compiled, from Intel's math library static WWINLINE long Float_To_Long(float f); #else -static WWINLINE float Cos(float val); -static WWINLINE float Sin(float val); -static WWINLINE float Sqrt(float val); -static WWINLINE float Inv_Sqrt(float a); -static WWINLINE long Float_To_Long(float f); +static float Cos(float val); +static float Sin(float val); +static float Sqrt(float val); +static float Inv_Sqrt(float a); +static long Float_To_Long(float f); #endif + static WWINLINE float Fast_Sin(float val); static WWINLINE float Fast_Inv_Sin(float val); static WWINLINE float Fast_Cos(float val); @@ -600,9 +602,9 @@ WWINLINE int WWMath::Float_To_Int_Floor (const float& f) // ---------------------------------------------------------------------------- #if defined(_MSC_VER) && defined(_M_IX86) -WWINLINE float WWMath::Inv_Sqrt(float a) +WWINLINE float __fastcall WWMath::Inv_Sqrt(float a) { - float result; + float retval; __asm { mov eax, 0be6eb508h @@ -645,10 +647,10 @@ WWINLINE float WWMath::Inv_Sqrt(float a) ;r3 = st(0) fmulp st(1), st - fstp result + fstp retval } - return result; + return retval; } #else WWINLINE float WWMath::Inv_Sqrt(float val)