diff options
| -rw-r--r-- | include/asm-generic/bitsperlong.h | 4 | ||||
| -rw-r--r-- | lib/vsprintf.c | 281 |
2 files changed, 194 insertions, 91 deletions
diff --git a/include/asm-generic/bitsperlong.h b/include/asm-generic/bitsperlong.h index 4ae54e07de83..a7b0914348fd 100644 --- a/include/asm-generic/bitsperlong.h +++ b/include/asm-generic/bitsperlong.h | |||
| @@ -28,5 +28,9 @@ | |||
| 28 | #error Inconsistent word size. Check asm/bitsperlong.h | 28 | #error Inconsistent word size. Check asm/bitsperlong.h |
| 29 | #endif | 29 | #endif |
| 30 | 30 | ||
| 31 | #ifndef BITS_PER_LONG_LONG | ||
| 32 | #define BITS_PER_LONG_LONG 64 | ||
| 33 | #endif | ||
| 34 | |||
| 31 | #endif /* __KERNEL__ */ | 35 | #endif /* __KERNEL__ */ |
| 32 | #endif /* __ASM_GENERIC_BITS_PER_LONG */ | 36 | #endif /* __ASM_GENERIC_BITS_PER_LONG */ |
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index b8fbd275bc46..c3f36d415bdf 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
| @@ -112,106 +112,199 @@ int skip_atoi(const char **s) | |||
| 112 | /* Decimal conversion is by far the most typical, and is used | 112 | /* Decimal conversion is by far the most typical, and is used |
| 113 | * for /proc and /sys data. This directly impacts e.g. top performance | 113 | * for /proc and /sys data. This directly impacts e.g. top performance |
| 114 | * with many processes running. We optimize it for speed | 114 | * with many processes running. We optimize it for speed |
| 115 | * using code from | 115 | * using ideas described at <http://www.cs.uiowa.edu/~jones/bcd/divide.html> |
| 116 | * http://www.cs.uiowa.edu/~jones/bcd/decimal.html | 116 | * (with permission from the author, Douglas W. Jones). |
| 117 | * (with permission from the author, Douglas W. Jones). */ | 117 | */ |
| 118 | 118 | ||
| 119 | /* Formats correctly any integer in [0,99999]. | 119 | #if BITS_PER_LONG != 32 || BITS_PER_LONG_LONG != 64 |
| 120 | * Outputs from one to five digits depending on input. | 120 | /* Formats correctly any integer in [0, 999999999] */ |
| 121 | * On i386 gcc 4.1.2 -O2: ~250 bytes of code. */ | ||
| 122 | static noinline_for_stack | 121 | static noinline_for_stack |
| 123 | char *put_dec_trunc(char *buf, unsigned q) | 122 | char *put_dec_full9(char *buf, unsigned q) |
| 124 | { | 123 | { |
| 125 | unsigned d3, d2, d1, d0; | 124 | unsigned r; |
| 126 | d1 = (q>>4) & 0xf; | ||
| 127 | d2 = (q>>8) & 0xf; | ||
| 128 | d3 = (q>>12); | ||
| 129 | |||
| 130 | d0 = 6*(d3 + d2 + d1) + (q & 0xf); | ||
| 131 | q = (d0 * 0xcd) >> 11; | ||
| 132 | d0 = d0 - 10*q; | ||
| 133 | *buf++ = d0 + '0'; /* least significant digit */ | ||
| 134 | d1 = q + 9*d3 + 5*d2 + d1; | ||
| 135 | if (d1 != 0) { | ||
| 136 | q = (d1 * 0xcd) >> 11; | ||
| 137 | d1 = d1 - 10*q; | ||
| 138 | *buf++ = d1 + '0'; /* next digit */ | ||
| 139 | |||
| 140 | d2 = q + 2*d2; | ||
| 141 | if ((d2 != 0) || (d3 != 0)) { | ||
| 142 | q = (d2 * 0xd) >> 7; | ||
| 143 | d2 = d2 - 10*q; | ||
| 144 | *buf++ = d2 + '0'; /* next digit */ | ||
| 145 | |||
| 146 | d3 = q + 4*d3; | ||
| 147 | if (d3 != 0) { | ||
| 148 | q = (d3 * 0xcd) >> 11; | ||
| 149 | d3 = d3 - 10*q; | ||
| 150 | *buf++ = d3 + '0'; /* next digit */ | ||
| 151 | if (q != 0) | ||
| 152 | *buf++ = q + '0'; /* most sign. digit */ | ||
| 153 | } | ||
| 154 | } | ||
| 155 | } | ||
| 156 | 125 | ||
| 126 | /* | ||
| 127 | * Possible ways to approx. divide by 10 | ||
| 128 | * (x * 0x1999999a) >> 32 x < 1073741829 (multiply must be 64-bit) | ||
| 129 | * (x * 0xcccd) >> 19 x < 81920 (x < 262149 when 64-bit mul) | ||
| 130 | * (x * 0x6667) >> 18 x < 43699 | ||
| 131 | * (x * 0x3334) >> 17 x < 16389 | ||
| 132 | * (x * 0x199a) >> 16 x < 16389 | ||
| 133 | * (x * 0x0ccd) >> 15 x < 16389 | ||
| 134 | * (x * 0x0667) >> 14 x < 2739 | ||
| 135 | * (x * 0x0334) >> 13 x < 1029 | ||
| 136 | * (x * 0x019a) >> 12 x < 1029 | ||
| 137 | * (x * 0x00cd) >> 11 x < 1029 shorter code than * 0x67 (on i386) | ||
| 138 | * (x * 0x0067) >> 10 x < 179 | ||
| 139 | * (x * 0x0034) >> 9 x < 69 same | ||
| 140 | * (x * 0x001a) >> 8 x < 69 same | ||
| 141 | * (x * 0x000d) >> 7 x < 69 same, shortest code (on i386) | ||
| 142 | * (x * 0x0007) >> 6 x < 19 | ||
| 143 | * See <http://www.cs.uiowa.edu/~jones/bcd/divide.html> | ||
| 144 | */ | ||
| 145 | r = (q * (uint64_t)0x1999999a) >> 32; | ||
| 146 | *buf++ = (q - 10 * r) + '0'; /* 1 */ | ||
| 147 | q = (r * (uint64_t)0x1999999a) >> 32; | ||
| 148 | *buf++ = (r - 10 * q) + '0'; /* 2 */ | ||
| 149 | r = (q * (uint64_t)0x1999999a) >> 32; | ||
| 150 | *buf++ = (q - 10 * r) + '0'; /* 3 */ | ||
| 151 | q = (r * (uint64_t)0x1999999a) >> 32; | ||
| 152 | *buf++ = (r - 10 * q) + '0'; /* 4 */ | ||
| 153 | r = (q * (uint64_t)0x1999999a) >> 32; | ||
| 154 | *buf++ = (q - 10 * r) + '0'; /* 5 */ | ||
| 155 | /* Now value is under 10000, can avoid 64-bit multiply */ | ||
| 156 | q = (r * 0x199a) >> 16; | ||
| 157 | *buf++ = (r - 10 * q) + '0'; /* 6 */ | ||
| 158 | r = (q * 0xcd) >> 11; | ||
| 159 | *buf++ = (q - 10 * r) + '0'; /* 7 */ | ||
| 160 | q = (r * 0xcd) >> 11; | ||
| 161 | *buf++ = (r - 10 * q) + '0'; /* 8 */ | ||
| 162 | *buf++ = q + '0'; /* 9 */ | ||
| 157 | return buf; | 163 | return buf; |
| 158 | } | 164 | } |
| 159 | /* Same with if's removed. Always emits five digits */ | 165 | #endif |
| 166 | |||
| 167 | /* Similar to above but do not pad with zeros. | ||
| 168 | * Code can be easily arranged to print 9 digits too, but our callers | ||
| 169 | * always call put_dec_full9() instead when the number has 9 decimal digits. | ||
| 170 | */ | ||
| 160 | static noinline_for_stack | 171 | static noinline_for_stack |
| 161 | char *put_dec_full(char *buf, unsigned q) | 172 | char *put_dec_trunc8(char *buf, unsigned r) |
| 162 | { | 173 | { |
| 163 | /* BTW, if q is in [0,9999], 8-bit ints will be enough, */ | 174 | unsigned q; |
| 164 | /* but anyway, gcc produces better code with full-sized ints */ | 175 | |
| 165 | unsigned d3, d2, d1, d0; | 176 | /* Copy of previous function's body with added early returns */ |
| 166 | d1 = (q>>4) & 0xf; | 177 | q = (r * (uint64_t)0x1999999a) >> 32; |
| 167 | d2 = (q>>8) & 0xf; | 178 | *buf++ = (r - 10 * q) + '0'; /* 2 */ |
| 168 | d3 = (q>>12); | 179 | if (q == 0) |
| 180 | return buf; | ||
| 181 | r = (q * (uint64_t)0x1999999a) >> 32; | ||
| 182 | *buf++ = (q - 10 * r) + '0'; /* 3 */ | ||
| 183 | if (r == 0) | ||
| 184 | return buf; | ||
| 185 | q = (r * (uint64_t)0x1999999a) >> 32; | ||
| 186 | *buf++ = (r - 10 * q) + '0'; /* 4 */ | ||
| 187 | if (q == 0) | ||
| 188 | return buf; | ||
| 189 | r = (q * (uint64_t)0x1999999a) >> 32; | ||
| 190 | *buf++ = (q - 10 * r) + '0'; /* 5 */ | ||
| 191 | if (r == 0) | ||
| 192 | return buf; | ||
| 193 | q = (r * 0x199a) >> 16; | ||
| 194 | *buf++ = (r - 10 * q) + '0'; /* 6 */ | ||
| 195 | if (q == 0) | ||
| 196 | return buf; | ||
| 197 | r = (q * 0xcd) >> 11; | ||
| 198 | *buf++ = (q - 10 * r) + '0'; /* 7 */ | ||
| 199 | if (r == 0) | ||
| 200 | return buf; | ||
| 201 | q = (r * 0xcd) >> 11; | ||
| 202 | *buf++ = (r - 10 * q) + '0'; /* 8 */ | ||
| 203 | if (q == 0) | ||
| 204 | return buf; | ||
| 205 | *buf++ = q + '0'; /* 9 */ | ||
| 206 | return buf; | ||
| 207 | } | ||
| 169 | 208 | ||
| 170 | /* | 209 | /* There are two algorithms to print larger numbers. |
| 171 | * Possible ways to approx. divide by 10 | 210 | * One is generic: divide by 1000000000 and repeatedly print |
| 172 | * gcc -O2 replaces multiply with shifts and adds | 211 | * groups of (up to) 9 digits. It's conceptually simple, |
| 173 | * (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386) | 212 | * but requires a (unsigned long long) / 1000000000 division. |
| 174 | * (x * 0x67) >> 10: 1100111 | 213 | * |
| 175 | * (x * 0x34) >> 9: 110100 - same | 214 | * Second algorithm splits 64-bit unsigned long long into 16-bit chunks, |
| 176 | * (x * 0x1a) >> 8: 11010 - same | 215 | * manipulates them cleverly and generates groups of 4 decimal digits. |
| 177 | * (x * 0x0d) >> 7: 1101 - same, shortest code (on i386) | 216 | * It so happens that it does NOT require long long division. |
| 178 | */ | 217 | * |
| 179 | d0 = 6*(d3 + d2 + d1) + (q & 0xf); | 218 | * If long is > 32 bits, division of 64-bit values is relatively easy, |
| 180 | q = (d0 * 0xcd) >> 11; | 219 | * and we will use the first algorithm. |
| 181 | d0 = d0 - 10*q; | 220 | * If long long is > 64 bits (strange architecture with VERY large long long), |
| 182 | *buf++ = d0 + '0'; | 221 | * second algorithm can't be used, and we again use the first one. |
| 183 | d1 = q + 9*d3 + 5*d2 + d1; | 222 | * |
| 184 | q = (d1 * 0xcd) >> 11; | 223 | * Else (if long is 32 bits and long long is 64 bits) we use second one. |
| 185 | d1 = d1 - 10*q; | 224 | */ |
| 186 | *buf++ = d1 + '0'; | ||
| 187 | |||
| 188 | d2 = q + 2*d2; | ||
| 189 | q = (d2 * 0xd) >> 7; | ||
| 190 | d2 = d2 - 10*q; | ||
| 191 | *buf++ = d2 + '0'; | ||
| 192 | |||
| 193 | d3 = q + 4*d3; | ||
| 194 | q = (d3 * 0xcd) >> 11; /* - shorter code */ | ||
| 195 | /* q = (d3 * 0x67) >> 10; - would also work */ | ||
| 196 | d3 = d3 - 10*q; | ||
| 197 | *buf++ = d3 + '0'; | ||
| 198 | *buf++ = q + '0'; | ||
| 199 | 225 | ||
| 200 | return buf; | 226 | |
