; match.a -- optional optimized asm version of longest match in deflate.c ; Copyright (C) 1992-1993 Jean-loup Gailly ; This is free software; you can redistribute it and/or modify it under the ; terms of the GNU General Public License, see the file COPYING. ; $Id: match.a,v 1.1 1993/03/11 16:05:57 jloup Exp $ ; ; 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 Amigas to crash. ; For maximum speed, UNALIGNED_OK can be defined in Makefile.sasc. ; The program will then only run on 68020-based Amigas, though. ; ; This code will run with registerized parameters too, unless SAS ; changes parameter passing conventions between new releases of SAS/C. 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 section match,code xdef _match_init xdef @match_init xdef _longest_match xdef @longest_match _match_init: @match_init: rts _longest_match: move.l 4(sp),Cur_Match @longest_match: ifd UNALIGNED_OK movem.l d2-d6/a2-a4,-(sp) else movem.l d2-d7/a2-a4,-(sp) endc 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 ifd UNALIGNED_OK move.w -MIN_MATCH(Scan_Ini),Scan_Start move.w -MIN_MATCH-1(Scan_Ini,Best_Len),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),Scan_End lsl.w #8,Scan_End move.b -MIN_MATCH(Scan_Ini,Best_Len),Scan_End endc bra.b do_scan long_loop: ifd UNALIGNED_OK move.w -MIN_MATCH-1(Scan_Ini,Best_Len),Scan_End else move.b -MIN_MATCH-1(Scan_Ini,Best_Len),Scan_End lsl.w #8,Scan_End move.b -MIN_MATCH(Scan_Ini,Best_Len),Scan_End endc short_loop: lsl.w #1,Cur_Match move.w 0(Prev_Address,Cur_Match),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 ifd UNALIGNED_OK cmp.w -MIN_MATCH-1(Match,Best_Len),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),Scan_Test lsl.w #8,Scan_Test move.b -MIN_MATCH(Match,Best_Len),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 endc 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 ifd UNALIGNED_OK movem.l (sp)+,d2-d6/a2-a4 else movem.l (sp)+,d2-d7/a2-a4 endc rts end