~ubuntu-branches/ubuntu/feisty/avidemux/feisty

« back to all changes in this revision

Viewing changes to adm_lavcodec/ppc/dsputil_altivec.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel T Chen
  • Date: 2006-12-15 17:13:20 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20061215171320-w79pvpehxx2fr217
Tags: 1:2.3.0-0.0ubuntu1
* Merge from debian-multimedia.org, remaining Ubuntu change:
  - desktop file,
  - no support for ccache and make -j.
* Closes Ubuntu: #69614.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (c) 2002 Brian Foley
3
 
 * Copyright (c) 2002 Dieter Shirley
4
 
 * Copyright (c) 2003-2004 Romain Dolbeau <romain@dolbeau.org>
5
 
 *
6
 
 * This library is free software; you can redistribute it and/or
7
 
 * modify it under the terms of the GNU Lesser General Public
8
 
 * License as published by the Free Software Foundation; either
9
 
 * version 2 of the License, or (at your option) any later version.
10
 
 *
11
 
 * This library is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 
 * Lesser General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU Lesser General Public
17
 
 * License along with this library; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 */
20
 
 
21
 
#include "../dsputil.h"
22
 
 
23
 
#include "gcc_fixes.h"
24
 
 
25
 
#include "dsputil_altivec.h"
26
 
 
27
 
#ifdef CONFIG_DARWIN
28
 
#include <sys/sysctl.h>
29
 
#else /* CONFIG_DARWIN */
30
 
#ifdef __AMIGAOS4__
31
 
#include <exec/exec.h>
32
 
#include <interfaces/exec.h>
33
 
#include <proto/exec.h>
34
 
#else /* __AMIGAOS4__ */
35
 
#include <signal.h>
36
 
#include <setjmp.h>
37
 
 
38
 
static sigjmp_buf jmpbuf;
39
 
static volatile sig_atomic_t canjump = 0;
40
 
 
41
 
static void sigill_handler (int sig)
42
 
{
43
 
    if (!canjump) {
44
 
        signal (sig, SIG_DFL);
45
 
        raise (sig);
46
 
    }
47
 
 
48
 
    canjump = 0;
49
 
    siglongjmp (jmpbuf, 1);
50
 
}
51
 
#endif /* CONFIG_DARWIN */
52
 
#endif /* __AMIGAOS4__ */
53
 
 
54
 
int sad16_x2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
55
 
{
56
 
    int i;
57
 
    int s __attribute__((aligned(16)));
58
 
    const_vector unsigned char zero = (const_vector unsigned char)vec_splat_u8(0);
59
 
    vector unsigned char *tv;
60
 
    vector unsigned char pix1v, pix2v, pix2iv, avgv, t5;
61
 
    vector unsigned int sad;
62
 
    vector signed int sumdiffs;
63
 
 
64
 
    s = 0;
65
 
    sad = (vector unsigned int)vec_splat_u32(0);
66
 
    for(i=0;i<h;i++) {
67
 
        /*
68
 
           Read unaligned pixels into our vectors. The vectors are as follows:
69
 
           pix1v: pix1[0]-pix1[15]
70
 
           pix2v: pix2[0]-pix2[15]      pix2iv: pix2[1]-pix2[16]
71
 
        */
72
 
        tv = (vector unsigned char *) pix1;
73
 
        pix1v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix1));
74
 
 
75
 
        tv = (vector unsigned char *) &pix2[0];
76
 
        pix2v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[0]));
77
 
 
78
 
        tv = (vector unsigned char *) &pix2[1];
79
 
        pix2iv = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[1]));
80
 
 
81
 
        /* Calculate the average vector */
82
 
        avgv = vec_avg(pix2v, pix2iv);
83
 
 
84
 
        /* Calculate a sum of abs differences vector */
85
 
        t5 = vec_sub(vec_max(pix1v, avgv), vec_min(pix1v, avgv));
86
 
 
87
 
        /* Add each 4 pixel group together and put 4 results into sad */
88
 
        sad = vec_sum4s(t5, sad);
89
 
 
90
 
        pix1 += line_size;
91
 
        pix2 += line_size;
92
 
    }
93
 
    /* Sum up the four partial sums, and put the result into s */
94
 
    sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
95
 
    sumdiffs = vec_splat(sumdiffs, 3);
96
 
    vec_ste(sumdiffs, 0, &s);
97
 
 
98
 
    return s;
99
 
}
100
 
 
101
 
int sad16_y2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
102
 
{
103
 
    int i;
104
 
    int s __attribute__((aligned(16)));
105
 
    const_vector unsigned char zero = (const_vector unsigned char)vec_splat_u8(0);
106
 
    vector unsigned char *tv;
107
 
    vector unsigned char pix1v, pix2v, pix3v, avgv, t5;
108
 
    vector unsigned int sad;
109
 
    vector signed int sumdiffs;
110
 
    uint8_t *pix3 = pix2 + line_size;
111
 
 
112
 
    s = 0;
113
 
    sad = (vector unsigned int)vec_splat_u32(0);
114
 
 
115
 
    /*
116
 
       Due to the fact that pix3 = pix2 + line_size, the pix3 of one
117
 
       iteration becomes pix2 in the next iteration. We can use this
118
 
       fact to avoid a potentially expensive unaligned read, each
119
 
       time around the loop.
120
 
       Read unaligned pixels into our vectors. The vectors are as follows:
121
 
       pix2v: pix2[0]-pix2[15]
122
 
       Split the pixel vectors into shorts
123
 
    */
124
 
    tv = (vector unsigned char *) &pix2[0];
125
 
    pix2v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[0]));
126
 
 
127
 
    for(i=0;i<h;i++) {
128
 
        /*
129
 
           Read unaligned pixels into our vectors. The vectors are as follows:
130
 
           pix1v: pix1[0]-pix1[15]
131
 
           pix3v: pix3[0]-pix3[15]
132
 
        */
133
 
        tv = (vector unsigned char *) pix1;
134
 
        pix1v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix1));
135
 
 
136
 
        tv = (vector unsigned char *) &pix3[0];
137
 
        pix3v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix3[0]));
138
 
 
139
 
        /* Calculate the average vector */
140
 
        avgv = vec_avg(pix2v, pix3v);
141
 
 
142
 
        /* Calculate a sum of abs differences vector */
143
 
        t5 = vec_sub(vec_max(pix1v, avgv), vec_min(pix1v, avgv));
144
 
 
145
 
        /* Add each 4 pixel group together and put 4 results into sad */
146
 
        sad = vec_sum4s(t5, sad);
147
 
 
148
 
        pix1 += line_size;
149
 
        pix2v = pix3v;
150
 
        pix3 += line_size;
151
 
 
152
 
    }
153
 
 
154
 
    /* Sum up the four partial sums, and put the result into s */
155
 
    sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
156
 
    sumdiffs = vec_splat(sumdiffs, 3);
157
 
    vec_ste(sumdiffs, 0, &s);
158
 
    return s;
159
 
}
160
 
 
161
 
int sad16_xy2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
162
 
{
163
 
    int i;
164
 
    int s __attribute__((aligned(16)));
165
 
    uint8_t *pix3 = pix2 + line_size;
166
 
    const_vector unsigned char zero = (const_vector unsigned char)vec_splat_u8(0);
167
 
    const_vector unsigned short two = (const_vector unsigned short)vec_splat_u16(2);
168
 
    vector unsigned char *tv, avgv, t5;
169
 
    vector unsigned char pix1v, pix2v, pix3v, pix2iv, pix3iv;
170
 
    vector unsigned short pix2lv, pix2hv, pix2ilv, pix2ihv;
171
 
    vector unsigned short pix3lv, pix3hv, pix3ilv, pix3ihv;
172
 
    vector unsigned short avghv, avglv;
173
 
    vector unsigned short t1, t2, t3, t4;
174
 
    vector unsigned int sad;
175
 
    vector signed int sumdiffs;
176
 
 
177
 
    sad = (vector unsigned int)vec_splat_u32(0);
178
 
 
179
 
    s = 0;
180
 
 
181
 
    /*
182
 
       Due to the fact that pix3 = pix2 + line_size, the pix3 of one
183
 
       iteration becomes pix2 in the next iteration. We can use this
184
 
       fact to avoid a potentially expensive unaligned read, as well
185
 
       as some splitting, and vector addition each time around the loop.
186
 
       Read unaligned pixels into our vectors. The vectors are as follows:
187
 
       pix2v: pix2[0]-pix2[15]  pix2iv: pix2[1]-pix2[16]
188
 
       Split the pixel vectors into shorts
189
 
    */
190
 
    tv = (vector unsigned char *) &pix2[0];
191
 
    pix2v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[0]));
192
 
 
193
 
    tv = (vector unsigned char *) &pix2[1];
194
 
    pix2iv = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[1]));
195
 
 
196
 
    pix2hv = (vector unsigned short) vec_mergeh(zero, pix2v);
197
 
    pix2lv = (vector unsigned short) vec_mergel(zero, pix2v);
198
 
    pix2ihv = (vector unsigned short) vec_mergeh(zero, pix2iv);
199
 
    pix2ilv = (vector unsigned short) vec_mergel(zero, pix2iv);
200
 
    t1 = vec_add(pix2hv, pix2ihv);
201
 
    t2 = vec_add(pix2lv, pix2ilv);
202
 
 
203
 
    for(i=0;i<h;i++) {
204
 
        /*
205
 
           Read unaligned pixels into our vectors. The vectors are as follows:
206
 
           pix1v: pix1[0]-pix1[15]
207
 
           pix3v: pix3[0]-pix3[15]      pix3iv: pix3[1]-pix3[16]
208
 
        */
209
 
        tv = (vector unsigned char *) pix1;
210
 
        pix1v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix1));
211
 
 
212
 
        tv = (vector unsigned char *) &pix3[0];
213
 
        pix3v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix3[0]));
214
 
 
215
 
        tv = (vector unsigned char *) &pix3[1];
216
 
        pix3iv = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix3[1]));
217
 
 
218
 
        /*
219
 
          Note that Altivec does have vec_avg, but this works on vector pairs
220
 
          and rounds up. We could do avg(avg(a,b),avg(c,d)), but the rounding
221
 
          would mean that, for example, avg(3,0,0,1) = 2, when it should be 1.
222
 
          Instead, we have to split the pixel vectors into vectors of shorts,
223
 
          and do the averaging by hand.
224
 
        */
225
 
 
226
 
        /* Split the pixel vectors into shorts */
227
 
        pix3hv = (vector unsigned short) vec_mergeh(zero, pix3v);
228
 
        pix3lv = (vector unsigned short) vec_mergel(zero, pix3v);
229
 
        pix3ihv = (vector unsigned short) vec_mergeh(zero, pix3iv);
230
 
        pix3ilv = (vector unsigned short) vec_mergel(zero, pix3iv);
231
 
 
232
 
        /* Do the averaging on them */
233
 
        t3 = vec_add(pix3hv, pix3ihv);
234
 
        t4 = vec_add(pix3lv, pix3ilv);
235
 
 
236
 
        avghv = vec_sr(vec_add(vec_add(t1, t3), two), two);
237
 
        avglv = vec_sr(vec_add(vec_add(t2, t4), two), two);
238
 
 
239
 
        /* Pack the shorts back into a result */
240
 
        avgv = vec_pack(avghv, avglv);
241
 
 
242
 
        /* Calculate a sum of abs differences vector */
243
 
        t5 = vec_sub(vec_max(pix1v, avgv), vec_min(pix1v, avgv));
244
 
 
245
 
        /* Add each 4 pixel group together and put 4 results into sad */
246
 
        sad = vec_sum4s(t5, sad);
247
 
 
248
 
        pix1 += line_size;
249
 
        pix3 += line_size;
250
 
        /* Transfer the calculated values for pix3 into pix2 */
251
 
        t1 = t3;
252
 
        t2 = t4;
253
 
    }
254
 
    /* Sum up the four partial sums, and put the result into s */
255
 
    sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
256
 
    sumdiffs = vec_splat(sumdiffs, 3);
257
 
    vec_ste(sumdiffs, 0, &s);
258
 
 
259
 
    return s;
260
 
}
261
 
 
262
 
int sad16_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
263
 
{
264
 
    int i;
265
 
    int s __attribute__((aligned(16)));
266
 
    const_vector unsigned int zero = (const_vector unsigned int)vec_splat_u32(0);
267
 
    vector unsigned char perm1, perm2, *pix1v, *pix2v;
268
 
    vector unsigned char t1, t2, t3,t4, t5;
269
 
    vector unsigned int sad;
270
 
    vector signed int sumdiffs;
271
 
 
272
 
    sad = (vector unsigned int)vec_splat_u32(0);
273
 
 
274
 
 
275
 
    for(i=0;i<h;i++) {
276
 
        /* Read potentially unaligned pixels into t1 and t2 */
277
 
        perm1 = vec_lvsl(0, pix1);
278
 
        pix1v = (vector unsigned char *) pix1;
279
 
        perm2 = vec_lvsl(0, pix2);
280
 
        pix2v = (vector unsigned char *) pix2;
281
 
        t1 = vec_perm(pix1v[0], pix1v[1], perm1);
282
 
        t2 = vec_perm(pix2v[0], pix2v[1], perm2);
283
 
 
284
 
        /* Calculate a sum of abs differences vector */
285
 
        t3 = vec_max(t1, t2);
286
 
        t4 = vec_min(t1, t2);
287
 
        t5 = vec_sub(t3, t4);
288
 
 
289
 
        /* Add each 4 pixel group together and put 4 results into sad */
290
 
        sad = vec_sum4s(t5, sad);
291
 
 
292
 
        pix1 += line_size;
293
 
        pix2 += line_size;
294
 
    }
295
 
 
296
 
    /* Sum up the four partial sums, and put the result into s */
297
 
    sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
298
 
    sumdiffs = vec_splat(sumdiffs, 3);
299
 
    vec_ste(sumdiffs, 0, &s);
300
 
 
301
 
    return s;
302
 
}
303
 
 
304
 
int sad8_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
305
 
{
306
 
    int i;
307
 
    int s __attribute__((aligned(16)));
308
 
    const_vector unsigned int zero = (const_vector unsigned int)vec_splat_u32(0);
309
 
    vector unsigned char perm1, perm2, permclear, *pix1v, *pix2v;
310
 
    vector unsigned char t1, t2, t3,t4, t5;
311
 
    vector unsigned int sad;
312
 
    vector signed int sumdiffs;
313
 
 
314
 
    sad = (vector unsigned int)vec_splat_u32(0);
315
 
 
316
 
    permclear = (vector unsigned char)AVV(255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0);
317
 
 
318
 
    for(i=0;i<h;i++) {
319
 
        /* Read potentially unaligned pixels into t1 and t2
320
 
           Since we're reading 16 pixels, and actually only want 8,
321
 
           mask out the last 8 pixels. The 0s don't change the sum. */
322
 
        perm1 = vec_lvsl(0, pix1);
323
 
        pix1v = (vector unsigned char *) pix1;
324
 
        perm2 = vec_lvsl(0, pix2);
325
 
        pix2v = (vector unsigned char *) pix2;
326
 
        t1 = vec_and(vec_perm(pix1v[0], pix1v[1], perm1), permclear);
327
 
        t2 = vec_and(vec_perm(pix2v[0], pix2v[1], perm2), permclear);
328
 
 
329
 
        /* Calculate a sum of abs differences vector */
330
 
        t3 = vec_max(t1, t2);
331
 
        t4 = vec_min(t1, t2);
332
 
        t5 = vec_sub(t3, t4);
333
 
 
334
 
        /* Add each 4 pixel group together and put 4 results into sad */
335
 
        sad = vec_sum4s(t5, sad);
336
 
 
337
 
        pix1 += line_size;
338
 
        pix2 += line_size;
339
 
    }
340
 
 
341
 
    /* Sum up the four partial sums, and put the result into s */
342
 
    sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
343
 
    sumdiffs = vec_splat(sumdiffs, 3);
344
 
    vec_ste(sumdiffs, 0, &s);
345
 
 
346
 
    return s;
347
 
}
348
 
 
349
 
int pix_norm1_altivec(uint8_t *pix, int line_size)
350
 
{
351
 
    int i;
352
 
    int s __attribute__((aligned(16)));
353
 
    const_vector unsigned int zero = (const_vector unsigned int)vec_splat_u32(0);
354
 
    vector unsigned char *tv;
355
 
    vector unsigned char pixv;
356
 
    vector unsigned int sv;
357
 
    vector signed int sum;
358
 
 
359
 
    sv = (vector unsigned int)vec_splat_u32(0);
360
 
 
361
 
    s = 0;
362
 
    for (i = 0; i < 16; i++) {
363
 
        /* Read in the potentially unaligned pixels */
364
 
        tv = (vector unsigned char *) pix;
365
 
        pixv = vec_perm(tv[0], tv[1], vec_lvsl(0, pix));
366
 
 
367
 
        /* Square the values, and add them to our sum */
368
 
        sv = vec_msum(pixv, pixv, sv);
369
 
 
370
 
        pix += line_size;
371
 
    }
372
 
    /* Sum up the four partial sums, and put the result into s */
373
 
    sum = vec_sums((vector signed int) sv, (vector signed int) zero);
374
 
    sum = vec_splat(sum, 3);
375
 
    vec_ste(sum, 0, &s);
376
 
 
377
 
    return s;
378
 
}
379
 
 
380
 
/**
381
 
 * Sum of Squared Errors for a 8x8 block.
382
 
 * AltiVec-enhanced.
383
 
 * It's the sad8_altivec code above w/ squaring added.
384
 
 */
385
 
int sse8_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
386
 
{
387
 
    int i;
388
 
    int s __attribute__((aligned(16)));
389
 
    const_vector unsigned int zero = (const_vector unsigned int)vec_splat_u32(0);
390
 
    vector unsigned char perm1, perm2, permclear, *pix1v, *pix2v;
391
 
    vector unsigned char t1, t2, t3,t4, t5;
392
 
    vector unsigned int sum;
393
 
    vector signed int sumsqr;
394
 
 
395
 
    sum = (vector unsigned int)vec_splat_u32(0);
396
 
 
397
 
    permclear = (vector unsigned char)AVV(255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0);
398
 
 
399
 
 
400
 
    for(i=0;i<h;i++) {
401
 
        /* Read potentially unaligned pixels into t1 and t2
402
 
           Since we're reading 16 pixels, and actually only want 8,
403
 
           mask out the last 8 pixels. The 0s don't change the sum. */
404
 
        perm1 = vec_lvsl(0, pix1);
405
 
        pix1v = (vector unsigned char *) pix1;
406
 
        perm2 = vec_lvsl(0, pix2);
407
 
        pix2v = (vector unsigned char *) pix2;
408
 
        t1 = vec_and(vec_perm(pix1v[0], pix1v[1], perm1), permclear);
409
 
        t2 = vec_and(vec_perm(pix2v[0], pix2v[1], perm2), permclear);
410
 
 
411
 
        /*
412
 
          Since we want to use unsigned chars, we can take advantage
413
 
          of the fact that abs(a-b)^2 = (a-b)^2.
414
 
        */
415
 
 
416
 
        /* Calculate abs differences vector */
417
 
        t3 = vec_max(t1, t2);
418
 
        t4 = vec_min(t1, t2);
419
 
        t5 = vec_sub(t3, t4);
420
 
 
421
 
        /* Square the values and add them to our sum */
422
 
        sum = vec_msum(t5, t5, sum);
423
 
 
424
 
        pix1 += line_size;
425
 
        pix2 += line_size;
426
 
    }
427
 
 
428
 
    /* Sum up the four partial sums, and put the result into s */
429
 
    sumsqr = vec_sums((vector signed int) sum, (vector signed int) zero);
430
 
    sumsqr = vec_splat(sumsqr, 3);
431
 
    vec_ste(sumsqr, 0, &s);
432
 
 
433
 
    return s;
434
 
}
435
 
 
436
 
/**
437
 
 * Sum of Squared Errors for a 16x16 block.
438
 
 * AltiVec-enhanced.
439
 
 * It's the sad16_altivec code above w/ squaring added.
440
 
 */
441
 
int sse16_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
442
 
{
443
 
    int i;
444
 
    int s __attribute__((aligned(16)));
445
 
    const_vector unsigned int zero = (const_vector unsigned int)vec_splat_u32(0);
446
 
    vector unsigned char perm1, perm2, *pix1v, *pix2v;
447
 
    vector unsigned char t1, t2, t3,t4, t5;
448
 
    vector unsigned int sum;
449
 
    vector signed int sumsqr;
450
 
 
451
 
    sum = (vector unsigned int)vec_splat_u32(0);
452
 
 
453
 
    for(i=0;i<h;i++) {
454
 
        /* Read potentially unaligned pixels into t1 and t2 */
455
 
        perm1 = vec_lvsl(0, pix1);
456
 
        pix1v = (vector unsigned char *) pix1;
457
 
        perm2 = vec_lvsl(0, pix2);
458
 
        pix2v = (vector unsigned char *) pix2;
459
 
        t1 = vec_perm(pix1v[0], pix1v[1], perm1);
460
 
        t2 = vec_perm(pix2v[0], pix2v[1], perm2);
461
 
 
462
 
        /*
463
 
          Since we want to use unsigned chars, we can take advantage
464
 
          of the fact that abs(a-b)^2 = (a-b)^2.
465
 
        */
466
 
 
467
 
        /* Calculate abs differences vector */
468
 
        t3 = vec_max(t1, t2);
469
 
        t4 = vec_min(t1, t2);
470
 
        t5 = vec_sub(t3, t4);
471
 
 
472
 
        /* Square the values and add them to our sum */
473
 
        sum = vec_msum(t5, t5, sum);
474
 
 
475
 
        pix1 += line_size;
476
 
        pix2 += line_size;
477
 
    }
478
 
 
479
 
    /* Sum up the four partial sums, and put the result into s */
480
 
    sumsqr = vec_sums((vector signed int) sum, (vector signed int) zero);
481
 
    sumsqr = vec_splat(sumsqr, 3);
482
 
    vec_ste(sumsqr, 0, &s);
483
 
 
484
 
    return s;
485
 
}
486
 
 
487
 
int pix_sum_altivec(uint8_t * pix, int line_size)
488
 
{
489
 
    const_vector unsigned int zero = (const_vector unsigned int)vec_splat_u32(0);
490
 
    vector unsigned char perm, *pixv;
491
 
    vector unsigned char t1;
492
 
    vector unsigned int sad;
493
 
    vector signed int sumdiffs;
494
 
 
495
 
    int i;
496
 
    int s __attribute__((aligned(16)));
497
 
 
498
 
    sad = (vector unsigned int)vec_splat_u32(0);
499
 
 
500
 
    for (i = 0; i < 16; i++) {
501
 
        /* Read the potentially unaligned 16 pixels into t1 */
502
 
        perm = vec_lvsl(0, pix);
503
 
        pixv = (vector unsigned char *) pix;
504
 
        t1 = vec_perm(pixv[0], pixv[1], perm);
505
 
 
506
 
        /* Add each 4 pixel group together and put 4 results into sad */
507
 
        sad = vec_sum4s(t1, sad);
508
 
 
509
 
        pix += line_size;
510
 
    }
511
 
 
512
 
    /* Sum up the four partial sums, and put the result into s */
513
 
    sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
514
 
    sumdiffs = vec_splat(sumdiffs, 3);
515
 
    vec_ste(sumdiffs, 0, &s);
516
 
 
517
 
    return s;
518
 
}
519
 
 
520
 
void get_pixels_altivec(DCTELEM *restrict block, const uint8_t *pixels, int line_size)
521
 
{
522
 
    int i;
523
 
    vector unsigned char perm, bytes, *pixv;
524
 
    const_vector unsigned char zero = (const_vector unsigned char)vec_splat_u8(0);
525
 
    vector signed short shorts;
526
 
 
527
 
    for(i=0;i<8;i++)
528
 
    {
529
 
        // Read potentially unaligned pixels.
530
 
        // We're reading 16 pixels, and actually only want 8,
531
 
        // but we simply ignore the extras.
532
 
        perm = vec_lvsl(0, pixels);
533
 
        pixv = (vector unsigned char *) pixels;
534
 
        bytes = vec_perm(pixv[0], pixv[1], perm);
535
 
 
536
 
        // convert the bytes into shorts
537
 
        shorts = (vector signed short)vec_mergeh(zero, bytes);
538
 
 
539
 
        // save the data to the block, we assume the block is 16-byte aligned
540
 
        vec_st(shorts, i*16, (vector signed short*)block);
541
 
 
542
 
        pixels += line_size;
543
 
    }
544
 
}
545
 
 
546
 
void diff_pixels_altivec(DCTELEM *restrict block, const uint8_t *s1,
547
 
        const uint8_t *s2, int stride)
548
 
{
549
 
    int i;
550
 
    vector unsigned char perm, bytes, *pixv;
551
 
    const_vector unsigned char zero = (const_vector unsigned char)vec_splat_u8(0);
552
 
    vector signed short shorts1, shorts2;
553
 
 
554
 
    for(i=0;i<4;i++)
555
 
    {
556
 
        // Read potentially unaligned pixels
557
 
        // We're reading 16 pixels, and actually only want 8,
558
 
        // but we simply ignore the extras.
559
 
        perm = vec_lvsl(0, s1);
560
 
        pixv = (vector unsigned char *) s1;
561
 
        bytes = vec_perm(pixv[0], pixv[1], perm);
562
 
 
563
 
        // convert the bytes into shorts
564
 
        shorts1 = (vector signed short)vec_mergeh(zero, bytes);
565
 
 
566
 
        // Do the same for the second block of pixels
567
 
        perm = vec_lvsl(0, s2);
568
 
        pixv = (vector unsigned char *) s2;
569
 
        bytes = vec_perm(pixv[0], pixv[1], perm);
570
 
 
571
 
        // convert the bytes into shorts
572
 
        shorts2 = (vector signed short)vec_mergeh(zero, bytes);
573
 
 
574
 
        // Do the subtraction
575
 
        shorts1 = vec_sub(shorts1, shorts2);
576
 
 
577
 
        // save the data to the block, we assume the block is 16-byte aligned
578
 
        vec_st(shorts1, 0, (vector signed short*)block);
579
 
 
580
 
        s1 += stride;
581
 
        s2 += stride;
582
 
        block += 8;
583
 
 
584
 
 
585
 
        // The code below is a copy of the code above... This is a manual
586
 
        // unroll.
587
 
 
588
 
        // Read potentially unaligned pixels
589
 
        // We're reading 16 pixels, and actually only want 8,
590
 
        // but we simply ignore the extras.
591
 
        perm = vec_lvsl(0, s1);
592
 
        pixv = (vector unsigned char *) s1;
593
 
        bytes = vec_perm(pixv[0], pixv[1], perm);
594
 
 
595
 
        // convert the bytes into shorts
596
 
        shorts1 = (vector signed short)vec_mergeh(zero, bytes);
597
 
 
598
 
        // Do the same for the second block of pixels
599
 
        perm = vec_lvsl(0, s2);
600
 
        pixv = (vector unsigned char *) s2;
601
 
        bytes = vec_perm(pixv[0], pixv[1], perm);
602
 
 
603
 
        // convert the bytes into shorts
604
 
        shorts2 = (vector signed short)vec_mergeh(zero, bytes);
605
 
 
606
 
        // Do the subtraction
607
 
        shorts1 = vec_sub(shorts1, shorts2);
608
 
 
609
 
        // save the data to the block, we assume the block is 16-byte aligned
610
 
        vec_st(shorts1, 0, (vector signed short*)block);
611
 
 
612
 
        s1 += stride;
613
 
        s2 += stride;
614
 
        block += 8;
615
 
    }
616
 
}
617
 
 
618
 
void add_bytes_altivec(uint8_t *dst, uint8_t *src, int w) {
619
 
#ifdef ALTIVEC_USE_REFERENCE_C_CODE
620
 
    int i;
621
 
    for(i=0; i+7<w; i++){
622
 
        dst[i+0] += src[i+0];
623
 
        dst[i+1] += src[i+1];
624
 
        dst[i+2] += src[i+2];
625
 
        dst[i+3] += src[i+3];
626
 
        dst[i+4] += src[i+4];
627
 
        dst[i+5] += src[i+5];
628
 
        dst[i+6] += src[i+6];
629
 
        dst[i+7] += src[i+7];
630
 
    }
631
 
    for(; i<w; i++)
632
 
        dst[i+0] += src[i+0];
633
 
#else /* ALTIVEC_USE_REFERENCE_C_CODE */
634
 
    register int i;
635
 
    register vector unsigned char vdst, vsrc;
636
 
 
637
 
    /* dst and src are 16 bytes-aligned (guaranteed) */
638
 
    for(i = 0 ; (i + 15) < w ; i++)
639
 
    {
640
 
      vdst = vec_ld(i << 4, (unsigned char*)dst);
641
 
      vsrc = vec_ld(i << 4, (unsigned char*)src);
642
 
      vdst = vec_add(vsrc, vdst);
643
 
      vec_st(vdst, i << 4, (unsigned char*)dst);
644
 
    }
645
 
    /* if w is not a multiple of 16 */
646
 
    for (; (i < w) ; i++)
647
 
    {
648
 
      dst[i] = src[i];
649
 
    }
650
 
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
651
 
}
652
 
 
653
 
/* next one assumes that ((line_size % 16) == 0) */
654
 
void put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
655
 
{
656
 
POWERPC_PERF_DECLARE(altivec_put_pixels16_num, 1);
657
 
#ifdef ALTIVEC_USE_REFERENCE_C_CODE
658
 
    int i;
659
 
 
660
 
POWERPC_PERF_START_COUNT(altivec_put_pixels16_num, 1);
661
 
 
662
 
    for(i=0; i<h; i++) {
663
 
      *((uint32_t*)(block)) = LD32(pixels);
664
 
      *((uint32_t*)(block+4)) = LD32(pixels+4);
665
 
      *((uint32_t*)(block+8)) = LD32(pixels+8);
666
 
      *((uint32_t*)(block+12)) = LD32(pixels+12);
667
 
      pixels+=line_size;
668
 
      block +=line_size;
669
 
    }
670
 
 
671
 
POWERPC_PERF_STOP_COUNT(altivec_put_pixels16_num, 1);
672
 
 
673
 
#else /* ALTIVEC_USE_REFERENCE_C_CODE */
674
 
    register vector unsigned char pixelsv1, pixelsv2;
675
 
    register vector unsigned char pixelsv1B, pixelsv2B;
676
 
    register vector unsigned char pixelsv1C, pixelsv2C;
677
 
    register vector unsigned char pixelsv1D, pixelsv2D;
678
 
 
679
 
    register vector unsigned char perm = vec_lvsl(0, pixels);
680
 
    int i;
681
 
    register int line_size_2 = line_size << 1;
682
 
    register int line_size_3 = line_size + line_size_2;
683
 
    register int line_size_4 = line_size << 2;
684
 
 
685
 
POWERPC_PERF_START_COUNT(altivec_put_pixels16_num, 1);
686
 
// hand-unrolling the loop by 4 gains about 15%
687
 
// mininum execution time goes from 74 to 60 cycles
688
 
// it's faster than -funroll-loops, but using
689
 
// -funroll-loops w/ this is bad - 74 cycles again.
690
 
// all this is on a 7450, tuning for the 7450
691
 
#if 0
692
 
    for(i=0; i<h; i++) {
693
 
      pixelsv1 = vec_ld(0, (unsigned char*)pixels);
694
 
      pixelsv2 = vec_ld(16, (unsigned char*)pixels);
695
 
      vec_st(vec_perm(pixelsv1, pixelsv2, perm),
696
 
             0, (unsigned char*)block);
697
 
      pixels+=line_size;
698
 
      block +=line_size;
699
 
    }
700
 
#else
701
 
    for(i=0; i<h; i+=4) {
702
 
      pixelsv1 = vec_ld(0, (unsigned char*)pixels);
703
 
      pixelsv2 = vec_ld(16, (unsigned char*)pixels);
704
 
      pixelsv1B = vec_ld(line_size, (unsigned char*)pixels);
705
 
      pixelsv2B = vec_ld(16 + line_size, (unsigned char*)pixels);
706
 
      pixelsv1C = vec_ld(line_size_2, (unsigned char*)pixels);
707
 
      pixelsv2C = vec_ld(16 + line_size_2, (unsigned char*)pixels);
708
 
      pixelsv1D = vec_ld(line_size_3, (unsigned char*)pixels);
709
 
      pixelsv2D = vec_ld(16 + line_size_3, (unsigned char*)pixels);
710
 
      vec_st(vec_perm(pixelsv1, pixelsv2, perm),
711
 
             0, (unsigned char*)block);
712
 
      vec_st(vec_perm(pixelsv1B, pixelsv2B, perm),
713
 
             line_size, (unsigned char*)block);
714
 
      vec_st(vec_perm(pixelsv1C, pixelsv2C, perm),
715
 
             line_size_2, (unsigned char*)block);
716
 
      vec_st(vec_perm(pixelsv1D, pixelsv2D, perm),
717
 
             line_size_3, (unsigned char*)block);
718
 
      pixels+=line_size_4;
719
 
      block +=line_size_4;
720
 
    }
721
 
#endif
722
 
POWERPC_PERF_STOP_COUNT(altivec_put_pixels16_num, 1);
723
 
 
724
 
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
725
 
}
726
 
 
727
 
/* next one assumes that ((line_size % 16) == 0) */
728
 
#define op_avg(a,b)  a = ( ((a)|(b)) - ((((a)^(b))&0xFEFEFEFEUL)>>1) )
729
 
void avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
730
 
{
731
 
POWERPC_PERF_DECLARE(altivec_avg_pixels16_num, 1);
732
 
#ifdef ALTIVEC_USE_REFERENCE_C_CODE
733
 
    int i;
734
 
 
735
 
POWERPC_PERF_START_COUNT(altivec_avg_pixels16_num, 1);
736
 
 
737
 
    for(i=0; i<h; i++) {
738
 
      op_avg(*((uint32_t*)(block)),LD32(pixels));
739
 
      op_avg(*((uint32_t*)(block+4)),LD32(pixels+4));
740
 
      op_avg(*((uint32_t*)(block+8)),LD32(pixels+8));
741
 
      op_avg(*((uint32_t*)(block+12)),LD32(pixels+12));
742
 
      pixels+=line_size;
743
 
      block +=line_size;
744
 
    }
745
 
 
746
 
POWERPC_PERF_STOP_COUNT(altivec_avg_pixels16_num, 1);
747
 
 
748
 
#else /* ALTIVEC_USE_REFERENCE_C_CODE */
749
 
    register vector unsigned char pixelsv1, pixelsv2, pixelsv, blockv;
750
 
    register vector unsigned char perm = vec_lvsl(0, pixels);
751
 
    int i;
752
 
 
753
 
POWERPC_PERF_START_COUNT(altivec_avg_pixels16_num, 1);
754
 
 
755
 
    for(i=0; i<h; i++) {
756
 
      pixelsv1 = vec_ld(0, (unsigned char*)pixels);
757
 
      pixelsv2 = vec_ld(16, (unsigned char*)pixels);
758
 
      blockv = vec_ld(0, block);
759
 
      pixelsv = vec_perm(pixelsv1, pixelsv2, perm);
760
 
      blockv = vec_avg(blockv,pixelsv);
761
 
      vec_st(blockv, 0, (unsigned char*)block);
762
 
      pixels+=line_size;
763
 
      block +=line_size;
764
 
    }
765
 
 
766
 
POWERPC_PERF_STOP_COUNT(altivec_avg_pixels16_num, 1);
767
 
 
768
 
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
769
 
}
770
 
 
771
 
/* next one assumes that ((line_size % 8) == 0) */
772
 
void avg_pixels8_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h)
773
 
{
774
 
POWERPC_PERF_DECLARE(altivec_avg_pixels8_num, 1);
775
 
#ifdef ALTIVEC_USE_REFERENCE_C_CODE
776
 
    int i;
777
 
POWERPC_PERF_START_COUNT(altivec_avg_pixels8_num, 1);
778
 
    for (i = 0; i < h; i++) {
779
 
        *((uint32_t *) (block)) =
780
 
            (((*((uint32_t *) (block))) |
781
 
              ((((const struct unaligned_32 *) (pixels))->l))) -
782
 
             ((((*((uint32_t *) (block))) ^
783
 
                ((((const struct unaligned_32 *) (pixels))->
784
 
                  l))) & 0xFEFEFEFEUL) >> 1));
785
 
        *((uint32_t *) (block + 4)) =
786
 
            (((*((uint32_t *) (block + 4))) |
787
 
              ((((const struct unaligned_32 *) (pixels + 4))->l))) -
788
 
             ((((*((uint32_t *) (block + 4))) ^
789
 
                ((((const struct unaligned_32 *) (pixels +
790
 
                                                  4))->
791
 
                  l))) & 0xFEFEFEFEUL) >> 1));
792
 
        pixels += line_size;
793
 
        block += line_size;
794
 
    }
795
 
POWERPC_PERF_STOP_COUNT(altivec_avg_pixels8_num, 1);
796
 
 
797
 
#else /* ALTIVEC_USE_REFERENCE_C_CODE */
798
 
    register vector unsigned char pixelsv1, pixelsv2, pixelsv, blockv;
799
 
    int i;
800
 
 
801
 
POWERPC_PERF_START_COUNT(altivec_avg_pixels8_num, 1);
802
 
 
803
 
   for (i = 0; i < h; i++) {
804
 
     /*
805
 
       block is 8 bytes-aligned, so we're either in the
806
 
       left block (16 bytes-aligned) or in the right block (not)
807
 
     */
808
 
     int rightside = ((unsigned long)block & 0x0000000F);
809
 
 
810
 
     blockv = vec_ld(0, block);
811
 
     pixelsv1 = vec_ld(0, (unsigned char*)pixels);
812
 
     pixelsv2 = vec_ld(16, (unsigned char*)pixels);
813
 
     pixelsv = vec_perm(pixelsv1, pixelsv2, vec_lvsl(0, pixels));
814
 
 
815
 
     if (rightside)
816
 
     {
817
 
       pixelsv = vec_perm(blockv, pixelsv, vcprm(0,1,s0,s1));
818
 
     }
819
 
     else
820
 
     {
821
 
       pixelsv = vec_perm(blockv, pixelsv, vcprm(s0,s1,2,3));
822
 
     }
823
 
 
824
 
     blockv = vec_avg(blockv, pixelsv);
825
 
 
826
 
     vec_st(blockv, 0, block);
827
 
 
828
 
     pixels += line_size;
829
 
     block += line_size;
830
 
   }
831
 
 
832
 
POWERPC_PERF_STOP_COUNT(altivec_avg_pixels8_num, 1);
833
 
 
834
 
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
835
 
}
836
 
 
837
 
/* next one assumes that ((line_size % 8) == 0) */
838
 
void put_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
839
 
{
840
 
POWERPC_PERF_DECLARE(altivec_put_pixels8_xy2_num, 1);
841
 
#ifdef ALTIVEC_USE_REFERENCE_C_CODE
842
 
    int j;
843
 
POWERPC_PERF_START_COUNT(altivec_put_pixels8_xy2_num, 1);
844
 
    for (j = 0; j < 2; j++) {
845
 
      int i;
846
 
      const uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
847
 
      const uint32_t b =
848
 
        (((const struct unaligned_32 *) (pixels + 1))->l);
849
 
      uint32_t l0 =
850
 
        (a & 0x03030303UL) + (b & 0x03030303UL) + 0x02020202UL;
851
 
      uint32_t h0 =
852
 
        ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
853
 
      uint32_t l1, h1;
854
 
      pixels += line_size;
855
 
      for (i = 0; i < h; i += 2) {
856
 
        uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
857
 
        uint32_t b = (((const struct unaligned_32 *) (pixels + 1))->l);
858
 
        l1 = (a & 0x03030303UL) + (b & 0x03030303UL);
859
 
        h1 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
860
 
        *((uint32_t *) block) =
861
 
          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
862
 
        pixels += line_size;
863
 
        block += line_size;
864
 
        a = (((const struct unaligned_32 *) (pixels))->l);
865
 
        b = (((const struct unaligned_32 *) (pixels + 1))->l);
866
 
        l0 = (a & 0x03030303UL) + (b & 0x03030303UL) + 0x02020202UL;
867
 
        h0 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
868
 
        *((uint32_t *) block) =
869
 
          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
870
 
        pixels += line_size;
871
 
        block += line_size;
872
 
      } pixels += 4 - line_size * (h + 1);
873
 
      block += 4 - line_size * h;
874
 
    }
875
 
 
876
 
POWERPC_PERF_STOP_COUNT(altivec_put_pixels8_xy2_num, 1);
877
 
 
878
 
#else /* ALTIVEC_USE_REFERENCE_C_CODE */
879
 
   register int i;
880
 
   register vector unsigned char
881
 
     pixelsv1, pixelsv2,
882
 
     pixelsavg;
883
 
   register vector unsigned char
884
 
     blockv, temp1, temp2;
885
 
   register vector unsigned short
886
 
     pixelssum1, pixelssum2, temp3;
887
 
   register const_vector unsigned char vczero = (const_vector unsigned char)vec_splat_u8(0);
888
 
   register const_vector unsigned short vctwo = (const_vector unsigned short)vec_splat_u16(2);
889
 
 
890
 
   temp1 = vec_ld(0, pixels);
891
 
   temp2 = vec_ld(16, pixels);
892
 
   pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
893
 
   if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F)
894
 
   {
895
 
     pixelsv2 = temp2;
896
 
   }
897
 
   else
898
 
   {
899
 
     pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
900
 
   }
901
 
   pixelsv1 = vec_mergeh(vczero, pixelsv1);
902
 
   pixelsv2 = vec_mergeh(vczero, pixelsv2);
903
 
   pixelssum1 = vec_add((vector unsigned short)pixelsv1,
904
 
                        (vector unsigned short)pixelsv2);
905
 
   pixelssum1 = vec_add(pixelssum1, vctwo);
906
 
 
907
 
POWERPC_PERF_START_COUNT(altivec_put_pixels8_xy2_num, 1);
908
 
   for (i = 0; i < h ; i++) {
909
 
     int rightside = ((unsigned long)block & 0x0000000F);
910
 
     blockv = vec_ld(0, block);
911
 
 
912
 
     temp1 = vec_ld(line_size, pixels);
913
 
     temp2 = vec_ld(line_size + 16, pixels);
914
 
     pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
915
 
     if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F)
916
 
     {
917
 
       pixelsv2 = temp2;
918
 
     }
919
 
     else
920
 
     {
921
 
       pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
922
 
     }
923
 
 
924
 
     pixelsv1 = vec_mergeh(vczero, pixelsv1);
925
 
     pixelsv2 = vec_mergeh(vczero, pixelsv2);
926
 
     pixelssum2 = vec_add((vector unsigned short)pixelsv1,
927
 
                          (vector unsigned short)pixelsv2);
928
 
     temp3 = vec_add(pixelssum1, pixelssum2);
929
 
     temp3 = vec_sra(temp3, vctwo);
930
 
     pixelssum1 = vec_add(pixelssum2, vctwo);
931
 
     pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero);
932
 
 
933
 
     if (rightside)
934
 
     {
935
 
       blockv = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1));
936
 
     }
937
 
     else
938
 
     {
939
 
       blockv = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3));
940
 
     }
941
 
 
942
 
     vec_st(blockv, 0, block);
943
 
 
944
 
     block += line_size;
945
 
     pixels += line_size;
946
 
   }
947
 
 
948
 
POWERPC_PERF_STOP_COUNT(altivec_put_pixels8_xy2_num, 1);
949
 
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
950
 
}
951
 
 
952
 
/* next one assumes that ((line_size % 8) == 0) */
953
 
void put_no_rnd_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
954
 
{
955
 
POWERPC_PERF_DECLARE(altivec_put_no_rnd_pixels8_xy2_num, 1);
956
 
#ifdef ALTIVEC_USE_REFERENCE_C_CODE
957
 
    int j;
958
 
POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1);
959
 
    for (j = 0; j < 2; j++) {
960
 
      int i;
961
 
      const uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
962
 
      const uint32_t b =
963
 
        (((const struct unaligned_32 *) (pixels + 1))->l);
964
 
      uint32_t l0 =
965
 
        (a & 0x03030303UL) + (b & 0x03030303UL) + 0x01010101UL;
966
 
      uint32_t h0 =
967
 
        ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
968
 
      uint32_t l1, h1;
969
 
      pixels += line_size;
970
 
      for (i = 0; i < h; i += 2) {
971
 
        uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
972
 
        uint32_t b = (((const struct unaligned_32 *) (pixels + 1))->l);
973
 
        l1 = (a & 0x03030303UL) + (b & 0x03030303UL);
974
 
        h1 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
975
 
        *((uint32_t *) block) =
976
 
          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
977
 
        pixels += line_size;
978
 
        block += line_size;
979
 
        a = (((const struct unaligned_32 *) (pixels))->l);
980
 
        b = (((const struct unaligned_32 *) (pixels + 1))->l);
981
 
        l0 = (a & 0x03030303UL) + (b & 0x03030303UL) + 0x01010101UL;
982
 
        h0 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
983
 
        *((uint32_t *) block) =
984
 
          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
985
 
        pixels += line_size;
986
 
        block += line_size;
987
 
      } pixels += 4 - line_size * (h + 1);
988
 
      block += 4 - line_size * h;
989
 
    }
990
 
 
991
 
POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1);
992
 
 
993
 
#else /* ALTIVEC_USE_REFERENCE_C_CODE */
994
 
   register int i;
995
 
   register vector unsigned char
996
 
     pixelsv1, pixelsv2,
997
 
     pixelsavg;
998
 
   register vector unsigned char
999
 
     blockv, temp1, temp2;
1000
 
   register vector unsigned short
1001
 
     pixelssum1, pixelssum2, temp3;
1002
 
   register const_vector unsigned char vczero = (const_vector unsigned char)vec_splat_u8(0);
1003
 
   register const_vector unsigned short vcone = (const_vector unsigned short)vec_splat_u16(1);
1004
 
   register const_vector unsigned short vctwo = (const_vector unsigned short)vec_splat_u16(2);
1005
 
 
1006
 
   temp1 = vec_ld(0, pixels);
1007
 
   temp2 = vec_ld(16, pixels);
1008
 
   pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
1009
 
   if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F)
1010
 
   {
1011
 
     pixelsv2 = temp2;
1012
 
   }
1013
 
   else
1014
 
   {
1015
 
     pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
1016
 
   }
1017
 
   pixelsv1 = vec_mergeh(vczero, pixelsv1);
1018
 
   pixelsv2 = vec_mergeh(vczero, pixelsv2);
1019
 
   pixelssum1 = vec_add((vector unsigned short)pixelsv1,
1020
 
                        (vector unsigned short)pixelsv2);
1021
 
   pixelssum1 = vec_add(pixelssum1, vcone);
1022
 
 
1023
 
POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1);
1024
 
   for (i = 0; i < h ; i++) {
1025
 
     int rightside = ((unsigned long)block & 0x0000000F);
1026
 
     blockv = vec_ld(0, block);
1027
 
 
1028
 
     temp1 = vec_ld(line_size, pixels);
1029
 
     temp2 = vec_ld(line_size + 16, pixels);
1030
 
     pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
1031
 
     if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F)
1032
 
     {
1033
 
       pixelsv2 = temp2;
1034
 
     }
1035
 
     else
1036
 
     {
1037
 
       pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
1038
 
     }
1039
 
 
1040
 
     pixelsv1 = vec_mergeh(vczero, pixelsv1);
1041
 
     pixelsv2 = vec_mergeh(vczero, pixelsv2);
1042
 
     pixelssum2 = vec_add((vector unsigned short)pixelsv1,
1043
 
                          (vector unsigned short)pixelsv2);
1044
 
     temp3 = vec_add(pixelssum1, pixelssum2);
1045
 
     temp3 = vec_sra(temp3, vctwo);
1046
 
     pixelssum1 = vec_add(pixelssum2, vcone);
1047
 
     pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero);
1048
 
 
1049
 
     if (rightside)
1050
 
     {
1051
 
       blockv = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1));
1052
 
     }
1053
 
     else
1054
 
     {
1055
 
       blockv = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3));
1056
 
     }
1057
 
 
1058
 
     vec_st(blockv, 0, block);
1059
 
 
1060
 
     block += line_size;
1061
 
     pixels += line_size;
1062
 
   }
1063
 
 
1064
 
POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1);
1065
 
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
1066
 
}
1067
 
 
1068
 
/* next one assumes that ((line_size % 16) == 0) */
1069
 
void put_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h)
1070
 
{
1071
 
POWERPC_PERF_DECLARE(altivec_put_pixels16_xy2_num, 1);
1072
 
#ifdef ALTIVEC_USE_REFERENCE_C_CODE
1073
 
    int j;
1074
 
POWERPC_PERF_START_COUNT(altivec_put_pixels16_xy2_num, 1);
1075
 
      for (j = 0; j < 4; j++) {
1076
 
      int i;
1077
 
      const uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
1078
 
      const uint32_t b =
1079
 
        (((const struct unaligned_32 *) (pixels + 1))->l);
1080
 
      uint32_t l0 =
1081
 
        (a & 0x03030303UL) + (b & 0x03030303UL) + 0x02020202UL;
1082
 
      uint32_t h0 =
1083
 
        ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
1084
 
      uint32_t l1, h1;
1085
 
      pixels += line_size;
1086
 
      for (i = 0; i < h; i += 2) {
1087
 
        uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
1088
 
        uint32_t b = (((const struct unaligned_32 *) (pixels + 1))->l);
1089
 
        l1 = (a & 0x03030303UL) + (b & 0x03030303UL);
1090
 
        h1 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
1091
 
        *((uint32_t *) block) =
1092
 
          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
1093
 
        pixels += line_size;
1094
 
        block += line_size;
1095
 
        a = (((const struct unaligned_32 *) (pixels))->l);
1096
 
        b = (((const struct unaligned_32 *) (pixels + 1))->l);
1097
 
        l0 = (a & 0x03030303UL) + (b & 0x03030303UL) + 0x02020202UL;
1098
 
        h0 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
1099
 
        *((uint32_t *) block) =
1100
 
          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
1101
 
        pixels += line_size;
1102
 
        block += line_size;
1103
 
      } pixels += 4 - line_size * (h + 1);
1104
 
      block += 4 - line_size * h;
1105
 
    }
1106
 
 
1107
 
POWERPC_PERF_STOP_COUNT(altivec_put_pixels16_xy2_num, 1);
1108
 
 
1109
 
#else /* ALTIVEC_USE_REFERENCE_C_CODE */
1110
 
   register int i;
1111
 
   register vector unsigned char
1112
 
     pixelsv1, pixelsv2, pixelsv3, pixelsv4;
1113
 
   register vector unsigned char
1114
 
     blockv, temp1, temp2;
1115
 
   register vector unsigned short
1116
 
     pixelssum1, pixelssum2, temp3,
1117
 
     pixelssum3, pixelssum4, temp4;
1118
 
   register const_vector unsigned char vczero = (const_vector unsigned char)vec_splat_u8(0);
1119
 
   register const_vector unsigned short vctwo = (const_vector unsigned short)vec_splat_u16(2);
1120
 
 
1121
 
POWERPC_PERF_START_COUNT(altivec_put_pixels16_xy2_num, 1);
1122
 
 
1123
 
   temp1 = vec_ld(0, pixels);
1124
 
   temp2 = vec_ld(16, pixels);
1125
 
   pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
1126
 
   if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F)
1127
 
   {
1128
 
     pixelsv2 = temp2;
1129
 
   }
1130
 
   else
1131
 
   {
1132
 
     pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
1133
 
   }
1134
 
   pixelsv3 = vec_mergel(vczero, pixelsv1);
1135
 
   pixelsv4 = vec_mergel(vczero, pixelsv2);
1136
 
   pixelsv1 = vec_mergeh(vczero, pixelsv1);
1137
 
   pixelsv2 = vec_mergeh(vczero, pixelsv2);
1138
 
   pixelssum3 = vec_add((vector unsigned short)pixelsv3,
1139
 
                        (vector unsigned short)pixelsv4);
1140
 
   pixelssum3 = vec_add(pixelssum3, vctwo);
1141
 
   pixelssum1 = vec_add((vector unsigned short)pixelsv1,
1142
 
                        (vector unsigned short)pixelsv2);
1143
 
   pixelssum1 = vec_add(pixelssum1, vctwo);
1144
 
 
1145
 
   for (i = 0; i < h ; i++) {
1146
 
     blockv = vec_ld(0, block);
1147
 
 
1148
 
     temp1 = vec_ld(line_size, pixels);
1149
 
     temp2 = vec_ld(line_size + 16, pixels);
1150
 
     pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
1151
 
     if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F)
1152
 
     {
1153
 
       pixelsv2 = temp2;
1154
 
     }
1155
 
     else
1156
 
     {
1157
 
       pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
1158
 
     }
1159
 
 
1160
 
     pixelsv3 = vec_mergel(vczero, pixelsv1);
1161
 
     pixelsv4 = vec_mergel(vczero, pixelsv2);
1162
 
     pixelsv1 = vec_mergeh(vczero, pixelsv1);
1163
 
     pixelsv2 = vec_mergeh(vczero, pixelsv2);
1164
 
 
1165
 
     pixelssum4 = vec_add((vector unsigned short)pixelsv3,
1166
 
                          (vector unsigned short)pixelsv4);
1167
 
     pixelssum2 = vec_add((vector unsigned short)pixelsv1,
1168
 
                          (vector unsigned short)pixelsv2);
1169
 
     temp4 = vec_add(pixelssum3, pixelssum4);
1170
 
     temp4 = vec_sra(temp4, vctwo);
1171
 
     temp3 = vec_add(pixelssum1, pixelssum2);
1172
 
     temp3 = vec_sra(temp3, vctwo);
1173
 
 
1174
 
     pixelssum3 = vec_add(pixelssum4, vctwo);
1175
 
     pixelssum1 = vec_add(pixelssum2, vctwo);
1176
 
 
1177
 
     blockv = vec_packsu(temp3, temp4);
1178
 
 
1179
 
     vec_st(blockv, 0, block);
1180
 
 
1181
 
     block += line_size;
1182
 
     pixels += line_size;
1183
 
   }
1184
 
 
1185
 
POWERPC_PERF_STOP_COUNT(altivec_put_pixels16_xy2_num, 1);
1186
 
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
1187
 
}
1188
 
 
1189
 
/* next one assumes that ((line_size % 16) == 0) */
1190
 
void put_no_rnd_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h)
1191
 
{
1192
 
POWERPC_PERF_DECLARE(altivec_put_no_rnd_pixels16_xy2_num, 1);
1193
 
#ifdef ALTIVEC_USE_REFERENCE_C_CODE
1194
 
    int j;
1195
 
POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1);
1196
 
      for (j = 0; j < 4; j++) {
1197
 
      int i;
1198
 
      const uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
1199
 
      const uint32_t b =
1200
 
        (((const struct unaligned_32 *) (pixels + 1))->l);
1201
 
      uint32_t l0 =
1202
 
        (a & 0x03030303UL) + (b & 0x03030303UL) + 0x01010101UL;
1203
 
      uint32_t h0 =
1204
 
        ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
1205
 
      uint32_t l1, h1;
1206
 
      pixels += line_size;
1207
 
      for (i = 0; i < h; i += 2) {
1208
 
        uint32_t a = (((const struct unaligned_32 *) (pixels))->l);
1209
 
        uint32_t b = (((const struct unaligned_32 *) (pixels + 1))->l);
1210
 
        l1 = (a & 0x03030303UL) + (b & 0x03030303UL);
1211
 
        h1 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
1212
 
        *((uint32_t *) block) =
1213
 
          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
1214
 
        pixels += line_size;
1215
 
        block += line_size;
1216
 
        a = (((const struct unaligned_32 *) (pixels))->l);
1217
 
        b = (((const struct unaligned_32 *) (pixels + 1))->l);
1218
 
        l0 = (a & 0x03030303UL) + (b & 0x03030303UL) + 0x01010101UL;
1219
 
        h0 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
1220
 
        *((uint32_t *) block) =
1221
 
          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
1222
 
        pixels += line_size;
1223
 
        block += line_size;
1224
 
      } pixels += 4 - line_size * (h + 1);
1225
 
      block += 4 - line_size * h;
1226
 
    }
1227
 
 
1228
 
POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1);
1229
 
 
1230
 
#else /* ALTIVEC_USE_REFERENCE_C_CODE */
1231
 
   register int i;
1232
 
   register vector unsigned char
1233
 
     pixelsv1, pixelsv2, pixelsv3, pixelsv4;
1234
 
   register vector unsigned char
1235
 
     blockv, temp1, temp2;
1236
 
   register vector unsigned short
1237
 
     pixelssum1, pixelssum2, temp3,
1238
 
     pixelssum3, pixelssum4, temp4;
1239
 
   register const_vector unsigned char vczero = (const_vector unsigned char)vec_splat_u8(0);
1240
 
   register const_vector unsigned short vcone = (const_vector unsigned short)vec_splat_u16(1);
1241
 
   register const_vector unsigned short vctwo = (const_vector unsigned short)vec_splat_u16(2);
1242
 
 
1243
 
POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1);
1244
 
 
1245
 
   temp1 = vec_ld(0, pixels);
1246
 
   temp2 = vec_ld(16, pixels);
1247
 
   pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
1248
 
   if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F)
1249
 
   {
1250
 
     pixelsv2 = temp2;
1251
 
   }
1252
 
   else
1253
 
   {
1254
 
     pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
1255
 
   }
1256
 
   pixelsv3 = vec_mergel(vczero, pixelsv1);
1257
 
   pixelsv4 = vec_mergel(vczero, pixelsv2);
1258
 
   pixelsv1 = vec_mergeh(vczero, pixelsv1);
1259
 
   pixelsv2 = vec_mergeh(vczero, pixelsv2);
1260
 
   pixelssum3 = vec_add((vector unsigned short)pixelsv3,
1261
 
                        (vector unsigned short)pixelsv4);
1262
 
   pixelssum3 = vec_add(pixelssum3, vcone);
1263
 
   pixelssum1 = vec_add((vector unsigned short)pixelsv1,
1264
 
                        (vector unsigned short)pixelsv2);
1265
 
   pixelssum1 = vec_add(pixelssum1, vcone);
1266
 
 
1267
 
   for (i = 0; i < h ; i++) {
1268
 
     blockv = vec_ld(0, block);
1269
 
 
1270
 
     temp1 = vec_ld(line_size, pixels);
1271
 
     temp2 = vec_ld(line_size + 16, pixels);
1272
 
     pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
1273
 
     if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F)
1274
 
     {
1275
 
       pixelsv2 = temp2;
1276
 
     }
1277
 
     else
1278
 
     {
1279
 
       pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
1280
 
     }
1281
 
 
1282
 
     pixelsv3 = vec_mergel(vczero, pixelsv1);
1283
 
     pixelsv4 = vec_mergel(vczero, pixelsv2);
1284
 
     pixelsv1 = vec_mergeh(vczero, pixelsv1);
1285
 
     pixelsv2 = vec_mergeh(vczero, pixelsv2);
1286
 
 
1287
 
     pixelssum4 = vec_add((vector unsigned short)pixelsv3,
1288
 
                          (vector unsigned short)pixelsv4);
1289
 
     pixelssum2 = vec_add((vector unsigned short)pixelsv1,
1290
 
                          (vector unsigned short)pixelsv2);
1291
 
     temp4 = vec_add(pixelssum3, pixelssum4);
1292
 
     temp4 = vec_sra(temp4, vctwo);
1293
 
     temp3 = vec_add(pixelssum1, pixelssum2);
1294
 
     temp3 = vec_sra(temp3, vctwo);
1295
 
 
1296
 
     pixelssum3 = vec_add(pixelssum4, vcone);
1297
 
     pixelssum1 = vec_add(pixelssum2, vcone);
1298
 
 
1299
 
     blockv = vec_packsu(temp3, temp4);
1300
 
 
1301
 
     vec_st(blockv, 0, block);
1302
 
 
1303
 
     block += line_size;
1304
 
     pixels += line_size;
1305
 
   }
1306
 
 
1307
 
POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1);
1308
 
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
1309
 
}
1310
 
 
1311
 
#ifdef CONFIG_DARWIN
1312
 
int hadamard8_diff8x8_altivec(/*MpegEncContext*/ void *s, uint8_t *dst, uint8_t *src, int stride, int h){
1313
 
POWERPC_PERF_DECLARE(altivec_hadamard8_diff8x8_num, 1);
1314
 
  int sum;
1315
 
POWERPC_PERF_START_COUNT(altivec_hadamard8_diff8x8_num, 1);
1316
 
  register const_vector unsigned char vzero = (const_vector unsigned char)vec_splat_u8(0);
1317
 
  register vector signed short temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
1318
 
  {
1319
 
    register const_vector signed short vprod1 = (const_vector signed short)AVV( 1,-1, 1,-1, 1,-1, 1,-1);
1320
 
    register const_vector signed short vprod2 = (const_vector signed short)AVV( 1, 1,-1,-1, 1, 1,-1,-1);
1321
 
    register const_vector signed short vprod3 = (const_vector signed short)AVV( 1, 1, 1, 1,-1,-1,-1,-1);
1322
 
    register const_vector unsigned char perm1 = (const_vector unsigned char)
1323
 
      AVV(0x02, 0x03, 0x00, 0x01,
1324
 
       0x06, 0x07, 0x04, 0x05,
1325
 
       0x0A, 0x0B, 0x08, 0x09,
1326
 
       0x0E, 0x0F, 0x0C, 0x0D);
1327
 
    register const_vector unsigned char perm2 = (const_vector unsigned char)
1328
 
      AVV(0x04, 0x05, 0x06, 0x07,
1329
 
       0x00, 0x01, 0x02, 0x03,
1330
 
       0x0C, 0x0D, 0x0E, 0x0F,
1331
 
       0x08, 0x09, 0x0A, 0x0B);
1332
 
    register const_vector unsigned char perm3 = (const_vector unsigned char)
1333
 
      AVV(0x08, 0x09, 0x0A, 0x0B,
1334
 
       0x0C, 0x0D, 0x0E, 0x0F,
1335
 
       0x00, 0x01, 0x02, 0x03,
1336
 
       0x04, 0x05, 0x06, 0x07);
1337
 
 
1338
 
#define ONEITERBUTTERFLY(i, res)                                        \
1339
 
    {                                                                   \
1340
 
      register vector unsigned char src1, src2, srcO;                   \
1341
 
      register vector unsigned char dst1, dst2, dstO;                   \
1342
 
      src1 = vec_ld(stride * i, src);                                   \
1343
 
      if ((((stride * i) + (unsigned long)src) & 0x0000000F) > 8)       \
1344
 
        src2 = vec_ld((stride * i) + 16, src);                          \
1345
 
      srcO = vec_perm(src1, src2, vec_lvsl(stride * i, src));           \
1346
 
      dst1 = vec_ld(stride * i, dst);                                   \
1347
 
      if ((((stride * i) + (unsigned long)dst) & 0x0000000F) > 8)       \
1348
 
        dst2 = vec_ld((stride * i) + 16, dst);                          \
1349
 
      dstO = vec_perm(dst1, dst2, vec_lvsl(stride * i, dst));           \
1350
 
      /* promote the unsigned chars to signed shorts */                 \
1351
 
      /* we're in the 8x8 function, we only care for the first 8 */     \
1352
 
      register vector signed short srcV =                               \
1353
 
        (vector signed short)vec_mergeh((vector signed char)vzero, (vector signed char)srcO); \
1354
 
      register vector signed short dstV =                               \
1355
 
        (vector signed short)vec_mergeh((vector signed char)vzero, (vector signed char)dstO); \
1356
 
      /* substractions inside the first butterfly */                    \
1357
 
      register vector signed short but0 = vec_sub(srcV, dstV);          \
1358
 
      register vector signed short op1 = vec_perm(but0, but0, perm1);   \
1359
 
      register vector signed short but1 = vec_mladd(but0, vprod1, op1); \
1360
 
      register vector signed short op2 = vec_perm(but1, but1, perm2);   \
1361
 
      register vector signed short but2 = vec_mladd(but1, vprod2, op2); \
1362
 
      register vector signed short op3 = vec_perm(but2, but2, perm3);   \
1363
 
      res = vec_mladd(but2, vprod3, op3);                               \
1364
 
    }
1365
 
    ONEITERBUTTERFLY(0, temp0);
1366
 
    ONEITERBUTTERFLY(1, temp1);
1367
 
    ONEITERBUTTERFLY(2, temp2);
1368
 
    ONEITERBUTTERFLY(3, temp3);
1369
 
    ONEITERBUTTERFLY(4, temp4);
1370
 
    ONEITERBUTTERFLY(5, temp5);
1371
 
    ONEITERBUTTERFLY(6, temp6);
1372
 
    ONEITERBUTTERFLY(7, temp7);
1373
 
  }
1374
 
#undef ONEITERBUTTERFLY
1375
 
  {
1376
 
    register vector signed int vsum;
1377
 
    register vector signed short line0 = vec_add(temp0, temp1);
1378
 
    register vector signed short line1 = vec_sub(temp0, temp1);
1379
 
    register vector signed short line2 = vec_add(temp2, temp3);
1380
 
    register vector signed short line3 = vec_sub(temp2, temp3);
1381
 
    register vector signed short line4 = vec_add(temp4, temp5);
1382
 
    register vector signed short line5 = vec_sub(temp4, temp5);
1383
 
    register vector signed short line6 = vec_add(temp6, temp7);
1384
 
    register vector signed short line7 = vec_sub(temp6, temp7);
1385
 
 
1386
 
    register vector signed short line0B = vec_add(line0, line2);
1387
 
    register vector signed short line2B = vec_sub(line0, line2);
1388
 
    register vector signed short line1B = vec_add(line1, line3);
1389
 
    register vector signed short line3B = vec_sub(line1, line3);
1390
 
    register vector signed short line4B = vec_add(line4, line6);
1391
 
    register vector signed short line6B = vec_sub(line4, line6);
1392
 
    register vector signed short line5B = vec_add(line5, line7);
1393
 
    register vector signed short line7B = vec_sub(line5, line7);
1394
 
 
1395
 
    register vector signed short line0C = vec_add(line0B, line4B);
1396
 
    register vector signed short line4C = vec_sub(line0B, line4B);
1397
 
    register vector signed short line1C = vec_add(line1B, line5B);
1398
 
    register vector signed short line5C = vec_sub(line1B, line5B);
1399
 
    register vector signed short line2C = vec_add(line2B, line6B);
1400
 
    register vector signed short line6C = vec_sub(line2B, line6B);
1401
 
    register vector signed short line3C = vec_add(line3B, line7B);
1402
 
    register vector signed short line7C = vec_sub(line3B, line7B);
1403
 
 
1404
 
    vsum = vec_sum4s(vec_abs(line0C), vec_splat_s32(0));
1405
 
    vsum = vec_sum4s(vec_abs(line1C), vsum);
1406
 
    vsum = vec_sum4s(vec_abs(line2C), vsum);
1407
 
    vsum = vec_sum4s(vec_abs(line3C), vsum);
1408
 
    vsum = vec_sum4s(vec_abs(line4C), vsum);
1409
 
    vsum = vec_sum4s(vec_abs(line5C), vsum);
1410
 
    vsum = vec_sum4s(vec_abs(line6C), vsum);
1411
 
    vsum = vec_sum4s(vec_abs(line7C), vsum);
1412
 
    vsum = vec_sums(vsum, (vector signed int)vzero);
1413
 
    vsum = vec_splat(vsum, 3);
1414
 
    vec_ste(vsum, 0, &sum);
1415
 
  }
1416
 
POWERPC_PERF_STOP_COUNT(altivec_hadamard8_diff8x8_num, 1);
1417
 
  return sum;
1418
 
}
1419
 
 
1420
 
/*
1421
 
  16x8 works with 16 elements ; it allows to avoid replicating
1422
 
  loads, and give the compiler more rooms for scheduling.
1423
 
  It's only used from inside hadamard8_diff16_altivec.
1424
 
 
1425
 
  Unfortunately, it seems gcc-3.3 is a bit dumb, and
1426
 
  the compiled code has a LOT of spill code, it seems
1427
 
  gcc (unlike xlc) cannot keep everything in registers
1428
 
  by itself. The following code include hand-made
1429
 
  registers allocation. It's not clean, but on
1430
 
  a 7450 the resulting code is much faster (best case
1431
 
  fall from 700+ cycles to 550).
1432
 
 
1433
 
  xlc doesn't add spill code, but it doesn't know how to
1434
 
  schedule for the 7450, and its code isn't much faster than
1435
 
  gcc-3.3 on the 7450 (but uses 25% less instructions...)
1436
 
 
1437
 
  On the 970, the hand-made RA is still a win (arount 690
1438
 
  vs. around 780), but xlc goes to around 660 on the
1439
 
  regular C code...
1440
 
*/
1441
 
 
1442
 
static int hadamard8_diff16x8_altivec(/*MpegEncContext*/ void *s, uint8_t *dst, uint8_t *src, int stride, int h) {
1443
 
  int sum;
1444
 
  register vector signed short
1445
 
    temp0 asm ("v0"),
1446
 
    temp1 asm ("v1"),
1447
 
    temp2 asm ("v2"),
1448
 
    temp3 asm ("v3"),
1449
 
    temp4 asm ("v4"),
1450
 
    temp5 asm ("v5"),
1451
 
    temp6 asm ("v6"),
1452
 
    temp7 asm ("v7");
1453
 
  register vector signed short
1454
 
    temp0S asm ("v8"),
1455
 
    temp1S asm ("v9"),
1456
 
    temp2S asm ("v10"),
1457
 
    temp3S asm ("v11"),
1458
 
    temp4S asm ("v12"),
1459
 
    temp5S asm ("v13"),
1460
 
    temp6S asm ("v14"),
1461
 
    temp7S asm ("v15");
1462
 
  register const_vector unsigned char vzero asm ("v31")= (const_vector unsigned char)vec_splat_u8(0);
1463
 
  {
1464
 
    register const_vector signed short vprod1 asm ("v16")= (const_vector signed short)AVV( 1,-1, 1,-1, 1,-1, 1,-1);
1465
 
    register const_vector signed short vprod2 asm ("v17")= (const_vector signed short)AVV( 1, 1,-1,-1, 1, 1,-1,-1);
1466
 
    register const_vector signed short vprod3 asm ("v18")= (const_vector signed short)AVV( 1, 1, 1, 1,-1,-1,-1,-1);
1467
 
    register const_vector unsigned char perm1 asm ("v19")= (const_vector unsigned char)
1468
 
      AVV(0x02, 0x03, 0x00, 0x01,
1469
 
       0x06, 0x07, 0x04, 0x05,
1470
 
       0x0A, 0x0B, 0x08, 0x09,
1471
 
       0x0E, 0x0F, 0x0C, 0x0D);
1472
 
    register const_vector unsigned char perm2 asm ("v20")= (const_vector unsigned char)
1473
 
      AVV(0x04, 0x05, 0x06, 0x07,
1474
 
       0x00, 0x01, 0x02, 0x03,
1475
 
       0x0C, 0x0D, 0x0E, 0x0F,
1476
 
       0x08, 0x09, 0x0A, 0x0B);
1477
 
    register const_vector unsigned char perm3 asm ("v21")= (const_vector unsigned char)
1478
 
      AVV(0x08, 0x09, 0x0A, 0x0B,
1479
 
       0x0C, 0x0D, 0x0E, 0x0F,
1480
 
       0x00, 0x01, 0x02, 0x03,
1481
 
       0x04, 0x05, 0x06, 0x07);
1482
 
 
1483
 
#define ONEITERBUTTERFLY(i, res1, res2)                                 \
1484
 
    {                                                                   \
1485
 
      register vector unsigned char src1 asm ("v22"), src2 asm ("v23"); \
1486
 
      register vector unsigned char dst1 asm ("v24"), dst2 asm ("v25"); \
1487
 
      src1 = vec_ld(stride * i, src);                                   \
1488
 
      src2 = vec_ld((stride * i) + 16, src);                            \
1489
 
      register vector unsigned char srcO asm ("v22") = vec_perm(src1, src2, vec_lvsl(stride * i, src)); \
1490
 
      dst1 = vec_ld(stride * i, dst);                                   \
1491
 
      dst2 = vec_ld((stride * i) + 16, dst);                            \
1492
 
      register vector unsigned char dstO asm ("v23") = vec_perm(dst1, dst2, vec_lvsl(stride * i, dst)); \
1493
 
      /* promote the unsigned chars to signed shorts */                 \
1494
 
      register vector signed short srcV asm ("v24") =                   \
1495
 
        (vector signed short)vec_mergeh((vector signed char)vzero, (vector signed char)srcO); \
1496
 
      register vector signed short dstV asm ("v25") =                   \
1497
 
        (vector signed short)vec_mergeh((vector signed char)vzero, (vector signed char)dstO); \
1498
 
      register vector signed short srcW asm ("v26") =                   \
1499
 
        (vector signed short)vec_mergel((vector signed char)vzero, (vector signed char)srcO); \
1500
 
      register vector signed short dstW asm ("v27") =                   \
1501
 
        (vector signed short)vec_mergel((vector signed char)vzero, (vector signed char)dstO); \
1502
 
      /* substractions inside the first butterfly */                    \
1503
 
      register vector signed short but0 asm ("v28") = vec_sub(srcV, dstV); \
1504
 
      register vector signed short but0S asm ("v29") = vec_sub(srcW, dstW); \
1505
 
      register vector signed short op1 asm ("v30") = vec_perm(but0, but0, perm1); \
1506
 
      register vector signed short but1 asm ("v22") = vec_mladd(but0, vprod1, op1); \
1507
 
      register vector signed short op1S asm ("v23") = vec_perm(but0S, but0S, perm1); \
1508
 
      register vector signed short but1S asm ("v24") = vec_mladd(but0S, vprod1, op1S); \
1509
 
      register vector signed short op2 asm ("v25") = vec_perm(but1, but1, perm2); \
1510
 
      register vector signed short but2 asm ("v26") = vec_mladd(but1, vprod2, op2); \
1511
 
      register vector signed short op2S asm ("v27") = vec_perm(but1S, but1S, perm2); \
1512
 
      register vector signed short but2S asm ("v28") = vec_mladd(but1S, vprod2, op2S); \
1513
 
      register vector signed short op3 asm ("v29") = vec_perm(but2, but2, perm3); \
1514
 
      res1 = vec_mladd(but2, vprod3, op3);                              \
1515
 
      register vector signed short op3S asm ("v30") = vec_perm(but2S, but2S, perm3); \
1516
 
      res2 = vec_mladd(but2S, vprod3, op3S);                            \
1517
 
    }
1518
 
    ONEITERBUTTERFLY(0, temp0, temp0S);
1519
 
    ONEITERBUTTERFLY(1, temp1, temp1S);
1520
 
    ONEITERBUTTERFLY(2, temp2, temp2S);
1521
 
    ONEITERBUTTERFLY(3, temp3, temp3S);
1522
 
    ONEITERBUTTERFLY(4, temp4, temp4S);
1523
 
    ONEITERBUTTERFLY(5, temp5, temp5S);
1524
 
    ONEITERBUTTERFLY(6, temp6, temp6S);
1525
 
    ONEITERBUTTERFLY(7, temp7, temp7S);
1526
 
  }
1527
 
#undef ONEITERBUTTERFLY
1528
 
  {
1529
 
    register vector signed int vsum;
1530
 
    register vector signed short line0 = vec_add(temp0, temp1);
1531
 
    register vector signed short line1 = vec_sub(temp0, temp1);
1532
 
    register vector signed short line2 = vec_add(temp2, temp3);
1533
 
    register vector signed short line3 = vec_sub(temp2, temp3);
1534
 
    register vector signed short line4 = vec_add(temp4, temp5);
1535
 
    register vector signed short line5 = vec_sub(temp4, temp5);
1536
 
    register vector signed short line6 = vec_add(temp6, temp7);
1537
 
    register vector signed short line7 = vec_sub(temp6, temp7);
1538
 
 
1539
 
    register vector signed short line0B = vec_add(line0, line2);
1540
 
    register vector signed short line2B = vec_sub(line0, line2);
1541
 
    register vector signed short line1B = vec_add(line1, line3);
1542
 
    register vector signed short line3B = vec_sub(line1, line3);
1543
 
    register vector signed short line4B = vec_add(line4, line6);
1544
 
    register vector signed short line6B = vec_sub(line4, line6);
1545
 
    register vector signed short line5B = vec_add(line5, line7);
1546
 
    register vector signed short line7B = vec_sub(line5, line7);
1547
 
 
1548
 
    register vector signed short line0C = vec_add(line0B, line4B);
1549
 
    register vector signed short line4C = vec_sub(line0B, line4B);
1550
 
    register vector signed short line1C = vec_add(line1B, line5B);
1551
 
    register vector signed short line5C = vec_sub(line1B, line5B);
1552
 
    register vector signed short line2C = vec_add(line2B, line6B);
1553
 
    register vector signed short line6C = vec_sub(line2B, line6B);
1554
 
    register vector signed short line3C = vec_add(line3B, line7B);
1555
 
    register vector signed short line7C = vec_sub(line3B, line7B);
1556
 
 
1557
 
    vsum = vec_sum4s(vec_abs(line0C), vec_splat_s32(0));
1558
 
    vsum = vec_sum4s(vec_abs(line1C), vsum);
1559
 
    vsum = vec_sum4s(vec_abs(line2C), vsum);
1560
 
    vsum = vec_sum4s(vec_abs(line3C), vsum);
1561
 
    vsum = vec_sum4s(vec_abs(line4C), vsum);
1562
 
    vsum = vec_sum4s(vec_abs(line5C), vsum);
1563
 
    vsum = vec_sum4s(vec_abs(line6C), vsum);
1564
 
    vsum = vec_sum4s(vec_abs(line7C), vsum);
1565
 
 
1566
 
    register vector signed short line0S = vec_add(temp0S, temp1S);
1567
 
    register vector signed short line1S = vec_sub(temp0S, temp1S);
1568
 
    register vector signed short line2S = vec_add(temp2S, temp3S);
1569
 
    register vector signed short line3S = vec_sub(temp2S, temp3S);
1570
 
    register vector signed short line4S = vec_add(temp4S, temp5S);
1571
 
    register vector signed short line5S = vec_sub(temp4S, temp5S);
1572
 
    register vector signed short line6S = vec_add(temp6S, temp7S);
1573
 
    register vector signed short line7S = vec_sub(temp6S, temp7S);
1574
 
 
1575
 
    register vector signed short line0BS = vec_add(line0S, line2S);
1576
 
    register vector signed short line2BS = vec_sub(line0S, line2S);
1577
 
    register vector signed short line1BS = vec_add(line1S, line3S);
1578
 
    register vector signed short line3BS = vec_sub(line1S, line3S);
1579
 
    register vector signed short line4BS = vec_add(line4S, line6S);
1580
 
    register vector signed short line6BS = vec_sub(line4S, line6S);
1581
 
    register vector signed short line5BS = vec_add(line5S, line7S);
1582
 
    register vector signed short line7BS = vec_sub(line5S, line7S);
1583
 
 
1584
 
    register vector signed short line0CS = vec_add(line0BS, line4BS);
1585
 
    register vector signed short line4CS = vec_sub(line0BS, line4BS);
1586
 
    register vector signed short line1CS = vec_add(line1BS, line5BS);
1587
 
    register vector signed short line5CS = vec_sub(line1BS, line5BS);
1588
 
    register vector signed short line2CS = vec_add(line2BS, line6BS);
1589
 
    register vector signed short line6CS = vec_sub(line2BS, line6BS);
1590
 
    register vector signed short line3CS = vec_add(line3BS, line7BS);
1591
 
    register vector signed short line7CS = vec_sub(line3BS, line7BS);
1592
 
 
1593
 
    vsum = vec_sum4s(vec_abs(line0CS), vsum);
1594
 
    vsum = vec_sum4s(vec_abs(line1CS), vsum);
1595
 
    vsum = vec_sum4s(vec_abs(line2CS), vsum);
1596
 
    vsum = vec_sum4s(vec_abs(line3CS), vsum);
1597
 
    vsum = vec_sum4s(vec_abs(line4CS), vsum);
1598
 
    vsum = vec_sum4s(vec_abs(line5CS), vsum);
1599
 
    vsum = vec_sum4s(vec_abs(line6CS), vsum);
1600
 
    vsum = vec_sum4s(vec_abs(line7CS), vsum);
1601
 
    vsum = vec_sums(vsum, (vector signed int)vzero);
1602
 
    vsum = vec_splat(vsum, 3);
1603
 
    vec_ste(vsum, 0, &sum);
1604
 
  }
1605
 
  return sum;
1606
 
}
1607
 
 
1608
 
int hadamard8_diff16_altivec(/*MpegEncContext*/ void *s, uint8_t *dst, uint8_t *src, int stride, int h){
1609
 
POWERPC_PERF_DECLARE(altivec_hadamard8_diff16_num, 1);
1610
 
  int score;
1611
 
POWERPC_PERF_START_COUNT(altivec_hadamard8_diff16_num, 1);
1612
 
  score = hadamard8_diff16x8_altivec(s, dst, src, stride, 8);
1613
 
  if (h==16) {
1614
 
    dst += 8*stride;
1615
 
    src += 8*stride;
1616
 
    score += hadamard8_diff16x8_altivec(s, dst, src, stride, 8);
1617
 
  }
1618
 
POWERPC_PERF_STOP_COUNT(altivec_hadamard8_diff16_num, 1);
1619
 
  return score;
1620
 
}
1621
 
#endif //CONFIG_DARWIN
1622
 
 
1623
 
int has_altivec(void)
1624
 
{
1625
 
#ifdef __AMIGAOS4__
1626
 
        ULONG result = 0;
1627
 
        extern struct ExecIFace *IExec;
1628
 
 
1629
 
        IExec->GetCPUInfoTags(GCIT_VectorUnit, &result, TAG_DONE);
1630
 
        if (result == VECTORTYPE_ALTIVEC) return 1;
1631
 
        return 0;
1632
 
#else /* __AMIGAOS4__ */
1633
 
 
1634
 
#ifdef CONFIG_DARWIN
1635
 
    int sels[2] = {CTL_HW, HW_VECTORUNIT};
1636
 
    int has_vu = 0;
1637
 
    size_t len = sizeof(has_vu);
1638
 
    int err;
1639
 
 
1640
 
    err = sysctl(sels, 2, &has_vu, &len, NULL, 0);
1641
 
 
1642
 
    if (err == 0) return (has_vu != 0);
1643
 
#else /* CONFIG_DARWIN */
1644
 
/* no Darwin, do it the brute-force way */
1645
 
/* this is borrowed from the libmpeg2 library */
1646
 
    {
1647
 
      signal (SIGILL, sigill_handler);
1648
 
      if (sigsetjmp (jmpbuf, 1)) {
1649
 
        signal (SIGILL, SIG_DFL);
1650
 
      } else {
1651
 
        canjump = 1;
1652
 
 
1653
 
        asm volatile ("mtspr 256, %0\n\t"
1654
 
                      "vand %%v0, %%v0, %%v0"
1655
 
                      :
1656
 
                      : "r" (-1));
1657
 
 
1658
 
        signal (SIGILL, SIG_DFL);
1659
 
        return 1;
1660
 
      }
1661
 
    }
1662
 
#endif /* CONFIG_DARWIN */
1663
 
    return 0;
1664
 
#endif /* __AMIGAOS4__ */
1665
 
}
1666
 
 
1667
 
/* next one assumes that ((line_size % 8) == 0) */
1668
 
void avg_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
1669
 
{
1670
 
POWERPC_PERF_DECLARE(altivec_avg_pixels8_xy2_num, 1);
1671
 
#ifdef ALTIVEC_USE_REFERENCE_C_CODE
1672
 
 
1673
 
    int j;
1674
 
POWERPC_PERF_START_COUNT(altivec_avg_pixels8_xy2_num, 1);
1675
 
 for (j = 0; j < 2; j++) {
1676
 
   int             i;
1677
 
   const uint32_t  a = (((const struct unaligned_32 *) (pixels))->l);
1678
 
   const uint32_t  b = (((const struct unaligned_32 *) (pixels + 1))->l);
1679
 
   uint32_t        l0 = (a & 0x03030303UL) + (b & 0x03030303UL) + 0x02020202UL;
1680
 
   uint32_t        h0 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
1681
 
   uint32_t        l1, h1;
1682
 
   pixels += line_size;
1683
 
   for (i = 0; i < h; i += 2) {
1684
 
     uint32_t        a = (((const struct unaligned_32 *) (pixels))->l);
1685
 
     uint32_t        b = (((const struct unaligned_32 *) (pixels + 1))->l);
1686
 
     l1 = (a & 0x03030303UL) + (b & 0x03030303UL);
1687
 
     h1 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
1688
 
     *((uint32_t *) block) = rnd_avg32(*((uint32_t *) block), h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL));
1689
 
     pixels += line_size;
1690
 
     block += line_size;
1691
 
     a = (((const struct unaligned_32 *) (pixels))->l);
1692
 
     b = (((const struct unaligned_32 *) (pixels + 1))->l);
1693
 
     l0 = (a & 0x03030303UL) + (b & 0x03030303UL) + 0x02020202UL;
1694
 
     h0 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
1695
 
     *((uint32_t *) block) = rnd_avg32(*((uint32_t *) block), h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL));
1696
 
     pixels += line_size;
1697
 
     block += line_size;
1698
 
   } pixels += 4 - line_size * (h + 1);
1699
 
   block += 4 - line_size * h;
1700
 
 }
1701
 
POWERPC_PERF_STOP_COUNT(altivec_avg_pixels8_xy2_num, 1);
1702
 
#else /* ALTIVEC_USE_REFERENCE_C_CODE */
1703
 
   register int i;
1704
 
   register vector unsigned char
1705
 
     pixelsv1, pixelsv2,
1706
 
     pixelsavg;
1707
 
   register vector unsigned char
1708
 
     blockv, temp1, temp2, blocktemp;
1709
 
   register vector unsigned short
1710
 
     pixelssum1, pixelssum2, temp3;
1711
 
   register const_vector unsigned char vczero = (const_vector unsigned char)vec_splat_u8(0);
1712
 
   register const_vector unsigned short vctwo = (const_vector unsigned short)vec_splat_u16(2);
1713
 
 
1714
 
   temp1 = vec_ld(0, pixels);
1715
 
   temp2 = vec_ld(16, pixels);
1716
 
   pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
1717
 
   if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F)
1718
 
   {
1719
 
     pixelsv2 = temp2;
1720
 
   }
1721
 
   else
1722
 
   {
1723
 
     pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
1724
 
   }
1725
 
   pixelsv1 = vec_mergeh(vczero, pixelsv1);
1726
 
   pixelsv2 = vec_mergeh(vczero, pixelsv2);
1727
 
   pixelssum1 = vec_add((vector unsigned short)pixelsv1,
1728
 
                        (vector unsigned short)pixelsv2);
1729
 
   pixelssum1 = vec_add(pixelssum1, vctwo);
1730
 
 
1731
 
POWERPC_PERF_START_COUNT(altivec_avg_pixels8_xy2_num, 1);
1732
 
   for (i = 0; i < h ; i++) {
1733
 
     int rightside = ((unsigned long)block & 0x0000000F);
1734
 
     blockv = vec_ld(0, block);
1735
 
 
1736
 
     temp1 = vec_ld(line_size, pixels);
1737
 
     temp2 = vec_ld(line_size + 16, pixels);
1738
 
     pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
1739
 
     if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F)
1740
 
     {
1741
 
       pixelsv2 = temp2;
1742
 
     }
1743
 
     else
1744
 
     {
1745
 
       pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
1746
 
     }
1747
 
 
1748
 
     pixelsv1 = vec_mergeh(vczero, pixelsv1);
1749
 
     pixelsv2 = vec_mergeh(vczero, pixelsv2);
1750
 
     pixelssum2 = vec_add((vector unsigned short)pixelsv1,
1751
 
                          (vector unsigned short)pixelsv2);
1752
 
     temp3 = vec_add(pixelssum1, pixelssum2);
1753
 
     temp3 = vec_sra(temp3, vctwo);
1754
 
     pixelssum1 = vec_add(pixelssum2, vctwo);
1755
 
     pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero);
1756
 
 
1757
 
     if (rightside)
1758
 
     {
1759
 
       blocktemp = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1));
1760
 
     }
1761
 
     else
1762
 
     {
1763
 
       blocktemp = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3));
1764
 
     }
1765
 
 
1766
 
     blockv = vec_avg(blocktemp, blockv);
1767
 
     vec_st(blockv, 0, block);
1768
 
 
1769
 
     block += line_size;
1770
 
     pixels += line_size;
1771
 
   }
1772
 
 
1773
 
POWERPC_PERF_STOP_COUNT(altivec_avg_pixels8_xy2_num, 1);
1774
 
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
1775
 
}