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
|
*===========================================================================
* 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.s -- optional optimized asm version of longest match in deflate.c
* Written by Jean-loup Gailly
*
* Adapted for X68000 by NIIMI Satoshi <a01309@cfi.waseda.ac.jp>
* 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 machines to crash.
* For maximum speed, UNALIGNED_OK can be defined.
* The program will then only run on 68020-based machines, though.
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
WSIZE equ 32768
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
.xdef _match_init
.xdef _longest_match
.text
.even
_match_init:
rts
_longest_match:
move.l 4(sp),Cur_Match
.ifdef UNALIGNED_OK
movem.l d2-d6/a2-a4,-(sp)
.else
movem.l d2-d7/a2-a4,-(sp)
.endif
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
.ifdef UNALIGNED_OK
move.w -MIN_MATCH(Scan_Ini),Scan_Start
move.w -MIN_MATCH-1(Scan_Ini,Best_Len.w),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.w),Scan_End
lsl.w #8,Scan_End
move.b -MIN_MATCH(Scan_Ini,Best_Len.w),Scan_End
.endif
bra.b do_scan
long_loop:
.ifdef UNALIGNED_OK
move.w -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End
.else
move.b -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End
lsl.w #8,Scan_End
move.b -MIN_MATCH(Scan_Ini,Best_Len.w),Scan_End
.endif
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
.ifdef UNALIGNED_OK
cmp.w -MIN_MATCH-1(Match,Best_Len.w),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.w),Scan_Test
lsl.w #8,Scan_Test
move.b -MIN_MATCH(Match,Best_Len.w),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
.endif
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
.ifdef UNALIGNED_OK
movem.l (sp)+,d2-d6/a2-a4
.else
movem.l (sp)+,d2-d7/a2-a4
.endif
rts
end
|