diff options
Diffstat (limited to 'lib/div64.c')
| -rw-r--r-- | lib/div64.c | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/lib/div64.c b/lib/div64.c index a111eb8de9cf..5b4919191778 100644 --- a/lib/div64.c +++ b/lib/div64.c | |||
| @@ -77,26 +77,58 @@ s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder) | |||
| 77 | EXPORT_SYMBOL(div_s64_rem); | 77 | EXPORT_SYMBOL(div_s64_rem); |
| 78 | #endif | 78 | #endif |
| 79 | 79 | ||
| 80 | /* 64bit divisor, dividend and result. dynamic precision */ | 80 | /** |
| 81 | * div64_u64 - unsigned 64bit divide with 64bit divisor | ||
| 82 | * @dividend: 64bit dividend | ||
| 83 | * @divisor: 64bit divisor | ||
| 84 | * | ||
| 85 | * This implementation is a modified version of the algorithm proposed | ||
| 86 | * by the book 'Hacker's Delight'. The original source and full proof | ||
| 87 | * can be found here and is available for use without restriction. | ||
| 88 | * | ||
| 89 | * 'http://www.hackersdelight.org/HDcode/newCode/divDouble.c' | ||
| 90 | */ | ||
| 81 | #ifndef div64_u64 | 91 | #ifndef div64_u64 |
| 82 | u64 div64_u64(u64 dividend, u64 divisor) | 92 | u64 div64_u64(u64 dividend, u64 divisor) |
| 83 | { | 93 | { |
| 84 | u32 high, d; | 94 | u32 high = divisor >> 32; |
| 95 | u64 quot; | ||
| 85 | 96 | ||
| 86 | high = divisor >> 32; | 97 | if (high == 0) { |
| 87 | if (high) { | 98 | quot = div_u64(dividend, divisor); |
| 88 | unsigned int shift = fls(high); | 99 | } else { |
| 100 | int n = 1 + fls(high); | ||
| 101 | quot = div_u64(dividend >> n, divisor >> n); | ||
| 89 | 102 | ||
| 90 | d = divisor >> shift; | 103 | if (quot != 0) |
| 91 | dividend >>= shift; | 104 | quot--; |
| 92 | } else | 105 | if ((dividend - quot * divisor) >= divisor) |
| 93 | d = divisor; | 106 | quot++; |
| 107 | } | ||
| 94 | 108 | ||
| 95 | return div_u64(dividend, d); | 109 | return quot; |
| 96 | } | 110 | } |
| 97 | EXPORT_SYMBOL(div64_u64); | 111 | EXPORT_SYMBOL(div64_u64); |
| 98 | #endif | 112 | #endif |
| 99 | 113 | ||
| 114 | /** | ||
| 115 | * div64_s64 - signed 64bit divide with 64bit divisor | ||
| 116 | * @dividend: 64bit dividend | ||
| 117 | * @divisor: 64bit divisor | ||
| 118 | */ | ||
| 119 | #ifndef div64_s64 | ||
| 120 | s64 div64_s64(s64 dividend, s64 divisor) | ||
| 121 | { | ||
| 122 | s64 quot, t; | ||
| 123 | |||
| 124 | quot = div64_u64(abs64(dividend), abs64(divisor)); | ||
| 125 | t = (dividend ^ divisor) >> 63; | ||
| 126 | |||
| 127 | return (quot ^ t) - t; | ||
| 128 | } | ||
| 129 | EXPORT_SYMBOL(div64_s64); | ||
| 130 | #endif | ||
| 131 | |||
| 100 | #endif /* BITS_PER_LONG == 32 */ | 132 | #endif /* BITS_PER_LONG == 32 */ |
| 101 | 133 | ||
| 102 | /* | 134 | /* |
