nmi_backtrace: add more trigger_*_cpu_backtrace() methods
[cascardo/linux.git] / arch / x86 / include / asm / div64.h
1 #ifndef _ASM_X86_DIV64_H
2 #define _ASM_X86_DIV64_H
3
4 #ifdef CONFIG_X86_32
5
6 #include <linux/types.h>
7 #include <linux/log2.h>
8
9 /*
10  * do_div() is NOT a C function. It wants to return
11  * two values (the quotient and the remainder), but
12  * since that doesn't work very well in C, what it
13  * does is:
14  *
15  * - modifies the 64-bit dividend _in_place_
16  * - returns the 32-bit remainder
17  *
18  * This ends up being the most efficient "calling
19  * convention" on x86.
20  */
21 #define do_div(n, base)                                         \
22 ({                                                              \
23         unsigned long __upper, __low, __high, __mod, __base;    \
24         __base = (base);                                        \
25         if (__builtin_constant_p(__base) && is_power_of_2(__base)) { \
26                 __mod = n & (__base - 1);                       \
27                 n >>= ilog2(__base);                            \
28         } else {                                                \
29                 asm("" : "=a" (__low), "=d" (__high) : "A" (n));\
30                 __upper = __high;                               \
31                 if (__high) {                                   \
32                         __upper = __high % (__base);            \
33                         __high = __high / (__base);             \
34                 }                                               \
35                 asm("divl %2" : "=a" (__low), "=d" (__mod)      \
36                         : "rm" (__base), "0" (__low), "1" (__upper));   \
37                 asm("" : "=A" (n) : "a" (__low), "d" (__high)); \
38         }                                                       \
39         __mod;                                                  \
40 })
41
42 static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
43 {
44         union {
45                 u64 v64;
46                 u32 v32[2];
47         } d = { dividend };
48         u32 upper;
49
50         upper = d.v32[1];
51         d.v32[1] = 0;
52         if (upper >= divisor) {
53                 d.v32[1] = upper / divisor;
54                 upper %= divisor;
55         }
56         asm ("divl %2" : "=a" (d.v32[0]), "=d" (*remainder) :
57                 "rm" (divisor), "0" (d.v32[0]), "1" (upper));
58         return d.v64;
59 }
60 #define div_u64_rem     div_u64_rem
61
62 #else
63 # include <asm-generic/div64.h>
64 #endif /* CONFIG_X86_32 */
65
66 #endif /* _ASM_X86_DIV64_H */