pixel.c
上传用户:lctgjx
上传日期:2022-06-04
资源大小:8887k
文件大小:74k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

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