Home | History | Annotate | Download | only in linux
      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 
     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  */
     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