From 0de507713b7c32f0514098f5458e493c22d69b23 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Thu, 13 Jul 2023 00:06:56 +0200 Subject: [PATCH] Make fbits inline, and add PopCount Floating point bitwise functions are now inline, also implemented a 'PopCount' function, which replicates the '__popcnt' instruction, but does not require the CPU to feature the instruction. This was mainly added as the SDK launcher doesn't check the CPU for SSSe3/popcnt, as it doesn't involve any instruction sets past SSE2. --- r5dev/mathlib/CMakeLists.txt | 2 +- r5dev/mathlib/bits.h | 24 ++++++++++++++++ r5dev/mathlib/fbits.cpp | 45 ----------------------------- r5dev/mathlib/fbits.h | 56 ++++++++++++++++++++++++++++++------ 4 files changed, 72 insertions(+), 55 deletions(-) create mode 100644 r5dev/mathlib/bits.h delete mode 100644 r5dev/mathlib/fbits.cpp diff --git a/r5dev/mathlib/CMakeLists.txt b/r5dev/mathlib/CMakeLists.txt index 2095608d..8c638ed4 100644 --- a/r5dev/mathlib/CMakeLists.txt +++ b/r5dev/mathlib/CMakeLists.txt @@ -43,7 +43,7 @@ add_sources( SOURCE_GROUP "Vector" add_sources( SOURCE_GROUP "Math" "almostequal.cpp" - "fbits.cpp" + "bits.h" "fbits.h" "math_pfns.h" "mathlib.h" diff --git a/r5dev/mathlib/bits.h b/r5dev/mathlib/bits.h new file mode 100644 index 00000000..417dd471 --- /dev/null +++ b/r5dev/mathlib/bits.h @@ -0,0 +1,24 @@ +#ifndef MATHLIB_BITS_H +#define MATHLIB_BITS_H +//=============================================================================// +// +// Purpose: bitwise utilities. +// +//=============================================================================// + +//----------------------------------------------------------------------------- +// '__popcnt' instruction reimplementation (allows for usage without requiring +// a processor to feature the popcnt instruction, only use for tools that have +// to run on processors that do NOT support popcnt!). +//----------------------------------------------------------------------------- +inline unsigned int PopCount(unsigned long long x) +{ + unsigned int count = 0; + while (x) { + x &= x - 1; // Clears the least significant bit set to 1. + count++; + } + return count; +} + +#endif // MATHLIB_BITS_H diff --git a/r5dev/mathlib/fbits.cpp b/r5dev/mathlib/fbits.cpp deleted file mode 100644 index 2e7934ea..00000000 --- a/r5dev/mathlib/fbits.cpp +++ /dev/null @@ -1,45 +0,0 @@ -//=============================================================================// -// -// Purpose: look for NANs, infinities, and underflows. -// -//=============================================================================// - -#include "mathlib/fbits.h" - -//----------------------------------------------------------------------------- -// This follows the ANSI/IEEE 754-1985 standard -//----------------------------------------------------------------------------- -unsigned long& FloatBits(float& f) -{ - return *reinterpret_cast(&f); -} - -unsigned long const& FloatBits(float const& f) -{ - return *reinterpret_cast(&f); -} - -float BitsToFloat(unsigned long i) -{ - return *reinterpret_cast(&i); -} - -bool IsFinite(float f) -{ - return ((FloatBits(f) & 0x7F800000) != 0x7F800000); -} - -unsigned long FloatAbsBits(float f) -{ - return FloatBits(f) & 0x7FFFFFFF; -} - -float FloatMakePositive(float f) -{ - return fabsf(f); // was since 2002: BitsToFloat( FloatBits(f) & 0x7FFFFFFF ); fixed in 2010 -} - -float FloatNegate(float f) -{ - return -f; //BitsToFloat( FloatBits(f) ^ 0x80000000 ); -} diff --git a/r5dev/mathlib/fbits.h b/r5dev/mathlib/fbits.h index eb0156c9..09968023 100644 --- a/r5dev/mathlib/fbits.h +++ b/r5dev/mathlib/fbits.h @@ -1,14 +1,52 @@ -#pragma once +#ifndef MATHLIB_FBITS_H +#define MATHLIB_FBITS_H +//=============================================================================// +// +// Purpose: look for NANs, infinities, and underflows. +// +//=============================================================================// -unsigned long& FloatBits(float& f); -unsigned long const& FloatBits(float const& f); -float BitsToFloat(unsigned long i); -bool IsFinite(float f); -unsigned long FloatAbsBits(float f); -float FloatMakePositive(float f); -float FloatNegate(float f); +//----------------------------------------------------------------------------- +// This follows the ANSI/IEEE 754-1985 standard +//----------------------------------------------------------------------------- +inline unsigned long& FloatBits(float& f) +{ + return *reinterpret_cast(&f); +} -#define FLOAT32_NAN_BITS (std::uint32_t)0x7FC00000 // NaN! +inline unsigned long const& FloatBits(float const& f) +{ + return *reinterpret_cast(&f); +} + +inline float BitsToFloat(unsigned long i) +{ + return *reinterpret_cast(&i); +} + +inline bool IsFinite(float f) +{ + return ((FloatBits(f) & 0x7F800000) != 0x7F800000); +} + +inline unsigned long FloatAbsBits(float f) +{ + return FloatBits(f) & 0x7FFFFFFF; +} + +inline float FloatMakePositive(float f) +{ + return fabsf(f); // was since 2002: BitsToFloat( FloatBits(f) & 0x7FFFFFFF ); fixed in 2010 +} + +inline float FloatNegate(float f) +{ + return -f; //BitsToFloat( FloatBits(f) ^ 0x80000000 ); +} + +#define FLOAT32_NAN_BITS (unsigned int)0x7FC00000 // NaN! #define FLOAT32_NAN BitsToFloat( FLOAT32_NAN_BITS ) #define VEC_T_NAN FLOAT32_NAN + +#endif // MATHLIB_FBITS_H