diff options
author | Hyun Jae Moon <hyunjaemoon@google.com> | 2024-02-03 00:30:41 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2024-02-03 00:30:41 +0000 |
commit | d3fcaefb69e16707f49c8d436f613be36f2929f4 (patch) | |
tree | f180a22cde2ef26fbc2b1c0d81d69f4bae8b34ac /src/sse2.rs | |
parent | ac77e74af6d4effbb7ce5fb5e34d050012158ddc (diff) | |
parent | 18bdbf00dc7d41bf4549b0542ced9c11d813e9b9 (diff) | |
download | glam-d3fcaefb69e16707f49c8d436f613be36f2929f4.tar.gz |
Revert^2 "Upgrade glam to 0.25.0" am: 18bdbf00dcemu-34-2-dev
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/glam/+/2946971
Change-Id: I7d7052ddb923335e7df96360e466612d92ef9545
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'src/sse2.rs')
-rw-r--r-- | src/sse2.rs | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/sse2.rs b/src/sse2.rs index e1e6b74..e31675a 100644 --- a/src/sse2.rs +++ b/src/sse2.rs @@ -3,6 +3,7 @@ use core::arch::x86::*; #[cfg(target_arch = "x86_64")] use core::arch::x86_64::*; +#[repr(C)] union UnionCast { u32x4: [u32; 4], f32x4: [f32; 4], @@ -17,6 +18,7 @@ const fn m128_from_u32x4(u32x4: [u32; 4]) -> __m128 { unsafe { UnionCast { u32x4 }.m128 } } +const PS_ABS_MASK: __m128 = m128_from_u32x4([0x7fffffff; 4]); const PS_INV_SIGN_MASK: __m128 = m128_from_u32x4([!0x8000_0000; 4]); const PS_SIGN_MASK: __m128 = m128_from_u32x4([0x8000_0000; 4]); const PS_NO_FRACTION: __m128 = m128_from_f32x4([8388608.0; 4]); @@ -156,6 +158,25 @@ pub(crate) unsafe fn m128_round(v: __m128) -> __m128 { _mm_xor_ps(r1, r2) } +#[inline] +pub(crate) unsafe fn m128_trunc(v: __m128) -> __m128 { + // Based on https://github.com/microsoft/DirectXMath `XMVectorTruncate` + // To handle NAN, INF and numbers greater than 8388608, use masking + // Get the abs value + let mut vtest = _mm_and_si128(_mm_castps_si128(v), _mm_castps_si128(PS_ABS_MASK)); + // Test for greater than 8388608 (All floats with NO fractionals, NAN and INF + vtest = _mm_cmplt_epi32(vtest, _mm_castps_si128(PS_NO_FRACTION)); + // Convert to int and back to float for rounding with truncation + let vint = _mm_cvttps_epi32(v); + // Convert back to floats + let mut vresult = _mm_cvtepi32_ps(vint); + // All numbers less than 8388608 will use the round to int + vresult = _mm_and_ps(vresult, _mm_castsi128_ps(vtest)); + // All others, use the ORIGINAL value + vtest = _mm_andnot_si128(vtest, _mm_castps_si128(v)); + _mm_or_ps(vresult, _mm_castsi128_ps(vtest)) +} + /// Returns a vector whose components are the corresponding components of Angles modulo 2PI. #[inline] pub(crate) unsafe fn m128_mod_angles(angles: __m128) -> __m128 { |