aboutsummaryrefslogtreecommitdiff
path: root/src/zlib/inffast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/zlib/inffast.c')
-rw-r--r--src/zlib/inffast.c89
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));