| 1123 | } |
| 1124 | |
| 1125 | int64_t libdivide_s64_do(int64_t numer, const struct libdivide_s64_t *denom) { |
| 1126 | uint8_t more = denom->more; |
| 1127 | uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; |
| 1128 | |
| 1129 | if (!denom->magic) { // shift path |
| 1130 | uint64_t mask = (1ULL << shift) - 1; |
| 1131 | uint64_t uq = numer + ((numer >> 63) & mask); |
| 1132 | int64_t q = (int64_t)uq; |
| 1133 | q >>= shift; |
| 1134 | // must be arithmetic shift and then sign-extend |
| 1135 | int64_t sign = (int8_t)more >> 7; |
| 1136 | q = (q ^ sign) - sign; |
| 1137 | return q; |
| 1138 | } else { |
| 1139 | uint64_t uq = (uint64_t)libdivide_mullhi_s64(denom->magic, numer); |
| 1140 | if (more & LIBDIVIDE_ADD_MARKER) { |
| 1141 | // must be arithmetic shift and then sign extend |
| 1142 | int64_t sign = (int8_t)more >> 7; |
| 1143 | // q += (more < 0 ? -numer : numer) |
| 1144 | // cast required to avoid UB |
| 1145 | uq += ((uint64_t)numer ^ sign) - sign; |
| 1146 | } |
| 1147 | int64_t q = (int64_t)uq; |
| 1148 | q >>= shift; |
| 1149 | q += (q < 0); |
| 1150 | return q; |
| 1151 | } |
| 1152 | } |
| 1153 | |
| 1154 | int64_t libdivide_s64_branchfree_do(int64_t numer, const struct libdivide_s64_branchfree_t *denom) { |
| 1155 | uint8_t more = denom->more; |
nothing calls this directly
no test coverage detected