Green shading in the line number column means the source is part of the translation unit, red means it is conditionally excluded. Highlighted line numbers link to the translation unit page. Highlighted macros link to the macro page.
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));\ __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 */ 67: