| /* |
| * div_u64() compat |
| */ |
| |
| #ifndef MATH64_COMPAT_H |
| #define MATH64_COMPAT_H |
| |
| #if BITS_PER_LONG >= 64 |
| |
| static inline u64 div_u64_rem(u64 n, u32 div, u32 *rem) |
| { |
| *rem = n % div; |
| return n / div; |
| } |
| |
| static inline u64 div_u64(u64 n, u32 div) |
| { |
| return n / div; |
| } |
| |
| #elif defined(i386) |
| |
| static inline u64 div_u64_rem(u64 n, u32 div, u32 *rem) |
| { |
| u32 low, high; |
| |
| low = (u32)n; |
| high = n >> 32; |
| if (high) { |
| u32 high1 = high % div; |
| high /= div; |
| asm("divl %2" : "=a" (low), "=d" (*rem) : \ |
| "rm" (div), "a" (low), "d" (high1)); |
| return (u64)high << 32 | low; |
| } else { |
| *rem = low % div; |
| return low / div; |
| } |
| } |
| |
| static inline u64 div_u64(u64 n, u32 div) |
| { |
| u32 low, high; |
| |
| low = (u32)n; |
| high = n >> 32; |
| if (high) { |
| u32 high1 = high % div; |
| high /= div; |
| asm("divl %2" : "=a" (low) : \ |
| "rm" (div), "a" (low), "d" (high1)); |
| return (u64)high << 32 | low; |
| } else |
| return low / div; |
| } |
| |
| #else |
| |
| static inline void divl(u32 high, u32 low, u32 div, u32 *q, u32 *r) |
| { |
| u64 n = (u64)high << 32 | low; |
| u64 d = (u64)div << 31; |
| u32 q1 = 0; |
| int c = 32; |
| while (n > 0xffffffffU) { |
| q1 <<= 1; |
| if (n >= d) { |
| n -= d; |
| q1 |= 1; |
| } |
| d >>= 1; |
| c--; |
| } |
| q1 <<= c; |
| if (n) { |
| low = n; |
| *q = q1 | (low / div); |
| *r = low % div; |
| } else { |
| *r = 0; |
| *q = q1; |
| } |
| return; |
| } |
| |
| static inline u64 div_u64_rem(u64 n, u32 div, u32 *rem) |
| { |
| u32 low, high; |
| low = (u32)n; |
| high = n >> 32; |
| if (high) { |
| u32 high1 = high % div; |
| u32 low1 = low; |
| high /= div; |
| divl(high1, low1, div, &low, rem); |
| return (u64)high << 32 | low; |
| } else { |
| *rem = low % div; |
| return low / div; |
| } |
| } |
| |
| static inline u64 div_u64(u64 n, u32 div) |
| { |
| u32 low, high, rem; |
| low = (u32)n; |
| high = n >> 32; |
| if (high) { |
| u32 high1 = high % div; |
| u32 low1 = low; |
| high /= div; |
| divl(high1, low1, div, &low, rem); |
| return (u64)high << 32 | low; |
| } else { |
| return low / div; |
| } |
| } |
| |
| #endif |
| |
| #endif /* MATH64_COMPAT_H */ |