VirtualBox

source: vbox/trunk/src/libs/zlib-1.2.1/contrib/inflate86/inffas86.c@ 34103

最後變更 在這個檔案從34103是 6392,由 vboxsync 提交於 17 年 前

export libpng and zlib so Windows and OS/2 builds cleanly.

  • 屬性 svn:eol-style 設為 native
檔案大小: 25.2 KB
 
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 <[email protected]>
8 * Please use the copyright conditions above.
9 *
10 * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
11 * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at
12 * the moment. I have successfully compiled and tested this code with gcc2.96,
13 * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S
14 * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
15 * enabled. I will attempt to merge the MMX code into this version. Newer
16 * versions of this and inffast.S can be found at
17 * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
18 */
19
20#include "zutil.h"
21#include "inftrees.h"
22#include "inflate.h"
23#include "inffast.h"
24
25/* Mark Adler's comments from inffast.c: */
26
27/*
28 Decode literal, length, and distance codes and write out the resulting
29 literal and match bytes until either not enough input or output is
30 available, an end-of-block is encountered, or a data error is encountered.
31 When large enough input and output buffers are supplied to inflate(), for
32 example, a 16K input buffer and a 64K output buffer, more than 95% of the
33 inflate execution time is spent in this routine.
34
35 Entry assumptions:
36
37 state->mode == LEN
38 strm->avail_in >= 6
39 strm->avail_out >= 258
40 start >= strm->avail_out
41 state->bits < 8
42
43 On return, state->mode is one of:
44
45 LEN -- ran out of enough output space or enough available input
46 TYPE -- reached end of block code, inflate() to interpret next block
47 BAD -- error in block data
48
49 Notes:
50
51 - The maximum input bits used by a length/distance pair is 15 bits for the
52 length code, 5 bits for the length extra, 15 bits for the distance code,
53 and 13 bits for the distance extra. This totals 48 bits, or six bytes.
54 Therefore if strm->avail_in >= 6, then there is enough input to avoid
55 checking for available input while decoding.
56
57 - The maximum bytes that a single length/distance pair can output is 258
58 bytes, which is the maximum length that can be coded. inflate_fast()
59 requires strm->avail_out >= 258 for each loop to avoid checking for
60 output space.
61 */
62void inflate_fast(strm, start)
63z_streamp strm;
64unsigned start; /* inflate()'s starting value for strm->avail_out */
65{
66 struct inflate_state FAR *state;
67 struct inffast_ar {
68 void *esp; /* esp save */
69 unsigned char FAR *in; /* local strm->next_in */
70 unsigned char FAR *last; /* while in < last, enough input available */
71 unsigned char FAR *out; /* local strm->next_out */
72 unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
73 unsigned char FAR *end; /* while out < end, enough space available */
74 unsigned wsize; /* window size or zero if not using window */
75 unsigned write; /* window write index */
76 unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
77 unsigned long hold; /* local strm->hold */
78 unsigned bits; /* local strm->bits */
79 code const FAR *lcode; /* local strm->lencode */
80 code const FAR *dcode; /* local strm->distcode */
81 unsigned lmask; /* mask for first level of length codes */
82 unsigned dmask; /* mask for first level of distance codes */
83 unsigned len; /* match length, unused bytes */
84 unsigned dist; /* match distance */
85 unsigned status; /* this is set when state changes */
86 } ar;
87
88 /* copy state to local variables */
89 state = (struct inflate_state FAR *)strm->state;
90 ar.in = strm->next_in;
91 ar.last = ar.in + (strm->avail_in - 5);
92 ar.out = strm->next_out;
93 ar.beg = ar.out - (start - strm->avail_out);
94 ar.end = ar.out + (strm->avail_out - 257);
95 ar.wsize = state->wsize;
96 ar.write = state->write;
97 ar.window = state->window;
98 ar.hold = state->hold;
99 ar.bits = state->bits;
100 ar.lcode = state->lencode;
101 ar.dcode = state->distcode;
102 ar.lmask = (1U << state->lenbits) - 1;
103 ar.dmask = (1U << state->distbits) - 1;
104
105 /* decode literals and length/distances until end-of-block or not enough
106 input data or output space */
107
108 /* align in on 2 byte boundary */
109 if (((unsigned long)(void *)ar.in & 0x1) != 0) {
110 ar.hold += (unsigned long)*ar.in++ << ar.bits;
111 ar.bits += 8;
112 }
113
114#if defined( __GNUC__ ) || defined( __ICC )
115 __asm__ __volatile__ (
116" leal %0, %%eax\n"
117" pushf\n"
118" pushl %%ebp\n"
119" movl %%esp, (%%eax)\n"
120" movl %%eax, %%esp\n"
121" movl 4(%%esp), %%esi\n" /* esi = in */
122" movl 12(%%esp), %%edi\n" /* edi = out */
123" movl 36(%%esp), %%edx\n" /* edx = hold */
124" movl 40(%%esp), %%ebx\n" /* ebx = bits */
125" movl 44(%%esp), %%ebp\n" /* ebp = lcode */
126
127" cld\n"
128" jmp .L_do_loop\n"
129
130".L_while_test:\n"
131" cmpl %%edi, 20(%%esp)\n"
132" jbe .L_break_loop\n"
133" cmpl %%esi, 8(%%esp)\n"
134" jbe .L_break_loop\n"
135
136".L_do_loop:\n"
137" cmpb $15, %%bl\n"
138" ja .L_get_length_code\n" /* if (15 < bits) */
139
140" xorl %%eax, %%eax\n"
141" lodsw\n" /* al = *(ushort *)in++ */
142" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
143" addb $16, %%bl\n" /* bits += 16 */
144" shll %%cl, %%eax\n"
145" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
146
147".L_get_length_code:\n"
148" movl 52(%%esp), %%eax\n" /* eax = lmask */
149" andl %%edx, %%eax\n" /* eax &= hold */
150" movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[hold & lmask] */
151
152".L_dolen:\n"
153" movb %%ah, %%cl\n" /* cl = this.bits */
154" subb %%ah, %%bl\n" /* bits -= this.bits */
155" shrl %%cl, %%edx\n" /* hold >>= this.bits */
156
157" testb %%al, %%al\n"
158" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */
159
160" shrl $16, %%eax\n" /* output this.val char */
161" stosb\n"
162" jmp .L_while_test\n"
163
164".L_test_for_length_base:\n"
165" movl %%eax, %%ecx\n" /* len = this */
166" shrl $16, %%ecx\n" /* len = this.val */
167" movl %%ecx, 60(%%esp)\n" /* len = this */
168" movb %%al, %%cl\n"
169
170" testb $16, %%al\n"
171" jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */
172" andb $15, %%cl\n" /* op &= 15 */
173" jz .L_decode_distance\n" /* if (!op) */
174" cmpb %%cl, %%bl\n"
175" jae .L_add_bits_to_len\n" /* if (op <= bits) */
176
177" movb %%cl, %%ch\n" /* stash op in ch, freeing cl */
178" xorl %%eax, %%eax\n"
179" lodsw\n" /* al = *(ushort *)in++ */
180" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
181" addb $16, %%bl\n" /* bits += 16 */
182" shll %%cl, %%eax\n"
183" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
184" movb %%ch, %%cl\n" /* move op back to ecx */
185
186".L_add_bits_to_len:\n"
187" movl $1, %%eax\n"
188" shll %%cl, %%eax\n"
189" decl %%eax\n"
190" subb %%cl, %%bl\n"
191" andl %%edx, %%eax\n" /* eax &= hold */
192" shrl %%cl, %%edx\n"
193" addl %%eax, 60(%%esp)\n" /* len += hold & mask[op] */
194
195".L_decode_distance:\n"
196" cmpb $15, %%bl\n"
197" ja .L_get_distance_code\n" /* if (15 < bits) */
198
199" xorl %%eax, %%eax\n"
200" lodsw\n" /* al = *(ushort *)in++ */
201" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
202" addb $16, %%bl\n" /* bits += 16 */
203" shll %%cl, %%eax\n"
204" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
205
206".L_get_distance_code:\n"
207" movl 56(%%esp), %%eax\n" /* eax = dmask */
208" movl 48(%%esp), %%ecx\n" /* ecx = dcode */
209" andl %%edx, %%eax\n" /* eax &= hold */
210" movl (%%ecx,%%eax,4), %%eax\n"/* eax = dcode[hold & dmask] */
211
212".L_dodist:\n"
213" movl %%eax, %%ebp\n" /* dist = this */
214" shrl $16, %%ebp\n" /* dist = this.val */
215" movb %%ah, %%cl\n"
216" subb %%ah, %%bl\n" /* bits -= this.bits */
217" shrl %%cl, %%edx\n" /* hold >>= this.bits */
218" movb %%al, %%cl\n" /* cl = this.op */
219
220" testb $16, %%al\n" /* if ((op & 16) == 0) */
221" jz .L_test_for_second_level_dist\n"
222" andb $15, %%cl\n" /* op &= 15 */
223" jz .L_check_dist_one\n"
224" cmpb %%cl, %%bl\n"
225" jae .L_add_bits_to_dist\n" /* if (op <= bits) 97.6% */
226
227" movb %%cl, %%ch\n" /* stash op in ch, freeing cl */
228" xorl %%eax, %%eax\n"
229" lodsw\n" /* al = *(ushort *)in++ */
230" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
231" addb $16, %%bl\n" /* bits += 16 */
232" shll %%cl, %%eax\n"
233" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
234" movb %%ch, %%cl\n" /* move op back to ecx */
235
236".L_add_bits_to_dist:\n"
237" movl $1, %%eax\n"
238" shll %%cl, %%eax\n"
239" decl %%eax\n" /* (1 << op) - 1 */
240" subb %%cl, %%bl\n"
241" andl %%edx, %%eax\n" /* eax &= hold */
242" shrl %%cl, %%edx\n"
243" addl %%eax, %%ebp\n" /* dist += hold & ((1 << op) - 1) */
244
245".L_check_window:\n"
246" movl %%esi, 4(%%esp)\n" /* save in so from can use it's reg */
247" movl %%edi, %%eax\n"
248" subl 16(%%esp), %%eax\n" /* nbytes = out - beg */
249
250" cmpl %%ebp, %%eax\n"
251" jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */
252
253" movl 60(%%esp), %%ecx\n"
254" movl %%edi, %%esi\n"
255" subl %%ebp, %%esi\n" /* from = out - dist */
256
257" subl $3, %%ecx\n" /* copy from to out */
258" movb (%%esi), %%al\n"
259" movb %%al, (%%edi)\n"
260" movb 1(%%esi), %%al\n"
261" movb 2(%%esi), %%ah\n"
262" addl $3, %%esi\n"
263" movb %%al, 1(%%edi)\n"
264" movb %%ah, 2(%%edi)\n"
265" addl $3, %%edi\n"
266" rep movsb\n"
267
268" movl 4(%%esp), %%esi\n" /* move in back to %esi, toss from */
269" movl 44(%%esp), %%ebp\n" /* ebp = lcode */
270" jmp .L_while_test\n"
271
272".L_check_dist_one:\n"
273" cmpl $1, %%ebp\n" /* if dist 1, is a memset */
274" jne .L_check_window\n"
275" cmpl %%edi, 16(%%esp)\n"
276" je .L_check_window\n"
277
278" decl %%edi\n"
279" movl 60(%%esp), %%ecx\n"
280" movb (%%edi), %%al\n"
281" subl $3, %%ecx\n"
282
283" movb %%al, 1(%%edi)\n" /* memset out with from[-1] */
284" movb %%al, 2(%%edi)\n"
285" movb %%al, 3(%%edi)\n"
286" addl $4, %%edi\n"
287" rep stosb\n"
288" movl 44(%%esp), %%ebp\n" /* ebp = lcode */
289" jmp .L_while_test\n"
290
291".L_test_for_second_level_length:\n"
292" testb $64, %%al\n"
293" jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */
294
295" movl $1, %%eax\n"
296" shll %%cl, %%eax\n"
297" decl %%eax\n"
298" andl %%edx, %%eax\n" /* eax &= hold */
299" addl 60(%%esp), %%eax\n" /* eax += this.val */
300" movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/
301" jmp .L_dolen\n"
302
303".L_test_for_second_level_dist:\n"
304" testb $64, %%al\n"
305" jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */
306
307" movl $1, %%eax\n"
308" shll %%cl, %%eax\n"
309" decl %%eax\n"
310" andl %%edx, %%eax\n" /* eax &= hold */
311" addl %%ebp, %%eax\n" /* eax += this.val */
312" movl 48(%%esp), %%ecx\n" /* ecx = dcode */
313" movl (%%ecx,%%eax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/
314" jmp .L_dodist\n"
315
316".L_clip_window:\n"
317" movl %%eax, %%ecx\n"
318" movl 24(%%esp), %%eax\n" /* prepare for dist compare */
319" negl %%ecx\n" /* nbytes = -nbytes */
320" movl 32(%%esp), %%esi\n" /* from = window */
321
322" cmpl %%ebp, %%eax\n"
323" jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */
324
325" addl %%ebp, %%ecx\n" /* nbytes = dist - nbytes */
326" cmpl $0, 28(%%esp)\n"
327" jne .L_wrap_around_window\n" /* if (write != 0) */
328
329" subl %%ecx, %%eax\n"
330" addl %%eax, %%esi\n" /* from += wsize - nbytes */
331
332" movl 60(%%esp), %%eax\n"
333" cmpl %%ecx, %%eax\n"
334" jbe .L_do_copy1\n" /* if (nbytes >= len) */
335
336" subl %%ecx, %%eax\n" /* len -= nbytes */
337" rep movsb\n"
338" movl %%edi, %%esi\n"
339" subl %%ebp, %%esi\n" /* from = out - dist */
340" jmp .L_do_copy1\n"
341
342" cmpl %%ecx, %%eax\n"
343" jbe .L_do_copy1\n" /* if (nbytes >= len) */
344
345" subl %%ecx, %%eax\n" /* len -= nbytes */
346" rep movsb\n"
347" movl %%edi, %%esi\n"
348" subl %%ebp, %%esi\n" /* from = out - dist */
349" jmp .L_do_copy1\n"
350
351".L_wrap_around_window:\n"
352" movl 28(%%esp), %%eax\n"
353" cmpl %%eax, %%ecx\n"
354" jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */
355
356" addl 24(%%esp), %%esi\n"
357" addl %%eax, %%esi\n"
358" subl %%ecx, %%esi\n" /* from += wsize + write - nbytes */
359" subl %%eax, %%ecx\n" /* nbytes -= write */
360
361" movl 60(%%esp), %%eax\n"
362" cmpl %%ecx, %%eax\n"
363" jbe .L_do_copy1\n" /* if (nbytes >= len) */
364
365" subl %%ecx, %%eax\n" /* len -= nbytes */
366" rep movsb\n"
367" movl 32(%%esp), %%esi\n" /* from = window */
368" movl 28(%%esp), %%ecx\n" /* nbytes = write */
369" cmpl %%ecx, %%eax\n"
370" jbe .L_do_copy1\n" /* if (nbytes >= len) */
371
372" subl %%ecx, %%eax\n" /* len -= nbytes */
373" rep movsb\n"
374" movl %%edi, %%esi\n"
375" subl %%ebp, %%esi\n" /* from = out - dist */
376" jmp .L_do_copy1\n"
377
378".L_contiguous_in_window:\n"
379" addl %%eax, %%esi\n"
380" subl %%ecx, %%esi\n" /* from += write - nbytes */
381
382" movl 60(%%esp), %%eax\n"
383" cmpl %%ecx, %%eax\n"
384" jbe .L_do_copy1\n" /* if (nbytes >= len) */
385
386" subl %%ecx, %%eax\n" /* len -= nbytes */
387" rep movsb\n"
388" movl %%edi, %%esi\n"
389" subl %%ebp, %%esi\n" /* from = out - dist */
390
391".L_do_copy1:\n"
392" movl %%eax, %%ecx\n"
393" rep movsb\n"
394
395" movl 4(%%esp), %%esi\n" /* move in back to %esi, toss from */
396" movl 44(%%esp), %%ebp\n" /* ebp = lcode */
397" jmp .L_while_test\n"
398
399".L_test_for_end_of_block:\n"
400" testb $32, %%al\n"
401" jz .L_invalid_literal_length_code\n"
402" movl $1, 68(%%esp)\n"
403" jmp .L_break_loop_with_status\n"
404
405".L_invalid_literal_length_code:\n"
406" movl $2, 68(%%esp)\n"
407" jmp .L_break_loop_with_status\n"
408
409".L_invalid_distance_code:\n"
410" movl $3, 68(%%esp)\n"
411" jmp .L_break_loop_with_status\n"
412
413".L_invalid_distance_too_far:\n"
414" movl 4(%%esp), %%esi\n"
415" movl $4, 68(%%esp)\n"
416" jmp .L_break_loop_with_status\n"
417
418".L_break_loop:\n"
419" movl $0, 68(%%esp)\n"
420
421".L_break_loop_with_status:\n"
422/* put in, out, bits, and hold back into ar and pop esp */
423" movl %%esi, 4(%%esp)\n"
424" movl %%edi, 12(%%esp)\n"
425" movl %%ebx, 40(%%esp)\n"
426" movl %%edx, 36(%%esp)\n"
427" movl (%%esp), %%esp\n"
428" popl %%ebp\n"
429" popf\n"
430 :
431 : "m" (ar)
432 : "memory", "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"
433 );
434#elif defined( _MSC_VER )
435 __asm {
436 lea eax, ar
437 pushfd
438 push ebp
439 mov [eax], esp
440 mov esp, eax
441 mov esi, [esp+4] /* esi = in */
442 mov edi, [esp+12] /* edi = out */
443 mov edx, [esp+36] /* edx = hold */
444 mov ebx, [esp+40] /* ebx = bits */
445 mov ebp, [esp+44] /* ebp = lcode */
446
447 cld
448 jmp L_do_loop
449
450L_while_test:
451 cmp [esp+20], edi
452 jbe L_break_loop
453 cmp [esp+8], esi
454 jbe L_break_loop
455
456L_do_loop:
457 cmp bl, 15
458 ja L_get_length_code /* if (15 < bits) */
459
460 xor eax, eax
461 lodsw /* al = *(ushort *)in++ */
462 mov cl, bl /* cl = bits, needs it for shifting */
463 add bl, 16 /* bits += 16 */
464 shl eax, cl
465 or edx, eax /* hold |= *((ushort *)in)++ << bits */
466
467L_get_length_code:
468 mov eax, [esp+52] /* eax = lmask */
469 and eax, edx /* eax &= hold */
470 mov eax, [ebp+eax*4] /* eax = lcode[hold & lmask] */
471
472L_dolen:
473 mov cl, ah /* cl = this.bits */
474 sub bl, ah /* bits -= this.bits */
475 shr edx, cl /* hold >>= this.bits */
476
477 test al, al
478 jnz L_test_for_length_base /* if (op != 0) 45.7% */
479
480 shr eax, 16 /* output this.val char */
481 stosb
482 jmp L_while_test
483
484L_test_for_length_base:
485 mov ecx, eax /* len = this */
486 shr ecx, 16 /* len = this.val */
487 mov [esp+60], ecx /* len = this */
488 mov cl, al
489
490 test al, 16
491 jz L_test_for_second_level_length /* if ((op & 16) == 0) 8% */
492 and cl, 15 /* op &= 15 */
493 jz L_decode_distance /* if (!op) */
494 cmp bl, cl
495 jae L_add_bits_to_len /* if (op <= bits) */
496
497 mov ch, cl /* stash op in ch, freeing cl */
498 xor eax, eax
499 lodsw /* al = *(ushort *)in++ */
500 mov cl, bl /* cl = bits, needs it for shifting */
501 add bl, 16 /* bits += 16 */
502 shl eax, cl
503 or edx, eax /* hold |= *((ushort *)in)++ << bits */
504 mov cl, ch /* move op back to ecx */
505
506L_add_bits_to_len:
507 mov eax, 1
508 shl eax, cl
509 dec eax
510 sub bl, cl
511 and eax, edx /* eax &= hold */
512 shr edx, cl
513 add [esp+60], eax /* len += hold & mask[op] */
514
515L_decode_distance:
516 cmp bl, 15
517 ja L_get_distance_code /* if (15 < bits) */
518
519 xor eax, eax
520 lodsw /* al = *(ushort *)in++ */
521 mov cl, bl /* cl = bits, needs it for shifting */
522 add bl, 16 /* bits += 16 */
523 shl eax, cl
524 or edx, eax /* hold |= *((ushort *)in)++ << bits */
525
526L_get_distance_code:
527 mov eax, [esp+56] /* eax = dmask */
528 mov ecx, [esp+48] /* ecx = dcode */
529 and eax, edx /* eax &= hold */
530 mov eax, [ecx+eax*4]/* eax = dcode[hold & dmask] */
531
532L_dodist:
533 mov ebp, eax /* dist = this */
534 shr ebp, 16 /* dist = this.val */
535 mov cl, ah
536 sub bl, ah /* bits -= this.bits */
537 shr edx, cl /* hold >>= this.bits */
538 mov cl, al /* cl = this.op */
539
540 test al, 16 /* if ((op & 16) == 0) */
541 jz L_test_for_second_level_dist
542 and cl, 15 /* op &= 15 */
543 jz L_check_dist_one
544 cmp bl, cl
545 jae L_add_bits_to_dist /* if (op <= bits) 97.6% */
546
547 mov ch, cl /* stash op in ch, freeing cl */
548 xor eax, eax
549 lodsw /* al = *(ushort *)in++ */
550 mov cl, bl /* cl = bits, needs it for shifting */
551 add bl, 16 /* bits += 16 */
552 shl eax, cl
553 or edx, eax /* hold |= *((ushort *)in)++ << bits */
554 mov cl, ch /* move op back to ecx */
555
556L_add_bits_to_dist:
557 mov eax, 1
558 shl eax, cl
559 dec eax /* (1 << op) - 1 */
560 sub bl, cl
561 and eax, edx /* eax &= hold */
562 shr edx, cl
563 add ebp, eax /* dist += hold & ((1 << op) - 1) */
564
565L_check_window:
566 mov [esp+4], esi /* save in so from can use it's reg */
567 mov eax, edi
568 sub eax, [esp+16] /* nbytes = out - beg */
569
570 cmp eax, ebp
571 jb L_clip_window /* if (dist > nbytes) 4.2% */
572
573 mov ecx, [esp+60]
574 mov esi, edi
575 sub esi, ebp /* from = out - dist */
576
577 sub ecx, 3 /* copy from to out */
578 mov al, [esi]
579 mov [edi], al
580 mov al, [esi+1]
581 mov ah, [esi+2]
582 add esi, 3
583 mov [edi+1], al
584 mov [edi+2], ah
585 add edi, 3
586 rep movsb
587
588 mov esi, [esp+4] /* move in back to %esi, toss from */
589 mov ebp, [esp+44] /* ebp = lcode */
590 jmp L_while_test
591
592L_check_dist_one:
593 cmp ebp, 1 /* if dist 1, is a memset */
594 jne L_check_window
595 cmp [esp+16], edi
596 je L_check_window
597
598 dec edi
599 mov ecx, [esp+60]
600 mov al, [edi]
601 sub ecx, 3
602
603 mov [edi+1], al /* memset out with from[-1] */
604 mov [edi+2], al
605 mov [edi+3], al
606 add edi, 4
607 rep stosb
608 mov ebp, [esp+44] /* ebp = lcode */
609 jmp L_while_test
610
611L_test_for_second_level_length:
612 test al, 64
613 jnz L_test_for_end_of_block /* if ((op & 64) != 0) */
614
615 mov eax, 1
616 shl eax, cl
617 dec eax
618 and eax, edx /* eax &= hold */
619 add eax, [esp+60] /* eax += this.val */
620 mov eax, [ebp+eax*4] /* eax = lcode[val+(hold&mask[op])]*/
621 jmp L_dolen
622
623L_test_for_second_level_dist:
624 test al, 64
625 jnz L_invalid_distance_code /* if ((op & 64) != 0) */
626
627 mov eax, 1
628 shl eax, cl
629 dec eax
630 and eax, edx /* eax &= hold */
631 add eax, ebp /* eax += this.val */
632 mov ecx, [esp+48] /* ecx = dcode */
633 mov eax, [ecx+eax*4] /* eax = dcode[val+(hold&mask[op])]*/
634 jmp L_dodist
635
636L_clip_window:
637 mov ecx, eax
638 mov eax, [esp+24] /* prepare for dist compare */
639 neg ecx /* nbytes = -nbytes */
640 mov esi, [esp+32] /* from = window */
641
642 cmp eax, ebp
643 jb L_invalid_distance_too_far /* if (dist > wsize) */
644
645 add ecx, ebp /* nbytes = dist - nbytes */
646 cmp dword ptr [esp+28], 0
647 jne L_wrap_around_window /* if (write != 0) */
648
649 sub eax, ecx
650 add esi, eax /* from += wsize - nbytes */
651
652 mov eax, [esp+60]
653 cmp eax, ecx
654 jbe L_do_copy1 /* if (nbytes >= len) */
655
656 sub eax, ecx /* len -= nbytes */
657 rep movsb
658 mov esi, edi
659 sub esi, ebp /* from = out - dist */
660 jmp L_do_copy1
661
662 cmp eax, ecx
663 jbe L_do_copy1 /* if (nbytes >= len) */
664
665 sub eax, ecx /* len -= nbytes */
666 rep movsb
667 mov esi, edi
668 sub esi, ebp /* from = out - dist */
669 jmp L_do_copy1
670
671L_wrap_around_window:
672 mov eax, [esp+28]
673 cmp ecx, eax
674 jbe L_contiguous_in_window /* if (write >= nbytes) */
675
676 add esi, [esp+24]
677 add esi, eax
678 sub esi, ecx /* from += wsize + write - nbytes */
679 sub ecx, eax /* nbytes -= write */
680
681 mov eax, [esp+60]
682 cmp eax, ecx
683 jbe L_do_copy1 /* if (nbytes >= len) */
684
685 sub eax, ecx /* len -= nbytes */
686 rep movsb
687 mov esi, [esp+32] /* from = window */
688 mov ecx, [esp+28] /* nbytes = write */
689 cmp eax, ecx
690 jbe L_do_copy1 /* if (nbytes >= len) */
691
692 sub eax, ecx /* len -= nbytes */
693 rep movsb
694 mov esi, edi
695 sub esi, ebp /* from = out - dist */
696 jmp L_do_copy1
697
698L_contiguous_in_window:
699 add esi, eax
700 sub esi, ecx /* from += write - nbytes */
701
702 mov eax, [esp+60]
703 cmp eax, ecx
704 jbe L_do_copy1 /* if (nbytes >= len) */
705
706 sub eax, ecx /* len -= nbytes */
707 rep movsb
708 mov esi, edi
709 sub esi, ebp /* from = out - dist */
710
711L_do_copy1:
712 mov ecx, eax
713 rep movsb
714
715 mov esi, [esp+4] /* move in back to %esi, toss from */
716 mov ebp, [esp+44] /* ebp = lcode */
717 jmp L_while_test
718
719L_test_for_end_of_block:
720 test al, 32
721 jz L_invalid_literal_length_code
722 mov dword ptr [esp+68], 1
723 jmp L_break_loop_with_status
724
725L_invalid_literal_length_code:
726 mov dword ptr [esp+68], 2
727 jmp L_break_loop_with_status
728
729L_invalid_distance_code:
730 mov dword ptr [esp+68], 3
731 jmp L_break_loop_with_status
732
733L_invalid_distance_too_far:
734 mov esi, [esp+4]
735 mov dword ptr [esp+68], 4
736 jmp L_break_loop_with_status
737
738L_break_loop:
739 mov dword ptr [esp+68], 0
740
741L_break_loop_with_status:
742/* put in, out, bits, and hold back into ar and pop esp */
743 mov [esp+4], esi
744 mov [esp+12], edi
745 mov [esp+40], ebx
746 mov [esp+36], edx
747 mov esp, [esp]
748 pop ebp
749 popfd
750 }
751#endif
752
753 if (ar.status > 1) {
754 if (ar.status == 2)
755 strm->msg = "invalid literal/length code";
756 else if (ar.status == 3)
757 strm->msg = "invalid distance code";
758 else
759 strm->msg = "invalid distance too far back";
760 state->mode = BAD;
761 }
762 else if ( ar.status == 1 ) {
763 state->mode = TYPE;
764 }
765
766 /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
767 ar.len = ar.bits >> 3;
768 ar.in -= ar.len;
769 ar.bits -= ar.len << 3;
770 ar.hold &= (1U << ar.bits) - 1;
771
772 /* update state and return */
773 strm->next_in = ar.in;
774 strm->next_out = ar.out;
775 strm->avail_in = (unsigned)(ar.in < ar.last ? 5 + (ar.last - ar.in) :
776 5 - (ar.in - ar.last));
777 strm->avail_out = (unsigned)(ar.out < ar.end ? 257 + (ar.end - ar.out) :
778 257 - (ar.out - ar.end));
779 state->hold = ar.hold;
780 state->bits = ar.bits;
781 return;
782}
783
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette