MCPcopy Create free account
hub / github.com/numpy/numpy / npyv_divc_s64

Function npyv_divc_s64

numpy/core/src/common/simd/sse/arithmetic.h:234–262  ·  view source on GitHub ↗

divide each signed 64-bit element by a precomputed divisor (round towards zero)

Source from the content-addressed store, hash-verified

232}
233// divide each signed 64-bit element by a precomputed divisor (round towards zero)
234NPY_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 ***************************/

Callers

nothing calls this directly

Calls 2

npyv__mullhi_u64Function · 0.70
npyv_setall_s64Function · 0.70

Tested by

no test coverage detected