Annotation of pgp/src/zmatch.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: 
                     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.