summaryrefslogtreecommitdiff
path: root/acorn/match.s
blob: ee68ce665e2da81d616fda9c3808be60a8f21f7f (plain)
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
;===========================================================================
; 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 for ARM by Sergio Monesi.

r0 RN 0
r1 RN 1
r2 RN 2
r3 RN 3
r4 RN 4
r5 RN 5
r6 RN 6
r7 RN 7
r8 RN 8
r9 RN 9
sl RN 10
fp RN 11
ip RN 12
sp RN 13
lr RN 14
pc RN 15

MAX_DIST   EQU  32506
WMASK      EQU  32767
MAX_MATCH  EQU  258

                AREA    |C$$code|, CODE, READONLY


; r1 = chain_lenght
; r2 = scan
; r3 = match
; r4 = len (tmp)
; r5 = best_len
; r6 = limit
; r7 = strend
; r8 = scan_end1
; r9 = scan_end
; lr = window
; fp = prev

|__max_chain_length|
        IMPORT  max_chain_length
        DCD     max_chain_length
|__window|
        IMPORT  window
        DCD     window
|__prev|
        IMPORT  prev
        DCD     prev
|__prev_length|
        IMPORT  prev_length
        DCD     prev_length
|__strstart|
        IMPORT  strstart
        DCD     strstart
|__good_match|
        IMPORT  good_match
        DCD     good_match
|__nice_match|
        IMPORT  nice_match
        DCD     nice_match
|__match_start|
        IMPORT  match_start
        DCD     match_start

        DCB     "longest_match"
        DCB     &00,&00,&00
        DCD     &ff000010

        EXPORT  longest_match
longest_match
        STMFD   sp!, {r4-r9,fp,lr}

        LDR     fp, [pc, #|__prev|-.-8]

        LDR     r1, [pc, #|__max_chain_length|-.-8]
        LDR     r1, [r1]
        LDR     lr, [pc, #|__window|-.-8]

        LDR     ip, [pc, #|__strstart|-.-8]
        LDR     ip, [ip]
        ADD     r2, lr, ip
        LDR     r5, [pc, #|__prev_length|-.-8]
        LDR     r5, [r5]
        SUBS    ip, ip, #MAX_DIST-250       ; if r6 > MAX_DIST
        SUBCSS  r6, ip, #250                ; r6 = r6 - MAXDIST
        MOVLS   r6, #0                      ; else r6 = 0

        ADD     r7, r2, #MAX_MATCH-256
        ADD     r7, r7, #256                ; r7 = r2 + MAX_MATCH (=258);

        SUB     ip, r5, #1
        LDRB    r8, [r2, ip]
        LDRB    r9, [r2, r5]

        LDR     ip, [pc, #|__good_match|-.-8]
        LDR     ip, [ip]
        CMP     r5, ip
        MOVCS   r1, r1, LSR #2

cycle
        ADD     r3, lr, r0

        LDRB    ip, [r3, r5]
        CMP     ip, r9
        BNE     cycle_end

        SUB     ip, r5, #1
        LDRB    ip, [r3, ip]
        CMP     ip, r8
        BNE     cycle_end

        LDRB    ip, [r2]
        LDRB    r4, [r3]
        CMP     ip, r4
        BNE     cycle_end

        LDRB    ip, [r3, #1]
        LDRB    r4, [r2, #1]
        CMP     ip, r4
        BNE     cycle_end

        ADD     r2, r2, #2
        ADD     r3, r3, #2

inn_cycle
        LDRB    ip, [r2, #1]!
        LDRB    r4, [r3, #1]!
        CMP     ip, r4
        BNE     exit_inn_cycle

        LDRB    ip, [r2, #1]!
        LDRB    r4, [r3, #1]!
        CMP     ip, r4
        BNE     exit_inn_cycle

        LDRB    ip, [r2, #1]!
        LDRB    r4, [r3, #1]!
        CMP     ip, r4
        BNE     exit_inn_cycle

        LDRB    ip, [r2, #1]!
        LDRB    r4, [r3, #1]!
        CMP     ip, r4
        BNE     exit_inn_cycle

        LDRB    ip, [r2, #1]!
        LDRB    r4, [r3, #1]!
        CMP     ip, r4
        BNE     exit_inn_cycle

        LDRB    ip, [r2, #1]!
        LDRB    r4, [r3, #1]!
        CMP     ip, r4
        BNE     exit_inn_cycle

        LDRB    ip, [r2, #1]!
        LDRB    r4, [r3, #1]!
        CMP     ip, r4
        BNE     exit_inn_cycle

        LDRB    ip, [r2, #1]!
        LDRB    r4, [r3, #1]!
        CMP     ip, r4
        BNE     exit_inn_cycle

        CMP     r2, r7
        BCC     inn_cycle

exit_inn_cycle
        SUB     r4, r2, r7               ; len = MAX_MATCH - (int)(strend - scan);
        ADD     r4, r4, #MAX_MATCH-256
        ADD     r4, r4, #256

        SUB     r2, r2, r4               ; scan = strend - MAX_MATCH

        CMP     r4, r5                   ; if (len > best_len) {
        BLE     cycle_end

        LDR     ip, [pc, #|__match_start|-.-8]  ; match_start = cur_match;
        STR     r0, [ip]
        MOV     r5, r4                          ; best_len = len;

        LDR     ip, [pc, #|__nice_match|-.-8]   ; if (len >= nice_match)
        LDR     ip, [ip]
        CMP     r4, ip
        BGE     exit_match                      ;   break;

        SUB     ip, r5, #1                      ; scan_end1  = scan[best_len-1];
        LDRB    r8, [r2, ip]
        LDRB    r9, [r2, r5]                    ; scan_end   = scan[best_len];

cycle_end
        MOV     ip, r0, LSL #17          ; cur_match & WMASK
        MOV     ip, ip, LSR #17

        LDR     r0, [fp, ip, ASL #1]     ; cur_match = prev[cur_match & WMASK]
        MOV     r0, r0, ASL #16
        MOV     r0, r0, LSR #16

        CMP     r0, r6                  ; cur_match > limit
        BLS     exit_match
        SUBS    r1, r1, #1              ; --chain_length
        BNE     cycle                   ; chain_length != 0

exit_match
        MOV     r0, r5

        LDMFD   sp!, {r4-r9,fp,pc}^

        END