Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
inffas86.c
Go to the documentation of this file.
1 /* inffas86.c is a hand tuned assembler version of
2  *
3  * inffast.c -- fast decoding
4  * Copyright (C) 1995-2003 Mark Adler
5  * For conditions of distribution and use, see copyright notice in zlib.h
6  *
7  * Copyright (C) 2003 Chris Anderson <christop@charm.net>
8  * Please use the copyright conditions above.
9  *
10  * Dec-29-2003 -- I added AMD64 inflate asm support. This version is also
11  * slightly quicker on x86 systems because, instead of using rep movsb to copy
12  * data, it uses rep movsw, which moves data in 2-byte chunks instead of single
13  * bytes. I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates
14  * from http://fedora.linux.duke.edu/fc1_x86_64
15  * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with
16  * 1GB ram. The 64-bit version is about 4% faster than the 32-bit version,
17  * when decompressing mozilla-source-1.3.tar.gz.
18  *
19  * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
20  * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at
21  * the moment. I have successfully compiled and tested this code with gcc2.96,
22  * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S
23  * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
24  * enabled. I will attempt to merge the MMX code into this version. Newer
25  * versions of this and inffast.S can be found at
26  * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
27  */
28 
29 #include "zutil.h"
30 #include "inftrees.h"
31 #include "inflate.h"
32 #include "inffast.h"
33 
34 /* Mark Adler's comments from inffast.c: */
35 
36 /*
37  Decode literal, length, and distance codes and write out the resulting
38  literal and match bytes until either not enough input or output is
39  available, an end-of-block is encountered, or a data error is encountered.
40  When large enough input and output buffers are supplied to inflate(), for
41  example, a 16K input buffer and a 64K output buffer, more than 95% of the
42  inflate execution time is spent in this routine.
43 
44  Entry assumptions:
45 
46  state->mode == LEN
47  strm->avail_in >= 6
48  strm->avail_out >= 258
49  start >= strm->avail_out
50  state->bits < 8
51 
52  On return, state->mode is one of:
53 
54  LEN -- ran out of enough output space or enough available input
55  TYPE -- reached end of block code, inflate() to interpret next block
56  BAD -- error in block data
57 
58  Notes:
59 
60  - The maximum input bits used by a length/distance pair is 15 bits for the
61  length code, 5 bits for the length extra, 15 bits for the distance code,
62  and 13 bits for the distance extra. This totals 48 bits, or six bytes.
63  Therefore if strm->avail_in >= 6, then there is enough input to avoid
64  checking for available input while decoding.
65 
66  - The maximum bytes that a single length/distance pair can output is 258
67  bytes, which is the maximum length that can be coded. inflate_fast()
68  requires strm->avail_out >= 258 for each loop to avoid checking for
69  output space.
70  */
71 void inflate_fast(strm, start)
72 z_streamp strm;
73 unsigned start; /* inflate()'s starting value for strm->avail_out */
74 {
75  struct inflate_state FAR *state;
76  struct inffast_ar {
77 /* 64 32 x86 x86_64 */
78 /* ar offset register */
79 /* 0 0 */ void *esp; /* esp save */
80 /* 8 4 */ void *ebp; /* ebp save */
81 /* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */
82 /* 24 12 */ unsigned char FAR *last; /* r9 while in < last */
83 /* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */
84 /* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */
85 /* 48 24 */ unsigned char FAR *end; /* r10 while out < end */
86 /* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */
87 /* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */
88 /* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */
89 /* 80 40 */ unsigned long hold; /* edx rdx local strm->hold */
90 /* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */
91 /* 92 48 */ unsigned wsize; /* window size */
92 /* 96 52 */ unsigned write; /* window write index */
93 /*100 56 */ unsigned lmask; /* r12 mask for lcode */
94 /*104 60 */ unsigned dmask; /* r13 mask for dcode */
95 /*108 64 */ unsigned len; /* r14 match length */
96 /*112 68 */ unsigned dist; /* r15 match distance */
97 /*116 72 */ unsigned status; /* set when state chng*/
98  } ar;
99 
100 #if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
101 #define PAD_AVAIL_IN 6
102 #define PAD_AVAIL_OUT 258
103 #else
104 #define PAD_AVAIL_IN 5
105 #define PAD_AVAIL_OUT 257
106 #endif
107 
108  /* copy state to local variables */
109  state = (struct inflate_state FAR *)strm->state;
110  ar.in = strm->next_in;
111  ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);
112  ar.out = strm->next_out;
113  ar.beg = ar.out - (start - strm->avail_out);
114  ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);
115  ar.wsize = state->wsize;
116  ar.write = state->wnext;
117  ar.window = state->window;
118  ar.hold = state->hold;
119  ar.bits = state->bits;
120  ar.lcode = state->lencode;
121  ar.dcode = state->distcode;
122  ar.lmask = (1U << state->lenbits) - 1;
123  ar.dmask = (1U << state->distbits) - 1;
124 
125  /* decode literals and length/distances until end-of-block or not enough
126  input data or output space */
127 
128  /* align in on 1/2 hold size boundary */
129  while (((unsigned long)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {
130  ar.hold += (unsigned long)*ar.in++ << ar.bits;
131  ar.bits += 8;
132  }
133 
134 #if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
135  __asm__ __volatile__ (
136 " leaq %0, %%rax\n"
137 " movq %%rbp, 8(%%rax)\n" /* save regs rbp and rsp */
138 " movq %%rsp, (%%rax)\n"
139 " movq %%rax, %%rsp\n" /* make rsp point to &ar */
140 " movq 16(%%rsp), %%rsi\n" /* rsi = in */
141 " movq 32(%%rsp), %%rdi\n" /* rdi = out */
142 " movq 24(%%rsp), %%r9\n" /* r9 = last */
143 " movq 48(%%rsp), %%r10\n" /* r10 = end */
144 " movq 64(%%rsp), %%rbp\n" /* rbp = lcode */
145 " movq 72(%%rsp), %%r11\n" /* r11 = dcode */
146 " movq 80(%%rsp), %%rdx\n" /* rdx = hold */
147 " movl 88(%%rsp), %%ebx\n" /* ebx = bits */
148 " movl 100(%%rsp), %%r12d\n" /* r12d = lmask */
149 " movl 104(%%rsp), %%r13d\n" /* r13d = dmask */
150  /* r14d = len */
151  /* r15d = dist */
152 " cld\n"
153 " cmpq %%rdi, %%r10\n"
154 " je .L_one_time\n" /* if only one decode left */
155 " cmpq %%rsi, %%r9\n"
156 " je .L_one_time\n"
157 " jmp .L_do_loop\n"
158 
159 ".L_one_time:\n"
160 " movq %%r12, %%r8\n" /* r8 = lmask */
161 " cmpb $32, %%bl\n"
162 " ja .L_get_length_code_one_time\n"
163 
164 " lodsl\n" /* eax = *(uint *)in++ */
165 " movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
166 " addb $32, %%bl\n" /* bits += 32 */
167 " shlq %%cl, %%rax\n"
168 " orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */
169 " jmp .L_get_length_code_one_time\n"
170 
171 ".align 32,0x90\n"
172 ".L_while_test:\n"
173 " cmpq %%rdi, %%r10\n"
174 " jbe .L_break_loop\n"
175 " cmpq %%rsi, %%r9\n"
176 " jbe .L_break_loop\n"
177 
178 ".L_do_loop:\n"
179 " movq %%r12, %%r8\n" /* r8 = lmask */
180 " cmpb $32, %%bl\n"
181 " ja .L_get_length_code\n" /* if (32 < bits) */
182 
183 " lodsl\n" /* eax = *(uint *)in++ */
184 " movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
185 " addb $32, %%bl\n" /* bits += 32 */
186 " shlq %%cl, %%rax\n"
187 " orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */
188 
189 ".L_get_length_code:\n"
190 " andq %%rdx, %%r8\n" /* r8 &= hold */
191 " movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */
192 
193 " movb %%ah, %%cl\n" /* cl = this.bits */
194 " subb %%ah, %%bl\n" /* bits -= this.bits */
195 " shrq %%cl, %%rdx\n" /* hold >>= this.bits */
196 
197 " testb %%al, %%al\n"
198 " jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */
199 
200 " movq %%r12, %%r8\n" /* r8 = lmask */
201 " shrl $16, %%eax\n" /* output this.val char */
202 " stosb\n"
203 
204 ".L_get_length_code_one_time:\n"
205 " andq %%rdx, %%r8\n" /* r8 &= hold */
206 " movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */
207 
208 ".L_dolen:\n"
209 " movb %%ah, %%cl\n" /* cl = this.bits */
210 " subb %%ah, %%bl\n" /* bits -= this.bits */
211 " shrq %%cl, %%rdx\n" /* hold >>= this.bits */
212 
213 " testb %%al, %%al\n"
214 " jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */
215 
216 " shrl $16, %%eax\n" /* output this.val char */
217 " stosb\n"
218 " jmp .L_while_test\n"
219 
220 ".align 32,0x90\n"
221 ".L_test_for_length_base:\n"
222 " movl %%eax, %%r14d\n" /* len = this */
223 " shrl $16, %%r14d\n" /* len = this.val */
224 " movb %%al, %%cl\n"
225 
226 " testb $16, %%al\n"
227 " jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */
228 " andb $15, %%cl\n" /* op &= 15 */
229 " jz .L_decode_distance\n" /* if (!op) */
230 
231 ".L_add_bits_to_len:\n"
232 " subb %%cl, %%bl\n"
233 " xorl %%eax, %%eax\n"
234 " incl %%eax\n"
235 " shll %%cl, %%eax\n"
236 " decl %%eax\n"
237 " andl %%edx, %%eax\n" /* eax &= hold */
238 " shrq %%cl, %%rdx\n"
239 " addl %%eax, %%r14d\n" /* len += hold & mask[op] */
240 
241 ".L_decode_distance:\n"
242 " movq %%r13, %%r8\n" /* r8 = dmask */
243 " cmpb $32, %%bl\n"
244 " ja .L_get_distance_code\n" /* if (32 < bits) */
245 
246 " lodsl\n" /* eax = *(uint *)in++ */
247 " movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
248 " addb $32, %%bl\n" /* bits += 32 */
249 " shlq %%cl, %%rax\n"
250 " orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */
251 
252 ".L_get_distance_code:\n"
253 " andq %%rdx, %%r8\n" /* r8 &= hold */
254 " movl (%%r11,%%r8,4), %%eax\n" /* eax = dcode[hold & dmask] */
255 
256 ".L_dodist:\n"
257 " movl %%eax, %%r15d\n" /* dist = this */
258 " shrl $16, %%r15d\n" /* dist = this.val */
259 " movb %%ah, %%cl\n"
260 " subb %%ah, %%bl\n" /* bits -= this.bits */
261 " shrq %%cl, %%rdx\n" /* hold >>= this.bits */
262 " movb %%al, %%cl\n" /* cl = this.op */
263 
264 " testb $16, %%al\n" /* if ((op & 16) == 0) */
265 " jz .L_test_for_second_level_dist\n"
266 " andb $15, %%cl\n" /* op &= 15 */
267 " jz .L_check_dist_one\n"
268 
269 ".L_add_bits_to_dist:\n"
270 " subb %%cl, %%bl\n"
271 " xorl %%eax, %%eax\n"
272 " incl %%eax\n"
273 " shll %%cl, %%eax\n"
274 " decl %%eax\n" /* (1 << op) - 1 */
275 " andl %%edx, %%eax\n" /* eax &= hold */
276 " shrq %%cl, %%rdx\n"
277 " addl %%eax, %%r15d\n" /* dist += hold & ((1 << op) - 1) */
278 
279 ".L_check_window:\n"
280 " movq %%rsi, %%r8\n" /* save in so from can use it's reg */
281 " movq %%rdi, %%rax\n"
282 " subq 40(%%rsp), %%rax\n" /* nbytes = out - beg */
283 
284 " cmpl %%r15d, %%eax\n"
285 " jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */
286 
287 " movl %%r14d, %%ecx\n" /* ecx = len */
288 " movq %%rdi, %%rsi\n"
289 " subq %%r15, %%rsi\n" /* from = out - dist */
290 
291 " sarl %%ecx\n"
292 " jnc .L_copy_two\n" /* if len % 2 == 0 */
293 
294 " rep movsw\n"
295 " movb (%%rsi), %%al\n"
296 " movb %%al, (%%rdi)\n"
297 " incq %%rdi\n"
298 
299 " movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */
300 " jmp .L_while_test\n"
301 
302 ".L_copy_two:\n"
303 " rep movsw\n"
304 " movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */
305 " jmp .L_while_test\n"
306 
307 ".align 32,0x90\n"
308 ".L_check_dist_one:\n"
309 " cmpl $1, %%r15d\n" /* if dist 1, is a memset */
310 " jne .L_check_window\n"
311 " cmpq %%rdi, 40(%%rsp)\n" /* if out == beg, outside window */
312 " je .L_check_window\n"
313 
314 " movl %%r14d, %%ecx\n" /* ecx = len */
315 " movb -1(%%rdi), %%al\n"
316 " movb %%al, %%ah\n"
317 
318 " sarl %%ecx\n"
319 " jnc .L_set_two\n"
320 " movb %%al, (%%rdi)\n"
321 " incq %%rdi\n"
322 
323 ".L_set_two:\n"
324 " rep stosw\n"
325 " jmp .L_while_test\n"
326 
327 ".align 32,0x90\n"
328 ".L_test_for_second_level_length:\n"
329 " testb $64, %%al\n"
330 " jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */
331 
332 " xorl %%eax, %%eax\n"
333 " incl %%eax\n"
334 " shll %%cl, %%eax\n"
335 " decl %%eax\n"
336 " andl %%edx, %%eax\n" /* eax &= hold */
337 " addl %%r14d, %%eax\n" /* eax += len */
338 " movl (%%rbp,%%rax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/
339 " jmp .L_dolen\n"
340 
341 ".align 32,0x90\n"
342 ".L_test_for_second_level_dist:\n"
343 " testb $64, %%al\n"
344 " jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */
345 
346 " xorl %%eax, %%eax\n"
347 " incl %%eax\n"
348 " shll %%cl, %%eax\n"
349 " decl %%eax\n"
350 " andl %%edx, %%eax\n" /* eax &= hold */
351 " addl %%r15d, %%eax\n" /* eax += dist */
352 " movl (%%r11,%%rax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/
353 " jmp .L_dodist\n"
354 
355 ".align 32,0x90\n"
356 ".L_clip_window:\n"
357 " movl %%eax, %%ecx\n" /* ecx = nbytes */
358 " movl 92(%%rsp), %%eax\n" /* eax = wsize, prepare for dist cmp */
359 " negl %%ecx\n" /* nbytes = -nbytes */
360 
361 " cmpl %%r15d, %%eax\n"
362 " jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */
363 
364 " addl %%r15d, %%ecx\n" /* nbytes = dist - nbytes */
365 " cmpl $0, 96(%%rsp)\n"
366 " jne .L_wrap_around_window\n" /* if (write != 0) */
367 
368 " movq 56(%%rsp), %%rsi\n" /* from = window */
369 " subl %%ecx, %%eax\n" /* eax -= nbytes */
370 " addq %%rax, %%rsi\n" /* from += wsize - nbytes */
371 
372 " movl %%r14d, %%eax\n" /* eax = len */
373 " cmpl %%ecx, %%r14d\n"
374 " jbe .L_do_copy\n" /* if (nbytes >= len) */
375 
376 " subl %%ecx, %%eax\n" /* eax -= nbytes */
377 " rep movsb\n"
378 " movq %%rdi, %%rsi\n"
379 " subq %%r15, %%rsi\n" /* from = &out[ -dist ] */
380 " jmp .L_do_copy\n"
381 
382 ".align 32,0x90\n"
383 ".L_wrap_around_window:\n"
384 " movl 96(%%rsp), %%eax\n" /* eax = write */
385 " cmpl %%eax, %%ecx\n"
386 " jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */
387 
388 " movl 92(%%rsp), %%esi\n" /* from = wsize */
389 " addq 56(%%rsp), %%rsi\n" /* from += window */
390 " addq %%rax, %%rsi\n" /* from += write */
391 " subq %%rcx, %%rsi\n" /* from -= nbytes */
392 " subl %%eax, %%ecx\n" /* nbytes -= write */
393 
394 " movl %%r14d, %%eax\n" /* eax = len */
395 " cmpl %%ecx, %%eax\n"
396 " jbe .L_do_copy\n" /* if (nbytes >= len) */
397 
398 " subl %%ecx, %%eax\n" /* len -= nbytes */
399 " rep movsb\n"
400 " movq 56(%%rsp), %%rsi\n" /* from = window */
401 " movl 96(%%rsp), %%ecx\n" /* nbytes = write */
402 " cmpl %%ecx, %%eax\n"
403 " jbe .L_do_copy\n" /* if (nbytes >= len) */
404 
405 " subl %%ecx, %%eax\n" /* len -= nbytes */
406 " rep movsb\n"
407 " movq %%rdi, %%rsi\n"
408 " subq %%r15, %%rsi\n" /* from = out - dist */
409 " jmp .L_do_copy\n"
410 
411 ".align 32,0x90\n"
412 ".L_contiguous_in_window:\n"
413 " movq 56(%%rsp), %%rsi\n" /* rsi = window */
414 " addq %%rax, %%rsi\n"
415 " subq %%rcx, %%rsi\n" /* from += write - nbytes */
416 
417 " movl %%r14d, %%eax\n" /* eax = len */
418 " cmpl %%ecx, %%eax\n"
419 " jbe .L_do_copy\n" /* if (nbytes >= len) */
420 
421 " subl %%ecx, %%eax\n" /* len -= nbytes */
422 " rep movsb\n"
423 " movq %%rdi, %%rsi\n"
424 " subq %%r15, %%rsi\n" /* from = out - dist */
425 " jmp .L_do_copy\n" /* if (nbytes >= len) */
426 
427 ".align 32,0x90\n"
428 ".L_do_copy:\n"
429 " movl %%eax, %%ecx\n" /* ecx = len */
430 " rep movsb\n"
431 
432 " movq %%r8, %%rsi\n" /* move in back to %esi, toss from */
433 " jmp .L_while_test\n"
434 
435 ".L_test_for_end_of_block:\n"
436 " testb $32, %%al\n"
437 " jz .L_invalid_literal_length_code\n"
438 " movl $1, 116(%%rsp)\n"
439 " jmp .L_break_loop_with_status\n"
440 
441 ".L_invalid_literal_length_code:\n"
442 " movl $2, 116(%%rsp)\n"
443 " jmp .L_break_loop_with_status\n"
444 
445 ".L_invalid_distance_code:\n"
446 " movl $3, 116(%%rsp)\n"
447 " jmp .L_break_loop_with_status\n"
448 
449 ".L_invalid_distance_too_far:\n"
450 " movl $4, 116(%%rsp)\n"
451 " jmp .L_break_loop_with_status\n"
452 
453 ".L_break_loop:\n"
454 " movl $0, 116(%%rsp)\n"
455 
456 ".L_break_loop_with_status:\n"
457 /* put in, out, bits, and hold back into ar and pop esp */
458 " movq %%rsi, 16(%%rsp)\n" /* in */
459 " movq %%rdi, 32(%%rsp)\n" /* out */
460 " movl %%ebx, 88(%%rsp)\n" /* bits */
461 " movq %%rdx, 80(%%rsp)\n" /* hold */
462 " movq (%%rsp), %%rax\n" /* restore rbp and rsp */
463 " movq 8(%%rsp), %%rbp\n"
464 " movq %%rax, %%rsp\n"
465  :
466  : "m" (ar)
467  : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi",
468  "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
469  );
470 #elif ( defined( __GNUC__ ) || defined( __ICC ) ) && defined( __i386 )
471  __asm__ __volatile__ (
472 " leal %0, %%eax\n"
473 " movl %%esp, (%%eax)\n" /* save esp, ebp */
474 " movl %%ebp, 4(%%eax)\n"
475 " movl %%eax, %%esp\n"
476 " movl 8(%%esp), %%esi\n" /* esi = in */
477 " movl 16(%%esp), %%edi\n" /* edi = out */
478 " movl 40(%%esp), %%edx\n" /* edx = hold */
479 " movl 44(%%esp), %%ebx\n" /* ebx = bits */
480 " movl 32(%%esp), %%ebp\n" /* ebp = lcode */
481 
482 " cld\n"
483 " jmp .L_do_loop\n"
484 
485 ".align 32,0x90\n"
486 ".L_while_test:\n"
487 " cmpl %%edi, 24(%%esp)\n" /* out < end */
488 " jbe .L_break_loop\n"
489 " cmpl %%esi, 12(%%esp)\n" /* in < last */
490 " jbe .L_break_loop\n"
491 
492 ".L_do_loop:\n"
493 " cmpb $15, %%bl\n"
494 " ja .L_get_length_code\n" /* if (15 < bits) */
495 
496 " xorl %%eax, %%eax\n"
497 " lodsw\n" /* al = *(ushort *)in++ */
498 " movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
499 " addb $16, %%bl\n" /* bits += 16 */
500 " shll %%cl, %%eax\n"
501 " orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
502 
503 ".L_get_length_code:\n"
504 " movl 56(%%esp), %%eax\n" /* eax = lmask */
505 " andl %%edx, %%eax\n" /* eax &= hold */
506 " movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[hold & lmask] */
507 
508 ".L_dolen:\n"
509 " movb %%ah, %%cl\n" /* cl = this.bits */
510 " subb %%ah, %%bl\n" /* bits -= this.bits */
511 " shrl %%cl, %%edx\n" /* hold >>= this.bits */
512 
513 " testb %%al, %%al\n"
514 " jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */
515 
516 " shrl $16, %%eax\n" /* output this.val char */
517 " stosb\n"
518 " jmp .L_while_test\n"
519 
520 ".align 32,0x90\n"
521 ".L_test_for_length_base:\n"
522 " movl %%eax, %%ecx\n" /* len = this */
523 " shrl $16, %%ecx\n" /* len = this.val */
524 " movl %%ecx, 64(%%esp)\n" /* save len */
525 " movb %%al, %%cl\n"
526 
527 " testb $16, %%al\n"
528 " jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */
529 " andb $15, %%cl\n" /* op &= 15 */
530 " jz .L_decode_distance\n" /* if (!op) */
531 " cmpb %%cl, %%bl\n"
532 " jae .L_add_bits_to_len\n" /* if (op <= bits) */
533 
534 " movb %%cl, %%ch\n" /* stash op in ch, freeing cl */
535 " xorl %%eax, %%eax\n"
536 " lodsw\n" /* al = *(ushort *)in++ */
537 " movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
538 " addb $16, %%bl\n" /* bits += 16 */
539 " shll %%cl, %%eax\n"
540 " orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
541 " movb %%ch, %%cl\n" /* move op back to ecx */
542 
543 ".L_add_bits_to_len:\n"
544 " subb %%cl, %%bl\n"
545 " xorl %%eax, %%eax\n"
546 " incl %%eax\n"
547 " shll %%cl, %%eax\n"
548 " decl %%eax\n"
549 " andl %%edx, %%eax\n" /* eax &= hold */
550 " shrl %%cl, %%edx\n"
551 " addl %%eax, 64(%%esp)\n" /* len += hold & mask[op] */
552 
553 ".L_decode_distance:\n"
554 " cmpb $15, %%bl\n"
555 " ja .L_get_distance_code\n" /* if (15 < bits) */
556 
557 " xorl %%eax, %%eax\n"
558 " lodsw\n" /* al = *(ushort *)in++ */
559 " movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
560 " addb $16, %%bl\n" /* bits += 16 */
561 " shll %%cl, %%eax\n"
562 " orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
563 
564 ".L_get_distance_code:\n"
565 " movl 60(%%esp), %%eax\n" /* eax = dmask */
566 " movl 36(%%esp), %%ecx\n" /* ecx = dcode */
567 " andl %%edx, %%eax\n" /* eax &= hold */
568 " movl (%%ecx,%%eax,4), %%eax\n"/* eax = dcode[hold & dmask] */
569 
570 ".L_dodist:\n"
571 " movl %%eax, %%ebp\n" /* dist = this */
572 " shrl $16, %%ebp\n" /* dist = this.val */
573 " movb %%ah, %%cl\n"
574 " subb %%ah, %%bl\n" /* bits -= this.bits */
575 " shrl %%cl, %%edx\n" /* hold >>= this.bits */
576 " movb %%al, %%cl\n" /* cl = this.op */
577 
578 " testb $16, %%al\n" /* if ((op & 16) == 0) */
579 " jz .L_test_for_second_level_dist\n"
580 " andb $15, %%cl\n" /* op &= 15 */
581 " jz .L_check_dist_one\n"
582 " cmpb %%cl, %%bl\n"
583 " jae .L_add_bits_to_dist\n" /* if (op <= bits) 97.6% */
584 
585 " movb %%cl, %%ch\n" /* stash op in ch, freeing cl */
586 " xorl %%eax, %%eax\n"
587 " lodsw\n" /* al = *(ushort *)in++ */
588 " movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
589 " addb $16, %%bl\n" /* bits += 16 */
590 " shll %%cl, %%eax\n"
591 " orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
592 " movb %%ch, %%cl\n" /* move op back to ecx */
593 
594 ".L_add_bits_to_dist:\n"
595 " subb %%cl, %%bl\n"
596 " xorl %%eax, %%eax\n"
597 " incl %%eax\n"
598 " shll %%cl, %%eax\n"
599 " decl %%eax\n" /* (1 << op) - 1 */
600 " andl %%edx, %%eax\n" /* eax &= hold */
601 " shrl %%cl, %%edx\n"
602 " addl %%eax, %%ebp\n" /* dist += hold & ((1 << op) - 1) */
603 
604 ".L_check_window:\n"
605 " movl %%esi, 8(%%esp)\n" /* save in so from can use it's reg */
606 " movl %%edi, %%eax\n"
607 " subl 20(%%esp), %%eax\n" /* nbytes = out - beg */
608 
609 " cmpl %%ebp, %%eax\n"
610 " jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */
611 
612 " movl 64(%%esp), %%ecx\n" /* ecx = len */
613 " movl %%edi, %%esi\n"
614 " subl %%ebp, %%esi\n" /* from = out - dist */
615 
616 " sarl %%ecx\n"
617 " jnc .L_copy_two\n" /* if len % 2 == 0 */
618 
619 " rep movsw\n"
620 " movb (%%esi), %%al\n"
621 " movb %%al, (%%edi)\n"
622 " incl %%edi\n"
623 
624 " movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */
625 " movl 32(%%esp), %%ebp\n" /* ebp = lcode */
626 " jmp .L_while_test\n"
627 
628 ".L_copy_two:\n"
629 " rep movsw\n"
630 " movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */
631 " movl 32(%%esp), %%ebp\n" /* ebp = lcode */
632 " jmp .L_while_test\n"
633 
634 ".align 32,0x90\n"
635 ".L_check_dist_one:\n"
636 " cmpl $1, %%ebp\n" /* if dist 1, is a memset */
637 " jne .L_check_window\n"
638 " cmpl %%edi, 20(%%esp)\n"
639 " je .L_check_window\n" /* out == beg, if outside window */
640 
641 " movl 64(%%esp), %%ecx\n" /* ecx = len */
642 " movb -1(%%edi), %%al\n"
643 " movb %%al, %%ah\n"
644 
645 " sarl %%ecx\n"
646 " jnc .L_set_two\n"
647 " movb %%al, (%%edi)\n"
648 " incl %%edi\n"
649 
650 ".L_set_two:\n"
651 " rep stosw\n"
652 " movl 32(%%esp), %%ebp\n" /* ebp = lcode */
653 " jmp .L_while_test\n"
654 
655 ".align 32,0x90\n"
656 ".L_test_for_second_level_length:\n"
657 " testb $64, %%al\n"
658 " jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */
659 
660 " xorl %%eax, %%eax\n"
661 " incl %%eax\n"
662 " shll %%cl, %%eax\n"
663 " decl %%eax\n"
664 " andl %%edx, %%eax\n" /* eax &= hold */
665 " addl 64(%%esp), %%eax\n" /* eax += len */
666 " movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/
667 " jmp .L_dolen\n"
668 
669 ".align 32,0x90\n"
670 ".L_test_for_second_level_dist:\n"
671 " testb $64, %%al\n"
672 " jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */
673 
674 " xorl %%eax, %%eax\n"
675 " incl %%eax\n"
676 " shll %%cl, %%eax\n"
677 " decl %%eax\n"
678 " andl %%edx, %%eax\n" /* eax &= hold */
679 " addl %%ebp, %%eax\n" /* eax += dist */
680 " movl 36(%%esp), %%ecx\n" /* ecx = dcode */
681 " movl (%%ecx,%%eax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/
682 " jmp .L_dodist\n"
683 
684 ".align 32,0x90\n"
685 ".L_clip_window:\n"
686 " movl %%eax, %%ecx\n"
687 " movl 48(%%esp), %%eax\n" /* eax = wsize */
688 " negl %%ecx\n" /* nbytes = -nbytes */
689 " movl 28(%%esp), %%esi\n" /* from = window */
690 
691 " cmpl %%ebp, %%eax\n"
692 " jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */
693 
694 " addl %%ebp, %%ecx\n" /* nbytes = dist - nbytes */
695 " cmpl $0, 52(%%esp)\n"
696 " jne .L_wrap_around_window\n" /* if (write != 0) */
697 
698 " subl %%ecx, %%eax\n"
699 " addl %%eax, %%esi\n" /* from += wsize - nbytes */
700 
701 " movl 64(%%esp), %%eax\n" /* eax = len */
702 " cmpl %%ecx, %%eax\n"
703 " jbe .L_do_copy\n" /* if (nbytes >= len) */
704 
705 " subl %%ecx, %%eax\n" /* len -= nbytes */
706 " rep movsb\n"
707 " movl %%edi, %%esi\n"
708 " subl %%ebp, %%esi\n" /* from = out - dist */
709 " jmp .L_do_copy\n"
710 
711 ".align 32,0x90\n"
712 ".L_wrap_around_window:\n"
713 " movl 52(%%esp), %%eax\n" /* eax = write */
714 " cmpl %%eax, %%ecx\n"
715 " jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */
716 
717 " addl 48(%%esp), %%esi\n" /* from += wsize */
718 " addl %%eax, %%esi\n" /* from += write */
719 " subl %%ecx, %%esi\n" /* from -= nbytes */
720 " subl %%eax, %%ecx\n" /* nbytes -= write */
721 
722 " movl 64(%%esp), %%eax\n" /* eax = len */
723 " cmpl %%ecx, %%eax\n"
724 " jbe .L_do_copy\n" /* if (nbytes >= len) */
725 
726 " subl %%ecx, %%eax\n" /* len -= nbytes */
727 " rep movsb\n"
728 " movl 28(%%esp), %%esi\n" /* from = window */
729 " movl 52(%%esp), %%ecx\n" /* nbytes = write */
730 " cmpl %%ecx, %%eax\n"
731 " jbe .L_do_copy\n" /* if (nbytes >= len) */
732 
733 " subl %%ecx, %%eax\n" /* len -= nbytes */
734 " rep movsb\n"
735 " movl %%edi, %%esi\n"
736 " subl %%ebp, %%esi\n" /* from = out - dist */
737 " jmp .L_do_copy\n"
738 
739 ".align 32,0x90\n"
740 ".L_contiguous_in_window:\n"
741 " addl %%eax, %%esi\n"
742 " subl %%ecx, %%esi\n" /* from += write - nbytes */
743 
744 " movl 64(%%esp), %%eax\n" /* eax = len */
745 " cmpl %%ecx, %%eax\n"
746 " jbe .L_do_copy\n" /* if (nbytes >= len) */
747 
748 " subl %%ecx, %%eax\n" /* len -= nbytes */
749 " rep movsb\n"
750 " movl %%edi, %%esi\n"
751 " subl %%ebp, %%esi\n" /* from = out - dist */
752 " jmp .L_do_copy\n" /* if (nbytes >= len) */
753 
754 ".align 32,0x90\n"
755 ".L_do_copy:\n"
756 " movl %%eax, %%ecx\n"
757 " rep movsb\n"
758 
759 " movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */
760 " movl 32(%%esp), %%ebp\n" /* ebp = lcode */
761 " jmp .L_while_test\n"
762 
763 ".L_test_for_end_of_block:\n"
764 " testb $32, %%al\n"
765 " jz .L_invalid_literal_length_code\n"
766 " movl $1, 72(%%esp)\n"
767 " jmp .L_break_loop_with_status\n"
768 
769 ".L_invalid_literal_length_code:\n"
770 " movl $2, 72(%%esp)\n"
771 " jmp .L_break_loop_with_status\n"
772 
773 ".L_invalid_distance_code:\n"
774 " movl $3, 72(%%esp)\n"
775 " jmp .L_break_loop_with_status\n"
776 
777 ".L_invalid_distance_too_far:\n"
778 " movl 8(%%esp), %%esi\n"
779 " movl $4, 72(%%esp)\n"
780 " jmp .L_break_loop_with_status\n"
781 
782 ".L_break_loop:\n"
783 " movl $0, 72(%%esp)\n"
784 
785 ".L_break_loop_with_status:\n"
786 /* put in, out, bits, and hold back into ar and pop esp */
787 " movl %%esi, 8(%%esp)\n" /* save in */
788 " movl %%edi, 16(%%esp)\n" /* save out */
789 " movl %%ebx, 44(%%esp)\n" /* save bits */
790 " movl %%edx, 40(%%esp)\n" /* save hold */
791 " movl 4(%%esp), %%ebp\n" /* restore esp, ebp */
792 " movl (%%esp), %%esp\n"
793  :
794  : "m" (ar)
795  : "memory", "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"
796  );
797 #elif defined( _MSC_VER ) && ! defined( _M_AMD64 )
798  __asm {
799  lea eax, ar
800  mov [eax], esp /* save esp, ebp */
801  mov [eax+4], ebp
802  mov esp, eax
803  mov esi, [esp+8] /* esi = in */
804  mov edi, [esp+16] /* edi = out */
805  mov edx, [esp+40] /* edx = hold */
806  mov ebx, [esp+44] /* ebx = bits */
807  mov ebp, [esp+32] /* ebp = lcode */
808 
809  cld
810  jmp L_do_loop
811 
812 ALIGN 4
813 L_while_test:
814  cmp [esp+24], edi
815  jbe L_break_loop
816  cmp [esp+12], esi
817  jbe L_break_loop
818 
819 L_do_loop:
820  cmp bl, 15
821  ja L_get_length_code /* if (15 < bits) */
822 
823  xor eax, eax
824  lodsw /* al = *(ushort *)in++ */
825  mov cl, bl /* cl = bits, needs it for shifting */
826  add bl, 16 /* bits += 16 */
827  shl eax, cl
828  or edx, eax /* hold |= *((ushort *)in)++ << bits */
829 
830 L_get_length_code:
831  mov eax, [esp+56] /* eax = lmask */
832  and eax, edx /* eax &= hold */
833  mov eax, [ebp+eax*4] /* eax = lcode[hold & lmask] */
834 
835 L_dolen:
836  mov cl, ah /* cl = this.bits */
837  sub bl, ah /* bits -= this.bits */
838  shr edx, cl /* hold >>= this.bits */
839 
840  test al, al
841  jnz L_test_for_length_base /* if (op != 0) 45.7% */
842 
843  shr eax, 16 /* output this.val char */
844  stosb
845  jmp L_while_test
846 
847 ALIGN 4
848 L_test_for_length_base:
849  mov ecx, eax /* len = this */
850  shr ecx, 16 /* len = this.val */
851  mov [esp+64], ecx /* save len */
852  mov cl, al
853 
854  test al, 16
855  jz L_test_for_second_level_length /* if ((op & 16) == 0) 8% */
856  and cl, 15 /* op &= 15 */
857  jz L_decode_distance /* if (!op) */
858  cmp bl, cl
859  jae L_add_bits_to_len /* if (op <= bits) */
860 
861  mov ch, cl /* stash op in ch, freeing cl */
862  xor eax, eax
863  lodsw /* al = *(ushort *)in++ */
864  mov cl, bl /* cl = bits, needs it for shifting */
865  add bl, 16 /* bits += 16 */
866  shl eax, cl
867  or edx, eax /* hold |= *((ushort *)in)++ << bits */
868  mov cl, ch /* move op back to ecx */
869 
870 L_add_bits_to_len:
871  sub bl, cl
872  xor eax, eax
873  inc eax
874  shl eax, cl
875  dec eax
876  and eax, edx /* eax &= hold */
877  shr edx, cl
878  add [esp+64], eax /* len += hold & mask[op] */
879 
880 L_decode_distance:
881  cmp bl, 15
882  ja L_get_distance_code /* if (15 < bits) */
883 
884  xor eax, eax
885  lodsw /* al = *(ushort *)in++ */
886  mov cl, bl /* cl = bits, needs it for shifting */
887  add bl, 16 /* bits += 16 */
888  shl eax, cl
889  or edx, eax /* hold |= *((ushort *)in)++ << bits */
890 
891 L_get_distance_code:
892  mov eax, [esp+60] /* eax = dmask */
893  mov ecx, [esp+36] /* ecx = dcode */
894  and eax, edx /* eax &= hold */
895  mov eax, [ecx+eax*4]/* eax = dcode[hold & dmask] */
896 
897 L_dodist:
898  mov ebp, eax /* dist = this */
899  shr ebp, 16 /* dist = this.val */
900  mov cl, ah
901  sub bl, ah /* bits -= this.bits */
902  shr edx, cl /* hold >>= this.bits */
903  mov cl, al /* cl = this.op */
904 
905  test al, 16 /* if ((op & 16) == 0) */
906  jz L_test_for_second_level_dist
907  and cl, 15 /* op &= 15 */
908  jz L_check_dist_one
909  cmp bl, cl
910  jae L_add_bits_to_dist /* if (op <= bits) 97.6% */
911 
912  mov ch, cl /* stash op in ch, freeing cl */
913  xor eax, eax
914  lodsw /* al = *(ushort *)in++ */
915  mov cl, bl /* cl = bits, needs it for shifting */
916  add bl, 16 /* bits += 16 */
917  shl eax, cl
918  or edx, eax /* hold |= *((ushort *)in)++ << bits */
919  mov cl, ch /* move op back to ecx */
920 
921 L_add_bits_to_dist:
922  sub bl, cl
923  xor eax, eax
924  inc eax
925  shl eax, cl
926  dec eax /* (1 << op) - 1 */
927  and eax, edx /* eax &= hold */
928  shr edx, cl
929  add ebp, eax /* dist += hold & ((1 << op) - 1) */
930 
931 L_check_window:
932  mov [esp+8], esi /* save in so from can use it's reg */
933  mov eax, edi
934  sub eax, [esp+20] /* nbytes = out - beg */
935 
936  cmp eax, ebp
937  jb L_clip_window /* if (dist > nbytes) 4.2% */
938 
939  mov ecx, [esp+64] /* ecx = len */
940  mov esi, edi
941  sub esi, ebp /* from = out - dist */
942 
943  sar ecx, 1
944  jnc L_copy_two
945 
946  rep movsw
947  mov al, [esi]
948  mov [edi], al
949  inc edi
950 
951  mov esi, [esp+8] /* move in back to %esi, toss from */
952  mov ebp, [esp+32] /* ebp = lcode */
953  jmp L_while_test
954 
955 L_copy_two:
956  rep movsw
957  mov esi, [esp+8] /* move in back to %esi, toss from */
958  mov ebp, [esp+32] /* ebp = lcode */
959  jmp L_while_test
960 
961 ALIGN 4
962 L_check_dist_one:
963  cmp ebp, 1 /* if dist 1, is a memset */
964  jne L_check_window
965  cmp [esp+20], edi
966  je L_check_window /* out == beg, if outside window */
967 
968  mov ecx, [esp+64] /* ecx = len */
969  mov al, [edi-1]
970  mov ah, al
971 
972  sar ecx, 1
973  jnc L_set_two
974  mov [edi], al /* memset out with from[-1] */
975  inc edi
976 
977 L_set_two:
978  rep stosw
979  mov ebp, [esp+32] /* ebp = lcode */
980  jmp L_while_test
981 
982 ALIGN 4
983 L_test_for_second_level_length:
984  test al, 64
985  jnz L_test_for_end_of_block /* if ((op & 64) != 0) */
986 
987  xor eax, eax
988  inc eax
989  shl eax, cl
990  dec eax
991  and eax, edx /* eax &= hold */
992  add eax, [esp+64] /* eax += len */
993  mov eax, [ebp+eax*4] /* eax = lcode[val+(hold&mask[op])]*/
994  jmp L_dolen
995 
996 ALIGN 4
997 L_test_for_second_level_dist:
998  test al, 64
999  jnz L_invalid_distance_code /* if ((op & 64) != 0) */
1000 
1001  xor eax, eax
1002  inc eax
1003  shl eax, cl
1004  dec eax
1005  and eax, edx /* eax &= hold */
1006  add eax, ebp /* eax += dist */
1007  mov ecx, [esp+36] /* ecx = dcode */
1008  mov eax, [ecx+eax*4] /* eax = dcode[val+(hold&mask[op])]*/
1009  jmp L_dodist
1010 
1011 ALIGN 4
1012 L_clip_window:
1013  mov ecx, eax
1014  mov eax, [esp+48] /* eax = wsize */
1015  neg ecx /* nbytes = -nbytes */
1016  mov esi, [esp+28] /* from = window */
1017 
1018  cmp eax, ebp
1019  jb L_invalid_distance_too_far /* if (dist > wsize) */
1020 
1021  add ecx, ebp /* nbytes = dist - nbytes */
1022  cmp dword ptr [esp+52], 0
1023  jne L_wrap_around_window /* if (write != 0) */
1024 
1025  sub eax, ecx
1026  add esi, eax /* from += wsize - nbytes */
1027 
1028  mov eax, [esp+64] /* eax = len */
1029  cmp eax, ecx
1030  jbe L_do_copy /* if (nbytes >= len) */
1031 
1032  sub eax, ecx /* len -= nbytes */
1033  rep movsb
1034  mov esi, edi
1035  sub esi, ebp /* from = out - dist */
1036  jmp L_do_copy
1037 
1038 ALIGN 4
1039 L_wrap_around_window:
1040  mov eax, [esp+52] /* eax = write */
1041  cmp ecx, eax
1042  jbe L_contiguous_in_window /* if (write >= nbytes) */
1043 
1044  add esi, [esp+48] /* from += wsize */
1045  add esi, eax /* from += write */
1046  sub esi, ecx /* from -= nbytes */
1047  sub ecx, eax /* nbytes -= write */
1048 
1049  mov eax, [esp+64] /* eax = len */
1050  cmp eax, ecx
1051  jbe L_do_copy /* if (nbytes >= len) */
1052 
1053  sub eax, ecx /* len -= nbytes */
1054  rep movsb
1055  mov esi, [esp+28] /* from = window */
1056  mov ecx, [esp+52] /* nbytes = write */
1057  cmp eax, ecx
1058  jbe L_do_copy /* if (nbytes >= len) */
1059 
1060  sub eax, ecx /* len -= nbytes */
1061  rep movsb
1062  mov esi, edi
1063  sub esi, ebp /* from = out - dist */
1064  jmp L_do_copy
1065 
1066 ALIGN 4
1067 L_contiguous_in_window:
1068  add esi, eax
1069  sub esi, ecx /* from += write - nbytes */
1070 
1071  mov eax, [esp+64] /* eax = len */
1072  cmp eax, ecx
1073  jbe L_do_copy /* if (nbytes >= len) */
1074 
1075  sub eax, ecx /* len -= nbytes */
1076  rep movsb
1077  mov esi, edi
1078  sub esi, ebp /* from = out - dist */
1079  jmp L_do_copy
1080 
1081 ALIGN 4
1082 L_do_copy:
1083  mov ecx, eax
1084  rep movsb
1085 
1086  mov esi, [esp+8] /* move in back to %esi, toss from */
1087  mov ebp, [esp+32] /* ebp = lcode */
1088  jmp L_while_test
1089 
1090 L_test_for_end_of_block:
1091  test al, 32
1092  jz L_invalid_literal_length_code
1093  mov dword ptr [esp+72], 1
1094  jmp L_break_loop_with_status
1095 
1096 L_invalid_literal_length_code:
1097  mov dword ptr [esp+72], 2
1098  jmp L_break_loop_with_status
1099 
1100 L_invalid_distance_code:
1101  mov dword ptr [esp+72], 3
1102  jmp L_break_loop_with_status
1103 
1104 L_invalid_distance_too_far:
1105  mov esi, [esp+4]
1106  mov dword ptr [esp+72], 4
1107  jmp L_break_loop_with_status
1108 
1109 L_break_loop:
1110  mov dword ptr [esp+72], 0
1111 
1112 L_break_loop_with_status:
1113 /* put in, out, bits, and hold back into ar and pop esp */
1114  mov [esp+8], esi /* save in */
1115  mov [esp+16], edi /* save out */
1116  mov [esp+44], ebx /* save bits */
1117  mov [esp+40], edx /* save hold */
1118  mov ebp, [esp+4] /* restore esp, ebp */
1119  mov esp, [esp]
1120  }
1121 #else
1122 #error "x86 architecture not defined"
1123 #endif
1124 
1125  if (ar.status > 1) {
1126  if (ar.status == 2)
1127  strm->msg = "invalid literal/length code";
1128  else if (ar.status == 3)
1129  strm->msg = "invalid distance code";
1130  else
1131  strm->msg = "invalid distance too far back";
1132  state->mode = BAD;
1133  }
1134  else if ( ar.status == 1 ) {
1135  state->mode = TYPE;
1136  }
1137 
1138  /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
1139  ar.len = ar.bits >> 3;
1140  ar.in -= ar.len;
1141  ar.bits -= ar.len << 3;
1142  ar.hold &= (1U << ar.bits) - 1;
1143 
1144  /* update state and return */
1145  strm->next_in = ar.in;
1146  strm->next_out = ar.out;
1147  strm->avail_in = (unsigned)(ar.in < ar.last ?
1148  PAD_AVAIL_IN + (ar.last - ar.in) :
1149  PAD_AVAIL_IN - (ar.in - ar.last));
1150  strm->avail_out = (unsigned)(ar.out < ar.end ?
1151  PAD_AVAIL_OUT + (ar.end - ar.out) :
1152  PAD_AVAIL_OUT - (ar.out - ar.end));
1153  state->hold = ar.hold;
1154  state->bits = ar.bits;
1155  return;
1156 }
1157 
int write(int fd, const char *buf, int nbytes)
Definition: tif_acorn.c:325
unsigned wnext
Definition: inflate.h:95
png_voidp ptr
Definition: png.h:1908
unsigned wsize
Definition: inflate.h:93
unsigned distbits
Definition: inflate.h:109
#define PAD_AVAIL_OUT
code const FAR * distcode
Definition: inflate.h:107
GLuint start
void inflate_fast(z_streamp strm, unsigned start)
Definition: inffas86.c:71
#define bits
Definition: infblock.c:15
unsigned lenbits
Definition: inflate.h:108
z_stream FAR * z_streamp
Definition: zlib.h:89
GLenum GLsizei len
#define BAD
Definition: inflate.c:10
unsigned long hold
Definition: inflate.h:98
local int out(void *out_desc, unsigned char *buf, unsigned len)
Definition: gun.c:131
typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque
#define PAD_AVAIL_IN
unsigned char bits
Definition: inftree9.h:26
GLuint GLuint end
Definition: inftree9.h:24
unsigned bits
Definition: inflate.h:99
unsigned char FAR * window
Definition: inflate9.h:37
GLuint in
inflate_mode mode
Definition: inflate.h:82
Definition: infutil.h:15
code const FAR * lencode
Definition: inflate.h:106