Annotation of coherent/b/bin/zip/match.s, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.