Warning, cross-references for /kernel/include/arch/i386-div64.h need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef __I386_DIV64_H__
0019 #define __I386_DIV64_H__
0020 #include"types.h"
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #define do_div(n, base) \
0037 ({ \
0038 unsigned long __upper, __low, __high, __mod, __base; \
0039 __base = (base); \
0040 asm("":"=a" (__low), "=d" (__high) : "A" (n)); \
0041 __upper = __high; \
0042 if (__high) { \
0043 __upper = __high % (__base); \
0044 __high = __high / (__base); \
0045 } \
0046 asm("divl %2":"=a" (__low), "=d" (__mod) \
0047 : "rm" (__base), "0" (__low), "1" (__upper)); \
0048 asm("":"=A" (n) : "a" (__low), "d" (__high)); \
0049 __mod; \
0050 })
0051
0052 static inline u64
0053 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
0054 {
0055 union {
0056 u64 v64;
0057 u32 v32[2];
0058 } d = { dividend };
0059 u32 upper;
0060
0061 upper = d.v32[1];
0062 d.v32[1] = 0;
0063 if (upper >= divisor) {
0064 d.v32[1] = upper / divisor;
0065 upper %= divisor;
0066 }
0067 asm ("divl %2" : "=a" (d.v32[0]), "=d" (*remainder) :
0068 "rm" (divisor), "0" (d.v32[0]), "1" (upper));
0069 return d.v64;
0070 }
0071 #define div_u64_rem div_u64_rem
0072
0073
0074 static inline uint64_t
0075 div64_64 (uint64_t dividend, uint64_t divisor)
0076 {
0077 uint32_t high, d;
0078
0079 high = divisor >> 32;
0080 if (high) {
0081 unsigned int shift = fls(high);
0082
0083 d = divisor >> shift;
0084 dividend >>= shift;
0085 } else
0086 d = divisor;
0087
0088 do_div(dividend, d);
0089
0090 return dividend;
0091 }
0092
0093 #endif
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104