mirror of
https://github.com/bkaradzic/bx.git
synced 2026-10-30 04:25:47 +00:00
Added mulHi64 intrinsics. (#477)
This commit is contained in:
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
@@ -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) );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user