summaryrefslogtreecommitdiff
path: root/contrib/asm386/gvmat32c.c
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2011-09-09 23:17:33 -0700
committerMark Adler <madler@alumni.caltech.edu>2011-09-09 23:17:33 -0700
commit7850e4e406dce1f7a819297eeb151d1ca18e7cd9 (patch)
treed4befddacae46b06c4924193904de533099610b4 /contrib/asm386/gvmat32c.c
parentebd3c2c0e734fc99a1360014ea52ed04fe6aade4 (diff)
downloadzlib-1.0.7.tar.gz
zlib-1.0.7.tar.bz2
zlib-1.0.7.zip
zlib 1.0.7v1.0.7
Diffstat (limited to 'contrib/asm386/gvmat32c.c')
-rw-r--r--contrib/asm386/gvmat32c.c229
1 files changed, 229 insertions, 0 deletions
diff --git a/contrib/asm386/gvmat32c.c b/contrib/asm386/gvmat32c.c
new file mode 100644
index 0000000..43d530b
--- /dev/null
+++ b/contrib/asm386/gvmat32c.c
@@ -0,0 +1,229 @@
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//#pragma optimize("agt",on)
11
12#include "deflate.h"
13
14#undef FAR
15#include <windows.h>
16
17#ifdef ASMV
18
19#define NIL 0
20
21static unsigned int tot=0;
22static unsigned int totl0=0;
23static unsigned int totl0p0=0;
24static unsigned int ba0=0;
25static unsigned int ba1=0;
26static unsigned int cpta=0;
27static unsigned int cptb=0;
28
29#define UNALIGNED_OK
30#define gvshow(a,b,c,d)
31/*
32void gvshow(int chain_length,int len,int limit,ushf* prev)
33{
34static int ival=0;
35char sz[80];
36unsigned long i;
37int prev0=*prev;
38 ival++;
39 //wsprintf(sz,"call %u, len=%u, chain_length=%u\n",ival,len,chain_length);
40 //OutputDebugString(sz);
41 tot++;
42 if (limit==NIL)
43 totl0++;
44 if ((limit==NIL) && (prev0==0))
45 totl0p0++;
46 for (i=limit+1;i<32768;i++)
47 {
48 ush va=*(prev+i);
49 if (ba0>4000000000)
50 {
51 ba0+=10;
52 }
53 ba0++;
54 if ((va>limit) || (va==0))
55 continue;
56 ba1++;
57 }
58}
59*/
60
61
62/* if your C compiler don't add underline before function name,
63 define ADD_UNDERLINE_ASMFUNC */
64#ifdef ADD_UNDERLINE_ASMFUNC
65#define longest_match_asm7fff _longest_match_asm7fff
66#endif
67void match_init()
68{
69}
70
71uInt longest_match_c(
72 deflate_state *s,
73 IPos cur_match); /* current match */
74
75
76uInt longest_match_asm7fff(
77 deflate_state *s,
78 IPos cur_match); /* current match */
79
80uInt longest_match(
81 deflate_state *s,
82 IPos cur_match) /* current match */
83{
84 if (s->w_mask == 0x7fff)
85 return longest_match_asm7fff(s,cur_match);
86 return longest_match_c(s,cur_match);
87}
88
89
90
91uInt longest_match_c(s, cur_match)
92 deflate_state *s;
93 IPos cur_match; /* current match */
94{
95 unsigned chain_length = s->max_chain_length;/* max hash chain length */
96 register Bytef *scan = s->window + s->strstart; /* current string */
97 register Bytef *match; /* matched string */
98 register int len; /* length of current match */
99 int best_len = s->prev_length; /* best match length so far */
100 int nice_match = s->nice_match; /* stop if match long enough */
101 IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
102 s->strstart - (IPos)MAX_DIST(s) : NIL;
103 /* Stop when cur_match becomes <= limit. To simplify the code,
104 * we prevent matches with the string of window index 0.
105 */
106 Posf *prev = s->prev;
107 uInt wmask = s->w_mask;
108
109#ifdef UNALIGNED_OK
110 /* Compare two bytes at a time. Note: this is not always beneficial.
111 * Try with and without -DUNALIGNED_OK to check.
112 */
113 register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
114 register ush scan_start = *(ushf*)scan;
115 register ush scan_end = *(ushf*)(scan+best_len-1);
116#else
117 register Bytef *strend = s->window + s->strstart + MAX_MATCH;
118 register Byte scan_end1 = scan[best_len-1];
119 register Byte scan_end = scan[best_len];
120#endif
121
122 /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
123 * It is easy to get rid of this optimization if necessary.
124 */
125 Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
126
127 /* Do not waste too much time if we already have a good match: */
128 if (s->prev_length >= s->good_match) {
129 chain_length >>= 2;
130 }
131 /* Do not look for matches beyond the end of the input. This is necessary
132 * to make deflate deterministic.
133 */
134 if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
135
136 Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
137
138 do {
139 Assert(cur_match < s->strstart, "no future");
140 match = s->window + cur_match;
141
142 /* Skip to next match if the match length cannot increase
143 * or if the match length is less than 2:
144 */
145#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
146 /* This code assumes sizeof(unsigned short) == 2. Do not use
147 * UNALIGNED_OK if your compiler uses a different size.
148 */
149 if (*(ushf*)(match+best_len-1) != scan_end ||
150 *(ushf*)match != scan_start) continue;
151
152 /* It is not necessary to compare scan[2] and match[2] since they are
153 * always equal when the other bytes match, given that the hash keys
154 * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
155 * strstart+3, +5, ... up to strstart+257. We check for insufficient
156 * lookahead only every 4th comparison; the 128th check will be made
157 * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
158 * necessary to put more guard bytes at the end of the window, or
159 * to check more often for insufficient lookahead.
160 */
161 Assert(scan[2] == match[2], "scan[2]?");
162 scan++, match++;
163 do {
164 } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
165 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
166 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
167 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
168 scan < strend);
169 /* The funny "do {}" generates better code on most compilers */
170
171 /* Here, scan <= window+strstart+257 */
172 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
173 if (*scan == *match) scan++;
174
175 len = (MAX_MATCH - 1) - (int)(strend-scan);
176 scan = strend - (MAX_MATCH-1);
177
178#else /* UNALIGNED_OK */
179
180 if (match[best_len] != scan_end ||
181 match[best_len-1] != scan_end1 ||
182 *match != *scan ||
183 *++match != scan[1]) continue;
184
185 /* The check at best_len-1 can be removed because it will be made
186 * again later. (This heuristic is not always a win.)
187 * It is not necessary to compare scan[2] and match[2] since they
188 * are always equal when the other bytes match, given that
189 * the hash keys are equal and that HASH_BITS >= 8.
190 */
191 scan += 2, match++;
192 Assert(*scan == *match, "match[2]?");
193
194 /* We check for insufficient lookahead only every 8th comparison;
195 * the 256th check will be made at strstart+258.
196 */
197 do {
198 } while (*++scan == *++match && *++scan == *++match &&
199 *++scan == *++match && *++scan == *++match &&
200 *++scan == *++match && *++scan == *++match &&
201 *++scan == *++match && *++scan == *++match &&
202 scan < strend);
203
204 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
205
206 len = MAX_MATCH - (int)(strend - scan);
207 scan = strend - MAX_MATCH;
208
209#endif /* UNALIGNED_OK */
210
211 if (len > best_len) {
212 s->match_start = cur_match;
213 best_len = len;
214 if (len >= nice_match) break;
215#ifdef UNALIGNED_OK
216 scan_end = *(ushf*)(scan+best_len-1);
217#else
218 scan_end1 = scan[best_len-1];
219 scan_end = scan[best_len];
220#endif
221 }
222 } while ((cur_match = prev[cur_match & wmask]) > limit
223 && --chain_length != 0);
224
225 if ((uInt)best_len <= s->lookahead) return best_len;
226 return s->lookahead;
227}
228
229#endif /* ASMV */