~ubuntu-branches/ubuntu/raring/perl-tk/raring

« back to all changes in this revision

Viewing changes to PNG/zlib/contrib/asm386/gvmat32c.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Tuckley
  • Date: 2008-02-15 13:56:59 UTC
  • mfrom: (1.1.3 upstream) (4.1.1 hardy)
  • Revision ID: james.westby@ubuntu.com-20080215135659-ru2oqlykuju20fav
Tags: 1:804.028-1
* New Upstream Release (Closes: #463080).
* Update to Debhelper v5.
* Build with XFT=1 (Closes: #411129).

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
11
 
#include "deflate.h"
12
 
 
13
 
#undef FAR
14
 
#include <windows.h>
15
 
 
16
 
#ifdef ASMV
17
 
#define NIL 0
18
 
 
19
 
#define UNALIGNED_OK
20
 
 
21
 
 
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
26
 
#endif
27
 
 
28
 
 
29
 
 
30
 
void match_init()
31
 
{
32
 
}
33
 
 
34
 
unsigned long cpudetect32();
35
 
 
36
 
uInt longest_match_c(
37
 
    deflate_state *s,
38
 
    IPos cur_match);                             /* current match */
39
 
 
40
 
 
41
 
uInt longest_match_7fff(
42
 
    deflate_state *s,
43
 
    IPos cur_match);                             /* current match */
44
 
 
45
 
uInt longest_match(
46
 
    deflate_state *s,
47
 
    IPos cur_match)                             /* current match */
48
 
{
49
 
        static uInt iIsPPro=2;
50
 
 
51
 
    if ((s->w_mask == 0x7fff) && (iIsPPro==0))
52
 
        return longest_match_7fff(s,cur_match);
53
 
 
54
 
        if (iIsPPro==2)
55
 
                iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;
56
 
 
57
 
        return longest_match_c(s,cur_match);
58
 
}
59
 
 
60
 
 
61
 
 
62
 
uInt longest_match_c(s, cur_match)
63
 
    deflate_state *s;
64
 
    IPos cur_match;                             /* current match */
65
 
{
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.
76
 
     */
77
 
    Posf *prev = s->prev;
78
 
    uInt wmask = s->w_mask;
79
 
 
80
 
#ifdef UNALIGNED_OK
81
 
    /* Compare two bytes at a time. Note: this is not always beneficial.
82
 
     * Try with and without -DUNALIGNED_OK to check.
83
 
     */
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);
87
 
#else
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];
91
 
#endif
92
 
 
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.
95
 
     */
96
 
    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
97
 
 
98
 
    /* Do not waste too much time if we already have a good match: */
99
 
    if (s->prev_length >= s->good_match) {
100
 
        chain_length >>= 2;
101
 
    }
102
 
    /* Do not look for matches beyond the end of the input. This is necessary
103
 
     * to make deflate deterministic.
104
 
     */
105
 
    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
106
 
 
107
 
    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
108
 
 
109
 
    do {
110
 
        Assert(cur_match < s->strstart, "no future");
111
 
        match = s->window + cur_match;
112
 
 
113
 
        /* Skip to next match if the match length cannot increase
114
 
         * or if the match length is less than 2:
115
 
         */
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.
119
 
         */
120
 
        if (*(ushf*)(match+best_len-1) != scan_end ||
121
 
            *(ushf*)match != scan_start) continue;
122
 
 
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.
131
 
         */
132
 
        Assert(scan[2] == match[2], "scan[2]?");
133
 
        scan++, match++;
134
 
        do {
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) &&
139
 
                 scan < strend);
140
 
        /* The funny "do {}" generates better code on most compilers */
141
 
 
142
 
        /* Here, scan <= window+strstart+257 */
143
 
        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
144
 
        if (*scan == *match) scan++;
145
 
 
146
 
        len = (MAX_MATCH - 1) - (int)(strend-scan);
147
 
        scan = strend - (MAX_MATCH-1);
148
 
 
149
 
#else /* UNALIGNED_OK */
150
 
 
151
 
        if (match[best_len]   != scan_end  ||
152
 
            match[best_len-1] != scan_end1 ||
153
 
            *match            != *scan     ||
154
 
            *++match          != scan[1])      continue;
155
 
 
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.
161
 
         */
162
 
        scan += 2, match++;
163
 
        Assert(*scan == *match, "match[2]?");
164
 
 
165
 
        /* We check for insufficient lookahead only every 8th comparison;
166
 
         * the 256th check will be made at strstart+258.
167
 
         */
168
 
        do {
169
 
        } while (*++scan == *++match && *++scan == *++match &&
170
 
                 *++scan == *++match && *++scan == *++match &&
171
 
                 *++scan == *++match && *++scan == *++match &&
172
 
                 *++scan == *++match && *++scan == *++match &&
173
 
                 scan < strend);
174
 
 
175
 
        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
176
 
 
177
 
        len = MAX_MATCH - (int)(strend - scan);
178
 
        scan = strend - MAX_MATCH;
179
 
 
180
 
#endif /* UNALIGNED_OK */
181
 
 
182
 
        if (len > best_len) {
183
 
            s->match_start = cur_match;
184
 
            best_len = len;
185
 
            if (len >= nice_match) break;
186
 
#ifdef UNALIGNED_OK
187
 
            scan_end = *(ushf*)(scan+best_len-1);
188
 
#else
189
 
            scan_end1  = scan[best_len-1];
190
 
            scan_end   = scan[best_len];
191
 
#endif
192
 
        }
193
 
    } while ((cur_match = prev[cur_match & wmask]) > limit
194
 
             && --chain_length != 0);
195
 
 
196
 
    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
197
 
    return s->lookahead;
198
 
}
199
 
 
200
 
#endif /* ASMV */