c14a20be8542df45461c4074671b92c729e40430
[debian/gzip] / amiga / match.a
1 ; match.a -- optional optimized asm version of longest match in deflate.c
2 ; Copyright (C) 1992-1993 Jean-loup Gailly
3 ; This is free software; you can redistribute it and/or modify it under the
4 ; terms of the GNU General Public License, see the file COPYING.
5
6 ; Adapted for the Amiga by Carsten Steger <stegerc@informatik.tu-muenchen.de>
7 ; using the code in match.S.
8 ; The major change in this code consists of removing all unaligned
9 ; word accesses, because they cause 68000-based Amigas to crash.
10 ; For maximum speed, UNALIGNED_OK can be defined in Makefile.sasc.
11 ; The program will then only run on 68020-based Amigas, though.
12 ;
13 ; This code will run with registerized parameters too, unless SAS
14 ; changes parameter passing conventions between new releases of SAS/C.
15
16
17 Cur_Match       reg     d0      ; Must be in d0!
18 Best_Len        reg     d1
19 Loop_Counter    reg     d2
20 Scan_Start      reg     d3
21 Scan_End        reg     d4
22 Limit           reg     d5
23 Chain_Length    reg     d6
24 Scan_Test       reg     d7
25 Scan            reg     a0
26 Match           reg     a1
27 Prev_Address    reg     a2
28 Scan_Ini        reg     a3
29 Match_Ini       reg     a4
30
31 MAX_MATCH       equ     258
32 MIN_MATCH       equ     3
33 WSIZE           equ     32768
34 MAX_DIST        equ     WSIZE-MAX_MATCH-MIN_MATCH-1
35
36
37         xref    _max_chain_length
38         xref    _prev_length
39         xref    _prev
40         xref    _window
41         xref    _strstart
42         xref    _good_match
43         xref    _match_start
44         xref    _nice_match
45
46
47         section match,code
48
49         xdef    _match_init
50         xdef    @match_init
51         xdef    _longest_match
52         xdef    @longest_match
53
54
55 _match_init:
56 @match_init:
57         rts
58
59
60 _longest_match:
61         move.l  4(sp),Cur_Match
62 @longest_match:
63         ifd     UNALIGNED_OK
64         movem.l d2-d6/a2-a4,-(sp)
65         else
66         movem.l d2-d7/a2-a4,-(sp)
67         endc
68         move.l  _max_chain_length,Chain_Length
69         move.l  _prev_length,Best_Len
70         lea     _prev,Prev_Address
71         lea     _window+MIN_MATCH,Match_Ini
72         move.l  _strstart,Limit
73         move.l  Match_Ini,Scan_Ini
74         add.l   Limit,Scan_Ini
75         subi.w  #MAX_DIST,Limit
76         bhi.b   limit_ok
77         moveq   #0,Limit
78 limit_ok:
79         cmp.l   _good_match,Best_Len
80         bcs.b   length_ok
81         lsr.l   #2,Chain_Length
82 length_ok:
83         subq.l  #1,Chain_Length
84
85         ifd     UNALIGNED_OK
86
87         move.w  -MIN_MATCH(Scan_Ini),Scan_Start
88         move.w  -MIN_MATCH-1(Scan_Ini,Best_Len),Scan_End
89
90         else
91
92         move.b  -MIN_MATCH(Scan_Ini),Scan_Start
93         lsl.w   #8,Scan_Start
94         move.b  -MIN_MATCH+1(Scan_Ini),Scan_Start
95         move.b  -MIN_MATCH-1(Scan_Ini,Best_Len),Scan_End
96         lsl.w   #8,Scan_End
97         move.b  -MIN_MATCH(Scan_Ini,Best_Len),Scan_End
98
99         endc
100
101         bra.b   do_scan
102
103 long_loop:
104
105         ifd     UNALIGNED_OK
106
107         move.w  -MIN_MATCH-1(Scan_Ini,Best_Len),Scan_End
108
109         else
110
111         move.b  -MIN_MATCH-1(Scan_Ini,Best_Len),Scan_End
112         lsl.w   #8,Scan_End
113         move.b  -MIN_MATCH(Scan_Ini,Best_Len),Scan_End
114
115         endc
116
117 short_loop:
118         lsl.w   #1,Cur_Match
119         move.w  0(Prev_Address,Cur_Match),Cur_Match
120         cmp.w   Limit,Cur_Match
121         dbls    Chain_Length,do_scan
122         bra.b   return
123
124 do_scan:
125         move.l  Match_Ini,Match
126         add.l   Cur_Match,Match
127
128         ifd     UNALIGNED_OK
129
130         cmp.w   -MIN_MATCH-1(Match,Best_Len),Scan_End
131         bne.b   short_loop
132         cmp.w   -MIN_MATCH(Match),Scan_Start
133         bne.b   short_loop
134
135         else
136
137         move.b  -MIN_MATCH-1(Match,Best_Len),Scan_Test
138         lsl.w   #8,Scan_Test
139         move.b  -MIN_MATCH(Match,Best_Len),Scan_Test
140         cmp.w   Scan_Test,Scan_End
141         bne.b   short_loop
142         move.b  -MIN_MATCH(Match),Scan_Test
143         lsl.w   #8,Scan_Test
144         move.b  -MIN_MATCH+1(Match),Scan_Test
145         cmp.w   Scan_Test,Scan_Start
146         bne.b   short_loop
147
148         endc
149
150         move.w  #(MAX_MATCH-MIN_MATCH),Loop_Counter
151         move.l  Scan_Ini,Scan
152 scan_loop:
153         cmpm.b  (Match)+,(Scan)+
154         dbne    Loop_Counter,scan_loop
155
156         sub.l   Scan_Ini,Scan
157         addq.l  #(MIN_MATCH-1),Scan
158         cmp.l   Best_Len,Scan
159         bls.b   short_loop
160         move.l  Scan,Best_Len
161         move.l  Cur_Match,_match_start
162         cmp.l   _nice_match,Best_Len
163         bcs.b   long_loop
164 return:
165         move.l  Best_Len,d0
166         ifd     UNALIGNED_OK
167         movem.l (sp)+,d2-d6/a2-a4
168         else
169         movem.l (sp)+,d2-d7/a2-a4
170         endc
171         rts
172
173         end