d853bb7ce8ab0b2b4a5aa37fc6ee567e6650bc78
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)
22 /* if your C compiler don't add underline before function name,
23 define ADD_UNDERLINE_ASMFUNC */
24 #ifdef ADD_UNDERLINE_ASMFUNC
25 #define longest_match_7fff _longest_match_7fff
34 unsigned long cpudetect32();
38 IPos cur_match
); /* current match */
41 uInt
longest_match_7fff(
43 IPos cur_match
); /* current match */
47 IPos cur_match
) /* current match */
49 static uInt iIsPPro
=2;
51 if ((s
->w_mask
== 0x7fff) && (iIsPPro
==0))
52 return longest_match_7fff(s
,cur_match
);
55 iIsPPro
= (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;
57 return longest_match_c(s
,cur_match
);
62 uInt
longest_match_c(s
, cur_match
)
64 IPos cur_match
; /* current match */
66 unsigned chain_length
= s
->max_chain_length
;/* max hash chain length */
67 register Bytef
*scan
= s
->window
+ s
->strstart
; /* current string */
68 register Bytef
*match
; /* matched string */
69 register int len
; /* length of current match */
70 int best_len
= s
->prev_length
; /* best match length so far */
71 int nice_match
= s
->nice_match
; /* stop if match long enough */
72 IPos limit
= s
->strstart
> (IPos
)MAX_DIST(s
) ?
73 s
->strstart
- (IPos
)MAX_DIST(s
) : NIL
;
74 /* Stop when cur_match becomes <= limit. To simplify the code,
75 * we prevent matches with the string of window index 0.
78 uInt wmask
= s
->w_mask
;
81 /* Compare two bytes at a time. Note: this is not always beneficial.
82 * Try with and without -DUNALIGNED_OK to check.
84 register Bytef
*strend
= s
->window
+ s
->strstart
+ MAX_MATCH
- 1;
85 register ush scan_start
= *(ushf
*)scan
;
86 register ush scan_end
= *(ushf
*)(scan
+best_len
-1);
88 register Bytef
*strend
= s
->window
+ s
->strstart
+ MAX_MATCH
;
89 register Byte scan_end1
= scan
[best_len
-1];
90 register Byte scan_end
= scan
[best_len
];
93 /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
94 * It is easy to get rid of this optimization if necessary.
96 Assert(s
->hash_bits
>= 8 && MAX_MATCH
== 258, "Code too clever");
98 /* Do not waste too much time if we already have a good match: */
99 if (s
->prev_length
>= s
->good_match
) {
102 /* Do not look for matches beyond the end of the input. This is necessary
103 * to make deflate deterministic.
105 if ((uInt
)nice_match
> s
->lookahead
) nice_match
= s
->lookahead
;
107 Assert((ulg
)s
->strstart
<= s
->window_size
-MIN_LOOKAHEAD
, "need lookahead");
110 Assert(cur_match
< s
->strstart
, "no future");
111 match
= s
->window
+ cur_match
;
113 /* Skip to next match if the match length cannot increase
114 * or if the match length is less than 2:
116 #if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
117 /* This code assumes sizeof(unsigned short) == 2. Do not use
118 * UNALIGNED_OK if your compiler uses a different size.
120 if (*(ushf
*)(match
+best_len
-1) != scan_end
||
121 *(ushf
*)match
!= scan_start
) continue;
123 /* It is not necessary to compare scan[2] and match[2] since they are
124 * always equal when the other bytes match, given that the hash keys
125 * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
126 * strstart+3, +5, ... up to strstart+257. We check for insufficient
127 * lookahead only every 4th comparison; the 128th check will be made
128 * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
129 * necessary to put more guard bytes at the end of the window, or
130 * to check more often for insufficient lookahead.
132 Assert(scan
[2] == match
[2], "scan[2]?");
135 } while (*(ushf
*)(scan
+=2) == *(ushf
*)(match
+=2) &&
136 *(ushf
*)(scan
+=2) == *(ushf
*)(match
+=2) &&
137 *(ushf
*)(scan
+=2) == *(ushf
*)(match
+=2) &&
138 *(ushf
*)(scan
+=2) == *(ushf
*)(match
+=2) &&
140 /* The funny "do {}" generates better code on most compilers */
142 /* Here, scan <= window+strstart+257 */
143 Assert(scan
<= s
->window
+(unsigned)(s
->window_size
-1), "wild scan");
144 if (*scan
== *match
) scan
++;
146 len
= (MAX_MATCH
- 1) - (int)(strend
-scan
);
147 scan
= strend
- (MAX_MATCH
-1);
149 #else /* UNALIGNED_OK */
151 if (match
[best_len
] != scan_end
||
152 match
[best_len
-1] != scan_end1
||
154 *++match
!= scan
[1]) continue;
156 /* The check at best_len-1 can be removed because it will be made
157 * again later. (This heuristic is not always a win.)
158 * It is not necessary to compare scan[2] and match[2] since they
159 * are always equal when the other bytes match, given that
160 * the hash keys are equal and that HASH_BITS >= 8.
163 Assert(*scan
== *match
, "match[2]?");
165 /* We check for insufficient lookahead only every 8th comparison;
166 * the 256th check will be made at strstart+258.
169 } while (*++scan
== *++match
&& *++scan
== *++match
&&
170 *++scan
== *++match
&& *++scan
== *++match
&&
171 *++scan
== *++match
&& *++scan
== *++match
&&
172 *++scan
== *++match
&& *++scan
== *++match
&&
175 Assert(scan
<= s
->window
+(unsigned)(s
->window_size
-1), "wild scan");
177 len
= MAX_MATCH
- (int)(strend
- scan
);
178 scan
= strend
- MAX_MATCH
;
180 #endif /* UNALIGNED_OK */
182 if (len
> best_len
) {
183 s
->match_start
= cur_match
;
185 if (len
>= nice_match
) break;
187 scan_end
= *(ushf
*)(scan
+best_len
-1);
189 scan_end1
= scan
[best_len
-1];
190 scan_end
= scan
[best_len
];
193 } while ((cur_match
= prev
[cur_match
& wmask
]) > limit
194 && --chain_length
!= 0);
196 if ((uInt
)best_len
<= s
->lookahead
) return (uInt
)best_len
;