From: Nathan Moinvaziri Date: Wed, 5 May 2021 22:32:40 +0000 (-0700) Subject: Change bi_reverse to use a bit-twiddling hack for 240x speed improvement. X-Git-Tag: 2.1.0-beta1~579 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1118fa8ecc0b5522738b8d7781c813d47f607394;p=thirdparty%2Fzlib-ng.git Change bi_reverse to use a bit-twiddling hack for 240x speed improvement. --- diff --git a/deflate.h b/deflate.h index 03ea3126f..7243d1d9d 100644 --- a/deflate.h +++ b/deflate.h @@ -387,7 +387,7 @@ void Z_INTERNAL zng_tr_flush_block(deflate_state *s, char *buf, uint32_t stored_ void Z_INTERNAL zng_tr_flush_bits(deflate_state *s); void Z_INTERNAL zng_tr_align(deflate_state *s); void Z_INTERNAL zng_tr_stored_block(deflate_state *s, char *buf, uint32_t stored_len, int last); -unsigned Z_INTERNAL bi_reverse(unsigned code, int len); +uint16_t Z_INTERNAL bi_reverse(unsigned code, int len); void Z_INTERNAL flush_pending(PREFIX3(streamp) strm); #define d_code(dist) ((dist) < 256 ? zng_dist_code[dist] : zng_dist_code[256+((dist)>>7)]) /* Mapping from a distance to a distance code. dist is the distance - 1 and diff --git a/tools/maketrees.c b/tools/maketrees.c index 337f2fc07..c648a650c 100644 --- a/tools/maketrees.c +++ b/tools/maketrees.c @@ -90,7 +90,7 @@ static void tr_static_init(void) { /* The static distance tree is trivial: */ for (n = 0; n < D_CODES; n++) { static_dtree[n].Len = 5; - static_dtree[n].Code = (uint16_t)bi_reverse((unsigned)n, 5); + static_dtree[n].Code = bi_reverse((unsigned)n, 5); } } diff --git a/trees.c b/trees.c index efd4d49fb..2a5e2de94 100644 --- a/trees.c +++ b/trees.c @@ -305,7 +305,7 @@ Z_INTERNAL void gen_codes(ct_data *tree, int max_code, uint16_t *bl_count) { if (len == 0) continue; /* Now reverse the bits */ - tree[n].Code = (uint16_t)bi_reverse(next_code[len]++, len); + tree[n].Code = bi_reverse(next_code[len]++, len); Tracecv(tree != static_ltree, (stderr, "\nn %3d %c l %2d c %4x (%x) ", n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); @@ -806,17 +806,13 @@ static void bi_flush(deflate_state *s) { } /* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 + * Reverse the first len bits of a code using bit manipulation */ -Z_INTERNAL unsigned bi_reverse(unsigned code, int len) { +Z_INTERNAL uint16_t bi_reverse(unsigned code, int len) { /* code: the value to invert */ /* len: its bit length */ - Z_REGISTER unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; + Assert(len >= 1 && len <= 15, "code length must be 1-15"); +#define bitrev8(b) \ + (uint8_t)((((uint8_t)(b) * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32) + return (bitrev8(code >> 8) | (uint16_t)bitrev8(code) << 8) >> (16 - len); }