* @brief Count the leading zeros for each lane in @c a. * * Valid for all data values of @c a; will return a per-lane value [0, 32]. */
| 459 | * Valid for all data values of @c a; will return a per-lane value [0, 32]. |
| 460 | */ |
| 461 | static ASTCENC_SIMD_INLINE vint4 clz(vint4 a) |
| 462 | { |
| 463 | // This function is a horrible abuse of floating point exponents to convert |
| 464 | // the original integer value into a 2^N encoding we can recover easily. |
| 465 | |
| 466 | // Convert to float without risk of rounding up by keeping only top 8 bits. |
| 467 | // This trick is guaranteed to keep top 8 bits and clear the 9th. |
| 468 | a = (~lsr<8>(a)) & a; |
| 469 | a = float_as_int(int_to_float(a)); |
| 470 | |
| 471 | // Extract and unbias exponent |
| 472 | a = vint4(127 + 31) - lsr<23>(a); |
| 473 | |
| 474 | // Clamp result to a valid 32-bit range |
| 475 | return clamp(0, 32, a); |
| 476 | } |
| 477 | |
| 478 | /** |
| 479 | * @brief Return lanewise 2^a for each lane in @c a. |