~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to ffmpeg/libavcodec/ppc/dsputil_altivec.c

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-25 15:47:12 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080225154712-qvr11ekcea4c9ry8
Tags: 1.1.6-0.1ubuntu1
* Merge from debian-multimedia (LP: #120003), Ubuntu Changes:
 - For ffmpeg-related build-deps, remove cvs from package names.
 - Standards-Version 3.7.3
 - Maintainer Spec

Show diffs side-by-side

added added

removed removed

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