1/*
2 * Copyright (C) 2000  Maciej W. Rozycki
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License.  See the file "COPYING" in the main directory of this archive
6 * for more details.
7 */
8#ifndef _ASM_DIV64_H
9#define _ASM_DIV64_H
10
11/*
12 * No traps on overflows for any of these...
13 */
14
15#define do_div64_32(res, high, low, base) ({ \
16	unsigned long __quot, __mod; \
17	unsigned long __cf, __tmp, __tmp2, __i; \
18	\
19	__asm__(".set	push\n\t" \
20		".set	noat\n\t" \
21		".set	noreorder\n\t" \
22		"move	%2, $0\n\t" \
23		"move	%3, $0\n\t" \
24		"b	1f\n\t" \
25		" li	%4, 0x21\n" \
26		"0:\n\t" \
27		"sll	$1, %0, 0x1\n\t" \
28		"srl	%3, %0, 0x1f\n\t" \
29		"or	%0, $1, %5\n\t" \
30		"sll	%1, %1, 0x1\n\t" \
31		"sll	%2, %2, 0x1\n" \
32		"1:\n\t" \
33		"bnez	%3, 2f\n\t" \
34		" sltu	%5, %0, %z6\n\t" \
35		"bnez	%5, 3f\n" \
36		"2:\n\t" \
37		" addiu	%4, %4, -1\n\t" \
38		"subu	%0, %0, %z6\n\t" \
39		"addiu	%2, %2, 1\n" \
40		"3:\n\t" \
41		"bnez	%4, 0b\n\t" \
42		" srl	%5, %1, 0x1f\n\t" \
43		".set	pop" \
44		: "=&r" (__mod), "=&r" (__tmp), "=&r" (__quot), "=&r" (__cf), \
45		  "=&r" (__i), "=&r" (__tmp2) \
46		: "Jr" (base), "0" (high), "1" (low)); \
47	\
48	(res) = __quot; \
49	__mod; })
50
51#define do_div(n, base) ({ \
52	unsigned long long __quot; \
53	unsigned long __mod; \
54	unsigned long long __div; \
55	unsigned long __upper, __low, __high, __base; \
56	\
57	__div = (n); \
58	__base = (base); \
59	\
60	__high = __div >> 32; \
61	__low = __div; \
62	__upper = __high; \
63	\
64	if (__high) \
65		__asm__("divu	$0, %z2, %z3" \
66			: "=h" (__upper), "=l" (__high) \
67			: "Jr" (__high), "Jr" (__base)); \
68	\
69	__mod = do_div64_32(__low, __upper, __low, __base); \
70	\
71	__quot = __high; \
72	__quot = __quot << 32 | __low; \
73	(n) = __quot; \
74	__mod; })
75
76#endif /* _ASM_DIV64_H */
77