xref: /linux-6.15/tools/include/linux/math64.h (revision 4164e152)
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