xref: /linux-6.15/include/linux/reciprocal_div.h (revision 6a2d7a95)
1*6a2d7a95SEric Dumazet #ifndef _LINUX_RECIPROCAL_DIV_H
2*6a2d7a95SEric Dumazet #define _LINUX_RECIPROCAL_DIV_H
3*6a2d7a95SEric Dumazet 
4*6a2d7a95SEric Dumazet #include <linux/types.h>
5*6a2d7a95SEric Dumazet 
6*6a2d7a95SEric Dumazet /*
7*6a2d7a95SEric Dumazet  * This file describes reciprocical division.
8*6a2d7a95SEric Dumazet  *
9*6a2d7a95SEric Dumazet  * This optimizes the (A/B) problem, when A and B are two u32
10*6a2d7a95SEric Dumazet  * and B is a known value (but not known at compile time)
11*6a2d7a95SEric Dumazet  *
12*6a2d7a95SEric Dumazet  * The math principle used is :
13*6a2d7a95SEric Dumazet  *   Let RECIPROCAL_VALUE(B) be (((1LL << 32) + (B - 1))/ B)
14*6a2d7a95SEric Dumazet  *   Then A / B = (u32)(((u64)(A) * (R)) >> 32)
15*6a2d7a95SEric Dumazet  *
16*6a2d7a95SEric Dumazet  * This replaces a divide by a multiply (and a shift), and
17*6a2d7a95SEric Dumazet  * is generally less expensive in CPU cycles.
18*6a2d7a95SEric Dumazet  */
19*6a2d7a95SEric Dumazet 
20*6a2d7a95SEric Dumazet /*
21*6a2d7a95SEric Dumazet  * Computes the reciprocal value (R) for the value B of the divisor.
22*6a2d7a95SEric Dumazet  * Should not be called before each reciprocal_divide(),
23*6a2d7a95SEric Dumazet  * or else the performance is slower than a normal divide.
24*6a2d7a95SEric Dumazet  */
25*6a2d7a95SEric Dumazet extern u32 reciprocal_value(u32 B);
26*6a2d7a95SEric Dumazet 
27*6a2d7a95SEric Dumazet 
28*6a2d7a95SEric Dumazet static inline u32 reciprocal_divide(u32 A, u32 R)
29*6a2d7a95SEric Dumazet {
30*6a2d7a95SEric Dumazet 	return (u32)(((u64)A * R) >> 32);
31*6a2d7a95SEric Dumazet }
32*6a2d7a95SEric Dumazet #endif
33