123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- ;===========================================================================
- ; 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
|