summaryrefslogtreecommitdiff
path: root/win32/lm32_lcc.asm
blob: 0450fe379a9c14a8a095525d6965a76772b5e481 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
;===========================================================================
; Copyright (c) 1990-1999 Info-ZIP.  All rights reserved.
;
; See the accompanying file LICENSE, version 1999-Oct-05 or later
; (the contents of which are also included in zip.h) for terms of use.
; If, for some reason, both of these files are missing, the Info-ZIP license
; also may be found at:  ftp://ftp.cdrom.com/pub/infozip/license.html
;===========================================================================
; match32.asm by Jean-loup Gailly.

; match32.asm, optimized version of longest_match() in deflate.c
; To be used only with 32 bit flat model. To simplify the code, the option
; -DDYN_ALLOC is not supported.
; This file is only optional. If you don't have an assembler, use the
; C version (add -DNO_ASM to CFLAGS in makefile and remove match.o
; from OBJI). If you have reduced WSIZE in zip.h, then make sure this is
; assembled with an equivalent -DWSIZE=<whatever>.
;
; Win32 (Windows NT) version - 1994/04/13 by Steve Salisbury
; * works with Microsoft MASM 6.1X and Microsoft Visual C++ / 32-bit edition
;
; The code in this file has been copied verbatim from match32.{asm|S};
; only the assembler syntax and metacommands have been adapted to
; the habits of the free LCC-Win32 C compiler package.
; IMPORTANT NOTE to the Info-ZIP editors:
; The TAB characters in this source file are required by the parser of
; the LCC-Win32 assembler program and MUST NOT be removed!!
;
;==============================================================================
;
; Do NOT assemble this source if external crc32 routine from zlib gets used.
;


;/* This version is for 386 Unix or OS/2 in 32 bit mode.
; * Warning: it uses the AT&T syntax: mov source,dest
; * This file is only optional. If you want to force the C version,
; * add -DNO_ASM to CFLAGS in Makefile and set OBJA to an empty string.
; * If you have reduced WSIZE in (g)zip.h, then make sure this is
; * assembled with an equivalent -DWSIZE=<whatever>.
; * This version assumes static allocation of the arrays (-DDYN_ALLOC not used).
; */

        .text
        .file	"match.S"


        .text
        .type	_match_init,function

_match_init:
        ret
_$98:
        .size	_match_init,_$98-_match_init
        .globl	_match_init

;/*-----------------------------------------------------------------------
; * Set match_start to the longest match starting at the given string and
; * return its length. Matches shorter or equal to prev_length are discarded,
; * in which case the result is equal to prev_length and match_start is
; * garbage.
; * IN assertions: cur_match is the head of the hash chain for the current
; *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
; */

        .align	4
        .type	_longest_match,function

_longest_match: ;/* int longest_match(cur_match) */

;       cur_match     equ 20(%esp)
;     /* return address */               /* esp+16 */
        push    %ebp
        push    %edi
;/* esp+8  */
        push    %esi
;/* esp+4  */
        push    %ebx
;/* esp    */

;/*
; *      match        equ esi
; *      scan         equ edi
; *      chain_length equ ebp
; *      best_len     equ ebx
; *      limit        equ edx
; */
        mov     20(%esp),%esi
        mov     _strstart,%edx
        mov     _max_chain_length,%ebp
        mov     %edx,%edi
        sub     $(32768-262),%edx
        cld
        jae     limit_ok
        sub     %edx,%edx
limit_ok:
        add     $2+_window,%edi
        mov     _prev_length,%ebx
        movw    -2(%edi),%cx
        movw    -3(%ebx,%edi),%ax
        cmp     _good_match,%ebx
        jb      do_scan
        shr     $2,%ebp
        jmp     do_scan

        .align	4
long_loop:
;/* at this point, edi == scan+2, esi == cur_match */
        movw    -3(%ebx,%edi),%ax
        movw     -2(%edi),%cx
short_loop:
;/*
; * at this point, di == scan+2, si == cur_match,
; * ax = scan[best_len-1..best_len] and cx = scan[0..1]
; */
        and     $(32768-1), %esi
        dec     %ebp
        movw    _prev(,%esi,2),%si
        jz      the_end
        cmp     %edx,%esi
        jbe     the_end
do_scan:
        cmpw    _window-1(%ebx,%esi),%ax
        jne     short_loop
        cmpw    _window(%esi),%cx
        jne     short_loop

        add     $2+_window,%esi
        mov     $((258>>1)-1),%ecx
        mov     %edi,%eax
        repe;   cmpsw
;/* loop until mismatch */
        je      maxmatch
;/* match of length MAX_MATCH? */
mismatch:
        movb    -2(%edi),%cl
        xchg    %edi,%eax
        subb    -2(%esi),%cl
        sub     %edi,%eax
        sub     $2+_window,%esi
        sub     %eax,%esi
        subb    $1,%cl
        adc     $0,%eax
        cmp     %ebx,%eax
        jle     long_loop
        mov     %esi,_match_start
        mov     %eax,%ebx
        cmp     _nice_match,%eax
; /* len >= nice_match ? */
        jl      long_loop
the_end:
        mov     %ebx,%eax
        pop     %ebx
        pop     %esi
        pop     %edi
        pop     %ebp
        ret
        .align	4
maxmatch:
        cmpsb
        jmp     mismatch
_$99:

        .size	_longest_match,_$99-_longest_match
        .globl	_longest_match

        .extern	_nice_match
        .extern	_good_match
        .extern	_max_chain_length
        .extern	_match_start
        .extern	_strstart
        .extern	_prev_length
        .extern	_prev
        .extern	_window