~ubuntu-branches/ubuntu/edgy/gstreamer0.10-ffmpeg/edgy

« back to all changes in this revision

Viewing changes to gst-libs/ext/ffmpeg/libavcodec/ppc/dsputil_altivec.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2006-04-01 16:13:43 UTC
  • mto: This revision was merged to the branch mainline in revision 5.
  • Revision ID: james.westby@ubuntu.com-20060401161343-n621cgjlujio0otg
Tags: upstream-0.10.1
Import upstream version 0.10.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 *
16
16
 * You should have received a copy of the GNU Lesser General Public
17
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
 
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
19
 */
20
 
 
 
20
 
21
21
#include "dsputil.h"
22
22
 
23
23
#include "gcc_fixes.h"
44
44
        signal (sig, SIG_DFL);
45
45
        raise (sig);
46
46
    }
47
 
    
 
47
 
48
48
    canjump = 0;
49
49
    siglongjmp (jmpbuf, 1);
50
50
}
67
67
        /*
68
68
           Read unaligned pixels into our vectors. The vectors are as follows:
69
69
           pix1v: pix1[0]-pix1[15]
70
 
           pix2v: pix2[0]-pix2[15]      pix2iv: pix2[1]-pix2[16]
 
70
           pix2v: pix2[0]-pix2[15]      pix2iv: pix2[1]-pix2[16]
71
71
        */
72
72
        tv = (vector unsigned char *) pix1;
73
73
        pix1v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix1));
74
 
        
 
74
 
75
75
        tv = (vector unsigned char *) &pix2[0];
76
76
        pix2v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[0]));
77
77
 
86
86
 
87
87
        /* Add each 4 pixel group together and put 4 results into sad */
88
88
        sad = vec_sum4s(t5, sad);
89
 
        
 
89
 
90
90
        pix1 += line_size;
91
91
        pix2 += line_size;
92
92
    }
123
123
    */
124
124
    tv = (vector unsigned char *) &pix2[0];
125
125
    pix2v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[0]));
126
 
    
 
126
 
127
127
    for(i=0;i<h;i++) {
128
128
        /*
129
129
           Read unaligned pixels into our vectors. The vectors are as follows:
144
144
 
145
145
        /* Add each 4 pixel group together and put 4 results into sad */
146
146
        sad = vec_sum4s(t5, sad);
147
 
        
 
147
 
148
148
        pix1 += line_size;
149
149
        pix2v = pix3v;
150
150
        pix3 += line_size;
151
 
        
 
151
 
152
152
    }
153
 
    
 
153
 
154
154
    /* Sum up the four partial sums, and put the result into s */
155
155
    sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
156
156
    sumdiffs = vec_splat(sumdiffs, 3);
157
157
    vec_ste(sumdiffs, 0, &s);
158
 
    return s;    
 
158
    return s;
159
159
}
160
160
 
161
161
int sad16_xy2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
175
175
    vector signed int sumdiffs;
176
176
 
177
177
    sad = (vector unsigned int)vec_splat_u32(0);
178
 
    
 
178
 
179
179
    s = 0;
180
180
 
181
181
    /*
184
184
       fact to avoid a potentially expensive unaligned read, as well
185
185
       as some splitting, and vector addition each time around the loop.
186
186
       Read unaligned pixels into our vectors. The vectors are as follows:
187
 
       pix2v: pix2[0]-pix2[15]  pix2iv: pix2[1]-pix2[16]
 
187
       pix2v: pix2[0]-pix2[15]  pix2iv: pix2[1]-pix2[16]
188
188
       Split the pixel vectors into shorts
189
189
    */
190
190
    tv = (vector unsigned char *) &pix2[0];
199
199
    pix2ilv = (vector unsigned short) vec_mergel(zero, pix2iv);
200
200
    t1 = vec_add(pix2hv, pix2ihv);
201
201
    t2 = vec_add(pix2lv, pix2ilv);
202
 
    
 
202
 
203
203
    for(i=0;i<h;i++) {
204
204
        /*
205
205
           Read unaligned pixels into our vectors. The vectors are as follows:
206
206
           pix1v: pix1[0]-pix1[15]
207
 
           pix3v: pix3[0]-pix3[15]      pix3iv: pix3[1]-pix3[16]
 
207
           pix3v: pix3[0]-pix3[15]      pix3iv: pix3[1]-pix3[16]
208
208
        */
209
209
        tv = (vector unsigned char *) pix1;
210
210
        pix1v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix1));
268
268
    vector unsigned char t1, t2, t3,t4, t5;
269
269
    vector unsigned int sad;
270
270
    vector signed int sumdiffs;
271
 
    
 
271
 
272
272
    sad = (vector unsigned int)vec_splat_u32(0);
273
273
 
274
274
 
275
275
    for(i=0;i<h;i++) {
276
 
        /* Read potentially unaligned pixels into t1 and t2 */
 
276
        /* Read potentially unaligned pixels into t1 and t2 */
277
277
        perm1 = vec_lvsl(0, pix1);
278
278
        pix1v = (vector unsigned char *) pix1;
279
279
        perm2 = vec_lvsl(0, pix2);
280
280
        pix2v = (vector unsigned char *) pix2;
281
281
        t1 = vec_perm(pix1v[0], pix1v[1], perm1);
282
282
        t2 = vec_perm(pix2v[0], pix2v[1], perm2);
283
 
       
284
 
        /* Calculate a sum of abs differences vector */ 
 
283
 
 
284
        /* Calculate a sum of abs differences vector */
285
285
        t3 = vec_max(t1, t2);
286
286
        t4 = vec_min(t1, t2);
287
287
        t5 = vec_sub(t3, t4);
288
 
        
289
 
        /* Add each 4 pixel group together and put 4 results into sad */
 
288
 
 
289
        /* Add each 4 pixel group together and put 4 results into sad */
290
290
        sad = vec_sum4s(t5, sad);
291
291
 
292
292
        pix1 += line_size;
297
297
    sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
298
298
    sumdiffs = vec_splat(sumdiffs, 3);
299
299
    vec_ste(sumdiffs, 0, &s);
300
 
    
 
300
 
301
301
    return s;
302
302
}
303
303
 
316
316
    permclear = (vector unsigned char)AVV(255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0);
317
317
 
318
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. */
 
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
322
        perm1 = vec_lvsl(0, pix1);
323
323
        pix1v = (vector unsigned char *) pix1;
324
324
        perm2 = vec_lvsl(0, pix2);
326
326
        t1 = vec_and(vec_perm(pix1v[0], pix1v[1], perm1), permclear);
327
327
        t2 = vec_and(vec_perm(pix2v[0], pix2v[1], perm2), permclear);
328
328
 
329
 
        /* Calculate a sum of abs differences vector */ 
 
329
        /* Calculate a sum of abs differences vector */
330
330
        t3 = vec_max(t1, t2);
331
331
        t4 = vec_min(t1, t2);
332
332
        t5 = vec_sub(t3, t4);
333
333
 
334
 
        /* Add each 4 pixel group together and put 4 results into sad */
 
334
        /* Add each 4 pixel group together and put 4 results into sad */
335
335
        sad = vec_sum4s(t5, sad);
336
336
 
337
337
        pix1 += line_size;
355
355
    vector unsigned char pixv;
356
356
    vector unsigned int sv;
357
357
    vector signed int sum;
358
 
    
 
358
 
359
359
    sv = (vector unsigned int)vec_splat_u32(0);
360
 
    
 
360
 
361
361
    s = 0;
362
362
    for (i = 0; i < 16; i++) {
363
363
        /* Read in the potentially unaligned pixels */
391
391
    vector unsigned char t1, t2, t3,t4, t5;
392
392
    vector unsigned int sum;
393
393
    vector signed int sumsqr;
394
 
    
 
394
 
395
395
    sum = (vector unsigned int)vec_splat_u32(0);
396
396
 
397
397
    permclear = (vector unsigned char)AVV(255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0);
398
398
 
399
 
    
 
399
 
400
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. */
 
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
404
        perm1 = vec_lvsl(0, pix1);
405
405
        pix1v = (vector unsigned char *) pix1;
406
406
        perm2 = vec_lvsl(0, pix2);
412
412
          Since we want to use unsigned chars, we can take advantage
413
413
          of the fact that abs(a-b)^2 = (a-b)^2.
414
414
        */
415
 
        
416
 
        /* Calculate abs differences vector */ 
 
415
 
 
416
        /* Calculate abs differences vector */
417
417
        t3 = vec_max(t1, t2);
418
418
        t4 = vec_min(t1, t2);
419
419
        t5 = vec_sub(t3, t4);
420
 
        
 
420
 
421
421
        /* Square the values and add them to our sum */
422
422
        sum = vec_msum(t5, t5, sum);
423
 
        
 
423
 
424
424
        pix1 += line_size;
425
425
        pix2 += line_size;
426
426
    }
427
 
    
 
427
 
428
428
    /* Sum up the four partial sums, and put the result into s */
429
429
    sumsqr = vec_sums((vector signed int) sum, (vector signed int) zero);
430
430
    sumsqr = vec_splat(sumsqr, 3);
431
431
    vec_ste(sumsqr, 0, &s);
432
 
    
 
432
 
433
433
    return s;
434
434
}
435
435
 
447
447
    vector unsigned char t1, t2, t3,t4, t5;
448
448
    vector unsigned int sum;
449
449
    vector signed int sumsqr;
450
 
    
 
450
 
451
451
    sum = (vector unsigned int)vec_splat_u32(0);
452
 
    
 
452
 
453
453
    for(i=0;i<h;i++) {
454
 
        /* Read potentially unaligned pixels into t1 and t2 */
 
454
        /* Read potentially unaligned pixels into t1 and t2 */
455
455
        perm1 = vec_lvsl(0, pix1);
456
456
        pix1v = (vector unsigned char *) pix1;
457
457
        perm2 = vec_lvsl(0, pix2);
463
463
          Since we want to use unsigned chars, we can take advantage
464
464
          of the fact that abs(a-b)^2 = (a-b)^2.
465
465
        */
466
 
        
467
 
        /* Calculate abs differences vector */ 
 
466
 
 
467
        /* Calculate abs differences vector */
468
468
        t3 = vec_max(t1, t2);
469
469
        t4 = vec_min(t1, t2);
470
470
        t5 = vec_sub(t3, t4);
471
 
        
 
471
 
472
472
        /* Square the values and add them to our sum */
473
473
        sum = vec_msum(t5, t5, sum);
474
 
        
 
474
 
475
475
        pix1 += line_size;
476
476
        pix2 += line_size;
477
477
    }
478
 
    
 
478
 
479
479
    /* Sum up the four partial sums, and put the result into s */
480
480
    sumsqr = vec_sums((vector signed int) sum, (vector signed int) zero);
481
481
    sumsqr = vec_splat(sumsqr, 3);
482
482
    vec_ste(sumsqr, 0, &s);
483
 
    
 
483
 
484
484
    return s;
485
485
}
486
486
 
494
494
 
495
495
    int i;
496
496
    int s __attribute__((aligned(16)));
497
 
    
 
497
 
498
498
    sad = (vector unsigned int)vec_splat_u32(0);
499
 
    
 
499
 
500
500
    for (i = 0; i < 16; i++) {
501
 
        /* Read the potentially unaligned 16 pixels into t1 */
 
501
        /* Read the potentially unaligned 16 pixels into t1 */
502
502
        perm = vec_lvsl(0, pix);
503
503
        pixv = (vector unsigned char *) pix;
504
504
        t1 = vec_perm(pixv[0], pixv[1], perm);
505
505
 
506
 
        /* Add each 4 pixel group together and put 4 results into sad */
 
506
        /* Add each 4 pixel group together and put 4 results into sad */
507
507
        sad = vec_sum4s(t1, sad);
508
 
        
 
508
 
509
509
        pix += line_size;
510
510
    }
511
 
    
 
511
 
512
512
    /* Sum up the four partial sums, and put the result into s */
513
513
    sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
514
514
    sumdiffs = vec_splat(sumdiffs, 3);
515
515
    vec_ste(sumdiffs, 0, &s);
516
 
    
 
516
 
517
517
    return s;
518
518
}
519
519
 
633
633
#else /* ALTIVEC_USE_REFERENCE_C_CODE */
634
634
    register int i;
635
635
    register vector unsigned char vdst, vsrc;
636
 
    
 
636
 
637
637
    /* dst and src are 16 bytes-aligned (guaranteed) */
638
638
    for(i = 0 ; (i + 15) < w ; i++)
639
639
    {
799
799
    int i;
800
800
 
801
801
POWERPC_PERF_START_COUNT(altivec_avg_pixels8_num, 1);
802
 
 
 
802
 
803
803
   for (i = 0; i < h; i++) {
804
804
     /*
805
805
       block is 8 bytes-aligned, so we're either in the
806
806
       left block (16 bytes-aligned) or in the right block (not)
807
807
     */
808
808
     int rightside = ((unsigned long)block & 0x0000000F);
809
 
     
 
809
 
810
810
     blockv = vec_ld(0, block);
811
811
     pixelsv1 = vec_ld(0, (unsigned char*)pixels);
812
812
     pixelsv2 = vec_ld(16, (unsigned char*)pixels);
813
813
     pixelsv = vec_perm(pixelsv1, pixelsv2, vec_lvsl(0, pixels));
814
 
     
 
814
 
815
815
     if (rightside)
816
816
     {
817
817
       pixelsv = vec_perm(blockv, pixelsv, vcprm(0,1,s0,s1));
820
820
     {
821
821
       pixelsv = vec_perm(blockv, pixelsv, vcprm(s0,s1,2,3));
822
822
     }
823
 
     
 
823
 
824
824
     blockv = vec_avg(blockv, pixelsv);
825
825
 
826
826
     vec_st(blockv, 0, block);
827
 
     
 
827
 
828
828
     pixels += line_size;
829
829
     block += line_size;
830
830
   }
831
 
   
 
831
 
832
832
POWERPC_PERF_STOP_COUNT(altivec_avg_pixels8_num, 1);
833
 
 
 
833
 
834
834
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
835
835
}
836
836
 
886
886
     pixelssum1, pixelssum2, temp3;
887
887
   register const_vector unsigned char vczero = (const_vector unsigned char)vec_splat_u8(0);
888
888
   register const_vector unsigned short vctwo = (const_vector unsigned short)vec_splat_u16(2);
889
 
   
 
889
 
890
890
   temp1 = vec_ld(0, pixels);
891
891
   temp2 = vec_ld(16, pixels);
892
892
   pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
903
903
   pixelssum1 = vec_add((vector unsigned short)pixelsv1,
904
904
                        (vector unsigned short)pixelsv2);
905
905
   pixelssum1 = vec_add(pixelssum1, vctwo);
906
 
   
907
 
POWERPC_PERF_START_COUNT(altivec_put_pixels8_xy2_num, 1); 
 
906
 
 
907
POWERPC_PERF_START_COUNT(altivec_put_pixels8_xy2_num, 1);
908
908
   for (i = 0; i < h ; i++) {
909
909
     int rightside = ((unsigned long)block & 0x0000000F);
910
910
     blockv = vec_ld(0, block);
929
929
     temp3 = vec_sra(temp3, vctwo);
930
930
     pixelssum1 = vec_add(pixelssum2, vctwo);
931
931
     pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero);
932
 
     
 
932
 
933
933
     if (rightside)
934
934
     {
935
935
       blockv = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1));
938
938
     {
939
939
       blockv = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3));
940
940
     }
941
 
     
 
941
 
942
942
     vec_st(blockv, 0, block);
943
 
     
 
943
 
944
944
     block += line_size;
945
945
     pixels += line_size;
946
946
   }
947
 
   
 
947
 
948
948
POWERPC_PERF_STOP_COUNT(altivec_put_pixels8_xy2_num, 1);
949
949
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
950
950
}
987
987
      } pixels += 4 - line_size * (h + 1);
988
988
      block += 4 - line_size * h;
989
989
    }
990
 
    
 
990
 
991
991
POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1);
992
992
 
993
993
#else /* ALTIVEC_USE_REFERENCE_C_CODE */
1002
1002
   register const_vector unsigned char vczero = (const_vector unsigned char)vec_splat_u8(0);
1003
1003
   register const_vector unsigned short vcone = (const_vector unsigned short)vec_splat_u16(1);
1004
1004
   register const_vector unsigned short vctwo = (const_vector unsigned short)vec_splat_u16(2);
1005
 
   
 
1005
 
1006
1006
   temp1 = vec_ld(0, pixels);
1007
1007
   temp2 = vec_ld(16, pixels);
1008
1008
   pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
1019
1019
   pixelssum1 = vec_add((vector unsigned short)pixelsv1,
1020
1020
                        (vector unsigned short)pixelsv2);
1021
1021
   pixelssum1 = vec_add(pixelssum1, vcone);
1022
 
   
1023
 
POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1); 
 
1022
 
 
1023
POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1);
1024
1024
   for (i = 0; i < h ; i++) {
1025
1025
     int rightside = ((unsigned long)block & 0x0000000F);
1026
1026
     blockv = vec_ld(0, block);
1045
1045
     temp3 = vec_sra(temp3, vctwo);
1046
1046
     pixelssum1 = vec_add(pixelssum2, vcone);
1047
1047
     pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero);
1048
 
     
 
1048
 
1049
1049
     if (rightside)
1050
1050
     {
1051
1051
       blockv = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1));
1054
1054
     {
1055
1055
       blockv = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3));
1056
1056
     }
1057
 
     
 
1057
 
1058
1058
     vec_st(blockv, 0, block);
1059
 
     
 
1059
 
1060
1060
     block += line_size;
1061
1061
     pixels += line_size;
1062
1062
   }
1063
 
   
 
1063
 
1064
1064
POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1);
1065
1065
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
1066
1066
}
1119
1119
   register const_vector unsigned short vctwo = (const_vector unsigned short)vec_splat_u16(2);
1120
1120
 
1121
1121
POWERPC_PERF_START_COUNT(altivec_put_pixels16_xy2_num, 1);
1122
 
 
 
1122
 
1123
1123
   temp1 = vec_ld(0, pixels);
1124
1124
   temp2 = vec_ld(16, pixels);
1125
1125
   pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
1141
1141
   pixelssum1 = vec_add((vector unsigned short)pixelsv1,
1142
1142
                        (vector unsigned short)pixelsv2);
1143
1143
   pixelssum1 = vec_add(pixelssum1, vctwo);
1144
 
   
 
1144
 
1145
1145
   for (i = 0; i < h ; i++) {
1146
1146
     blockv = vec_ld(0, block);
1147
1147
 
1161
1161
     pixelsv4 = vec_mergel(vczero, pixelsv2);
1162
1162
     pixelsv1 = vec_mergeh(vczero, pixelsv1);
1163
1163
     pixelsv2 = vec_mergeh(vczero, pixelsv2);
1164
 
     
 
1164
 
1165
1165
     pixelssum4 = vec_add((vector unsigned short)pixelsv3,
1166
1166
                          (vector unsigned short)pixelsv4);
1167
1167
     pixelssum2 = vec_add((vector unsigned short)pixelsv1,
1175
1175
     pixelssum1 = vec_add(pixelssum2, vctwo);
1176
1176
 
1177
1177
     blockv = vec_packsu(temp3, temp4);
1178
 
     
 
1178
 
1179
1179
     vec_st(blockv, 0, block);
1180
 
     
 
1180
 
1181
1181
     block += line_size;
1182
1182
     pixels += line_size;
1183
1183
   }
1184
 
   
 
1184
 
1185
1185
POWERPC_PERF_STOP_COUNT(altivec_put_pixels16_xy2_num, 1);
1186
1186
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
1187
1187
}
1241
1241
   register const_vector unsigned short vctwo = (const_vector unsigned short)vec_splat_u16(2);
1242
1242
 
1243
1243
POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1);
1244
 
 
 
1244
 
1245
1245
   temp1 = vec_ld(0, pixels);
1246
1246
   temp2 = vec_ld(16, pixels);
1247
1247
   pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
1263
1263
   pixelssum1 = vec_add((vector unsigned short)pixelsv1,
1264
1264
                        (vector unsigned short)pixelsv2);
1265
1265
   pixelssum1 = vec_add(pixelssum1, vcone);
1266
 
   
 
1266
 
1267
1267
   for (i = 0; i < h ; i++) {
1268
1268
     blockv = vec_ld(0, block);
1269
1269
 
1283
1283
     pixelsv4 = vec_mergel(vczero, pixelsv2);
1284
1284
     pixelsv1 = vec_mergeh(vczero, pixelsv1);
1285
1285
     pixelsv2 = vec_mergeh(vczero, pixelsv2);
1286
 
     
 
1286
 
1287
1287
     pixelssum4 = vec_add((vector unsigned short)pixelsv3,
1288
1288
                          (vector unsigned short)pixelsv4);
1289
1289
     pixelssum2 = vec_add((vector unsigned short)pixelsv1,
1297
1297
     pixelssum1 = vec_add(pixelssum2, vcone);
1298
1298
 
1299
1299
     blockv = vec_packsu(temp3, temp4);
1300
 
     
 
1300
 
1301
1301
     vec_st(blockv, 0, block);
1302
 
     
 
1302
 
1303
1303
     block += line_size;
1304
1304
     pixels += line_size;
1305
1305
   }
1306
 
   
 
1306
 
1307
1307
POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1);
1308
1308
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
1309
1309
}
1335
1335
       0x00, 0x01, 0x02, 0x03,
1336
1336
       0x04, 0x05, 0x06, 0x07);
1337
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);                               \
 
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
1364
    }
1365
1365
    ONEITERBUTTERFLY(0, temp0);
1366
1366
    ONEITERBUTTERFLY(1, temp1);
1382
1382
    register vector signed short line5 = vec_sub(temp4, temp5);
1383
1383
    register vector signed short line6 = vec_add(temp6, temp7);
1384
1384
    register vector signed short line7 = vec_sub(temp6, temp7);
1385
 
    
 
1385
 
1386
1386
    register vector signed short line0B = vec_add(line0, line2);
1387
1387
    register vector signed short line2B = vec_sub(line0, line2);
1388
1388
    register vector signed short line1B = vec_add(line1, line3);
1391
1391
    register vector signed short line6B = vec_sub(line4, line6);
1392
1392
    register vector signed short line5B = vec_add(line5, line7);
1393
1393
    register vector signed short line7B = vec_sub(line5, line7);
1394
 
    
 
1394
 
1395
1395
    register vector signed short line0C = vec_add(line0B, line4B);
1396
1396
    register vector signed short line4C = vec_sub(line0B, line4B);
1397
1397
    register vector signed short line1C = vec_add(line1B, line5B);
1400
1400
    register vector signed short line6C = vec_sub(line2B, line6B);
1401
1401
    register vector signed short line3C = vec_add(line3B, line7B);
1402
1402
    register vector signed short line7C = vec_sub(line3B, line7B);
1403
 
    
 
1403
 
1404
1404
    vsum = vec_sum4s(vec_abs(line0C), vec_splat_s32(0));
1405
1405
    vsum = vec_sum4s(vec_abs(line1C), vsum);
1406
1406
    vsum = vec_sum4s(vec_abs(line2C), vsum);
1421
1421
  16x8 works with 16 elements ; it allows to avoid replicating
1422
1422
  loads, and give the compiler more rooms for scheduling.
1423
1423
  It's only used from inside hadamard8_diff16_altivec.
1424
 
  
 
1424
 
1425
1425
  Unfortunately, it seems gcc-3.3 is a bit dumb, and
1426
1426
  the compiled code has a LOT of spill code, it seems
1427
1427
  gcc (unlike xlc) cannot keep everything in registers
1429
1429
  registers allocation. It's not clean, but on
1430
1430
  a 7450 the resulting code is much faster (best case
1431
1431
  fall from 700+ cycles to 550).
1432
 
  
 
1432
 
1433
1433
  xlc doesn't add spill code, but it doesn't know how to
1434
1434
  schedule for the 7450, and its code isn't much faster than
1435
1435
  gcc-3.3 on the 7450 (but uses 25% less instructions...)
1436
 
  
 
1436
 
1437
1437
  On the 970, the hand-made RA is still a win (arount 690
1438
1438
  vs. around 780), but xlc goes to around 660 on the
1439
1439
  regular C code...
1480
1480
       0x00, 0x01, 0x02, 0x03,
1481
1481
       0x04, 0x05, 0x06, 0x07);
1482
1482
 
1483
 
#define ONEITERBUTTERFLY(i, res1, res2)                                 \
1484
 
    {                                                                   \
 
1483
#define ONEITERBUTTERFLY(i, res1, res2)                                 \
 
1484
    {                                                                   \
1485
1485
      register vector unsigned char src1 asm ("v22"), src2 asm ("v23"); \
1486
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);                            \
 
1487
      src1 = vec_ld(stride * i, src);                                   \
 
1488
      src2 = vec_ld((stride * i) + 16, src);                            \
1489
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);                            \
 
1490
      dst1 = vec_ld(stride * i, dst);                                   \
 
1491
      dst2 = vec_ld((stride * i) + 16, dst);                            \
1492
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 */                 \
 
1493
      /* promote the unsigned chars to signed shorts */                 \
1494
1494
      register vector signed short srcV asm ("v24") =                   \
1495
 
        (vector signed short)vec_mergeh((vector signed char)vzero, (vector signed char)srcO); \
 
1495
        (vector signed short)vec_mergeh((vector signed char)vzero, (vector signed char)srcO); \
1496
1496
      register vector signed short dstV asm ("v25") =                   \
1497
 
        (vector signed short)vec_mergeh((vector signed char)vzero, (vector signed char)dstO); \
 
1497
        (vector signed short)vec_mergeh((vector signed char)vzero, (vector signed char)dstO); \
1498
1498
      register vector signed short srcW asm ("v26") =                   \
1499
 
        (vector signed short)vec_mergel((vector signed char)vzero, (vector signed char)srcO); \
 
1499
        (vector signed short)vec_mergel((vector signed char)vzero, (vector signed char)srcO); \
1500
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 */                    \
 
1501
        (vector signed short)vec_mergel((vector signed char)vzero, (vector signed char)dstO); \
 
1502
      /* substractions inside the first butterfly */                    \
1503
1503
      register vector signed short but0 asm ("v28") = vec_sub(srcV, dstV); \
1504
1504
      register vector signed short but0S asm ("v29") = vec_sub(srcW, dstW); \
1505
1505
      register vector signed short op1 asm ("v30") = vec_perm(but0, but0, perm1); \
1511
1511
      register vector signed short op2S asm ("v27") = vec_perm(but1S, but1S, perm2); \
1512
1512
      register vector signed short but2S asm ("v28") = vec_mladd(but1S, vprod2, op2S); \
1513
1513
      register vector signed short op3 asm ("v29") = vec_perm(but2, but2, perm3); \
1514
 
      res1 = vec_mladd(but2, vprod3, op3);                              \
 
1514
      res1 = vec_mladd(but2, vprod3, op3);                              \
1515
1515
      register vector signed short op3S asm ("v30") = vec_perm(but2S, but2S, perm3); \
1516
 
      res2 = vec_mladd(but2S, vprod3, op3S);                            \
 
1516
      res2 = vec_mladd(but2S, vprod3, op3S);                            \
1517
1517
    }
1518
1518
    ONEITERBUTTERFLY(0, temp0, temp0S);
1519
1519
    ONEITERBUTTERFLY(1, temp1, temp1S);
1535
1535
    register vector signed short line5 = vec_sub(temp4, temp5);
1536
1536
    register vector signed short line6 = vec_add(temp6, temp7);
1537
1537
    register vector signed short line7 = vec_sub(temp6, temp7);
1538
 
      
 
1538
 
1539
1539
    register vector signed short line0B = vec_add(line0, line2);
1540
1540
    register vector signed short line2B = vec_sub(line0, line2);
1541
1541
    register vector signed short line1B = vec_add(line1, line3);
1544
1544
    register vector signed short line6B = vec_sub(line4, line6);
1545
1545
    register vector signed short line5B = vec_add(line5, line7);
1546
1546
    register vector signed short line7B = vec_sub(line5, line7);
1547
 
      
 
1547
 
1548
1548
    register vector signed short line0C = vec_add(line0B, line4B);
1549
1549
    register vector signed short line4C = vec_sub(line0B, line4B);
1550
1550
    register vector signed short line1C = vec_add(line1B, line5B);
1553
1553
    register vector signed short line6C = vec_sub(line2B, line6B);
1554
1554
    register vector signed short line3C = vec_add(line3B, line7B);
1555
1555
    register vector signed short line7C = vec_sub(line3B, line7B);
1556
 
      
 
1556
 
1557
1557
    vsum = vec_sum4s(vec_abs(line0C), vec_splat_s32(0));
1558
1558
    vsum = vec_sum4s(vec_abs(line1C), vsum);
1559
1559
    vsum = vec_sum4s(vec_abs(line2C), vsum);
1623
1623
int has_altivec(void)
1624
1624
{
1625
1625
#ifdef __AMIGAOS4__
1626
 
        ULONG result = 0;
1627
 
        extern struct ExecIFace *IExec;
 
1626
        ULONG result = 0;
 
1627
        extern struct ExecIFace *IExec;
1628
1628
 
1629
 
        IExec->GetCPUInfoTags(GCIT_VectorUnit, &result, TAG_DONE);
1630
 
        if (result == VECTORTYPE_ALTIVEC) return 1;
1631
 
        return 0;
 
1629
        IExec->GetCPUInfoTags(GCIT_VectorUnit, &result, TAG_DONE);
 
1630
        if (result == VECTORTYPE_ALTIVEC) return 1;
 
1631
        return 0;
1632
1632
#else /* __AMIGAOS4__ */
1633
1633
 
1634
1634
#ifdef CONFIG_DARWIN
1649
1649
        signal (SIGILL, SIG_DFL);
1650
1650
      } else {
1651
1651
        canjump = 1;
1652
 
        
 
1652
 
1653
1653
        asm volatile ("mtspr 256, %0\n\t"
1654
1654
                      "vand %%v0, %%v0, %%v0"
1655
1655
                      :
1656
1656
                      : "r" (-1));
1657
 
        
 
1657
 
1658
1658
        signal (SIGILL, SIG_DFL);
1659
1659
        return 1;
1660
1660
      }
1710
1710
     pixelssum1, pixelssum2, temp3;
1711
1711
   register const_vector unsigned char vczero = (const_vector unsigned char)vec_splat_u8(0);
1712
1712
   register const_vector unsigned short vctwo = (const_vector unsigned short)vec_splat_u16(2);
1713
 
   
 
1713
 
1714
1714
   temp1 = vec_ld(0, pixels);
1715
1715
   temp2 = vec_ld(16, pixels);
1716
1716
   pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
1727
1727
   pixelssum1 = vec_add((vector unsigned short)pixelsv1,
1728
1728
                        (vector unsigned short)pixelsv2);
1729
1729
   pixelssum1 = vec_add(pixelssum1, vctwo);
1730
 
   
1731
 
POWERPC_PERF_START_COUNT(altivec_avg_pixels8_xy2_num, 1); 
 
1730
 
 
1731
POWERPC_PERF_START_COUNT(altivec_avg_pixels8_xy2_num, 1);
1732
1732
   for (i = 0; i < h ; i++) {
1733
1733
     int rightside = ((unsigned long)block & 0x0000000F);
1734
1734
     blockv = vec_ld(0, block);
1753
1753
     temp3 = vec_sra(temp3, vctwo);
1754
1754
     pixelssum1 = vec_add(pixelssum2, vctwo);
1755
1755
     pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero);
1756
 
     
 
1756
 
1757
1757
     if (rightside)
1758
1758
     {
1759
1759
       blocktemp = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1));
1762
1762
     {
1763
1763
       blocktemp = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3));
1764
1764
     }
1765
 
     
 
1765
 
1766
1766
     blockv = vec_avg(blocktemp, blockv);
1767
1767
     vec_st(blockv, 0, block);
1768
 
     
 
1768
 
1769
1769
     block += line_size;
1770
1770
     pixels += line_size;
1771
1771
   }
1772
 
   
 
1772
 
1773
1773
POWERPC_PERF_STOP_COUNT(altivec_avg_pixels8_xy2_num, 1);
1774
1774
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
1775
1775
}