Added mulHi64 intrinsics. (#477)

This commit is contained in:
Branimir Karadžić
2026-10-28 17:16:18 +00:00
committed by GitHub
parent dae5c595b7
commit f9c90f5081
5 changed files with 247 additions and 177 deletions
+81 -74
View File
@@ -40,99 +40,106 @@ namespace bx
BX_SIMD_INLINE void float4x4_mul(float4x4_t* _result, const float4x4_t* _a, const float4x4_t* _b)
{
#if BX_SIMD_SUPPORTED
_result->col[0] = simd128_mul(_a->col[0], _b);
_result->col[1] = simd128_mul(_a->col[1], _b);
_result->col[2] = simd128_mul(_a->col[2], _b);
_result->col[3] = simd128_mul(_a->col[3], _b);
#else
const float* aa = (const float*)_a;
const float* bb = (const float*)_b;
float *rr = (float*)_result;
if constexpr (kSimdSupported)
{
_result->col[0] = simd128_mul(_a->col[0], _b);
_result->col[1] = simd128_mul(_a->col[1], _b);
_result->col[2] = simd128_mul(_a->col[2], _b);
_result->col[3] = simd128_mul(_a->col[3], _b);
}
else
{
const float* aa = (const float*)_a;
const float* bb = (const float*)_b;
float *rr = (float*)_result;
rr[ 0] = aa[ 0]*bb[ 0] + aa[ 1]*bb[ 4] + aa[ 2]*bb[ 8] + aa[ 3]*bb[12];
rr[ 1] = aa[ 0]*bb[ 1] + aa[ 1]*bb[ 5] + aa[ 2]*bb[ 9] + aa[ 3]*bb[13];
rr[ 2] = aa[ 0]*bb[ 2] + aa[ 1]*bb[ 6] + aa[ 2]*bb[10] + aa[ 3]*bb[14];
rr[ 3] = aa[ 0]*bb[ 3] + aa[ 1]*bb[ 7] + aa[ 2]*bb[11] + aa[ 3]*bb[15];
rr[ 0] = aa[ 0]*bb[ 0] + aa[ 1]*bb[ 4] + aa[ 2]*bb[ 8] + aa[ 3]*bb[12];
rr[ 1] = aa[ 0]*bb[ 1] + aa[ 1]*bb[ 5] + aa[ 2]*bb[ 9] + aa[ 3]*bb[13];
rr[ 2] = aa[ 0]*bb[ 2] + aa[ 1]*bb[ 6] + aa[ 2]*bb[10] + aa[ 3]*bb[14];
rr[ 3] = aa[ 0]*bb[ 3] + aa[ 1]*bb[ 7] + aa[ 2]*bb[11] + aa[ 3]*bb[15];
rr[ 4] = aa[ 4]*bb[ 0] + aa[ 5]*bb[ 4] + aa[ 6]*bb[ 8] + aa[ 7]*bb[12];
rr[ 5] = aa[ 4]*bb[ 1] + aa[ 5]*bb[ 5] + aa[ 6]*bb[ 9] + aa[ 7]*bb[13];
rr[ 6] = aa[ 4]*bb[ 2] + aa[ 5]*bb[ 6] + aa[ 6]*bb[10] + aa[ 7]*bb[14];
rr[ 7] = aa[ 4]*bb[ 3] + aa[ 5]*bb[ 7] + aa[ 6]*bb[11] + aa[ 7]*bb[15];
rr[ 4] = aa[ 4]*bb[ 0] + aa[ 5]*bb[ 4] + aa[ 6]*bb[ 8] + aa[ 7]*bb[12];
rr[ 5] = aa[ 4]*bb[ 1] + aa[ 5]*bb[ 5] + aa[ 6]*bb[ 9] + aa[ 7]*bb[13];
rr[ 6] = aa[ 4]*bb[ 2] + aa[ 5]*bb[ 6] + aa[ 6]*bb[10] + aa[ 7]*bb[14];
rr[ 7] = aa[ 4]*bb[ 3] + aa[ 5]*bb[ 7] + aa[ 6]*bb[11] + aa[ 7]*bb[15];
rr[ 8] = aa[ 8]*bb[ 0] + aa[ 9]*bb[ 4] + aa[10]*bb[ 8] + aa[11]*bb[12];
rr[ 9] = aa[ 8]*bb[ 1] + aa[ 9]*bb[ 5] + aa[10]*bb[ 9] + aa[11]*bb[13];
rr[10] = aa[ 8]*bb[ 2] + aa[ 9]*bb[ 6] + aa[10]*bb[10] + aa[11]*bb[14];
rr[11] = aa[ 8]*bb[ 3] + aa[ 9]*bb[ 7] + aa[10]*bb[11] + aa[11]*bb[15];
rr[ 8] = aa[ 8]*bb[ 0] + aa[ 9]*bb[ 4] + aa[10]*bb[ 8] + aa[11]*bb[12];
rr[ 9] = aa[ 8]*bb[ 1] + aa[ 9]*bb[ 5] + aa[10]*bb[ 9] + aa[11]*bb[13];
rr[10] = aa[ 8]*bb[ 2] + aa[ 9]*bb[ 6] + aa[10]*bb[10] + aa[11]*bb[14];
rr[11] = aa[ 8]*bb[ 3] + aa[ 9]*bb[ 7] + aa[10]*bb[11] + aa[11]*bb[15];
rr[12] = aa[12]*bb[ 0] + aa[13]*bb[ 4] + aa[14]*bb[ 8] + aa[15]*bb[12];
rr[13] = aa[12]*bb[ 1] + aa[13]*bb[ 5] + aa[14]*bb[ 9] + aa[15]*bb[13];
rr[14] = aa[12]*bb[ 2] + aa[13]*bb[ 6] + aa[14]*bb[10] + aa[15]*bb[14];
rr[15] = aa[12]*bb[ 3] + aa[13]*bb[ 7] + aa[14]*bb[11] + aa[15]*bb[15];
#endif // BX_SIMD_SUPPORTED
rr[12] = aa[12]*bb[ 0] + aa[13]*bb[ 4] + aa[14]*bb[ 8] + aa[15]*bb[12];
rr[13] = aa[12]*bb[ 1] + aa[13]*bb[ 5] + aa[14]*bb[ 9] + aa[15]*bb[13];
rr[14] = aa[12]*bb[ 2] + aa[13]*bb[ 6] + aa[14]*bb[10] + aa[15]*bb[14];
rr[15] = aa[12]*bb[ 3] + aa[13]*bb[ 7] + aa[14]*bb[11] + aa[15]*bb[15];
}
}
BX_SIMD_INLINE void model4x4_mul(float4x4_t* _result, const float4x4_t* _a, const float4x4_t* _b)
{
#if BX_SIMD_SUPPORTED
// With SIMD faster to do the general 4x4 form:
float4x4_mul(_result, _a, _b);
#else
const float* aa = (const float*)_a; // aa[ 3] == aa[ 7] == aa[11] == 0.0f, aa[15] = 1.0f
const float* bb = (const float*)_b; // bb[ 3] == bb[ 7] == bb[11] == 0.0f, bb[15] = 1.0f
float *rr = (float*)_result;
if constexpr (kSimdSupported)
{
float4x4_mul(_result, _a, _b);
}
else
{
const float* aa = (const float*)_a; // aa[ 3] == aa[ 7] == aa[11] == 0.0f, aa[15] = 1.0f
const float* bb = (const float*)_b; // bb[ 3] == bb[ 7] == bb[11] == 0.0f, bb[15] = 1.0f
float *rr = (float*)_result;
rr[ 0] = aa[ 0]*bb[ 0] + aa[ 1]*bb[ 4] + aa[ 2]*bb[ 8];
rr[ 1] = aa[ 0]*bb[ 1] + aa[ 1]*bb[ 5] + aa[ 2]*bb[ 9];
rr[ 2] = aa[ 0]*bb[ 2] + aa[ 1]*bb[ 6] + aa[ 2]*bb[10];
rr[ 3] = 0.0f;
rr[ 0] = aa[ 0]*bb[ 0] + aa[ 1]*bb[ 4] + aa[ 2]*bb[ 8];
rr[ 1] = aa[ 0]*bb[ 1] + aa[ 1]*bb[ 5] + aa[ 2]*bb[ 9];
rr[ 2] = aa[ 0]*bb[ 2] + aa[ 1]*bb[ 6] + aa[ 2]*bb[10];
rr[ 3] = 0.0f;
rr[ 4] = aa[ 4]*bb[ 0] + aa[ 5]*bb[ 4] + aa[ 6]*bb[ 8];
rr[ 5] = aa[ 4]*bb[ 1] + aa[ 5]*bb[ 5] + aa[ 6]*bb[ 9];
rr[ 6] = aa[ 4]*bb[ 2] + aa[ 5]*bb[ 6] + aa[ 6]*bb[10];
rr[ 7] = 0.0f;
rr[ 4] = aa[ 4]*bb[ 0] + aa[ 5]*bb[ 4] + aa[ 6]*bb[ 8];
rr[ 5] = aa[ 4]*bb[ 1] + aa[ 5]*bb[ 5] + aa[ 6]*bb[ 9];
rr[ 6] = aa[ 4]*bb[ 2] + aa[ 5]*bb[ 6] + aa[ 6]*bb[10];
rr[ 7] = 0.0f;
rr[ 8] = aa[ 8]*bb[ 0] + aa[ 9]*bb[ 4] + aa[10]*bb[ 8];
rr[ 9] = aa[ 8]*bb[ 1] + aa[ 9]*bb[ 5] + aa[10]*bb[ 9];
rr[10] = aa[ 8]*bb[ 2] + aa[ 9]*bb[ 6] + aa[10]*bb[10];
rr[11] = 0.0f;
rr[ 8] = aa[ 8]*bb[ 0] + aa[ 9]*bb[ 4] + aa[10]*bb[ 8];
rr[ 9] = aa[ 8]*bb[ 1] + aa[ 9]*bb[ 5] + aa[10]*bb[ 9];
rr[10] = aa[ 8]*bb[ 2] + aa[ 9]*bb[ 6] + aa[10]*bb[10];
rr[11] = 0.0f;
rr[12] = aa[12]*bb[ 0] + aa[13]*bb[ 4] + aa[14]*bb[ 8] + bb[12];
rr[13] = aa[12]*bb[ 1] + aa[13]*bb[ 5] + aa[14]*bb[ 9] + bb[13];
rr[14] = aa[12]*bb[ 2] + aa[13]*bb[ 6] + aa[14]*bb[10] + bb[14];
rr[15] = 1.0f;
#endif // BX_SIMD_SUPPORTED
rr[12] = aa[12]*bb[ 0] + aa[13]*bb[ 4] + aa[14]*bb[ 8] + bb[12];
rr[13] = aa[12]*bb[ 1] + aa[13]*bb[ 5] + aa[14]*bb[ 9] + bb[13];
rr[14] = aa[12]*bb[ 2] + aa[13]*bb[ 6] + aa[14]*bb[10] + bb[14];
rr[15] = 1.0f;
}
}
BX_SIMD_INLINE void model4x4_mul_viewproj4x4(float4x4_t* _result, const float4x4_t* _model, const float4x4_t* _viewProj)
{
#if BX_SIMD_SUPPORTED
// With SIMD faster to do the general 4x4 form:
float4x4_mul(_result, _model, _viewProj);
#else
const float* aa = (const float*)_model; // aa[ 3] == aa[ 7] == aa[11] == 0.0f, aa[15] == 1.0f
const float* bb = (const float*)_viewProj;
float *rr = (float*)_result;
rr[ 0] = aa[ 0]*bb[ 0] + aa[ 1]*bb[ 4] + aa[ 2]*bb[ 8];
rr[ 1] = aa[ 0]*bb[ 1] + aa[ 1]*bb[ 5] + aa[ 2]*bb[ 9];
rr[ 2] = aa[ 0]*bb[ 2] + aa[ 1]*bb[ 6] + aa[ 2]*bb[10];
rr[ 3] = aa[ 0]*bb[ 3] + aa[ 1]*bb[ 7] + aa[ 2]*bb[11];
if constexpr (kSimdSupported)
{
float4x4_mul(_result, _model, _viewProj);
}
else
{
const float* aa = (const float*)_model; // aa[ 3] == aa[ 7] == aa[11] == 0.0f, aa[15] == 1.0f
const float* bb = (const float*)_viewProj;
float *rr = (float*)_result;
rr[ 0] = aa[ 0]*bb[ 0] + aa[ 1]*bb[ 4] + aa[ 2]*bb[ 8];
rr[ 1] = aa[ 0]*bb[ 1] + aa[ 1]*bb[ 5] + aa[ 2]*bb[ 9];
rr[ 2] = aa[ 0]*bb[ 2] + aa[ 1]*bb[ 6] + aa[ 2]*bb[10];
rr[ 3] = aa[ 0]*bb[ 3] + aa[ 1]*bb[ 7] + aa[ 2]*bb[11];
rr[ 4] = aa[ 4]*bb[ 0] + aa[ 5]*bb[ 4] + aa[ 6]*bb[ 8];
rr[ 5] = aa[ 4]*bb[ 1] + aa[ 5]*bb[ 5] + aa[ 6]*bb[ 9];
rr[ 6] = aa[ 4]*bb[ 2] + aa[ 5]*bb[ 6] + aa[ 6]*bb[10];
rr[ 7] = aa[ 4]*bb[ 3] + aa[ 5]*bb[ 7] + aa[ 6]*bb[11];
rr[ 4] = aa[ 4]*bb[ 0] + aa[ 5]*bb[ 4] + aa[ 6]*bb[ 8];
rr[ 5] = aa[ 4]*bb[ 1] + aa[ 5]*bb[ 5] + aa[ 6]*bb[ 9];
rr[ 6] = aa[ 4]*bb[ 2] + aa[ 5]*bb[ 6] + aa[ 6]*bb[10];
rr[ 7] = aa[ 4]*bb[ 3] + aa[ 5]*bb[ 7] + aa[ 6]*bb[11];
rr[ 8] = aa[ 8]*bb[ 0] + aa[ 9]*bb[ 4] + aa[10]*bb[ 8];
rr[ 9] = aa[ 8]*bb[ 1] + aa[ 9]*bb[ 5] + aa[10]*bb[ 9];
rr[10] = aa[ 8]*bb[ 2] + aa[ 9]*bb[ 6] + aa[10]*bb[10];
rr[11] = aa[ 8]*bb[ 3] + aa[ 9]*bb[ 7] + aa[10]*bb[11];
rr[ 8] = aa[ 8]*bb[ 0] + aa[ 9]*bb[ 4] + aa[10]*bb[ 8];
rr[ 9] = aa[ 8]*bb[ 1] + aa[ 9]*bb[ 5] + aa[10]*bb[ 9];
rr[10] = aa[ 8]*bb[ 2] + aa[ 9]*bb[ 6] + aa[10]*bb[10];
rr[11] = aa[ 8]*bb[ 3] + aa[ 9]*bb[ 7] + aa[10]*bb[11];
rr[12] = aa[12]*bb[ 0] + aa[13]*bb[ 4] + aa[14]*bb[ 8] + bb[12];
rr[13] = aa[12]*bb[ 1] + aa[13]*bb[ 5] + aa[14]*bb[ 9] + bb[13];
rr[14] = aa[12]*bb[ 2] + aa[13]*bb[ 6] + aa[14]*bb[10] + bb[14];
rr[15] = aa[12]*bb[ 3] + aa[13]*bb[ 7] + aa[14]*bb[11] + bb[15];
#endif // BX_SIMD_SUPPORTED
rr[12] = aa[12]*bb[ 0] + aa[13]*bb[ 4] + aa[14]*bb[ 8] + bb[12];
rr[13] = aa[12]*bb[ 1] + aa[13]*bb[ 5] + aa[14]*bb[ 9] + bb[13];
rr[14] = aa[12]*bb[ 2] + aa[13]*bb[ 6] + aa[14]*bb[10] + bb[14];
rr[15] = aa[12]*bb[ 3] + aa[13]*bb[ 7] + aa[14]*bb[11] + bb[15];
}
}
BX_SIMD_FORCE_INLINE void float4x4_transpose(float4x4_t* _result, const float4x4_t* _mtx)
+90 -79
View File
@@ -24,6 +24,9 @@ extern "C" unsigned char _BitScanReverse64(unsigned long* _Index, unsigned __int
extern "C" unsigned char _BitScanForward64(unsigned long* _Index, unsigned __int64 _Mask);
# pragma intrinsic(_BitScanForward64)
extern "C" unsigned __int64 __umulh(unsigned __int64 _a, unsigned __int64 _b);
# pragma intrinsic(__umulh)
# endif // BX_ARCH_64BIT
#endif // BX_COMPILER_MSVC
@@ -232,7 +235,6 @@ namespace bx
return ceilT<double>(_a);
}
#if BX_SIMD_SUPPORTED
inline BX_CONST_FUNC float truncSimd(float _a)
{
const simd128_t aa = simd_splat<simd128_t>(_a);
@@ -287,7 +289,6 @@ namespace bx
return out[0];
}
#endif // BX_SIMD_SUPPORTED
inline BX_CONSTEXPR_FUNC float roundRef(float _a)
{
@@ -299,7 +300,6 @@ namespace bx
return roundT<double>(_a);
}
#if BX_SIMD_SUPPORTED
inline BX_CONST_FUNC float roundSimd(float _a)
{
const simd128_t aa = simd_splat<simd128_t>(_a);
@@ -321,7 +321,6 @@ namespace bx
return out[0];
}
#endif // BX_SIMD_SUPPORTED
inline BX_CONSTEXPR_FUNC float lerp(float _a, float _b, float _t)
{
@@ -1084,16 +1083,15 @@ BX_FP_PRECISE_BEGIN()
inline BX_CONSTEXPR_FUNC float trunc(float _a)
{
#if BX_SIMD_SUPPORTED
if (isConstantEvaluated() )
if constexpr (kSimdSupported)
{
return truncRef(_a);
if (!isConstantEvaluated() )
{
return truncSimd(_a);
}
}
return truncSimd(_a);
#else
return truncRef(_a);
#endif // BX_SIMD_SUPPORTED
}
inline BX_CONSTEXPR_FUNC double trunc(double _a)
@@ -1103,86 +1101,80 @@ BX_FP_PRECISE_BEGIN()
inline BX_CONSTEXPR_FUNC float floor(float _a)
{
#if BX_SIMD_SUPPORTED
if (isConstantEvaluated() )
if constexpr (kSimdSupported)
{
return floorRef(_a);
if (!isConstantEvaluated() )
{
return floorSimd(_a);
}
}
return floorSimd(_a);
#else
return floorRef(_a);
#endif // BX_SIMD_SUPPORTED
}
inline BX_CONSTEXPR_FUNC double floor(double _a)
{
#if BX_SIMD_SUPPORTED
if (isConstantEvaluated() )
if constexpr (kSimdSupported)
{
return floorRef(_a);
if (!isConstantEvaluated() )
{
return floorSimd(_a);
}
}
return floorSimd(_a);
#else
return floorRef(_a);
#endif // BX_SIMD_SUPPORTED
}
inline BX_CONSTEXPR_FUNC float ceil(float _a)
{
#if BX_SIMD_SUPPORTED
if (isConstantEvaluated() )
if constexpr (kSimdSupported)
{
return ceilRef(_a);
if (!isConstantEvaluated() )
{
return ceilSimd(_a);
}
}
return ceilSimd(_a);
#else
return ceilRef(_a);
#endif // BX_SIMD_SUPPORTED
}
inline BX_CONSTEXPR_FUNC double ceil(double _a)
{
#if BX_SIMD_SUPPORTED
if (isConstantEvaluated() )
if constexpr (kSimdSupported)
{
return ceilRef(_a);
if (!isConstantEvaluated() )
{
return ceilSimd(_a);
}
}
return ceilSimd(_a);
#else
return ceilRef(_a);
#endif // BX_SIMD_SUPPORTED
}
inline BX_CONSTEXPR_FUNC float round(float _a)
{
#if BX_SIMD_SUPPORTED
if (isConstantEvaluated() )
if constexpr (kSimdSupported)
{
return roundRef(_a);
if (!isConstantEvaluated() )
{
return roundSimd(_a);
}
}
return roundSimd(_a);
#else
return roundRef(_a);
#endif // BX_SIMD_SUPPORTED
}
inline BX_CONSTEXPR_FUNC double round(double _a)
{
#if BX_SIMD_SUPPORTED
if (isConstantEvaluated() )
if constexpr (kSimdSupported)
{
return roundRef(_a);
if (!isConstantEvaluated() )
{
return roundSimd(_a);
}
}
return roundSimd(_a);
#else
return roundRef(_a);
#endif // BX_SIMD_SUPPORTED
}
inline BX_CONSTEXPR_FUNC float fract(float _a)
@@ -1478,24 +1470,46 @@ BX_FP_PRECISE_BEGIN()
return result;
}
inline BX_CONSTEXPR_FUNC uint64_t mulHi64Ref(uint64_t _a, uint64_t _b)
{
const simd64_t loMask = simd64_splat(uint64_t(UINT32_MAX) );
const simd64_t aa = simd64_splat(_a);
const simd64_t bb = simd64_splat(_b);
const simd64_t aLo = simd64_and(aa, loMask);
const simd64_t aHi = simd64_x64_srl(aa, 32);
const simd64_t bLo = simd64_and(bb, loMask);
const simd64_t bHi = simd64_x64_srl(bb, 32);
const simd64_t ll = simd64_u64_mul(aLo, bLo);
const simd64_t lh = simd64_u64_mul(aLo, bHi);
const simd64_t hl = simd64_u64_mul(aHi, bLo);
const simd64_t hh = simd64_u64_mul(aHi, bHi);
const simd64_t llHi = simd64_x64_srl(ll, 32);
const simd64_t lhLo = simd64_and(lh, loMask);
const simd64_t hlLo = simd64_and(hl, loMask);
const simd64_t mid0 = simd64_u64_add(llHi, lhLo);
const simd64_t mid = simd64_u64_add(mid0, hlLo);
const simd64_t lhHi = simd64_x64_srl(lh, 32);
const simd64_t hlHi = simd64_x64_srl(hl, 32);
const simd64_t midHi = simd64_x64_srl(mid, 32);
const simd64_t sum0 = simd64_u64_add(hh, lhHi);
const simd64_t sum1 = simd64_u64_add(sum0, hlHi);
const simd64_t result = simd64_u64_add(sum1, midHi);
return result.u64;
}
inline BX_CONSTEXPR_FUNC uint64_t mulHi64(uint64_t _a, uint64_t _b)
{
constexpr uint64_t kLoMask = UINT64_C(0xffffffff);
if (!isConstantEvaluated() )
{
#if BX_COMPILER_MSVC && BX_ARCH_64BIT
return __umulh(_a, _b);
#elif (BX_COMPILER_GCC || BX_COMPILER_CLANG) && BX_ARCH_64BIT
return uint64_t( ( (unsigned __int128)_a * _b)>>64);
#endif // BX_COMPILER_*
}
const uint64_t aLo = _a & kLoMask;
const uint64_t aHi = _a >> 32;
const uint64_t bLo = _b & kLoMask;
const uint64_t bHi = _b >> 32;
const uint64_t ll = aLo * bLo;
const uint64_t lh = aLo * bHi;
const uint64_t hl = aHi * bLo;
const uint64_t hh = aHi * bHi;
const uint64_t mid = (ll >> 32) + (lh & kLoMask) + (hl & kLoMask);
const uint64_t result = hh + (lh >> 32) + (hl >> 32) + (mid >> 32);
return result;
return mulHi64Ref(_a, _b);
}
inline BX_CONSTEXPR_FUNC uint64_t twoOverPiWord(int32_t _index)
@@ -2751,16 +2765,15 @@ BX_FP_PRECISE_END()
inline BX_CONSTEXPR_FUNC float rsqrt(float _a)
{
#if BX_SIMD_SUPPORTED
if (isConstantEvaluated() )
if constexpr (kSimdSupported)
{
return rsqrtRef(_a);
if (!isConstantEvaluated() )
{
return rsqrtSimd(_a);
}
}
return rsqrtSimd(_a);
#else
return rsqrtRef(_a);
#endif // BX_SIMD_SUPPORTED
}
inline BX_CONSTEXPR_FUNC double rsqrt(double _a)
@@ -2770,30 +2783,28 @@ BX_FP_PRECISE_END()
inline BX_CONSTEXPR_FUNC float sqrt(float _a)
{
#if BX_SIMD_SUPPORTED
if (isConstantEvaluated() )
if constexpr (kSimdSupported)
{
return sqrtRef(_a);
if (!isConstantEvaluated() )
{
return sqrtSimd(_a);
}
}
return sqrtSimd(_a);
#else
return sqrtRef(_a);
#endif // BX_SIMD_SUPPORTED
}
inline BX_CONSTEXPR_FUNC double sqrt(double _a)
{
#if BX_SIMD_SUPPORTED
if (isConstantEvaluated() )
if constexpr (kSimdSupported)
{
return sqrtRef(_a);
if (!isConstantEvaluated() )
{
return sqrtSimd(_a);
}
}
return sqrtSimd(_a);
#else
return sqrtRef(_a);
#endif // BX_SIMD_SUPPORTED
}
inline BX_CONSTEXPR_FUNC bool isEqual(float _a, float _b, float _epsilon)
+9
View File
@@ -168,6 +168,15 @@ namespace bx
///
BX_CONSTEXPR_FUNC double bitsToDouble(uint64_t _a);
/// Returns the high 64 bits of the 128-bit product of _a and _b.
///
/// @param[in] _a First factor.
/// @param[in] _b Second factor.
///
/// @returns High 64 bits of `_a * _b`.
///
BX_CONSTEXPR_FUNC uint64_t mulHi64(uint64_t _a, uint64_t _b);
/// Format constants and bit access for a floating-point type.
template<typename Ty>
struct FloatT;
+44 -24
View File
@@ -244,13 +244,18 @@ namespace bx
void memCopy(void* _dst, const void* _src, size_t _numBytes)
{
#if BX_SIMD_SUPPORTED
memCopySimd(_dst, _src, _numBytes);
#elif BX_CRT_NONE
memCopyRef(_dst, _src, _numBytes);
if constexpr (kSimdSupported)
{
memCopySimd(_dst, _src, _numBytes);
}
else
{
#if BX_CRT_NONE
memCopyRef(_dst, _src, _numBytes);
#else
::memcpy(_dst, _src, _numBytes);
#endif // BX_*
::memcpy(_dst, _src, _numBytes);
#endif // BX_CRT_NONE
}
}
void memCopy(
@@ -368,13 +373,18 @@ namespace bx
void memMove(void* _dst, const void* _src, size_t _numBytes)
{
#if BX_SIMD_SUPPORTED
memMoveSimd(_dst, _src, _numBytes);
#elif BX_CRT_NONE
memMoveRef(_dst, _src, _numBytes);
if constexpr (kSimdSupported)
{
memMoveSimd(_dst, _src, _numBytes);
}
else
{
#if BX_CRT_NONE
memMoveRef(_dst, _src, _numBytes);
#else
::memmove(_dst, _src, _numBytes);
#endif // BX_*
::memmove(_dst, _src, _numBytes);
#endif // BX_CRT_NONE
}
}
void memMove(
@@ -478,13 +488,18 @@ namespace bx
void memSet(void* _dst, uint8_t _ch, size_t _numBytes)
{
#if BX_SIMD_SUPPORTED
memSetSimd(_dst, _ch, _numBytes);
#elif BX_CRT_NONE
memSetRef(_dst, _ch, _numBytes);
if constexpr (kSimdSupported)
{
memSetSimd(_dst, _ch, _numBytes);
}
else
{
#if BX_CRT_NONE
memSetRef(_dst, _ch, _numBytes);
#else
::memset(_dst, _ch, _numBytes);
#endif // BX_*
::memset(_dst, _ch, _numBytes);
#endif // BX_CRT_NONE
}
}
void memSet(void* _dst, uint32_t _dstStride, uint8_t _ch, uint32_t _stride, uint32_t _num)
@@ -602,13 +617,18 @@ namespace bx
int32_t memCmp(const void* _lhs, const void* _rhs, size_t _numBytes)
{
#if BX_SIMD_SUPPORTED
return memCmpSimd(_lhs, _rhs, _numBytes);
#elif BX_CRT_NONE
return memCmpRef(_lhs, _rhs, _numBytes);
if constexpr (kSimdSupported)
{
return memCmpSimd(_lhs, _rhs, _numBytes);
}
else
{
#if BX_CRT_NONE
return memCmpRef(_lhs, _rhs, _numBytes);
#else
return ::memcmp(_lhs, _rhs, _numBytes);
#endif // BX_*
return ::memcmp(_lhs, _rhs, _numBytes);
#endif // BX_CRT_NONE
}
}
///
+23
View File
@@ -1841,3 +1841,26 @@ TEST_CASE("limits", "[math]")
STATIC_REQUIRE(bx::kFloatSmallest == std::numeric_limits<float>::min() );
STATIC_REQUIRE(bx::kDoubleSmallest == std::numeric_limits<double>::min() );
}
TEST_CASE("mulHi64", "[math]")
{
STATIC_REQUIRE(0 == bx::mulHi64(0, 0) );
STATIC_REQUIRE(0 == bx::mulHi64(UINT64_MAX, 0) );
STATIC_REQUIRE(0 == bx::mulHi64(UINT64_MAX, 1) );
STATIC_REQUIRE(1 == bx::mulHi64(UINT64_C(1)<<32, UINT64_C(1)<<32) );
STATIC_REQUIRE(UINT64_MAX-1 == bx::mulHi64(UINT64_MAX, UINT64_MAX) );
STATIC_REQUIRE(UINT64_C(0x7641f3080ff92329) == bx::mulHi64(UINT64_C(0x9e3779b97f4a7c15), UINT64_C(0xbf58476d1ce4e5b9) ) );
REQUIRE(UINT64_MAX-1 == bx::mulHi64(UINT64_MAX, UINT64_MAX) );
REQUIRE(UINT64_C(0x7641f3080ff92329) == bx::mulHi64(UINT64_C(0x9e3779b97f4a7c15), UINT64_C(0xbf58476d1ce4e5b9) ) );
bx::RngMwc rng;
for (uint32_t ii = 0; ii < 100000; ++ii)
{
const uint64_t aa = (uint64_t(rng.gen() )<<32) | rng.gen();
const uint64_t bb = (uint64_t(rng.gen() )<<32) | rng.gen();
REQUIRE(bx::mulHi64Ref(aa, bb) == bx::mulHi64(aa, bb) );
}
}