Rev 5056 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5056 | Rev 6082 | ||
---|---|---|---|
Line 140... | Line 140... | ||
140 | { |
140 | { |
141 | return (u64)(((unsigned __int128)a * mul) >> shift); |
141 | return (u64)(((unsigned __int128)a * mul) >> shift); |
142 | } |
142 | } |
143 | #endif /* mul_u64_u32_shr */ |
143 | #endif /* mul_u64_u32_shr */ |
Line -... | Line 144... | ||
- | 144 | ||
- | 145 | #ifndef mul_u64_u64_shr |
|
- | 146 | static inline u64 mul_u64_u64_shr(u64 a, u64 mul, unsigned int shift) |
|
- | 147 | { |
|
- | 148 | return (u64)(((unsigned __int128)a * mul) >> shift); |
|
- | 149 | } |
|
- | 150 | #endif /* mul_u64_u64_shr */ |
|
144 | 151 | ||
Line 145... | Line 152... | ||
145 | #else |
152 | #else |
146 | 153 | ||
147 | #ifndef mul_u64_u32_shr |
154 | #ifndef mul_u64_u32_shr |
Line 159... | Line 166... | ||
159 | 166 | ||
160 | return ret; |
167 | return ret; |
161 | } |
168 | } |
Line -... | Line 169... | ||
- | 169 | #endif /* mul_u64_u32_shr */ |
|
- | 170 | ||
- | 171 | #ifndef mul_u64_u64_shr |
|
- | 172 | static inline u64 mul_u64_u64_shr(u64 a, u64 b, unsigned int shift) |
|
- | 173 | { |
|
- | 174 | union { |
|
- | 175 | u64 ll; |
|
- | 176 | struct { |
|
- | 177 | #ifdef __BIG_ENDIAN |
|
- | 178 | u32 high, low; |
|
- | 179 | #else |
|
- | 180 | u32 low, high; |
|
- | 181 | #endif |
|
- | 182 | } l; |
|
- | 183 | } rl, rm, rn, rh, a0, b0; |
|
- | 184 | u64 c; |
|
- | 185 | ||
- | 186 | a0.ll = a; |
|
- | 187 | b0.ll = b; |
|
- | 188 | ||
- | 189 | rl.ll = (u64)a0.l.low * b0.l.low; |
|
- | 190 | rm.ll = (u64)a0.l.low * b0.l.high; |
|
- | 191 | rn.ll = (u64)a0.l.high * b0.l.low; |
|
- | 192 | rh.ll = (u64)a0.l.high * b0.l.high; |
|
- | 193 | ||
- | 194 | /* |
|
- | 195 | * Each of these lines computes a 64-bit intermediate result into "c", |
|
- | 196 | * starting at bits 32-95. The low 32-bits go into the result of the |
|
- | 197 | * multiplication, the high 32-bits are carried into the next step. |
|
- | 198 | */ |
|
- | 199 | rl.l.high = c = (u64)rl.l.high + rm.l.low + rn.l.low; |
|
- | 200 | rh.l.low = c = (c >> 32) + rm.l.high + rn.l.high + rh.l.low; |
|
- | 201 | rh.l.high = (c >> 32) + rh.l.high; |
|
- | 202 | ||
- | 203 | /* |
|
- | 204 | * The 128-bit result of the multiplication is in rl.ll and rh.ll, |
|
- | 205 | * shift it right and throw away the high part of the result. |
|
- | 206 | */ |
|
- | 207 | if (shift == 0) |
|
- | 208 | return rl.ll; |
|
- | 209 | if (shift < 64) |
|
- | 210 | return (rl.ll >> shift) | (rh.ll << (64 - shift)); |
|
- | 211 | return rh.ll >> (shift & 63); |
|
- | 212 | } |
|
162 | #endif /* mul_u64_u32_shr */ |
213 | #endif /* mul_u64_u64_shr */ |
Line -... | Line 214... | ||
- | 214 | ||
- | 215 | #endif |
|
- | 216 | ||
- | 217 | #ifndef mul_u64_u32_div |
|
- | 218 | static inline u64 mul_u64_u32_div(u64 a, u32 mul, u32 divisor) |
|
- | 219 | { |
|
- | 220 | union { |
|
- | 221 | u64 ll; |
|
- | 222 | struct { |
|
- | 223 | #ifdef __BIG_ENDIAN |
|
- | 224 | u32 high, low; |
|
- | 225 | #else |
|
- | 226 | u32 low, high; |
|
- | 227 | #endif |
|
- | 228 | } l; |
|
- | 229 | } u, rl, rh; |
|
- | 230 | ||
- | 231 | u.ll = a; |
|
- | 232 | rl.ll = (u64)u.l.low * mul; |
|
- | 233 | rh.ll = (u64)u.l.high * mul + rl.l.high; |
|
- | 234 | ||
- | 235 | /* Bits 32-63 of the result will be in rh.l.low. */ |
|
- | 236 | rl.l.high = do_div(rh.ll, divisor); |
|
- | 237 | ||
- | 238 | /* Bits 0-31 of the result will be in rl.l.low. */ |
|
- | 239 | do_div(rl.ll, divisor); |
|
- | 240 | ||
- | 241 | rl.l.high = rh.l.low; |
|
- | 242 | return rl.ll; |
|
163 | 243 | } |