kusano fc6ab3
; match686.asm -- Asm portion of the optimized longest_match for 32 bits x86
kusano fc6ab3
; Copyright (C) 1995-1996 Jean-loup Gailly, Brian Raiter and Gilles Vollant.
kusano fc6ab3
; File written by Gilles Vollant, by converting match686.S from Brian Raiter
kusano fc6ab3
; for MASM. This is as assembly version of longest_match
kusano fc6ab3
;  from Jean-loup Gailly in deflate.c
kusano fc6ab3
;
kusano fc6ab3
;         http://www.zlib.net
kusano fc6ab3
;         http://www.winimage.com/zLibDll
kusano fc6ab3
;         http://www.muppetlabs.com/~breadbox/software/assembly.html
kusano fc6ab3
;
kusano fc6ab3
; For Visual C++ 4.x and higher and ML 6.x and higher
kusano fc6ab3
;   ml.exe is distributed in
kusano fc6ab3
;  http://www.microsoft.com/downloads/details.aspx?FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64
kusano fc6ab3
;
kusano fc6ab3
; this file contain two implementation of longest_match
kusano fc6ab3
;
kusano fc6ab3
;  this longest_match was written by Brian raiter (1998), optimized for Pentium Pro
kusano fc6ab3
;   (and the faster known version of match_init on modern Core 2 Duo and AMD Phenom)
kusano fc6ab3
;
kusano fc6ab3
;  for using an assembly version of longest_match, you need define ASMV in project
kusano fc6ab3
;
kusano fc6ab3
;    compile the asm file running
kusano fc6ab3
;           ml /coff /Zi /c /Flmatch686.lst match686.asm
kusano fc6ab3
;    and do not include match686.obj in your project
kusano fc6ab3
;
kusano fc6ab3
; note: contrib of zLib 1.2.3 and earlier contained both a deprecated version for
kusano fc6ab3
;  Pentium (prior Pentium Pro) and this version for Pentium Pro and modern processor
kusano fc6ab3
;  with autoselect (with cpu detection code)
kusano fc6ab3
;  if you want support the old pentium optimization, you can still use these version
kusano fc6ab3
;
kusano fc6ab3
; this file is not optimized for old pentium, but it compatible with all x86 32 bits
kusano fc6ab3
; processor (starting 80386)
kusano fc6ab3
;
kusano fc6ab3
;
kusano fc6ab3
; see below : zlib1222add must be adjuster if you use a zlib version < 1.2.2.2
kusano fc6ab3
kusano fc6ab3
;uInt longest_match(s, cur_match)
kusano fc6ab3
;    deflate_state *s;
kusano fc6ab3
;    IPos cur_match;                             /* current match */
kusano fc6ab3
kusano fc6ab3
    NbStack         equ     76
kusano fc6ab3
    cur_match       equ     dword ptr[esp+NbStack-0]
kusano fc6ab3
    str_s           equ     dword ptr[esp+NbStack-4]
kusano fc6ab3
; 5 dword on top (ret,ebp,esi,edi,ebx)
kusano fc6ab3
    adrret          equ     dword ptr[esp+NbStack-8]
kusano fc6ab3
    pushebp         equ     dword ptr[esp+NbStack-12]
kusano fc6ab3
    pushedi         equ     dword ptr[esp+NbStack-16]
kusano fc6ab3
    pushesi         equ     dword ptr[esp+NbStack-20]
kusano fc6ab3
    pushebx         equ     dword ptr[esp+NbStack-24]
kusano fc6ab3
kusano fc6ab3
    chain_length    equ     dword ptr [esp+NbStack-28]
kusano fc6ab3
    limit           equ     dword ptr [esp+NbStack-32]
kusano fc6ab3
    best_len        equ     dword ptr [esp+NbStack-36]
kusano fc6ab3
    window          equ     dword ptr [esp+NbStack-40]
kusano fc6ab3
    prev            equ     dword ptr [esp+NbStack-44]
kusano fc6ab3
    scan_start      equ      word ptr [esp+NbStack-48]
kusano fc6ab3
    wmask           equ     dword ptr [esp+NbStack-52]
kusano fc6ab3
    match_start_ptr equ     dword ptr [esp+NbStack-56]
kusano fc6ab3
    nice_match      equ     dword ptr [esp+NbStack-60]
kusano fc6ab3
    scan            equ     dword ptr [esp+NbStack-64]
kusano fc6ab3
kusano fc6ab3
    windowlen       equ     dword ptr [esp+NbStack-68]
kusano fc6ab3
    match_start     equ     dword ptr [esp+NbStack-72]
kusano fc6ab3
    strend          equ     dword ptr [esp+NbStack-76]
kusano fc6ab3
    NbStackAdd      equ     (NbStack-24)
kusano fc6ab3
kusano fc6ab3
    .386p
kusano fc6ab3
kusano fc6ab3
    name    gvmatch
kusano fc6ab3
    .MODEL  FLAT
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
;  all the +zlib1222add offsets are due to the addition of fields
kusano fc6ab3
;  in zlib in the deflate_state structure since the asm code was first written
kusano fc6ab3
;  (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
kusano fc6ab3
;  (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
kusano fc6ab3
;  if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
kusano fc6ab3
kusano fc6ab3
    zlib1222add         equ     8
kusano fc6ab3
kusano fc6ab3
;  Note : these value are good with a 8 bytes boundary pack structure
kusano fc6ab3
    dep_chain_length    equ     74h+zlib1222add
kusano fc6ab3
    dep_window          equ     30h+zlib1222add
kusano fc6ab3
    dep_strstart        equ     64h+zlib1222add
kusano fc6ab3
    dep_prev_length     equ     70h+zlib1222add
kusano fc6ab3
    dep_nice_match      equ     88h+zlib1222add
kusano fc6ab3
    dep_w_size          equ     24h+zlib1222add
kusano fc6ab3
    dep_prev            equ     38h+zlib1222add
kusano fc6ab3
    dep_w_mask          equ     2ch+zlib1222add
kusano fc6ab3
    dep_good_match      equ     84h+zlib1222add
kusano fc6ab3
    dep_match_start     equ     68h+zlib1222add
kusano fc6ab3
    dep_lookahead       equ     6ch+zlib1222add
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
_TEXT                   segment
kusano fc6ab3
kusano fc6ab3
IFDEF NOUNDERLINE
kusano fc6ab3
            public  longest_match
kusano fc6ab3
            public  match_init
kusano fc6ab3
ELSE
kusano fc6ab3
            public  _longest_match
kusano fc6ab3
            public  _match_init
kusano fc6ab3
ENDIF
kusano fc6ab3
kusano fc6ab3
    MAX_MATCH           equ     258
kusano fc6ab3
    MIN_MATCH           equ     3
kusano fc6ab3
    MIN_LOOKAHEAD       equ     (MAX_MATCH+MIN_MATCH+1)
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
MAX_MATCH       equ     258
kusano fc6ab3
MIN_MATCH       equ     3
kusano fc6ab3
MIN_LOOKAHEAD   equ     (MAX_MATCH + MIN_MATCH + 1)
kusano fc6ab3
MAX_MATCH_8_     equ     ((MAX_MATCH + 7) AND 0FFF0h)
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
;;; stack frame offsets
kusano fc6ab3
kusano fc6ab3
chainlenwmask   equ  esp + 0    ; high word: current chain len
kusano fc6ab3
                    ; low word: s->wmask
kusano fc6ab3
window      equ  esp + 4    ; local copy of s->window
kusano fc6ab3
windowbestlen   equ  esp + 8    ; s->window + bestlen
kusano fc6ab3
scanstart   equ  esp + 16   ; first two bytes of string
kusano fc6ab3
scanend     equ  esp + 12   ; last two bytes of string
kusano fc6ab3
scanalign   equ  esp + 20   ; dword-misalignment of string
kusano fc6ab3
nicematch   equ  esp + 24   ; a good enough match size
kusano fc6ab3
bestlen     equ  esp + 28   ; size of best match so far
kusano fc6ab3
scan        equ  esp + 32   ; ptr to string wanting match
kusano fc6ab3
kusano fc6ab3
LocalVarsSize   equ 36
kusano fc6ab3
;   saved ebx   byte esp + 36
kusano fc6ab3
;   saved edi   byte esp + 40
kusano fc6ab3
;   saved esi   byte esp + 44
kusano fc6ab3
;   saved ebp   byte esp + 48
kusano fc6ab3
;   return address  byte esp + 52
kusano fc6ab3
deflatestate    equ  esp + 56   ; the function arguments
kusano fc6ab3
curmatch    equ  esp + 60
kusano fc6ab3
kusano fc6ab3
;;; Offsets for fields in the deflate_state structure. These numbers
kusano fc6ab3
;;; are calculated from the definition of deflate_state, with the
kusano fc6ab3
;;; assumption that the compiler will dword-align the fields. (Thus,
kusano fc6ab3
;;; changing the definition of deflate_state could easily cause this
kusano fc6ab3
;;; program to crash horribly, without so much as a warning at
kusano fc6ab3
;;; compile time. Sigh.)
kusano fc6ab3
kusano fc6ab3
dsWSize     equ 36+zlib1222add
kusano fc6ab3
dsWMask     equ 44+zlib1222add
kusano fc6ab3
dsWindow    equ 48+zlib1222add
kusano fc6ab3
dsPrev      equ 56+zlib1222add
kusano fc6ab3
dsMatchLen  equ 88+zlib1222add
kusano fc6ab3
dsPrevMatch equ 92+zlib1222add
kusano fc6ab3
dsStrStart  equ 100+zlib1222add
kusano fc6ab3
dsMatchStart    equ 104+zlib1222add
kusano fc6ab3
dsLookahead equ 108+zlib1222add
kusano fc6ab3
dsPrevLen   equ 112+zlib1222add
kusano fc6ab3
dsMaxChainLen   equ 116+zlib1222add
kusano fc6ab3
dsGoodMatch equ 132+zlib1222add
kusano fc6ab3
dsNiceMatch equ 136+zlib1222add
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
;;; match686.asm -- Pentium-Pro-optimized version of longest_match()
kusano fc6ab3
;;; Written for zlib 1.1.2
kusano fc6ab3
;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com></breadbox@muppetlabs.com>
kusano fc6ab3
;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html
kusano fc6ab3
;;;
kusano fc6ab3
;;
kusano fc6ab3
;;  This software is provided 'as-is', without any express or implied
kusano fc6ab3
;;  warranty.  In no event will the authors be held liable for any damages
kusano fc6ab3
;;  arising from the use of this software.
kusano fc6ab3
;;
kusano fc6ab3
;;  Permission is granted to anyone to use this software for any purpose,
kusano fc6ab3
;;  including commercial applications, and to alter it and redistribute it
kusano fc6ab3
;;  freely, subject to the following restrictions:
kusano fc6ab3
;;
kusano fc6ab3
;;  1. The origin of this software must not be misrepresented; you must not
kusano fc6ab3
;;     claim that you wrote the original software. If you use this software
kusano fc6ab3
;;     in a product, an acknowledgment in the product documentation would be
kusano fc6ab3
;;     appreciated but is not required.
kusano fc6ab3
;;  2. Altered source versions must be plainly marked as such, and must not be
kusano fc6ab3
;;     misrepresented as being the original software
kusano fc6ab3
;;  3. This notice may not be removed or altered from any source distribution.
kusano fc6ab3
;;
kusano fc6ab3
kusano fc6ab3
;GLOBAL _longest_match, _match_init
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
;SECTION    .text
kusano fc6ab3
kusano fc6ab3
;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
kusano fc6ab3
kusano fc6ab3
;_longest_match:
kusano fc6ab3
    IFDEF NOUNDERLINE
kusano fc6ab3
    longest_match       proc near
kusano fc6ab3
    ELSE
kusano fc6ab3
    _longest_match      proc near
kusano fc6ab3
    ENDIF
kusano fc6ab3
.FPO (9, 4, 0, 0, 1, 0)
kusano fc6ab3
kusano fc6ab3
;;; Save registers that the compiler may be using, and adjust esp to
kusano fc6ab3
;;; make room for our stack frame.
kusano fc6ab3
kusano fc6ab3
        push    ebp
kusano fc6ab3
        push    edi
kusano fc6ab3
        push    esi
kusano fc6ab3
        push    ebx
kusano fc6ab3
        sub esp, LocalVarsSize
kusano fc6ab3
kusano fc6ab3
;;; Retrieve the function arguments. ecx will hold cur_match
kusano fc6ab3
;;; throughout the entire function. edx will hold the pointer to the
kusano fc6ab3
;;; deflate_state structure during the function's setup (before
kusano fc6ab3
;;; entering the main loop.
kusano fc6ab3
kusano fc6ab3
        mov edx, [deflatestate]
kusano fc6ab3
        mov ecx, [curmatch]
kusano fc6ab3
kusano fc6ab3
;;; uInt wmask = s->w_mask;
kusano fc6ab3
;;; unsigned chain_length = s->max_chain_length;
kusano fc6ab3
;;; if (s->prev_length >= s->good_match) {
kusano fc6ab3
;;;     chain_length >>= 2;
kusano fc6ab3
;;; }
kusano fc6ab3
kusano fc6ab3
        mov eax, [edx + dsPrevLen]
kusano fc6ab3
        mov ebx, [edx + dsGoodMatch]
kusano fc6ab3
        cmp eax, ebx
kusano fc6ab3
        mov eax, [edx + dsWMask]
kusano fc6ab3
        mov ebx, [edx + dsMaxChainLen]
kusano fc6ab3
        jl  LastMatchGood
kusano fc6ab3
        shr ebx, 2
kusano fc6ab3
LastMatchGood:
kusano fc6ab3
kusano fc6ab3
;;; chainlen is decremented once beforehand so that the function can
kusano fc6ab3
;;; use the sign flag instead of the zero flag for the exit test.
kusano fc6ab3
;;; It is then shifted into the high word, to make room for the wmask
kusano fc6ab3
;;; value, which it will always accompany.
kusano fc6ab3
kusano fc6ab3
        dec ebx
kusano fc6ab3
        shl ebx, 16
kusano fc6ab3
        or  ebx, eax
kusano fc6ab3
        mov [chainlenwmask], ebx
kusano fc6ab3
kusano fc6ab3
;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
kusano fc6ab3
kusano fc6ab3
        mov eax, [edx + dsNiceMatch]
kusano fc6ab3
        mov ebx, [edx + dsLookahead]
kusano fc6ab3
        cmp ebx, eax
kusano fc6ab3
        jl  LookaheadLess
kusano fc6ab3
        mov ebx, eax
kusano fc6ab3
LookaheadLess:  mov [nicematch], ebx
kusano fc6ab3
kusano fc6ab3
;;; register Bytef *scan = s->window + s->strstart;
kusano fc6ab3
kusano fc6ab3
        mov esi, [edx + dsWindow]
kusano fc6ab3
        mov [window], esi
kusano fc6ab3
        mov ebp, [edx + dsStrStart]
kusano fc6ab3
        lea edi, [esi + ebp]
kusano fc6ab3
        mov [scan], edi
kusano fc6ab3
kusano fc6ab3
;;; Determine how many bytes the scan ptr is off from being
kusano fc6ab3
;;; dword-aligned.
kusano fc6ab3
kusano fc6ab3
        mov eax, edi
kusano fc6ab3
        neg eax
kusano fc6ab3
        and eax, 3
kusano fc6ab3
        mov [scanalign], eax
kusano fc6ab3
kusano fc6ab3
;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
kusano fc6ab3
;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;
kusano fc6ab3
kusano fc6ab3
        mov eax, [edx + dsWSize]
kusano fc6ab3
        sub eax, MIN_LOOKAHEAD
kusano fc6ab3
        sub ebp, eax
kusano fc6ab3
        jg  LimitPositive
kusano fc6ab3
        xor ebp, ebp
kusano fc6ab3
LimitPositive:
kusano fc6ab3
kusano fc6ab3
;;; int best_len = s->prev_length;
kusano fc6ab3
kusano fc6ab3
        mov eax, [edx + dsPrevLen]
kusano fc6ab3
        mov [bestlen], eax
kusano fc6ab3
kusano fc6ab3
;;; Store the sum of s->window + best_len in esi locally, and in esi.
kusano fc6ab3
kusano fc6ab3
        add esi, eax
kusano fc6ab3
        mov [windowbestlen], esi
kusano fc6ab3
kusano fc6ab3
;;; register ush scan_start = *(ushf*)scan;
kusano fc6ab3
;;; register ush scan_end   = *(ushf*)(scan+best_len-1);
kusano fc6ab3
;;; Posf *prev = s->prev;
kusano fc6ab3
kusano fc6ab3
        movzx   ebx, word ptr [edi]
kusano fc6ab3
        mov [scanstart], ebx
kusano fc6ab3
        movzx   ebx, word ptr [edi + eax - 1]
kusano fc6ab3
        mov [scanend], ebx
kusano fc6ab3
        mov edi, [edx + dsPrev]
kusano fc6ab3
kusano fc6ab3
;;; Jump into the main loop.
kusano fc6ab3
kusano fc6ab3
        mov edx, [chainlenwmask]
kusano fc6ab3
        jmp short LoopEntry
kusano fc6ab3
kusano fc6ab3
align 4
kusano fc6ab3
kusano fc6ab3
;;; do {
kusano fc6ab3
;;;     match = s->window + cur_match;
kusano fc6ab3
;;;     if (*(ushf*)(match+best_len-1) != scan_end ||
kusano fc6ab3
;;;         *(ushf*)match != scan_start) continue;
kusano fc6ab3
;;;     [...]
kusano fc6ab3
;;; } while ((cur_match = prev[cur_match & wmask]) > limit
kusano fc6ab3
;;;          && --chain_length != 0);
kusano fc6ab3
;;;
kusano fc6ab3
;;; Here is the inner loop of the function. The function will spend the
kusano fc6ab3
;;; majority of its time in this loop, and majority of that time will
kusano fc6ab3
;;; be spent in the first ten instructions.
kusano fc6ab3
;;;
kusano fc6ab3
;;; Within this loop:
kusano fc6ab3
;;; ebx = scanend
kusano fc6ab3
;;; ecx = curmatch
kusano fc6ab3
;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
kusano fc6ab3
;;; esi = windowbestlen - i.e., (window + bestlen)
kusano fc6ab3
;;; edi = prev
kusano fc6ab3
;;; ebp = limit
kusano fc6ab3
kusano fc6ab3
LookupLoop:
kusano fc6ab3
        and ecx, edx
kusano fc6ab3
        movzx   ecx, word ptr [edi + ecx*2]
kusano fc6ab3
        cmp ecx, ebp
kusano fc6ab3
        jbe LeaveNow
kusano fc6ab3
        sub edx, 00010000h
kusano fc6ab3
        js  LeaveNow
kusano fc6ab3
LoopEntry:  movzx   eax, word ptr [esi + ecx - 1]
kusano fc6ab3
        cmp eax, ebx
kusano fc6ab3
        jnz LookupLoop
kusano fc6ab3
        mov eax, [window]
kusano fc6ab3
        movzx   eax, word ptr [eax + ecx]
kusano fc6ab3
        cmp eax, [scanstart]
kusano fc6ab3
        jnz LookupLoop
kusano fc6ab3
kusano fc6ab3
;;; Store the current value of chainlen.
kusano fc6ab3
kusano fc6ab3
        mov [chainlenwmask], edx
kusano fc6ab3
kusano fc6ab3
;;; Point edi to the string under scrutiny, and esi to the string we
kusano fc6ab3
;;; are hoping to match it up with. In actuality, esi and edi are
kusano fc6ab3
;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
kusano fc6ab3
;;; initialized to -(MAX_MATCH_8 - scanalign).
kusano fc6ab3
kusano fc6ab3
        mov esi, [window]
kusano fc6ab3
        mov edi, [scan]
kusano fc6ab3
        add esi, ecx
kusano fc6ab3
        mov eax, [scanalign]
kusano fc6ab3
        mov edx, 0fffffef8h; -(MAX_MATCH_8)
kusano fc6ab3
        lea edi, [edi + eax + 0108h] ;MAX_MATCH_8]
kusano fc6ab3
        lea esi, [esi + eax + 0108h] ;MAX_MATCH_8]
kusano fc6ab3
kusano fc6ab3
;;; Test the strings for equality, 8 bytes at a time. At the end,
kusano fc6ab3
;;; adjust edx so that it is offset to the exact byte that mismatched.
kusano fc6ab3
;;;
kusano fc6ab3
;;; We already know at this point that the first three bytes of the
kusano fc6ab3
;;; strings match each other, and they can be safely passed over before
kusano fc6ab3
;;; starting the compare loop. So what this code does is skip over 0-3
kusano fc6ab3
;;; bytes, as much as necessary in order to dword-align the edi
kusano fc6ab3
;;; pointer. (esi will still be misaligned three times out of four.)
kusano fc6ab3
;;;
kusano fc6ab3
;;; It should be confessed that this loop usually does not represent
kusano fc6ab3
;;; much of the total running time. Replacing it with a more
kusano fc6ab3
;;; straightforward "rep cmpsb" would not drastically degrade
kusano fc6ab3
;;; performance.
kusano fc6ab3
kusano fc6ab3
LoopCmps:
kusano fc6ab3
        mov eax, [esi + edx]
kusano fc6ab3
        xor eax, [edi + edx]
kusano fc6ab3
        jnz LeaveLoopCmps
kusano fc6ab3
        mov eax, [esi + edx + 4]
kusano fc6ab3
        xor eax, [edi + edx + 4]
kusano fc6ab3
        jnz LeaveLoopCmps4
kusano fc6ab3
        add edx, 8
kusano fc6ab3
        jnz LoopCmps
kusano fc6ab3
        jmp short LenMaximum
kusano fc6ab3
LeaveLoopCmps4: add edx, 4
kusano fc6ab3
LeaveLoopCmps:  test    eax, 0000FFFFh
kusano fc6ab3
        jnz LenLower
kusano fc6ab3
        add edx,  2
kusano fc6ab3
        shr eax, 16
kusano fc6ab3
LenLower:   sub al, 1
kusano fc6ab3
        adc edx, 0
kusano fc6ab3
kusano fc6ab3
;;; Calculate the length of the match. If it is longer than MAX_MATCH,
kusano fc6ab3
;;; then automatically accept it as the best possible match and leave.
kusano fc6ab3
kusano fc6ab3
        lea eax, [edi + edx]
kusano fc6ab3
        mov edi, [scan]
kusano fc6ab3
        sub eax, edi
kusano fc6ab3
        cmp eax, MAX_MATCH
kusano fc6ab3
        jge LenMaximum
kusano fc6ab3
kusano fc6ab3
;;; If the length of the match is not longer than the best match we
kusano fc6ab3
;;; have so far, then forget it and return to the lookup loop.
kusano fc6ab3
kusano fc6ab3
        mov edx, [deflatestate]
kusano fc6ab3
        mov ebx, [bestlen]
kusano fc6ab3
        cmp eax, ebx
kusano fc6ab3
        jg  LongerMatch
kusano fc6ab3
        mov esi, [windowbestlen]
kusano fc6ab3
        mov edi, [edx + dsPrev]
kusano fc6ab3
        mov ebx, [scanend]
kusano fc6ab3
        mov edx, [chainlenwmask]
kusano fc6ab3
        jmp LookupLoop
kusano fc6ab3
kusano fc6ab3
;;;         s->match_start = cur_match;
kusano fc6ab3
;;;         best_len = len;
kusano fc6ab3
;;;         if (len >= nice_match) break;
kusano fc6ab3
;;;         scan_end = *(ushf*)(scan+best_len-1);
kusano fc6ab3
kusano fc6ab3
LongerMatch:    mov ebx, [nicematch]
kusano fc6ab3
        mov [bestlen], eax
kusano fc6ab3
        mov [edx + dsMatchStart], ecx
kusano fc6ab3
        cmp eax, ebx
kusano fc6ab3
        jge LeaveNow
kusano fc6ab3
        mov esi, [window]
kusano fc6ab3
        add esi, eax
kusano fc6ab3
        mov [windowbestlen], esi
kusano fc6ab3
        movzx   ebx, word ptr [edi + eax - 1]
kusano fc6ab3
        mov edi, [edx + dsPrev]
kusano fc6ab3
        mov [scanend], ebx
kusano fc6ab3
        mov edx, [chainlenwmask]
kusano fc6ab3
        jmp LookupLoop
kusano fc6ab3
kusano fc6ab3
;;; Accept the current string, with the maximum possible length.
kusano fc6ab3
kusano fc6ab3
LenMaximum: mov edx, [deflatestate]
kusano fc6ab3
        mov dword ptr [bestlen], MAX_MATCH
kusano fc6ab3
        mov [edx + dsMatchStart], ecx
kusano fc6ab3
kusano fc6ab3
;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
kusano fc6ab3
;;; return s->lookahead;
kusano fc6ab3
kusano fc6ab3
LeaveNow:
kusano fc6ab3
        mov edx, [deflatestate]
kusano fc6ab3
        mov ebx, [bestlen]
kusano fc6ab3
        mov eax, [edx + dsLookahead]
kusano fc6ab3
        cmp ebx, eax
kusano fc6ab3
        jg  LookaheadRet
kusano fc6ab3
        mov eax, ebx
kusano fc6ab3
LookaheadRet:
kusano fc6ab3
kusano fc6ab3
;;; Restore the stack and return from whence we came.
kusano fc6ab3
kusano fc6ab3
        add esp, LocalVarsSize
kusano fc6ab3
        pop ebx
kusano fc6ab3
        pop esi
kusano fc6ab3
        pop edi
kusano fc6ab3
        pop ebp
kusano fc6ab3
kusano fc6ab3
        ret
kusano fc6ab3
; please don't remove this string !
kusano fc6ab3
; Your can freely use match686 in any free or commercial app if you don't remove the string in the binary!
kusano fc6ab3
    db     0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
    IFDEF NOUNDERLINE
kusano fc6ab3
    longest_match       endp
kusano fc6ab3
    ELSE
kusano fc6ab3
    _longest_match      endp
kusano fc6ab3
    ENDIF
kusano fc6ab3
kusano fc6ab3
    IFDEF NOUNDERLINE
kusano fc6ab3
    match_init      proc near
kusano fc6ab3
                    ret
kusano fc6ab3
    match_init      endp
kusano fc6ab3
    ELSE
kusano fc6ab3
    _match_init     proc near
kusano fc6ab3
                    ret
kusano fc6ab3
    _match_init     endp
kusano fc6ab3
    ENDIF
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
_TEXT   ends
kusano fc6ab3
end