• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _LINUX_CALC64_H
2 #define _LINUX_CALC64_H
3 
4 #include <linux/types.h>
5 #include <asm/div64.h>
6 
7 /*
8  * This is a generic macro which is used when the architecture
9  * specific div64.h does not provide a optimized one.
10  *
11  * The 64bit dividend is divided by the divisor (data type long), the
12  * result is returned and the remainder stored in the variable
13  * referenced by remainder (data type long *). In contrast to the
14  * do_div macro the dividend is kept intact.
15  */
16 #ifndef div_long_long_rem
17 #define div_long_long_rem(dividend, divisor, remainder)	\
18 	do_div_llr((dividend), divisor, remainder)
19 
do_div_llr(const long long dividend,const long divisor,long * remainder)20 static inline unsigned long do_div_llr(const long long dividend,
21 				       const long divisor, long *remainder)
22 {
23 	u64 result = dividend;
24 
25 	*(remainder) = do_div(result, divisor);
26 	return (unsigned long) result;
27 }
28 #endif
29 
30 /*
31  * Sign aware variation of the above. On some architectures a
32  * negative dividend leads to an divide overflow exception, which
33  * is avoided by the sign check.
34  */
div_long_long_rem_signed(const long long dividend,const long divisor,long * remainder)35 static inline long div_long_long_rem_signed(const long long dividend,
36 					    const long divisor, long *remainder)
37 {
38 	long res;
39 
40 	if (unlikely(dividend < 0)) {
41 		res = -div_long_long_rem(-dividend, divisor, remainder);
42 		*remainder = -(*remainder);
43 	} else
44 		res = div_long_long_rem(dividend, divisor, remainder);
45 
46 	return res;
47 }
48 
49 #endif
50