| 1006 | } |
| 1007 | |
| 1008 | int32_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 | |
| 1044 | int32_t libdivide_s32_branchfree_recover(const struct libdivide_s32_branchfree_t *denom) { |
| 1045 | return libdivide_s32_recover((const struct libdivide_s32_t *)denom); |
no outgoing calls
no test coverage detected