Commit | Line | Data |
---|---|---|
2fc83c2c RH |
1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _LINUX_MATH64_H | |
3 | #define _LINUX_MATH64_H | |
4 | ||
5 | #include <linux/types.h> | |
6 | ||
7 | #ifdef __x86_64__ | |
8 | static inline u64 mul_u64_u64_div64(u64 a, u64 b, u64 c) | |
9 | { | |
10 | u64 q; | |
11 | ||
12 | asm ("mulq %2; divq %3" : "=a" (q) | |
13 | : "a" (a), "rm" (b), "rm" (c) | |
14 | : "rdx"); | |
15 | ||
16 | return q; | |
17 | } | |
18 | #define mul_u64_u64_div64 mul_u64_u64_div64 | |
19 | #endif | |
20 | ||
21 | #ifdef __SIZEOF_INT128__ | |
22 | static inline u64 mul_u64_u32_shr(u64 a, u32 b, unsigned int shift) | |
23 | { | |
24 | return (u64)(((unsigned __int128)a * b) >> shift); | |
25 | } | |
26 | ||
27 | #else | |
28 | ||
29 | #ifdef __i386__ | |
30 | static inline u64 mul_u32_u32(u32 a, u32 b) | |
31 | { | |
32 | u32 high, low; | |
33 | ||
34 | asm ("mull %[b]" : "=a" (low), "=d" (high) | |
35 | : [a] "a" (a), [b] "rm" (b) ); | |
36 | ||
37 | return low | ((u64)high) << 32; | |
38 | } | |
39 | #else | |
40 | static inline u64 mul_u32_u32(u32 a, u32 b) | |
41 | { | |
42 | return (u64)a * b; | |
43 | } | |
44 | #endif | |
45 | ||
46 | static inline u64 mul_u64_u32_shr(u64 a, u32 b, unsigned int shift) | |
47 | { | |
48 | u32 ah, al; | |
49 | u64 ret; | |
50 | ||
51 | al = a; | |
52 | ah = a >> 32; | |
53 | ||
54 | ret = mul_u32_u32(al, b) >> shift; | |
55 | if (ah) | |
56 | ret += mul_u32_u32(ah, b) << (32 - shift); | |
57 | ||
58 | return ret; | |
59 | } | |
60 | ||
61 | #endif /* __SIZEOF_INT128__ */ | |
62 | ||
63 | #ifndef mul_u64_u64_div64 | |
64 | static inline u64 mul_u64_u64_div64(u64 a, u64 b, u64 c) | |
65 | { | |
66 | u64 quot, rem; | |
67 | ||
68 | quot = a / c; | |
69 | rem = a % c; | |
70 | ||
71 | return quot * b + (rem * b) / c; | |
72 | } | |
73 | #endif | |
74 | ||
75 | #endif /* _LINUX_MATH64_H */ |