|
|
1.1 ! root 1: / ! 2: / Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly, ! 3: / Kai Uwe Rommel and Igor Mandrichenko. ! 4: / Permission is granted to any individual or institution to use, copy, or ! 5: / redistribute this software so long as all of the original files are included ! 6: / unmodified, that it is not sold for profit, and that this copyright notice ! 7: / is retained. ! 8: / ! 9: / match.s by Jean-loup Gailly. Translated to 32 bit code by Kai Uwe Rommel. ! 10: ! 11: / match.s, optimized version of longest_match() in deflate.c ! 12: / This version is for 386 Unix or OS/2 in 32 bit mode. ! 13: / Warning: it uses the AT&T syntax: mov source,dest ! 14: / This file is only optional. If you want to force the C version, ! 15: / add -DNO_ASM to CFLAGS in makefile and remove match.o from OBJI). ! 16: / If you have reduced WSIZE in zip.h, then change its value below. ! 17: / This version assumes static allocation of the arrays (-DDYN_ALLOC not used). ! 18: ! 19: .file "match.s" ! 20: ! 21: #if defined(__GO32__) && defined(unix) ! 22: # undef unix ! 23: #endif ! 24: ! 25: #ifdef unix ! 26: # define _prev prev ! 27: # define _window window ! 28: # define _match_start match_start ! 29: # define _prev_length prev_length ! 30: # define _good_match good_match ! 31: # define _strstart strstart ! 32: # define _max_chain_length max_chain_length ! 33: ! 34: # define _match_init match_init ! 35: # define _longest_match longest_match ! 36: #endif ! 37: ! 38: #define MAX_MATCH 258 ! 39: #define MAX_MATCH2 128 /* MAX_MATCH/2-1 */ ! 40: #define MIN_MATCH 3 ! 41: #define WSIZE 32768 ! 42: #define MAX_DIST WSIZE - MAX_MATCH - MIN_MATCH - 1 ! 43: ! 44: .globl _match_init ! 45: .globl _longest_match ! 46: ! 47: .text ! 48: ! 49: _match_init: ! 50: ret ! 51: ! 52: / ----------------------------------------------------------------------- ! 53: / Set match_start to the longest match starting at the given string and ! 54: / return its length. Matches shorter or equal to prev_length are discarded, ! 55: / in which case the result is equal to prev_length and match_start is ! 56: / garbage. ! 57: / IN assertions: cur_match is the head of the hash chain for the current ! 58: / string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 ! 59: ! 60: _longest_match: /* int longest_match(cur_match) */ ! 61: ! 62: #define cur_match 20(%esp) ! 63: / return address / esp+16 ! 64: push %ebp / esp+12 ! 65: push %edi / esp+8 ! 66: push %esi / esp+4 ! 67: push %ebx / esp ! 68: ! 69: / match equ esi ! 70: / scan equ edi ! 71: / chain_length equ ebp ! 72: / best_len equ ebx ! 73: / limit equ edx ! 74: ! 75: mov cur_match,%esi ! 76: mov _max_chain_length,%ebp / chain_length = max_chain_length ! 77: mov _strstart,%edi ! 78: mov %edi,%edx ! 79: sub $ MAX_DIST,%edx / limit = strstart-MAX_DIST ! 80: jae limit_ok ! 81: sub %edx,%edx / limit = NIL ! 82: limit_ok: ! 83: add $_window+2,%edi / edi = offset(window + strstart + 2) ! 84: mov _prev_length,%ebx / best_len = prev_length ! 85: movw -3(%ebx,%edi),%ax / ax = scan[best_len-1..best_len] ! 86: movw -2(%edi),%cx / cx = scan[0..1] ! 87: cmp _good_match,%ebx / do we have a good match already? ! 88: jb do_scan ! 89: shr $2,%ebp / chain_length >>= 2 ! 90: jmp do_scan ! 91: ! 92: .align 4 ! 93: long_loop: ! 94: / at this point, edi == scan+2, esi == cur_match ! 95: movw -3(%ebx,%edi),%ax / ax = scan[best_len-1..best_len] ! 96: movw -2(%edi),%cx / cx = scan[0..1] ! 97: short_loop: ! 98: dec %ebp / --chain_length ! 99: jz the_end ! 100: / at this point, di == scan+2, si == cur_match, ! 101: / ax = scan[best_len-1..best_len] and cx = scan[0..1] ! 102: and $ WSIZE-1, %esi ! 103: movw _prev(%esi,%esi),%si / cur_match = prev[cur_match] ! 104: / top word of esi is still 0 ! 105: cmp %edx,%esi / cur_match <= limit ? ! 106: jbe the_end ! 107: do_scan: ! 108: cmpw _window-1(%ebx,%esi),%ax /check match at best_len-1 ! 109: jne short_loop ! 110: cmpw _window(%esi),%cx / check min_match_length match ! 111: jne short_loop ! 112: ! 113: lea _window+2(%esi),%esi / si = match ! 114: mov %edi,%eax / ax = scan+2 ! 115: mov $ MAX_MATCH2,%ecx / scan for at most MAX_MATCH bytes ! 116: #ifdef unix ! 117: repz; cmpsw / loop until mismatch ! 118: #else ! 119: repe; cmpsw ! 120: #endif ! 121: je maxmatch / match of length MAX_MATCH? ! 122: mismatch: ! 123: movb -2(%edi),%cl / mismatch on first or second byte? ! 124: subb -2(%esi),%cl / cl = 0 if first bytes equal ! 125: xchg %edi,%eax / edi = scan+2, eax = end of scan ! 126: sub %edi,%eax / eax = len ! 127: sub %eax,%esi / esi = cur_match + 2 + offset(window) ! 128: sub $_window+2,%esi / esi = cur_match ! 129: subb $1,%cl / set carry if cl == 0 (cannot use DEC) ! 130: adc $0,%eax / eax = carry ? len+1 : len ! 131: cmp %ebx,%eax / len > best_len ? ! 132: jle long_loop ! 133: mov %esi,_match_start / match_start = cur_match ! 134: mov %eax,%ebx / ebx = best_len = len ! 135: cmp $ MAX_MATCH,%eax / len >= MAX_MATCH ? ! 136: jl long_loop ! 137: the_end: ! 138: mov %ebx,%eax / result = eax = best_len ! 139: pop %ebx ! 140: pop %esi ! 141: pop %edi ! 142: pop %ebp ! 143: ret ! 144: maxmatch: ! 145: cmpsb ! 146: jmp mismatch
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.