| 369 | #define npyv_trunc_f64(A) _mm_round_pd(A, _MM_FROUND_TO_ZERO) |
| 370 | #else |
| 371 | NPY_FINLINE npyv_f32 npyv_trunc_f32(npyv_f32 a) |
| 372 | { |
| 373 | const __m128 szero = _mm_set1_ps(-0.0f); |
| 374 | const __m128i exp_mask = _mm_set1_epi32(0xff000000); |
| 375 | |
| 376 | __m128i nfinite_mask = _mm_slli_epi32(_mm_castps_si128(a), 1); |
| 377 | nfinite_mask = _mm_and_si128(nfinite_mask, exp_mask); |
| 378 | nfinite_mask = _mm_cmpeq_epi32(nfinite_mask, exp_mask); |
| 379 | |
| 380 | // eliminate nans/inf to avoid invalid fp errors |
| 381 | __m128 x = _mm_xor_ps(a, _mm_castsi128_ps(nfinite_mask)); |
| 382 | __m128i trunci = _mm_cvttps_epi32(x); |
| 383 | __m128 trunc = _mm_cvtepi32_ps(trunci); |
| 384 | // respect signed zero, e.g. -0.5 -> -0.0 |
| 385 | trunc = _mm_or_ps(trunc, _mm_and_ps(a, szero)); |
| 386 | // if overflow return a |
| 387 | __m128i overflow_mask = _mm_cmpeq_epi32(trunci, _mm_castps_si128(szero)); |
| 388 | // a if a overflow or nonfinite |
| 389 | return npyv_select_f32(_mm_or_si128(nfinite_mask, overflow_mask), a, trunc); |
| 390 | } |
| 391 | NPY_FINLINE npyv_f64 npyv_trunc_f64(npyv_f64 a) |
| 392 | { |
| 393 | const __m128d one = _mm_set1_pd(1.0); |
nothing calls this directly
no test coverage detected