ppc: Optimize add8x8_idct_dc
authorAlexandra Hájková <alexandra.khirnova@gmail.com>
Sat, 23 Jun 2018 14:58:17 +0000 (14:58 +0000)
committerHenrik Gramner <henrik@gramner.com>
Mon, 9 Jul 2018 00:29:13 +0000 (02:29 +0200)
common/ppc/dct.c

index 9956e69..0dbddd3 100644 (file)
@@ -294,29 +294,64 @@ void x264_sub16x16_dct8_altivec( int16_t dct[4][64], uint8_t *pix1, uint8_t *pix
     vec_vsx_st( dcvsum8, 0, dest );                                   \
 }
 
-static void idct8_dc_altivec( uint8_t *dst, vec_s16_t dcv )
-{
-    LOAD_ZERO;
-    ALTIVEC_STORE8_DC_SUM_CLIP( &dst[0*FDEC_STRIDE], dcv );
-    ALTIVEC_STORE8_DC_SUM_CLIP( &dst[1*FDEC_STRIDE], dcv );
-    ALTIVEC_STORE8_DC_SUM_CLIP( &dst[2*FDEC_STRIDE], dcv );
-    ALTIVEC_STORE8_DC_SUM_CLIP( &dst[3*FDEC_STRIDE], dcv );
-}
-
 void x264_add8x8_idct_dc_altivec( uint8_t *p_dst, int16_t dct[4] )
 {
-    vec_s16_t dcv;
+    vec_s16_t dcv0, dcv1;
     vec_s16_t v32 = vec_sl( vec_splat_s16( 8 ), vec_splat_u16( 2 ) );
     vec_u16_t v6 = vec_splat_u16( 6 );
-    vec_s16_t dctv = vec_vsx_ld( 0, dct );
+    vec_s16_t dctv = vec_ld( 0, dct );
+    vec_u8_t dstv0, dstv1, dstv2, dstv3, dstv4, dstv5, dstv6, dstv7;
+    vec_s16_t dcvsum0, dcvsum1, dcvsum2, dcvsum3, dcvsum4, dcvsum5, dcvsum6, dcvsum7;
+    vec_u8_t dcvsum8_0, dcvsum8_1, dcvsum8_2, dcvsum8_3, dcvsum8_4, dcvsum8_5, dcvsum8_6, dcvsum8_7;
+    LOAD_ZERO;
 
     dctv = vec_sra( vec_add( dctv, v32 ), v6 );
-    dcv = (vec_s16_t)vec_mergeh( (vec_s32_t)vec_splat( dctv, 0 ), (vec_s32_t)vec_splat( dctv, 1 ) );
-    dcv = (vec_s16_t)vec_mergeh( (vec_s32_t)dcv, (vec_s32_t)dcv );
-    idct8_dc_altivec( &p_dst[0], dcv );
-    dcv = (vec_s16_t)vec_mergeh( (vec_s32_t)vec_splat( dctv, 2 ), (vec_s32_t)vec_splat( dctv, 3 ) );
-    dcv = (vec_s16_t)vec_mergeh( (vec_s32_t)dcv, (vec_s32_t)dcv );
-    idct8_dc_altivec( &p_dst[4*FDEC_STRIDE+0], dcv );
+    dcv1 = (vec_s16_t)vec_mergeh( dctv, dctv );
+    dcv0 = (vec_s16_t)vec_mergeh( (vec_s32_t)dcv1, (vec_s32_t)dcv1 );
+    dcv1 = (vec_s16_t)vec_mergel( (vec_s32_t)dcv1, (vec_s32_t)dcv1 );
+
+    dstv0   = vec_vsx_ld( 0, p_dst );
+    dstv4   = vec_vsx_ld( 0, p_dst + 4*FDEC_STRIDE );
+    dstv1   = vec_vsx_ld( 0, p_dst + 1*FDEC_STRIDE );
+    dstv5   = vec_vsx_ld( 0, p_dst + 4*FDEC_STRIDE + 1*FDEC_STRIDE );
+    dstv2   = vec_vsx_ld( 0, p_dst + 2*FDEC_STRIDE);
+    dstv6   = vec_vsx_ld( 0, p_dst + 4*FDEC_STRIDE + 2*FDEC_STRIDE );
+    dstv3   = vec_vsx_ld( 0, p_dst + 3*FDEC_STRIDE);
+    dstv7   = vec_vsx_ld( 0, p_dst + 4*FDEC_STRIDE + 3*FDEC_STRIDE );
+
+    vec_s16_t s0 = vec_u8_to_s16_h( dstv0 );
+    vec_s16_t s1 = vec_u8_to_s16_h( dstv4 );
+    vec_s16_t s2 = vec_u8_to_s16_h( dstv1 );
+    vec_s16_t s3 = vec_u8_to_s16_h( dstv5 );
+    vec_s16_t s4 = vec_u8_to_s16_h( dstv2 );
+    vec_s16_t s5 = vec_u8_to_s16_h( dstv6 );
+    vec_s16_t s6 = vec_u8_to_s16_h( dstv3 );
+    vec_s16_t s7 = vec_u8_to_s16_h( dstv7 );
+    dcvsum0 = vec_adds( dcv0, s0 );
+    dcvsum4 = vec_adds( dcv1, s1 );
+    dcvsum1 = vec_adds( dcv0, s2 );
+    dcvsum5 = vec_adds( dcv1, s3 );
+    dcvsum2 = vec_adds( dcv0, s4 );
+    dcvsum6 = vec_adds( dcv1, s5 );
+    dcvsum3 = vec_adds( dcv0, s6 );
+    dcvsum7 = vec_adds( dcv1, s7 );
+    dcvsum8_0 = vec_packsu( dcvsum0, vec_u8_to_s16_l( dstv0 ) );
+    dcvsum8_1 = vec_packsu( dcvsum1, vec_u8_to_s16_l( dstv1 ) );
+    dcvsum8_2 = vec_packsu( dcvsum2, vec_u8_to_s16_l( dstv2 ) );
+    dcvsum8_3 = vec_packsu( dcvsum3, vec_u8_to_s16_l( dstv3 ) );
+    dcvsum8_4 = vec_packsu( dcvsum4, vec_u8_to_s16_l( dstv4 ) );
+    dcvsum8_5 = vec_packsu( dcvsum5, vec_u8_to_s16_l( dstv5 ) );
+    dcvsum8_6 = vec_packsu( dcvsum6, vec_u8_to_s16_l( dstv6 ) );
+    dcvsum8_7 = vec_packsu( dcvsum7, vec_u8_to_s16_l( dstv7 ) );
+
+    vec_vsx_st( dcvsum8_0, 0, p_dst );
+    vec_vsx_st( dcvsum8_4, 0, p_dst + 4*FDEC_STRIDE );
+    vec_vsx_st( dcvsum8_1, 0, p_dst + 1*FDEC_STRIDE );
+    vec_vsx_st( dcvsum8_5, 0, p_dst + 4*FDEC_STRIDE + 1*FDEC_STRIDE );
+    vec_vsx_st( dcvsum8_2, 0, p_dst + 2*FDEC_STRIDE );
+    vec_vsx_st( dcvsum8_6, 0, p_dst + 4*FDEC_STRIDE + 2*FDEC_STRIDE );
+    vec_vsx_st( dcvsum8_3, 0, p_dst + 3*FDEC_STRIDE );
+    vec_vsx_st( dcvsum8_7, 0, p_dst + 4*FDEC_STRIDE + 3*FDEC_STRIDE );
 }
 
 #define IDCT_1D_ALTIVEC(s0, s1, s2, s3,  d0, d1, d2, d3) \