]> git.sesse.net Git - x264/blob - common/ppc/pixel.c
Update file headers throughout x264
[x264] / common / ppc / pixel.c
1 /*****************************************************************************
2  * pixel.c: h264 encoder
3  *****************************************************************************
4  * Copyright (C) 2003-2008 x264 project
5  *
6  * Authors: Eric Petit <titer@m0k.org>
7  *          Guillaume Poirier <gpoirier@mplayerhq.hu>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #ifdef SYS_LINUX
25 #include <altivec.h>
26 #endif
27
28 #include "common/common.h"
29 #include "ppccommon.h"
30
31 /***********************************************************************
32  * SAD routines
33  **********************************************************************/
34
35 #define PIXEL_SAD_ALTIVEC( name, lx, ly, a, b )        \
36 static int name( uint8_t *pix1, int i_pix1,            \
37                  uint8_t *pix2, int i_pix2 )           \
38 {                                                      \
39     int y;                                             \
40     DECLARE_ALIGNED_16( int sum );                     \
41                                                        \
42     LOAD_ZERO;                                         \
43     PREP_LOAD;                                         \
44     vec_u8_t  pix1v, pix2v;                            \
45     vec_s32_t sumv = zero_s32v;                        \
46     for( y = 0; y < ly; y++ )                          \
47     {                                                  \
48         VEC_LOAD( pix1, pix1v, lx, vec_u8_t );         \
49         VEC_LOAD( pix2, pix2v, lx, vec_u8_t );         \
50         sumv = (vec_s32_t) vec_sum4s(                  \
51                    vec_sub( vec_max( pix1v, pix2v ),   \
52                             vec_min( pix1v, pix2v ) ), \
53                    (vec_u32_t) sumv );                 \
54         pix1 += i_pix1;                                \
55         pix2 += i_pix2;                                \
56     }                                                  \
57     sumv = vec_sum##a( sumv, zero_s32v );              \
58     sumv = vec_splat( sumv, b );                       \
59     vec_ste( sumv, 0, &sum );                          \
60     return sum;                                        \
61 }
62
63 PIXEL_SAD_ALTIVEC( pixel_sad_16x16_altivec, 16, 16, s,  3 )
64 PIXEL_SAD_ALTIVEC( pixel_sad_8x16_altivec,  8,  16, 2s, 1 )
65 PIXEL_SAD_ALTIVEC( pixel_sad_16x8_altivec,  16, 8,  s,  3 )
66 PIXEL_SAD_ALTIVEC( pixel_sad_8x8_altivec,   8,  8,  2s, 1 )
67
68
69
70 /***********************************************************************
71  * SATD routines
72  **********************************************************************/
73
74 /***********************************************************************
75  * VEC_HADAMAR
76  ***********************************************************************
77  * b[0] = a[0] + a[1] + a[2] + a[3]
78  * b[1] = a[0] + a[1] - a[2] - a[3]
79  * b[2] = a[0] - a[1] - a[2] + a[3]
80  * b[3] = a[0] - a[1] + a[2] - a[3]
81  **********************************************************************/
82 #define VEC_HADAMAR(a0,a1,a2,a3,b0,b1,b2,b3) \
83     b2 = vec_add( a0, a1 ); \
84     b3 = vec_add( a2, a3 ); \
85     a0 = vec_sub( a0, a1 ); \
86     a2 = vec_sub( a2, a3 ); \
87     b0 = vec_add( b2, b3 ); \
88     b1 = vec_sub( b2, b3 ); \
89     b2 = vec_sub( a0, a2 ); \
90     b3 = vec_add( a0, a2 )
91
92 /***********************************************************************
93  * VEC_ABS
94  ***********************************************************************
95  * a: s16v
96  *
97  * a = abs(a)
98  * 
99  * Call vec_sub()/vec_max() instead of vec_abs() because vec_abs()
100  * actually also calls vec_splat(0), but we already have a null vector.
101  **********************************************************************/
102 #define VEC_ABS(a) \
103     a     = vec_max( a, vec_sub( zero_s16v, a ) );
104
105 /***********************************************************************
106  * VEC_ADD_ABS
107  ***********************************************************************
108  * a:    s16v
109  * b, c: s32v
110  *
111  * c[i] = abs(a[2*i]) + abs(a[2*i+1]) + [bi]
112  **********************************************************************/
113 #define VEC_ADD_ABS(a,b,c) \
114     VEC_ABS( a ); \
115     c = vec_sum4s( a, b )
116
117 /***********************************************************************
118  * SATD 4x4
119  **********************************************************************/
120 static int pixel_satd_4x4_altivec( uint8_t *pix1, int i_pix1,
121                                    uint8_t *pix2, int i_pix2 )
122 {
123     DECLARE_ALIGNED_16( int i_satd );
124
125     PREP_DIFF;
126     vec_s16_t diff0v, diff1v, diff2v, diff3v;
127     vec_s16_t temp0v, temp1v, temp2v, temp3v;
128     vec_s32_t satdv;
129
130     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, diff0v );
131     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, diff1v );
132     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, diff2v );
133     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, diff3v );
134
135     /* Hadamar H */
136     VEC_HADAMAR( diff0v, diff1v, diff2v, diff3v,
137                  temp0v, temp1v, temp2v, temp3v );
138     
139     VEC_TRANSPOSE_4( temp0v, temp1v, temp2v, temp3v,
140                      diff0v, diff1v, diff2v, diff3v );
141     /* Hadamar V */
142     VEC_HADAMAR( diff0v, diff1v, diff2v, diff3v,
143                  temp0v, temp1v, temp2v, temp3v );
144
145     VEC_ADD_ABS( temp0v, zero_s32v, satdv );
146     VEC_ADD_ABS( temp1v, satdv,     satdv );
147     VEC_ADD_ABS( temp2v, satdv,     satdv );
148     VEC_ADD_ABS( temp3v, satdv,     satdv );
149
150     satdv = vec_sum2s( satdv, zero_s32v );
151     satdv = vec_splat( satdv, 1 );
152     vec_ste( satdv, 0, &i_satd );
153
154     return i_satd / 2;
155 }
156
157 /***********************************************************************
158  * SATD 4x8
159  **********************************************************************/
160 static int pixel_satd_4x8_altivec( uint8_t *pix1, int i_pix1,
161                                    uint8_t *pix2, int i_pix2 )
162 {
163     DECLARE_ALIGNED_16( int i_satd );
164
165     PREP_DIFF;
166     vec_s16_t diff0v, diff1v, diff2v, diff3v;
167     vec_s16_t temp0v, temp1v, temp2v, temp3v;
168     vec_s32_t satdv;
169
170     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, diff0v );
171     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, diff1v );
172     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, diff2v );
173     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, diff3v );
174     VEC_HADAMAR( diff0v, diff1v, diff2v, diff3v,
175                  temp0v, temp1v, temp2v, temp3v );
176     VEC_TRANSPOSE_4( temp0v, temp1v, temp2v, temp3v,
177                      diff0v, diff1v, diff2v, diff3v );
178     VEC_HADAMAR( diff0v, diff1v, diff2v, diff3v,
179                  temp0v, temp1v, temp2v, temp3v );
180     VEC_ADD_ABS( temp0v, zero_s32v, satdv );
181     VEC_ADD_ABS( temp1v, satdv,     satdv );
182     VEC_ADD_ABS( temp2v, satdv,     satdv );
183     VEC_ADD_ABS( temp3v, satdv,     satdv );
184
185     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, diff0v );
186     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, diff1v );
187     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, diff2v );
188     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, diff3v );
189     VEC_HADAMAR( diff0v, diff1v, diff2v, diff3v,
190                  temp0v, temp1v, temp2v, temp3v );
191     VEC_TRANSPOSE_4( temp0v, temp1v, temp2v, temp3v,
192                      diff0v, diff1v, diff2v, diff3v );
193     VEC_HADAMAR( diff0v, diff1v, diff2v, diff3v,
194                  temp0v, temp1v, temp2v, temp3v );
195     VEC_ADD_ABS( temp0v, satdv,     satdv );
196     VEC_ADD_ABS( temp1v, satdv,     satdv );
197     VEC_ADD_ABS( temp2v, satdv,     satdv );
198     VEC_ADD_ABS( temp3v, satdv,     satdv );
199
200     satdv = vec_sum2s( satdv, zero_s32v );
201     satdv = vec_splat( satdv, 1 );
202     vec_ste( satdv, 0, &i_satd );
203
204     return i_satd / 2;
205 }
206
207 /***********************************************************************
208  * SATD 8x4
209  **********************************************************************/
210 static int pixel_satd_8x4_altivec( uint8_t *pix1, int i_pix1,
211                                    uint8_t *pix2, int i_pix2 )
212 {
213     DECLARE_ALIGNED_16( int i_satd );
214
215     PREP_DIFF;
216     vec_s16_t diff0v, diff1v, diff2v, diff3v,
217               diff4v, diff5v, diff6v, diff7v;
218     vec_s16_t temp0v, temp1v, temp2v, temp3v,
219               temp4v, temp5v, temp6v, temp7v;
220     vec_s32_t satdv;
221
222     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff0v );
223     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff1v );
224     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff2v );
225     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff3v );
226
227     VEC_HADAMAR( diff0v, diff1v, diff2v, diff3v,
228                  temp0v, temp1v, temp2v, temp3v );
229     /* This causes warnings because temp4v...temp7v haven't be set,
230        but we don't care */
231     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
232                      temp4v, temp5v, temp6v, temp7v,
233                      diff0v, diff1v, diff2v, diff3v,
234                      diff4v, diff5v, diff6v, diff7v );
235     VEC_HADAMAR( diff0v, diff1v, diff2v, diff3v,
236                  temp0v, temp1v, temp2v, temp3v );
237     VEC_HADAMAR( diff4v, diff5v, diff6v, diff7v,
238                  temp4v, temp5v, temp6v, temp7v );
239
240     VEC_ADD_ABS( temp0v, zero_s32v, satdv );
241     VEC_ADD_ABS( temp1v, satdv,     satdv );
242     VEC_ADD_ABS( temp2v, satdv,     satdv );
243     VEC_ADD_ABS( temp3v, satdv,     satdv );
244     VEC_ADD_ABS( temp4v, satdv,     satdv );
245     VEC_ADD_ABS( temp5v, satdv,     satdv );
246     VEC_ADD_ABS( temp6v, satdv,     satdv );
247     VEC_ADD_ABS( temp7v, satdv,     satdv );
248
249     satdv = vec_sum2s( satdv, zero_s32v );
250     satdv = vec_splat( satdv, 1 );
251     vec_ste( satdv, 0, &i_satd );
252
253     return i_satd / 2;
254 }
255
256 /***********************************************************************
257  * SATD 8x8
258  **********************************************************************/
259 static int pixel_satd_8x8_altivec( uint8_t *pix1, int i_pix1,
260                                    uint8_t *pix2, int i_pix2 )
261 {
262     DECLARE_ALIGNED_16( int i_satd );
263
264     PREP_DIFF;
265     vec_s16_t diff0v, diff1v, diff2v, diff3v,
266               diff4v, diff5v, diff6v, diff7v;
267     vec_s16_t temp0v, temp1v, temp2v, temp3v,
268               temp4v, temp5v, temp6v, temp7v;
269     vec_s32_t satdv;
270
271     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff0v );
272     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff1v );
273     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff2v );
274     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff3v );
275     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff4v );
276     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff5v );
277     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff6v );
278     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff7v );
279
280     VEC_HADAMAR( diff0v, diff1v, diff2v, diff3v,
281                  temp0v, temp1v, temp2v, temp3v );
282     VEC_HADAMAR( diff4v, diff5v, diff6v, diff7v,
283                  temp4v, temp5v, temp6v, temp7v );
284
285     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
286                      temp4v, temp5v, temp6v, temp7v,
287                      diff0v, diff1v, diff2v, diff3v,
288                      diff4v, diff5v, diff6v, diff7v );
289
290     VEC_HADAMAR( diff0v, diff1v, diff2v, diff3v,
291                  temp0v, temp1v, temp2v, temp3v );
292     VEC_HADAMAR( diff4v, diff5v, diff6v, diff7v,
293                  temp4v, temp5v, temp6v, temp7v );
294
295     VEC_ADD_ABS( temp0v, zero_s32v, satdv );
296     VEC_ADD_ABS( temp1v, satdv,     satdv );
297     VEC_ADD_ABS( temp2v, satdv,     satdv );
298     VEC_ADD_ABS( temp3v, satdv,     satdv );
299     VEC_ADD_ABS( temp4v, satdv,     satdv );
300     VEC_ADD_ABS( temp5v, satdv,     satdv );
301     VEC_ADD_ABS( temp6v, satdv,     satdv );
302     VEC_ADD_ABS( temp7v, satdv,     satdv );
303
304     satdv = vec_sums( satdv, zero_s32v );
305     satdv = vec_splat( satdv, 3 );
306     vec_ste( satdv, 0, &i_satd );
307
308     return i_satd / 2;
309 }
310
311 /***********************************************************************
312  * SATD 8x16
313  **********************************************************************/
314 static int pixel_satd_8x16_altivec( uint8_t *pix1, int i_pix1,
315                                     uint8_t *pix2, int i_pix2 )
316 {
317     DECLARE_ALIGNED_16( int i_satd );
318
319     PREP_DIFF;
320     vec_s16_t diff0v, diff1v, diff2v, diff3v,
321               diff4v, diff5v, diff6v, diff7v;
322     vec_s16_t temp0v, temp1v, temp2v, temp3v,
323               temp4v, temp5v, temp6v, temp7v;
324     vec_s32_t satdv;
325
326     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff0v );
327     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff1v );
328     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff2v );
329     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff3v );
330     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff4v );
331     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff5v );
332     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff6v );
333     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff7v );
334     VEC_HADAMAR( diff0v, diff1v, diff2v, diff3v,
335                  temp0v, temp1v, temp2v, temp3v );
336     VEC_HADAMAR( diff4v, diff5v, diff6v, diff7v,
337                  temp4v, temp5v, temp6v, temp7v );
338     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
339                      temp4v, temp5v, temp6v, temp7v,
340                      diff0v, diff1v, diff2v, diff3v,
341                      diff4v, diff5v, diff6v, diff7v );
342     VEC_HADAMAR( diff0v, diff1v, diff2v, diff3v,
343                  temp0v, temp1v, temp2v, temp3v );
344     VEC_HADAMAR( diff4v, diff5v, diff6v, diff7v,
345                  temp4v, temp5v, temp6v, temp7v );
346     VEC_ADD_ABS( temp0v, zero_s32v, satdv );
347     VEC_ADD_ABS( temp1v, satdv,     satdv );
348     VEC_ADD_ABS( temp2v, satdv,     satdv );
349     VEC_ADD_ABS( temp3v, satdv,     satdv );
350     VEC_ADD_ABS( temp4v, satdv,     satdv );
351     VEC_ADD_ABS( temp5v, satdv,     satdv );
352     VEC_ADD_ABS( temp6v, satdv,     satdv );
353     VEC_ADD_ABS( temp7v, satdv,     satdv );
354
355     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff0v );
356     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff1v );
357     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff2v );
358     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff3v );
359     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff4v );
360     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff5v );
361     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff6v );
362     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff7v );
363     VEC_HADAMAR( diff0v, diff1v, diff2v, diff3v,
364                  temp0v, temp1v, temp2v, temp3v );
365     VEC_HADAMAR( diff4v, diff5v, diff6v, diff7v,
366                  temp4v, temp5v, temp6v, temp7v );
367     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
368                      temp4v, temp5v, temp6v, temp7v,
369                      diff0v, diff1v, diff2v, diff3v,
370                      diff4v, diff5v, diff6v, diff7v );
371     VEC_HADAMAR( diff0v, diff1v, diff2v, diff3v,
372                  temp0v, temp1v, temp2v, temp3v );
373     VEC_HADAMAR( diff4v, diff5v, diff6v, diff7v,
374                  temp4v, temp5v, temp6v, temp7v );
375     VEC_ADD_ABS( temp0v, satdv,     satdv );
376     VEC_ADD_ABS( temp1v, satdv,     satdv );
377     VEC_ADD_ABS( temp2v, satdv,     satdv );
378     VEC_ADD_ABS( temp3v, satdv,     satdv );
379     VEC_ADD_ABS( temp4v, satdv,     satdv );
380     VEC_ADD_ABS( temp5v, satdv,     satdv );
381     VEC_ADD_ABS( temp6v, satdv,     satdv );
382     VEC_ADD_ABS( temp7v, satdv,     satdv );
383
384     satdv = vec_sums( satdv, zero_s32v );
385     satdv = vec_splat( satdv, 3 );
386     vec_ste( satdv, 0, &i_satd );
387
388     return i_satd / 2;
389 }
390
391 /***********************************************************************
392  * SATD 16x8
393  **********************************************************************/
394 static int pixel_satd_16x8_altivec( uint8_t *pix1, int i_pix1,
395                                     uint8_t *pix2, int i_pix2 )
396 {
397     DECLARE_ALIGNED_16( int i_satd );
398
399     LOAD_ZERO;
400     PREP_LOAD;
401     vec_s32_t satdv;
402     vec_s16_t pix1v, pix2v;
403     vec_s16_t diffh0v, diffh1v, diffh2v, diffh3v,
404               diffh4v, diffh5v, diffh6v, diffh7v;
405     vec_s16_t diffl0v, diffl1v, diffl2v, diffl3v,
406               diffl4v, diffl5v, diffl6v, diffl7v;
407     vec_s16_t temp0v, temp1v, temp2v, temp3v,
408               temp4v, temp5v, temp6v, temp7v;
409
410     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh0v, diffl0v );
411     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh1v, diffl1v );
412     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh2v, diffl2v );
413     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh3v, diffl3v );
414     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh4v, diffl4v );
415     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh5v, diffl5v );
416     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh6v, diffl6v );
417     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh7v, diffl7v );
418
419     VEC_HADAMAR( diffh0v, diffh1v, diffh2v, diffh3v,
420                  temp0v, temp1v, temp2v, temp3v );
421     VEC_HADAMAR( diffh4v, diffh5v, diffh6v, diffh7v,
422                  temp4v, temp5v, temp6v, temp7v );
423
424     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
425                      temp4v, temp5v, temp6v, temp7v,
426                      diffh0v, diffh1v, diffh2v, diffh3v,
427                      diffh4v, diffh5v, diffh6v, diffh7v );
428
429     VEC_HADAMAR( diffh0v, diffh1v, diffh2v, diffh3v,
430                  temp0v, temp1v, temp2v, temp3v );
431     VEC_HADAMAR( diffh4v, diffh5v, diffh6v, diffh7v,
432                  temp4v, temp5v, temp6v, temp7v );
433
434     VEC_ADD_ABS( temp0v, zero_s32v, satdv );
435     VEC_ADD_ABS( temp1v, satdv,     satdv );
436     VEC_ADD_ABS( temp2v, satdv,     satdv );
437     VEC_ADD_ABS( temp3v, satdv,     satdv );
438     VEC_ADD_ABS( temp4v, satdv,     satdv );
439     VEC_ADD_ABS( temp5v, satdv,     satdv );
440     VEC_ADD_ABS( temp6v, satdv,     satdv );
441     VEC_ADD_ABS( temp7v, satdv,     satdv );
442
443     VEC_HADAMAR( diffl0v, diffl1v, diffl2v, diffl3v,
444                  temp0v, temp1v, temp2v, temp3v );
445     VEC_HADAMAR( diffl4v, diffl5v, diffl6v, diffl7v,
446                  temp4v, temp5v, temp6v, temp7v );
447
448     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
449                      temp4v, temp5v, temp6v, temp7v,
450                      diffl0v, diffl1v, diffl2v, diffl3v,
451                      diffl4v, diffl5v, diffl6v, diffl7v );
452
453     VEC_HADAMAR( diffl0v, diffl1v, diffl2v, diffl3v,
454                  temp0v, temp1v, temp2v, temp3v );
455     VEC_HADAMAR( diffl4v, diffl5v, diffl6v, diffl7v,
456                  temp4v, temp5v, temp6v, temp7v );
457
458     VEC_ADD_ABS( temp0v, satdv,     satdv );
459     VEC_ADD_ABS( temp1v, satdv,     satdv );
460     VEC_ADD_ABS( temp2v, satdv,     satdv );
461     VEC_ADD_ABS( temp3v, satdv,     satdv );
462     VEC_ADD_ABS( temp4v, satdv,     satdv );
463     VEC_ADD_ABS( temp5v, satdv,     satdv );
464     VEC_ADD_ABS( temp6v, satdv,     satdv );
465     VEC_ADD_ABS( temp7v, satdv,     satdv );
466
467     satdv = vec_sums( satdv, zero_s32v );
468     satdv = vec_splat( satdv, 3 );
469     vec_ste( satdv, 0, &i_satd );
470
471     return i_satd / 2;
472 }
473
474 /***********************************************************************
475  * SATD 16x16
476  **********************************************************************/
477 static int pixel_satd_16x16_altivec( uint8_t *pix1, int i_pix1,
478                                      uint8_t *pix2, int i_pix2 )
479 {
480     DECLARE_ALIGNED_16( int i_satd );
481
482     LOAD_ZERO;
483     PREP_LOAD;
484     vec_s32_t satdv;
485     vec_s16_t pix1v, pix2v;
486     vec_s16_t diffh0v, diffh1v, diffh2v, diffh3v,
487               diffh4v, diffh5v, diffh6v, diffh7v;
488     vec_s16_t diffl0v, diffl1v, diffl2v, diffl3v,
489               diffl4v, diffl5v, diffl6v, diffl7v;
490     vec_s16_t temp0v, temp1v, temp2v, temp3v,
491               temp4v, temp5v, temp6v, temp7v;
492
493     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh0v, diffl0v );
494     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh1v, diffl1v );
495     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh2v, diffl2v );
496     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh3v, diffl3v );
497     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh4v, diffl4v );
498     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh5v, diffl5v );
499     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh6v, diffl6v );
500     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh7v, diffl7v );
501     VEC_HADAMAR( diffh0v, diffh1v, diffh2v, diffh3v,
502                  temp0v, temp1v, temp2v, temp3v );
503     VEC_HADAMAR( diffh4v, diffh5v, diffh6v, diffh7v,
504                  temp4v, temp5v, temp6v, temp7v );
505     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
506                      temp4v, temp5v, temp6v, temp7v,
507                      diffh0v, diffh1v, diffh2v, diffh3v,
508                      diffh4v, diffh5v, diffh6v, diffh7v );
509     VEC_HADAMAR( diffh0v, diffh1v, diffh2v, diffh3v,
510                  temp0v, temp1v, temp2v, temp3v );
511     VEC_HADAMAR( diffh4v, diffh5v, diffh6v, diffh7v,
512                  temp4v, temp5v, temp6v, temp7v );
513     VEC_ADD_ABS( temp0v, zero_s32v, satdv );
514     VEC_ADD_ABS( temp1v, satdv,     satdv );
515     VEC_ADD_ABS( temp2v, satdv,     satdv );
516     VEC_ADD_ABS( temp3v, satdv,     satdv );
517     VEC_ADD_ABS( temp4v, satdv,     satdv );
518     VEC_ADD_ABS( temp5v, satdv,     satdv );
519     VEC_ADD_ABS( temp6v, satdv,     satdv );
520     VEC_ADD_ABS( temp7v, satdv,     satdv );
521     VEC_HADAMAR( diffl0v, diffl1v, diffl2v, diffl3v,
522                  temp0v, temp1v, temp2v, temp3v );
523     VEC_HADAMAR( diffl4v, diffl5v, diffl6v, diffl7v,
524                  temp4v, temp5v, temp6v, temp7v );
525     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
526                      temp4v, temp5v, temp6v, temp7v,
527                      diffl0v, diffl1v, diffl2v, diffl3v,
528                      diffl4v, diffl5v, diffl6v, diffl7v );
529     VEC_HADAMAR( diffl0v, diffl1v, diffl2v, diffl3v,
530                  temp0v, temp1v, temp2v, temp3v );
531     VEC_HADAMAR( diffl4v, diffl5v, diffl6v, diffl7v,
532                  temp4v, temp5v, temp6v, temp7v );
533     VEC_ADD_ABS( temp0v, satdv,     satdv );
534     VEC_ADD_ABS( temp1v, satdv,     satdv );
535     VEC_ADD_ABS( temp2v, satdv,     satdv );
536     VEC_ADD_ABS( temp3v, satdv,     satdv );
537     VEC_ADD_ABS( temp4v, satdv,     satdv );
538     VEC_ADD_ABS( temp5v, satdv,     satdv );
539     VEC_ADD_ABS( temp6v, satdv,     satdv );
540     VEC_ADD_ABS( temp7v, satdv,     satdv );
541
542     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh0v, diffl0v );
543     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh1v, diffl1v );
544     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh2v, diffl2v );
545     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh3v, diffl3v );
546     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh4v, diffl4v );
547     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh5v, diffl5v );
548     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh6v, diffl6v );
549     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, diffh7v, diffl7v );
550     VEC_HADAMAR( diffh0v, diffh1v, diffh2v, diffh3v,
551                  temp0v, temp1v, temp2v, temp3v );
552     VEC_HADAMAR( diffh4v, diffh5v, diffh6v, diffh7v,
553                  temp4v, temp5v, temp6v, temp7v );
554     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
555                      temp4v, temp5v, temp6v, temp7v,
556                      diffh0v, diffh1v, diffh2v, diffh3v,
557                      diffh4v, diffh5v, diffh6v, diffh7v );
558     VEC_HADAMAR( diffh0v, diffh1v, diffh2v, diffh3v,
559                  temp0v, temp1v, temp2v, temp3v );
560     VEC_HADAMAR( diffh4v, diffh5v, diffh6v, diffh7v,
561                  temp4v, temp5v, temp6v, temp7v );
562     VEC_ADD_ABS( temp0v, satdv,     satdv );
563     VEC_ADD_ABS( temp1v, satdv,     satdv );
564     VEC_ADD_ABS( temp2v, satdv,     satdv );
565     VEC_ADD_ABS( temp3v, satdv,     satdv );
566     VEC_ADD_ABS( temp4v, satdv,     satdv );
567     VEC_ADD_ABS( temp5v, satdv,     satdv );
568     VEC_ADD_ABS( temp6v, satdv,     satdv );
569     VEC_ADD_ABS( temp7v, satdv,     satdv );
570     VEC_HADAMAR( diffl0v, diffl1v, diffl2v, diffl3v,
571                  temp0v, temp1v, temp2v, temp3v );
572     VEC_HADAMAR( diffl4v, diffl5v, diffl6v, diffl7v,
573                  temp4v, temp5v, temp6v, temp7v );
574     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
575                      temp4v, temp5v, temp6v, temp7v,
576                      diffl0v, diffl1v, diffl2v, diffl3v,
577                      diffl4v, diffl5v, diffl6v, diffl7v );
578     VEC_HADAMAR( diffl0v, diffl1v, diffl2v, diffl3v,
579                  temp0v, temp1v, temp2v, temp3v );
580     VEC_HADAMAR( diffl4v, diffl5v, diffl6v, diffl7v,
581                  temp4v, temp5v, temp6v, temp7v );
582     VEC_ADD_ABS( temp0v, satdv,     satdv );
583     VEC_ADD_ABS( temp1v, satdv,     satdv );
584     VEC_ADD_ABS( temp2v, satdv,     satdv );
585     VEC_ADD_ABS( temp3v, satdv,     satdv );
586     VEC_ADD_ABS( temp4v, satdv,     satdv );
587     VEC_ADD_ABS( temp5v, satdv,     satdv );
588     VEC_ADD_ABS( temp6v, satdv,     satdv );
589     VEC_ADD_ABS( temp7v, satdv,     satdv );
590
591     satdv = vec_sums( satdv, zero_s32v );
592     satdv = vec_splat( satdv, 3 );
593     vec_ste( satdv, 0, &i_satd );
594
595     return i_satd / 2;
596 }
597
598
599
600 /***********************************************************************
601 * Interleaved SAD routines
602 **********************************************************************/
603
604 static void pixel_sad_x4_16x16_altivec( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1, uint8_t *pix2, uint8_t *pix3, int i_stride, int scores[4] )
605 {
606     DECLARE_ALIGNED_16( int sum0 );
607     DECLARE_ALIGNED_16( int sum1 );
608     DECLARE_ALIGNED_16( int sum2 );
609     DECLARE_ALIGNED_16( int sum3 );
610     int y;
611     
612     LOAD_ZERO;
613     vec_u8_t temp_lv, temp_hv;
614     vec_u8_t fencv, pix0v, pix1v, pix2v, pix3v;
615     //vec_u8_t perm0v, perm1v, perm2v, perm3v;
616     vec_u8_t perm0vA, perm1vA, perm2vA, perm3vA, perm0vB, perm1vB, perm2vB, perm3vB;
617     
618     vec_s32_t sum0v, sum1v, sum2v, sum3v;
619     
620     sum0v = vec_splat_s32(0);
621     sum1v = vec_splat_s32(0);
622     sum2v = vec_splat_s32(0);
623     sum3v = vec_splat_s32(0);
624     
625     perm0vA = vec_lvsl(0, pix0);
626     perm1vA = vec_lvsl(0, pix1);
627     perm2vA = vec_lvsl(0, pix2);
628     perm3vA = vec_lvsl(0, pix3);
629     
630     perm0vB = vec_lvsl(0, pix0 + i_stride);
631     perm1vB = vec_lvsl(0, pix1 + i_stride);
632     perm2vB = vec_lvsl(0, pix2 + i_stride);
633     perm3vB = vec_lvsl(0, pix3 + i_stride);
634     
635     
636     for (y = 0; y < 8; y++)
637     {
638         temp_lv = vec_ld(0, pix0);
639         temp_hv = vec_ld(16, pix0);
640         pix0v = vec_perm(temp_lv, temp_hv, perm0vA);
641         pix0 += i_stride;
642         
643         
644         temp_lv = vec_ld(0, pix1);
645         temp_hv = vec_ld(16, pix1);
646         pix1v = vec_perm(temp_lv, temp_hv, perm1vA);
647         pix1 += i_stride;
648         
649         fencv = vec_ld(0, fenc);
650         fenc += FENC_STRIDE;
651         
652         temp_lv = vec_ld(0, pix2);
653         temp_hv = vec_ld(16, pix2);
654         pix2v = vec_perm(temp_lv, temp_hv, perm2vA);
655         pix2 += i_stride;
656         
657         temp_lv = vec_ld(0, pix3);
658         temp_hv = vec_ld(16, pix3);
659         pix3v = vec_perm(temp_lv, temp_hv, perm3vA);
660         pix3 += i_stride;
661         
662         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
663         
664         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
665         
666         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v ); 
667         
668         sum3v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix3v ), vec_min( fencv, pix3v ) ), (vec_u32_t) sum3v ); 
669         
670         temp_lv = vec_ld(0, pix0);
671         temp_hv = vec_ld(16, pix0);
672         pix0v = vec_perm(temp_lv, temp_hv, perm0vB);
673         pix0 += i_stride;
674         
675         
676         temp_lv = vec_ld(0, pix1);
677         temp_hv = vec_ld(16, pix1);
678         pix1v = vec_perm(temp_lv, temp_hv, perm1vB);
679         pix1 += i_stride;
680         
681         fencv = vec_ld(0, fenc);
682         fenc += FENC_STRIDE;
683         
684         temp_lv = vec_ld(0, pix2);
685         temp_hv = vec_ld(16, pix2);
686         pix2v = vec_perm(temp_lv, temp_hv, perm2vB);
687         pix2 += i_stride;
688         
689         temp_lv = vec_ld(0, pix3);
690         temp_hv = vec_ld(16, pix3);
691         pix3v = vec_perm(temp_lv, temp_hv, perm3vB);
692         pix3 += i_stride;
693         
694         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
695         
696         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
697         
698         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v ); 
699         
700         sum3v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix3v ), vec_min( fencv, pix3v ) ), (vec_u32_t) sum3v ); 
701         
702         
703     }
704     
705     sum0v = vec_sums( sum0v, zero_s32v );
706     sum1v = vec_sums( sum1v, zero_s32v );
707     sum2v = vec_sums( sum2v, zero_s32v );
708     sum3v = vec_sums( sum3v, zero_s32v );
709     
710     sum0v = vec_splat( sum0v, 3 );
711     sum1v = vec_splat( sum1v, 3 );
712     sum2v = vec_splat( sum2v, 3 );
713     sum3v = vec_splat( sum3v, 3 );
714     
715     vec_ste( sum0v, 0, &sum0);
716     vec_ste( sum1v, 0, &sum1);
717     vec_ste( sum2v, 0, &sum2);
718     vec_ste( sum3v, 0, &sum3);
719     
720     scores[0] = sum0;
721     scores[1] = sum1;
722     scores[2] = sum2;
723     scores[3] = sum3;
724     
725     
726     
727 }
728
729 static void pixel_sad_x3_16x16_altivec( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1, uint8_t *pix2, int i_stride, int scores[3] )
730 {
731     
732     DECLARE_ALIGNED_16( int sum0 );
733     DECLARE_ALIGNED_16( int sum1 );
734     DECLARE_ALIGNED_16( int sum2 );
735     int y;
736     
737     LOAD_ZERO;
738     vec_u8_t temp_lv, temp_hv; // temporary load vectors
739     vec_u8_t fencv, pix0v, pix1v, pix2v;
740     vec_u8_t perm0vA, perm1vA, perm2vA, perm0vB, perm1vB, perm2vB;
741     
742     vec_s32_t sum0v, sum1v, sum2v;
743     
744     sum0v = vec_splat_s32(0);
745     sum1v = vec_splat_s32(0);
746     sum2v = vec_splat_s32(0);
747     
748     perm0vA = vec_lvsl(0, pix0);
749     perm1vA = vec_lvsl(0, pix1);
750     perm2vA = vec_lvsl(0, pix2);
751     
752     perm0vB = vec_lvsl(0, pix0 + i_stride);
753     perm1vB = vec_lvsl(0, pix1 + i_stride);
754     perm2vB = vec_lvsl(0, pix2 + i_stride);
755     
756     for (y = 0; y < 8; y++)
757     {
758         temp_lv = vec_ld(0, pix0);
759         temp_hv = vec_ld(16, pix0);
760         pix0v = vec_perm(temp_lv, temp_hv, perm0vA);
761         pix0 += i_stride;
762         
763         
764         temp_lv = vec_ld(0, pix1);
765         temp_hv = vec_ld(16, pix1);
766         pix1v = vec_perm(temp_lv, temp_hv, perm1vA);
767         pix1 += i_stride;
768         
769         fencv = vec_ld(0, fenc);
770         fenc += FENC_STRIDE;
771         
772         temp_lv = vec_ld(0, pix2);
773         temp_hv = vec_ld(16, pix2);
774         pix2v = vec_perm(temp_lv, temp_hv, perm2vA);
775         pix2 += i_stride;
776         
777         
778         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
779         
780         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
781         
782         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v ); 
783         
784         temp_lv = vec_ld(0, pix0);
785         temp_hv = vec_ld(16, pix0);
786         pix0v = vec_perm(temp_lv, temp_hv, perm0vB);
787         pix0 += i_stride;
788         
789         
790         temp_lv = vec_ld(0, pix1);
791         temp_hv = vec_ld(16, pix1);
792         pix1v = vec_perm(temp_lv, temp_hv, perm1vB);
793         pix1 += i_stride;
794         
795         fencv = vec_ld(0, fenc);
796         fenc += FENC_STRIDE;
797         
798         temp_lv = vec_ld(0, pix2);
799         temp_hv = vec_ld(16, pix2);
800         pix2v = vec_perm(temp_lv, temp_hv, perm2vB);
801         pix2 += i_stride;
802         
803         
804         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
805         
806         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
807         
808         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v ); 
809         
810         
811         
812     }
813     
814     sum0v = vec_sums( sum0v, zero_s32v );
815     sum1v = vec_sums( sum1v, zero_s32v );
816     sum2v = vec_sums( sum2v, zero_s32v );
817     
818     sum0v = vec_splat( sum0v, 3 );
819     sum1v = vec_splat( sum1v, 3 );
820     sum2v = vec_splat( sum2v, 3 );
821     
822     vec_ste( sum0v, 0, &sum0);
823     vec_ste( sum1v, 0, &sum1);
824     vec_ste( sum2v, 0, &sum2);
825     
826     scores[0] = sum0;
827     scores[1] = sum1;
828     scores[2] = sum2;
829     
830
831
832 static void pixel_sad_x4_16x8_altivec( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1, uint8_t *pix2, uint8_t *pix3, int i_stride, int scores[4] )
833 {
834     DECLARE_ALIGNED_16( int sum0 );
835     DECLARE_ALIGNED_16( int sum1 );
836     DECLARE_ALIGNED_16( int sum2 );
837     DECLARE_ALIGNED_16( int sum3 );
838     int y;
839     
840     LOAD_ZERO;
841     vec_u8_t temp_lv, temp_hv; 
842     vec_u8_t fencv, pix0v, pix1v, pix2v, pix3v;
843     vec_u8_t perm0vA, perm1vA, perm2vA, perm3vA, perm0vB, perm1vB, perm2vB, perm3vB;
844     
845     vec_s32_t sum0v, sum1v, sum2v, sum3v;
846     
847     sum0v = vec_splat_s32(0);
848     sum1v = vec_splat_s32(0);
849     sum2v = vec_splat_s32(0);
850     sum3v = vec_splat_s32(0);
851     
852     perm0vA = vec_lvsl(0, pix0);
853     perm1vA = vec_lvsl(0, pix1);
854     perm2vA = vec_lvsl(0, pix2);
855     perm3vA = vec_lvsl(0, pix3);
856     
857     perm0vB = vec_lvsl(0, pix0 + i_stride);
858     perm1vB = vec_lvsl(0, pix1 + i_stride);
859     perm2vB = vec_lvsl(0, pix2 + i_stride);
860     perm3vB = vec_lvsl(0, pix3 + i_stride);
861     
862     
863     
864     for (y = 0; y < 4; y++)
865     {
866         temp_lv = vec_ld(0, pix0);
867         temp_hv = vec_ld(16, pix0);
868         pix0v = vec_perm(temp_lv, temp_hv, perm0vA);
869         pix0 += i_stride;
870         
871         
872         temp_lv = vec_ld(0, pix1);
873         temp_hv = vec_ld(16, pix1);
874         pix1v = vec_perm(temp_lv, temp_hv, perm1vA);
875         pix1 += i_stride;
876         
877         fencv = vec_ld(0, fenc);
878         fenc += FENC_STRIDE;
879         
880         temp_lv = vec_ld(0, pix2);
881         temp_hv = vec_ld(16, pix2);
882         pix2v = vec_perm(temp_lv, temp_hv, perm2vA);
883         pix2 += i_stride;
884         
885         temp_lv = vec_ld(0, pix3);
886         temp_hv = vec_ld(16, pix3);
887         pix3v = vec_perm(temp_lv, temp_hv, perm3vA);
888         pix3 += i_stride;
889         
890         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
891         
892         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
893         
894         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v ); 
895         
896         sum3v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix3v ), vec_min( fencv, pix3v ) ), (vec_u32_t) sum3v ); 
897         
898         temp_lv = vec_ld(0, pix0);
899         temp_hv = vec_ld(16, pix0);
900         pix0v = vec_perm(temp_lv, temp_hv, perm0vB);
901         pix0 += i_stride;
902         
903         
904         temp_lv = vec_ld(0, pix1);
905         temp_hv = vec_ld(16, pix1);
906         pix1v = vec_perm(temp_lv, temp_hv, perm1vB);
907         pix1 += i_stride;
908         
909         fencv = vec_ld(0, fenc);
910         fenc += FENC_STRIDE;
911         
912         temp_lv = vec_ld(0, pix2);
913         temp_hv = vec_ld(16, pix2);
914         pix2v = vec_perm(temp_lv, temp_hv, perm2vB);
915         pix2 += i_stride;
916         
917         temp_lv = vec_ld(0, pix3);
918         temp_hv = vec_ld(16, pix3);
919         pix3v = vec_perm(temp_lv, temp_hv, perm3vB);
920         pix3 += i_stride;
921         
922         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
923         
924         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
925         
926         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v ); 
927         
928         sum3v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix3v ), vec_min( fencv, pix3v ) ), (vec_u32_t) sum3v );
929         
930         
931     }
932     
933     sum0v = vec_sums( sum0v, zero_s32v );
934     sum1v = vec_sums( sum1v, zero_s32v );
935     sum2v = vec_sums( sum2v, zero_s32v );
936     sum3v = vec_sums( sum3v, zero_s32v );
937     
938     sum0v = vec_splat( sum0v, 3 );
939     sum1v = vec_splat( sum1v, 3 );
940     sum2v = vec_splat( sum2v, 3 );
941     sum3v = vec_splat( sum3v, 3 );
942     
943     vec_ste( sum0v, 0, &sum0);
944     vec_ste( sum1v, 0, &sum1);
945     vec_ste( sum2v, 0, &sum2);
946     vec_ste( sum3v, 0, &sum3);
947     
948     scores[0] = sum0;
949     scores[1] = sum1;
950     scores[2] = sum2;
951     scores[3] = sum3;
952     
953     
954     
955 }
956
957 static void pixel_sad_x3_16x8_altivec( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1, uint8_t *pix2, int i_stride, int scores[3] )
958 {
959     
960     DECLARE_ALIGNED_16( int sum0 );
961     DECLARE_ALIGNED_16( int sum1 );
962     DECLARE_ALIGNED_16( int sum2 );
963     int y;
964     
965     LOAD_ZERO;
966     vec_u8_t temp_lv, temp_hv; 
967     vec_u8_t fencv, pix0v, pix1v, pix2v;
968     vec_u8_t perm0vA, perm1vA, perm2vA, perm0vB, perm1vB, perm2vB;
969     
970     vec_s32_t sum0v, sum1v, sum2v;
971     
972     sum0v = vec_splat_s32(0);
973     sum1v = vec_splat_s32(0);
974     sum2v = vec_splat_s32(0);
975
976     
977     perm0vA = vec_lvsl(0, pix0);
978     perm1vA = vec_lvsl(0, pix1);
979     perm2vA = vec_lvsl(0, pix2);
980     
981     perm0vB = vec_lvsl(0, pix0 + i_stride);
982     perm1vB = vec_lvsl(0, pix1 + i_stride);
983     perm2vB = vec_lvsl(0, pix2 + i_stride);
984     
985     for (y = 0; y < 4; y++)
986     {
987         temp_lv = vec_ld(0, pix0);
988         temp_hv = vec_ld(16, pix0);
989         pix0v = vec_perm(temp_lv, temp_hv, perm0vA);
990         pix0 += i_stride;
991         
992         
993         temp_lv = vec_ld(0, pix1);
994         temp_hv = vec_ld(16, pix1);
995         pix1v = vec_perm(temp_lv, temp_hv, perm1vA);
996         pix1 += i_stride;
997         
998         fencv = vec_ld(0, fenc);
999         fenc += FENC_STRIDE;
1000         
1001         temp_lv = vec_ld(0, pix2);
1002         temp_hv = vec_ld(16, pix2);
1003         pix2v = vec_perm(temp_lv, temp_hv, perm2vA);
1004         pix2 += i_stride;
1005         
1006         
1007         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
1008         
1009         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
1010         
1011         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v ); 
1012         
1013         temp_lv = vec_ld(0, pix0);
1014         temp_hv = vec_ld(16, pix0);
1015         pix0v = vec_perm(temp_lv, temp_hv, perm0vB);
1016         pix0 += i_stride;
1017         
1018         
1019         temp_lv = vec_ld(0, pix1);
1020         temp_hv = vec_ld(16, pix1);
1021         pix1v = vec_perm(temp_lv, temp_hv, perm1vB);
1022         pix1 += i_stride;
1023         
1024         fencv = vec_ld(0, fenc);
1025         fenc += FENC_STRIDE;
1026         
1027         temp_lv = vec_ld(0, pix2);
1028         temp_hv = vec_ld(16, pix2);
1029         pix2v = vec_perm(temp_lv, temp_hv, perm2vB);
1030         pix2 += i_stride;
1031         
1032         
1033         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
1034         
1035         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
1036         
1037         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v );
1038         
1039         
1040     }
1041     
1042     sum0v = vec_sums( sum0v, zero_s32v );
1043     sum1v = vec_sums( sum1v, zero_s32v );
1044     sum2v = vec_sums( sum2v, zero_s32v );
1045     
1046     sum0v = vec_splat( sum0v, 3 );
1047     sum1v = vec_splat( sum1v, 3 );
1048     sum2v = vec_splat( sum2v, 3 );
1049     
1050     vec_ste( sum0v, 0, &sum0);
1051     vec_ste( sum1v, 0, &sum1);
1052     vec_ste( sum2v, 0, &sum2);
1053     
1054     scores[0] = sum0;
1055     scores[1] = sum1;
1056     scores[2] = sum2;
1057     
1058
1059
1060
1061 static void pixel_sad_x4_8x16_altivec( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1, uint8_t *pix2, uint8_t *pix3, int i_stride, int scores[4] )
1062 {
1063     DECLARE_ALIGNED_16( int sum0 );
1064     DECLARE_ALIGNED_16( int sum1 );
1065     DECLARE_ALIGNED_16( int sum2 );
1066     DECLARE_ALIGNED_16( int sum3 );
1067     int y;
1068     
1069     LOAD_ZERO;
1070     vec_u8_t temp_lv, temp_hv; 
1071     vec_u8_t fencv, pix0v, pix1v, pix2v, pix3v;
1072     vec_u8_t perm0vA, perm1vA, perm2vA, perm3vA, perm0vB, perm1vB, perm2vB, perm3vB, permEncv;
1073     
1074     vec_s32_t sum0v, sum1v, sum2v, sum3v;
1075     
1076     sum0v = vec_splat_s32(0);
1077     sum1v = vec_splat_s32(0);
1078     sum2v = vec_splat_s32(0);
1079     sum3v = vec_splat_s32(0);
1080     
1081     permEncv = vec_lvsl(0, fenc);
1082     perm0vA = vec_lvsl(0, pix0);
1083     perm1vA = vec_lvsl(0, pix1);
1084     perm2vA = vec_lvsl(0, pix2);
1085     perm3vA = vec_lvsl(0, pix3);
1086     
1087     perm0vB = vec_lvsl(0, pix0 + i_stride);
1088     perm1vB = vec_lvsl(0, pix1 + i_stride);
1089     perm2vB = vec_lvsl(0, pix2 + i_stride);
1090     perm3vB = vec_lvsl(0, pix3 + i_stride);
1091     
1092     
1093     for (y = 0; y < 8; y++)
1094     {
1095         temp_lv = vec_ld(0, pix0);
1096         temp_hv = vec_ld(16, pix0);
1097         pix0v = vec_perm(temp_lv, temp_hv, perm0vA);
1098         pix0 += i_stride;
1099         
1100         
1101         temp_lv = vec_ld(0, pix1);
1102         temp_hv = vec_ld(16, pix1);
1103         pix1v = vec_perm(temp_lv, temp_hv, perm1vA);
1104         pix1 += i_stride;
1105         
1106         temp_lv = vec_ld(0, fenc);
1107         fencv = vec_perm(temp_lv, temp_hv, permEncv);
1108         fenc += FENC_STRIDE;
1109         
1110         temp_lv = vec_ld(0, pix2);
1111         temp_hv = vec_ld(16, pix2);
1112         pix2v = vec_perm(temp_lv, temp_hv, perm2vA);
1113         pix2 += i_stride;
1114         
1115         temp_lv = vec_ld(0, pix3);
1116         temp_hv = vec_ld(16, pix3);
1117         pix3v = vec_perm(temp_lv, temp_hv, perm3vA);
1118         pix3 += i_stride;
1119         
1120         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
1121         
1122         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
1123         
1124         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v ); 
1125         
1126         sum3v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix3v ), vec_min( fencv, pix3v ) ), (vec_u32_t) sum3v ); 
1127         
1128         temp_lv = vec_ld(0, pix0);
1129         temp_hv = vec_ld(16, pix0);
1130         pix0v = vec_perm(temp_lv, temp_hv, perm0vB);
1131         pix0 += i_stride;
1132         
1133         
1134         temp_lv = vec_ld(0, pix1);
1135         temp_hv = vec_ld(16, pix1);
1136         pix1v = vec_perm(temp_lv, temp_hv, perm1vB);
1137         pix1 += i_stride;
1138         
1139         temp_lv = vec_ld(0, fenc);
1140         fencv = vec_perm(temp_lv, temp_hv, permEncv);
1141         fenc += FENC_STRIDE;
1142         
1143         temp_lv = vec_ld(0, pix2);
1144         temp_hv = vec_ld(16, pix2);
1145         pix2v = vec_perm(temp_lv, temp_hv, perm2vB);
1146         pix2 += i_stride;
1147         
1148         temp_lv = vec_ld(0, pix3);
1149         temp_hv = vec_ld(16, pix3);
1150         pix3v = vec_perm(temp_lv, temp_hv, perm3vB);
1151         pix3 += i_stride;
1152         
1153         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
1154         
1155         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
1156         
1157         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v ); 
1158         
1159         sum3v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix3v ), vec_min( fencv, pix3v ) ), (vec_u32_t) sum3v ); 
1160     }
1161     
1162     sum0v = vec_sum2s( sum0v, zero_s32v );
1163     sum1v = vec_sum2s( sum1v, zero_s32v );
1164     sum2v = vec_sum2s( sum2v, zero_s32v );
1165     sum3v = vec_sum2s( sum3v, zero_s32v );
1166     
1167     sum0v = vec_splat( sum0v, 1 );
1168     sum1v = vec_splat( sum1v, 1 );
1169     sum2v = vec_splat( sum2v, 1 );
1170     sum3v = vec_splat( sum3v, 1 );
1171     
1172     vec_ste( sum0v, 0, &sum0);
1173     vec_ste( sum1v, 0, &sum1);
1174     vec_ste( sum2v, 0, &sum2);
1175     vec_ste( sum3v, 0, &sum3);
1176     
1177     scores[0] = sum0;
1178     scores[1] = sum1;
1179     scores[2] = sum2;
1180     scores[3] = sum3; 
1181         
1182 }
1183
1184 static void pixel_sad_x3_8x16_altivec( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1, uint8_t *pix2, int i_stride, int scores[3] )
1185 {
1186     DECLARE_ALIGNED_16( int sum0 );
1187     DECLARE_ALIGNED_16( int sum1 );
1188     DECLARE_ALIGNED_16( int sum2 );
1189     int y;
1190     
1191     LOAD_ZERO;
1192     vec_u8_t temp_lv, temp_hv; 
1193     vec_u8_t fencv, pix0v, pix1v, pix2v;
1194     vec_u8_t perm0vA, perm1vA, perm2vA, perm0vB, perm1vB, perm2vB,permEncv;
1195     
1196     vec_s32_t sum0v, sum1v, sum2v;
1197     
1198     sum0v = vec_splat_s32(0);
1199     sum1v = vec_splat_s32(0);
1200     sum2v = vec_splat_s32(0);
1201     
1202     permEncv = vec_lvsl(0, fenc);
1203     perm0vA = vec_lvsl(0, pix0);
1204     perm1vA = vec_lvsl(0, pix1);
1205     perm2vA = vec_lvsl(0, pix2);
1206     
1207     perm0vB = vec_lvsl(0, pix0 + i_stride);
1208     perm1vB = vec_lvsl(0, pix1 + i_stride);
1209     perm2vB = vec_lvsl(0, pix2 + i_stride);
1210     
1211     for (y = 0; y < 8; y++)
1212     {
1213         temp_lv = vec_ld(0, pix0);
1214         temp_hv = vec_ld(16, pix0);
1215         pix0v = vec_perm(temp_lv, temp_hv, perm0vA);
1216         pix0 += i_stride;
1217         
1218         
1219         temp_lv = vec_ld(0, pix1);
1220         temp_hv = vec_ld(16, pix1);
1221         pix1v = vec_perm(temp_lv, temp_hv, perm1vA);
1222         pix1 += i_stride;
1223         
1224         temp_lv = vec_ld(0, fenc);
1225         fencv = vec_perm(temp_lv, temp_hv, permEncv);
1226         fenc += FENC_STRIDE;
1227         
1228         temp_lv = vec_ld(0, pix2);
1229         temp_hv = vec_ld(16, pix2);
1230         pix2v = vec_perm(temp_lv, temp_hv, perm2vA);
1231         pix2 += i_stride;
1232         
1233         
1234         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
1235         
1236         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
1237         
1238         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v ); 
1239         
1240         
1241         temp_lv = vec_ld(0, pix0);
1242         temp_hv = vec_ld(16, pix0);
1243         pix0v = vec_perm(temp_lv, temp_hv, perm0vB);
1244         pix0 += i_stride;
1245         
1246         
1247         temp_lv = vec_ld(0, pix1);
1248         temp_hv = vec_ld(16, pix1);
1249         pix1v = vec_perm(temp_lv, temp_hv, perm1vB);
1250         pix1 += i_stride;
1251         
1252         temp_lv = vec_ld(0, fenc);
1253         fencv = vec_perm(temp_lv, temp_hv, permEncv);
1254         fenc += FENC_STRIDE;
1255         
1256         temp_lv = vec_ld(0, pix2);
1257         temp_hv = vec_ld(16, pix2);
1258         pix2v = vec_perm(temp_lv, temp_hv, perm2vB);
1259         pix2 += i_stride;
1260         
1261         
1262         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
1263         
1264         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
1265         
1266         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v ); 
1267         
1268     }
1269     
1270     
1271     sum0v = vec_sum2s( sum0v, zero_s32v );
1272     sum1v = vec_sum2s( sum1v, zero_s32v );
1273     sum2v = vec_sum2s( sum2v, zero_s32v );
1274     
1275     sum0v = vec_splat( sum0v, 1 );
1276     sum1v = vec_splat( sum1v, 1 );
1277     sum2v = vec_splat( sum2v, 1 );
1278     
1279     vec_ste( sum0v, 0, &sum0);
1280     vec_ste( sum1v, 0, &sum1);
1281     vec_ste( sum2v, 0, &sum2);
1282     
1283     scores[0] = sum0;
1284     scores[1] = sum1;
1285     scores[2] = sum2;
1286     
1287 }
1288
1289 static void pixel_sad_x4_8x8_altivec( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1, uint8_t *pix2, uint8_t *pix3, int i_stride, int scores[4] )
1290 {
1291     DECLARE_ALIGNED_16( int sum0 );
1292     DECLARE_ALIGNED_16( int sum1 );
1293     DECLARE_ALIGNED_16( int sum2 );
1294     DECLARE_ALIGNED_16( int sum3 );
1295     int y;
1296     
1297     LOAD_ZERO;
1298     vec_u8_t temp_lv, temp_hv; 
1299     vec_u8_t fencv, pix0v, pix1v, pix2v, pix3v;
1300     vec_u8_t perm0vA, perm1vA, perm2vA, perm3vA, perm0vB, perm1vB, perm2vB, perm3vB, permEncv;
1301     
1302     vec_s32_t sum0v, sum1v, sum2v, sum3v;
1303     
1304     sum0v = vec_splat_s32(0);
1305     sum1v = vec_splat_s32(0);
1306     sum2v = vec_splat_s32(0);
1307     sum3v = vec_splat_s32(0);
1308     
1309     permEncv = vec_lvsl(0, fenc);
1310     perm0vA = vec_lvsl(0, pix0);
1311     perm1vA = vec_lvsl(0, pix1);
1312     perm2vA = vec_lvsl(0, pix2);
1313     perm3vA = vec_lvsl(0, pix3);
1314     
1315     perm0vB = vec_lvsl(0, pix0 + i_stride);
1316     perm1vB = vec_lvsl(0, pix1 + i_stride);
1317     perm2vB = vec_lvsl(0, pix2 + i_stride);
1318     perm3vB = vec_lvsl(0, pix3 + i_stride);
1319     
1320     
1321     for (y = 0; y < 4; y++)
1322     {
1323         temp_lv = vec_ld(0, pix0);
1324         temp_hv = vec_ld(16, pix0);
1325         pix0v = vec_perm(temp_lv, temp_hv, perm0vA);
1326         pix0 += i_stride;
1327         
1328         
1329         temp_lv = vec_ld(0, pix1);
1330         temp_hv = vec_ld(16, pix1);
1331         pix1v = vec_perm(temp_lv, temp_hv, perm1vA);
1332         pix1 += i_stride;
1333         
1334         temp_lv = vec_ld(0, fenc);
1335         fencv = vec_perm(temp_lv, temp_hv, permEncv);
1336         fenc += FENC_STRIDE;
1337         
1338         temp_lv = vec_ld(0, pix2);
1339         temp_hv = vec_ld(16, pix2);
1340         pix2v = vec_perm(temp_lv, temp_hv, perm2vA);
1341         pix2 += i_stride;
1342         
1343         temp_lv = vec_ld(0, pix3);
1344         temp_hv = vec_ld(16, pix3);
1345         pix3v = vec_perm(temp_lv, temp_hv, perm3vA);
1346         pix3 += i_stride;
1347         
1348         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
1349         
1350         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
1351         
1352         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v ); 
1353         
1354         sum3v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix3v ), vec_min( fencv, pix3v ) ), (vec_u32_t) sum3v ); 
1355         
1356         temp_lv = vec_ld(0, pix0);
1357         temp_hv = vec_ld(16, pix0);
1358         pix0v = vec_perm(temp_lv, temp_hv, perm0vB);
1359         pix0 += i_stride;
1360         
1361         
1362         temp_lv = vec_ld(0, pix1);
1363         temp_hv = vec_ld(16, pix1);
1364         pix1v = vec_perm(temp_lv, temp_hv, perm1vB);
1365         pix1 += i_stride;
1366         
1367         temp_lv = vec_ld(0, fenc);
1368         fencv = vec_perm(temp_lv, temp_hv, permEncv);
1369         fenc += FENC_STRIDE;
1370         
1371         temp_lv = vec_ld(0, pix2);
1372         temp_hv = vec_ld(16, pix2);
1373         pix2v = vec_perm(temp_lv, temp_hv, perm2vB);
1374         pix2 += i_stride;
1375         
1376         temp_lv = vec_ld(0, pix3);
1377         temp_hv = vec_ld(16, pix3);
1378         pix3v = vec_perm(temp_lv, temp_hv, perm3vB);
1379         pix3 += i_stride;
1380         
1381         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
1382         
1383         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
1384         
1385         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v ); 
1386         
1387         sum3v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix3v ), vec_min( fencv, pix3v ) ), (vec_u32_t) sum3v ); 
1388     }
1389     
1390     
1391     sum0v = vec_sum2s( sum0v, zero_s32v );
1392     sum1v = vec_sum2s( sum1v, zero_s32v );
1393     sum2v = vec_sum2s( sum2v, zero_s32v );
1394     sum3v = vec_sum2s( sum3v, zero_s32v );
1395     
1396     sum0v = vec_splat( sum0v, 1 );
1397     sum1v = vec_splat( sum1v, 1 );
1398     sum2v = vec_splat( sum2v, 1 );
1399     sum3v = vec_splat( sum3v, 1 );
1400     
1401     vec_ste( sum0v, 0, &sum0);
1402     vec_ste( sum1v, 0, &sum1);
1403     vec_ste( sum2v, 0, &sum2);
1404     vec_ste( sum3v, 0, &sum3);
1405     
1406     scores[0] = sum0;
1407     scores[1] = sum1;
1408     scores[2] = sum2;
1409     scores[3] = sum3; 
1410     
1411     
1412 }
1413
1414 static void pixel_sad_x3_8x8_altivec( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1, uint8_t *pix2, int i_stride, int scores[3] )
1415 {
1416     DECLARE_ALIGNED_16( int sum0 );
1417     DECLARE_ALIGNED_16( int sum1 );
1418     DECLARE_ALIGNED_16( int sum2 );
1419     int y;
1420     
1421     LOAD_ZERO;
1422     vec_u8_t temp_lv, temp_hv; 
1423     vec_u8_t fencv, pix0v, pix1v, pix2v;
1424     vec_u8_t perm0vA, perm1vA, perm2vA, perm0vB, perm1vB, perm2vB,  permEncv;
1425     
1426     vec_s32_t sum0v, sum1v, sum2v;
1427     
1428     sum0v = vec_splat_s32(0);
1429     sum1v = vec_splat_s32(0);
1430     sum2v = vec_splat_s32(0);
1431     
1432     permEncv = vec_lvsl(0, fenc);
1433     perm0vA = vec_lvsl(0, pix0);
1434     perm1vA = vec_lvsl(0, pix1);
1435     perm2vA = vec_lvsl(0, pix2);
1436     
1437     perm0vB = vec_lvsl(0, pix0 + i_stride);
1438     perm1vB = vec_lvsl(0, pix1 + i_stride);
1439     perm2vB = vec_lvsl(0, pix2 + i_stride);
1440     
1441     for (y = 0; y < 4; y++)
1442     {
1443         temp_lv = vec_ld(0, pix0);
1444         temp_hv = vec_ld(16, pix0);
1445         pix0v = vec_perm(temp_lv, temp_hv, perm0vA);
1446         pix0 += i_stride;
1447         
1448         
1449         temp_lv = vec_ld(0, pix1);
1450         temp_hv = vec_ld(16, pix1);
1451         pix1v = vec_perm(temp_lv, temp_hv, perm1vA);
1452         pix1 += i_stride;
1453         
1454         temp_lv = vec_ld(0, fenc);
1455         fencv = vec_perm(temp_lv, temp_hv, permEncv);
1456         fenc += FENC_STRIDE;
1457         
1458         temp_lv = vec_ld(0, pix2);
1459         temp_hv = vec_ld(16, pix2);
1460         pix2v = vec_perm(temp_lv, temp_hv, perm2vA);
1461         pix2 += i_stride;
1462         
1463         
1464         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
1465         
1466         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
1467         
1468         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v ); 
1469         
1470         
1471         temp_lv = vec_ld(0, pix0);
1472         temp_hv = vec_ld(16, pix0);
1473         pix0v = vec_perm(temp_lv, temp_hv, perm0vB);
1474         pix0 += i_stride;
1475         
1476         
1477         temp_lv = vec_ld(0, pix1);
1478         temp_hv = vec_ld(16, pix1);
1479         pix1v = vec_perm(temp_lv, temp_hv, perm1vB);
1480         pix1 += i_stride;
1481         
1482         temp_lv = vec_ld(0, fenc);
1483         fencv = vec_perm(temp_lv, temp_hv, permEncv);
1484         fenc += FENC_STRIDE;
1485         
1486         temp_lv = vec_ld(0, pix2);
1487         temp_hv = vec_ld(16, pix2);
1488         pix2v = vec_perm(temp_lv, temp_hv, perm2vB);
1489         pix2 += i_stride;
1490         
1491         
1492         sum0v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix0v ), vec_min( fencv, pix0v ) ), (vec_u32_t) sum0v ); 
1493         
1494         sum1v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix1v ), vec_min( fencv, pix1v ) ), (vec_u32_t) sum1v ); 
1495         
1496         sum2v = (vec_s32_t) vec_sum4s( vec_sub( vec_max( fencv, pix2v ), vec_min( fencv, pix2v ) ), (vec_u32_t) sum2v ); 
1497         
1498     }
1499     
1500     
1501     sum0v = vec_sum2s( sum0v, zero_s32v );
1502     sum1v = vec_sum2s( sum1v, zero_s32v );
1503     sum2v = vec_sum2s( sum2v, zero_s32v );
1504     
1505     sum0v = vec_splat( sum0v, 1 );
1506     sum1v = vec_splat( sum1v, 1 );
1507     sum2v = vec_splat( sum2v, 1 );
1508     
1509     vec_ste( sum0v, 0, &sum0);
1510     vec_ste( sum1v, 0, &sum1);
1511     vec_ste( sum2v, 0, &sum2);
1512     
1513     scores[0] = sum0;
1514     scores[1] = sum1;
1515     scores[2] = sum2;
1516 }
1517
1518 /***********************************************************************
1519 * SSD routines
1520 **********************************************************************/
1521
1522 static int pixel_ssd_16x16_altivec ( uint8_t *pix1, int i_stride_pix1,
1523                                      uint8_t *pix2, int i_stride_pix2)
1524 {
1525     DECLARE_ALIGNED_16( int sum );
1526     
1527     int y;
1528     LOAD_ZERO;
1529     vec_u8_t  pix1vA, pix2vA, pix1vB, pix2vB;
1530     vec_u32_t sumv;
1531     vec_u8_t maxA, minA, diffA, maxB, minB, diffB;
1532     vec_u8_t temp_lv, temp_hv;
1533     vec_u8_t permA, permB;
1534     
1535     sumv = vec_splat_u32(0);
1536     
1537     permA = vec_lvsl(0, pix2);
1538     permB = vec_lvsl(0, pix2 + i_stride_pix2);
1539     
1540     temp_lv = vec_ld(0, pix2);
1541     temp_hv = vec_ld(16, pix2);
1542     pix2vA = vec_perm(temp_lv, temp_hv, permA);
1543     pix1vA = vec_ld(0, pix1);
1544     
1545     for (y=0; y < 7; y++)
1546     {
1547         pix1 += i_stride_pix1;
1548         pix2 += i_stride_pix2;
1549         
1550         
1551         maxA = vec_max(pix1vA, pix2vA);
1552         minA = vec_min(pix1vA, pix2vA);
1553     
1554         
1555         temp_lv = vec_ld(0, pix2);
1556         temp_hv = vec_ld(16, pix2);
1557         pix2vB = vec_perm(temp_lv, temp_hv, permB);
1558         pix1vB = vec_ld(0, pix1);
1559     
1560         
1561         diffA = vec_sub(maxA, minA);
1562         sumv = vec_msum(diffA, diffA, sumv);
1563         
1564         pix1 += i_stride_pix1;
1565         pix2 += i_stride_pix2;
1566         
1567         maxB = vec_max(pix1vB, pix2vB);
1568         minB = vec_min(pix1vB, pix2vB);
1569         
1570         temp_lv = vec_ld(0, pix2);
1571         temp_hv = vec_ld(16, pix2);
1572         pix2vA = vec_perm(temp_lv, temp_hv, permA);
1573         pix1vA = vec_ld(0, pix1);
1574         
1575         diffB = vec_sub(maxB, minB);
1576         sumv = vec_msum(diffB, diffB, sumv);
1577         
1578     }
1579     
1580     pix1 += i_stride_pix1;
1581     pix2 += i_stride_pix2;
1582     
1583     temp_lv = vec_ld(0, pix2);
1584     temp_hv = vec_ld(16, pix2);
1585     pix2vB = vec_perm(temp_lv, temp_hv, permB);
1586     pix1vB = vec_ld(0, pix1);
1587     
1588     maxA = vec_max(pix1vA, pix2vA);
1589     minA = vec_min(pix1vA, pix2vA);
1590     
1591     maxB = vec_max(pix1vB, pix2vB); 
1592     minB = vec_min(pix1vB, pix2vB); 
1593     
1594     diffA = vec_sub(maxA, minA);
1595     sumv = vec_msum(diffA, diffA, sumv);
1596     
1597     diffB = vec_sub(maxB, minB);
1598     sumv = vec_msum(diffB, diffB, sumv);
1599     
1600     sumv = (vec_u32_t) vec_sums((vec_s32_t) sumv, zero_s32v);
1601     sumv = vec_splat(sumv, 3);
1602     vec_ste((vec_s32_t) sumv, 0, &sum);
1603     return sum;
1604
1605
1606 static int pixel_ssd_8x8_altivec ( uint8_t *pix1, int i_stride_pix1,
1607                                    uint8_t *pix2, int i_stride_pix2)
1608 {
1609     DECLARE_ALIGNED_16( int sum );
1610     
1611     int y;
1612     LOAD_ZERO;
1613     vec_u8_t  pix1v, pix2v;
1614     vec_u32_t sumv;
1615     vec_u8_t maxv, minv, diffv;
1616     vec_u8_t temp_lv, temp_hv;
1617     vec_u8_t perm1v, perm2v;
1618
1619     const vec_u32_t sel = (vec_u32_t)CV(-1,-1,0,0);
1620
1621     sumv = vec_splat_u32(0);
1622     
1623     perm1v = vec_lvsl(0, pix1);
1624     perm2v = vec_lvsl(0, pix2);
1625     
1626     for (y=0; y < 8; y++)
1627     {
1628         temp_hv = vec_ld(0, pix1);
1629         temp_lv = vec_ld(7, pix1);
1630         pix1v = vec_perm(temp_hv, temp_lv, perm1v);
1631
1632         temp_hv = vec_ld(0, pix2);
1633         temp_lv = vec_ld(7, pix2);
1634         pix2v = vec_perm(temp_hv, temp_lv, perm2v);
1635
1636         maxv = vec_max(pix1v, pix2v);
1637         minv = vec_min(pix1v, pix2v);
1638     
1639         diffv = vec_sub(maxv, minv);
1640         sumv = vec_msum(diffv, diffv, sumv);
1641
1642         pix1 += i_stride_pix1;
1643         pix2 += i_stride_pix2;
1644     }
1645
1646     sumv = vec_sel( zero_u32v, sumv, sel );
1647
1648     sumv = (vec_u32_t) vec_sums((vec_s32_t) sumv, zero_s32v);
1649     sumv = vec_splat(sumv, 3);
1650     vec_ste((vec_s32_t) sumv, 0, &sum);
1651
1652     return sum;
1653
1654
1655 /**********************************************************************
1656  * SA8D routines: sum of 8x8 Hadamard transformed differences
1657  **********************************************************************/
1658 /* SA8D_1D unrolled by 8 in Altivec */
1659 #define SA8D_1D_ALTIVEC( sa8d0v, sa8d1v, sa8d2v, sa8d3v, sa8d4v, sa8d5v, sa8d6v, sa8d7v )\
1660 {\
1661     /* int    a0  =        SRC(0) + SRC(4) */\
1662     vec_s16_t a0v = vec_add(sa8d0v, sa8d4v); \
1663     /* int    a4  =        SRC(0) - SRC(4) */\
1664     vec_s16_t a4v = vec_sub(sa8d0v, sa8d4v); \
1665     /* int    a1  =        SRC(1) + SRC(5) */\
1666     vec_s16_t a1v = vec_add(sa8d1v, sa8d5v); \
1667     /* int    a5  =        SRC(1) - SRC(5) */\
1668     vec_s16_t a5v = vec_sub(sa8d1v, sa8d5v); \
1669     /* int    a2  =        SRC(2) + SRC(6) */\
1670     vec_s16_t a2v = vec_add(sa8d2v, sa8d6v); \
1671     /* int    a6  =        SRC(2) - SRC(6) */\
1672     vec_s16_t a6v = vec_sub(sa8d2v, sa8d6v); \
1673     /* int    a3  =        SRC(3) + SRC(7) */\
1674     vec_s16_t a3v = vec_add(sa8d3v, sa8d7v); \
1675     /* int    a7  =        SRC(3) - SRC(7) */\
1676     vec_s16_t a7v = vec_sub(sa8d3v, sa8d7v); \
1677 \
1678     /* int    b0  =         a0 + a2  */\
1679     vec_s16_t b0v = vec_add(a0v, a2v); \
1680     /* int    b2  =         a0 - a2; */\
1681     vec_s16_t  b2v = vec_sub(a0v, a2v);\
1682     /* int    b1  =         a1 + a3; */\
1683     vec_s16_t b1v = vec_add(a1v, a3v); \
1684     /* int    b3  =         a1 - a3; */\
1685     vec_s16_t b3v = vec_sub(a1v, a3v); \
1686     /* int    b4  =         a4 + a6; */\
1687     vec_s16_t b4v = vec_add(a4v, a6v); \
1688     /* int    b6  =         a4 - a6; */\
1689     vec_s16_t b6v = vec_sub(a4v, a6v); \
1690     /* int    b5  =         a5 + a7; */\
1691     vec_s16_t b5v = vec_add(a5v, a7v); \
1692     /* int    b7  =         a5 - a7; */\
1693     vec_s16_t b7v = vec_sub(a5v, a7v); \
1694 \
1695     /* DST(0,        b0 + b1) */\
1696     sa8d0v = vec_add(b0v, b1v); \
1697     /* DST(1,        b0 - b1) */\
1698     sa8d1v = vec_sub(b0v, b1v); \
1699     /* DST(2,        b2 + b3) */\
1700     sa8d2v = vec_add(b2v, b3v); \
1701     /* DST(3,        b2 - b3) */\
1702     sa8d3v = vec_sub(b2v, b3v); \
1703     /* DST(4,        b4 + b5) */\
1704     sa8d4v = vec_add(b4v, b5v); \
1705     /* DST(5,        b4 - b5) */\
1706     sa8d5v = vec_sub(b4v, b5v); \
1707     /* DST(6,        b6 + b7) */\
1708     sa8d6v = vec_add(b6v, b7v); \
1709     /* DST(7,        b6 - b7) */\
1710     sa8d7v = vec_sub(b6v, b7v); \
1711 }
1712
1713 static int pixel_sa8d_8x8_core_altivec( uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2 )
1714 {
1715     int32_t i_satd=0;
1716
1717     PREP_DIFF;
1718
1719     vec_s16_t diff0v, diff1v, diff2v, diff3v, diff4v, diff5v, diff6v, diff7v;
1720
1721     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff0v );
1722     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff1v );
1723     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff2v );
1724     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff3v );
1725
1726     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff4v );
1727     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff5v );
1728     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff6v );
1729     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, diff7v );
1730
1731     vec_s16_t sa8d0v, sa8d1v, sa8d2v, sa8d3v, sa8d4v, sa8d5v, sa8d6v, sa8d7v;
1732
1733     SA8D_1D_ALTIVEC(diff0v, diff1v, diff2v, diff3v,
1734                     diff4v, diff5v, diff6v, diff7v);
1735
1736     VEC_TRANSPOSE_8(diff0v, diff1v, diff2v, diff3v,
1737                     diff4v, diff5v, diff6v, diff7v,
1738                     sa8d0v, sa8d1v, sa8d2v, sa8d3v,
1739                     sa8d4v, sa8d5v, sa8d6v, sa8d7v );
1740
1741     SA8D_1D_ALTIVEC(sa8d0v, sa8d1v, sa8d2v, sa8d3v,
1742                     sa8d4v, sa8d5v, sa8d6v, sa8d7v );
1743
1744     /* accumulation of the absolute value of all elements of the resulting bloc */
1745     vec_s16_t abs0v = VEC_ABS(sa8d0v);
1746     vec_s16_t abs1v = VEC_ABS(sa8d1v);
1747     vec_s16_t sum01v = vec_add(abs0v, abs1v);
1748
1749     vec_s16_t abs2v = VEC_ABS(sa8d2v);
1750     vec_s16_t abs3v = VEC_ABS(sa8d3v);
1751     vec_s16_t sum23v = vec_add(abs2v, abs3v);
1752
1753     vec_s16_t abs4v = VEC_ABS(sa8d4v);
1754     vec_s16_t abs5v = VEC_ABS(sa8d5v);
1755     vec_s16_t sum45v = vec_add(abs4v, abs5v);
1756
1757     vec_s16_t abs6v = VEC_ABS(sa8d6v);
1758     vec_s16_t abs7v = VEC_ABS(sa8d7v);
1759     vec_s16_t sum67v = vec_add(abs6v, abs7v);
1760
1761     vec_s16_t sum0123v = vec_add(sum01v, sum23v);
1762     vec_s16_t sum4567v = vec_add(sum45v, sum67v);
1763
1764     vec_s32_t sumblocv;
1765
1766     sumblocv = vec_sum4s(sum0123v, (vec_s32_t)zerov );
1767     sumblocv = vec_sum4s(sum4567v, sumblocv );
1768
1769     sumblocv = vec_sums(sumblocv, (vec_s32_t)zerov );
1770
1771     sumblocv = vec_splat(sumblocv, 3);
1772
1773     vec_ste(sumblocv, 0, &i_satd);
1774
1775     return i_satd;
1776 }
1777
1778 static int pixel_sa8d_8x8_altivec( uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2 )
1779 {
1780     int32_t i_satd;
1781     i_satd = (pixel_sa8d_8x8_core_altivec( pix1, i_pix1, pix2, i_pix2 )+2)>>2;
1782     return i_satd;
1783 }
1784
1785 static int pixel_sa8d_16x16_altivec( uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2 )
1786 {
1787     int32_t i_satd;
1788     
1789     i_satd = (pixel_sa8d_8x8_core_altivec( &pix1[0],     i_pix1, &pix2[0],     i_pix2 )
1790             + pixel_sa8d_8x8_core_altivec( &pix1[8],     i_pix1, &pix2[8],     i_pix2 )
1791             + pixel_sa8d_8x8_core_altivec( &pix1[8*i_pix1],   i_pix1, &pix2[8*i_pix2],   i_pix2 )
1792             + pixel_sa8d_8x8_core_altivec( &pix1[8*i_pix1+8], i_pix1, &pix2[8*i_pix2+8], i_pix2 ) +2)>>2;
1793     return i_satd;
1794 }
1795
1796 /****************************************************************************
1797  * structural similarity metric
1798  ****************************************************************************/
1799 static void ssim_4x4x2_core_altivec( const uint8_t *pix1, int stride1,
1800                                      const uint8_t *pix2, int stride2,
1801                                      int sums[2][4] )
1802 {
1803     DECLARE_ALIGNED_16( int temp[4] );
1804
1805     int y;
1806     vec_u8_t pix1v, pix2v;
1807     vec_u32_t s1v, s2v, ssv, s12v;
1808     PREP_LOAD;
1809     LOAD_ZERO;
1810
1811     s1v = s2v = ssv = s12v = zero_u32v;
1812
1813     for(y=0; y<4; y++)
1814     {
1815         VEC_LOAD( &pix1[y*stride1], pix1v, 16, vec_u8_t );
1816         VEC_LOAD( &pix2[y*stride2], pix2v, 16, vec_u8_t );
1817
1818         s1v = vec_sum4s( pix1v, s1v );
1819         s2v = vec_sum4s( pix2v, s2v );
1820         ssv = vec_msum( pix1v, pix1v, ssv );
1821         ssv = vec_msum( pix2v, pix2v, ssv );
1822         s12v = vec_msum( pix1v, pix2v, s12v );
1823     }
1824
1825     vec_st( (vec_s32_t)s1v, 0, temp );
1826     sums[0][0] = temp[0];
1827     sums[1][0] = temp[1];
1828     vec_st( (vec_s32_t)s2v, 0, temp );
1829     sums[0][1] = temp[0];
1830     sums[1][1] = temp[1];
1831     vec_st( (vec_s32_t)ssv, 0, temp );
1832     sums[0][2] = temp[0];
1833     sums[1][2] = temp[1];
1834     vec_st( (vec_s32_t)s12v, 0, temp );
1835     sums[0][3] = temp[0];
1836     sums[1][3] = temp[1];
1837 }
1838
1839 /****************************************************************************
1840  * x264_pixel_init:
1841  ****************************************************************************/
1842 void x264_pixel_altivec_init( x264_pixel_function_t *pixf )
1843 {
1844     pixf->sad[PIXEL_16x16]  = pixel_sad_16x16_altivec;
1845     pixf->sad[PIXEL_8x16]   = pixel_sad_8x16_altivec;
1846     pixf->sad[PIXEL_16x8]   = pixel_sad_16x8_altivec;
1847     pixf->sad[PIXEL_8x8]    = pixel_sad_8x8_altivec;
1848
1849     pixf->sad_x3[PIXEL_16x16] = pixel_sad_x3_16x16_altivec;
1850     pixf->sad_x3[PIXEL_8x16]  = pixel_sad_x3_8x16_altivec;
1851     pixf->sad_x3[PIXEL_16x8]  = pixel_sad_x3_16x8_altivec;
1852     pixf->sad_x3[PIXEL_8x8]   = pixel_sad_x3_8x8_altivec;
1853
1854     pixf->sad_x4[PIXEL_16x16] = pixel_sad_x4_16x16_altivec;
1855     pixf->sad_x4[PIXEL_8x16]  = pixel_sad_x4_8x16_altivec;
1856     pixf->sad_x4[PIXEL_16x8]  = pixel_sad_x4_16x8_altivec;
1857     pixf->sad_x4[PIXEL_8x8]   = pixel_sad_x4_8x8_altivec;
1858
1859     pixf->satd[PIXEL_16x16] = pixel_satd_16x16_altivec;
1860     pixf->satd[PIXEL_8x16]  = pixel_satd_8x16_altivec;
1861     pixf->satd[PIXEL_16x8]  = pixel_satd_16x8_altivec;
1862     pixf->satd[PIXEL_8x8]   = pixel_satd_8x8_altivec;
1863     pixf->satd[PIXEL_8x4]   = pixel_satd_8x4_altivec;
1864     pixf->satd[PIXEL_4x8]   = pixel_satd_4x8_altivec;
1865     pixf->satd[PIXEL_4x4]   = pixel_satd_4x4_altivec;
1866     
1867     pixf->ssd[PIXEL_16x16] = pixel_ssd_16x16_altivec;
1868     pixf->ssd[PIXEL_8x8]   = pixel_ssd_8x8_altivec;
1869
1870     pixf->sa8d[PIXEL_16x16] = pixel_sa8d_16x16_altivec;
1871     pixf->sa8d[PIXEL_8x8]   = pixel_sa8d_8x8_altivec;
1872
1873     pixf->ssim_4x4x2_core = ssim_4x4x2_core_altivec;
1874 }