123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- *===========================================================================
- * 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 -- optional optimized asm version of longest match in deflate.c
- * Written by Jean-loup Gailly
- *
- * Adapted for X68000 by NIIMI Satoshi <a01309@cfi.waseda.ac.jp>
- * 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 machines to crash.
- * For maximum speed, UNALIGNED_OK can be defined.
- * The program will then only run on 68020-based machines, though.
- 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
- WSIZE equ 32768
- 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
- .xdef _match_init
- .xdef _longest_match
- .text
- .even
- _match_init:
- rts
- _longest_match:
- move.l 4(sp),Cur_Match
- .ifdef UNALIGNED_OK
- movem.l d2-d6/a2-a4,-(sp)
- .else
- movem.l d2-d7/a2-a4,-(sp)
- .endif
- 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
- .ifdef UNALIGNED_OK
- move.w -MIN_MATCH(Scan_Ini),Scan_Start
- move.w -MIN_MATCH-1(Scan_Ini,Best_Len.w),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.w),Scan_End
- lsl.w #8,Scan_End
- move.b -MIN_MATCH(Scan_Ini,Best_Len.w),Scan_End
- .endif
- bra.b do_scan
- long_loop:
- .ifdef UNALIGNED_OK
- move.w -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End
- .else
- move.b -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End
- lsl.w #8,Scan_End
- move.b -MIN_MATCH(Scan_Ini,Best_Len.w),Scan_End
- .endif
- 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
- .ifdef UNALIGNED_OK
- cmp.w -MIN_MATCH-1(Match,Best_Len.w),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.w),Scan_Test
- lsl.w #8,Scan_Test
- move.b -MIN_MATCH(Match,Best_Len.w),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
- .endif
- 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
- .ifdef UNALIGNED_OK
- movem.l (sp)+,d2-d6/a2-a4
- .else
- movem.l (sp)+,d2-d7/a2-a4
- .endif
- rts
- end
|