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

Function libdivide_s32_recover

numpy/core/include/numpy/libdivide/libdivide.h:1008–1042  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1006}
1007
1008int32_t libdivide_s32_recover(const struct libdivide_s32_t *denom) {
1009 uint8_t more = denom->more;
1010 uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
1011 if (!denom->magic) {
1012 uint32_t absD = 1U << shift;
1013 if (more & LIBDIVIDE_NEGATIVE_DIVISOR) {
1014 absD = -absD;
1015 }
1016 return (int32_t)absD;
1017 } else {
1018 // Unsigned math is much easier
1019 // We negate the magic number only in the branchfull case, and we don't
1020 // know which case we're in. However we have enough information to
1021 // determine the correct sign of the magic number. The divisor was
1022 // negative if LIBDIVIDE_NEGATIVE_DIVISOR is set. If ADD_MARKER is set,
1023 // the magic number's sign is opposite that of the divisor.
1024 // We want to compute the positive magic number.
1025 int negative_divisor = (more & LIBDIVIDE_NEGATIVE_DIVISOR);
1026 int magic_was_negated = (more & LIBDIVIDE_ADD_MARKER)
1027 ? denom->magic > 0 : denom->magic < 0;
1028
1029 // Handle the power of 2 case (including branchfree)
1030 if (denom->magic == 0) {
1031 int32_t result = 1U << shift;
1032 return negative_divisor ? -result : result;
1033 }
1034
1035 uint32_t d = (uint32_t)(magic_was_negated ? -denom->magic : denom->magic);
1036 uint64_t n = 1ULL << (32 + shift); // this shift cannot exceed 30
1037 uint32_t q = (uint32_t)(n / d);
1038 int32_t result = (int32_t)q;
1039 result += 1;
1040 return negative_divisor ? -result : result;
1041 }
1042}
1043
1044int32_t libdivide_s32_branchfree_recover(const struct libdivide_s32_branchfree_t *denom) {
1045 return libdivide_s32_recover((const struct libdivide_s32_t *)denom);

Callers 1

Calls

no outgoing calls

Tested by

no test coverage detected