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