xref: /minix3/common/dist/zlib/contrib/masm686/match.asm (revision 44bedb31d842b4b0444105519bcf929a69fe2dc1)
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