Annotation of coherent/b/bin/zip/match.s, revision 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.