| @@ -160,3 +160,42 @@ void vpx_hadamard_8x8_neon(const int16_t *src_diff, int src_stride, · 159 unmodified lines |
| 160 | 160 | vst1q_s16(coeff + 48, a6); |
| 161 | 161 | vst1q_s16(coeff + 56, a7); |
| 162 | 162 | } |
| 163 | + |
| 164 | +void vpx_hadamard_16x16_neon(const int16_t *src_diff, int src_stride, |
| 165 | + int16_t *coeff) { |
| 166 | + int i; |
| 167 | + |
| 168 | + /* Rearrange 16x16 to 8x32 and remove stride. |
| 169 | + * Top left first. */ |
| 170 | + vpx_hadamard_8x8_neon(src_diff + 0 + 0 * src_stride, src_stride, coeff + 0); |
| 171 | + /* Top right. */ |
| 172 | + vpx_hadamard_8x8_neon(src_diff + 8 + 0 * src_stride, src_stride, coeff + 64); |
| 173 | + /* Bottom left. */ |
| 174 | + vpx_hadamard_8x8_neon(src_diff + 0 + 8 * src_stride, src_stride, coeff + 128); |
| 175 | + /* Bottom right. */ |
| 176 | + vpx_hadamard_8x8_neon(src_diff + 8 + 8 * src_stride, src_stride, coeff + 192); |
| 177 | + |
| 178 | + for (i = 0; i < 64; i += 8) { |
| 179 | + const int16x8_t a0 = vld1q_s16(coeff + 0); |
| 180 | + const int16x8_t a1 = vld1q_s16(coeff + 64); |
| 181 | + const int16x8_t a2 = vld1q_s16(coeff + 128); |
| 182 | + const int16x8_t a3 = vld1q_s16(coeff + 192); |
| 183 | + |
| 184 | + const int16x8_t b0 = vhaddq_s16(a0, a1); |
| 185 | + const int16x8_t b1 = vhsubq_s16(a0, a1); |
| 186 | + const int16x8_t b2 = vhaddq_s16(a2, a3); |
| 187 | + const int16x8_t b3 = vhsubq_s16(a2, a3); |
| 188 | + |
| 189 | + const int16x8_t c0 = vaddq_s16(b0, b2); |
| 190 | + const int16x8_t c1 = vaddq_s16(b1, b3); |
| 191 | + const int16x8_t c2 = vsubq_s16(b0, b2); |
| 192 | + const int16x8_t c3 = vsubq_s16(b1, b3); |
| 193 | + |
| 194 | + vst1q_s16(coeff + 0, c0); |
| 195 | + vst1q_s16(coeff + 64, c1); |
| 196 | + vst1q_s16(coeff + 128, c2); |
| 197 | + vst1q_s16(coeff + 192, c3); |
| 198 | + |
| 199 | + coeff += 8; |
| 200 | + } |
| 201 | +} |