match.s 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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. ;
  12. ; Adapted for the Amiga by Carsten Steger <stegerc@informatik.tu-muenchen.de>
  13. ; using the code in match.S.
  14. ; The major change in this code consists of removing all unaligned
  15. ; word accesses, because they cause 68000-based Amigas to crash.
  16. ; For maximum speed, UNALIGNED_OK can be defined in Makefile.sasc.
  17. ; The program will then only run on 68020-based Amigas, though.
  18. ;
  19. ; This code will run with registerized parameters too, unless SAS
  20. ; changes parameter passing conventions between new releases of SAS/C.
  21. ;;Cur_Match equr d0 ; Must be in d0!
  22. ;;Best_Len equr d1
  23. ;;Loop_Counter equr d2
  24. ;;Scan_Start equr d3
  25. ;;Scan_End equr d4
  26. ;;Limit equr d5
  27. ;;Chain_Length equr d6
  28. ;;Scan_Test equr d7
  29. ;;Scan equr a0
  30. ;;Match equr a1
  31. ;;Prev_Address equr a2
  32. ;;Scan_Ini equr a3
  33. ;;Match_Ini equr a4
  34. MAX_MATCH equ 258
  35. MIN_MATCH equ 3
  36. WSIZE equ 32768
  37. MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1
  38. .globl _max_chain_length
  39. .globl _prev_length
  40. .globl _prev
  41. .globl _window
  42. .globl _strstart
  43. .globl _good_match
  44. .globl _match_start
  45. .globl _nice_match
  46. .text
  47. .globl _match_init
  48. .globl _longest_match
  49. _match_init:
  50. rts
  51. _longest_match:
  52. move.l 4(sp),d0
  53. movem.l d2-d7/a2-a4,-(sp)
  54. move.l _max_chain_length,d6
  55. move.l _prev_length,d1
  56. lea _prev,a2
  57. lea _window+MIN_MATCH,a4
  58. move.l _strstart,d5
  59. move.l a4,a3
  60. add.l d5,a3
  61. subi.w #MAX_DIST,d5
  62. bhi limit_ok
  63. moveq #0,d5
  64. limit_ok:
  65. cmp.l _good_match,d1
  66. bcs length_ok
  67. lsr.l #2,d6
  68. length_ok:
  69. subq.l #1,d6
  70. move.b -MIN_MATCH(a3),d3
  71. lsl.w #8,d3
  72. move.b -MIN_MATCH+1(a3),d3
  73. move.b -MIN_MATCH-1(a3,d1),d4
  74. lsl.w #8,d4
  75. move.b -MIN_MATCH(a3,d1),d4
  76. bra do_scan
  77. long_loop:
  78. move.b -MIN_MATCH-1(a3,d1),d4
  79. lsl.w #8,d4
  80. move.b -MIN_MATCH(a3,d1),d4
  81. short_loop:
  82. lsl.w #1,d0
  83. move.w 0(a2,d0.l),d0
  84. cmp.w d5,d0
  85. dbls d6,do_scan
  86. bra return
  87. do_scan:
  88. move.l a4,a1
  89. add.l d0,a1
  90. move.b -MIN_MATCH-1(a1,d1),d7
  91. lsl.w #8,d7
  92. move.b -MIN_MATCH(a1,d1),d7
  93. cmp.w d7,d4
  94. bne short_loop
  95. move.b -MIN_MATCH(a1),d7
  96. lsl.w #8,d7
  97. move.b -MIN_MATCH+1(a1),d7
  98. cmp.w d7,d3
  99. bne short_loop
  100. move.w #(MAX_MATCH-MIN_MATCH),d2
  101. move.l a3,a0
  102. scan_loop:
  103. cmpm.b (a1)+,(a0)+
  104. dbne d2,scan_loop
  105. sub.l a3,a0
  106. addq.l #(MIN_MATCH-1),a0
  107. cmp.l d1,a0
  108. bls short_loop
  109. move.l a0,d1
  110. move.l d0,_match_start
  111. cmp.l _nice_match,d1
  112. bcs long_loop
  113. return:
  114. move.l d1,d0
  115. movem.l (sp)+,d2-d7/a2-a4
  116. rts
  117. end