1*===========================================================================
2* Copyright (c) 1990-1999 Info-ZIP.  All rights reserved.
3*
4* See the accompanying file LICENSE, version 1999-Oct-05 or later
5* (the contents of which are also included in zip.h) for terms of use.
6* If, for some reason, both of these files are missing, the Info-ZIP license
7* also may be found at:  ftp://ftp.cdrom.com/pub/infozip/license.html
8*===========================================================================
9*
10* match.s -- optional optimized asm version of longest match in deflate.c
11* Written by Jean-loup Gailly
12*
13* Adapted for X68000 by NIIMI Satoshi <a01309@cfi.waseda.ac.jp>
14* Adapted for the Amiga by Carsten Steger <stegerc@informatik.tu-muenchen.de>
15* using the code in match.S.
16* The major change in this code consists of removing all unaligned
17* word accesses, because they cause 68000-based machines to crash.
18* For maximum speed, UNALIGNED_OK can be defined.
19* The program will then only run on 68020-based machines, though.
20
21
22Cur_Match       reg     d0      ; Must be in d0!
23Best_Len        reg     d1
24Loop_Counter    reg     d2
25Scan_Start      reg     d3
26Scan_End        reg     d4
27Limit           reg     d5
28Chain_Length    reg     d6
29Scan_Test       reg     d7
30Scan            reg     a0
31Match           reg     a1
32Prev_Address    reg     a2
33Scan_Ini        reg     a3
34Match_Ini       reg     a4
35
36MAX_MATCH       equ     258
37MIN_MATCH       equ     3
38WSIZE           equ     32768
39MAX_DIST        equ     WSIZE-MAX_MATCH-MIN_MATCH-1
40
41
42        .xref   _max_chain_length
43        .xref   _prev_length
44        .xref   _prev
45        .xref   _window
46        .xref   _strstart
47        .xref   _good_match
48        .xref   _match_start
49        .xref   _nice_match
50
51
52        .xdef   _match_init
53        .xdef   _longest_match
54
55        .text
56        .even
57
58
59_match_init:
60        rts
61
62
63_longest_match:
64        move.l  4(sp),Cur_Match
65.ifdef  UNALIGNED_OK
66        movem.l d2-d6/a2-a4,-(sp)
67.else
68        movem.l d2-d7/a2-a4,-(sp)
69.endif
70        move.l  _max_chain_length,Chain_Length
71        move.l  _prev_length,Best_Len
72        lea     _prev,Prev_Address
73        lea     _window+MIN_MATCH,Match_Ini
74        move.l  _strstart,Limit
75        move.l  Match_Ini,Scan_Ini
76        add.l   Limit,Scan_Ini
77        subi.w  #MAX_DIST,Limit
78        bhi.b   limit_ok
79        moveq   #0,Limit
80limit_ok:
81        cmp.l   _good_match,Best_Len
82        bcs.b   length_ok
83        lsr.l   #2,Chain_Length
84length_ok:
85        subq.l  #1,Chain_Length
86
87.ifdef  UNALIGNED_OK
88        move.w  -MIN_MATCH(Scan_Ini),Scan_Start
89        move.w  -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End
90.else
91        move.b  -MIN_MATCH(Scan_Ini),Scan_Start
92        lsl.w   #8,Scan_Start
93        move.b  -MIN_MATCH+1(Scan_Ini),Scan_Start
94        move.b  -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End
95        lsl.w   #8,Scan_End
96        move.b  -MIN_MATCH(Scan_Ini,Best_Len.w),Scan_End
97.endif
98
99        bra.b   do_scan
100
101long_loop:
102
103.ifdef  UNALIGNED_OK
104        move.w  -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End
105.else
106        move.b  -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End
107        lsl.w   #8,Scan_End
108        move.b  -MIN_MATCH(Scan_Ini,Best_Len.w),Scan_End
109.endif
110
111short_loop:
112        lsl.w   #1,Cur_Match
113        move.w  0(Prev_Address,Cur_Match.l),Cur_Match
114        cmp.w   Limit,Cur_Match
115        dbls    Chain_Length,do_scan
116        bra.b   return
117
118do_scan:
119        move.l  Match_Ini,Match
120        add.l   Cur_Match,Match
121
122.ifdef  UNALIGNED_OK
123        cmp.w   -MIN_MATCH-1(Match,Best_Len.w),Scan_End
124        bne.b   short_loop
125        cmp.w   -MIN_MATCH(Match),Scan_Start
126        bne.b   short_loop
127.else
128        move.b  -MIN_MATCH-1(Match,Best_Len.w),Scan_Test
129        lsl.w   #8,Scan_Test
130        move.b  -MIN_MATCH(Match,Best_Len.w),Scan_Test
131        cmp.w   Scan_Test,Scan_End
132        bne.b   short_loop
133        move.b  -MIN_MATCH(Match),Scan_Test
134        lsl.w   #8,Scan_Test
135        move.b  -MIN_MATCH+1(Match),Scan_Test
136        cmp.w   Scan_Test,Scan_Start
137        bne.b   short_loop
138.endif
139
140        move.w  #(MAX_MATCH-MIN_MATCH),Loop_Counter
141        move.l  Scan_Ini,Scan
142scan_loop:
143        cmpm.b  (Match)+,(Scan)+
144        dbne    Loop_Counter,scan_loop
145
146        sub.l   Scan_Ini,Scan
147        addq.l  #(MIN_MATCH-1),Scan
148        cmp.l   Best_Len,Scan
149        bls.b   short_loop
150        move.l  Scan,Best_Len
151        move.l  Cur_Match,_match_start
152        cmp.l   _nice_match,Best_Len
153        bcs.b   long_loop
154return:
155        move.l  Best_Len,d0
156.ifdef  UNALIGNED_OK
157        movem.l (sp)+,d2-d6/a2-a4
158.else
159        movem.l (sp)+,d2-d7/a2-a4
160.endif
161        rts
162
163        end
164