returns the high 64 bits of unsigned 64-bit multiplication xref https://stackoverflow.com/a/28827013
| 196 | // returns the high 64 bits of unsigned 64-bit multiplication |
| 197 | // xref https://stackoverflow.com/a/28827013 |
| 198 | NPY_FINLINE npyv_u64 npyv__mullhi_u64(npyv_u64 a, npyv_u64 b) |
| 199 | { |
| 200 | __m128i lomask = npyv_setall_s64(0xffffffff); |
| 201 | __m128i a_hi = _mm_srli_epi64(a, 32); // a0l, a0h, a1l, a1h |
| 202 | __m128i b_hi = _mm_srli_epi64(b, 32); // b0l, b0h, b1l, b1h |
| 203 | // compute partial products |
| 204 | __m128i w0 = _mm_mul_epu32(a, b); // a0l*b0l, a1l*b1l |
| 205 | __m128i w1 = _mm_mul_epu32(a, b_hi); // a0l*b0h, a1l*b1h |
| 206 | __m128i w2 = _mm_mul_epu32(a_hi, b); // a0h*b0l, a1h*b0l |
| 207 | __m128i w3 = _mm_mul_epu32(a_hi, b_hi); // a0h*b0h, a1h*b1h |
| 208 | // sum partial products |
| 209 | __m128i w0h = _mm_srli_epi64(w0, 32); |
| 210 | __m128i s1 = _mm_add_epi64(w1, w0h); |
| 211 | __m128i s1l = _mm_and_si128(s1, lomask); |
| 212 | __m128i s1h = _mm_srli_epi64(s1, 32); |
| 213 | |
| 214 | __m128i s2 = _mm_add_epi64(w2, s1l); |
| 215 | __m128i s2h = _mm_srli_epi64(s2, 32); |
| 216 | |
| 217 | __m128i hi = _mm_add_epi64(w3, s1h); |
| 218 | hi = _mm_add_epi64(hi, s2h); |
| 219 | return hi; |
| 220 | } |
| 221 | // divide each unsigned 64-bit element by a precomputed divisor |
| 222 | NPY_FINLINE npyv_u64 npyv_divc_u64(npyv_u64 a, const npyv_u64x3 divisor) |
| 223 | { |
no test coverage detected