You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
6.8 KiB

  1. /* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86
  2. * Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
  3. * File written by Gilles Vollant, by modifiying the longest_match
  4. * from Jean-loup Gailly in deflate.c
  5. * it prepare all parameters and call the assembly longest_match_gvasm
  6. * longest_match execute standard C code is wmask != 0x7fff
  7. * (assembly code is faster with a fixed wmask)
  8. *
  9. */
  10. #include "deflate.h"
  11. #undef FAR
  12. #include <windows.h>
  13. #ifdef ASMV
  14. #define NIL 0
  15. #define UNALIGNED_OK
  16. /* if your C compiler don't add underline before function name,
  17. define ADD_UNDERLINE_ASMFUNC */
  18. #ifdef ADD_UNDERLINE_ASMFUNC
  19. #define longest_match_7fff _longest_match_7fff
  20. #endif
  21. void match_init()
  22. {
  23. }
  24. unsigned long cpudetect32();
  25. uInt longest_match_c(
  26. deflate_state *s,
  27. IPos cur_match); /* current match */
  28. uInt longest_match_7fff(
  29. deflate_state *s,
  30. IPos cur_match); /* current match */
  31. uInt longest_match(
  32. deflate_state *s,
  33. IPos cur_match) /* current match */
  34. {
  35. static uInt iIsPPro=2;
  36. if ((s->w_mask == 0x7fff) && (iIsPPro==0))
  37. return longest_match_7fff(s,cur_match);
  38. if (iIsPPro==2)
  39. iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;
  40. return longest_match_c(s,cur_match);
  41. }
  42. uInt longest_match_c(s, cur_match)
  43. deflate_state *s;
  44. IPos cur_match; /* current match */
  45. {
  46. unsigned chain_length = s->max_chain_length;/* max hash chain length */
  47. register Bytef *scan = s->window + s->strstart; /* current string */
  48. register Bytef *match; /* matched string */
  49. register int len; /* length of current match */
  50. int best_len = s->prev_length; /* best match length so far */
  51. int nice_match = s->nice_match; /* stop if match long enough */
  52. IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
  53. s->strstart - (IPos)MAX_DIST(s) : NIL;
  54. /* Stop when cur_match becomes <= limit. To simplify the code,
  55. * we prevent matches with the string of window index 0.
  56. */
  57. Posf *prev = s->prev;
  58. uInt wmask = s->w_mask;
  59. #ifdef UNALIGNED_OK
  60. /* Compare two bytes at a time. Note: this is not always beneficial.
  61. * Try with and without -DUNALIGNED_OK to check.
  62. */
  63. register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
  64. register ush scan_start = *(ushf*)scan;
  65. register ush scan_end = *(ushf*)(scan+best_len-1);
  66. #else
  67. register Bytef *strend = s->window + s->strstart + MAX_MATCH;
  68. register Byte scan_end1 = scan[best_len-1];
  69. register Byte scan_end = scan[best_len];
  70. #endif
  71. /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
  72. * It is easy to get rid of this optimization if necessary.
  73. */
  74. Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
  75. /* Do not waste too much time if we already have a good match: */
  76. if (s->prev_length >= s->good_match) {
  77. chain_length >>= 2;
  78. }
  79. /* Do not look for matches beyond the end of the input. This is necessary
  80. * to make deflate deterministic.
  81. */
  82. if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
  83. Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
  84. do {
  85. Assert(cur_match < s->strstart, "no future");
  86. match = s->window + cur_match;
  87. /* Skip to next match if the match length cannot increase
  88. * or if the match length is less than 2:
  89. */
  90. #if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
  91. /* This code assumes sizeof(unsigned short) == 2. Do not use
  92. * UNALIGNED_OK if your compiler uses a different size.
  93. */
  94. if (*(ushf*)(match+best_len-1) != scan_end ||
  95. *(ushf*)match != scan_start) continue;
  96. /* It is not necessary to compare scan[2] and match[2] since they are
  97. * always equal when the other bytes match, given that the hash keys
  98. * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
  99. * strstart+3, +5, ... up to strstart+257. We check for insufficient
  100. * lookahead only every 4th comparison; the 128th check will be made
  101. * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
  102. * necessary to put more guard bytes at the end of the window, or
  103. * to check more often for insufficient lookahead.
  104. */
  105. Assert(scan[2] == match[2], "scan[2]?");
  106. scan++, match++;
  107. do {
  108. } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
  109. *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
  110. *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
  111. *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
  112. scan < strend);
  113. /* The funny "do {}" generates better code on most compilers */
  114. /* Here, scan <= window+strstart+257 */
  115. Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
  116. if (*scan == *match) scan++;
  117. len = (MAX_MATCH - 1) - (int)(strend-scan);
  118. scan = strend - (MAX_MATCH-1);
  119. #else /* UNALIGNED_OK */
  120. if (match[best_len] != scan_end ||
  121. match[best_len-1] != scan_end1 ||
  122. *match != *scan ||
  123. *++match != scan[1]) continue;
  124. /* The check at best_len-1 can be removed because it will be made
  125. * again later. (This heuristic is not always a win.)
  126. * It is not necessary to compare scan[2] and match[2] since they
  127. * are always equal when the other bytes match, given that
  128. * the hash keys are equal and that HASH_BITS >= 8.
  129. */
  130. scan += 2, match++;
  131. Assert(*scan == *match, "match[2]?");
  132. /* We check for insufficient lookahead only every 8th comparison;
  133. * the 256th check will be made at strstart+258.
  134. */
  135. do {
  136. } while (*++scan == *++match && *++scan == *++match &&
  137. *++scan == *++match && *++scan == *++match &&
  138. *++scan == *++match && *++scan == *++match &&
  139. *++scan == *++match && *++scan == *++match &&
  140. scan < strend);
  141. Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
  142. len = MAX_MATCH - (int)(strend - scan);
  143. scan = strend - MAX_MATCH;
  144. #endif /* UNALIGNED_OK */
  145. if (len > best_len) {
  146. s->match_start = cur_match;
  147. best_len = len;
  148. if (len >= nice_match) break;
  149. #ifdef UNALIGNED_OK
  150. scan_end = *(ushf*)(scan+best_len-1);
  151. #else
  152. scan_end1 = scan[best_len-1];
  153. scan_end = scan[best_len];
  154. #endif
  155. }
  156. } while ((cur_match = prev[cur_match & wmask]) > limit
  157. && --chain_length != 0);
  158. if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
  159. return s->lookahead;
  160. }
  161. #endif /* ASMV */