Code-base clean-up and refactoring (#47)
[lunaix-os.git] / lunaix-os / arch / x86 / includes / asm / muldiv64.h
1 #ifndef __LUNAIX_MULDIV64_H
2 #define __LUNAIX_MULDIV64_H
3
4 #include <lunaix/spike.h>
5 #include <lunaix/types.h>
6
7 #ifdef CONFIG_ARCH_I386
8 #define do_udiv64(n, base)                                                     \
9     ({                                                                         \
10         unsigned long __upper, __low, __high, __mod, __base;                   \
11         __base = (base);                                                       \
12         if (__builtin_constant_p(__base) && is_pot(__base)) {                  \
13             __mod = n & (__base - 1);                                          \
14             n >>= ilog2(__base);                                               \
15         } else {                                                               \
16             asm("" : "=a"(__low), "=d"(__high) : "A"(n));                      \
17             __upper = __high;                                                  \
18             if (__high) {                                                      \
19                 __upper = __high % (__base);                                   \
20                 __high = __high / (__base);                                    \
21             }                                                                  \
22             asm("divl %2"                                                      \
23                 : "=a"(__low), "=d"(__mod)                                     \
24                 : "rm"(__base), "0"(__low), "1"(__upper));                     \
25             asm("" : "=A"(n) : "a"(__low), "d"(__high));                       \
26         }                                                                      \
27         __mod;                                                                 \
28     })
29 #else
30     #define do_udiv64(n, base)  \
31         ({                      \
32             n = (n) / (base);   \
33             (n) % (base);       \
34         })
35 #endif
36
37 static inline u64_t
38 udiv64(u64_t n, unsigned int base)
39 {
40     do_udiv64(n, base);
41
42     return n;
43 }
44
45 static inline unsigned int
46 umod64(u64_t n, unsigned int base)
47 {
48     return do_udiv64(n, base);
49 }
50
51 #endif /* __LUNAIX_MULDIV64_H */