1*44bedb31SLionel Sambuc 2*44bedb31SLionel Sambuc; match.asm -- Pentium-Pro optimized version of longest_match() 3*44bedb31SLionel Sambuc; 4*44bedb31SLionel Sambuc; Updated for zlib 1.1.3 and converted to MASM 6.1x 5*44bedb31SLionel Sambuc; Copyright (C) 2000 Dan Higdon <hdan@kinesoft.com> 6*44bedb31SLionel Sambuc; and Chuck Walbourn <chuckw@kinesoft.com> 7*44bedb31SLionel Sambuc; Corrections by Cosmin Truta <cosmint@cs.ubbcluj.ro> 8*44bedb31SLionel Sambuc; 9*44bedb31SLionel Sambuc; This is free software; you can redistribute it and/or modify it 10*44bedb31SLionel Sambuc; under the terms of the GNU General Public License. 11*44bedb31SLionel Sambuc 12*44bedb31SLionel Sambuc; Based on match.S 13*44bedb31SLionel Sambuc; Written for zlib 1.1.2 14*44bedb31SLionel Sambuc; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com> 15*44bedb31SLionel Sambuc; 16*44bedb31SLionel Sambuc; Modified by Gilles Vollant (2005) for add gzhead and gzindex 17*44bedb31SLionel Sambuc 18*44bedb31SLionel Sambuc .686P 19*44bedb31SLionel Sambuc .MODEL FLAT 20*44bedb31SLionel Sambuc 21*44bedb31SLionel Sambuc;=========================================================================== 22*44bedb31SLionel Sambuc; EQUATES 23*44bedb31SLionel Sambuc;=========================================================================== 24*44bedb31SLionel Sambuc 25*44bedb31SLionel SambucMAX_MATCH EQU 258 26*44bedb31SLionel SambucMIN_MATCH EQU 3 27*44bedb31SLionel SambucMIN_LOOKAHEAD EQU (MAX_MATCH + MIN_MATCH + 1) 28*44bedb31SLionel SambucMAX_MATCH_8 EQU ((MAX_MATCH + 7) AND (NOT 7)) 29*44bedb31SLionel Sambuc 30*44bedb31SLionel Sambuc;=========================================================================== 31*44bedb31SLionel Sambuc; STRUCTURES 32*44bedb31SLionel Sambuc;=========================================================================== 33*44bedb31SLionel Sambuc 34*44bedb31SLionel Sambuc; This STRUCT assumes a 4-byte alignment 35*44bedb31SLionel Sambuc 36*44bedb31SLionel SambucDEFLATE_STATE STRUCT 37*44bedb31SLionel Sambucds_strm dd ? 38*44bedb31SLionel Sambucds_status dd ? 39*44bedb31SLionel Sambucds_pending_buf dd ? 40*44bedb31SLionel Sambucds_pending_buf_size dd ? 41*44bedb31SLionel Sambucds_pending_out dd ? 42*44bedb31SLionel Sambucds_pending dd ? 43*44bedb31SLionel Sambucds_wrap dd ? 44*44bedb31SLionel Sambuc; gzhead and gzindex are added in zlib 1.2.2.2 (see deflate.h) 45*44bedb31SLionel Sambucds_gzhead dd ? 46*44bedb31SLionel Sambucds_gzindex dd ? 47*44bedb31SLionel Sambucds_data_type db ? 48*44bedb31SLionel Sambucds_method db ? 49*44bedb31SLionel Sambuc db ? ; padding 50*44bedb31SLionel Sambuc db ? ; padding 51*44bedb31SLionel Sambucds_last_flush dd ? 52*44bedb31SLionel Sambucds_w_size dd ? ; used 53*44bedb31SLionel Sambucds_w_bits dd ? 54*44bedb31SLionel Sambucds_w_mask dd ? ; used 55*44bedb31SLionel Sambucds_window dd ? ; used 56*44bedb31SLionel Sambucds_window_size dd ? 57*44bedb31SLionel Sambucds_prev dd ? ; used 58*44bedb31SLionel Sambucds_head dd ? 59*44bedb31SLionel Sambucds_ins_h dd ? 60*44bedb31SLionel Sambucds_hash_size dd ? 61*44bedb31SLionel Sambucds_hash_bits dd ? 62*44bedb31SLionel Sambucds_hash_mask dd ? 63*44bedb31SLionel Sambucds_hash_shift dd ? 64*44bedb31SLionel Sambucds_block_start dd ? 65*44bedb31SLionel Sambucds_match_length dd ? ; used 66*44bedb31SLionel Sambucds_prev_match dd ? ; used 67*44bedb31SLionel Sambucds_match_available dd ? 68*44bedb31SLionel Sambucds_strstart dd ? ; used 69*44bedb31SLionel Sambucds_match_start dd ? ; used 70*44bedb31SLionel Sambucds_lookahead dd ? ; used 71*44bedb31SLionel Sambucds_prev_length dd ? ; used 72*44bedb31SLionel Sambucds_max_chain_length dd ? ; used 73*44bedb31SLionel Sambucds_max_laxy_match dd ? 74*44bedb31SLionel Sambucds_level dd ? 75*44bedb31SLionel Sambucds_strategy dd ? 76*44bedb31SLionel Sambucds_good_match dd ? ; used 77*44bedb31SLionel Sambucds_nice_match dd ? ; used 78*44bedb31SLionel Sambuc 79*44bedb31SLionel Sambuc; Don't need anymore of the struct for match 80*44bedb31SLionel SambucDEFLATE_STATE ENDS 81*44bedb31SLionel Sambuc 82*44bedb31SLionel Sambuc;=========================================================================== 83*44bedb31SLionel Sambuc; CODE 84*44bedb31SLionel Sambuc;=========================================================================== 85*44bedb31SLionel Sambuc_TEXT SEGMENT 86*44bedb31SLionel Sambuc 87*44bedb31SLionel Sambuc;--------------------------------------------------------------------------- 88*44bedb31SLionel Sambuc; match_init 89*44bedb31SLionel Sambuc;--------------------------------------------------------------------------- 90*44bedb31SLionel Sambuc ALIGN 4 91*44bedb31SLionel SambucPUBLIC _match_init 92*44bedb31SLionel Sambuc_match_init PROC 93*44bedb31SLionel Sambuc ; no initialization needed 94*44bedb31SLionel Sambuc ret 95*44bedb31SLionel Sambuc_match_init ENDP 96*44bedb31SLionel Sambuc 97*44bedb31SLionel Sambuc;--------------------------------------------------------------------------- 98*44bedb31SLionel Sambuc; uInt longest_match(deflate_state *deflatestate, IPos curmatch) 99*44bedb31SLionel Sambuc;--------------------------------------------------------------------------- 100*44bedb31SLionel Sambuc ALIGN 4 101*44bedb31SLionel Sambuc 102*44bedb31SLionel SambucPUBLIC _longest_match 103*44bedb31SLionel Sambuc_longest_match PROC 104*44bedb31SLionel Sambuc 105*44bedb31SLionel Sambuc; Since this code uses EBP for a scratch register, the stack frame must 106*44bedb31SLionel Sambuc; be manually constructed and referenced relative to the ESP register. 107*44bedb31SLionel Sambuc 108*44bedb31SLionel Sambuc; Stack image 109*44bedb31SLionel Sambuc; Variables 110*44bedb31SLionel Sambucchainlenwmask = 0 ; high word: current chain len 111*44bedb31SLionel Sambuc ; low word: s->wmask 112*44bedb31SLionel Sambucwindow = 4 ; local copy of s->window 113*44bedb31SLionel Sambucwindowbestlen = 8 ; s->window + bestlen 114*44bedb31SLionel Sambucscanend = 12 ; last two bytes of string 115*44bedb31SLionel Sambucscanstart = 16 ; first two bytes of string 116*44bedb31SLionel Sambucscanalign = 20 ; dword-misalignment of string 117*44bedb31SLionel Sambucnicematch = 24 ; a good enough match size 118*44bedb31SLionel Sambucbestlen = 28 ; size of best match so far 119*44bedb31SLionel Sambucscan = 32 ; ptr to string wanting match 120*44bedb31SLionel Sambucvarsize = 36 ; number of bytes (also offset to last saved register) 121*44bedb31SLionel Sambuc 122*44bedb31SLionel Sambuc; Saved Registers (actually pushed into place) 123*44bedb31SLionel Sambucebx_save = 36 124*44bedb31SLionel Sambucedi_save = 40 125*44bedb31SLionel Sambucesi_save = 44 126*44bedb31SLionel Sambucebp_save = 48 127*44bedb31SLionel Sambuc 128*44bedb31SLionel Sambuc; Parameters 129*44bedb31SLionel Sambucretaddr = 52 130*44bedb31SLionel Sambucdeflatestate = 56 131*44bedb31SLionel Sambuccurmatch = 60 132*44bedb31SLionel Sambuc 133*44bedb31SLionel Sambuc; Save registers that the compiler may be using 134*44bedb31SLionel Sambuc push ebp 135*44bedb31SLionel Sambuc push edi 136*44bedb31SLionel Sambuc push esi 137*44bedb31SLionel Sambuc push ebx 138*44bedb31SLionel Sambuc 139*44bedb31SLionel Sambuc; Allocate local variable space 140*44bedb31SLionel Sambuc sub esp,varsize 141*44bedb31SLionel Sambuc 142*44bedb31SLionel Sambuc; Retrieve the function arguments. ecx will hold cur_match 143*44bedb31SLionel Sambuc; throughout the entire function. edx will hold the pointer to the 144*44bedb31SLionel Sambuc; deflate_state structure during the function's setup (before 145*44bedb31SLionel Sambuc; entering the main loop). 146*44bedb31SLionel Sambuc 147*44bedb31SLionel Sambuc mov edx, [esp+deflatestate] 148*44bedb31SLionel SambucASSUME edx:PTR DEFLATE_STATE 149*44bedb31SLionel Sambuc 150*44bedb31SLionel Sambuc mov ecx, [esp+curmatch] 151*44bedb31SLionel Sambuc 152*44bedb31SLionel Sambuc; uInt wmask = s->w_mask; 153*44bedb31SLionel Sambuc; unsigned chain_length = s->max_chain_length; 154*44bedb31SLionel Sambuc; if (s->prev_length >= s->good_match) { 155*44bedb31SLionel Sambuc; chain_length >>= 2; 156*44bedb31SLionel Sambuc; } 157*44bedb31SLionel Sambuc 158*44bedb31SLionel Sambuc mov eax, [edx].ds_prev_length 159*44bedb31SLionel Sambuc mov ebx, [edx].ds_good_match 160*44bedb31SLionel Sambuc cmp eax, ebx 161*44bedb31SLionel Sambuc mov eax, [edx].ds_w_mask 162*44bedb31SLionel Sambuc mov ebx, [edx].ds_max_chain_length 163*44bedb31SLionel Sambuc jl SHORT LastMatchGood 164*44bedb31SLionel Sambuc shr ebx, 2 165*44bedb31SLionel SambucLastMatchGood: 166*44bedb31SLionel Sambuc 167*44bedb31SLionel Sambuc; chainlen is decremented once beforehand so that the function can 168*44bedb31SLionel Sambuc; use the sign flag instead of the zero flag for the exit test. 169*44bedb31SLionel Sambuc; It is then shifted into the high word, to make room for the wmask 170*44bedb31SLionel Sambuc; value, which it will always accompany. 171*44bedb31SLionel Sambuc 172*44bedb31SLionel Sambuc dec ebx 173*44bedb31SLionel Sambuc shl ebx, 16 174*44bedb31SLionel Sambuc or ebx, eax 175*44bedb31SLionel Sambuc mov [esp+chainlenwmask], ebx 176*44bedb31SLionel Sambuc 177*44bedb31SLionel Sambuc; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; 178*44bedb31SLionel Sambuc 179*44bedb31SLionel Sambuc mov eax, [edx].ds_nice_match 180*44bedb31SLionel Sambuc mov ebx, [edx].ds_lookahead 181*44bedb31SLionel Sambuc cmp ebx, eax 182*44bedb31SLionel Sambuc jl SHORT LookaheadLess 183*44bedb31SLionel Sambuc mov ebx, eax 184*44bedb31SLionel SambucLookaheadLess: 185*44bedb31SLionel Sambuc mov [esp+nicematch], ebx 186*44bedb31SLionel Sambuc 187*44bedb31SLionel Sambuc;/* register Bytef *scan = s->window + s->strstart; */ 188*44bedb31SLionel Sambuc 189*44bedb31SLionel Sambuc mov esi, [edx].ds_window 190*44bedb31SLionel Sambuc mov [esp+window], esi 191*44bedb31SLionel Sambuc mov ebp, [edx].ds_strstart 192*44bedb31SLionel Sambuc lea edi, [esi+ebp] 193*44bedb31SLionel Sambuc mov [esp+scan],edi 194*44bedb31SLionel Sambuc 195*44bedb31SLionel Sambuc;/* Determine how many bytes the scan ptr is off from being */ 196*44bedb31SLionel Sambuc;/* dword-aligned. */ 197*44bedb31SLionel Sambuc 198*44bedb31SLionel Sambuc mov eax, edi 199*44bedb31SLionel Sambuc neg eax 200*44bedb31SLionel Sambuc and eax, 3 201*44bedb31SLionel Sambuc mov [esp+scanalign], eax 202*44bedb31SLionel Sambuc 203*44bedb31SLionel Sambuc;/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ 204*44bedb31SLionel Sambuc;/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ 205*44bedb31SLionel Sambuc 206*44bedb31SLionel Sambuc mov eax, [edx].ds_w_size 207*44bedb31SLionel Sambuc sub eax, MIN_LOOKAHEAD 208*44bedb31SLionel Sambuc sub ebp, eax 209*44bedb31SLionel Sambuc jg SHORT LimitPositive 210*44bedb31SLionel Sambuc xor ebp, ebp 211*44bedb31SLionel SambucLimitPositive: 212*44bedb31SLionel Sambuc 213*44bedb31SLionel Sambuc;/* int best_len = s->prev_length; */ 214*44bedb31SLionel Sambuc 215*44bedb31SLionel Sambuc mov eax, [edx].ds_prev_length 216*44bedb31SLionel Sambuc mov [esp+bestlen], eax 217*44bedb31SLionel Sambuc 218*44bedb31SLionel Sambuc;/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ 219*44bedb31SLionel Sambuc 220*44bedb31SLionel Sambuc add esi, eax 221*44bedb31SLionel Sambuc mov [esp+windowbestlen], esi 222*44bedb31SLionel Sambuc 223*44bedb31SLionel Sambuc;/* register ush scan_start = *(ushf*)scan; */ 224*44bedb31SLionel Sambuc;/* register ush scan_end = *(ushf*)(scan+best_len-1); */ 225*44bedb31SLionel Sambuc;/* Posf *prev = s->prev; */ 226*44bedb31SLionel Sambuc 227*44bedb31SLionel Sambuc movzx ebx, WORD PTR[edi] 228*44bedb31SLionel Sambuc mov [esp+scanstart], ebx 229*44bedb31SLionel Sambuc movzx ebx, WORD PTR[eax+edi-1] 230*44bedb31SLionel Sambuc mov [esp+scanend], ebx 231*44bedb31SLionel Sambuc mov edi, [edx].ds_prev 232*44bedb31SLionel Sambuc 233*44bedb31SLionel Sambuc;/* Jump into the main loop. */ 234*44bedb31SLionel Sambuc 235*44bedb31SLionel Sambuc mov edx, [esp+chainlenwmask] 236*44bedb31SLionel Sambuc jmp SHORT LoopEntry 237*44bedb31SLionel Sambuc 238*44bedb31SLionel Sambuc;/* do { 239*44bedb31SLionel Sambuc; * match = s->window + cur_match; 240*44bedb31SLionel Sambuc; * if (*(ushf*)(match+best_len-1) != scan_end || 241*44bedb31SLionel Sambuc; * *(ushf*)match != scan_start) continue; 242*44bedb31SLionel Sambuc; * [...] 243*44bedb31SLionel Sambuc; * } while ((cur_match = prev[cur_match & wmask]) > limit 244*44bedb31SLionel Sambuc; * && --chain_length != 0); 245*44bedb31SLionel Sambuc; * 246*44bedb31SLionel Sambuc; * Here is the inner loop of the function. The function will spend the 247*44bedb31SLionel Sambuc; * majority of its time in this loop, and majority of that time will 248*44bedb31SLionel Sambuc; * be spent in the first ten instructions. 249*44bedb31SLionel Sambuc; * 250*44bedb31SLionel Sambuc; * Within this loop: 251*44bedb31SLionel Sambuc; * %ebx = scanend 252*44bedb31SLionel Sambuc; * %ecx = curmatch 253*44bedb31SLionel Sambuc; * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) 254*44bedb31SLionel Sambuc; * %esi = windowbestlen - i.e., (window + bestlen) 255*44bedb31SLionel Sambuc; * %edi = prev 256*44bedb31SLionel Sambuc; * %ebp = limit 257*44bedb31SLionel Sambuc; */ 258*44bedb31SLionel Sambuc 259*44bedb31SLionel Sambuc ALIGN 4 260*44bedb31SLionel SambucLookupLoop: 261*44bedb31SLionel Sambuc and ecx, edx 262*44bedb31SLionel Sambuc movzx ecx, WORD PTR[edi+ecx*2] 263*44bedb31SLionel Sambuc cmp ecx, ebp 264*44bedb31SLionel Sambuc jbe LeaveNow 265*44bedb31SLionel Sambuc sub edx, 000010000H 266*44bedb31SLionel Sambuc js LeaveNow 267*44bedb31SLionel Sambuc 268*44bedb31SLionel SambucLoopEntry: 269*44bedb31SLionel Sambuc movzx eax, WORD PTR[esi+ecx-1] 270*44bedb31SLionel Sambuc cmp eax, ebx 271*44bedb31SLionel Sambuc jnz SHORT LookupLoop 272*44bedb31SLionel Sambuc 273*44bedb31SLionel Sambuc mov eax, [esp+window] 274*44bedb31SLionel Sambuc movzx eax, WORD PTR[eax+ecx] 275*44bedb31SLionel Sambuc cmp eax, [esp+scanstart] 276*44bedb31SLionel Sambuc jnz SHORT LookupLoop 277*44bedb31SLionel Sambuc 278*44bedb31SLionel Sambuc;/* Store the current value of chainlen. */ 279*44bedb31SLionel Sambuc 280*44bedb31SLionel Sambuc mov [esp+chainlenwmask], edx 281*44bedb31SLionel Sambuc 282*44bedb31SLionel Sambuc;/* Point %edi to the string under scrutiny, and %esi to the string we */ 283*44bedb31SLionel Sambuc;/* are hoping to match it up with. In actuality, %esi and %edi are */ 284*44bedb31SLionel Sambuc;/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ 285*44bedb31SLionel Sambuc;/* initialized to -(MAX_MATCH_8 - scanalign). */ 286*44bedb31SLionel Sambuc 287*44bedb31SLionel Sambuc mov esi, [esp+window] 288*44bedb31SLionel Sambuc mov edi, [esp+scan] 289*44bedb31SLionel Sambuc add esi, ecx 290*44bedb31SLionel Sambuc mov eax, [esp+scanalign] 291*44bedb31SLionel Sambuc mov edx, -MAX_MATCH_8 292*44bedb31SLionel Sambuc lea edi, [edi+eax+MAX_MATCH_8] 293*44bedb31SLionel Sambuc lea esi, [esi+eax+MAX_MATCH_8] 294*44bedb31SLionel Sambuc 295*44bedb31SLionel Sambuc;/* Test the strings for equality, 8 bytes at a time. At the end, 296*44bedb31SLionel Sambuc; * adjust %edx so that it is offset to the exact byte that mismatched. 297*44bedb31SLionel Sambuc; * 298*44bedb31SLionel Sambuc; * We already know at this point that the first three bytes of the 299*44bedb31SLionel Sambuc; * strings match each other, and they can be safely passed over before 300*44bedb31SLionel Sambuc; * starting the compare loop. So what this code does is skip over 0-3 301*44bedb31SLionel Sambuc; * bytes, as much as necessary in order to dword-align the %edi 302*44bedb31SLionel Sambuc; * pointer. (%esi will still be misaligned three times out of four.) 303*44bedb31SLionel Sambuc; * 304*44bedb31SLionel Sambuc; * It should be confessed that this loop usually does not represent 305*44bedb31SLionel Sambuc; * much of the total running time. Replacing it with a more 306*44bedb31SLionel Sambuc; * straightforward "rep cmpsb" would not drastically degrade 307*44bedb31SLionel Sambuc; * performance. 308*44bedb31SLionel Sambuc; */ 309*44bedb31SLionel Sambuc 310*44bedb31SLionel SambucLoopCmps: 311*44bedb31SLionel Sambuc mov eax, DWORD PTR[esi+edx] 312*44bedb31SLionel Sambuc xor eax, DWORD PTR[edi+edx] 313*44bedb31SLionel Sambuc jnz SHORT LeaveLoopCmps 314*44bedb31SLionel Sambuc 315*44bedb31SLionel Sambuc mov eax, DWORD PTR[esi+edx+4] 316*44bedb31SLionel Sambuc xor eax, DWORD PTR[edi+edx+4] 317*44bedb31SLionel Sambuc jnz SHORT LeaveLoopCmps4 318*44bedb31SLionel Sambuc 319*44bedb31SLionel Sambuc add edx, 8 320*44bedb31SLionel Sambuc jnz SHORT LoopCmps 321*44bedb31SLionel Sambuc jmp LenMaximum 322*44bedb31SLionel Sambuc ALIGN 4 323*44bedb31SLionel Sambuc 324*44bedb31SLionel SambucLeaveLoopCmps4: 325*44bedb31SLionel Sambuc add edx, 4 326*44bedb31SLionel Sambuc 327*44bedb31SLionel SambucLeaveLoopCmps: 328*44bedb31SLionel Sambuc test eax, 00000FFFFH 329*44bedb31SLionel Sambuc jnz SHORT LenLower 330*44bedb31SLionel Sambuc 331*44bedb31SLionel Sambuc add edx, 2 332*44bedb31SLionel Sambuc shr eax, 16 333*44bedb31SLionel Sambuc 334*44bedb31SLionel SambucLenLower: 335*44bedb31SLionel Sambuc sub al, 1 336*44bedb31SLionel Sambuc adc edx, 0 337*44bedb31SLionel Sambuc 338*44bedb31SLionel Sambuc;/* Calculate the length of the match. If it is longer than MAX_MATCH, */ 339*44bedb31SLionel Sambuc;/* then automatically accept it as the best possible match and leave. */ 340*44bedb31SLionel Sambuc 341*44bedb31SLionel Sambuc lea eax, [edi+edx] 342*44bedb31SLionel Sambuc mov edi, [esp+scan] 343*44bedb31SLionel Sambuc sub eax, edi 344*44bedb31SLionel Sambuc cmp eax, MAX_MATCH 345*44bedb31SLionel Sambuc jge SHORT LenMaximum 346*44bedb31SLionel Sambuc 347*44bedb31SLionel Sambuc;/* If the length of the match is not longer than the best match we */ 348*44bedb31SLionel Sambuc;/* have so far, then forget it and return to the lookup loop. */ 349*44bedb31SLionel Sambuc 350*44bedb31SLionel Sambuc mov edx, [esp+deflatestate] 351*44bedb31SLionel Sambuc mov ebx, [esp+bestlen] 352*44bedb31SLionel Sambuc cmp eax, ebx 353*44bedb31SLionel Sambuc jg SHORT LongerMatch 354*44bedb31SLionel Sambuc mov esi, [esp+windowbestlen] 355*44bedb31SLionel Sambuc mov edi, [edx].ds_prev 356*44bedb31SLionel Sambuc mov ebx, [esp+scanend] 357*44bedb31SLionel Sambuc mov edx, [esp+chainlenwmask] 358*44bedb31SLionel Sambuc jmp LookupLoop 359*44bedb31SLionel Sambuc ALIGN 4 360*44bedb31SLionel Sambuc 361*44bedb31SLionel Sambuc;/* s->match_start = cur_match; */ 362*44bedb31SLionel Sambuc;/* best_len = len; */ 363*44bedb31SLionel Sambuc;/* if (len >= nice_match) break; */ 364*44bedb31SLionel Sambuc;/* scan_end = *(ushf*)(scan+best_len-1); */ 365*44bedb31SLionel Sambuc 366*44bedb31SLionel SambucLongerMatch: 367*44bedb31SLionel Sambuc mov ebx, [esp+nicematch] 368*44bedb31SLionel Sambuc mov [esp+bestlen], eax 369*44bedb31SLionel Sambuc mov [edx].ds_match_start, ecx 370*44bedb31SLionel Sambuc cmp eax, ebx 371*44bedb31SLionel Sambuc jge SHORT LeaveNow 372*44bedb31SLionel Sambuc mov esi, [esp+window] 373*44bedb31SLionel Sambuc add esi, eax 374*44bedb31SLionel Sambuc mov [esp+windowbestlen], esi 375*44bedb31SLionel Sambuc movzx ebx, WORD PTR[edi+eax-1] 376*44bedb31SLionel Sambuc mov edi, [edx].ds_prev 377*44bedb31SLionel Sambuc mov [esp+scanend], ebx 378*44bedb31SLionel Sambuc mov edx, [esp+chainlenwmask] 379*44bedb31SLionel Sambuc jmp LookupLoop 380*44bedb31SLionel Sambuc ALIGN 4 381*44bedb31SLionel Sambuc 382*44bedb31SLionel Sambuc;/* Accept the current string, with the maximum possible length. */ 383*44bedb31SLionel Sambuc 384*44bedb31SLionel SambucLenMaximum: 385*44bedb31SLionel Sambuc mov edx, [esp+deflatestate] 386*44bedb31SLionel Sambuc mov DWORD PTR[esp+bestlen], MAX_MATCH 387*44bedb31SLionel Sambuc mov [edx].ds_match_start, ecx 388*44bedb31SLionel Sambuc 389*44bedb31SLionel Sambuc;/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ 390*44bedb31SLionel Sambuc;/* return s->lookahead; */ 391*44bedb31SLionel Sambuc 392*44bedb31SLionel SambucLeaveNow: 393*44bedb31SLionel Sambuc mov edx, [esp+deflatestate] 394*44bedb31SLionel Sambuc mov ebx, [esp+bestlen] 395*44bedb31SLionel Sambuc mov eax, [edx].ds_lookahead 396*44bedb31SLionel Sambuc cmp ebx, eax 397*44bedb31SLionel Sambuc jg SHORT LookaheadRet 398*44bedb31SLionel Sambuc mov eax, ebx 399*44bedb31SLionel SambucLookaheadRet: 400*44bedb31SLionel Sambuc 401*44bedb31SLionel Sambuc; Restore the stack and return from whence we came. 402*44bedb31SLionel Sambuc 403*44bedb31SLionel Sambuc add esp, varsize 404*44bedb31SLionel Sambuc pop ebx 405*44bedb31SLionel Sambuc pop esi 406*44bedb31SLionel Sambuc pop edi 407*44bedb31SLionel Sambuc pop ebp 408*44bedb31SLionel Sambuc ret 409*44bedb31SLionel Sambuc 410*44bedb31SLionel Sambuc_longest_match ENDP 411*44bedb31SLionel Sambuc 412*44bedb31SLionel Sambuc_TEXT ENDS 413*44bedb31SLionel SambucEND 414