Coverage Report

Created: 2025-06-10 07:19

/src/ghostpdl/base/gsroprun1.h
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* This file is repeatedly included by gsroprun.c to 'autogenerate' many
18
 * different versions of roprun code. DO NOT USE THIS FILE EXCEPT FROM
19
 * gsroprun.c.
20
 */
21
22
/* Set the following defines as appropriate on entry:
23
 *   TEMPLATE_NAME (Compulsory)  The name of the function to generate
24
 *   SPECIFIC_ROP  (Optional)    If set, the function will base its decision
25
 *                               about whether to provide S and T upon
26
 *                               this value.
27
 *   SPECIFIC_CODE (Optional)    If set, this should expand out to code to
28
 *                               perform the rop. Will be invoked as:
29
 *                               SPECIFIC_ROP(OUT,D,S,T)
30
 *   S_CONST       (Optional)    If set, S will be taken to be constant, else
31
 *                               S will be read from a pointer.
32
 *   T_CONST       (Optional)    If set, T will be taken to be constant, else
33
 *                               T will be read from a pointer.
34
 */
35
36
#if defined(TEMPLATE_NAME)
37
38
#ifdef SPECIFIC_ROP
39
#if rop3_uses_S(SPECIFIC_ROP)
40
#define S_USED
41
#endif
42
#if rop3_uses_T(SPECIFIC_ROP)
43
#define T_USED
44
#endif
45
#else /* !SPECIFIC_ROP */
46
#define S_USED
47
#define T_USED
48
#endif /* SPECIFIC_ROP */
49
50
/* We work in 'chunks' here; for bigendian machines, we can safely use
51
 * chunks of 'int' size. For little endian machines where we have a cheap
52
 * endian swap, we can do likewise. For others, we'll work at the byte
53
 * level. */
54
#if !ARCH_IS_BIG_ENDIAN && !defined(ENDIAN_SWAP_INT)
55
#define CHUNKSIZE 8
56
#define CHUNK byte
57
#define CHUNKONES 255
58
59
#define ADJUST_TO_CHUNK(d,dpos) do {} while (0)
60
61
#else /* ARCH_IS_BIG_ENDIAN || defined(ENDIAN_SWAP_INT) */
62
#if ARCH_LOG2_SIZEOF_INT == 2
63
69.8M
#define CHUNKSIZE 32
64
14.0M
#define CHUNK unsigned int
65
7.02M
#define CHUNKONES 0xFFFFFFFFU
66
67
#if ARCH_SIZEOF_PTR == (1<<ARCH_LOG2_SIZEOF_INT)
68
#define ROP_PTRDIFF_T int
69
#else
70
#define ROP_PTRDIFF_T int64_t
71
#endif
72
#define ADJUST_TO_CHUNK(d, dpos)                      \
73
7.03M
    do { int offset = ((ROP_PTRDIFF_T)d) & ((CHUNKSIZE>>3)-1);  \
74
7.03M
         d = (CHUNK *)(void *)(((byte *)(void *)d)-offset);   \
75
7.03M
         dpos += offset<<3;                           \
76
7.03M
     } while (0)
77
#else
78
/* FIXME: Write more code in here when we find an example. */
79
#endif
80
#endif /* ARCH_IS_BIG_ENDIAN || defined(ENDIAN_SWAP_INT) */
81
82
/* We define an 'RE' macro that reverses the endianness of a chunk, if we
83
 * need it, and does nothing otherwise. */
84
#if !ARCH_IS_BIG_ENDIAN && defined(ENDIAN_SWAP_INT) && (CHUNKSIZE != 8)
85
34.7M
#define RE(I) ((CHUNK)ENDIAN_SWAP_INT(I))
86
#else /* ARCH_IS_BIG_ENDIAN || !defined(ENDIAN_SWAP_INT) || (CHUNKSIZE == 8) */
87
#define RE(I) (I)
88
#endif /* ARCH_IS_BIG_ENDIAN || !defined(ENDIAN_SWAP_INT) || (CHUNKSIZE == 8) */
89
90
/* In some cases we will need to fetch values from a pointer, and 'skew'
91
 * them. We need 2 variants of this macro. One that is 'SAFE' to use when
92
 * SKEW might be 0, and one that can be faster, because we know that SKEW
93
 * is non zero. */
94
#define SKEW_FETCH(S,s,SKEW) \
95
21.2M
    do { S = RE((RE(s[0])<<SKEW) | (RE(s[1])>>(CHUNKSIZE-SKEW))); s++; } while (0)
96
#define SAFE_SKEW_FETCH(S,s,SKEW,L,R)                                    \
97
6.43M
    do { S = RE(((L) ? 0 : (RE(s[0])<<SKEW)) | ((R) ? 0 : (RE(s[1])>>(CHUNKSIZE-SKEW)))); s++; } while (0)
98
99
#if defined(S_USED) && !defined(S_CONST)
100
#define S_SKEW
101
21.2M
#define FETCH_S           SKEW_FETCH(S,s,s_skew)
102
6.43M
#define SAFE_FETCH_S(L,R) SAFE_SKEW_FETCH(S,s,s_skew,L,R)
103
#else /* !defined(S_USED) || defined(S_CONST) */
104
#define FETCH_S
105
#define SAFE_FETCH_S(L,R)
106
#endif /* !defined(S_USED) || defined(S_CONST) */
107
108
#if defined(T_USED) && !defined(T_CONST)
109
#define T_SKEW
110
0
#define FETCH_T           SKEW_FETCH(T,t,t_skew)
111
0
#define SAFE_FETCH_T(L,R) SAFE_SKEW_FETCH(T,t,t_skew,L,R)
112
#else /* !defined(T_USED) || defined(T_CONST) */
113
#define FETCH_T
114
#define SAFE_FETCH_T(L,R)
115
#endif /* !defined(T_USED) || defined(T_CONST) */
116
117
static void TEMPLATE_NAME(rop_run_op *op, byte *d_, int len)
118
3.51M
{
119
#ifndef SPECIFIC_CODE
120
    rop_proc     proc = rop_proc_table[op->rop];
121
434k
#define SPECIFIC_CODE(OUT_, D_,S_,T_) OUT_ = proc(D_,S_,T_)
122
#endif /* !defined(SPECIFIC_CODE) */
123
3.51M
    CHUNK        lmask, rmask;
124
#ifdef S_USED
125
#ifdef S_CONST
126
0
    CHUNK        S = (CHUNK)op->s.c;
127
#else /* !defined(S_CONST) */
128
    const CHUNK *s = (CHUNK *)(void *)op->s.b.ptr;
129
3.51M
    CHUNK        S;
130
    int          s_skew;
131
#endif /* !defined(S_CONST) */
132
#else /* !defined(S_USED) */
133
#define S 0
134
#undef S_CONST
135
#endif /* !defined(S_USED) */
136
#ifdef T_USED
137
#ifdef T_CONST
138
32.9k
    CHUNK        T = (CHUNK)op->t.c;
139
#else /* !defined(T_CONST) */
140
    const CHUNK *t = (CHUNK *)(void *)op->t.b.ptr;
141
0
    CHUNK        T;
142
    int          t_skew;
143
#endif /* !defined(T_CONST) */
144
#else /* !defined(T_USED) */
145
#define T 0
146
#undef T_CONST
147
#endif /* !defined(T_USED) */
148
#if defined(S_SKEW) || defined(T_SKEW)
149
    int skewflags = 0;
150
#endif
151
3.51M
    CHUNK        D;
152
3.51M
    int          dpos = op->dpos;
153
3.51M
    CHUNK       *d = (CHUNK *)(void *)d_;
154
155
    /* Align d to CHUNKSIZE */
156
3.51M
    ADJUST_TO_CHUNK(d,dpos);
157
158
    /* On entry len = length in 'depth' chunks. Change it to be the length
159
     * in bits, and add on the number of bits we skip at the start of the
160
     * run. */
161
3.51M
    len    = len * op->depth + dpos;
162
163
    /* lmask = the set of bits to alter in the output bitmap on the left
164
     * hand edge of the run. rmask = the set of bits NOT to alter in the
165
     * output bitmap on the right hand edge of the run. */
166
3.51M
    lmask  = RE((CHUNKONES>>((CHUNKSIZE-1) & dpos)));
167
3.51M
    rmask  = RE((CHUNKONES>>((CHUNKSIZE-1) & len)));
168
3.51M
    if (rmask == CHUNKONES) rmask = 0;
169
170
#if defined(S_CONST) || defined(T_CONST)
171
    /* S and T should be supplied as 'depth' bits. Duplicate them up to be
172
     * byte size (if they are supplied byte sized, that's fine too). */
173
32.9k
    if (op->depth & 1) {
174
#ifdef S_CONST
175
        S |= S<<1;
176
#endif /* !defined(S_CONST) */
177
32.9k
#ifdef T_CONST
178
32.9k
        T |= T<<1;
179
32.9k
#endif /* !defined(T_CONST) */
180
32.9k
    }
181
32.9k
    if (op->depth & 3) {
182
#ifdef S_CONST
183
        S |= S<<2;
184
#endif /* !defined(S_CONST) */
185
32.9k
#ifdef T_CONST
186
32.9k
        T |= T<<2;
187
32.9k
#endif /* !defined(T_CONST) */
188
32.9k
    }
189
32.9k
    if (op->depth & 7) {
190
#ifdef S_CONST
191
        S |= S<<4;
192
#endif /* !defined(S_CONST) */
193
32.9k
#ifdef T_CONST
194
32.9k
        T |= T<<4;
195
32.9k
#endif /* !defined(T_CONST) */
196
32.9k
    }
197
#if CHUNKSIZE > 8
198
32.9k
    if (op->depth & 15) {
199
#ifdef S_CONST
200
        S |= S<<8;
201
#endif /* !defined(S_CONST) */
202
32.9k
#ifdef T_CONST
203
32.9k
        T |= T<<8;
204
32.9k
#endif /* !defined(T_CONST) */
205
32.9k
    }
206
#endif /* CHUNKSIZE > 8 */
207
#if CHUNKSIZE > 16
208
32.9k
    if (op->depth & 31) {
209
#ifdef S_CONST
210
        S |= S<<16;
211
#endif /* !defined(S_CONST) */
212
32.9k
#ifdef T_CONST
213
32.9k
        T |= T<<16;
214
32.9k
#endif /* !defined(T_CONST) */
215
32.9k
    }
216
#endif /* CHUNKSIZE > 16 */
217
#endif /* defined(S_CONST) || defined(T_CONST) */
218
219
    /* Note #1: This mirrors what the original code did, but I think it has
220
     * the risk of moving s and t back beyond officially allocated space. We
221
     * may be saved by the fact that all blocks have a word or two in front
222
     * of them due to the allocator. If we ever get valgrind properly marking
223
     * allocated blocks as readable etc, then this may throw some spurious
224
     * errors. RJW. */
225
#ifdef S_SKEW
226
    {
227
        int slen, slen2;
228
        int spos = op->s.b.pos;
229
3.51M
        ADJUST_TO_CHUNK(s, spos);
230
        s_skew = spos - dpos;
231
3.51M
        if (s_skew < 0) {
232
2.60M
            s_skew += CHUNKSIZE;
233
2.60M
            s--;
234
2.60M
            skewflags |= 1; /* Suppress reading off left edge */
235
2.60M
        }
236
        /* We are allowed to read all the data bits, so: len - dpos + tpos
237
         * We're allowed to read in CHUNKS, so: CHUNKUP(len-dpos+tpos).
238
         * This code will actually read CHUNKUP(len)+CHUNKSIZE bits. If
239
         * This is larger, then suppress. */
240
3.51M
        slen  = (len + s_skew    + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
241
3.51M
        slen2 = (len + CHUNKSIZE + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
242
3.51M
        if ((s_skew == 0) || (slen < slen2)) {
243
1.68M
            skewflags |= 4; /* Suppress reading off the right edge */
244
1.68M
        }
245
    }
246
#endif /* !defined(S_SKEW) */
247
#ifdef T_SKEW
248
    {
249
        int tlen, tlen2;
250
        int tpos = op->t.b.pos;
251
0
        ADJUST_TO_CHUNK(t, tpos);
252
        t_skew = tpos - dpos;
253
0
        if (t_skew < 0) {
254
0
            t_skew += CHUNKSIZE;
255
0
            t--;
256
0
            skewflags |= 2; /* Suppress reading off left edge */
257
0
        }
258
        /* We are allowed to read all the data bits, so: len - dpos + tpos
259
         * We're allowed to read in CHUNKS, so: CHUNKUP(len-dpos+tpos).
260
         * This code will actually read CHUNKUP(len)+CHUNKSIZE bits. If
261
         * This is larger, then suppress. */
262
0
        tlen  = (len + t_skew    + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
263
0
        tlen2 = (len + CHUNKSIZE + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
264
0
        if ((t_skew == 0) || (tlen < tlen2)) {
265
0
            skewflags |= 8; /* Suppress reading off the right edge */
266
0
        }
267
    }
268
#endif /* !defined(T_SKEW) */
269
270
3.51M
    len -= CHUNKSIZE; /* len = bytes to do - CHUNKSIZE */
271
    /* len <= 0 means 1 word or less to do */
272
3.51M
    if (len <= 0) {
273
        /* Short case - starts and ends in the same chunk */
274
5.22k
        lmask &= ~rmask; /* Combined mask = bits to alter */
275
5.22k
        SAFE_FETCH_S(skewflags & 1,skewflags & 4);
276
5.22k
        SAFE_FETCH_T(skewflags & 2,skewflags & 8);
277
5.22k
        SPECIFIC_CODE(D, *d, S, T);
278
5.22k
        *d = (*d & ~lmask) | (D & lmask);
279
5.22k
        return;
280
5.22k
    }
281
3.51M
    if ((lmask != CHUNKONES)
282
#if defined(S_SKEW) || defined(T_SKEW)
283
597k
        || (skewflags & 3)
284
#endif
285
3.51M
        ) {
286
        /* Unaligned left hand case */
287
2.91M
        SAFE_FETCH_S(skewflags & 1,s_skew == 0);
288
2.91M
        SAFE_FETCH_T(skewflags & 2,t_skew == 0);
289
2.91M
        SPECIFIC_CODE(D, *d, S, T);
290
2.91M
        *d = (*d & ~lmask) | (D & lmask);
291
2.91M
        d++;
292
2.91M
        len -= CHUNKSIZE;
293
2.91M
    }
294
3.51M
    if (len > 0) {
295
        /* Simple middle case (complete destination chunks). */
296
#ifdef S_SKEW
297
2.47M
        if (s_skew == 0) {
298
#ifdef T_SKEW
299
0
            if (t_skew == 0) {
300
0
                do {
301
0
                    SPECIFIC_CODE(*d, *d, *s++, *t++);
302
0
                    d++;
303
0
                    len -= CHUNKSIZE;
304
0
                } while (len > 0);
305
0
            } else
306
0
#endif /* !defined(T_SKEW) */
307
0
            {
308
14.9M
                do {
309
14.9M
                    FETCH_T;
310
14.9M
                    SPECIFIC_CODE(*d, *d, *s++, T);
311
14.9M
                    d++;
312
14.9M
                    len -= CHUNKSIZE;
313
14.9M
                } while (len > 0);
314
0
            }
315
414k
        } else
316
2.06M
#endif /* !defined(S_SKEW) */
317
2.06M
        {
318
#ifdef T_SKEW
319
0
            if (t_skew == 0) {
320
0
                do {
321
0
                    FETCH_S;
322
0
                    SPECIFIC_CODE(*d, *d, S, *t++);
323
0
                    d++;
324
0
                    len -= CHUNKSIZE;
325
0
                } while (len > 0);
326
0
            } else
327
0
#endif /* !defined(T_SKEW) */
328
0
            {
329
21.2M
                do {
330
21.2M
                    FETCH_S;
331
21.2M
                    FETCH_T;
332
21.2M
                    SPECIFIC_CODE(*d, *d, S, T);
333
21.2M
                    d++;
334
21.2M
                    len -= CHUNKSIZE;
335
21.2M
                } while (len > 0);
336
0
            }
337
2.06M
        }
338
2.47M
    }
339
    /* Unaligned right hand case */
340
3.51M
    SAFE_FETCH_S(0,skewflags & 4);
341
3.51M
    SAFE_FETCH_T(0,skewflags & 8);
342
3.51M
    SPECIFIC_CODE(D, *d, S, T);
343
3.51M
    *d = (*d & rmask) | (D & ~rmask);
344
3.51M
}
gsroprun.c:notS_rop_run1_const_t
Line
Count
Source
118
48.2k
{
119
#ifndef SPECIFIC_CODE
120
    rop_proc     proc = rop_proc_table[op->rop];
121
#define SPECIFIC_CODE(OUT_, D_,S_,T_) OUT_ = proc(D_,S_,T_)
122
#endif /* !defined(SPECIFIC_CODE) */
123
48.2k
    CHUNK        lmask, rmask;
124
48.2k
#ifdef S_USED
125
#ifdef S_CONST
126
    CHUNK        S = (CHUNK)op->s.c;
127
#else /* !defined(S_CONST) */
128
48.2k
    const CHUNK *s = (CHUNK *)(void *)op->s.b.ptr;
129
48.2k
    CHUNK        S;
130
48.2k
    int          s_skew;
131
48.2k
#endif /* !defined(S_CONST) */
132
#else /* !defined(S_USED) */
133
#define S 0
134
#undef S_CONST
135
#endif /* !defined(S_USED) */
136
#ifdef T_USED
137
#ifdef T_CONST
138
    CHUNK        T = (CHUNK)op->t.c;
139
#else /* !defined(T_CONST) */
140
    const CHUNK *t = (CHUNK *)(void *)op->t.b.ptr;
141
    CHUNK        T;
142
    int          t_skew;
143
#endif /* !defined(T_CONST) */
144
#else /* !defined(T_USED) */
145
48.2k
#define T 0
146
48.2k
#undef T_CONST
147
48.2k
#endif /* !defined(T_USED) */
148
48.2k
#if defined(S_SKEW) || defined(T_SKEW)
149
48.2k
    int skewflags = 0;
150
48.2k
#endif
151
48.2k
    CHUNK        D;
152
48.2k
    int          dpos = op->dpos;
153
48.2k
    CHUNK       *d = (CHUNK *)(void *)d_;
154
155
    /* Align d to CHUNKSIZE */
156
48.2k
    ADJUST_TO_CHUNK(d,dpos);
157
158
    /* On entry len = length in 'depth' chunks. Change it to be the length
159
     * in bits, and add on the number of bits we skip at the start of the
160
     * run. */
161
48.2k
    len    = len * op->depth + dpos;
162
163
    /* lmask = the set of bits to alter in the output bitmap on the left
164
     * hand edge of the run. rmask = the set of bits NOT to alter in the
165
     * output bitmap on the right hand edge of the run. */
166
48.2k
    lmask  = RE((CHUNKONES>>((CHUNKSIZE-1) & dpos)));
167
48.2k
    rmask  = RE((CHUNKONES>>((CHUNKSIZE-1) & len)));
168
48.2k
    if (rmask == CHUNKONES) rmask = 0;
169
170
#if defined(S_CONST) || defined(T_CONST)
171
    /* S and T should be supplied as 'depth' bits. Duplicate them up to be
172
     * byte size (if they are supplied byte sized, that's fine too). */
173
    if (op->depth & 1) {
174
#ifdef S_CONST
175
        S |= S<<1;
176
#endif /* !defined(S_CONST) */
177
#ifdef T_CONST
178
        T |= T<<1;
179
#endif /* !defined(T_CONST) */
180
    }
181
    if (op->depth & 3) {
182
#ifdef S_CONST
183
        S |= S<<2;
184
#endif /* !defined(S_CONST) */
185
#ifdef T_CONST
186
        T |= T<<2;
187
#endif /* !defined(T_CONST) */
188
    }
189
    if (op->depth & 7) {
190
#ifdef S_CONST
191
        S |= S<<4;
192
#endif /* !defined(S_CONST) */
193
#ifdef T_CONST
194
        T |= T<<4;
195
#endif /* !defined(T_CONST) */
196
    }
197
#if CHUNKSIZE > 8
198
    if (op->depth & 15) {
199
#ifdef S_CONST
200
        S |= S<<8;
201
#endif /* !defined(S_CONST) */
202
#ifdef T_CONST
203
        T |= T<<8;
204
#endif /* !defined(T_CONST) */
205
    }
206
#endif /* CHUNKSIZE > 8 */
207
#if CHUNKSIZE > 16
208
    if (op->depth & 31) {
209
#ifdef S_CONST
210
        S |= S<<16;
211
#endif /* !defined(S_CONST) */
212
#ifdef T_CONST
213
        T |= T<<16;
214
#endif /* !defined(T_CONST) */
215
    }
216
#endif /* CHUNKSIZE > 16 */
217
#endif /* defined(S_CONST) || defined(T_CONST) */
218
219
    /* Note #1: This mirrors what the original code did, but I think it has
220
     * the risk of moving s and t back beyond officially allocated space. We
221
     * may be saved by the fact that all blocks have a word or two in front
222
     * of them due to the allocator. If we ever get valgrind properly marking
223
     * allocated blocks as readable etc, then this may throw some spurious
224
     * errors. RJW. */
225
48.2k
#ifdef S_SKEW
226
48.2k
    {
227
48.2k
        int slen, slen2;
228
48.2k
        int spos = op->s.b.pos;
229
48.2k
        ADJUST_TO_CHUNK(s, spos);
230
48.2k
        s_skew = spos - dpos;
231
48.2k
        if (s_skew < 0) {
232
27.8k
            s_skew += CHUNKSIZE;
233
27.8k
            s--;
234
27.8k
            skewflags |= 1; /* Suppress reading off left edge */
235
27.8k
        }
236
        /* We are allowed to read all the data bits, so: len - dpos + tpos
237
         * We're allowed to read in CHUNKS, so: CHUNKUP(len-dpos+tpos).
238
         * This code will actually read CHUNKUP(len)+CHUNKSIZE bits. If
239
         * This is larger, then suppress. */
240
48.2k
        slen  = (len + s_skew    + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
241
48.2k
        slen2 = (len + CHUNKSIZE + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
242
48.2k
        if ((s_skew == 0) || (slen < slen2)) {
243
44.5k
            skewflags |= 4; /* Suppress reading off the right edge */
244
44.5k
        }
245
48.2k
    }
246
48.2k
#endif /* !defined(S_SKEW) */
247
#ifdef T_SKEW
248
    {
249
        int tlen, tlen2;
250
        int tpos = op->t.b.pos;
251
        ADJUST_TO_CHUNK(t, tpos);
252
        t_skew = tpos - dpos;
253
        if (t_skew < 0) {
254
            t_skew += CHUNKSIZE;
255
            t--;
256
            skewflags |= 2; /* Suppress reading off left edge */
257
        }
258
        /* We are allowed to read all the data bits, so: len - dpos + tpos
259
         * We're allowed to read in CHUNKS, so: CHUNKUP(len-dpos+tpos).
260
         * This code will actually read CHUNKUP(len)+CHUNKSIZE bits. If
261
         * This is larger, then suppress. */
262
        tlen  = (len + t_skew    + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
263
        tlen2 = (len + CHUNKSIZE + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
264
        if ((t_skew == 0) || (tlen < tlen2)) {
265
            skewflags |= 8; /* Suppress reading off the right edge */
266
        }
267
    }
268
#endif /* !defined(T_SKEW) */
269
270
48.2k
    len -= CHUNKSIZE; /* len = bytes to do - CHUNKSIZE */
271
    /* len <= 0 means 1 word or less to do */
272
48.2k
    if (len <= 0) {
273
        /* Short case - starts and ends in the same chunk */
274
0
        lmask &= ~rmask; /* Combined mask = bits to alter */
275
0
        SAFE_FETCH_S(skewflags & 1,skewflags & 4);
276
0
        SAFE_FETCH_T(skewflags & 2,skewflags & 8);
277
0
        SPECIFIC_CODE(D, *d, S, T);
278
0
        *d = (*d & ~lmask) | (D & lmask);
279
0
        return;
280
0
    }
281
48.2k
    if ((lmask != CHUNKONES)
282
48.2k
#if defined(S_SKEW) || defined(T_SKEW)
283
48.2k
        || (skewflags & 3)
284
48.2k
#endif
285
48.2k
        ) {
286
        /* Unaligned left hand case */
287
28.6k
        SAFE_FETCH_S(skewflags & 1,s_skew == 0);
288
28.6k
        SAFE_FETCH_T(skewflags & 2,t_skew == 0);
289
28.6k
        SPECIFIC_CODE(D, *d, S, T);
290
28.6k
        *d = (*d & ~lmask) | (D & lmask);
291
28.6k
        d++;
292
28.6k
        len -= CHUNKSIZE;
293
28.6k
    }
294
48.2k
    if (len > 0) {
295
        /* Simple middle case (complete destination chunks). */
296
48.1k
#ifdef S_SKEW
297
48.1k
        if (s_skew == 0) {
298
#ifdef T_SKEW
299
            if (t_skew == 0) {
300
                do {
301
                    SPECIFIC_CODE(*d, *d, *s++, *t++);
302
                    d++;
303
                    len -= CHUNKSIZE;
304
                } while (len > 0);
305
            } else
306
#endif /* !defined(T_SKEW) */
307
20.0k
            {
308
966k
                do {
309
966k
                    FETCH_T;
310
966k
                    SPECIFIC_CODE(*d, *d, *s++, T);
311
966k
                    d++;
312
966k
                    len -= CHUNKSIZE;
313
966k
                } while (len > 0);
314
20.0k
            }
315
20.0k
        } else
316
28.1k
#endif /* !defined(S_SKEW) */
317
28.1k
        {
318
#ifdef T_SKEW
319
            if (t_skew == 0) {
320
                do {
321
                    FETCH_S;
322
                    SPECIFIC_CODE(*d, *d, S, *t++);
323
                    d++;
324
                    len -= CHUNKSIZE;
325
                } while (len > 0);
326
            } else
327
#endif /* !defined(T_SKEW) */
328
28.1k
            {
329
274k
                do {
330
274k
                    FETCH_S;
331
274k
                    FETCH_T;
332
274k
                    SPECIFIC_CODE(*d, *d, S, T);
333
274k
                    d++;
334
274k
                    len -= CHUNKSIZE;
335
274k
                } while (len > 0);
336
28.1k
            }
337
28.1k
        }
338
48.1k
    }
339
    /* Unaligned right hand case */
340
48.2k
    SAFE_FETCH_S(0,skewflags & 4);
341
48.2k
    SAFE_FETCH_T(0,skewflags & 8);
342
48.2k
    SPECIFIC_CODE(D, *d, S, T);
343
48.2k
    *d = (*d & rmask) | (D & ~rmask);
344
48.2k
}
Unexecuted instantiation: gsroprun.c:invert_rop_run1
Unexecuted instantiation: gsroprun.c:xor_rop_run1_const_t
gsroprun.c:sets_rop_run1
Line
Count
Source
118
2.15M
{
119
#ifndef SPECIFIC_CODE
120
    rop_proc     proc = rop_proc_table[op->rop];
121
#define SPECIFIC_CODE(OUT_, D_,S_,T_) OUT_ = proc(D_,S_,T_)
122
#endif /* !defined(SPECIFIC_CODE) */
123
2.15M
    CHUNK        lmask, rmask;
124
2.15M
#ifdef S_USED
125
#ifdef S_CONST
126
    CHUNK        S = (CHUNK)op->s.c;
127
#else /* !defined(S_CONST) */
128
2.15M
    const CHUNK *s = (CHUNK *)(void *)op->s.b.ptr;
129
2.15M
    CHUNK        S;
130
2.15M
    int          s_skew;
131
2.15M
#endif /* !defined(S_CONST) */
132
#else /* !defined(S_USED) */
133
#define S 0
134
#undef S_CONST
135
#endif /* !defined(S_USED) */
136
#ifdef T_USED
137
#ifdef T_CONST
138
    CHUNK        T = (CHUNK)op->t.c;
139
#else /* !defined(T_CONST) */
140
    const CHUNK *t = (CHUNK *)(void *)op->t.b.ptr;
141
    CHUNK        T;
142
    int          t_skew;
143
#endif /* !defined(T_CONST) */
144
#else /* !defined(T_USED) */
145
2.15M
#define T 0
146
2.15M
#undef T_CONST
147
2.15M
#endif /* !defined(T_USED) */
148
2.15M
#if defined(S_SKEW) || defined(T_SKEW)
149
2.15M
    int skewflags = 0;
150
2.15M
#endif
151
2.15M
    CHUNK        D;
152
2.15M
    int          dpos = op->dpos;
153
2.15M
    CHUNK       *d = (CHUNK *)(void *)d_;
154
155
    /* Align d to CHUNKSIZE */
156
2.15M
    ADJUST_TO_CHUNK(d,dpos);
157
158
    /* On entry len = length in 'depth' chunks. Change it to be the length
159
     * in bits, and add on the number of bits we skip at the start of the
160
     * run. */
161
2.15M
    len    = len * op->depth + dpos;
162
163
    /* lmask = the set of bits to alter in the output bitmap on the left
164
     * hand edge of the run. rmask = the set of bits NOT to alter in the
165
     * output bitmap on the right hand edge of the run. */
166
2.15M
    lmask  = RE((CHUNKONES>>((CHUNKSIZE-1) & dpos)));
167
2.15M
    rmask  = RE((CHUNKONES>>((CHUNKSIZE-1) & len)));
168
2.15M
    if (rmask == CHUNKONES) rmask = 0;
169
170
#if defined(S_CONST) || defined(T_CONST)
171
    /* S and T should be supplied as 'depth' bits. Duplicate them up to be
172
     * byte size (if they are supplied byte sized, that's fine too). */
173
    if (op->depth & 1) {
174
#ifdef S_CONST
175
        S |= S<<1;
176
#endif /* !defined(S_CONST) */
177
#ifdef T_CONST
178
        T |= T<<1;
179
#endif /* !defined(T_CONST) */
180
    }
181
    if (op->depth & 3) {
182
#ifdef S_CONST
183
        S |= S<<2;
184
#endif /* !defined(S_CONST) */
185
#ifdef T_CONST
186
        T |= T<<2;
187
#endif /* !defined(T_CONST) */
188
    }
189
    if (op->depth & 7) {
190
#ifdef S_CONST
191
        S |= S<<4;
192
#endif /* !defined(S_CONST) */
193
#ifdef T_CONST
194
        T |= T<<4;
195
#endif /* !defined(T_CONST) */
196
    }
197
#if CHUNKSIZE > 8
198
    if (op->depth & 15) {
199
#ifdef S_CONST
200
        S |= S<<8;
201
#endif /* !defined(S_CONST) */
202
#ifdef T_CONST
203
        T |= T<<8;
204
#endif /* !defined(T_CONST) */
205
    }
206
#endif /* CHUNKSIZE > 8 */
207
#if CHUNKSIZE > 16
208
    if (op->depth & 31) {
209
#ifdef S_CONST
210
        S |= S<<16;
211
#endif /* !defined(S_CONST) */
212
#ifdef T_CONST
213
        T |= T<<16;
214
#endif /* !defined(T_CONST) */
215
    }
216
#endif /* CHUNKSIZE > 16 */
217
#endif /* defined(S_CONST) || defined(T_CONST) */
218
219
    /* Note #1: This mirrors what the original code did, but I think it has
220
     * the risk of moving s and t back beyond officially allocated space. We
221
     * may be saved by the fact that all blocks have a word or two in front
222
     * of them due to the allocator. If we ever get valgrind properly marking
223
     * allocated blocks as readable etc, then this may throw some spurious
224
     * errors. RJW. */
225
2.15M
#ifdef S_SKEW
226
2.15M
    {
227
2.15M
        int slen, slen2;
228
2.15M
        int spos = op->s.b.pos;
229
2.15M
        ADJUST_TO_CHUNK(s, spos);
230
2.15M
        s_skew = spos - dpos;
231
2.15M
        if (s_skew < 0) {
232
1.36M
            s_skew += CHUNKSIZE;
233
1.36M
            s--;
234
1.36M
            skewflags |= 1; /* Suppress reading off left edge */
235
1.36M
        }
236
        /* We are allowed to read all the data bits, so: len - dpos + tpos
237
         * We're allowed to read in CHUNKS, so: CHUNKUP(len-dpos+tpos).
238
         * This code will actually read CHUNKUP(len)+CHUNKSIZE bits. If
239
         * This is larger, then suppress. */
240
2.15M
        slen  = (len + s_skew    + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
241
2.15M
        slen2 = (len + CHUNKSIZE + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
242
2.15M
        if ((s_skew == 0) || (slen < slen2)) {
243
1.02M
            skewflags |= 4; /* Suppress reading off the right edge */
244
1.02M
        }
245
2.15M
    }
246
2.15M
#endif /* !defined(S_SKEW) */
247
#ifdef T_SKEW
248
    {
249
        int tlen, tlen2;
250
        int tpos = op->t.b.pos;
251
        ADJUST_TO_CHUNK(t, tpos);
252
        t_skew = tpos - dpos;
253
        if (t_skew < 0) {
254
            t_skew += CHUNKSIZE;
255
            t--;
256
            skewflags |= 2; /* Suppress reading off left edge */
257
        }
258
        /* We are allowed to read all the data bits, so: len - dpos + tpos
259
         * We're allowed to read in CHUNKS, so: CHUNKUP(len-dpos+tpos).
260
         * This code will actually read CHUNKUP(len)+CHUNKSIZE bits. If
261
         * This is larger, then suppress. */
262
        tlen  = (len + t_skew    + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
263
        tlen2 = (len + CHUNKSIZE + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
264
        if ((t_skew == 0) || (tlen < tlen2)) {
265
            skewflags |= 8; /* Suppress reading off the right edge */
266
        }
267
    }
268
#endif /* !defined(T_SKEW) */
269
270
2.15M
    len -= CHUNKSIZE; /* len = bytes to do - CHUNKSIZE */
271
    /* len <= 0 means 1 word or less to do */
272
2.15M
    if (len <= 0) {
273
        /* Short case - starts and ends in the same chunk */
274
211
        lmask &= ~rmask; /* Combined mask = bits to alter */
275
211
        SAFE_FETCH_S(skewflags & 1,skewflags & 4);
276
211
        SAFE_FETCH_T(skewflags & 2,skewflags & 8);
277
211
        SPECIFIC_CODE(D, *d, S, T);
278
211
        *d = (*d & ~lmask) | (D & lmask);
279
211
        return;
280
211
    }
281
2.15M
    if ((lmask != CHUNKONES)
282
2.15M
#if defined(S_SKEW) || defined(T_SKEW)
283
2.15M
        || (skewflags & 3)
284
2.15M
#endif
285
2.15M
        ) {
286
        /* Unaligned left hand case */
287
1.66M
        SAFE_FETCH_S(skewflags & 1,s_skew == 0);
288
1.66M
        SAFE_FETCH_T(skewflags & 2,t_skew == 0);
289
1.66M
        SPECIFIC_CODE(D, *d, S, T);
290
1.66M
        *d = (*d & ~lmask) | (D & lmask);
291
1.66M
        d++;
292
1.66M
        len -= CHUNKSIZE;
293
1.66M
    }
294
2.15M
    if (len > 0) {
295
        /* Simple middle case (complete destination chunks). */
296
1.68M
#ifdef S_SKEW
297
1.68M
        if (s_skew == 0) {
298
#ifdef T_SKEW
299
            if (t_skew == 0) {
300
                do {
301
                    SPECIFIC_CODE(*d, *d, *s++, *t++);
302
                    d++;
303
                    len -= CHUNKSIZE;
304
                } while (len > 0);
305
            } else
306
#endif /* !defined(T_SKEW) */
307
348k
            {
308
13.5M
                do {
309
13.5M
                    FETCH_T;
310
13.5M
                    SPECIFIC_CODE(*d, *d, *s++, T);
311
13.5M
                    d++;
312
13.5M
                    len -= CHUNKSIZE;
313
13.5M
                } while (len > 0);
314
348k
            }
315
348k
        } else
316
1.33M
#endif /* !defined(S_SKEW) */
317
1.33M
        {
318
#ifdef T_SKEW
319
            if (t_skew == 0) {
320
                do {
321
                    FETCH_S;
322
                    SPECIFIC_CODE(*d, *d, S, *t++);
323
                    d++;
324
                    len -= CHUNKSIZE;
325
                } while (len > 0);
326
            } else
327
#endif /* !defined(T_SKEW) */
328
1.33M
            {
329
19.1M
                do {
330
19.1M
                    FETCH_S;
331
19.1M
                    FETCH_T;
332
19.1M
                    SPECIFIC_CODE(*d, *d, S, T);
333
19.1M
                    d++;
334
19.1M
                    len -= CHUNKSIZE;
335
19.1M
                } while (len > 0);
336
1.33M
            }
337
1.33M
        }
338
1.68M
    }
339
    /* Unaligned right hand case */
340
2.15M
    SAFE_FETCH_S(0,skewflags & 4);
341
2.15M
    SAFE_FETCH_T(0,skewflags & 8);
342
2.15M
    SPECIFIC_CODE(D, *d, S, T);
343
2.15M
    *d = (*d & rmask) | (D & ~rmask);
344
2.15M
}
gsroprun.c:dors_rop_run1_const_t
Line
Count
Source
118
1.27M
{
119
#ifndef SPECIFIC_CODE
120
    rop_proc     proc = rop_proc_table[op->rop];
121
#define SPECIFIC_CODE(OUT_, D_,S_,T_) OUT_ = proc(D_,S_,T_)
122
#endif /* !defined(SPECIFIC_CODE) */
123
1.27M
    CHUNK        lmask, rmask;
124
1.27M
#ifdef S_USED
125
#ifdef S_CONST
126
    CHUNK        S = (CHUNK)op->s.c;
127
#else /* !defined(S_CONST) */
128
1.27M
    const CHUNK *s = (CHUNK *)(void *)op->s.b.ptr;
129
1.27M
    CHUNK        S;
130
1.27M
    int          s_skew;
131
1.27M
#endif /* !defined(S_CONST) */
132
#else /* !defined(S_USED) */
133
#define S 0
134
#undef S_CONST
135
#endif /* !defined(S_USED) */
136
#ifdef T_USED
137
#ifdef T_CONST
138
    CHUNK        T = (CHUNK)op->t.c;
139
#else /* !defined(T_CONST) */
140
    const CHUNK *t = (CHUNK *)(void *)op->t.b.ptr;
141
    CHUNK        T;
142
    int          t_skew;
143
#endif /* !defined(T_CONST) */
144
#else /* !defined(T_USED) */
145
1.27M
#define T 0
146
1.27M
#undef T_CONST
147
1.27M
#endif /* !defined(T_USED) */
148
1.27M
#if defined(S_SKEW) || defined(T_SKEW)
149
1.27M
    int skewflags = 0;
150
1.27M
#endif
151
1.27M
    CHUNK        D;
152
1.27M
    int          dpos = op->dpos;
153
1.27M
    CHUNK       *d = (CHUNK *)(void *)d_;
154
155
    /* Align d to CHUNKSIZE */
156
1.27M
    ADJUST_TO_CHUNK(d,dpos);
157
158
    /* On entry len = length in 'depth' chunks. Change it to be the length
159
     * in bits, and add on the number of bits we skip at the start of the
160
     * run. */
161
1.27M
    len    = len * op->depth + dpos;
162
163
    /* lmask = the set of bits to alter in the output bitmap on the left
164
     * hand edge of the run. rmask = the set of bits NOT to alter in the
165
     * output bitmap on the right hand edge of the run. */
166
1.27M
    lmask  = RE((CHUNKONES>>((CHUNKSIZE-1) & dpos)));
167
1.27M
    rmask  = RE((CHUNKONES>>((CHUNKSIZE-1) & len)));
168
1.27M
    if (rmask == CHUNKONES) rmask = 0;
169
170
#if defined(S_CONST) || defined(T_CONST)
171
    /* S and T should be supplied as 'depth' bits. Duplicate them up to be
172
     * byte size (if they are supplied byte sized, that's fine too). */
173
    if (op->depth & 1) {
174
#ifdef S_CONST
175
        S |= S<<1;
176
#endif /* !defined(S_CONST) */
177
#ifdef T_CONST
178
        T |= T<<1;
179
#endif /* !defined(T_CONST) */
180
    }
181
    if (op->depth & 3) {
182
#ifdef S_CONST
183
        S |= S<<2;
184
#endif /* !defined(S_CONST) */
185
#ifdef T_CONST
186
        T |= T<<2;
187
#endif /* !defined(T_CONST) */
188
    }
189
    if (op->depth & 7) {
190
#ifdef S_CONST
191
        S |= S<<4;
192
#endif /* !defined(S_CONST) */
193
#ifdef T_CONST
194
        T |= T<<4;
195
#endif /* !defined(T_CONST) */
196
    }
197
#if CHUNKSIZE > 8
198
    if (op->depth & 15) {
199
#ifdef S_CONST
200
        S |= S<<8;
201
#endif /* !defined(S_CONST) */
202
#ifdef T_CONST
203
        T |= T<<8;
204
#endif /* !defined(T_CONST) */
205
    }
206
#endif /* CHUNKSIZE > 8 */
207
#if CHUNKSIZE > 16
208
    if (op->depth & 31) {
209
#ifdef S_CONST
210
        S |= S<<16;
211
#endif /* !defined(S_CONST) */
212
#ifdef T_CONST
213
        T |= T<<16;
214
#endif /* !defined(T_CONST) */
215
    }
216
#endif /* CHUNKSIZE > 16 */
217
#endif /* defined(S_CONST) || defined(T_CONST) */
218
219
    /* Note #1: This mirrors what the original code did, but I think it has
220
     * the risk of moving s and t back beyond officially allocated space. We
221
     * may be saved by the fact that all blocks have a word or two in front
222
     * of them due to the allocator. If we ever get valgrind properly marking
223
     * allocated blocks as readable etc, then this may throw some spurious
224
     * errors. RJW. */
225
1.27M
#ifdef S_SKEW
226
1.27M
    {
227
1.27M
        int slen, slen2;
228
1.27M
        int spos = op->s.b.pos;
229
1.27M
        ADJUST_TO_CHUNK(s, spos);
230
1.27M
        s_skew = spos - dpos;
231
1.27M
        if (s_skew < 0) {
232
1.18M
            s_skew += CHUNKSIZE;
233
1.18M
            s--;
234
1.18M
            skewflags |= 1; /* Suppress reading off left edge */
235
1.18M
        }
236
        /* We are allowed to read all the data bits, so: len - dpos + tpos
237
         * We're allowed to read in CHUNKS, so: CHUNKUP(len-dpos+tpos).
238
         * This code will actually read CHUNKUP(len)+CHUNKSIZE bits. If
239
         * This is larger, then suppress. */
240
1.27M
        slen  = (len + s_skew    + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
241
1.27M
        slen2 = (len + CHUNKSIZE + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
242
1.27M
        if ((s_skew == 0) || (slen < slen2)) {
243
585k
            skewflags |= 4; /* Suppress reading off the right edge */
244
585k
        }
245
1.27M
    }
246
1.27M
#endif /* !defined(S_SKEW) */
247
#ifdef T_SKEW
248
    {
249
        int tlen, tlen2;
250
        int tpos = op->t.b.pos;
251
        ADJUST_TO_CHUNK(t, tpos);
252
        t_skew = tpos - dpos;
253
        if (t_skew < 0) {
254
            t_skew += CHUNKSIZE;
255
            t--;
256
            skewflags |= 2; /* Suppress reading off left edge */
257
        }
258
        /* We are allowed to read all the data bits, so: len - dpos + tpos
259
         * We're allowed to read in CHUNKS, so: CHUNKUP(len-dpos+tpos).
260
         * This code will actually read CHUNKUP(len)+CHUNKSIZE bits. If
261
         * This is larger, then suppress. */
262
        tlen  = (len + t_skew    + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
263
        tlen2 = (len + CHUNKSIZE + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
264
        if ((t_skew == 0) || (tlen < tlen2)) {
265
            skewflags |= 8; /* Suppress reading off the right edge */
266
        }
267
    }
268
#endif /* !defined(T_SKEW) */
269
270
1.27M
    len -= CHUNKSIZE; /* len = bytes to do - CHUNKSIZE */
271
    /* len <= 0 means 1 word or less to do */
272
1.27M
    if (len <= 0) {
273
        /* Short case - starts and ends in the same chunk */
274
5.01k
        lmask &= ~rmask; /* Combined mask = bits to alter */
275
5.01k
        SAFE_FETCH_S(skewflags & 1,skewflags & 4);
276
5.01k
        SAFE_FETCH_T(skewflags & 2,skewflags & 8);
277
5.01k
        SPECIFIC_CODE(D, *d, S, T);
278
5.01k
        *d = (*d & ~lmask) | (D & lmask);
279
5.01k
        return;
280
5.01k
    }
281
1.27M
    if ((lmask != CHUNKONES)
282
1.27M
#if defined(S_SKEW) || defined(T_SKEW)
283
1.27M
        || (skewflags & 3)
284
1.27M
#endif
285
1.27M
        ) {
286
        /* Unaligned left hand case */
287
1.19M
        SAFE_FETCH_S(skewflags & 1,s_skew == 0);
288
1.19M
        SAFE_FETCH_T(skewflags & 2,t_skew == 0);
289
1.19M
        SPECIFIC_CODE(D, *d, S, T);
290
1.19M
        *d = (*d & ~lmask) | (D & lmask);
291
1.19M
        d++;
292
1.19M
        len -= CHUNKSIZE;
293
1.19M
    }
294
1.27M
    if (len > 0) {
295
        /* Simple middle case (complete destination chunks). */
296
722k
#ifdef S_SKEW
297
722k
        if (s_skew == 0) {
298
#ifdef T_SKEW
299
            if (t_skew == 0) {
300
                do {
301
                    SPECIFIC_CODE(*d, *d, *s++, *t++);
302
                    d++;
303
                    len -= CHUNKSIZE;
304
                } while (len > 0);
305
            } else
306
#endif /* !defined(T_SKEW) */
307
35.0k
            {
308
79.2k
                do {
309
79.2k
                    FETCH_T;
310
79.2k
                    SPECIFIC_CODE(*d, *d, *s++, T);
311
79.2k
                    d++;
312
79.2k
                    len -= CHUNKSIZE;
313
79.2k
                } while (len > 0);
314
35.0k
            }
315
35.0k
        } else
316
687k
#endif /* !defined(S_SKEW) */
317
687k
        {
318
#ifdef T_SKEW
319
            if (t_skew == 0) {
320
                do {
321
                    FETCH_S;
322
                    SPECIFIC_CODE(*d, *d, S, *t++);
323
                    d++;
324
                    len -= CHUNKSIZE;
325
                } while (len > 0);
326
            } else
327
#endif /* !defined(T_SKEW) */
328
687k
            {
329
1.83M
                do {
330
1.83M
                    FETCH_S;
331
1.83M
                    FETCH_T;
332
1.83M
                    SPECIFIC_CODE(*d, *d, S, T);
333
1.83M
                    d++;
334
1.83M
                    len -= CHUNKSIZE;
335
1.83M
                } while (len > 0);
336
687k
            }
337
687k
        }
338
722k
    }
339
    /* Unaligned right hand case */
340
1.27M
    SAFE_FETCH_S(0,skewflags & 4);
341
1.27M
    SAFE_FETCH_T(0,skewflags & 8);
342
1.27M
    SPECIFIC_CODE(D, *d, S, T);
343
1.27M
    *d = (*d & rmask) | (D & ~rmask);
344
1.27M
}
Unexecuted instantiation: gsroprun.c:generic_rop_run1
gsroprun.c:generic_rop_run1_const_t
Line
Count
Source
118
32.9k
{
119
32.9k
#ifndef SPECIFIC_CODE
120
32.9k
    rop_proc     proc = rop_proc_table[op->rop];
121
32.9k
#define SPECIFIC_CODE(OUT_, D_,S_,T_) OUT_ = proc(D_,S_,T_)
122
32.9k
#endif /* !defined(SPECIFIC_CODE) */
123
32.9k
    CHUNK        lmask, rmask;
124
32.9k
#ifdef S_USED
125
#ifdef S_CONST
126
    CHUNK        S = (CHUNK)op->s.c;
127
#else /* !defined(S_CONST) */
128
32.9k
    const CHUNK *s = (CHUNK *)(void *)op->s.b.ptr;
129
32.9k
    CHUNK        S;
130
32.9k
    int          s_skew;
131
32.9k
#endif /* !defined(S_CONST) */
132
#else /* !defined(S_USED) */
133
#define S 0
134
#undef S_CONST
135
#endif /* !defined(S_USED) */
136
32.9k
#ifdef T_USED
137
32.9k
#ifdef T_CONST
138
32.9k
    CHUNK        T = (CHUNK)op->t.c;
139
#else /* !defined(T_CONST) */
140
    const CHUNK *t = (CHUNK *)(void *)op->t.b.ptr;
141
    CHUNK        T;
142
    int          t_skew;
143
#endif /* !defined(T_CONST) */
144
#else /* !defined(T_USED) */
145
#define T 0
146
#undef T_CONST
147
#endif /* !defined(T_USED) */
148
32.9k
#if defined(S_SKEW) || defined(T_SKEW)
149
32.9k
    int skewflags = 0;
150
32.9k
#endif
151
32.9k
    CHUNK        D;
152
32.9k
    int          dpos = op->dpos;
153
32.9k
    CHUNK       *d = (CHUNK *)(void *)d_;
154
155
    /* Align d to CHUNKSIZE */
156
32.9k
    ADJUST_TO_CHUNK(d,dpos);
157
158
    /* On entry len = length in 'depth' chunks. Change it to be the length
159
     * in bits, and add on the number of bits we skip at the start of the
160
     * run. */
161
32.9k
    len    = len * op->depth + dpos;
162
163
    /* lmask = the set of bits to alter in the output bitmap on the left
164
     * hand edge of the run. rmask = the set of bits NOT to alter in the
165
     * output bitmap on the right hand edge of the run. */
166
32.9k
    lmask  = RE((CHUNKONES>>((CHUNKSIZE-1) & dpos)));
167
32.9k
    rmask  = RE((CHUNKONES>>((CHUNKSIZE-1) & len)));
168
32.9k
    if (rmask == CHUNKONES) rmask = 0;
169
170
32.9k
#if defined(S_CONST) || defined(T_CONST)
171
    /* S and T should be supplied as 'depth' bits. Duplicate them up to be
172
     * byte size (if they are supplied byte sized, that's fine too). */
173
32.9k
    if (op->depth & 1) {
174
#ifdef S_CONST
175
        S |= S<<1;
176
#endif /* !defined(S_CONST) */
177
32.9k
#ifdef T_CONST
178
32.9k
        T |= T<<1;
179
32.9k
#endif /* !defined(T_CONST) */
180
32.9k
    }
181
32.9k
    if (op->depth & 3) {
182
#ifdef S_CONST
183
        S |= S<<2;
184
#endif /* !defined(S_CONST) */
185
32.9k
#ifdef T_CONST
186
32.9k
        T |= T<<2;
187
32.9k
#endif /* !defined(T_CONST) */
188
32.9k
    }
189
32.9k
    if (op->depth & 7) {
190
#ifdef S_CONST
191
        S |= S<<4;
192
#endif /* !defined(S_CONST) */
193
32.9k
#ifdef T_CONST
194
32.9k
        T |= T<<4;
195
32.9k
#endif /* !defined(T_CONST) */
196
32.9k
    }
197
32.9k
#if CHUNKSIZE > 8
198
32.9k
    if (op->depth & 15) {
199
#ifdef S_CONST
200
        S |= S<<8;
201
#endif /* !defined(S_CONST) */
202
32.9k
#ifdef T_CONST
203
32.9k
        T |= T<<8;
204
32.9k
#endif /* !defined(T_CONST) */
205
32.9k
    }
206
32.9k
#endif /* CHUNKSIZE > 8 */
207
32.9k
#if CHUNKSIZE > 16
208
32.9k
    if (op->depth & 31) {
209
#ifdef S_CONST
210
        S |= S<<16;
211
#endif /* !defined(S_CONST) */
212
32.9k
#ifdef T_CONST
213
32.9k
        T |= T<<16;
214
32.9k
#endif /* !defined(T_CONST) */
215
32.9k
    }
216
32.9k
#endif /* CHUNKSIZE > 16 */
217
32.9k
#endif /* defined(S_CONST) || defined(T_CONST) */
218
219
    /* Note #1: This mirrors what the original code did, but I think it has
220
     * the risk of moving s and t back beyond officially allocated space. We
221
     * may be saved by the fact that all blocks have a word or two in front
222
     * of them due to the allocator. If we ever get valgrind properly marking
223
     * allocated blocks as readable etc, then this may throw some spurious
224
     * errors. RJW. */
225
32.9k
#ifdef S_SKEW
226
32.9k
    {
227
32.9k
        int slen, slen2;
228
32.9k
        int spos = op->s.b.pos;
229
32.9k
        ADJUST_TO_CHUNK(s, spos);
230
32.9k
        s_skew = spos - dpos;
231
32.9k
        if (s_skew < 0) {
232
20.9k
            s_skew += CHUNKSIZE;
233
20.9k
            s--;
234
20.9k
            skewflags |= 1; /* Suppress reading off left edge */
235
20.9k
        }
236
        /* We are allowed to read all the data bits, so: len - dpos + tpos
237
         * We're allowed to read in CHUNKS, so: CHUNKUP(len-dpos+tpos).
238
         * This code will actually read CHUNKUP(len)+CHUNKSIZE bits. If
239
         * This is larger, then suppress. */
240
32.9k
        slen  = (len + s_skew    + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
241
32.9k
        slen2 = (len + CHUNKSIZE + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
242
32.9k
        if ((s_skew == 0) || (slen < slen2)) {
243
23.1k
            skewflags |= 4; /* Suppress reading off the right edge */
244
23.1k
        }
245
32.9k
    }
246
32.9k
#endif /* !defined(S_SKEW) */
247
#ifdef T_SKEW
248
    {
249
        int tlen, tlen2;
250
        int tpos = op->t.b.pos;
251
        ADJUST_TO_CHUNK(t, tpos);
252
        t_skew = tpos - dpos;
253
        if (t_skew < 0) {
254
            t_skew += CHUNKSIZE;
255
            t--;
256
            skewflags |= 2; /* Suppress reading off left edge */
257
        }
258
        /* We are allowed to read all the data bits, so: len - dpos + tpos
259
         * We're allowed to read in CHUNKS, so: CHUNKUP(len-dpos+tpos).
260
         * This code will actually read CHUNKUP(len)+CHUNKSIZE bits. If
261
         * This is larger, then suppress. */
262
        tlen  = (len + t_skew    + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
263
        tlen2 = (len + CHUNKSIZE + CHUNKSIZE-1) & ~(CHUNKSIZE-1);
264
        if ((t_skew == 0) || (tlen < tlen2)) {
265
            skewflags |= 8; /* Suppress reading off the right edge */
266
        }
267
    }
268
#endif /* !defined(T_SKEW) */
269
270
32.9k
    len -= CHUNKSIZE; /* len = bytes to do - CHUNKSIZE */
271
    /* len <= 0 means 1 word or less to do */
272
32.9k
    if (len <= 0) {
273
        /* Short case - starts and ends in the same chunk */
274
0
        lmask &= ~rmask; /* Combined mask = bits to alter */
275
0
        SAFE_FETCH_S(skewflags & 1,skewflags & 4);
276
0
        SAFE_FETCH_T(skewflags & 2,skewflags & 8);
277
0
        SPECIFIC_CODE(D, *d, S, T);
278
0
        *d = (*d & ~lmask) | (D & lmask);
279
0
        return;
280
0
    }
281
32.9k
    if ((lmask != CHUNKONES)
282
32.9k
#if defined(S_SKEW) || defined(T_SKEW)
283
32.9k
        || (skewflags & 3)
284
32.9k
#endif
285
32.9k
        ) {
286
        /* Unaligned left hand case */
287
24.7k
        SAFE_FETCH_S(skewflags & 1,s_skew == 0);
288
24.7k
        SAFE_FETCH_T(skewflags & 2,t_skew == 0);
289
24.7k
        SPECIFIC_CODE(D, *d, S, T);
290
24.7k
        *d = (*d & ~lmask) | (D & lmask);
291
24.7k
        d++;
292
24.7k
        len -= CHUNKSIZE;
293
24.7k
    }
294
32.9k
    if (len > 0) {
295
        /* Simple middle case (complete destination chunks). */
296
19.9k
#ifdef S_SKEW
297
19.9k
        if (s_skew == 0) {
298
#ifdef T_SKEW
299
            if (t_skew == 0) {
300
                do {
301
                    SPECIFIC_CODE(*d, *d, *s++, *t++);
302
                    d++;
303
                    len -= CHUNKSIZE;
304
                } while (len > 0);
305
            } else
306
#endif /* !defined(T_SKEW) */
307
11.8k
            {
308
336k
                do {
309
336k
                    FETCH_T;
310
336k
                    SPECIFIC_CODE(*d, *d, *s++, T);
311
336k
                    d++;
312
336k
                    len -= CHUNKSIZE;
313
336k
                } while (len > 0);
314
11.8k
            }
315
11.8k
        } else
316
8.09k
#endif /* !defined(S_SKEW) */
317
8.09k
        {
318
#ifdef T_SKEW
319
            if (t_skew == 0) {
320
                do {
321
                    FETCH_S;
322
                    SPECIFIC_CODE(*d, *d, S, *t++);
323
                    d++;
324
                    len -= CHUNKSIZE;
325
                } while (len > 0);
326
            } else
327
#endif /* !defined(T_SKEW) */
328
8.09k
            {
329
40.3k
                do {
330
40.3k
                    FETCH_S;
331
40.3k
                    FETCH_T;
332
40.3k
                    SPECIFIC_CODE(*d, *d, S, T);
333
40.3k
                    d++;
334
40.3k
                    len -= CHUNKSIZE;
335
40.3k
                } while (len > 0);
336
8.09k
            }
337
8.09k
        }
338
19.9k
    }
339
    /* Unaligned right hand case */
340
32.9k
    SAFE_FETCH_S(0,skewflags & 4);
341
32.9k
    SAFE_FETCH_T(0,skewflags & 8);
342
32.9k
    SPECIFIC_CODE(D, *d, S, T);
343
32.9k
    *d = (*d & rmask) | (D & ~rmask);
344
32.9k
}
Unexecuted instantiation: gsroprun.c:generic_rop_run1_const_st
345
346
#undef ADJUST_TO_CHUNK
347
#undef CHUNKSIZE
348
#undef CHUNK
349
#undef CHUNKONES
350
#undef FETCH_S
351
#undef FETCH_T
352
#undef SAFE_FETCH_S
353
#undef SAFE_FETCH_T
354
#undef RE
355
#undef S
356
#undef S_USED
357
#undef S_CONST
358
#undef S_SKEW
359
#undef SKEW_FETCH
360
#undef SAFE_SKEW_FETCH
361
#undef SPECIFIC_CODE
362
#undef SPECIFIC_ROP
363
#undef T
364
#undef T_USED
365
#undef T_CONST
366
#undef T_SKEW
367
#undef TEMPLATE_NAME
368
#undef ROP_PTRDIFF_T
369
370
#else
371
int dummy;
372
#endif