0001
0002 #ifndef _ASM_GENERIC_DIV64_H
0003 #define _ASM_GENERIC_DIV64_H
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <linux/types.h>
0027 #include <linux/compiler.h>
0028
0029 #if BITS_PER_LONG == 64
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 # define do_div(n,base) ({ \
0046 uint32_t __base = (base); \
0047 uint32_t __rem; \
0048 __rem = ((uint64_t)(n)) % __base; \
0049 (n) = ((uint64_t)(n)) / __base; \
0050 __rem; \
0051 })
0052
0053 #elif BITS_PER_LONG == 32
0054
0055 #include <linux/log2.h>
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 #define __div64_const32(n, ___b) \
0066 ({ \
0067
0068
0069
0070
0071
0072
0073
0074
0075 \
0076 uint64_t ___res, ___x, ___t, ___m, ___n = (n); \
0077 uint32_t ___p, ___bias; \
0078 \
0079 \
0080 ___p = 1 << ilog2(___b); \
0081 \
0082 \
0083 ___m = (~0ULL / ___b) * ___p; \
0084 ___m += (((~0ULL % ___b + 1) * ___p) + ___b - 1) / ___b; \
0085 \
0086 \
0087 ___x = ~0ULL / ___b * ___b - 1; \
0088 \
0089 \
0090 ___res = ((___m & 0xffffffff) * (___x & 0xffffffff)) >> 32; \
0091 ___t = ___res += (___m & 0xffffffff) * (___x >> 32); \
0092 ___res += (___x & 0xffffffff) * (___m >> 32); \
0093 ___t = (___res < ___t) ? (1ULL << 32) : 0; \
0094 ___res = (___res >> 32) + ___t; \
0095 ___res += (___m >> 32) * (___x >> 32); \
0096 ___res /= ___p; \
0097 \
0098 \
0099 if (~0ULL % (___b / (___b & -___b)) == 0) { \
0100 \
0101 ___n /= (___b & -___b); \
0102 ___m = ~0ULL / (___b / (___b & -___b)); \
0103 ___p = 1; \
0104 ___bias = 1; \
0105 } else if (___res != ___x / ___b) { \
0106
0107
0108
0109
0110
0111
0112
0113 \
0114 ___bias = 1; \
0115 \
0116 ___m = (~0ULL / ___b) * ___p; \
0117 ___m += ((~0ULL % ___b + 1) * ___p) / ___b; \
0118 } else { \
0119
0120
0121
0122
0123 \
0124 uint32_t ___bits = -(___m & -___m); \
0125 ___bits |= ___m >> 32; \
0126 ___bits = (~___bits) << 1; \
0127
0128
0129
0130
0131
0132 \
0133 if (!___bits) { \
0134 ___p /= (___m & -___m); \
0135 ___m /= (___m & -___m); \
0136 } else { \
0137 ___p >>= ilog2(___bits); \
0138 ___m >>= ilog2(___bits); \
0139 } \
0140 \
0141 ___bias = 0; \
0142 } \
0143 \
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154 \
0155 ___res = __arch_xprod_64(___m, ___n, ___bias); \
0156 \
0157 ___res /= ___p; \
0158 })
0159
0160 #ifndef __arch_xprod_64
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171 static inline uint64_t __arch_xprod_64(const uint64_t m, uint64_t n, bool bias)
0172 {
0173 uint32_t m_lo = m;
0174 uint32_t m_hi = m >> 32;
0175 uint32_t n_lo = n;
0176 uint32_t n_hi = n >> 32;
0177 uint64_t res;
0178 uint32_t res_lo, res_hi, tmp;
0179
0180 if (!bias) {
0181 res = ((uint64_t)m_lo * n_lo) >> 32;
0182 } else if (!(m & ((1ULL << 63) | (1ULL << 31)))) {
0183
0184 res = (m + (uint64_t)m_lo * n_lo) >> 32;
0185 } else {
0186 res = m + (uint64_t)m_lo * n_lo;
0187 res_lo = res >> 32;
0188 res_hi = (res_lo < m_hi);
0189 res = res_lo | ((uint64_t)res_hi << 32);
0190 }
0191
0192 if (!(m & ((1ULL << 63) | (1ULL << 31)))) {
0193
0194 res += (uint64_t)m_lo * n_hi;
0195 res += (uint64_t)m_hi * n_lo;
0196 res >>= 32;
0197 } else {
0198 res += (uint64_t)m_lo * n_hi;
0199 tmp = res >> 32;
0200 res += (uint64_t)m_hi * n_lo;
0201 res_lo = res >> 32;
0202 res_hi = (res_lo < tmp);
0203 res = res_lo | ((uint64_t)res_hi << 32);
0204 }
0205
0206 res += (uint64_t)m_hi * n_hi;
0207
0208 return res;
0209 }
0210 #endif
0211
0212 #ifndef __div64_32
0213 extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
0214 #endif
0215
0216
0217
0218
0219 # define do_div(n,base) ({ \
0220 uint32_t __base = (base); \
0221 uint32_t __rem; \
0222 (void)(((typeof((n)) *)0) == ((uint64_t *)0)); \
0223 if (__builtin_constant_p(__base) && \
0224 is_power_of_2(__base)) { \
0225 __rem = (n) & (__base - 1); \
0226 (n) >>= ilog2(__base); \
0227 } else if (__builtin_constant_p(__base) && \
0228 __base != 0) { \
0229 uint32_t __res_lo, __n_lo = (n); \
0230 (n) = __div64_const32(n, __base); \
0231 \
0232 __res_lo = (n); \
0233 __rem = __n_lo - __res_lo * __base; \
0234 } else if (likely(((n) >> 32) == 0)) { \
0235 __rem = (uint32_t)(n) % __base; \
0236 (n) = (uint32_t)(n) / __base; \
0237 } else { \
0238 __rem = __div64_32(&(n), __base); \
0239 } \
0240 __rem; \
0241 })
0242
0243 #else
0244
0245 # error do_div() does not yet support the C64
0246
0247 #endif
0248
0249 #endif