Branch data Line data Source code
1 : : #ifndef _LINUX_MATH64_H
2 : : #define _LINUX_MATH64_H
3 : :
4 : : #include <linux/types.h>
5 : : #include <asm/div64.h>
6 : :
7 : : #if BITS_PER_LONG == 64
8 : :
9 : : #define div64_long(x, y) div64_s64((x), (y))
10 : : #define div64_ul(x, y) div64_u64((x), (y))
11 : :
12 : : /**
13 : : * div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder
14 : : *
15 : : * This is commonly provided by 32bit archs to provide an optimized 64bit
16 : : * divide.
17 : : */
18 : : static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
19 : : {
20 : : *remainder = dividend % divisor;
21 : : return dividend / divisor;
22 : : }
23 : :
24 : : /**
25 : : * div_s64_rem - signed 64bit divide with 32bit divisor with remainder
26 : : */
27 : : static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
28 : : {
29 : : *remainder = dividend % divisor;
30 : : return dividend / divisor;
31 : : }
32 : :
33 : : /**
34 : : * div64_u64_rem - unsigned 64bit divide with 64bit divisor and remainder
35 : : */
36 : : static inline u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder)
37 : : {
38 : : *remainder = dividend % divisor;
39 : : return dividend / divisor;
40 : : }
41 : :
42 : : /**
43 : : * div64_u64 - unsigned 64bit divide with 64bit divisor
44 : : */
45 : : static inline u64 div64_u64(u64 dividend, u64 divisor)
46 : : {
47 : : return dividend / divisor;
48 : : }
49 : :
50 : : /**
51 : : * div64_s64 - signed 64bit divide with 64bit divisor
52 : : */
53 : : static inline s64 div64_s64(s64 dividend, s64 divisor)
54 : : {
55 : : return dividend / divisor;
56 : : }
57 : :
58 : : #elif BITS_PER_LONG == 32
59 : :
60 : : #define div64_long(x, y) div_s64((x), (y))
61 : : #define div64_ul(x, y) div_u64((x), (y))
62 : :
63 : : #ifndef div_u64_rem
64 : : static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
65 : : {
66 [ + + ][ + + ]: 25652028 : *remainder = do_div(dividend, divisor);
[ + + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ - + ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ - + ][ # # ]
[ - + ][ - + ]
[ - + ][ - - ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ - + ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ + + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - - ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
67 : : return dividend;
68 : : }
69 : : #endif
70 : :
71 : : #ifndef div_s64_rem
72 : : extern s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder);
73 : : #endif
74 : :
75 : : #ifndef div64_u64_rem
76 : : extern u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder);
77 : : #endif
78 : :
79 : : #ifndef div64_u64
80 : : extern u64 div64_u64(u64 dividend, u64 divisor);
81 : : #endif
82 : :
83 : : #ifndef div64_s64
84 : : extern s64 div64_s64(s64 dividend, s64 divisor);
85 : : #endif
86 : :
87 : : #endif /* BITS_PER_LONG */
88 : :
89 : : /**
90 : : * div_u64 - unsigned 64bit divide with 32bit divisor
91 : : *
92 : : * This is the most common 64bit divide and should be used if possible,
93 : : * as many 32bit archs can optimize this variant better than a full 64bit
94 : : * divide.
95 : : */
96 : : #ifndef div_u64
97 : : static inline u64 div_u64(u64 dividend, u32 divisor)
98 : : {
99 : : u32 remainder;
100 : : return div_u64_rem(dividend, divisor, &remainder);
101 : : }
102 : : #endif
103 : :
104 : : /**
105 : : * div_s64 - signed 64bit divide with 32bit divisor
106 : : */
107 : : #ifndef div_s64
108 : : static inline s64 div_s64(s64 dividend, s32 divisor)
109 : : {
110 : : s32 remainder;
111 : 5056 : return div_s64_rem(dividend, divisor, &remainder);
112 : : }
113 : : #endif
114 : :
115 : : u32 iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder);
116 : :
117 : : static __always_inline u32
118 : : __iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder)
119 : : {
120 : : u32 ret = 0;
121 : :
122 [ + + ][ # # ]: 47730092 : while (dividend >= divisor) {
[ # # ][ + + ]
[ + + ][ - + ]
123 : : /* The following asm() prevents the compiler from
124 : : optimising this loop into a modulo operation. */
125 : 1208133 : asm("" : "+rm"(dividend));
126 : :
127 : 1208133 : dividend -= divisor;
128 : 1208133 : ret++;
129 : : }
130 : :
131 : 0 : *remainder = dividend;
132 : :
133 : : return ret;
134 : : }
135 : :
136 : : #if defined(CONFIG_ARCH_SUPPORTS_INT128) && defined(__SIZEOF_INT128__)
137 : :
138 : : #ifndef mul_u64_u32_shr
139 : : static inline u64 mul_u64_u32_shr(u64 a, u32 mul, unsigned int shift)
140 : : {
141 : : return (u64)(((unsigned __int128)a * mul) >> shift);
142 : : }
143 : : #endif /* mul_u64_u32_shr */
144 : :
145 : : #else
146 : :
147 : : #ifndef mul_u64_u32_shr
148 : : static inline u64 mul_u64_u32_shr(u64 a, u32 mul, unsigned int shift)
149 : : {
150 : : u32 ah, al;
151 : : u64 ret;
152 : :
153 : : al = a;
154 : 2836393 : ah = a >> 32;
155 : :
156 : 2836393 : ret = ((u64)al * mul) >> shift;
157 [ - + ]: 2836393 : if (ah)
158 : 0 : ret += ((u64)ah * mul) << (32 - shift);
159 : :
160 : : return ret;
161 : : }
162 : : #endif /* mul_u64_u32_shr */
163 : :
164 : : #endif
165 : :
166 : : #endif /* _LINUX_MATH64_H */
|