gvmat32c.c
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:7k
源码类别:

Symbian

开发平台:

C/C++

  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 */