12fc83c2cSRob Herring /* SPDX-License-Identifier: GPL-2.0 */
22fc83c2cSRob Herring #ifndef _LINUX_MATH64_H
32fc83c2cSRob Herring #define _LINUX_MATH64_H
42fc83c2cSRob Herring
52fc83c2cSRob Herring #include <linux/types.h>
62fc83c2cSRob Herring
72fc83c2cSRob Herring #ifdef __x86_64__
mul_u64_u64_div64(u64 a,u64 b,u64 c)82fc83c2cSRob Herring static inline u64 mul_u64_u64_div64(u64 a, u64 b, u64 c)
92fc83c2cSRob Herring {
102fc83c2cSRob Herring u64 q;
112fc83c2cSRob Herring
122fc83c2cSRob Herring asm ("mulq %2; divq %3" : "=a" (q)
132fc83c2cSRob Herring : "a" (a), "rm" (b), "rm" (c)
142fc83c2cSRob Herring : "rdx");
152fc83c2cSRob Herring
162fc83c2cSRob Herring return q;
172fc83c2cSRob Herring }
182fc83c2cSRob Herring #define mul_u64_u64_div64 mul_u64_u64_div64
192fc83c2cSRob Herring #endif
202fc83c2cSRob Herring
212fc83c2cSRob Herring #ifdef __SIZEOF_INT128__
mul_u64_u32_shr(u64 a,u32 b,unsigned int shift)222fc83c2cSRob Herring static inline u64 mul_u64_u32_shr(u64 a, u32 b, unsigned int shift)
232fc83c2cSRob Herring {
242fc83c2cSRob Herring return (u64)(((unsigned __int128)a * b) >> shift);
252fc83c2cSRob Herring }
262fc83c2cSRob Herring
272fc83c2cSRob Herring #else
282fc83c2cSRob Herring
292fc83c2cSRob Herring #ifdef __i386__
mul_u32_u32(u32 a,u32 b)302fc83c2cSRob Herring static inline u64 mul_u32_u32(u32 a, u32 b)
312fc83c2cSRob Herring {
322fc83c2cSRob Herring u32 high, low;
332fc83c2cSRob Herring
342fc83c2cSRob Herring asm ("mull %[b]" : "=a" (low), "=d" (high)
352fc83c2cSRob Herring : [a] "a" (a), [b] "rm" (b) );
362fc83c2cSRob Herring
372fc83c2cSRob Herring return low | ((u64)high) << 32;
382fc83c2cSRob Herring }
392fc83c2cSRob Herring #else
mul_u32_u32(u32 a,u32 b)402fc83c2cSRob Herring static inline u64 mul_u32_u32(u32 a, u32 b)
412fc83c2cSRob Herring {
422fc83c2cSRob Herring return (u64)a * b;
432fc83c2cSRob Herring }
442fc83c2cSRob Herring #endif
452fc83c2cSRob Herring
mul_u64_u32_shr(u64 a,u32 b,unsigned int shift)462fc83c2cSRob Herring static inline u64 mul_u64_u32_shr(u64 a, u32 b, unsigned int shift)
472fc83c2cSRob Herring {
482fc83c2cSRob Herring u32 ah, al;
492fc83c2cSRob Herring u64 ret;
502fc83c2cSRob Herring
512fc83c2cSRob Herring al = a;
522fc83c2cSRob Herring ah = a >> 32;
532fc83c2cSRob Herring
542fc83c2cSRob Herring ret = mul_u32_u32(al, b) >> shift;
552fc83c2cSRob Herring if (ah)
562fc83c2cSRob Herring ret += mul_u32_u32(ah, b) << (32 - shift);
572fc83c2cSRob Herring
582fc83c2cSRob Herring return ret;
592fc83c2cSRob Herring }
602fc83c2cSRob Herring
612fc83c2cSRob Herring #endif /* __SIZEOF_INT128__ */
622fc83c2cSRob Herring
632fc83c2cSRob Herring #ifndef mul_u64_u64_div64
mul_u64_u64_div64(u64 a,u64 b,u64 c)642fc83c2cSRob Herring static inline u64 mul_u64_u64_div64(u64 a, u64 b, u64 c)
652fc83c2cSRob Herring {
662fc83c2cSRob Herring u64 quot, rem;
672fc83c2cSRob Herring
682fc83c2cSRob Herring quot = a / c;
692fc83c2cSRob Herring rem = a % c;
702fc83c2cSRob Herring
712fc83c2cSRob Herring return quot * b + (rem * b) / c;
722fc83c2cSRob Herring }
732fc83c2cSRob Herring #endif
742fc83c2cSRob Herring
div_u64(u64 dividend,u32 divisor)75*4164e152SWei Yang static inline u64 div_u64(u64 dividend, u32 divisor)
76*4164e152SWei Yang {
77*4164e152SWei Yang return dividend / divisor;
78*4164e152SWei Yang }
79*4164e152SWei Yang
802fc83c2cSRob Herring #endif /* _LINUX_MATH64_H */
81