[PATCH] Fix problem introduced by do_div() patch
[linux-flexiantxendom0-3.2.10.git] / lib / div64.c
1 /*
2  * Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>
3  *
4  * Based on former do_div() implementation from asm-parisc/div64.h:
5  *      Copyright (C) 1999 Hewlett-Packard Co
6  *      Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
7  *
8  *
9  * Generic C version of 64bit/32bit division and modulo, with
10  * 64bit result and 32bit remainder.
11  *
12  * The fast case for (n>>32 == 0) is handled inline by do_div(). 
13  *
14  * Code generated for this function might be very inefficient
15  * for some CPUs. __div64_32() can be overridden by linking arch-specific
16  * assembly versions such as arch/ppc/lib/div64.S and arch/sh/lib/div64.S.
17  */
18
19 #include <linux/types.h>
20 #include <linux/module.h>
21 #include <asm/div64.h>
22
23 /* Not needed on 64bit architectures */
24 #if BITS_PER_LONG == 32
25
26 uint32_t __div64_32(uint64_t *n, uint32_t base)
27 {
28         uint32_t low, low2, high, rem;
29
30         low   = *n   & 0xffffffff;
31         high  = *n  >> 32;
32         rem   = high % (uint32_t)base;
33         high  = high / (uint32_t)base;
34         low2  = low >> 16;
35         low2 += rem << 16;
36         rem   = low2 % (uint32_t)base;
37         low2  = low2 / (uint32_t)base;
38         low   = low  & 0xffff;
39         low  += rem << 16;
40         rem   = low  % (uint32_t)base;
41         low   = low  / (uint32_t)base;
42
43         *n = low +
44                 ((uint64_t)low2 << 16) +
45                 ((uint64_t)high << 32);
46
47         return rem;
48 }
49
50 EXPORT_SYMBOL(__div64_32);
51
52 #endif /* BITS_PER_LONG == 32 */