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
175
176
177
178
179
180
181
182
|
;===========================================================================
; 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
;===========================================================================
; match.a -- optional optimized asm version of longest match in deflate.c
; Written by Jean-loup Gailly
; Adapted for the Amiga by Carsten Steger <stegerc@informatik.tu-muenchen.de>
; using the code in match.S.
; The major change in this code consists of removing all unaligned
; word accesses, because they cause 68000-based Amigas to crash.
; For maximum speed, UNALIGNED_OK can be defined in Makefile.sasc.
; The program will then only run on 68020-based Amigas, though.
; If you have reduced WSIZE in zip.h, then make sure this is
; assembled with an equivalent -dWSIZE=<whatever>.
;
; This code will run with registerized parameters too, unless SAS
; changes parameter passing conventions between new releases of SAS/C.
Cur_Match reg d0 ; Must be in d0!
Best_Len reg d1
Loop_Counter reg d2
Scan_Start reg d3
Scan_End reg d4
Limit reg d5
Chain_Length reg d6
Scan_Test reg d7
Scan reg a0
Match reg a1
Prev_Address reg a2
Scan_Ini reg a3
Match_Ini reg a4
MAX_MATCH equ 258
MIN_MATCH equ 3
ifnd WSIZE
WSIZE equ 32768
endc
MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1
xref _max_chain_length
xref _prev_length
xref _prev
xref _window
xref _strstart
xref _good_match
xref _match_start
xref _nice_match
section match,code
xdef _match_init
xdef @match_init
xdef _longest_match
xdef @longest_match
_match_init:
@match_init:
rts
_longest_match:
move.l 4(sp),Cur_Match
@longest_match:
ifd UNALIGNED_OK
movem.l d2-d6/a2-a4,-(sp)
else
movem.l d2-d7/a2-a4,-(sp)
endc
move.l _max_chain_length,Chain_Length
move.l _prev_length,Best_Len
lea _prev,Prev_Address
lea _window+MIN_MATCH,Match_Ini
move.l _strstart,Limit
move.l Match_Ini,Scan_Ini
add.l Limit,Scan_Ini
subi.w #MAX_DIST,Limit
bhi.b limit_ok
moveq #0,Limit
limit_ok:
cmp.l _good_match,Best_Len
bcs.b length_ok
lsr.l #2,Chain_Length
length_ok:
subq.l #1,Chain_Length
ifd UNALIGNED_OK
move.w -MIN_MATCH(Scan_Ini),Scan_Start
move.w -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
else
move.b -MIN_MATCH(Scan_Ini),Scan_Start
lsl.w #8,Scan_Start
move.b -MIN_MATCH+1(Scan_Ini),Scan_Start
move.b -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
lsl.w #8,Scan_End
move.b -MIN_MATCH(Scan_Ini,Best_Len.L),Scan_End
endc
bra.b do_scan
long_loop:
ifd UNALIGNED_OK
move.w -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
else
move.b -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
lsl.w #8,Scan_End
move.b -MIN_MATCH(Scan_Ini,Best_Len.L),Scan_End
endc
short_loop:
lsl.w #1,Cur_Match
move.w 0(Prev_Address,Cur_Match.L),Cur_Match
cmp.w Limit,Cur_Match
dbls Chain_Length,do_scan
bra.b return
do_scan:
move.l Match_Ini,Match
add.l Cur_Match,Match
ifd UNALIGNED_OK
cmp.w -MIN_MATCH-1(Match,Best_Len.L),Scan_End
bne.b short_loop
cmp.w -MIN_MATCH(Match),Scan_Start
bne.b short_loop
else
move.b -MIN_MATCH-1(Match,Best_Len.L),Scan_Test
lsl.w #8,Scan_Test
move.b -MIN_MATCH(Match,Best_Len.L),Scan_Test
cmp.w Scan_Test,Scan_End
bne.b short_loop
move.b -MIN_MATCH(Match),Scan_Test
lsl.w #8,Scan_Test
move.b -MIN_MATCH+1(Match),Scan_Test
cmp.w Scan_Test,Scan_Start
bne.b short_loop
endc
move.w #(MAX_MATCH-MIN_MATCH),Loop_Counter
move.l Scan_Ini,Scan
scan_loop:
cmpm.b (Match)+,(Scan)+
dbne Loop_Counter,scan_loop
sub.l Scan_Ini,Scan
addq.l #(MIN_MATCH-1),Scan
cmp.l Best_Len,Scan
bls.b short_loop
move.l Scan,Best_Len
move.l Cur_Match,_match_start
cmp.l _nice_match,Best_Len
bcs.b long_loop
return:
move.l Best_Len,d0
ifd UNALIGNED_OK
movem.l (sp)+,d2-d6/a2-a4
else
movem.l (sp)+,d2-d7/a2-a4
endc
rts
end
|