divide each signed 64-bit element by a precomputed divisor (round towards zero)
| 232 | } |
| 233 | // divide each signed 64-bit element by a precomputed divisor (round towards zero) |
| 234 | NPY_FINLINE npyv_s64 npyv_divc_s64(npyv_s64 a, const npyv_s64x3 divisor) |
| 235 | { |
| 236 | // high part of unsigned multiplication |
| 237 | __m128i mulhi = npyv__mullhi_u64(a, divisor.val[0]); |
| 238 | // convert unsigned to signed high multiplication |
| 239 | // mulhi - ((a < 0) ? m : 0) - ((m < 0) ? a : 0); |
| 240 | #ifdef NPY_HAVE_SSE42 |
| 241 | const __m128i msign= _mm_cmpgt_epi64(_mm_setzero_si128(), divisor.val[0]); |
| 242 | __m128i asign = _mm_cmpgt_epi64(_mm_setzero_si128(), a); |
| 243 | #else |
| 244 | const __m128i msign= _mm_srai_epi32(_mm_shuffle_epi32(divisor.val[0], _MM_SHUFFLE(3, 3, 1, 1)), 31); |
| 245 | __m128i asign = _mm_srai_epi32(_mm_shuffle_epi32(a, _MM_SHUFFLE(3, 3, 1, 1)), 31); |
| 246 | #endif |
| 247 | __m128i m_asign = _mm_and_si128(divisor.val[0], asign); |
| 248 | __m128i a_msign = _mm_and_si128(a, msign); |
| 249 | mulhi = _mm_sub_epi64(mulhi, m_asign); |
| 250 | mulhi = _mm_sub_epi64(mulhi, a_msign); |
| 251 | // q = (a + mulhi) >> sh |
| 252 | __m128i q = _mm_add_epi64(a, mulhi); |
| 253 | // emulate arithmetic right shift |
| 254 | const __m128i sigb = npyv_setall_s64(1LL << 63); |
| 255 | q = _mm_srl_epi64(_mm_add_epi64(q, sigb), divisor.val[1]); |
| 256 | q = _mm_sub_epi64(q, _mm_srl_epi64(sigb, divisor.val[1])); |
| 257 | // q = q - XSIGN(a) |
| 258 | // trunc(a/d) = (q ^ dsign) - dsign |
| 259 | q = _mm_sub_epi64(q, asign); |
| 260 | q = _mm_sub_epi64(_mm_xor_si128(q, divisor.val[2]), divisor.val[2]); |
| 261 | return q; |
| 262 | } |
| 263 | /*************************** |
| 264 | * Division |
| 265 | ***************************/ |
nothing calls this directly
no test coverage detected