xref: /rk3399_rockchip-uboot/include/div64.h (revision 3feb647f3fd0881382c7a29f4cf280b66473ae0a)
1f7c086e9SDirk Behme #ifndef _ASM_GENERIC_DIV64_H
2f7c086e9SDirk Behme #define _ASM_GENERIC_DIV64_H
3f7c086e9SDirk Behme /*
4f7c086e9SDirk Behme  * Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>
5f7c086e9SDirk Behme  * Based on former asm-ppc/div64.h and asm-m68knommu/div64.h
6f7c086e9SDirk Behme  *
7f7c086e9SDirk Behme  * The semantics of do_div() are:
8f7c086e9SDirk Behme  *
9f7c086e9SDirk Behme  * uint32_t do_div(uint64_t *n, uint32_t base)
10f7c086e9SDirk Behme  * {
11f7c086e9SDirk Behme  *	uint32_t remainder = *n % base;
12f7c086e9SDirk Behme  *	*n = *n / base;
13f7c086e9SDirk Behme  *	return remainder;
14f7c086e9SDirk Behme  * }
15f7c086e9SDirk Behme  *
16f7c086e9SDirk Behme  * NOTE: macro parameter n is evaluated multiple times,
17f7c086e9SDirk Behme  *       beware of side effects!
18f7c086e9SDirk Behme  */
19f7c086e9SDirk Behme 
20f7c086e9SDirk Behme #include <linux/types.h>
21f7c086e9SDirk Behme 
22f7c086e9SDirk Behme extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
23f7c086e9SDirk Behme 
24f7c086e9SDirk Behme /* The unnecessary pointer compare is there
25f7c086e9SDirk Behme  * to check for type safety (n must be 64bit)
26f7c086e9SDirk Behme  */
27f7c086e9SDirk Behme # define do_div(n,base) ({				\
28f7c086e9SDirk Behme 	uint32_t __base = (base);			\
29f7c086e9SDirk Behme 	uint32_t __rem;					\
30f7c086e9SDirk Behme 	(void)(((typeof((n)) *)0) == ((uint64_t *)0));	\
31f7c086e9SDirk Behme 	if (((n) >> 32) == 0) {			\
32f7c086e9SDirk Behme 		__rem = (uint32_t)(n) % __base;		\
33f7c086e9SDirk Behme 		(n) = (uint32_t)(n) / __base;		\
34f7c086e9SDirk Behme 	} else						\
35f7c086e9SDirk Behme 		__rem = __div64_32(&(n), __base);	\
36f7c086e9SDirk Behme 	__rem;						\
37f7c086e9SDirk Behme  })
38f7c086e9SDirk Behme 
39*3feb647fSSergei Poselenov /* Wrapper for do_div(). Doesn't modify dividend and returns
40*3feb647fSSergei Poselenov  * the result, not reminder.
41*3feb647fSSergei Poselenov  */
42*3feb647fSSergei Poselenov static inline uint64_t lldiv(uint64_t dividend, uint32_t divisor)
43*3feb647fSSergei Poselenov {
44*3feb647fSSergei Poselenov 	uint64_t __res = dividend;
45*3feb647fSSergei Poselenov 	do_div(__res, divisor);
46*3feb647fSSergei Poselenov 	return(__res);
47*3feb647fSSergei Poselenov }
48*3feb647fSSergei Poselenov 
49f7c086e9SDirk Behme #endif /* _ASM_GENERIC_DIV64_H */
50