Annotation of pgp/src/zmatch.S, revision 1.1.1.2

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: 
1.1.1.2 ! root       22: #if defined(SYSV) || defined(__ELF__)
1.1       root       23: #  define _prev             prev
1.1.1.2 ! root       24: #  define _slide            slide
1.1       root       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:
1.1.1.2 ! root       82:         add     $_slide+2,%edi         /* edi = offset(slide + strstart + 2) */
1.1       root       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] */
1.1.1.2 ! root       95:         movw    -2(%edi),%cx           /* cx = scan[0..1] */
1.1       root       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
1.1.1.2 ! root      103:         movw    _prev(%esi,%esi),%si   /* cur_match = prev[cur_match] */
1.1       root      104:                                        /* top word of esi is still 0 */
                    105:         cmp     %edx,%esi       /* cur_match <= limit ? */
                    106:         jbe     the_end
                    107: do_scan:
1.1.1.2 ! root      108:         cmpw    _slide-1(%ebx,%esi),%ax/*check match at best_len-1 */
1.1       root      109:         jne     short_loop
1.1.1.2 ! root      110:         cmpw    _slide(%esi),%cx       /* check min_match_length match */
1.1       root      111:         jne     short_loop
                    112: 
1.1.1.2 ! root      113:         lea     _slide+2(%esi),%esi    /* si = match */
1.1       root      114:         mov     %edi,%eax              /* ax = scan+2 */
                    115:         mov     $ MAX_MATCH2,%ecx      /* scan for at most MAX_MATCH bytes */
1.1.1.2 ! root      116: #if defined(SYSV) || defined(__ELF__)
1.1       root      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 */
1.1.1.2 ! root      127:         sub     %eax,%esi              /* esi = cur_match + 2 + offset(slide) */
        !           128:         sub     $_slide+2,%esi         /* esi = cur_match */
1.1       root      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.