Initializing divisor parameters for unsigned 8-bit division
| 181 | } |
| 182 | // Initializing divisor parameters for unsigned 8-bit division |
| 183 | NPY_FINLINE npyv_u8x3 npyv_divisor_u8(npy_uint8 d) |
| 184 | { |
| 185 | unsigned l, l2, sh1, sh2, m; |
| 186 | switch (d) { |
| 187 | case 0: // LCOV_EXCL_LINE |
| 188 | // for potential divide by zero, On x86 GCC inserts `ud2` instruction |
| 189 | // instead of letting the HW/CPU trap it which leads to illegal instruction exception. |
| 190 | // 'volatile' should suppress this behavior and allow us to raise HW/CPU |
| 191 | // arithmetic exception. |
| 192 | m = sh1 = sh2 = 1 / ((npy_uint8 volatile *)&d)[0]; |
| 193 | break; |
| 194 | case 1: |
| 195 | m = 1; sh1 = sh2 = 0; |
| 196 | break; |
| 197 | case 2: |
| 198 | m = 1; sh1 = 1; sh2 = 0; |
| 199 | break; |
| 200 | default: |
| 201 | l = npyv__bitscan_revnz_u32(d - 1) + 1; // ceil(log2(d)) |
| 202 | l2 = (npy_uint8)(1 << l); // 2^l, overflow to 0 if l = 8 |
| 203 | m = ((npy_uint16)((l2 - d) << 8)) / d + 1; // multiplier |
| 204 | sh1 = 1; sh2 = l - 1; // shift counts |
| 205 | } |
| 206 | npyv_u8x3 divisor; |
| 207 | #ifdef NPY_HAVE_SSE2 // SSE/AVX2/AVX512 |
| 208 | divisor.val[0] = npyv_setall_u16(m); |
| 209 | divisor.val[1] = npyv_set_u8(sh1); |
| 210 | divisor.val[2] = npyv_set_u8(sh2); |
| 211 | #elif defined(NPY_HAVE_VSX2) || defined(NPY_HAVE_VX) |
| 212 | divisor.val[0] = npyv_setall_u8(m); |
| 213 | divisor.val[1] = npyv_setall_u8(sh1); |
| 214 | divisor.val[2] = npyv_setall_u8(sh2); |
| 215 | #elif defined(NPY_HAVE_NEON) |
| 216 | divisor.val[0] = npyv_setall_u8(m); |
| 217 | divisor.val[1] = npyv_reinterpret_u8_s8(npyv_setall_s8(-sh1)); |
| 218 | divisor.val[2] = npyv_reinterpret_u8_s8(npyv_setall_s8(-sh2)); |
| 219 | #else |
| 220 | #error "please initialize the shifting operand for the new architecture" |
| 221 | #endif |
| 222 | return divisor; |
| 223 | } |
| 224 | // Initializing divisor parameters for signed 8-bit division |
| 225 | NPY_FINLINE npyv_s16x3 npyv_divisor_s16(npy_int16 d); |
| 226 | NPY_FINLINE npyv_s8x3 npyv_divisor_s8(npy_int8 d) |
nothing calls this directly
no test coverage detected