source: GPL/trunk/include/linux/math64.h@ 772

Last change on this file since 772 was 772, checked in by David Azarewicz, 4 months ago

Merge in changes from 6.6-LTS branch.
Fixed additional 25+ problems.

File size: 2.4 KB
Line 
1/*
2 * div_u64() compat
3 */
4
5#ifndef MATH64_COMPAT_H
6#define MATH64_COMPAT_H
7
8#include <linux/types.h>
9
10#if BITS_PER_LONG >= 64
11
12static inline u64 div_u64_rem(u64 n, u32 div, u32 *rem)
13{
14 *rem = n % div;
15 return n / div;
16}
17
18
19static inline u64 div_u64(u64 n, u32 div)
20{
21 return n / div;
22}
23
24#elif defined(i386)
25
26static inline u64 div_u64_rem(u64 n, u32 div, u32 *rem)
27{
28 u32 low, high;
29
30 low = (u32)n;
31 high = n >> 32;
32 if (high) {
33 u32 high1 = high % div;
34 high /= div;
35 asm("divl %2" : "=a" (low), "=d" (*rem) : \
36 "rm" (div), "a" (low), "d" (high1));
37 return (u64)high << 32 | low;
38 } else {
39 *rem = low % div;
40 return low / div;
41 }
42}
43
44static inline u64 div_u64(u64 n, u32 div)
45{
46 u32 low, high;
47
48 low = (u32)n;
49 high = n >> 32;
50 if (high) {
51 u32 high1 = high % div;
52 high /= div;
53 asm("divl %2" : "=a" (low) : \
54 "rm" (div), "a" (low), "d" (high1));
55 return (u64)high << 32 | low;
56 } else
57 return low / div;
58}
59
60/**
61 * div_s64_rem - signed 64bit divide with 32bit divisor with remainder
62 */
63static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
64{
65 *remainder = dividend % divisor;
66 return dividend / divisor;
67}
68
69#else
70
71static inline void divl(u32 high, u32 low, u32 div, u32 *q, u32 *r)
72{
73 u64 n = (u64)high << 32 | low;
74 u64 d = (u64)div << 31;
75 u32 q1 = 0;
76 int c = 32;
77 while (n > 0xffffffffUi64) {
78 q1 <<= 1;
79 if (n >= d) {
80 n -= d;
81 q1 |= 1;
82 }
83 d >>= 1;
84 c--;
85 }
86 q1 <<= c;
87 if (n) {
88 low = n;
89 *q = q1 | (low / div);
90 *r = low % div;
91 } else {
92 *r = 0;
93 *q = q1;
94 }
95 return;
96}
97
98static inline u64 div_u64_rem(u64 n, u32 div, u32 *rem)
99{
100 u32 low, high;
101 low = (u32)n;
102 high = n >> 32;
103 if (high) {
104 u32 high1 = high % div;
105 u32 low1 = low;
106 high /= div;
107 divl(high1, low1, div, &low, rem);
108 return (u64)high << 32 | low;
109 } else {
110 *rem = low % div;
111 return low / div;
112 }
113}
114
115static inline u64 div_u64(u64 n, u32 div)
116{
117 u32 low, high, rem;
118 low = (u32)n;
119 high = n >> 32;
120 if (high) {
121 u32 high1 = high % div;
122 u32 low1 = low;
123 high /= div;
124 divl(high1, low1, div, &low, &rem);
125 return (u64)high << 32 | low;
126 } else {
127 return low / div;
128 }
129}
130
131/**
132 * div_s64_rem - signed 64bit divide with 32bit divisor with remainder
133 */
134static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
135{
136 *remainder = dividend % divisor;
137 return dividend / divisor;
138}
139
140#endif
141
142u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder);
143
144#endif /* MATH64_COMPAT_H */
Note: See TracBrowser for help on using the repository browser.