*=========================================================================== * 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 * Adapted for the Amiga by Carsten Steger * 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