[Zlib-devel] infnew-5 available for testing
Chris Anderson
christop at fellspt.charm.net
Wed Jan 15 23:56:01 EST 2003
I hacked up the gcc asm output of infnew-5/inffast.c pretty good, to see
what I could get out of it.
zbuflen 1024, clock 10.500, time 10.553
zbuflen 1024, clock 10.500, time 10.577
zbuflen 2048, clock 9.930, time 9.943
zbuflen 2048, clock 9.910, time 9.928
zbuflen 4096, clock 9.610, time 9.626
zbuflen 4096, clock 9.610, time 9.615
zbuflen 8192, clock 9.390, time 9.404
zbuflen 8192, clock 9.380, time 9.401
zbuflen 16384, clock 9.180, time 9.214
zbuflen 16384, clock 9.150, time 9.190
zbuflen 32768, clock 9.370, time 9.410
zbuflen 32768, clock 9.330, time 9.370
zbuflen 65536, clock 10.370, time 10.426
zbuflen 65536, clock 10.420, time 10.465
The critical paths in this code are only about 20 to 30 instructions long,
so a small change can have a pretty large effect. At this speed, my
compiler is only about 10% off the mark, so I doubt the wisdom of this
hack. Anyway, I attached a copy in case someone finds it useful or can
point out some wonderful x86 instruction I should have used.
-------------- next part --------------
/* infasm.S is based on:
*
* inffast.c -- fast decoding
* Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
.print "WARNING: infasm.S is test code, it's stability is questionable"
.file "infasm.S"
.globl inflate_fast
/* for profile counters */
#define P(name) /* .globl p_ ## name */
P(break_loop)
P(test_for_end_of_block)
P(test_for_second_level_length)
P(test_for_second_level_dist)
P(do_copy2)
P(do_copy1)
P(contiguous_in_window)
P(wrap_around_window)
P(check_window)
P(get_op_bits2)
P(dodist)
P(get_bits2)
P(decode_distance)
P(get_op_bits1)
P(test_for_length_base)
P(output_char)
P(get_bits1)
P(do_loop)
P(inflate_fast)
.text
.align 4,0
.L_mask: /* mask[N] = ( 1 << N ) - 1 */
.long 0
.long 1
.long 3
.long 7
.long 15
.long 31
.long 63
.long 127
.long 255
.long 511
.long 1023
.long 2047
.long 4095
.long 8191
.long 16383
.long 32767
.long 65535
.long 131071
.long 262143
.long 524287
.long 1048575
.long 2097151
.long 4194303
.long 8388607
.long 16777215
.long 33554431
.long 67108863
.long 134217727
.long 268435455
.long 536870911
.long 1073741823
.long 2147483647
.long 4294967295
.align 4,0
.L_invalid_literal_length_code_msg:
.string "invalid literal/length code"
.align 4,0
.L_invalid_distance_code_msg:
.string "invalid distance code"
.align 4,0
.L_invalid_distance_too_far_msg:
.string "invalid distance too far back"
.data
.align 4,0
#undef P
#define P(name) /* p_ ## name: .long 0 */
P(break_loop)
P(test_for_end_of_block)
P(test_for_second_level_length)
P(test_for_second_level_dist)
P(do_copy2)
P(do_copy1)
P(contiguous_in_window)
P(wrap_around_window)
P(check_window)
P(get_op_bits2)
P(dodist)
P(get_bits2)
P(decode_distance)
P(get_op_bits1)
P(test_for_length_base)
P(output_char)
P(get_bits1)
P(do_loop)
P(inflate_fast)
#undef P
#define P(name) /*incl p_ ## name */
.text
#define local_var_size 52 /* how much local space for vars */
#define strm_sp 72 /* first arg: z_stream * (local_var_size + 20) */
#define start_sp 76 /* second arg: unsigned int (local_var_size + 24) */
/*
* struct z_stream offsets, in zlib.h
*/
#define next_in_strm 0 /* strm->next_in */
#define avail_in_strm 4 /* strm->avail_in */
#define next_out_strm 12 /* strm->next_out */
#define avail_out_strm 16 /* strm->avail_out */
#define msg_strm 24 /* strm->msg */
#define state_strm 28 /* strm->state */
/*
* struct inflate_state offsets, in inflate.h
*/
#define mode_state 0 /* state->mode */
#define wsize_state 32 /* state->wsize */
#define write_state 36 /* state->write */
#define window_state 40 /* state->window */
#define hold_state 44 /* state->hold */
#define bits_state 48 /* state->bits */
#define lencode_state 64 /* state->lencode */
#define distcode_state 68 /* state->distcode */
#define lenbits_state 72 /* state->lenbits */
#define distbits_state 76 /* state->distbits */
#define last 48 /* unsigned char* */
#define end 44 /* unsigned char* */
#define beg 40 /* unsigned char* */
#define out 36 /* unsigned char* */
#define in 32 /* unsigned char* */
#define window 28 /* unsigned char* */
#define lcode 24 /* code* */
#define dcode 20 /* code* */
#define wsize 16 /* unsigned int */
#define write 12 /* unsigned int */
#define lmask 8 /* unsigned int */
#define dmask 4 /* unsigned int */
#define len 0 /* unsigned int */
/*
* typedef enum inflate_mode consts, in inflate.h
*/
#ifndef NO_GUNZIP
#define GUNZIP
#endif
#ifdef GUNZIP
#define INFLATE_MODE_TYPE 11 /* state->mode flags enum-ed in inflate.h */
#define INFLATE_MODE_BAD 26
#else
#define INFLATE_MODE_TYPE 3
#define INFLATE_MODE_BAD 17
#endif
.align 4,0x90
inflate_fast:
pushl %edi
pushl %esi
pushl %ebp
pushl %ebx
subl $local_var_size, %esp
cld /* save eflags? */
#define strm_r %esi
#define state_r %edi
movl strm_sp(%esp), strm_r
movl state_strm(strm_r), state_r
/* in = strm->next_in;
* out = strm->next_out;
* last = in + strm->avail_in - 5;
* beg = out - (start - strm->avail_out);
* end = out + (strm->avail_out - 257);
*/
movl next_in_strm(strm_r), %eax
movl next_out_strm(strm_r), %ebx
movl avail_in_strm(strm_r), %edx
movl avail_out_strm(strm_r), %ecx
movl start_sp(%esp), %ebp
addl %eax, %edx /* avail_in += next_in */
subl $5, %edx /* avail_in -= 5 */
subl %ecx, %ebp /* start -= avail_out */
negl %ebp /* start = -start */
addl %ebx, %ebp /* start += next_out */
subl $257, %ecx /* avail_out -= 257 */
addl %ebx, %ecx /* avail_out += out */
movl %eax, in(%esp)
movl %ebx, out(%esp)
movl %edx, last(%esp)
movl %ebp, beg(%esp)
movl %ecx, end(%esp)
/* wsize = state->wsize;
* write = state->write;
* window = state->window;
* hold = state->hold;
* bits = state->bits;
* lcode = state->lencode;
* dcode = state->distcode;
* lmask = ( 1 << state->lenbits ) - 1;
* dmask = ( 1 << state->distbits ) - 1;
*/
#define hold_r %ebp
#define bits_r %bl
#define bitslong_r %ebx
movl wsize_state(state_r), %eax
movl write_state(state_r), %ecx
movl window_state(state_r), %edx
movl hold_state(state_r), hold_r
movl bits_state(state_r), bitslong_r
movl %eax, wsize(%esp)
movl %ecx, write(%esp)
movl %edx, window(%esp)
movl lencode_state(state_r), %eax
movl distcode_state(state_r), %ecx
movl %eax, lcode(%esp)
movl %ecx, dcode(%esp)
movl lenbits_state(state_r), %ecx
movl distbits_state(state_r), %edx
movl .L_mask(,%ecx,4), %ecx
movl .L_mask(,%edx,4), %edx
movl %ecx, lmask(%esp)
movl %edx, dmask(%esp)
#undef strm_r
#undef state_r
#define in_r %esi
#define out_r %edi
movl in(%esp), in_r
movl out(%esp), out_r
P(inflate_fast)
.align 16,0x90
.L_do_loop:
P(do_loop)
/* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out
*
* do {
* if (bits < 15) {
* hold |= *((unsigned short *)in)++ << bits;
* bits += 16
* }
* this = lcode[hold & lmask]
*/
#if 0
cmpb $15, bits_r
jae .L_get_length_code /* if (15 <= bits) */
#endif
testb $48, bits_r
jnz .L_get_length_code /* if ((bits & 0x30) != 0) 38% */
P(get_bits1)
xorl %eax, %eax
movb bits_r, %cl /* %cl needs it for shifting */
lodsw
addb $16, bits_r /* bits += 16 */
shll %cl, %eax
orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */
.L_get_length_code:
movl lmask(%esp), %eax /* eax = lmask */
movl lcode(%esp), %ecx /* ecx = lcode */
andl hold_r, %eax /* eax &= hold */
movl (%ecx,%eax,4), %eax /* eax = lcode[hold & lmask] */
.L_dolen:
/* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out
*
* dolen:
* bits -= this.bits;
* hold >>= this.bits
*/
movb %ah, %cl /* cl = this.bits */
subb %ah, bits_r /* bits -= this.bits */
shrl %cl, hold_r /* hold >>= this.bits */
/* check if op is a literal
* if (op == 0) {
* PUP(out) = this.val;
* }
*/
testb %al, %al
jnz .L_test_for_length_base /* if (op != 0) 45.7% */
P(output_char)
shrl $16, %eax
stosb
.L_while_test:
/* while (in < last && out < end)
*/
cmpl out_r, end(%esp)
jbe .L_break_loop /* if (out >= end) */
cmpl in_r, last(%esp)
ja .L_do_loop /* if (in < last) */
jmp .L_break_loop
.L_test_for_length_base:
P(test_for_length_base)
#define len_r %edx
/* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = len
*
* else if (op & 16) {
* len = this.val
* op &= 15
* if (op) {
* if (op > bits) {
* hold |= *((unsigned short *)in)++ << bits;
* bits += 16
* }
* len += hold & mask[op];
* bits -= op;
* hold >>= op;
* }
*/
movl %eax, len_r /* len = this */
shrl $16, len_r /* len = this.val */
testb $16, %al
jz .L_test_for_second_level_length /* if ((op & 16) == 0) 8% */
andb $15, %al /* op &= 15 */
jz .L_save_len /* if (!op) */
movb %al, %ch
/*.L_check_len_bits:*/
cmpb %ch, bits_r
jae .L_add_bits_to_len /* if (op <= bits) */
P(get_op_bits1)
xorl %eax, %eax
movb bits_r, %cl /* %cl needs it for shifting */
lodsw
addb $16, bits_r /* bits += 16 */
shll %cl, %eax
orl %eax, hold_r /* hold |= *in++ << bits */
/*jmp .L_check_len_bits (if adding bits by $8 with lodsb) */
.L_add_bits_to_len:
movzbl %ch, %ecx
movl .L_mask(,%ecx,4), %eax /* eax = mask[op] */
subb %cl, bits_r
andl hold_r, %eax /* eax &= hold */
shrl %cl, hold_r
addl %eax, len_r /* len += hold & mask[op] */
.L_save_len:
movl len_r, len(%esp) /* save len */
.L_decode_distance:
P(decode_distance)
#define dist_r %edx
#undef len_r
/* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = dist
*
* if (bits < 15) {
* hold |= *((unsigned short *)in)++ << bits;
* bits += 16
* }
* this = dcode[hold & dmask];
* dodist:
* bits -= this.bits;
* hold >>= this.bits;
* op = this.op;
*/
#if 0
cmpb $15, bits_r
jae .L_get_distance_code /* if (15 <= bits) */
#endif
testb $48, bits_r
jnz .L_get_distance_code /* if ((bits & 0x30) != 0) 69% */
P(get_bits2)
xorl %eax, %eax
movb bits_r, %cl /* %cl needs it for shifting */
lodsw
addb $16, bits_r /* bits += 16 */
shll %cl, %eax
orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */
.L_get_distance_code:
movl dmask(%esp), %eax /* eax = dmask */
movl dcode(%esp), %ecx /* ecx = dcode */
andl hold_r, %eax /* eax &= hold */
movl (%ecx,%eax,4), %eax /* eax = dcode[hold & dmask] */
.L_dodist:
P(dodist)
movb %ah, %cl
subb %ah, bits_r /* bits -= this.bits */
shrl %cl, hold_r /* hold >>= this.bits */
/* if (op & 16) {
* dist = this.val
* op &= 15
* if (op > bits) {
* hold |= *((unsigned short *)in)++ << bits;
* bits += 16
* }
* dist += hold & mask[op];
* bits -= op;
* hold >>= op;
*/
movl %eax, dist_r /* dist = this */
shrl $16, dist_r /* dist = this.val */
testb $16, %al /* if ((op & 16) == 0) */
jz .L_test_for_second_level_dist
andb $15, %al /* op &= 15 */
movb %al, %ch
/*.L_check_dist_bits:*/
cmpb %ch, bits_r
jae .L_add_bits_to_dist /* if (op <= bits) 97.6% */
P(get_op_bits2)
xorl %eax, %eax
movb bits_r, %cl /* %cl needs it for shifting */
lodsw
addb $16, bits_r /* bits += 16 */
shll %cl, %eax
orl %eax, hold_r /* hold |= *in++ << bits */
/*jmp .L_check_dist_bits (if adding bits by $8 with lodsb) */
.L_add_bits_to_dist:
movzbl %ch, %ecx
movl .L_mask(,%ecx,4), %eax /* eax = mask[op] */
subb %cl, bits_r
andl hold_r, %eax /* eax &= hold */
shrl %cl, hold_r
addl %eax, dist_r /* dist += hold & mask[op] */
.L_check_window:
P(check_window)
/* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
* %ecx = nbytes
*
* nbytes = out - beg;
* if (dist > nbytes) {
* if (dist > wsize) {
* invalid distance
* }
* from = window;
* nbytes = dist - nbytes;
* if (write == 0) {
* from += wsize - nbytes;
*/
#define nbytes_r %ecx
movl out_r, nbytes_r
movl in_r, in(%esp) /* save in so from can use it's reg */
subl beg(%esp), nbytes_r /* nbytes = out - beg */
cmpl dist_r, nbytes_r
jae .L_do_copy2 /* if (dist <= nbytes) 95.8% */
#define from_r %esi
#undef in_r
movl wsize(%esp), %eax /* prepare for dist compare */
negl nbytes_r /* nbytes = -nbytes */
movl window(%esp), from_r /* from = window */
cmpl dist_r, %eax
jb .L_invalid_distance_too_far /* if (dist < wsize) */
addl dist_r, nbytes_r /* nbytes = dist - nbytes */
cmpl $0, write(%esp)
jne .L_wrap_around_window /* if (write != 0) */
subl nbytes_r, %eax
addl %eax, from_r /* from += wsize - nbytes */
#define len_r %eax
/* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
* %ecx = nbytes, %eax = len
*
* if (nbytes < len) {
* len -= nbytes;
* do {
* PUP(out) = PUP(from);
* } while (--nbytes);
* from = out - dist;
* }
* }
*/
movl len(%esp), len_r
cmpl nbytes_r, len_r
jbe .L_do_copy1 /* if (nbytes >= len) */
subl nbytes_r, len_r /* len -= nbytes */
rep movsb /* ecx = nbytes, esi = from, edi = out*/
movl out_r, from_r
subl dist_r, from_r /* from = out - dist */
jmp .L_do_copy1
.L_wrap_around_window:
P(wrap_around_window)
#define write_r %eax
/* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
* %ecx = nbytes, %eax = write, %eax = len
*
* else if (write < nbytes) {
* from += wsize + write - nbytes;
* nbytes -= write;
* if (nbytes < len) {
* len -= nbytes;
* do {
* PUP(out) = PUP(from);
* } while (--nbytes);
* from = window;
* nbytes = write;
* if (nbytes < len) {
* len -= nbytes;
* do {
* PUP(out) = PUP(from);
* } while(--nbytes);
* from = out - dist;
* }
* }
* }
*/
movl write(%esp), write_r
cmpl write_r, nbytes_r
jbe .L_contiguous_in_window /* if (write >= nbytes) */
addl wsize(%esp), from_r
addl write_r, from_r
subl nbytes_r, from_r /* from += wsize + write - nbytes */
subl write_r, nbytes_r /* nbytes -= write */
#undef write_r
movl len(%esp), len_r
cmpl nbytes_r, len_r
jbe .L_do_copy1 /* if (nbytes >= len) */
subl nbytes_r, len_r /* len -= nbytes */
rep movsb /* ecx = nbytes, esi = from, edi = out*/
movl window(%esp), from_r /* from = window */
movl write(%esp), nbytes_r /* nbytes = write */
cmpl nbytes_r, len_r
jbe .L_do_copy1 /* if (nbytes >= len) */
subl nbytes_r, len_r /* len -= nbytes */
rep movsb /* ecx = nbytes, esi = from, edi = out*/
movl out_r, from_r
subl dist_r, from_r /* from = out - dist */
jmp .L_do_copy1
.L_contiguous_in_window:
P(contiguous_in_window)
#define write_r %eax
/* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
* %ecx = nbytes, %eax = write, %eax = len
*
* else {
* from += write - nbytes;
* if (nbytes < len) {
* len -= nbytes;
* do {
* PUP(out) = PUP(from);
* } while (--nbytes);
* from = out - dist;
* }
* }
*/
addl write_r, from_r
subl nbytes_r, from_r /* from += write - nbytes */
#undef write_r
movl len(%esp), len_r
cmpl nbytes_r, len_r
jbe .L_do_copy1 /* if (nbytes >= len) */
subl nbytes_r, len_r /* len -= nbytes */
rep movsb /* ecx = nbytes, esi = from, edi = out*/
movl out_r, from_r
subl dist_r, from_r /* from = out - dist */
.L_do_copy1:
P(do_copy1)
#undef nbytes_r
#define in_r %esi
/* regs: %esi = from, %esi = in, %ebp = hold, %bl = bits, %edi = out
* %eax = len
*
* while (len > 0) {
* PUP(out) = PUP(from);
* len--;
* }
* }
* else {
* (.L_do_copy2)
* }
* } while (in < last && out < end);
*/
movl len_r, %ecx /* ecx = len for rep movsb */
rep movsb /* ecx = len, esi = from, edi = out */
movl in(%esp), in_r /* move in back to %esi, toss from */
jmp .L_while_test
.L_do_copy2:
P(do_copy2)
/* regs: %esi = from, %esi = in, %ebp = hold, %bl = bits, %edi = out
* %edx = dist
* }
* else {
* from = out - dist;
* while (len > 0) {
* PUP(out) = PUP(from);
* len--;
* }
* }
* } while (in < last && out < end);
*/
movl len(%esp), %ecx /* ecx = len for rep movsb */
movl out_r, from_r
subl dist_r, from_r /* from = out - dist */
rep movsb
movl in(%esp), in_r /* move in back to %esi, toss from */
jmp .L_while_test
#undef len_r
#undef from_r
#undef dist_r
.L_test_for_second_level_dist:
P(test_for_second_level_dist)
/* else if ((op & 64) == 0) {
* this = dcode[this.val + (hold & mask[op])];
* }
*/
testb $64, %al
jnz .L_invalid_distance_code /* if ((op & 64) != 0) */
movzbl %al, %eax /* eax = op */
movl dcode(%esp), %ecx /* ecx = dcode */
movl .L_mask(,%eax,4), %eax /* eax = mask[op] */
andl hold_r, %eax /* eax &= hold */
addl %edx, %eax /* eax += this.val */
movl (%ecx,%eax,4), %eax /* eax = dcode[val + (hold&mask[op])] */
jmp .L_dodist
.L_invalid_distance_code:
/* else {
* strm->msg = "invalid distance code";
* state->mode = BAD;
* }
*/
movl $.L_invalid_distance_code_msg, %ecx
movl $INFLATE_MODE_BAD, %edx
jmp .L_update_stream_state
.L_test_for_second_level_length:
P(test_for_second_level_length)
/* else if ((op & 64) == 0) {
* this = lcode[this.val + (hold & mask[op])];
* }
*/
testb $64, %al
jnz .L_test_for_end_of_block /* if ((op & 64) != 0) */
movzbl %al, %eax /* eax = op */
movl lcode(%esp), %ecx /* ecx = lcode */
movl .L_mask(,%eax,4), %eax /* eax = mask[op] */
andl hold_r, %eax /* eax &= hold */
addl %edx, %eax /* eax += this.val */
movl (%ecx,%eax,4), %eax /* eax = lcode[val + (hold&mask[op])] */
jmp .L_dolen
.L_test_for_end_of_block:
P(test_for_end_of_block)
/* else if (op & 32) {
* state->mode = TYPE;
* break;
* }
*/
testb $32, %al
jz .L_invalid_literal_length_code /* if ((op & 32) == 0) */
movl $0, %ecx
movl $INFLATE_MODE_TYPE, %edx
jmp .L_update_stream_state
.L_invalid_literal_length_code:
/* else {
* strm->msg = "invalid literal/length code";
* state->mode = BAD;
* }
*/
movl $.L_invalid_literal_length_code_msg, %ecx
movl $INFLATE_MODE_BAD, %edx
jmp .L_update_stream_state
.L_invalid_distance_too_far:
/* strm->msg = "invalid distance too far back";
* state->mode = BAD;
*/
movl in(%esp), in_r /* from_r has in's reg, put in back */
movl $.L_invalid_distance_too_far_msg, %ecx
movl $INFLATE_MODE_BAD, %edx
jmp .L_update_stream_state
.L_update_stream_state:
/* set strm->msg = %ecx, strm->state->mode = %edx */
movl strm_sp(%esp), %eax
testl %ecx, %ecx /* if (msg != NULL) */
jz .L_skip_msg
movl %ecx, msg_strm(%eax) /* strm->msg = msg */
.L_skip_msg:
movl state_strm(%eax), %eax /* state = strm->state */
movl %edx, mode_state(%eax) /* state->mode = edx (BAD | TYPE) */
.L_break_loop:
P(break_loop)
#define strm_r %eax
#define state_r %edx
/* len = bits >> 3;
* in -= len;
* bits -= len << 3;
* hold &= (1U << bits) - 1;
* state->hold = hold;
* state->bits = bits;
* strm->next_in = in;
* strm->next_out = out;
*/
movl strm_sp(%esp), strm_r
movl bitslong_r, %ecx
movl state_strm(strm_r), state_r
shrl $3, %ecx
subl %ecx, in_r
shll $3, %ecx
subb %cl, bits_r
movl .L_mask(,bitslong_r,4), %ecx /* ecx = mask[bits] */
andl %ecx, hold_r
movl bitslong_r, bits_state(state_r)
movl hold_r, hold_state(state_r)
movl out_r, next_out_strm(strm_r)
movl in_r, next_in_strm(strm_r)
#undef hold_r
#undef bits_r
#undef bitslong_r
#define last_r %ebx
/* strm->avail_in = in < last ? 5 + (last - in) : 5 - (in - last) */
movl last(%esp), last_r
cmpl in_r, last_r
jbe .L_last_is_smaller /* if (in >= last) */
subl in_r, last_r /* last -= in */
addl $5, last_r /* last += 5 */
movl last_r, avail_in_strm(strm_r)
jmp .L_fixup_out
.L_last_is_smaller:
subl last_r, in_r /* in -= last */
negl in_r /* in = -in */
addl $5, in_r /* in += 5 */
movl in_r, avail_in_strm(strm_r)
#undef last_r
#define end_r %ebx
.L_fixup_out:
/* strm->avail_out = out < end ? 257 + (end - out) : 257 - (out - end)*/
movl end(%esp), end_r
cmpl out_r, end_r
jbe .L_end_is_smaller /* if (out >= end) */
subl out_r, end_r /* end -= out */
addl $257, end_r /* end += 257 */
movl end_r, avail_out_strm(strm_r)
jmp .L_done
.L_end_is_smaller:
subl end_r, out_r /* out -= end */
negl out_r /* out = -out */
addl $257, out_r /* out += 257 */
movl out_r, avail_out_strm(strm_r)
#undef end_r
.L_done:
addl $local_var_size, %esp
popl %ebx
popl %ebp
popl %esi
popl %edi
ret
.type inflate_fast, at function
.size inflate_fast,.-inflate_fast
More information about the Zlib-devel
mailing list