X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdiv64.c;h=a111eb8de9cfeefb2bc82011ef580f970091bfcd;hb=068f5ae05c51d2cee6b31cb3da06775dd83bd348;hp=c3d7655cdfb5537b2b6ef71e09d284827552050a;hpb=3927f2e8f9afa3424bb51ca81f7abac01ffd0005;p=linux-2.6-omap-h63xx.git diff --git a/lib/div64.c b/lib/div64.c index c3d7655cdfb..a111eb8de9c 100644 --- a/lib/div64.c +++ b/lib/div64.c @@ -16,14 +16,13 @@ * assembly versions such as arch/ppc/lib/div64.S and arch/sh/lib/div64.S. */ -#include #include -#include +#include /* Not needed on 64bit architectures */ #if BITS_PER_LONG == 32 -uint32_t __div64_32(uint64_t *n, uint32_t base) +uint32_t __attribute__((weak)) __div64_32(uint64_t *n, uint32_t base) { uint64_t rem = *n; uint64_t b = base; @@ -58,26 +57,54 @@ uint32_t __div64_32(uint64_t *n, uint32_t base) EXPORT_SYMBOL(__div64_32); +#ifndef div_s64_rem +s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder) +{ + u64 quotient; + + if (dividend < 0) { + quotient = div_u64_rem(-dividend, abs(divisor), (u32 *)remainder); + *remainder = -*remainder; + if (divisor > 0) + quotient = -quotient; + } else { + quotient = div_u64_rem(dividend, abs(divisor), (u32 *)remainder); + if (divisor < 0) + quotient = -quotient; + } + return quotient; +} +EXPORT_SYMBOL(div_s64_rem); +#endif + /* 64bit divisor, dividend and result. dynamic precision */ -uint64_t div64_64(uint64_t dividend, uint64_t divisor) +#ifndef div64_u64 +u64 div64_u64(u64 dividend, u64 divisor) { - uint32_t d = divisor; + u32 high, d; - if (divisor > 0xffffffffULL) { - unsigned int shift = fls(divisor >> 32); + high = divisor >> 32; + if (high) { + unsigned int shift = fls(high); d = divisor >> shift; dividend >>= shift; - } + } else + d = divisor; - /* avoid 64 bit division if possible */ - if (dividend >> 32) - do_div(dividend, d); - else - dividend = (uint32_t) dividend / d; - - return dividend; + return div_u64(dividend, d); } -EXPORT_SYMBOL(div64_64); +EXPORT_SYMBOL(div64_u64); +#endif #endif /* BITS_PER_LONG == 32 */ + +/* + * Iterative div/mod for use when dividend is not expected to be much + * bigger than divisor. + */ +u32 iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder) +{ + return __iter_div_u64_rem(dividend, divisor, remainder); +} +EXPORT_SYMBOL(iter_div_u64_rem);