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

Function libdivide_internal_u32_gen

numpy/core/include/numpy/libdivide/libdivide.h:555–603  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

553////////// UINT32
554
555static inline struct libdivide_u32_t libdivide_internal_u32_gen(uint32_t d, int branchfree) {
556 if (d == 0) {
557 LIBDIVIDE_ERROR("divider must be != 0");
558 }
559
560 struct libdivide_u32_t result;
561 uint32_t floor_log_2_d = 31 - libdivide_count_leading_zeros32(d);
562
563 // Power of 2
564 if ((d & (d - 1)) == 0) {
565 // We need to subtract 1 from the shift value in case of an unsigned
566 // branchfree divider because there is a hardcoded right shift by 1
567 // in its division algorithm. Because of this we also need to add back
568 // 1 in its recovery algorithm.
569 result.magic = 0;
570 result.more = (uint8_t)(floor_log_2_d - (branchfree != 0));
571 } else {
572 uint8_t more;
573 uint32_t rem, proposed_m;
574 proposed_m = libdivide_64_div_32_to_32(1U << floor_log_2_d, 0, d, &rem);
575
576 LIBDIVIDE_ASSERT(rem > 0 && rem < d);
577 const uint32_t e = d - rem;
578
579 // This power works if e < 2**floor_log_2_d.
580 if (!branchfree && (e < (1U << floor_log_2_d))) {
581 // This power works
582 more = floor_log_2_d;
583 } else {
584 // We have to use the general 33-bit algorithm. We need to compute
585 // (2**power) / d. However, we already have (2**(power-1))/d and
586 // its remainder. By doubling both, and then correcting the
587 // remainder, we can compute the larger division.
588 // don't care about overflow here - in fact, we expect it
589 proposed_m += proposed_m;
590 const uint32_t twice_rem = rem + rem;
591 if (twice_rem >= d || twice_rem < rem) proposed_m += 1;
592 more = floor_log_2_d | LIBDIVIDE_ADD_MARKER;
593 }
594 result.magic = 1 + proposed_m;
595 result.more = more;
596 // result.more's shift should in general be ceil_log_2_d. But if we
597 // used the smaller power, we subtract one from the shift because we're
598 // using the smaller power. If we're using the larger power, we
599 // subtract one from the shift because it's taken care of by the add
600 // indicator. So floor_log_2_d happens to be correct in both cases.
601 }
602 return result;
603}
604
605struct libdivide_u32_t libdivide_u32_gen(uint32_t d) {
606 return libdivide_internal_u32_gen(d, 0);

Callers 2

libdivide_u32_genFunction · 0.85

Calls 2

Tested by

no test coverage detected