more changes on original files
[linux-2.4.git] / include / asm-parisc / div64.h
1 #ifndef __ASM_PARISC_DIV64
2 #define __ASM_PARISC_DIV64
3
4 #ifdef __LP64__
5
6 /*
7  * Copyright (C) 1999 Hewlett-Packard Co
8  * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
9  *
10  * vsprintf uses this to divide a 64-bit integer N by a small integer BASE.
11  * This is incredibly hard on IA-64 and HPPA
12  */
13
14 #define do_div(n,base)                                          \
15 ({                                                              \
16         int _res;                                               \
17         _res = ((unsigned long) (n)) % (unsigned) (base);       \
18         (n) = ((unsigned long) (n)) / (unsigned) (base);        \
19         _res;                                                   \
20 })
21
22 #else
23 /*
24  * unsigned long long division.  Yuck Yuck!  What is Linux coming to?
25  * This is 100% disgusting
26  */
27 #define do_div(n,base)                                                  \
28 ({                                                                      \
29         unsigned long __low, __low2, __high, __rem;                     \
30         __low  = (n) & 0xffffffff;                                      \
31         __high = (n) >> 32;                                             \
32         if (__high) {                                                   \
33                 __rem   = __high % (unsigned long)base;                 \
34                 __high  = __high / (unsigned long)base;                 \
35                 __low2  = __low >> 16;                                  \
36                 __low2 += __rem << 16;                                  \
37                 __rem   = __low2 % (unsigned long)base;                 \
38                 __low2  = __low2 / (unsigned long)base;                 \
39                 __low   = __low & 0xffff;                               \
40                 __low  += __rem << 16;                                  \
41                 __rem   = __low  % (unsigned long)base;                 \
42                 __low   = __low  / (unsigned long)base;                 \
43                 n = __low  + ((long long)__low2 << 16) +                \
44                         ((long long) __high << 32);                     \
45         } else {                                                        \
46                 __rem = __low % (unsigned long)base;                    \
47                 n = (__low / (unsigned long)base);                      \
48         }                                                               \
49         __rem;                                                          \
50 })
51 #endif
52
53 #endif
54