summaryrefslogtreecommitdiff
path: root/contrib/masmx86/gvmat32c.c
diff options
context:
space:
mode:
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 29void match_init()
30 30{
31 31}
32void match_init() 32
33{ 33unsigned long cpudetect32();
34} 34
35 35uInt longest_match_c(
36unsigned long cpudetect32(); 36 deflate_state *s,
37 37 IPos cur_match); /* current match */
38uInt longest_match_c( 38
39 deflate_state *s, 39
40 IPos cur_match); /* current match */ 40uInt longest_match_7fff(
41 41 deflate_state *s,
42 42 IPos cur_match); /* current match */
43uInt longest_match_7fff( 43
44 deflate_state *s, 44uInt longest_match_686(
45 IPos cur_match); /* current match */ 45 deflate_state *s,
46 46 IPos cur_match); /* current match */
47uInt longest_match_686( 47
48 deflate_state *s, 48uInt longest_match(
49 IPos cur_match); /* current match */ 49 deflate_state *s,
50 50 IPos cur_match) /* current match */
51uInt 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 68uInt longest_match_c(s, cur_match)
69 69 deflate_state *s;
70 70 IPos cur_match; /* current match */
71uInt 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 */