aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/asm-generic/bitsperlong.h4
-rw-r--r--lib/vsprintf.c281
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. */
122static noinline_for_stack 121static noinline_for_stack
123char *put_dec_trunc(char *buf, unsigned q) 122char *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 */
160static noinline_for_stack 171static noinline_for_stack
161char *put_dec_full(char *buf, unsigned q) 172char *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