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
|
;===========================================================================
; 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.
;
; This code will run with registerized parameters too, unless SAS
; changes parameter passing conventions between new releases of SAS/C.
;;Cur_Match equr d0 ; Must be in d0!
;;Best_Len equr d1
;;Loop_Counter equr d2
;;Scan_Start equr d3
;;Scan_End equr d4
;;Limit equr d5
;;Chain_Length equr d6
;;Scan_Test equr d7
;;Scan equr a0
;;Match equr a1
;;Prev_Address equr a2
;;Scan_Ini equr a3
;;Match_Ini equr a4
MAX_MATCH equ 258
MIN_MATCH equ 3
WSIZE equ 32768
MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1
.globl _max_chain_length
.globl _prev_length
.globl _prev
.globl _window
.globl _strstart
.globl _good_match
.globl _match_start
.globl _nice_match
.text
.globl _match_init
.globl _longest_match
_match_init:
rts
_longest_match:
move.l 4(sp),d0
movem.l d2-d7/a2-a4,-(sp)
move.l _max_chain_length,d6
move.l _prev_length,d1
lea _prev,a2
lea _window+MIN_MATCH,a4
move.l _strstart,d5
move.l a4,a3
add.l d5,a3
subi.w #MAX_DIST,d5
bhi limit_ok
moveq #0,d5
limit_ok:
cmp.l _good_match,d1
bcs length_ok
lsr.l #2,d6
length_ok:
subq.l #1,d6
move.b -MIN_MATCH(a3),d3
lsl.w #8,d3
move.b -MIN_MATCH+1(a3),d3
move.b -MIN_MATCH-1(a3,d1),d4
lsl.w #8,d4
move.b -MIN_MATCH(a3,d1),d4
bra do_scan
long_loop:
move.b -MIN_MATCH-1(a3,d1),d4
lsl.w #8,d4
move.b -MIN_MATCH(a3,d1),d4
short_loop:
lsl.w #1,d0
move.w 0(a2,d0.l),d0
cmp.w d5,d0
dbls d6,do_scan
bra return
do_scan:
move.l a4,a1
add.l d0,a1
move.b -MIN_MATCH-1(a1,d1),d7
lsl.w #8,d7
move.b -MIN_MATCH(a1,d1),d7
cmp.w d7,d4
bne short_loop
move.b -MIN_MATCH(a1),d7
lsl.w #8,d7
move.b -MIN_MATCH+1(a1),d7
cmp.w d7,d3
bne short_loop
move.w #(MAX_MATCH-MIN_MATCH),d2
move.l a3,a0
scan_loop:
cmpm.b (a1)+,(a0)+
dbne d2,scan_loop
sub.l a3,a0
addq.l #(MIN_MATCH-1),a0
cmp.l d1,a0
bls short_loop
move.l a0,d1
move.l d0,_match_start
cmp.l _nice_match,d1
bcs long_loop
return:
move.l d1,d0
movem.l (sp)+,d2-d7/a2-a4
rts
end
|