match.a 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. ;===========================================================================
  2. ; Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
  3. ;
  4. ; See the accompanying file LICENSE, version 1999-Oct-05 or later
  5. ; (the contents of which are also included in zip.h) for terms of use.
  6. ; If, for some reason, both of these files are missing, the Info-ZIP license
  7. ; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
  8. ;===========================================================================
  9. ; match.a -- optional optimized asm version of longest match in deflate.c
  10. ; Written by Jean-loup Gailly
  11. ; Adapted for the Amiga by Carsten Steger <stegerc@informatik.tu-muenchen.de>
  12. ; using the code in match.S.
  13. ; The major change in this code consists of removing all unaligned
  14. ; word accesses, because they cause 68000-based Amigas to crash.
  15. ; For maximum speed, UNALIGNED_OK can be defined in Makefile.sasc.
  16. ; The program will then only run on 68020-based Amigas, though.
  17. ; If you have reduced WSIZE in zip.h, then make sure this is
  18. ; assembled with an equivalent -dWSIZE=<whatever>.
  19. ;
  20. ; This code will run with registerized parameters too, unless SAS
  21. ; changes parameter passing conventions between new releases of SAS/C.
  22. Cur_Match reg d0 ; Must be in d0!
  23. Best_Len reg d1
  24. Loop_Counter reg d2
  25. Scan_Start reg d3
  26. Scan_End reg d4
  27. Limit reg d5
  28. Chain_Length reg d6
  29. Scan_Test reg d7
  30. Scan reg a0
  31. Match reg a1
  32. Prev_Address reg a2
  33. Scan_Ini reg a3
  34. Match_Ini reg a4
  35. MAX_MATCH equ 258
  36. MIN_MATCH equ 3
  37. ifnd WSIZE
  38. WSIZE equ 32768
  39. endc
  40. MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1
  41. xref _max_chain_length
  42. xref _prev_length
  43. xref _prev
  44. xref _window
  45. xref _strstart
  46. xref _good_match
  47. xref _match_start
  48. xref _nice_match
  49. section match,code
  50. xdef _match_init
  51. xdef @match_init
  52. xdef _longest_match
  53. xdef @longest_match
  54. _match_init:
  55. @match_init:
  56. rts
  57. _longest_match:
  58. move.l 4(sp),Cur_Match
  59. @longest_match:
  60. ifd UNALIGNED_OK
  61. movem.l d2-d6/a2-a4,-(sp)
  62. else
  63. movem.l d2-d7/a2-a4,-(sp)
  64. endc
  65. move.l _max_chain_length,Chain_Length
  66. move.l _prev_length,Best_Len
  67. lea _prev,Prev_Address
  68. lea _window+MIN_MATCH,Match_Ini
  69. move.l _strstart,Limit
  70. move.l Match_Ini,Scan_Ini
  71. add.l Limit,Scan_Ini
  72. subi.w #MAX_DIST,Limit
  73. bhi.b limit_ok
  74. moveq #0,Limit
  75. limit_ok:
  76. cmp.l _good_match,Best_Len
  77. bcs.b length_ok
  78. lsr.l #2,Chain_Length
  79. length_ok:
  80. subq.l #1,Chain_Length
  81. ifd UNALIGNED_OK
  82. move.w -MIN_MATCH(Scan_Ini),Scan_Start
  83. move.w -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
  84. else
  85. move.b -MIN_MATCH(Scan_Ini),Scan_Start
  86. lsl.w #8,Scan_Start
  87. move.b -MIN_MATCH+1(Scan_Ini),Scan_Start
  88. move.b -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
  89. lsl.w #8,Scan_End
  90. move.b -MIN_MATCH(Scan_Ini,Best_Len.L),Scan_End
  91. endc
  92. bra.b do_scan
  93. long_loop:
  94. ifd UNALIGNED_OK
  95. move.w -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
  96. else
  97. move.b -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
  98. lsl.w #8,Scan_End
  99. move.b -MIN_MATCH(Scan_Ini,Best_Len.L),Scan_End
  100. endc
  101. short_loop:
  102. lsl.w #1,Cur_Match
  103. move.w 0(Prev_Address,Cur_Match.L),Cur_Match
  104. cmp.w Limit,Cur_Match
  105. dbls Chain_Length,do_scan
  106. bra.b return
  107. do_scan:
  108. move.l Match_Ini,Match
  109. add.l Cur_Match,Match
  110. ifd UNALIGNED_OK
  111. cmp.w -MIN_MATCH-1(Match,Best_Len.L),Scan_End
  112. bne.b short_loop
  113. cmp.w -MIN_MATCH(Match),Scan_Start
  114. bne.b short_loop
  115. else
  116. move.b -MIN_MATCH-1(Match,Best_Len.L),Scan_Test
  117. lsl.w #8,Scan_Test
  118. move.b -MIN_MATCH(Match,Best_Len.L),Scan_Test
  119. cmp.w Scan_Test,Scan_End
  120. bne.b short_loop
  121. move.b -MIN_MATCH(Match),Scan_Test
  122. lsl.w #8,Scan_Test
  123. move.b -MIN_MATCH+1(Match),Scan_Test
  124. cmp.w Scan_Test,Scan_Start
  125. bne.b short_loop
  126. endc
  127. move.w #(MAX_MATCH-MIN_MATCH),Loop_Counter
  128. move.l Scan_Ini,Scan
  129. scan_loop:
  130. cmpm.b (Match)+,(Scan)+
  131. dbne Loop_Counter,scan_loop
  132. sub.l Scan_Ini,Scan
  133. addq.l #(MIN_MATCH-1),Scan
  134. cmp.l Best_Len,Scan
  135. bls.b short_loop
  136. move.l Scan,Best_Len
  137. move.l Cur_Match,_match_start
  138. cmp.l _nice_match,Best_Len
  139. bcs.b long_loop
  140. return:
  141. move.l Best_Len,d0
  142. ifd UNALIGNED_OK
  143. movem.l (sp)+,d2-d6/a2-a4
  144. else
  145. movem.l (sp)+,d2-d7/a2-a4
  146. endc
  147. rts
  148. end