| 954 | } |
| 955 | |
| 956 | int32_t libdivide_s32_do(int32_t numer, const struct libdivide_s32_t *denom) { |
| 957 | uint8_t more = denom->more; |
| 958 | uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; |
| 959 | |
| 960 | if (!denom->magic) { |
| 961 | uint32_t sign = (int8_t)more >> 7; |
| 962 | uint32_t mask = (1U << shift) - 1; |
| 963 | uint32_t uq = numer + ((numer >> 31) & mask); |
| 964 | int32_t q = (int32_t)uq; |
| 965 | q >>= shift; |
| 966 | q = (q ^ sign) - sign; |
| 967 | return q; |
| 968 | } else { |
| 969 | uint32_t uq = (uint32_t)libdivide_mullhi_s32(denom->magic, numer); |
| 970 | if (more & LIBDIVIDE_ADD_MARKER) { |
| 971 | // must be arithmetic shift and then sign extend |
| 972 | int32_t sign = (int8_t)more >> 7; |
| 973 | // q += (more < 0 ? -numer : numer) |
| 974 | // cast required to avoid UB |
| 975 | uq += ((uint32_t)numer ^ sign) - sign; |
| 976 | } |
| 977 | int32_t q = (int32_t)uq; |
| 978 | q >>= shift; |
| 979 | q += (q < 0); |
| 980 | return q; |
| 981 | } |
| 982 | } |
| 983 | |
| 984 | int32_t libdivide_s32_branchfree_do(int32_t numer, const struct libdivide_s32_branchfree_t *denom) { |
| 985 | uint8_t more = denom->more; |
nothing calls this directly
no test coverage detected