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 * @dividend: unsigned 64bit dividend 15 * @divisor: unsigned 32bit divisor 16 * @remainder: pointer to unsigned 32bit remainder 17 * 18 * Return: sets ``*remainder``, then returns dividend / divisor 19 * 20 * This is commonly provided by 32bit archs to provide an optimized 64bit 21 * divide. 22 */ 23 static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) 24 { 25 *remainder = dividend % divisor; 26 return dividend / divisor; 27 } 28 29 /** 30 * div_s64_rem - signed 64bit divide with 32bit divisor with remainder 31 * @dividend: signed 64bit dividend 32 * @divisor: signed 32bit divisor 33 * @remainder: pointer to signed 32bit remainder 34 * 35 * Return: sets ``*remainder``, then returns dividend / divisor 36 */ 37 static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder) 38 { 39 *remainder = dividend % divisor; 40 return dividend / divisor; 41 } 42 43 /** 44 * div64_u64_rem - unsigned 64bit divide with 64bit divisor and remainder 45 * @dividend: unsigned 64bit dividend 46 * @divisor: unsigned 64bit divisor 47 * @remainder: pointer to unsigned 64bit remainder 48 * 49 * Return: sets ``*remainder``, then returns dividend / divisor 50 */ 51 static inline u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder) 52 { 53 *remainder = dividend % divisor; 54 return dividend / divisor; 55 } 56 57 /** 58 * div64_u64 - unsigned 64bit divide with 64bit divisor 59 * @dividend: unsigned 64bit dividend 60 * @divisor: unsigned 64bit divisor 61 * 62 * Return: dividend / divisor 63 */ 64 static inline u64 div64_u64(u64 dividend, u64 divisor) 65 { 66 return dividend / divisor; 67 } 68 69 /** 70 * div64_s64 - signed 64bit divide with 64bit divisor 71 * @dividend: signed 64bit dividend 72 * @divisor: signed 64bit divisor 73 * 74 * Return: dividend / divisor 75 */ 76 static inline s64 div64_s64(s64 dividend, s64 divisor) 77 { 78 return dividend / divisor; 79 } 80 81 #elif BITS_PER_LONG == 32 82 83 #define div64_long(x, y) div_s64((x), (y)) 84 #define div64_ul(x, y) div_u64((x), (y)) 85 86 #ifndef div_u64_rem 87 static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) 88 { 89 *remainder = do_div(dividend, divisor); 90 return dividend; 91 } 92 #endif 93 94 #ifndef div_s64_rem 95 extern s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder); 96 #endif 97 98 #ifndef div64_u64_rem 99 extern u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder); 100 #endif 101 102 #ifndef div64_u64 103 extern u64 div64_u64(u64 dividend, u64 divisor); 104 #endif 105 106 #ifndef div64_s64 107 extern s64 div64_s64(s64 dividend, s64 divisor); 108 #endif 109 110 #endif /* BITS_PER_LONG */ 111 112 /** 113 * div_u64 - unsigned 64bit divide with 32bit divisor 114 * @dividend: unsigned 64bit dividend 115 * @divisor: unsigned 32bit divisor 116 * 117 * This is the most common 64bit divide and should be used if possible, 118 * as many 32bit archs can optimize this variant better than a full 64bit 119 * divide. 120 */ 121 #ifndef div_u64 122 static inline u64 div_u64(u64 dividend, u32 divisor) 123 { 124 u32 remainder; 125 return div_u64_rem(dividend, divisor, &remainder); 126 } 127 #endif 128 129 /** 130 * div_s64 - signed 64bit divide with 32bit divisor 131 * @dividend: signed 64bit dividend 132 * @divisor: signed 32bit divisor 133 */ 134 #ifndef div_s64 135 static inline s64 div_s64(s64 dividend, s32 divisor) 136 { 137 s32 remainder; 138 return div_s64_rem(dividend, divisor, &remainder); 139 } 140 #endif 141 142 u32 iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder); 143 144 static __always_inline u32 145 __iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder) 146 { 147 u32 ret = 0; 148 149 while (dividend >= divisor) { 150 /* The following asm() prevents the compiler from 151 optimising this loop into a modulo operation. */ 152 asm("" : "+rm"(dividend)); 153 154 dividend -= divisor; 155 ret++; 156 } 157 158 *remainder = dividend; 159 160 return ret; 161 } 162 163 #ifndef mul_u32_u32 164 /* 165 * Many a GCC version messes this up and generates a 64x64 mult :-( 166 */ 167 static inline u64 mul_u32_u32(u32 a, u32 b) 168 { 169 return (u64)a * b; 170 } 171 #endif 172 173 #if defined(CONFIG_ARCH_SUPPORTS_INT128) && defined(__SIZEOF_INT128__) 174 175 #ifndef mul_u64_u32_shr 176 static inline u64 mul_u64_u32_shr(u64 a, u32 mul, unsigned int shift) 177 { 178 return (u64)(((unsigned __int128)a * mul) >> shift); 179 } 180 #endif /* mul_u64_u32_shr */ 181 182 #ifndef mul_u64_u64_shr 183 static inline u64 mul_u64_u64_shr(u64 a, u64 mul, unsigned int shift) 184 { 185 return (u64)(((unsigned __int128)a * mul) >> shift); 186 } 187 #endif /* mul_u64_u64_shr */ 188 189 #else 190 191 #ifndef mul_u64_u32_shr 192 static inline u64 mul_u64_u32_shr(u64 a, u32 mul, unsigned int shift) 193 { 194 u32 ah, al; 195 u64 ret; 196 197 al = a; 198 ah = a >> 32; 199 200 ret = mul_u32_u32(al, mul) >> shift; 201 if (ah) 202 ret += mul_u32_u32(ah, mul) << (32 - shift); 203 204 return ret; 205 } 206 #endif /* mul_u64_u32_shr */ 207 208 #ifndef mul_u64_u64_shr 209 static inline u64 mul_u64_u64_shr(u64 a, u64 b, unsigned int shift) 210 { 211 union { 212 u64 ll; 213 struct { 214 #ifdef __BIG_ENDIAN 215 u32 high, low; 216 #else 217 u32 low, high; 218 #endif 219 } l; 220 } rl, rm, rn, rh, a0, b0; 221 u64 c; 222 223 a0.ll = a; 224 b0.ll = b; 225 226 rl.ll = mul_u32_u32(a0.l.low, b0.l.low); 227 rm.ll = mul_u32_u32(a0.l.low, b0.l.high); 228 rn.ll = mul_u32_u32(a0.l.high, b0.l.low); 229 rh.ll = mul_u32_u32(a0.l.high, b0.l.high); 230 231 /* 232 * Each of these lines computes a 64-bit intermediate result into "c", 233 * starting at bits 32-95. The low 32-bits go into the result of the 234 * multiplication, the high 32-bits are carried into the next step. 235 */ 236 rl.l.high = c = (u64)rl.l.high + rm.l.low + rn.l.low; 237 rh.l.low = c = (c >> 32) + rm.l.high + rn.l.high + rh.l.low; 238 rh.l.high = (c >> 32) + rh.l.high; 239 240 /* 241 * The 128-bit result of the multiplication is in rl.ll and rh.ll, 242 * shift it right and throw away the high part of the result. 243 */ 244 if (shift == 0) 245 return rl.ll; 246 if (shift < 64) 247 return (rl.ll >> shift) | (rh.ll << (64 - shift)); 248 return rh.ll >> (shift & 63); 249 } 250 #endif /* mul_u64_u64_shr */ 251 252 #endif 253 254 #ifndef mul_u64_u32_div 255 static inline u64 mul_u64_u32_div(u64 a, u32 mul, u32 divisor) 256 { 257 union { 258 u64 ll; 259 struct { 260 #ifdef __BIG_ENDIAN 261 u32 high, low; 262 #else 263 u32 low, high; 264 #endif 265 } l; 266 } u, rl, rh; 267 268 u.ll = a; 269 rl.ll = mul_u32_u32(u.l.low, mul); 270 rh.ll = mul_u32_u32(u.l.high, mul) + rl.l.high; 271 272 /* Bits 32-63 of the result will be in rh.l.low. */ 273 rl.l.high = do_div(rh.ll, divisor); 274 275 /* Bits 0-31 of the result will be in rl.l.low. */ 276 do_div(rl.ll, divisor); 277 278 rl.l.high = rh.l.low; 279 return rl.ll; 280 } 281 #endif /* mul_u64_u32_div */ 282 283 #endif /* _LINUX_MATH64_H */ 284