xref: /aosp_15_r20/external/libvpx/vpx_dsp/ppc/hadamard_vsx.c (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
1*fb1b10abSAndroid Build Coastguard Worker /*
2*fb1b10abSAndroid Build Coastguard Worker  *  Copyright (c) 2017 The WebM project authors. All Rights Reserved.
3*fb1b10abSAndroid Build Coastguard Worker  *
4*fb1b10abSAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*fb1b10abSAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*fb1b10abSAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*fb1b10abSAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*fb1b10abSAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*fb1b10abSAndroid Build Coastguard Worker  */
10*fb1b10abSAndroid Build Coastguard Worker 
11*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_dsp_rtcd.h"
12*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/ppc/types_vsx.h"
13*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/ppc/transpose_vsx.h"
14*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/ppc/bitdepth_conversion_vsx.h"
15*fb1b10abSAndroid Build Coastguard Worker 
vpx_hadamard_s16_8x8_one_pass(int16x8_t v[8])16*fb1b10abSAndroid Build Coastguard Worker static void vpx_hadamard_s16_8x8_one_pass(int16x8_t v[8]) {
17*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t b0 = vec_add(v[0], v[1]);
18*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t b1 = vec_sub(v[0], v[1]);
19*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t b2 = vec_add(v[2], v[3]);
20*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t b3 = vec_sub(v[2], v[3]);
21*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t b4 = vec_add(v[4], v[5]);
22*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t b5 = vec_sub(v[4], v[5]);
23*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t b6 = vec_add(v[6], v[7]);
24*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t b7 = vec_sub(v[6], v[7]);
25*fb1b10abSAndroid Build Coastguard Worker 
26*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t c0 = vec_add(b0, b2);
27*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t c1 = vec_add(b1, b3);
28*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t c2 = vec_sub(b0, b2);
29*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t c3 = vec_sub(b1, b3);
30*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t c4 = vec_add(b4, b6);
31*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t c5 = vec_add(b5, b7);
32*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t c6 = vec_sub(b4, b6);
33*fb1b10abSAndroid Build Coastguard Worker   const int16x8_t c7 = vec_sub(b5, b7);
34*fb1b10abSAndroid Build Coastguard Worker 
35*fb1b10abSAndroid Build Coastguard Worker   v[0] = vec_add(c0, c4);
36*fb1b10abSAndroid Build Coastguard Worker   v[1] = vec_sub(c2, c6);
37*fb1b10abSAndroid Build Coastguard Worker   v[2] = vec_sub(c0, c4);
38*fb1b10abSAndroid Build Coastguard Worker   v[3] = vec_add(c2, c6);
39*fb1b10abSAndroid Build Coastguard Worker   v[4] = vec_add(c3, c7);
40*fb1b10abSAndroid Build Coastguard Worker   v[5] = vec_sub(c3, c7);
41*fb1b10abSAndroid Build Coastguard Worker   v[6] = vec_sub(c1, c5);
42*fb1b10abSAndroid Build Coastguard Worker   v[7] = vec_add(c1, c5);
43*fb1b10abSAndroid Build Coastguard Worker }
44*fb1b10abSAndroid Build Coastguard Worker 
vpx_hadamard_8x8_vsx(const int16_t * src_diff,ptrdiff_t src_stride,tran_low_t * coeff)45*fb1b10abSAndroid Build Coastguard Worker void vpx_hadamard_8x8_vsx(const int16_t *src_diff, ptrdiff_t src_stride,
46*fb1b10abSAndroid Build Coastguard Worker                           tran_low_t *coeff) {
47*fb1b10abSAndroid Build Coastguard Worker   int16x8_t v[8];
48*fb1b10abSAndroid Build Coastguard Worker 
49*fb1b10abSAndroid Build Coastguard Worker   v[0] = vec_vsx_ld(0, src_diff);
50*fb1b10abSAndroid Build Coastguard Worker   v[1] = vec_vsx_ld(0, src_diff + src_stride);
51*fb1b10abSAndroid Build Coastguard Worker   v[2] = vec_vsx_ld(0, src_diff + (2 * src_stride));
52*fb1b10abSAndroid Build Coastguard Worker   v[3] = vec_vsx_ld(0, src_diff + (3 * src_stride));
53*fb1b10abSAndroid Build Coastguard Worker   v[4] = vec_vsx_ld(0, src_diff + (4 * src_stride));
54*fb1b10abSAndroid Build Coastguard Worker   v[5] = vec_vsx_ld(0, src_diff + (5 * src_stride));
55*fb1b10abSAndroid Build Coastguard Worker   v[6] = vec_vsx_ld(0, src_diff + (6 * src_stride));
56*fb1b10abSAndroid Build Coastguard Worker   v[7] = vec_vsx_ld(0, src_diff + (7 * src_stride));
57*fb1b10abSAndroid Build Coastguard Worker 
58*fb1b10abSAndroid Build Coastguard Worker   vpx_hadamard_s16_8x8_one_pass(v);
59*fb1b10abSAndroid Build Coastguard Worker 
60*fb1b10abSAndroid Build Coastguard Worker   vpx_transpose_s16_8x8(v);
61*fb1b10abSAndroid Build Coastguard Worker 
62*fb1b10abSAndroid Build Coastguard Worker   vpx_hadamard_s16_8x8_one_pass(v);
63*fb1b10abSAndroid Build Coastguard Worker 
64*fb1b10abSAndroid Build Coastguard Worker   store_tran_low(v[0], 0, coeff);
65*fb1b10abSAndroid Build Coastguard Worker   store_tran_low(v[1], 0, coeff + 8);
66*fb1b10abSAndroid Build Coastguard Worker   store_tran_low(v[2], 0, coeff + 16);
67*fb1b10abSAndroid Build Coastguard Worker   store_tran_low(v[3], 0, coeff + 24);
68*fb1b10abSAndroid Build Coastguard Worker   store_tran_low(v[4], 0, coeff + 32);
69*fb1b10abSAndroid Build Coastguard Worker   store_tran_low(v[5], 0, coeff + 40);
70*fb1b10abSAndroid Build Coastguard Worker   store_tran_low(v[6], 0, coeff + 48);
71*fb1b10abSAndroid Build Coastguard Worker   store_tran_low(v[7], 0, coeff + 56);
72*fb1b10abSAndroid Build Coastguard Worker }
73*fb1b10abSAndroid Build Coastguard Worker 
vpx_hadamard_16x16_vsx(const int16_t * src_diff,ptrdiff_t src_stride,tran_low_t * coeff)74*fb1b10abSAndroid Build Coastguard Worker void vpx_hadamard_16x16_vsx(const int16_t *src_diff, ptrdiff_t src_stride,
75*fb1b10abSAndroid Build Coastguard Worker                             tran_low_t *coeff) {
76*fb1b10abSAndroid Build Coastguard Worker   int i;
77*fb1b10abSAndroid Build Coastguard Worker   const uint16x8_t ones = vec_splat_u16(1);
78*fb1b10abSAndroid Build Coastguard Worker 
79*fb1b10abSAndroid Build Coastguard Worker   /* Rearrange 16x16 to 8x32 and remove stride.
80*fb1b10abSAndroid Build Coastguard Worker    * Top left first. */
81*fb1b10abSAndroid Build Coastguard Worker   vpx_hadamard_8x8_vsx(src_diff, src_stride, coeff);
82*fb1b10abSAndroid Build Coastguard Worker   /* Top right. */
83*fb1b10abSAndroid Build Coastguard Worker   vpx_hadamard_8x8_vsx(src_diff + 8 + 0 * src_stride, src_stride, coeff + 64);
84*fb1b10abSAndroid Build Coastguard Worker   /* Bottom left. */
85*fb1b10abSAndroid Build Coastguard Worker   vpx_hadamard_8x8_vsx(src_diff + 0 + 8 * src_stride, src_stride, coeff + 128);
86*fb1b10abSAndroid Build Coastguard Worker   /* Bottom right. */
87*fb1b10abSAndroid Build Coastguard Worker   vpx_hadamard_8x8_vsx(src_diff + 8 + 8 * src_stride, src_stride, coeff + 192);
88*fb1b10abSAndroid Build Coastguard Worker 
89*fb1b10abSAndroid Build Coastguard Worker   /* Overlay the 8x8 blocks and combine. */
90*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < 64; i += 8) {
91*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t a0 = load_tran_low(0, coeff);
92*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t a1 = load_tran_low(0, coeff + 64);
93*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t a2 = load_tran_low(0, coeff + 128);
94*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t a3 = load_tran_low(0, coeff + 192);
95*fb1b10abSAndroid Build Coastguard Worker 
96*fb1b10abSAndroid Build Coastguard Worker     /* Prevent the result from escaping int16_t. */
97*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t b0 = vec_sra(a0, ones);
98*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t b1 = vec_sra(a1, ones);
99*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t b2 = vec_sra(a2, ones);
100*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t b3 = vec_sra(a3, ones);
101*fb1b10abSAndroid Build Coastguard Worker 
102*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t c0 = vec_add(b0, b1);
103*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t c2 = vec_add(b2, b3);
104*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t c1 = vec_sub(b0, b1);
105*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t c3 = vec_sub(b2, b3);
106*fb1b10abSAndroid Build Coastguard Worker 
107*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t d0 = vec_add(c0, c2);
108*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t d1 = vec_add(c1, c3);
109*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t d2 = vec_sub(c0, c2);
110*fb1b10abSAndroid Build Coastguard Worker     const int16x8_t d3 = vec_sub(c1, c3);
111*fb1b10abSAndroid Build Coastguard Worker 
112*fb1b10abSAndroid Build Coastguard Worker     store_tran_low(d0, 0, coeff);
113*fb1b10abSAndroid Build Coastguard Worker     store_tran_low(d1, 0, coeff + 64);
114*fb1b10abSAndroid Build Coastguard Worker     store_tran_low(d2, 0, coeff + 128);
115*fb1b10abSAndroid Build Coastguard Worker     store_tran_low(d3, 0, coeff + 192);
116*fb1b10abSAndroid Build Coastguard Worker 
117*fb1b10abSAndroid Build Coastguard Worker     coeff += 8;
118*fb1b10abSAndroid Build Coastguard Worker   }
119*fb1b10abSAndroid Build Coastguard Worker }
120