00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "zutil.h"
00030 #include "inftrees.h"
00031 #include "inflate.h"
00032 #include "inffast.h"
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 void inflate_fast(strm, start)
00072 z_streamp strm;
00073 unsigned start;
00074 {
00075 struct inflate_state FAR *state;
00076 struct inffast_ar {
00077
00078
00079 void *esp;
00080 void *ebp;
00081 unsigned char FAR *in;
00082 unsigned char FAR *last;
00083 unsigned char FAR *out;
00084 unsigned char FAR *beg;
00085 unsigned char FAR *end;
00086 unsigned char FAR *window;
00087 code const FAR *lcode;
00088 code const FAR *dcode;
00089 unsigned long hold;
00090 unsigned bits;
00091 unsigned wsize;
00092 unsigned write;
00093 unsigned lmask;
00094 unsigned dmask;
00095 unsigned len;
00096 unsigned dist;
00097 unsigned status;
00098 } ar;
00099
00100 #if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
00101 #define PAD_AVAIL_IN 6
00102 #define PAD_AVAIL_OUT 258
00103 #else
00104 #define PAD_AVAIL_IN 5
00105 #define PAD_AVAIL_OUT 257
00106 #endif
00107
00108
00109 state = (struct inflate_state FAR *)strm->state;
00110 ar.in = strm->next_in;
00111 ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);
00112 ar.out = strm->next_out;
00113 ar.beg = ar.out - (start - strm->avail_out);
00114 ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);
00115 ar.wsize = state->wsize;
00116 ar.write = state->wnext;
00117 ar.window = state->window;
00118 ar.hold = state->hold;
00119 ar.bits = state->bits;
00120 ar.lcode = state->lencode;
00121 ar.dcode = state->distcode;
00122 ar.lmask = (1U << state->lenbits) - 1;
00123 ar.dmask = (1U << state->distbits) - 1;
00124
00125
00126
00127
00128
00129 while (((unsigned long)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {
00130 ar.hold += (unsigned long)*ar.in++ << ar.bits;
00131 ar.bits += 8;
00132 }
00133
00134 #if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
00135 __asm__ __volatile__ (
00136 " leaq %0, %%rax\n"
00137 " movq %%rbp, 8(%%rax)\n"
00138 " movq %%rsp, (%%rax)\n"
00139 " movq %%rax, %%rsp\n"
00140 " movq 16(%%rsp), %%rsi\n"
00141 " movq 32(%%rsp), %%rdi\n"
00142 " movq 24(%%rsp), %%r9\n"
00143 " movq 48(%%rsp), %%r10\n"
00144 " movq 64(%%rsp), %%rbp\n"
00145 " movq 72(%%rsp), %%r11\n"
00146 " movq 80(%%rsp), %%rdx\n"
00147 " movl 88(%%rsp), %%ebx\n"
00148 " movl 100(%%rsp), %%r12d\n"
00149 " movl 104(%%rsp), %%r13d\n"
00150
00151
00152 " cld\n"
00153 " cmpq %%rdi, %%r10\n"
00154 " je .L_one_time\n"
00155 " cmpq %%rsi, %%r9\n"
00156 " je .L_one_time\n"
00157 " jmp .L_do_loop\n"
00158
00159 ".L_one_time:\n"
00160 " movq %%r12, %%r8\n"
00161 " cmpb $32, %%bl\n"
00162 " ja .L_get_length_code_one_time\n"
00163
00164 " lodsl\n"
00165 " movb %%bl, %%cl\n"
00166 " addb $32, %%bl\n"
00167 " shlq %%cl, %%rax\n"
00168 " orq %%rax, %%rdx\n"
00169 " jmp .L_get_length_code_one_time\n"
00170
00171 ".align 32,0x90\n"
00172 ".L_while_test:\n"
00173 " cmpq %%rdi, %%r10\n"
00174 " jbe .L_break_loop\n"
00175 " cmpq %%rsi, %%r9\n"
00176 " jbe .L_break_loop\n"
00177
00178 ".L_do_loop:\n"
00179 " movq %%r12, %%r8\n"
00180 " cmpb $32, %%bl\n"
00181 " ja .L_get_length_code\n"
00182
00183 " lodsl\n"
00184 " movb %%bl, %%cl\n"
00185 " addb $32, %%bl\n"
00186 " shlq %%cl, %%rax\n"
00187 " orq %%rax, %%rdx\n"
00188
00189 ".L_get_length_code:\n"
00190 " andq %%rdx, %%r8\n"
00191 " movl (%%rbp,%%r8,4), %%eax\n"
00192
00193 " movb %%ah, %%cl\n"
00194 " subb %%ah, %%bl\n"
00195 " shrq %%cl, %%rdx\n"
00196
00197 " testb %%al, %%al\n"
00198 " jnz .L_test_for_length_base\n"
00199
00200 " movq %%r12, %%r8\n"
00201 " shrl $16, %%eax\n"
00202 " stosb\n"
00203
00204 ".L_get_length_code_one_time:\n"
00205 " andq %%rdx, %%r8\n"
00206 " movl (%%rbp,%%r8,4), %%eax\n"
00207
00208 ".L_dolen:\n"
00209 " movb %%ah, %%cl\n"
00210 " subb %%ah, %%bl\n"
00211 " shrq %%cl, %%rdx\n"
00212
00213 " testb %%al, %%al\n"
00214 " jnz .L_test_for_length_base\n"
00215
00216 " shrl $16, %%eax\n"
00217 " stosb\n"
00218 " jmp .L_while_test\n"
00219
00220 ".align 32,0x90\n"
00221 ".L_test_for_length_base:\n"
00222 " movl %%eax, %%r14d\n"
00223 " shrl $16, %%r14d\n"
00224 " movb %%al, %%cl\n"
00225
00226 " testb $16, %%al\n"
00227 " jz .L_test_for_second_level_length\n"
00228 " andb $15, %%cl\n"
00229 " jz .L_decode_distance\n"
00230
00231 ".L_add_bits_to_len:\n"
00232 " subb %%cl, %%bl\n"
00233 " xorl %%eax, %%eax\n"
00234 " incl %%eax\n"
00235 " shll %%cl, %%eax\n"
00236 " decl %%eax\n"
00237 " andl %%edx, %%eax\n"
00238 " shrq %%cl, %%rdx\n"
00239 " addl %%eax, %%r14d\n"
00240
00241 ".L_decode_distance:\n"
00242 " movq %%r13, %%r8\n"
00243 " cmpb $32, %%bl\n"
00244 " ja .L_get_distance_code\n"
00245
00246 " lodsl\n"
00247 " movb %%bl, %%cl\n"
00248 " addb $32, %%bl\n"
00249 " shlq %%cl, %%rax\n"
00250 " orq %%rax, %%rdx\n"
00251
00252 ".L_get_distance_code:\n"
00253 " andq %%rdx, %%r8\n"
00254 " movl (%%r11,%%r8,4), %%eax\n"
00255
00256 ".L_dodist:\n"
00257 " movl %%eax, %%r15d\n"
00258 " shrl $16, %%r15d\n"
00259 " movb %%ah, %%cl\n"
00260 " subb %%ah, %%bl\n"
00261 " shrq %%cl, %%rdx\n"
00262 " movb %%al, %%cl\n"
00263
00264 " testb $16, %%al\n"
00265 " jz .L_test_for_second_level_dist\n"
00266 " andb $15, %%cl\n"
00267 " jz .L_check_dist_one\n"
00268
00269 ".L_add_bits_to_dist:\n"
00270 " subb %%cl, %%bl\n"
00271 " xorl %%eax, %%eax\n"
00272 " incl %%eax\n"
00273 " shll %%cl, %%eax\n"
00274 " decl %%eax\n"
00275 " andl %%edx, %%eax\n"
00276 " shrq %%cl, %%rdx\n"
00277 " addl %%eax, %%r15d\n"
00278
00279 ".L_check_window:\n"
00280 " movq %%rsi, %%r8\n"
00281 " movq %%rdi, %%rax\n"
00282 " subq 40(%%rsp), %%rax\n"
00283
00284 " cmpl %%r15d, %%eax\n"
00285 " jb .L_clip_window\n"
00286
00287 " movl %%r14d, %%ecx\n"
00288 " movq %%rdi, %%rsi\n"
00289 " subq %%r15, %%rsi\n"
00290
00291 " sarl %%ecx\n"
00292 " jnc .L_copy_two\n"
00293
00294 " rep movsw\n"
00295 " movb (%%rsi), %%al\n"
00296 " movb %%al, (%%rdi)\n"
00297 " incq %%rdi\n"
00298
00299 " movq %%r8, %%rsi\n"
00300 " jmp .L_while_test\n"
00301
00302 ".L_copy_two:\n"
00303 " rep movsw\n"
00304 " movq %%r8, %%rsi\n"
00305 " jmp .L_while_test\n"
00306
00307 ".align 32,0x90\n"
00308 ".L_check_dist_one:\n"
00309 " cmpl $1, %%r15d\n"
00310 " jne .L_check_window\n"
00311 " cmpq %%rdi, 40(%%rsp)\n"
00312 " je .L_check_window\n"
00313
00314 " movl %%r14d, %%ecx\n"
00315 " movb -1(%%rdi), %%al\n"
00316 " movb %%al, %%ah\n"
00317
00318 " sarl %%ecx\n"
00319 " jnc .L_set_two\n"
00320 " movb %%al, (%%rdi)\n"
00321 " incq %%rdi\n"
00322
00323 ".L_set_two:\n"
00324 " rep stosw\n"
00325 " jmp .L_while_test\n"
00326
00327 ".align 32,0x90\n"
00328 ".L_test_for_second_level_length:\n"
00329 " testb $64, %%al\n"
00330 " jnz .L_test_for_end_of_block\n"
00331
00332 " xorl %%eax, %%eax\n"
00333 " incl %%eax\n"
00334 " shll %%cl, %%eax\n"
00335 " decl %%eax\n"
00336 " andl %%edx, %%eax\n"
00337 " addl %%r14d, %%eax\n"
00338 " movl (%%rbp,%%rax,4), %%eax\n"
00339 " jmp .L_dolen\n"
00340
00341 ".align 32,0x90\n"
00342 ".L_test_for_second_level_dist:\n"
00343 " testb $64, %%al\n"
00344 " jnz .L_invalid_distance_code\n"
00345
00346 " xorl %%eax, %%eax\n"
00347 " incl %%eax\n"
00348 " shll %%cl, %%eax\n"
00349 " decl %%eax\n"
00350 " andl %%edx, %%eax\n"
00351 " addl %%r15d, %%eax\n"
00352 " movl (%%r11,%%rax,4), %%eax\n"
00353 " jmp .L_dodist\n"
00354
00355 ".align 32,0x90\n"
00356 ".L_clip_window:\n"
00357 " movl %%eax, %%ecx\n"
00358 " movl 92(%%rsp), %%eax\n"
00359 " negl %%ecx\n"
00360
00361 " cmpl %%r15d, %%eax\n"
00362 " jb .L_invalid_distance_too_far\n"
00363
00364 " addl %%r15d, %%ecx\n"
00365 " cmpl $0, 96(%%rsp)\n"
00366 " jne .L_wrap_around_window\n"
00367
00368 " movq 56(%%rsp), %%rsi\n"
00369 " subl %%ecx, %%eax\n"
00370 " addq %%rax, %%rsi\n"
00371
00372 " movl %%r14d, %%eax\n"
00373 " cmpl %%ecx, %%r14d\n"
00374 " jbe .L_do_copy\n"
00375
00376 " subl %%ecx, %%eax\n"
00377 " rep movsb\n"
00378 " movq %%rdi, %%rsi\n"
00379 " subq %%r15, %%rsi\n"
00380 " jmp .L_do_copy\n"
00381
00382 ".align 32,0x90\n"
00383 ".L_wrap_around_window:\n"
00384 " movl 96(%%rsp), %%eax\n"
00385 " cmpl %%eax, %%ecx\n"
00386 " jbe .L_contiguous_in_window\n"
00387
00388 " movl 92(%%rsp), %%esi\n"
00389 " addq 56(%%rsp), %%rsi\n"
00390 " addq %%rax, %%rsi\n"
00391 " subq %%rcx, %%rsi\n"
00392 " subl %%eax, %%ecx\n"
00393
00394 " movl %%r14d, %%eax\n"
00395 " cmpl %%ecx, %%eax\n"
00396 " jbe .L_do_copy\n"
00397
00398 " subl %%ecx, %%eax\n"
00399 " rep movsb\n"
00400 " movq 56(%%rsp), %%rsi\n"
00401 " movl 96(%%rsp), %%ecx\n"
00402 " cmpl %%ecx, %%eax\n"
00403 " jbe .L_do_copy\n"
00404
00405 " subl %%ecx, %%eax\n"
00406 " rep movsb\n"
00407 " movq %%rdi, %%rsi\n"
00408 " subq %%r15, %%rsi\n"
00409 " jmp .L_do_copy\n"
00410
00411 ".align 32,0x90\n"
00412 ".L_contiguous_in_window:\n"
00413 " movq 56(%%rsp), %%rsi\n"
00414 " addq %%rax, %%rsi\n"
00415 " subq %%rcx, %%rsi\n"
00416
00417 " movl %%r14d, %%eax\n"
00418 " cmpl %%ecx, %%eax\n"
00419 " jbe .L_do_copy\n"
00420
00421 " subl %%ecx, %%eax\n"
00422 " rep movsb\n"
00423 " movq %%rdi, %%rsi\n"
00424 " subq %%r15, %%rsi\n"
00425 " jmp .L_do_copy\n"
00426
00427 ".align 32,0x90\n"
00428 ".L_do_copy:\n"
00429 " movl %%eax, %%ecx\n"
00430 " rep movsb\n"
00431
00432 " movq %%r8, %%rsi\n"
00433 " jmp .L_while_test\n"
00434
00435 ".L_test_for_end_of_block:\n"
00436 " testb $32, %%al\n"
00437 " jz .L_invalid_literal_length_code\n"
00438 " movl $1, 116(%%rsp)\n"
00439 " jmp .L_break_loop_with_status\n"
00440
00441 ".L_invalid_literal_length_code:\n"
00442 " movl $2, 116(%%rsp)\n"
00443 " jmp .L_break_loop_with_status\n"
00444
00445 ".L_invalid_distance_code:\n"
00446 " movl $3, 116(%%rsp)\n"
00447 " jmp .L_break_loop_with_status\n"
00448
00449 ".L_invalid_distance_too_far:\n"
00450 " movl $4, 116(%%rsp)\n"
00451 " jmp .L_break_loop_with_status\n"
00452
00453 ".L_break_loop:\n"
00454 " movl $0, 116(%%rsp)\n"
00455
00456 ".L_break_loop_with_status:\n"
00457
00458 " movq %%rsi, 16(%%rsp)\n"
00459 " movq %%rdi, 32(%%rsp)\n"
00460 " movl %%ebx, 88(%%rsp)\n"
00461 " movq %%rdx, 80(%%rsp)\n"
00462 " movq (%%rsp), %%rax\n"
00463 " movq 8(%%rsp), %%rbp\n"
00464 " movq %%rax, %%rsp\n"
00465 :
00466 : "m" (ar)
00467 : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi",
00468 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
00469 );
00470 #elif ( defined( __GNUC__ ) || defined( __ICC ) ) && defined( __i386 )
00471 __asm__ __volatile__ (
00472 " leal %0, %%eax\n"
00473 " movl %%esp, (%%eax)\n"
00474 " movl %%ebp, 4(%%eax)\n"
00475 " movl %%eax, %%esp\n"
00476 " movl 8(%%esp), %%esi\n"
00477 " movl 16(%%esp), %%edi\n"
00478 " movl 40(%%esp), %%edx\n"
00479 " movl 44(%%esp), %%ebx\n"
00480 " movl 32(%%esp), %%ebp\n"
00481
00482 " cld\n"
00483 " jmp .L_do_loop\n"
00484
00485 ".align 32,0x90\n"
00486 ".L_while_test:\n"
00487 " cmpl %%edi, 24(%%esp)\n"
00488 " jbe .L_break_loop\n"
00489 " cmpl %%esi, 12(%%esp)\n"
00490 " jbe .L_break_loop\n"
00491
00492 ".L_do_loop:\n"
00493 " cmpb $15, %%bl\n"
00494 " ja .L_get_length_code\n"
00495
00496 " xorl %%eax, %%eax\n"
00497 " lodsw\n"
00498 " movb %%bl, %%cl\n"
00499 " addb $16, %%bl\n"
00500 " shll %%cl, %%eax\n"
00501 " orl %%eax, %%edx\n"
00502
00503 ".L_get_length_code:\n"
00504 " movl 56(%%esp), %%eax\n"
00505 " andl %%edx, %%eax\n"
00506 " movl (%%ebp,%%eax,4), %%eax\n"
00507
00508 ".L_dolen:\n"
00509 " movb %%ah, %%cl\n"
00510 " subb %%ah, %%bl\n"
00511 " shrl %%cl, %%edx\n"
00512
00513 " testb %%al, %%al\n"
00514 " jnz .L_test_for_length_base\n"
00515
00516 " shrl $16, %%eax\n"
00517 " stosb\n"
00518 " jmp .L_while_test\n"
00519
00520 ".align 32,0x90\n"
00521 ".L_test_for_length_base:\n"
00522 " movl %%eax, %%ecx\n"
00523 " shrl $16, %%ecx\n"
00524 " movl %%ecx, 64(%%esp)\n"
00525 " movb %%al, %%cl\n"
00526
00527 " testb $16, %%al\n"
00528 " jz .L_test_for_second_level_length\n"
00529 " andb $15, %%cl\n"
00530 " jz .L_decode_distance\n"
00531 " cmpb %%cl, %%bl\n"
00532 " jae .L_add_bits_to_len\n"
00533
00534 " movb %%cl, %%ch\n"
00535 " xorl %%eax, %%eax\n"
00536 " lodsw\n"
00537 " movb %%bl, %%cl\n"
00538 " addb $16, %%bl\n"
00539 " shll %%cl, %%eax\n"
00540 " orl %%eax, %%edx\n"
00541 " movb %%ch, %%cl\n"
00542
00543 ".L_add_bits_to_len:\n"
00544 " subb %%cl, %%bl\n"
00545 " xorl %%eax, %%eax\n"
00546 " incl %%eax\n"
00547 " shll %%cl, %%eax\n"
00548 " decl %%eax\n"
00549 " andl %%edx, %%eax\n"
00550 " shrl %%cl, %%edx\n"
00551 " addl %%eax, 64(%%esp)\n"
00552
00553 ".L_decode_distance:\n"
00554 " cmpb $15, %%bl\n"
00555 " ja .L_get_distance_code\n"
00556
00557 " xorl %%eax, %%eax\n"
00558 " lodsw\n"
00559 " movb %%bl, %%cl\n"
00560 " addb $16, %%bl\n"
00561 " shll %%cl, %%eax\n"
00562 " orl %%eax, %%edx\n"
00563
00564 ".L_get_distance_code:\n"
00565 " movl 60(%%esp), %%eax\n"
00566 " movl 36(%%esp), %%ecx\n"
00567 " andl %%edx, %%eax\n"
00568 " movl (%%ecx,%%eax,4), %%eax\n"
00569
00570 ".L_dodist:\n"
00571 " movl %%eax, %%ebp\n"
00572 " shrl $16, %%ebp\n"
00573 " movb %%ah, %%cl\n"
00574 " subb %%ah, %%bl\n"
00575 " shrl %%cl, %%edx\n"
00576 " movb %%al, %%cl\n"
00577
00578 " testb $16, %%al\n"
00579 " jz .L_test_for_second_level_dist\n"
00580 " andb $15, %%cl\n"
00581 " jz .L_check_dist_one\n"
00582 " cmpb %%cl, %%bl\n"
00583 " jae .L_add_bits_to_dist\n"
00584
00585 " movb %%cl, %%ch\n"
00586 " xorl %%eax, %%eax\n"
00587 " lodsw\n"
00588 " movb %%bl, %%cl\n"
00589 " addb $16, %%bl\n"
00590 " shll %%cl, %%eax\n"
00591 " orl %%eax, %%edx\n"
00592 " movb %%ch, %%cl\n"
00593
00594 ".L_add_bits_to_dist:\n"
00595 " subb %%cl, %%bl\n"
00596 " xorl %%eax, %%eax\n"
00597 " incl %%eax\n"
00598 " shll %%cl, %%eax\n"
00599 " decl %%eax\n"
00600 " andl %%edx, %%eax\n"
00601 " shrl %%cl, %%edx\n"
00602 " addl %%eax, %%ebp\n"
00603
00604 ".L_check_window:\n"
00605 " movl %%esi, 8(%%esp)\n"
00606 " movl %%edi, %%eax\n"
00607 " subl 20(%%esp), %%eax\n"
00608
00609 " cmpl %%ebp, %%eax\n"
00610 " jb .L_clip_window\n"
00611
00612 " movl 64(%%esp), %%ecx\n"
00613 " movl %%edi, %%esi\n"
00614 " subl %%ebp, %%esi\n"
00615
00616 " sarl %%ecx\n"
00617 " jnc .L_copy_two\n"
00618
00619 " rep movsw\n"
00620 " movb (%%esi), %%al\n"
00621 " movb %%al, (%%edi)\n"
00622 " incl %%edi\n"
00623
00624 " movl 8(%%esp), %%esi\n"
00625 " movl 32(%%esp), %%ebp\n"
00626 " jmp .L_while_test\n"
00627
00628 ".L_copy_two:\n"
00629 " rep movsw\n"
00630 " movl 8(%%esp), %%esi\n"
00631 " movl 32(%%esp), %%ebp\n"
00632 " jmp .L_while_test\n"
00633
00634 ".align 32,0x90\n"
00635 ".L_check_dist_one:\n"
00636 " cmpl $1, %%ebp\n"
00637 " jne .L_check_window\n"
00638 " cmpl %%edi, 20(%%esp)\n"
00639 " je .L_check_window\n"
00640
00641 " movl 64(%%esp), %%ecx\n"
00642 " movb -1(%%edi), %%al\n"
00643 " movb %%al, %%ah\n"
00644
00645 " sarl %%ecx\n"
00646 " jnc .L_set_two\n"
00647 " movb %%al, (%%edi)\n"
00648 " incl %%edi\n"
00649
00650 ".L_set_two:\n"
00651 " rep stosw\n"
00652 " movl 32(%%esp), %%ebp\n"
00653 " jmp .L_while_test\n"
00654
00655 ".align 32,0x90\n"
00656 ".L_test_for_second_level_length:\n"
00657 " testb $64, %%al\n"
00658 " jnz .L_test_for_end_of_block\n"
00659
00660 " xorl %%eax, %%eax\n"
00661 " incl %%eax\n"
00662 " shll %%cl, %%eax\n"
00663 " decl %%eax\n"
00664 " andl %%edx, %%eax\n"
00665 " addl 64(%%esp), %%eax\n"
00666 " movl (%%ebp,%%eax,4), %%eax\n"
00667 " jmp .L_dolen\n"
00668
00669 ".align 32,0x90\n"
00670 ".L_test_for_second_level_dist:\n"
00671 " testb $64, %%al\n"
00672 " jnz .L_invalid_distance_code\n"
00673
00674 " xorl %%eax, %%eax\n"
00675 " incl %%eax\n"
00676 " shll %%cl, %%eax\n"
00677 " decl %%eax\n"
00678 " andl %%edx, %%eax\n"
00679 " addl %%ebp, %%eax\n"
00680 " movl 36(%%esp), %%ecx\n"
00681 " movl (%%ecx,%%eax,4), %%eax\n"
00682 " jmp .L_dodist\n"
00683
00684 ".align 32,0x90\n"
00685 ".L_clip_window:\n"
00686 " movl %%eax, %%ecx\n"
00687 " movl 48(%%esp), %%eax\n"
00688 " negl %%ecx\n"
00689 " movl 28(%%esp), %%esi\n"
00690
00691 " cmpl %%ebp, %%eax\n"
00692 " jb .L_invalid_distance_too_far\n"
00693
00694 " addl %%ebp, %%ecx\n"
00695 " cmpl $0, 52(%%esp)\n"
00696 " jne .L_wrap_around_window\n"
00697
00698 " subl %%ecx, %%eax\n"
00699 " addl %%eax, %%esi\n"
00700
00701 " movl 64(%%esp), %%eax\n"
00702 " cmpl %%ecx, %%eax\n"
00703 " jbe .L_do_copy\n"
00704
00705 " subl %%ecx, %%eax\n"
00706 " rep movsb\n"
00707 " movl %%edi, %%esi\n"
00708 " subl %%ebp, %%esi\n"
00709 " jmp .L_do_copy\n"
00710
00711 ".align 32,0x90\n"
00712 ".L_wrap_around_window:\n"
00713 " movl 52(%%esp), %%eax\n"
00714 " cmpl %%eax, %%ecx\n"
00715 " jbe .L_contiguous_in_window\n"
00716
00717 " addl 48(%%esp), %%esi\n"
00718 " addl %%eax, %%esi\n"
00719 " subl %%ecx, %%esi\n"
00720 " subl %%eax, %%ecx\n"
00721
00722 " movl 64(%%esp), %%eax\n"
00723 " cmpl %%ecx, %%eax\n"
00724 " jbe .L_do_copy\n"
00725
00726 " subl %%ecx, %%eax\n"
00727 " rep movsb\n"
00728 " movl 28(%%esp), %%esi\n"
00729 " movl 52(%%esp), %%ecx\n"
00730 " cmpl %%ecx, %%eax\n"
00731 " jbe .L_do_copy\n"
00732
00733 " subl %%ecx, %%eax\n"
00734 " rep movsb\n"
00735 " movl %%edi, %%esi\n"
00736 " subl %%ebp, %%esi\n"
00737 " jmp .L_do_copy\n"
00738
00739 ".align 32,0x90\n"
00740 ".L_contiguous_in_window:\n"
00741 " addl %%eax, %%esi\n"
00742 " subl %%ecx, %%esi\n"
00743
00744 " movl 64(%%esp), %%eax\n"
00745 " cmpl %%ecx, %%eax\n"
00746 " jbe .L_do_copy\n"
00747
00748 " subl %%ecx, %%eax\n"
00749 " rep movsb\n"
00750 " movl %%edi, %%esi\n"
00751 " subl %%ebp, %%esi\n"
00752 " jmp .L_do_copy\n"
00753
00754 ".align 32,0x90\n"
00755 ".L_do_copy:\n"
00756 " movl %%eax, %%ecx\n"
00757 " rep movsb\n"
00758
00759 " movl 8(%%esp), %%esi\n"
00760 " movl 32(%%esp), %%ebp\n"
00761 " jmp .L_while_test\n"
00762
00763 ".L_test_for_end_of_block:\n"
00764 " testb $32, %%al\n"
00765 " jz .L_invalid_literal_length_code\n"
00766 " movl $1, 72(%%esp)\n"
00767 " jmp .L_break_loop_with_status\n"
00768
00769 ".L_invalid_literal_length_code:\n"
00770 " movl $2, 72(%%esp)\n"
00771 " jmp .L_break_loop_with_status\n"
00772
00773 ".L_invalid_distance_code:\n"
00774 " movl $3, 72(%%esp)\n"
00775 " jmp .L_break_loop_with_status\n"
00776
00777 ".L_invalid_distance_too_far:\n"
00778 " movl 8(%%esp), %%esi\n"
00779 " movl $4, 72(%%esp)\n"
00780 " jmp .L_break_loop_with_status\n"
00781
00782 ".L_break_loop:\n"
00783 " movl $0, 72(%%esp)\n"
00784
00785 ".L_break_loop_with_status:\n"
00786
00787 " movl %%esi, 8(%%esp)\n"
00788 " movl %%edi, 16(%%esp)\n"
00789 " movl %%ebx, 44(%%esp)\n"
00790 " movl %%edx, 40(%%esp)\n"
00791 " movl 4(%%esp), %%ebp\n"
00792 " movl (%%esp), %%esp\n"
00793 :
00794 : "m" (ar)
00795 : "memory", "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"
00796 );
00797 #elif defined( _MSC_VER ) && ! defined( _M_AMD64 )
00798 __asm {
00799 lea eax, ar
00800 mov [eax], esp
00801 mov [eax+4], ebp
00802 mov esp, eax
00803 mov esi, [esp+8]
00804 mov edi, [esp+16]
00805 mov edx, [esp+40]
00806 mov ebx, [esp+44]
00807 mov ebp, [esp+32]
00808
00809 cld
00810 jmp L_do_loop
00811
00812 ALIGN 4
00813 L_while_test:
00814 cmp [esp+24], edi
00815 jbe L_break_loop
00816 cmp [esp+12], esi
00817 jbe L_break_loop
00818
00819 L_do_loop:
00820 cmp bl, 15
00821 ja L_get_length_code
00822
00823 xor eax, eax
00824 lodsw
00825 mov cl, bl
00826 add bl, 16
00827 shl eax, cl
00828 or edx, eax
00829
00830 L_get_length_code:
00831 mov eax, [esp+56]
00832 and eax, edx
00833 mov eax, [ebp+eax*4]
00834
00835 L_dolen:
00836 mov cl, ah
00837 sub bl, ah
00838 shr edx, cl
00839
00840 test al, al
00841 jnz L_test_for_length_base
00842
00843 shr eax, 16
00844 stosb
00845 jmp L_while_test
00846
00847 ALIGN 4
00848 L_test_for_length_base:
00849 mov ecx, eax
00850 shr ecx, 16
00851 mov [esp+64], ecx
00852 mov cl, al
00853
00854 test al, 16
00855 jz L_test_for_second_level_length
00856 and cl, 15
00857 jz L_decode_distance
00858 cmp bl, cl
00859 jae L_add_bits_to_len
00860
00861 mov ch, cl
00862 xor eax, eax
00863 lodsw
00864 mov cl, bl
00865 add bl, 16
00866 shl eax, cl
00867 or edx, eax
00868 mov cl, ch
00869
00870 L_add_bits_to_len:
00871 sub bl, cl
00872 xor eax, eax
00873 inc eax
00874 shl eax, cl
00875 dec eax
00876 and eax, edx
00877 shr edx, cl
00878 add [esp+64], eax
00879
00880 L_decode_distance:
00881 cmp bl, 15
00882 ja L_get_distance_code
00883
00884 xor eax, eax
00885 lodsw
00886 mov cl, bl
00887 add bl, 16
00888 shl eax, cl
00889 or edx, eax
00890
00891 L_get_distance_code:
00892 mov eax, [esp+60]
00893 mov ecx, [esp+36]
00894 and eax, edx
00895 mov eax, [ecx+eax*4]
00896
00897 L_dodist:
00898 mov ebp, eax
00899 shr ebp, 16
00900 mov cl, ah
00901 sub bl, ah
00902 shr edx, cl
00903 mov cl, al
00904
00905 test al, 16
00906 jz L_test_for_second_level_dist
00907 and cl, 15
00908 jz L_check_dist_one
00909 cmp bl, cl
00910 jae L_add_bits_to_dist
00911
00912 mov ch, cl
00913 xor eax, eax
00914 lodsw
00915 mov cl, bl
00916 add bl, 16
00917 shl eax, cl
00918 or edx, eax
00919 mov cl, ch
00920
00921 L_add_bits_to_dist:
00922 sub bl, cl
00923 xor eax, eax
00924 inc eax
00925 shl eax, cl
00926 dec eax
00927 and eax, edx
00928 shr edx, cl
00929 add ebp, eax
00930
00931 L_check_window:
00932 mov [esp+8], esi
00933 mov eax, edi
00934 sub eax, [esp+20]
00935
00936 cmp eax, ebp
00937 jb L_clip_window
00938
00939 mov ecx, [esp+64]
00940 mov esi, edi
00941 sub esi, ebp
00942
00943 sar ecx, 1
00944 jnc L_copy_two
00945
00946 rep movsw
00947 mov al, [esi]
00948 mov [edi], al
00949 inc edi
00950
00951 mov esi, [esp+8]
00952 mov ebp, [esp+32]
00953 jmp L_while_test
00954
00955 L_copy_two:
00956 rep movsw
00957 mov esi, [esp+8]
00958 mov ebp, [esp+32]
00959 jmp L_while_test
00960
00961 ALIGN 4
00962 L_check_dist_one:
00963 cmp ebp, 1
00964 jne L_check_window
00965 cmp [esp+20], edi
00966 je L_check_window
00967
00968 mov ecx, [esp+64]
00969 mov al, [edi-1]
00970 mov ah, al
00971
00972 sar ecx, 1
00973 jnc L_set_two
00974 mov [edi], al
00975 inc edi
00976
00977 L_set_two:
00978 rep stosw
00979 mov ebp, [esp+32]
00980 jmp L_while_test
00981
00982 ALIGN 4
00983 L_test_for_second_level_length:
00984 test al, 64
00985 jnz L_test_for_end_of_block
00986
00987 xor eax, eax
00988 inc eax
00989 shl eax, cl
00990 dec eax
00991 and eax, edx
00992 add eax, [esp+64]
00993 mov eax, [ebp+eax*4]
00994 jmp L_dolen
00995
00996 ALIGN 4
00997 L_test_for_second_level_dist:
00998 test al, 64
00999 jnz L_invalid_distance_code
01000
01001 xor eax, eax
01002 inc eax
01003 shl eax, cl
01004 dec eax
01005 and eax, edx
01006 add eax, ebp
01007 mov ecx, [esp+36]
01008 mov eax, [ecx+eax*4]
01009 jmp L_dodist
01010
01011 ALIGN 4
01012 L_clip_window:
01013 mov ecx, eax
01014 mov eax, [esp+48]
01015 neg ecx
01016 mov esi, [esp+28]
01017
01018 cmp eax, ebp
01019 jb L_invalid_distance_too_far
01020
01021 add ecx, ebp
01022 cmp dword ptr [esp+52], 0
01023 jne L_wrap_around_window
01024
01025 sub eax, ecx
01026 add esi, eax
01027
01028 mov eax, [esp+64]
01029 cmp eax, ecx
01030 jbe L_do_copy
01031
01032 sub eax, ecx
01033 rep movsb
01034 mov esi, edi
01035 sub esi, ebp
01036 jmp L_do_copy
01037
01038 ALIGN 4
01039 L_wrap_around_window:
01040 mov eax, [esp+52]
01041 cmp ecx, eax
01042 jbe L_contiguous_in_window
01043
01044 add esi, [esp+48]
01045 add esi, eax
01046 sub esi, ecx
01047 sub ecx, eax
01048
01049 mov eax, [esp+64]
01050 cmp eax, ecx
01051 jbe L_do_copy
01052
01053 sub eax, ecx
01054 rep movsb
01055 mov esi, [esp+28]
01056 mov ecx, [esp+52]
01057 cmp eax, ecx
01058 jbe L_do_copy
01059
01060 sub eax, ecx
01061 rep movsb
01062 mov esi, edi
01063 sub esi, ebp
01064 jmp L_do_copy
01065
01066 ALIGN 4
01067 L_contiguous_in_window:
01068 add esi, eax
01069 sub esi, ecx
01070
01071 mov eax, [esp+64]
01072 cmp eax, ecx
01073 jbe L_do_copy
01074
01075 sub eax, ecx
01076 rep movsb
01077 mov esi, edi
01078 sub esi, ebp
01079 jmp L_do_copy
01080
01081 ALIGN 4
01082 L_do_copy:
01083 mov ecx, eax
01084 rep movsb
01085
01086 mov esi, [esp+8]
01087 mov ebp, [esp+32]
01088 jmp L_while_test
01089
01090 L_test_for_end_of_block:
01091 test al, 32
01092 jz L_invalid_literal_length_code
01093 mov dword ptr [esp+72], 1
01094 jmp L_break_loop_with_status
01095
01096 L_invalid_literal_length_code:
01097 mov dword ptr [esp+72], 2
01098 jmp L_break_loop_with_status
01099
01100 L_invalid_distance_code:
01101 mov dword ptr [esp+72], 3
01102 jmp L_break_loop_with_status
01103
01104 L_invalid_distance_too_far:
01105 mov esi, [esp+4]
01106 mov dword ptr [esp+72], 4
01107 jmp L_break_loop_with_status
01108
01109 L_break_loop:
01110 mov dword ptr [esp+72], 0
01111
01112 L_break_loop_with_status:
01113
01114 mov [esp+8], esi
01115 mov [esp+16], edi
01116 mov [esp+44], ebx
01117 mov [esp+40], edx
01118 mov ebp, [esp+4]
01119 mov esp, [esp]
01120 }
01121 #else
01122 #error "x86 architecture not defined"
01123 #endif
01124
01125 if (ar.status > 1) {
01126 if (ar.status == 2)
01127 strm->msg = "invalid literal/length code";
01128 else if (ar.status == 3)
01129 strm->msg = "invalid distance code";
01130 else
01131 strm->msg = "invalid distance too far back";
01132 state->mode = BAD;
01133 }
01134 else if ( ar.status == 1 ) {
01135 state->mode = TYPE;
01136 }
01137
01138
01139 ar.len = ar.bits >> 3;
01140 ar.in -= ar.len;
01141 ar.bits -= ar.len << 3;
01142 ar.hold &= (1U << ar.bits) - 1;
01143
01144
01145 strm->next_in = ar.in;
01146 strm->next_out = ar.out;
01147 strm->avail_in = (unsigned)(ar.in < ar.last ?
01148 PAD_AVAIL_IN + (ar.last - ar.in) :
01149 PAD_AVAIL_IN - (ar.in - ar.last));
01150 strm->avail_out = (unsigned)(ar.out < ar.end ?
01151 PAD_AVAIL_OUT + (ar.end - ar.out) :
01152 PAD_AVAIL_OUT - (ar.out - ar.end));
01153 state->hold = ar.hold;
01154 state->bits = ar.bits;
01155 return;
01156 }
01157