match.s 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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. *
  10. * match.s -- optional optimized asm version of longest match in deflate.c
  11. * Written by Jean-loup Gailly
  12. *
  13. * Adapted for X68000 by NIIMI Satoshi <a01309@cfi.waseda.ac.jp>
  14. * Adapted for the Amiga by Carsten Steger <stegerc@informatik.tu-muenchen.de>
  15. * using the code in match.S.
  16. * The major change in this code consists of removing all unaligned
  17. * word accesses, because they cause 68000-based machines to crash.
  18. * For maximum speed, UNALIGNED_OK can be defined.
  19. * The program will then only run on 68020-based machines, though.
  20. Cur_Match reg d0 ; Must be in d0!
  21. Best_Len reg d1
  22. Loop_Counter reg d2
  23. Scan_Start reg d3
  24. Scan_End reg d4
  25. Limit reg d5
  26. Chain_Length reg d6
  27. Scan_Test reg d7
  28. Scan reg a0
  29. Match reg a1
  30. Prev_Address reg a2
  31. Scan_Ini reg a3
  32. Match_Ini reg a4
  33. MAX_MATCH equ 258
  34. MIN_MATCH equ 3
  35. WSIZE equ 32768
  36. MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1
  37. .xref _max_chain_length
  38. .xref _prev_length
  39. .xref _prev
  40. .xref _window
  41. .xref _strstart
  42. .xref _good_match
  43. .xref _match_start
  44. .xref _nice_match
  45. .xdef _match_init
  46. .xdef _longest_match
  47. .text
  48. .even
  49. _match_init:
  50. rts
  51. _longest_match:
  52. move.l 4(sp),Cur_Match
  53. .ifdef UNALIGNED_OK
  54. movem.l d2-d6/a2-a4,-(sp)
  55. .else
  56. movem.l d2-d7/a2-a4,-(sp)
  57. .endif
  58. move.l _max_chain_length,Chain_Length
  59. move.l _prev_length,Best_Len
  60. lea _prev,Prev_Address
  61. lea _window+MIN_MATCH,Match_Ini
  62. move.l _strstart,Limit
  63. move.l Match_Ini,Scan_Ini
  64. add.l Limit,Scan_Ini
  65. subi.w #MAX_DIST,Limit
  66. bhi.b limit_ok
  67. moveq #0,Limit
  68. limit_ok:
  69. cmp.l _good_match,Best_Len
  70. bcs.b length_ok
  71. lsr.l #2,Chain_Length
  72. length_ok:
  73. subq.l #1,Chain_Length
  74. .ifdef UNALIGNED_OK
  75. move.w -MIN_MATCH(Scan_Ini),Scan_Start
  76. move.w -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End
  77. .else
  78. move.b -MIN_MATCH(Scan_Ini),Scan_Start
  79. lsl.w #8,Scan_Start
  80. move.b -MIN_MATCH+1(Scan_Ini),Scan_Start
  81. move.b -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End
  82. lsl.w #8,Scan_End
  83. move.b -MIN_MATCH(Scan_Ini,Best_Len.w),Scan_End
  84. .endif
  85. bra.b do_scan
  86. long_loop:
  87. .ifdef UNALIGNED_OK
  88. move.w -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End
  89. .else
  90. move.b -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End
  91. lsl.w #8,Scan_End
  92. move.b -MIN_MATCH(Scan_Ini,Best_Len.w),Scan_End
  93. .endif
  94. short_loop:
  95. lsl.w #1,Cur_Match
  96. move.w 0(Prev_Address,Cur_Match.l),Cur_Match
  97. cmp.w Limit,Cur_Match
  98. dbls Chain_Length,do_scan
  99. bra.b return
  100. do_scan:
  101. move.l Match_Ini,Match
  102. add.l Cur_Match,Match
  103. .ifdef UNALIGNED_OK
  104. cmp.w -MIN_MATCH-1(Match,Best_Len.w),Scan_End
  105. bne.b short_loop
  106. cmp.w -MIN_MATCH(Match),Scan_Start
  107. bne.b short_loop
  108. .else
  109. move.b -MIN_MATCH-1(Match,Best_Len.w),Scan_Test
  110. lsl.w #8,Scan_Test
  111. move.b -MIN_MATCH(Match,Best_Len.w),Scan_Test
  112. cmp.w Scan_Test,Scan_End
  113. bne.b short_loop
  114. move.b -MIN_MATCH(Match),Scan_Test
  115. lsl.w #8,Scan_Test
  116. move.b -MIN_MATCH+1(Match),Scan_Test
  117. cmp.w Scan_Test,Scan_Start
  118. bne.b short_loop
  119. .endif
  120. move.w #(MAX_MATCH-MIN_MATCH),Loop_Counter
  121. move.l Scan_Ini,Scan
  122. scan_loop:
  123. cmpm.b (Match)+,(Scan)+
  124. dbne Loop_Counter,scan_loop
  125. sub.l Scan_Ini,Scan
  126. addq.l #(MIN_MATCH-1),Scan
  127. cmp.l Best_Len,Scan
  128. bls.b short_loop
  129. move.l Scan,Best_Len
  130. move.l Cur_Match,_match_start
  131. cmp.l _nice_match,Best_Len
  132. bcs.b long_loop
  133. return:
  134. move.l Best_Len,d0
  135. .ifdef UNALIGNED_OK
  136. movem.l (sp)+,d2-d6/a2-a4
  137. .else
  138. movem.l (sp)+,d2-d7/a2-a4
  139. .endif
  140. rts
  141. end