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