2023-05-10 21:19:54 -07:00
|
|
|
|
#ifndef COSMOPOLITAN_LIBC_TINYMATH_MAGICU_H_
|
|
|
|
|
#define COSMOPOLITAN_LIBC_TINYMATH_MAGICU_H_
|
|
|
|
|
COSMOPOLITAN_C_START_
|
|
|
|
|
|
|
|
|
|
struct magicu {
|
|
|
|
|
uint32_t M;
|
|
|
|
|
uint32_t s;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct magicu __magicu_get(uint32_t);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Performs fast division using precomputed magic for constant divisor.
|
|
|
|
|
*
|
|
|
|
|
* @param x is unsigned integer that shall be divided
|
|
|
|
|
* @param d should be `__magicu_get(y)` if computing `x / y`
|
|
|
|
|
* @return result of unsigned integer division
|
|
|
|
|
*/
|
2023-05-15 16:32:10 -07:00
|
|
|
|
forceinline uint32_t __magicu_div(uint32_t x, struct magicu d) {
|
2023-05-10 21:19:54 -07:00
|
|
|
|
return ((((uint64_t)x * d.M) >> 32) + ((d.s & 64) ? x : 0)) >> (d.s & 63);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-18 19:05:08 -07:00
|
|
|
|
/**
|
|
|
|
|
* Checks if 𝑑 contains a valid initialized divisor.
|
|
|
|
|
*/
|
2023-11-15 20:57:18 -08:00
|
|
|
|
static inline bool32 __magicu_valid(struct magicu d) {
|
2024-06-15 13:34:48 -07:00
|
|
|
|
if (!d.M && !d.s)
|
|
|
|
|
return false; /* uninitialized */
|
|
|
|
|
if (d.s & ~(64 | 63))
|
|
|
|
|
return false; /* corrupted */
|
2023-05-18 19:05:08 -07:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-10 21:19:54 -07:00
|
|
|
|
COSMOPOLITAN_C_END_
|
|
|
|
|
#endif /* COSMOPOLITAN_LIBC_TINYMATH_MAGICU_H_ */
|