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