1
2
3
4
5
6
7
8
9
10
11#ifndef _ASM_DIV64
12#define _ASM_DIV64
13
14#include <linux/types.h>
15
16extern void ____unhandled_size_in_do_div___(void);
17
18
19
20
21
22
23#define do_div(n, base) \
24({ \
25 unsigned __rem = 0; \
26 if (sizeof(n) <= 4) { \
27 asm("mov %1,mdr \n" \
28 "divu %2,%0 \n" \
29 "mov mdr,%1 \n" \
30 : "+r"(n), "=d"(__rem) \
31 : "r"(base), "1"(__rem) \
32 : "cc" \
33 ); \
34 } else if (sizeof(n) <= 8) { \
35 union { \
36 unsigned long long l; \
37 u32 w[2]; \
38 } __quot; \
39 __quot.l = n; \
40 asm("mov %0,mdr \n" \
41 "divu %3,%1 \n" \
42 \
43 \
44 "divu %3,%2 \n" \
45 \
46 \
47 "mov mdr,%0 \n" \
48 : "=d"(__rem), "=r"(__quot.w[1]), "=r"(__quot.w[0]) \
49 : "r"(base), "0"(__rem), "1"(__quot.w[1]), \
50 "2"(__quot.w[0]) \
51 : "cc" \
52 ); \
53 n = __quot.l; \
54 } else { \
55 ____unhandled_size_in_do_div___(); \
56 } \
57 __rem; \
58})
59
60
61
62
63
64
65static inline __attribute__((const))
66unsigned __muldiv64u(unsigned val, unsigned mult, unsigned div)
67{
68 unsigned result;
69
70 asm("mulu %2,%0 \n"
71 "divu %3,%0 \n"
72
73 : "=r"(result)
74 : "0"(val), "ir"(mult), "r"(div)
75 : "cc"
76 );
77
78 return result;
79}
80
81
82
83
84
85
86static inline __attribute__((const))
87signed __muldiv64s(signed val, signed mult, signed div)
88{
89 signed result;
90
91 asm("mul %2,%0 \n"
92 "div %3,%0 \n"
93
94 : "=r"(result)
95 : "0"(val), "ir"(mult), "r"(div)
96 : "cc"
97 );
98
99 return result;
100}
101
102#endif
103