~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/x86/include/asm/div64.h

Version: ~ [ linux-5.15-rc5 ] ~ [ linux-5.14.11 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.72 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.152 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.210 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.250 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.286 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.288 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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), "" (__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), "" (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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp