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
|