Add a helper for least common multiple For one number being a power of two. Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/kern/include/common.h b/kern/include/common.h index 5086bfc..a9f6c79 100644 --- a/kern/include/common.h +++ b/kern/include/common.h
@@ -79,6 +79,29 @@ #ifndef __ASSEMBLER__ +/* Returns the least common multiple of x and p2; p2 is a power of 2. Returns 0 + * on error, including non-power-of-2, overflow, or a 0 input. */ +static inline unsigned long LCM_PWR2(unsigned long x, unsigned long p2) +{ + /* All multiples of p2, which has exactly one bit set, will have zeros + * for the bits below its set bit. The LCM will be x, shifted left as + * little as possible, such that it has no bits below p2's set bit. + * Each shift is a multiplication by 2, which is the only prime factor + * if p2. */ + int p2_bit, x_first_bit; + unsigned long ret; + + if (!x || !IS_PWR2(p2)) + return 0; + p2_bit = __builtin_ffsl(p2); + x_first_bit = __builtin_ffsl(x); + if (x_first_bit >= p2_bit) + return x; + if (check_shl_overflow(x, p2_bit - x_first_bit, &ret)) + return 0; + return ret; +} + static inline uint32_t low32(uint64_t val) { return val & 0xffffffff;