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