xref: /DragonStub/inc/dragonstub/linux/math.h (revision 823f04931913f01ee1fc0dc0c7876156ad150388)
1*823f0493SLoGin #pragma once
2*823f0493SLoGin 
3*823f0493SLoGin #include "../types.h"
4*823f0493SLoGin #include "div64.h"
5*823f0493SLoGin 
6*823f0493SLoGin /*
7*823f0493SLoGin  * This looks more complex than it should be. But we need to
8*823f0493SLoGin  * get the type for the ~ right in round_down (it needs to be
9*823f0493SLoGin  * as wide as the result!), and we want to evaluate the macro
10*823f0493SLoGin  * arguments just once each.
11*823f0493SLoGin  */
12*823f0493SLoGin #define __round_mask(x, y) ((__typeof__(x))((y)-1))
13*823f0493SLoGin 
14*823f0493SLoGin /**
15*823f0493SLoGin  * round_up - round up to next specified power of 2
16*823f0493SLoGin  * @x: the value to round
17*823f0493SLoGin  * @y: multiple to round up to (must be a power of 2)
18*823f0493SLoGin  *
19*823f0493SLoGin  * Rounds @x up to next multiple of @y (which must be a power of 2).
20*823f0493SLoGin  * To perform arbitrary rounding up, use roundup() below.
21*823f0493SLoGin  */
22*823f0493SLoGin #define round_up(x, y) ((((x)-1) | __round_mask(x, y)) + 1)
23*823f0493SLoGin 
24*823f0493SLoGin /**
25*823f0493SLoGin  * round_down - round down to next specified power of 2
26*823f0493SLoGin  * @x: the value to round
27*823f0493SLoGin  * @y: multiple to round down to (must be a power of 2)
28*823f0493SLoGin  *
29*823f0493SLoGin  * Rounds @x down to next multiple of @y (which must be a power of 2).
30*823f0493SLoGin  * To perform arbitrary rounding down, use rounddown() below.
31*823f0493SLoGin  */
32*823f0493SLoGin #define round_down(x, y) ((x) & ~__round_mask(x, y))
33*823f0493SLoGin 
34*823f0493SLoGin #define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP
35*823f0493SLoGin 
36*823f0493SLoGin #define DIV_ROUND_DOWN_ULL(ll, d)               \
37*823f0493SLoGin 	({                                      \
38*823f0493SLoGin 		unsigned long long _tmp = (ll); \
39*823f0493SLoGin 		do_div(_tmp, d);                \
40*823f0493SLoGin 		_tmp;                           \
41*823f0493SLoGin 	})
42*823f0493SLoGin 
43*823f0493SLoGin #define DIV_ROUND_UP_ULL(ll, d) \
44*823f0493SLoGin 	DIV_ROUND_DOWN_ULL((unsigned long long)(ll) + (d)-1, (d))
45*823f0493SLoGin 
46*823f0493SLoGin #if BITS_PER_LONG == 32
47*823f0493SLoGin #define DIV_ROUND_UP_SECTOR_T(ll, d) DIV_ROUND_UP_ULL(ll, d)
48*823f0493SLoGin #else
49*823f0493SLoGin #define DIV_ROUND_UP_SECTOR_T(ll, d) DIV_ROUND_UP(ll, d)
50*823f0493SLoGin #endif
51*823f0493SLoGin 
52*823f0493SLoGin /**
53*823f0493SLoGin  * roundup - round up to the next specified multiple
54*823f0493SLoGin  * @x: the value to up
55*823f0493SLoGin  * @y: multiple to round up to
56*823f0493SLoGin  *
57*823f0493SLoGin  * Rounds @x up to next multiple of @y. If @y will always be a power
58*823f0493SLoGin  * of 2, consider using the faster round_up().
59*823f0493SLoGin  */
60*823f0493SLoGin #define roundup(x, y)                            \
61*823f0493SLoGin 	({                                       \
62*823f0493SLoGin 		typeof(y) __y = y;               \
63*823f0493SLoGin 		(((x) + (__y - 1)) / __y) * __y; \
64*823f0493SLoGin 	})
65*823f0493SLoGin /**
66*823f0493SLoGin  * rounddown - round down to next specified multiple
67*823f0493SLoGin  * @x: the value to round
68*823f0493SLoGin  * @y: multiple to round down to
69*823f0493SLoGin  *
70*823f0493SLoGin  * Rounds @x down to next multiple of @y. If @y will always be a power
71*823f0493SLoGin  * of 2, consider using the faster round_down().
72*823f0493SLoGin  */
73*823f0493SLoGin #define rounddown(x, y)              \
74*823f0493SLoGin 	({                           \
75*823f0493SLoGin 		typeof(x) __x = (x); \
76*823f0493SLoGin 		__x - (__x % (y));   \
77*823f0493SLoGin 	})
78*823f0493SLoGin 
79*823f0493SLoGin /*
80*823f0493SLoGin  * Divide positive or negative dividend by positive or negative divisor
81*823f0493SLoGin  * and round to closest integer. Result is undefined for negative
82*823f0493SLoGin  * divisors if the dividend variable type is unsigned and for negative
83*823f0493SLoGin  * dividends if the divisor variable type is unsigned.
84*823f0493SLoGin  */
85*823f0493SLoGin #define DIV_ROUND_CLOSEST(x, divisor)                                \
86*823f0493SLoGin 	({                                                           \
87*823f0493SLoGin 		typeof(x) __x = x;                                   \
88*823f0493SLoGin 		typeof(divisor) __d = divisor;                       \
89*823f0493SLoGin 		(((typeof(x))-1) > 0 || ((typeof(divisor))-1) > 0 || \
90*823f0493SLoGin 		 (((__x) > 0) == ((__d) > 0))) ?                     \
91*823f0493SLoGin 			(((__x) + ((__d) / 2)) / (__d)) :            \
92*823f0493SLoGin 			(((__x) - ((__d) / 2)) / (__d));             \
93*823f0493SLoGin 	})
94*823f0493SLoGin /*
95*823f0493SLoGin  * Same as above but for u64 dividends. divisor must be a 32-bit
96*823f0493SLoGin  * number.
97*823f0493SLoGin  */
98*823f0493SLoGin #define DIV_ROUND_CLOSEST_ULL(x, divisor)                  \
99*823f0493SLoGin 	({                                                 \
100*823f0493SLoGin 		typeof(divisor) __d = divisor;             \
101*823f0493SLoGin 		unsigned long long _tmp = (x) + (__d) / 2; \
102*823f0493SLoGin 		do_div(_tmp, __d);                         \
103*823f0493SLoGin 		_tmp;                                      \
104*823f0493SLoGin 	})
105