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