divide each unsigned 64-bit element by a divisor (round towards zero)
| 200 | } |
| 201 | // divide each unsigned 64-bit element by a divisor (round towards zero) |
| 202 | NPY_FINLINE npyv_s64 npyv_divc_s64(npyv_s64 a, const npyv_s64x3 divisor) |
| 203 | { |
| 204 | const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]); |
| 205 | // high part of unsigned multiplication |
| 206 | __m256i mulhi = npyv__mullhi_u64(a, divisor.val[0]); |
| 207 | // convert unsigned to signed high multiplication |
| 208 | // mulhi - ((a < 0) ? m : 0) - ((m < 0) ? a : 0); |
| 209 | __m256i asign = _mm256_cmpgt_epi64(_mm256_setzero_si256(), a); |
| 210 | __m256i msign = _mm256_cmpgt_epi64(_mm256_setzero_si256(), divisor.val[0]); |
| 211 | __m256i m_asign = _mm256_and_si256(divisor.val[0], asign); |
| 212 | __m256i a_msign = _mm256_and_si256(a, msign); |
| 213 | mulhi = _mm256_sub_epi64(mulhi, m_asign); |
| 214 | mulhi = _mm256_sub_epi64(mulhi, a_msign); |
| 215 | // q = (a + mulhi) >> sh |
| 216 | __m256i q = _mm256_add_epi64(a, mulhi); |
| 217 | // emulate arithmetic right shift |
| 218 | const __m256i sigb = npyv_setall_s64(1LL << 63); |
| 219 | q = _mm256_srl_epi64(_mm256_add_epi64(q, sigb), shf1); |
| 220 | q = _mm256_sub_epi64(q, _mm256_srl_epi64(sigb, shf1)); |
| 221 | // q = q - XSIGN(a) |
| 222 | // trunc(a/d) = (q ^ dsign) - dsign |
| 223 | q = _mm256_sub_epi64(q, asign); |
| 224 | q = _mm256_sub_epi64(_mm256_xor_si256(q, divisor.val[2]), divisor.val[2]); |
| 225 | return q; |
| 226 | } |
| 227 | /*************************** |
| 228 | * Division |
| 229 | ***************************/ |
nothing calls this directly
no test coverage detected