diff options
Diffstat (limited to 'src/zlib/inffast.c')
-rw-r--r-- | src/zlib/inffast.c | 89 |
1 files changed, 53 insertions, 36 deletions
diff --git a/src/zlib/inffast.c b/src/zlib/inffast.c index 0dbd1db..2f1d60b 100644 --- a/src/zlib/inffast.c +++ b/src/zlib/inffast.c @@ -1,5 +1,5 @@ /* inffast.c -- fast decoding - * Copyright (C) 1995-2017 Mark Adler + * Copyright (C) 1995-2008, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -8,9 +8,26 @@ #include "inflate.h" #include "inffast.h" -#ifdef ASMINF -# pragma message("Assembler code may have bugs -- use at your own risk") +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ #else +# define OFF 1 +# define PUP(a) *++(a) +#endif /* Decode literal, length, and distance codes and write out the resulting @@ -52,8 +69,8 @@ z_streamp strm; unsigned start; /* inflate()'s starting value for strm->avail_out */ { struct inflate_state FAR *state; - z_const unsigned char FAR *in; /* local strm->next_in */ - z_const unsigned char FAR *last; /* have enough input while in < last */ + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ unsigned char FAR *out; /* local strm->next_out */ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ unsigned char FAR *end; /* while out < end, enough space available */ @@ -79,9 +96,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ /* copy state to local variables */ state = (struct inflate_state FAR *)strm->state; - in = strm->next_in; + in = strm->next_in - OFF; last = in + (strm->avail_in - 5); - out = strm->next_out; + out = strm->next_out - OFF; beg = out - (start - strm->avail_out); end = out + (strm->avail_out - 257); #ifdef INFLATE_STRICT @@ -102,9 +119,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ input data or output space */ do { if (bits < 15) { - hold += (unsigned long)(*in++) << bits; + hold += (unsigned long)(PUP(in)) << bits; bits += 8; - hold += (unsigned long)(*in++) << bits; + hold += (unsigned long)(PUP(in)) << bits; bits += 8; } here = lcode[hold & lmask]; @@ -117,14 +134,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); - *out++ = (unsigned char)(here.val); + PUP(out) = (unsigned char)(here.val); } else if (op & 16) { /* length base */ len = (unsigned)(here.val); op &= 15; /* number of extra bits */ if (op) { if (bits < op) { - hold += (unsigned long)(*in++) << bits; + hold += (unsigned long)(PUP(in)) << bits; bits += 8; } len += (unsigned)hold & ((1U << op) - 1); @@ -133,9 +150,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ } Tracevv((stderr, "inflate: length %u\n", len)); if (bits < 15) { - hold += (unsigned long)(*in++) << bits; + hold += (unsigned long)(PUP(in)) << bits; bits += 8; - hold += (unsigned long)(*in++) << bits; + hold += (unsigned long)(PUP(in)) << bits; bits += 8; } here = dcode[hold & dmask]; @@ -148,10 +165,10 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ dist = (unsigned)(here.val); op &= 15; /* number of extra bits */ if (bits < op) { - hold += (unsigned long)(*in++) << bits; + hold += (unsigned long)(PUP(in)) << bits; bits += 8; if (bits < op) { - hold += (unsigned long)(*in++) << bits; + hold += (unsigned long)(PUP(in)) << bits; bits += 8; } } @@ -179,30 +196,30 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR if (len <= op - whave) { do { - *out++ = 0; + PUP(out) = 0; } while (--len); continue; } len -= op - whave; do { - *out++ = 0; + PUP(out) = 0; } while (--op > whave); if (op == 0) { from = out - dist; do { - *out++ = *from++; + PUP(out) = PUP(from); } while (--len); continue; } #endif } - from = window; + from = window - OFF; if (wnext == 0) { /* very common case */ from += wsize - op; if (op < len) { /* some from window */ len -= op; do { - *out++ = *from++; + PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } @@ -213,14 +230,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ if (op < len) { /* some from end of window */ len -= op; do { - *out++ = *from++; + PUP(out) = PUP(from); } while (--op); - from = window; + from = window - OFF; if (wnext < len) { /* some from start of window */ op = wnext; len -= op; do { - *out++ = *from++; + PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } @@ -231,35 +248,35 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ if (op < len) { /* some from window */ len -= op; do { - *out++ = *from++; + PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } while (len > 2) { - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); len -= 3; } if (len) { - *out++ = *from++; + PUP(out) = PUP(from); if (len > 1) - *out++ = *from++; + PUP(out) = PUP(from); } } else { from = out - dist; /* copy direct from output */ do { /* minimum length is three */ - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); len -= 3; } while (len > 2); if (len) { - *out++ = *from++; + PUP(out) = PUP(from); if (len > 1) - *out++ = *from++; + PUP(out) = PUP(from); } } } @@ -296,8 +313,8 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ hold &= (1U << bits) - 1; /* update state and return */ - strm->next_in = in; - strm->next_out = out; + strm->next_in = in + OFF; + strm->next_out = out + OFF; strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); strm->avail_out = (unsigned)(out < end ? 257 + (end - out) : 257 - (out - end)); |