|
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 /** |
|
10 * div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder |
|
11 * |
|
12 * This is commonly provided by 32bit archs to provide an optimized 64bit |
|
13 * divide. |
|
14 */ |
|
15 static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) |
|
16 { |
|
17 *remainder = dividend % divisor; |
|
18 return dividend / divisor; |
|
19 } |
|
20 |
|
21 /** |
|
22 * div_s64_rem - signed 64bit divide with 32bit divisor with remainder |
|
23 */ |
|
24 static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder) |
|
25 { |
|
26 *remainder = dividend % divisor; |
|
27 return dividend / divisor; |
|
28 } |
|
29 |
|
30 /** |
|
31 * div64_u64 - unsigned 64bit divide with 64bit divisor |
|
32 */ |
|
33 static inline u64 div64_u64(u64 dividend, u64 divisor) |
|
34 { |
|
35 return dividend / divisor; |
|
36 } |
|
37 |
|
38 #elif BITS_PER_LONG == 32 |
|
39 |
|
40 #ifndef div_u64_rem |
|
41 static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) |
|
42 { |
|
43 *remainder = do_div(dividend, divisor); |
|
44 return dividend; |
|
45 } |
|
46 #endif |
|
47 |
|
48 #ifndef div_s64_rem |
|
49 extern s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder); |
|
50 #endif |
|
51 |
|
52 #ifndef div64_u64 |
|
53 extern u64 div64_u64(u64 dividend, u64 divisor); |
|
54 #endif |
|
55 |
|
56 #endif /* BITS_PER_LONG */ |
|
57 |
|
58 /** |
|
59 * div_u64 - unsigned 64bit divide with 32bit divisor |
|
60 * |
|
61 * This is the most common 64bit divide and should be used if possible, |
|
62 * as many 32bit archs can optimize this variant better than a full 64bit |
|
63 * divide. |
|
64 */ |
|
65 #ifndef div_u64 |
|
66 static inline u64 div_u64(u64 dividend, u32 divisor) |
|
67 { |
|
68 u32 remainder; |
|
69 return div_u64_rem(dividend, divisor, &remainder); |
|
70 } |
|
71 #endif |
|
72 |
|
73 /** |
|
74 * div_s64 - signed 64bit divide with 32bit divisor |
|
75 */ |
|
76 #ifndef div_s64 |
|
77 static inline s64 div_s64(s64 dividend, s32 divisor) |
|
78 { |
|
79 s32 remainder; |
|
80 return div_s64_rem(dividend, divisor, &remainder); |
|
81 } |
|
82 #endif |
|
83 |
|
84 u32 iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder); |
|
85 |
|
86 static __always_inline u32 |
|
87 __iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder) |
|
88 { |
|
89 u32 ret = 0; |
|
90 |
|
91 while (dividend >= divisor) { |
|
92 /* The following asm() prevents the compiler from |
|
93 optimising this loop into a modulo operation. */ |
|
94 asm("" : "+rm"(dividend)); |
|
95 |
|
96 dividend -= divisor; |
|
97 ret++; |
|
98 } |
|
99 |
|
100 *remainder = dividend; |
|
101 |
|
102 return ret; |
|
103 } |
|
104 |
|
105 #endif /* _LINUX_MATH64_H */ |