• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef __ASM_ARM_DIV64
2 #define __ASM_ARM_DIV64
3 
4 #include <asm/system.h>
5 
6 /*
7  * The semantics of do_div() are:
8  *
9  * uint32_t do_div(uint64_t *n, uint32_t base)
10  * {
11  * 	uint32_t remainder = *n % base;
12  * 	*n = *n / base;
13  * 	return remainder;
14  * }
15  *
16  * In other words, a 64-bit dividend with a 32-bit divisor producing
17  * a 64-bit result and a 32-bit remainder.  To accomplish this optimally
18  * we call a special __do_div64 helper with completely non standard
19  * calling convention for arguments and results (beware).
20  */
21 
22 #ifdef __ARMEB__
23 #define __xh "r0"
24 #define __xl "r1"
25 #else
26 #define __xl "r0"
27 #define __xh "r1"
28 #endif
29 
30 #define do_div(n,base)						\
31 ({								\
32 	register unsigned int __base      asm("r4") = base;	\
33 	register unsigned long long __n   asm("r0") = n;	\
34 	register unsigned long long __res asm("r2");		\
35 	register unsigned int __rem       asm(__xh);		\
36 	asm(	__asmeq("%0", __xh)				\
37 		__asmeq("%1", "r2")				\
38 		__asmeq("%2", "r0")				\
39 		__asmeq("%3", "r4")				\
40 		"bl	__do_div64"				\
41 		: "=r" (__rem), "=r" (__res)			\
42 		: "r" (__n), "r" (__base)			\
43 		: "ip", "lr", "cc");				\
44 	n = __res;						\
45 	__rem;							\
46 })
47 
48 #endif
49