idct32x32_1_add_neon.c revision 7ce0a1d1337c01056ba24006efab21f00e179e04
1/* 2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include <arm_neon.h> 12 13#include "./vpx_config.h" 14 15#include "vpx_dsp/inv_txfm.h" 16#include "vpx_ports/mem.h" 17 18static INLINE void LD_16x8( 19 uint8_t *d, 20 int d_stride, 21 uint8x16_t *q8u8, 22 uint8x16_t *q9u8, 23 uint8x16_t *q10u8, 24 uint8x16_t *q11u8, 25 uint8x16_t *q12u8, 26 uint8x16_t *q13u8, 27 uint8x16_t *q14u8, 28 uint8x16_t *q15u8) { 29 *q8u8 = vld1q_u8(d); 30 d += d_stride; 31 *q9u8 = vld1q_u8(d); 32 d += d_stride; 33 *q10u8 = vld1q_u8(d); 34 d += d_stride; 35 *q11u8 = vld1q_u8(d); 36 d += d_stride; 37 *q12u8 = vld1q_u8(d); 38 d += d_stride; 39 *q13u8 = vld1q_u8(d); 40 d += d_stride; 41 *q14u8 = vld1q_u8(d); 42 d += d_stride; 43 *q15u8 = vld1q_u8(d); 44 return; 45} 46 47static INLINE void ADD_DIFF_16x8( 48 uint8x16_t qdiffu8, 49 uint8x16_t *q8u8, 50 uint8x16_t *q9u8, 51 uint8x16_t *q10u8, 52 uint8x16_t *q11u8, 53 uint8x16_t *q12u8, 54 uint8x16_t *q13u8, 55 uint8x16_t *q14u8, 56 uint8x16_t *q15u8) { 57 *q8u8 = vqaddq_u8(*q8u8, qdiffu8); 58 *q9u8 = vqaddq_u8(*q9u8, qdiffu8); 59 *q10u8 = vqaddq_u8(*q10u8, qdiffu8); 60 *q11u8 = vqaddq_u8(*q11u8, qdiffu8); 61 *q12u8 = vqaddq_u8(*q12u8, qdiffu8); 62 *q13u8 = vqaddq_u8(*q13u8, qdiffu8); 63 *q14u8 = vqaddq_u8(*q14u8, qdiffu8); 64 *q15u8 = vqaddq_u8(*q15u8, qdiffu8); 65 return; 66} 67 68static INLINE void SUB_DIFF_16x8( 69 uint8x16_t qdiffu8, 70 uint8x16_t *q8u8, 71 uint8x16_t *q9u8, 72 uint8x16_t *q10u8, 73 uint8x16_t *q11u8, 74 uint8x16_t *q12u8, 75 uint8x16_t *q13u8, 76 uint8x16_t *q14u8, 77 uint8x16_t *q15u8) { 78 *q8u8 = vqsubq_u8(*q8u8, qdiffu8); 79 *q9u8 = vqsubq_u8(*q9u8, qdiffu8); 80 *q10u8 = vqsubq_u8(*q10u8, qdiffu8); 81 *q11u8 = vqsubq_u8(*q11u8, qdiffu8); 82 *q12u8 = vqsubq_u8(*q12u8, qdiffu8); 83 *q13u8 = vqsubq_u8(*q13u8, qdiffu8); 84 *q14u8 = vqsubq_u8(*q14u8, qdiffu8); 85 *q15u8 = vqsubq_u8(*q15u8, qdiffu8); 86 return; 87} 88 89static INLINE void ST_16x8( 90 uint8_t *d, 91 int d_stride, 92 uint8x16_t *q8u8, 93 uint8x16_t *q9u8, 94 uint8x16_t *q10u8, 95 uint8x16_t *q11u8, 96 uint8x16_t *q12u8, 97 uint8x16_t *q13u8, 98 uint8x16_t *q14u8, 99 uint8x16_t *q15u8) { 100 vst1q_u8(d, *q8u8); 101 d += d_stride; 102 vst1q_u8(d, *q9u8); 103 d += d_stride; 104 vst1q_u8(d, *q10u8); 105 d += d_stride; 106 vst1q_u8(d, *q11u8); 107 d += d_stride; 108 vst1q_u8(d, *q12u8); 109 d += d_stride; 110 vst1q_u8(d, *q13u8); 111 d += d_stride; 112 vst1q_u8(d, *q14u8); 113 d += d_stride; 114 vst1q_u8(d, *q15u8); 115 return; 116} 117 118void vpx_idct32x32_1_add_neon( 119 int16_t *input, 120 uint8_t *dest, 121 int dest_stride) { 122 uint8x16_t q0u8, q8u8, q9u8, q10u8, q11u8, q12u8, q13u8, q14u8, q15u8; 123 int i, j, dest_stride8; 124 uint8_t *d; 125 int16_t a1, cospi_16_64 = 11585; 126 int16_t out = dct_const_round_shift(input[0] * cospi_16_64); 127 128 out = dct_const_round_shift(out * cospi_16_64); 129 a1 = ROUND_POWER_OF_TWO(out, 6); 130 131 dest_stride8 = dest_stride * 8; 132 if (a1 >= 0) { // diff_positive_32_32 133 a1 = a1 < 0 ? 0 : a1 > 255 ? 255 : a1; 134 q0u8 = vdupq_n_u8(a1); 135 for (i = 0; i < 2; i++, dest += 16) { // diff_positive_32_32_loop 136 d = dest; 137 for (j = 0; j < 4; j++) { 138 LD_16x8(d, dest_stride, &q8u8, &q9u8, &q10u8, &q11u8, 139 &q12u8, &q13u8, &q14u8, &q15u8); 140 ADD_DIFF_16x8(q0u8, &q8u8, &q9u8, &q10u8, &q11u8, 141 &q12u8, &q13u8, &q14u8, &q15u8); 142 ST_16x8(d, dest_stride, &q8u8, &q9u8, &q10u8, &q11u8, 143 &q12u8, &q13u8, &q14u8, &q15u8); 144 d += dest_stride8; 145 } 146 } 147 } else { // diff_negative_32_32 148 a1 = -a1; 149 a1 = a1 < 0 ? 0 : a1 > 255 ? 255 : a1; 150 q0u8 = vdupq_n_u8(a1); 151 for (i = 0; i < 2; i++, dest += 16) { // diff_negative_32_32_loop 152 d = dest; 153 for (j = 0; j < 4; j++) { 154 LD_16x8(d, dest_stride, &q8u8, &q9u8, &q10u8, &q11u8, 155 &q12u8, &q13u8, &q14u8, &q15u8); 156 SUB_DIFF_16x8(q0u8, &q8u8, &q9u8, &q10u8, &q11u8, 157 &q12u8, &q13u8, &q14u8, &q15u8); 158 ST_16x8(d, dest_stride, &q8u8, &q9u8, &q10u8, &q11u8, 159 &q12u8, &q13u8, &q14u8, &q15u8); 160 d += dest_stride8; 161 } 162 } 163 } 164 return; 165} 166