aboutsummaryrefslogtreecommitdiffstats
path: root/lib/zlib_inflate/inffast.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/zlib_inflate/inffast.c')
-rw-r--r--lib/zlib_inflate/inffast.c73
1 files changed, 62 insertions, 11 deletions
diff --git a/lib/zlib_inflate/inffast.c b/lib/zlib_inflate/inffast.c
index 8550b0c05d00..2c13ecc5bb2c 100644
--- a/lib/zlib_inflate/inffast.c
+++ b/lib/zlib_inflate/inffast.c
@@ -21,12 +21,31 @@
21 - Pentium III (Anderson) 21 - Pentium III (Anderson)
22 - M68060 (Nikl) 22 - M68060 (Nikl)
23 */ 23 */
24union uu {
25 unsigned short us;
26 unsigned char b[2];
27};
28
29/* Endian independed version */
30static inline unsigned short
31get_unaligned16(const unsigned short *p)
32{
33 union uu mm;
34 unsigned char *b = (unsigned char *)p;
35
36 mm.b[0] = b[0];
37 mm.b[1] = b[1];
38 return mm.us;
39}
40
24#ifdef POSTINC 41#ifdef POSTINC
25# define OFF 0 42# define OFF 0
26# define PUP(a) *(a)++ 43# define PUP(a) *(a)++
44# define UP_UNALIGNED(a) get_unaligned16((a)++)
27#else 45#else
28# define OFF 1 46# define OFF 1
29# define PUP(a) *++(a) 47# define PUP(a) *++(a)
48# define UP_UNALIGNED(a) get_unaligned16(++(a))
30#endif 49#endif
31 50
32/* 51/*
@@ -239,18 +258,50 @@ void inflate_fast(z_streamp strm, unsigned start)
239 } 258 }
240 } 259 }
241 else { 260 else {
261 unsigned short *sout;
262 unsigned long loops;
263
242 from = out - dist; /* copy direct from output */ 264 from = out - dist; /* copy direct from output */
243 do { /* minimum length is three */ 265 /* minimum length is three */
244 PUP(out) = PUP(from); 266 /* Align out addr */
245 PUP(out) = PUP(from); 267 if (!((long)(out - 1 + OFF) & 1)) {
246 PUP(out) = PUP(from); 268 PUP(out) = PUP(from);
247 len -= 3; 269 len--;
248 } while (len > 2); 270 }
249 if (len) { 271 sout = (unsigned short *)(out - OFF);
250 PUP(out) = PUP(from); 272 if (dist > 2) {
251 if (len > 1) 273 unsigned short *sfrom;
252 PUP(out) = PUP(from); 274
253 } 275 sfrom = (unsigned short *)(from - OFF);
276 loops = len >> 1;
277 do
278#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
279 PUP(sout) = PUP(sfrom);
280#else
281 PUP(sout) = UP_UNALIGNED(sfrom);
282#endif
283 while (--loops);
284 out = (unsigned char *)sout + OFF;
285 from = (unsigned char *)sfrom + OFF;
286 } else { /* dist == 1 or dist == 2 */
287 unsigned short pat16;
288
289 pat16 = *(sout-1+OFF);
290 if (dist == 1) {
291 union uu mm;
292 /* copy one char pattern to both bytes */
293 mm.us = pat16;
294 mm.b[0] = mm.b[1];
295 pat16 = mm.us;
296 }
297 loops = len >> 1;
298 do
299 PUP(sout) = pat16;
300 while (--loops);
301 out = (unsigned char *)sout + OFF;
302 }
303 if (len & 1)
304 PUP(out) = PUP(from);
254 } 305 }
255 } 306 }
256 else if ((op & 64) == 0) { /* 2nd level distance code */ 307 else if ((op & 64) == 0) { /* 2nd level distance code */