Annotation of pgp/src/zmatch.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: 
        !            20:         .file   "zmatch.S"
        !            21: 
        !            22: #ifdef SYSV
        !            23: #  define _prev             prev
        !            24: #  define _window           window
        !            25: #  define _match_start      match_start
        !            26: #  define _prev_length      prev_length
        !            27: #  define _good_match       good_match
        !            28: #  define _strstart         strstart
        !            29: #  define _max_chain_length max_chain_length
        !            30: 
        !            31: #  define _match_init       match_init
        !            32: #  define _longest_match    longest_match
        !            33: #endif
        !            34: 
        !            35: #define MAX_MATCH       258
        !            36: #define MAX_MATCH2      128    /* MAX_MATCH/2-1 */
        !            37: #define MIN_MATCH       3
        !            38: #define WSIZE           8192
        !            39: #define MAX_DIST        WSIZE - MAX_MATCH - MIN_MATCH - 1
        !            40: 
        !            41:         .globl  _match_init
        !            42:         .globl  _longest_match
        !            43: 
        !            44:         .text
        !            45: 
        !            46: _match_init:
        !            47:         ret
        !            48: 
        !            49: /* -----------------------------------------------------------------------
        !            50:  * Set match_start to the longest match starting at the given string and
        !            51:  * return its length. Matches shorter or equal to prev_length are discarded,
        !            52:  * in which case the result is equal to prev_length and match_start is
        !            53:  * garbage.
        !            54:  * IN assertions: cur_match is the head of the hash chain for the current
        !            55:  *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
        !            56:  */
        !            57: 
        !            58: _longest_match: /* int longest_match(cur_match) */
        !            59: 
        !            60: #define cur_match   20(%esp)
        !            61:        /* return address                / esp+16 */
        !            62:         push    %ebp                   /* esp+12 */
        !            63:         push    %edi                   /* esp+8 */
        !            64:         push    %esi                   /* esp+4 */
        !            65:         push    %ebx            /* esp */
        !            66: 
        !            67: /*       match        equ esi
        !            68:  *       scan         equ edi
        !            69:  *       chain_length equ ebp
        !            70:  *       best_len     equ ebx
        !            71:  *       limit        equ edx
        !            72:  */
        !            73: 
        !            74:         mov     cur_match,%esi
        !            75:         mov     _max_chain_length,%ebp /* chain_length = max_chain_length */
        !            76:         mov     _strstart,%edi
        !            77:         mov     %edi,%edx
        !            78:         sub     $ MAX_DIST,%edx        /* limit = strstart-MAX_DIST */
        !            79:         jae     limit_ok
        !            80:         sub     %edx,%edx              /* limit = NIL */
        !            81: limit_ok:
        !            82:         add     $_window+2,%edi        /* edi = offset(window + strstart + 2) */
        !            83:         mov     _prev_length,%ebx      /* best_len = prev_length */
        !            84:         movw    -3(%ebx,%edi),%ax      /* ax = scan[best_len-1..best_len] */
        !            85:         movw    -2(%edi),%cx           /* cx = scan[0..1] */
        !            86:         cmp     _good_match,%ebx       /* do we have a good match already? */
        !            87:         jb      do_scan
        !            88:         shr     $2,%ebp                /* chain_length >>= 2 */
        !            89:         jmp     do_scan
        !            90: 
        !            91:         .align  4
        !            92: long_loop:
        !            93: /* at this point, edi == scan+2, esi == cur_match */
        !            94:         movw    -3(%ebx,%edi),%ax      /* ax = scan[best_len-1..best_len] */
        !            95:         movw     -2(%edi),%cx           /* cx = scan[0..1] */
        !            96: short_loop:
        !            97:         dec     %ebp                   /* --chain_length */
        !            98:         jz      the_end
        !            99: /* at this point, di == scan+2, si == cur_match,
        !           100:  * ax = scan[best_len-1..best_len] and cx = scan[0..1]
        !           101:  */
        !           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 SYSV
        !           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.