Add constants for fast path resume copying
[coreboot.git] / src / include / arch-generic / div64.h
1 #ifndef ARCH_GENERIC_DIV64_H
2 #define ARCH_GENERIC_DIV64_H
3 /*
4  * Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>
5  * Based on former asm-ppc/div64.h and asm-m68knommu/div64.h
6  *
7  * The semantics of do_div() are:
8  *
9  * uint32_t do_div(uint64_t *n, uint32_t base)
10  * {
11  *      uint32_t remainder = *n % base;
12  *      *n = *n / base;
13  *      return remainder;
14  * }
15  *
16  * NOTE: macro parameter n is evaluated multiple times,
17  *       beware of side effects!
18  */
19
20 #ifndef ULONG_MAX
21 #include <limits.h>
22 #endif
23 #include <stdint.h>
24
25 #if ULONG_MAX == 4294967295
26
27 extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
28
29 /* The unnecessary pointer compare is there
30  * to check for type safety (n must be 64bit)
31  */
32 # define do_div(n,base) ({                              \
33         uint32_t __base = (base);                       \
34         uint32_t __rem;                                 \
35         (void)(((typeof((n)) *)0) == ((uint64_t *)0));  \
36         if (((n) >> 32) == 0) {                         \
37                 __rem = (uint32_t)(n) % __base;         \
38                 (n) = (uint32_t)(n) / __base;           \
39         } else                                          \
40                 __rem = __div64_32(&(n), __base);       \
41         __rem;                                          \
42  })
43
44 #elif ULONG_MAX == 18446744073709551615
45
46 # define do_div(n,base) ({                                      \
47         uint32_t __base = (base);                               \
48         uint32_t __rem;                                         \
49         __rem = ((uint64_t)(n)) % __base;                       \
50         (n) = ((uint64_t)(n)) / __base;                         \
51         __rem;                                                  \
52  })
53
54
55 #else /* BITS_PER_LONG == ?? */
56
57 # error do_div() does not yet support the C64
58
59 #endif /* BITS_PER_LONG */
60
61 #endif /* ARCH_GENERIC_DIV64_H */