diff options
Diffstat (limited to 'lib/div64.c')
-rw-r--r-- | lib/div64.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/lib/div64.c b/lib/div64.c index a163b6caef73..3af5728d95fd 100644 --- a/lib/div64.c +++ b/lib/div64.c | |||
@@ -79,9 +79,10 @@ EXPORT_SYMBOL(div_s64_rem); | |||
79 | #endif | 79 | #endif |
80 | 80 | ||
81 | /** | 81 | /** |
82 | * div64_u64 - unsigned 64bit divide with 64bit divisor | 82 | * div64_u64_rem - unsigned 64bit divide with 64bit divisor and 64bit remainder |
83 | * @dividend: 64bit dividend | 83 | * @dividend: 64bit dividend |
84 | * @divisor: 64bit divisor | 84 | * @divisor: 64bit divisor |
85 | * @remainder: 64bit remainder | ||
85 | * | 86 | * |
86 | * This implementation is a modified version of the algorithm proposed | 87 | * This implementation is a modified version of the algorithm proposed |
87 | * by the book 'Hacker's Delight'. The original source and full proof | 88 | * by the book 'Hacker's Delight'. The original source and full proof |
@@ -89,27 +90,33 @@ EXPORT_SYMBOL(div_s64_rem); | |||
89 | * | 90 | * |
90 | * 'http://www.hackersdelight.org/HDcode/newCode/divDouble.c.txt' | 91 | * 'http://www.hackersdelight.org/HDcode/newCode/divDouble.c.txt' |
91 | */ | 92 | */ |
92 | #ifndef div64_u64 | 93 | #ifndef div64_u64_rem |
93 | u64 div64_u64(u64 dividend, u64 divisor) | 94 | u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder) |
94 | { | 95 | { |
95 | u32 high = divisor >> 32; | 96 | u32 high = divisor >> 32; |
96 | u64 quot; | 97 | u64 quot; |
97 | 98 | ||
98 | if (high == 0) { | 99 | if (high == 0) { |
99 | quot = div_u64(dividend, divisor); | 100 | u32 rem32; |
101 | quot = div_u64_rem(dividend, divisor, &rem32); | ||
102 | *remainder = rem32; | ||
100 | } else { | 103 | } else { |
101 | int n = 1 + fls(high); | 104 | int n = 1 + fls(high); |
102 | quot = div_u64(dividend >> n, divisor >> n); | 105 | quot = div_u64(dividend >> n, divisor >> n); |
103 | 106 | ||
104 | if (quot != 0) | 107 | if (quot != 0) |
105 | quot--; | 108 | quot--; |
106 | if ((dividend - quot * divisor) >= divisor) | 109 | |
110 | *remainder = dividend - quot * divisor; | ||
111 | if (*remainder >= divisor) { | ||
107 | quot++; | 112 | quot++; |
113 | *remainder -= divisor; | ||
114 | } | ||
108 | } | 115 | } |
109 | 116 | ||
110 | return quot; | 117 | return quot; |
111 | } | 118 | } |
112 | EXPORT_SYMBOL(div64_u64); | 119 | EXPORT_SYMBOL(div64_u64_rem); |
113 | #endif | 120 | #endif |
114 | 121 | ||
115 | /** | 122 | /** |