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