10a39d0a697ff3603e8c100300fda363658e10b23James Zern/*
20a39d0a697ff3603e8c100300fda363658e10b23James Zern *  Copyright (c) 2017 The WebM project authors. All Rights Reserved.
30a39d0a697ff3603e8c100300fda363658e10b23James Zern *
40a39d0a697ff3603e8c100300fda363658e10b23James Zern *  Use of this source code is governed by a BSD-style license
50a39d0a697ff3603e8c100300fda363658e10b23James Zern *  that can be found in the LICENSE file in the root of the source
60a39d0a697ff3603e8c100300fda363658e10b23James Zern *  tree. An additional intellectual property rights grant can be found
70a39d0a697ff3603e8c100300fda363658e10b23James Zern *  in the file PATENTS.  All contributing project authors may
80a39d0a697ff3603e8c100300fda363658e10b23James Zern *  be found in the AUTHORS file in the root of the source tree.
90a39d0a697ff3603e8c100300fda363658e10b23James Zern */
100a39d0a697ff3603e8c100300fda363658e10b23James Zern
110a39d0a697ff3603e8c100300fda363658e10b23James Zern#include "./vpx_dsp_rtcd.h"
120a39d0a697ff3603e8c100300fda363658e10b23James Zern#include "vpx_dsp/ppc/types_vsx.h"
130a39d0a697ff3603e8c100300fda363658e10b23James Zern#include "vpx_dsp/ppc/transpose_vsx.h"
140a39d0a697ff3603e8c100300fda363658e10b23James Zern#include "vpx_dsp/ppc/bitdepth_conversion_vsx.h"
150a39d0a697ff3603e8c100300fda363658e10b23James Zern
160a39d0a697ff3603e8c100300fda363658e10b23James Zernstatic void vpx_hadamard_s16_8x8_one_pass(int16x8_t v[8]) {
170a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t b0 = vec_add(v[0], v[1]);
180a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t b1 = vec_sub(v[0], v[1]);
190a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t b2 = vec_add(v[2], v[3]);
200a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t b3 = vec_sub(v[2], v[3]);
210a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t b4 = vec_add(v[4], v[5]);
220a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t b5 = vec_sub(v[4], v[5]);
230a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t b6 = vec_add(v[6], v[7]);
240a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t b7 = vec_sub(v[6], v[7]);
250a39d0a697ff3603e8c100300fda363658e10b23James Zern
260a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t c0 = vec_add(b0, b2);
270a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t c1 = vec_add(b1, b3);
280a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t c2 = vec_sub(b0, b2);
290a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t c3 = vec_sub(b1, b3);
300a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t c4 = vec_add(b4, b6);
310a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t c5 = vec_add(b5, b7);
320a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t c6 = vec_sub(b4, b6);
330a39d0a697ff3603e8c100300fda363658e10b23James Zern  const int16x8_t c7 = vec_sub(b5, b7);
340a39d0a697ff3603e8c100300fda363658e10b23James Zern
350a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[0] = vec_add(c0, c4);
360a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[1] = vec_sub(c2, c6);
370a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[2] = vec_sub(c0, c4);
380a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[3] = vec_add(c2, c6);
390a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[4] = vec_add(c3, c7);
400a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[5] = vec_sub(c3, c7);
410a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[6] = vec_sub(c1, c5);
420a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[7] = vec_add(c1, c5);
430a39d0a697ff3603e8c100300fda363658e10b23James Zern}
440a39d0a697ff3603e8c100300fda363658e10b23James Zern
45df37111358d02836cb29bbcb9c6e4c95dff90a16Johannvoid vpx_hadamard_8x8_vsx(const int16_t *src_diff, ptrdiff_t src_stride,
460a39d0a697ff3603e8c100300fda363658e10b23James Zern                          tran_low_t *coeff) {
470a39d0a697ff3603e8c100300fda363658e10b23James Zern  int16x8_t v[8];
480a39d0a697ff3603e8c100300fda363658e10b23James Zern
490a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[0] = vec_vsx_ld(0, src_diff);
500a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[1] = vec_vsx_ld(0, src_diff + src_stride);
510a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[2] = vec_vsx_ld(0, src_diff + (2 * src_stride));
520a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[3] = vec_vsx_ld(0, src_diff + (3 * src_stride));
530a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[4] = vec_vsx_ld(0, src_diff + (4 * src_stride));
540a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[5] = vec_vsx_ld(0, src_diff + (5 * src_stride));
550a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[6] = vec_vsx_ld(0, src_diff + (6 * src_stride));
560a39d0a697ff3603e8c100300fda363658e10b23James Zern  v[7] = vec_vsx_ld(0, src_diff + (7 * src_stride));
570a39d0a697ff3603e8c100300fda363658e10b23James Zern
580a39d0a697ff3603e8c100300fda363658e10b23James Zern  vpx_hadamard_s16_8x8_one_pass(v);
590a39d0a697ff3603e8c100300fda363658e10b23James Zern
600a39d0a697ff3603e8c100300fda363658e10b23James Zern  vpx_transpose_s16_8x8(v);
610a39d0a697ff3603e8c100300fda363658e10b23James Zern
620a39d0a697ff3603e8c100300fda363658e10b23James Zern  vpx_hadamard_s16_8x8_one_pass(v);
630a39d0a697ff3603e8c100300fda363658e10b23James Zern
640a39d0a697ff3603e8c100300fda363658e10b23James Zern  store_tran_low(v[0], 0, coeff);
650a39d0a697ff3603e8c100300fda363658e10b23James Zern  store_tran_low(v[1], 0, coeff + 8);
660a39d0a697ff3603e8c100300fda363658e10b23James Zern  store_tran_low(v[2], 0, coeff + 16);
670a39d0a697ff3603e8c100300fda363658e10b23James Zern  store_tran_low(v[3], 0, coeff + 24);
680a39d0a697ff3603e8c100300fda363658e10b23James Zern  store_tran_low(v[4], 0, coeff + 32);
690a39d0a697ff3603e8c100300fda363658e10b23James Zern  store_tran_low(v[5], 0, coeff + 40);
700a39d0a697ff3603e8c100300fda363658e10b23James Zern  store_tran_low(v[6], 0, coeff + 48);
710a39d0a697ff3603e8c100300fda363658e10b23James Zern  store_tran_low(v[7], 0, coeff + 56);
720a39d0a697ff3603e8c100300fda363658e10b23James Zern}
730a39d0a697ff3603e8c100300fda363658e10b23James Zern
74df37111358d02836cb29bbcb9c6e4c95dff90a16Johannvoid vpx_hadamard_16x16_vsx(const int16_t *src_diff, ptrdiff_t src_stride,
750a39d0a697ff3603e8c100300fda363658e10b23James Zern                            tran_low_t *coeff) {
760a39d0a697ff3603e8c100300fda363658e10b23James Zern  int i;
770a39d0a697ff3603e8c100300fda363658e10b23James Zern  const uint16x8_t ones = vec_splat_u16(1);
780a39d0a697ff3603e8c100300fda363658e10b23James Zern
790a39d0a697ff3603e8c100300fda363658e10b23James Zern  /* Rearrange 16x16 to 8x32 and remove stride.
800a39d0a697ff3603e8c100300fda363658e10b23James Zern   * Top left first. */
810a39d0a697ff3603e8c100300fda363658e10b23James Zern  vpx_hadamard_8x8_vsx(src_diff, src_stride, coeff);
820a39d0a697ff3603e8c100300fda363658e10b23James Zern  /* Top right. */
830a39d0a697ff3603e8c100300fda363658e10b23James Zern  vpx_hadamard_8x8_vsx(src_diff + 8 + 0 * src_stride, src_stride, coeff + 64);
840a39d0a697ff3603e8c100300fda363658e10b23James Zern  /* Bottom left. */
850a39d0a697ff3603e8c100300fda363658e10b23James Zern  vpx_hadamard_8x8_vsx(src_diff + 0 + 8 * src_stride, src_stride, coeff + 128);
860a39d0a697ff3603e8c100300fda363658e10b23James Zern  /* Bottom right. */
870a39d0a697ff3603e8c100300fda363658e10b23James Zern  vpx_hadamard_8x8_vsx(src_diff + 8 + 8 * src_stride, src_stride, coeff + 192);
880a39d0a697ff3603e8c100300fda363658e10b23James Zern
890a39d0a697ff3603e8c100300fda363658e10b23James Zern  /* Overlay the 8x8 blocks and combine. */
900a39d0a697ff3603e8c100300fda363658e10b23James Zern  for (i = 0; i < 64; i += 8) {
910a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t a0 = load_tran_low(0, coeff);
920a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t a1 = load_tran_low(0, coeff + 64);
930a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t a2 = load_tran_low(0, coeff + 128);
940a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t a3 = load_tran_low(0, coeff + 192);
950a39d0a697ff3603e8c100300fda363658e10b23James Zern
960a39d0a697ff3603e8c100300fda363658e10b23James Zern    /* Prevent the result from escaping int16_t. */
970a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t b0 = vec_sra(a0, ones);
980a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t b1 = vec_sra(a1, ones);
990a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t b2 = vec_sra(a2, ones);
1000a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t b3 = vec_sra(a3, ones);
1010a39d0a697ff3603e8c100300fda363658e10b23James Zern
1020a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t c0 = vec_add(b0, b1);
1030a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t c2 = vec_add(b2, b3);
1040a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t c1 = vec_sub(b0, b1);
1050a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t c3 = vec_sub(b2, b3);
1060a39d0a697ff3603e8c100300fda363658e10b23James Zern
1070a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t d0 = vec_add(c0, c2);
1080a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t d1 = vec_add(c1, c3);
1090a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t d2 = vec_sub(c0, c2);
1100a39d0a697ff3603e8c100300fda363658e10b23James Zern    const int16x8_t d3 = vec_sub(c1, c3);
1110a39d0a697ff3603e8c100300fda363658e10b23James Zern
1120a39d0a697ff3603e8c100300fda363658e10b23James Zern    store_tran_low(d0, 0, coeff);
1130a39d0a697ff3603e8c100300fda363658e10b23James Zern    store_tran_low(d1, 0, coeff + 64);
1140a39d0a697ff3603e8c100300fda363658e10b23James Zern    store_tran_low(d2, 0, coeff + 128);
1150a39d0a697ff3603e8c100300fda363658e10b23James Zern    store_tran_low(d3, 0, coeff + 192);
1160a39d0a697ff3603e8c100300fda363658e10b23James Zern
1170a39d0a697ff3603e8c100300fda363658e10b23James Zern    coeff += 8;
1180a39d0a697ff3603e8c100300fda363658e10b23James Zern  }
1190a39d0a697ff3603e8c100300fda363658e10b23James Zern}
120