| 178 | 2^XSUM_LOW_MANTISSA_BITS - 1. */ |
| 179 | |
| 180 | static NOINLINE int xsum_carry_propagate (xsum_small_accumulator *restrict sacc) |
| 181 | { |
| 182 | int i, u, uix; |
| 183 | |
| 184 | if (xsum_debug) c_printf("\nCARRY PROPAGATING IN SMALL ACCUMULATOR\n"); |
| 185 | |
| 186 | /* Set u to the index of the uppermost non-zero (for now) chunk, or |
| 187 | return with value 0 if there is none. */ |
| 188 | |
| 189 | # if OPT_CARRY |
| 190 | |
| 191 | { u = XSUM_SCHUNKS-1; |
| 192 | switch (XSUM_SCHUNKS & 0x3) /* get u to be a multiple of 4 minus one */ |
| 193 | { |
| 194 | case 3: if (sacc->chunk[u] != 0) |
| 195 | { goto found2; |
| 196 | } |
| 197 | u -= 1; /* XSUM_SCHUNKS is a */ |
| 198 | mxFallThrough; |
| 199 | case 2: if (sacc->chunk[u] != 0) /* constant, so the */ |
| 200 | { goto found2; /* compiler will do */ |
| 201 | } /* simple code here */ |
| 202 | u -= 1; |
| 203 | mxFallThrough; |
| 204 | case 1: if (sacc->chunk[u] != 0) |
| 205 | { goto found2; |
| 206 | } |
| 207 | u -= 1; |
| 208 | mxFallThrough; |
| 209 | case 0: ; |
| 210 | } |
| 211 | |
| 212 | do /* here, u should be a multiple of 4 minus one, and at least 3 */ |
| 213 | { |
| 214 | # if USE_SIMD && __AVX__ |
| 215 | { __m256i ch; |
| 216 | ch = _mm256_loadu_si256 ((__m256i *)(sacc->chunk+u-3)); |
| 217 | if (!_mm256_testz_si256(ch,ch)) |
| 218 | { goto found; |
| 219 | } |
| 220 | u -= 4; |
| 221 | if (u < 0) /* never actually happens, because value of XSUM_SCHUNKS */ |
| 222 | { break; /* is such that u < 0 occurs at end of do loop instead */ |
| 223 | } |
| 224 | ch = _mm256_loadu_si256 ((__m256i *)(sacc->chunk+u-3)); |
| 225 | if (!_mm256_testz_si256(ch,ch)) |
| 226 | { goto found; |
| 227 | } |
| 228 | u -= 4; |
| 229 | } |
| 230 | # else |
| 231 | { if (sacc->chunk[u] | sacc->chunk[u-1] |
| 232 | | sacc->chunk[u-2] | sacc->chunk[u-3]) |
| 233 | { goto found; |
| 234 | } |
| 235 | u -= 4; |
| 236 | } |
| 237 | # endif |
no test coverage detected