]> granicus.if.org Git - libvpx/blob - vpx_dsp/arm/idct8x8_add_neon.c
vpx_dsp: apply clang-format
[libvpx] / vpx_dsp / arm / idct8x8_add_neon.c
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 #include "vpx_dsp/txfm_common.h"
15
16 static INLINE void TRANSPOSE8X8(int16x8_t *q8s16, int16x8_t *q9s16,
17                                 int16x8_t *q10s16, int16x8_t *q11s16,
18                                 int16x8_t *q12s16, int16x8_t *q13s16,
19                                 int16x8_t *q14s16, int16x8_t *q15s16) {
20   int16x4_t d16s16, d17s16, d18s16, d19s16, d20s16, d21s16, d22s16, d23s16;
21   int16x4_t d24s16, d25s16, d26s16, d27s16, d28s16, d29s16, d30s16, d31s16;
22   int32x4x2_t q0x2s32, q1x2s32, q2x2s32, q3x2s32;
23   int16x8x2_t q0x2s16, q1x2s16, q2x2s16, q3x2s16;
24
25   d16s16 = vget_low_s16(*q8s16);
26   d17s16 = vget_high_s16(*q8s16);
27   d18s16 = vget_low_s16(*q9s16);
28   d19s16 = vget_high_s16(*q9s16);
29   d20s16 = vget_low_s16(*q10s16);
30   d21s16 = vget_high_s16(*q10s16);
31   d22s16 = vget_low_s16(*q11s16);
32   d23s16 = vget_high_s16(*q11s16);
33   d24s16 = vget_low_s16(*q12s16);
34   d25s16 = vget_high_s16(*q12s16);
35   d26s16 = vget_low_s16(*q13s16);
36   d27s16 = vget_high_s16(*q13s16);
37   d28s16 = vget_low_s16(*q14s16);
38   d29s16 = vget_high_s16(*q14s16);
39   d30s16 = vget_low_s16(*q15s16);
40   d31s16 = vget_high_s16(*q15s16);
41
42   *q8s16 = vcombine_s16(d16s16, d24s16);   // vswp d17, d24
43   *q9s16 = vcombine_s16(d18s16, d26s16);   // vswp d19, d26
44   *q10s16 = vcombine_s16(d20s16, d28s16);  // vswp d21, d28
45   *q11s16 = vcombine_s16(d22s16, d30s16);  // vswp d23, d30
46   *q12s16 = vcombine_s16(d17s16, d25s16);
47   *q13s16 = vcombine_s16(d19s16, d27s16);
48   *q14s16 = vcombine_s16(d21s16, d29s16);
49   *q15s16 = vcombine_s16(d23s16, d31s16);
50
51   q0x2s32 =
52       vtrnq_s32(vreinterpretq_s32_s16(*q8s16), vreinterpretq_s32_s16(*q10s16));
53   q1x2s32 =
54       vtrnq_s32(vreinterpretq_s32_s16(*q9s16), vreinterpretq_s32_s16(*q11s16));
55   q2x2s32 =
56       vtrnq_s32(vreinterpretq_s32_s16(*q12s16), vreinterpretq_s32_s16(*q14s16));
57   q3x2s32 =
58       vtrnq_s32(vreinterpretq_s32_s16(*q13s16), vreinterpretq_s32_s16(*q15s16));
59
60   q0x2s16 = vtrnq_s16(vreinterpretq_s16_s32(q0x2s32.val[0]),   // q8
61                       vreinterpretq_s16_s32(q1x2s32.val[0]));  // q9
62   q1x2s16 = vtrnq_s16(vreinterpretq_s16_s32(q0x2s32.val[1]),   // q10
63                       vreinterpretq_s16_s32(q1x2s32.val[1]));  // q11
64   q2x2s16 = vtrnq_s16(vreinterpretq_s16_s32(q2x2s32.val[0]),   // q12
65                       vreinterpretq_s16_s32(q3x2s32.val[0]));  // q13
66   q3x2s16 = vtrnq_s16(vreinterpretq_s16_s32(q2x2s32.val[1]),   // q14
67                       vreinterpretq_s16_s32(q3x2s32.val[1]));  // q15
68
69   *q8s16 = q0x2s16.val[0];
70   *q9s16 = q0x2s16.val[1];
71   *q10s16 = q1x2s16.val[0];
72   *q11s16 = q1x2s16.val[1];
73   *q12s16 = q2x2s16.val[0];
74   *q13s16 = q2x2s16.val[1];
75   *q14s16 = q3x2s16.val[0];
76   *q15s16 = q3x2s16.val[1];
77   return;
78 }
79
80 static INLINE void IDCT8x8_1D(int16x8_t *q8s16, int16x8_t *q9s16,
81                               int16x8_t *q10s16, int16x8_t *q11s16,
82                               int16x8_t *q12s16, int16x8_t *q13s16,
83                               int16x8_t *q14s16, int16x8_t *q15s16) {
84   int16x4_t d0s16, d1s16, d2s16, d3s16;
85   int16x4_t d8s16, d9s16, d10s16, d11s16, d12s16, d13s16, d14s16, d15s16;
86   int16x4_t d16s16, d17s16, d18s16, d19s16, d20s16, d21s16, d22s16, d23s16;
87   int16x4_t d24s16, d25s16, d26s16, d27s16, d28s16, d29s16, d30s16, d31s16;
88   int16x8_t q0s16, q1s16, q2s16, q3s16, q4s16, q5s16, q6s16, q7s16;
89   int32x4_t q2s32, q3s32, q5s32, q6s32, q8s32, q9s32;
90   int32x4_t q10s32, q11s32, q12s32, q13s32, q15s32;
91
92   d0s16 = vdup_n_s16(cospi_28_64);
93   d1s16 = vdup_n_s16(cospi_4_64);
94   d2s16 = vdup_n_s16(cospi_12_64);
95   d3s16 = vdup_n_s16(cospi_20_64);
96
97   d16s16 = vget_low_s16(*q8s16);
98   d17s16 = vget_high_s16(*q8s16);
99   d18s16 = vget_low_s16(*q9s16);
100   d19s16 = vget_high_s16(*q9s16);
101   d20s16 = vget_low_s16(*q10s16);
102   d21s16 = vget_high_s16(*q10s16);
103   d22s16 = vget_low_s16(*q11s16);
104   d23s16 = vget_high_s16(*q11s16);
105   d24s16 = vget_low_s16(*q12s16);
106   d25s16 = vget_high_s16(*q12s16);
107   d26s16 = vget_low_s16(*q13s16);
108   d27s16 = vget_high_s16(*q13s16);
109   d28s16 = vget_low_s16(*q14s16);
110   d29s16 = vget_high_s16(*q14s16);
111   d30s16 = vget_low_s16(*q15s16);
112   d31s16 = vget_high_s16(*q15s16);
113
114   q2s32 = vmull_s16(d18s16, d0s16);
115   q3s32 = vmull_s16(d19s16, d0s16);
116   q5s32 = vmull_s16(d26s16, d2s16);
117   q6s32 = vmull_s16(d27s16, d2s16);
118
119   q2s32 = vmlsl_s16(q2s32, d30s16, d1s16);
120   q3s32 = vmlsl_s16(q3s32, d31s16, d1s16);
121   q5s32 = vmlsl_s16(q5s32, d22s16, d3s16);
122   q6s32 = vmlsl_s16(q6s32, d23s16, d3s16);
123
124   d8s16 = vqrshrn_n_s32(q2s32, 14);
125   d9s16 = vqrshrn_n_s32(q3s32, 14);
126   d10s16 = vqrshrn_n_s32(q5s32, 14);
127   d11s16 = vqrshrn_n_s32(q6s32, 14);
128   q4s16 = vcombine_s16(d8s16, d9s16);
129   q5s16 = vcombine_s16(d10s16, d11s16);
130
131   q2s32 = vmull_s16(d18s16, d1s16);
132   q3s32 = vmull_s16(d19s16, d1s16);
133   q9s32 = vmull_s16(d26s16, d3s16);
134   q13s32 = vmull_s16(d27s16, d3s16);
135
136   q2s32 = vmlal_s16(q2s32, d30s16, d0s16);
137   q3s32 = vmlal_s16(q3s32, d31s16, d0s16);
138   q9s32 = vmlal_s16(q9s32, d22s16, d2s16);
139   q13s32 = vmlal_s16(q13s32, d23s16, d2s16);
140
141   d14s16 = vqrshrn_n_s32(q2s32, 14);
142   d15s16 = vqrshrn_n_s32(q3s32, 14);
143   d12s16 = vqrshrn_n_s32(q9s32, 14);
144   d13s16 = vqrshrn_n_s32(q13s32, 14);
145   q6s16 = vcombine_s16(d12s16, d13s16);
146   q7s16 = vcombine_s16(d14s16, d15s16);
147
148   d0s16 = vdup_n_s16(cospi_16_64);
149
150   q2s32 = vmull_s16(d16s16, d0s16);
151   q3s32 = vmull_s16(d17s16, d0s16);
152   q13s32 = vmull_s16(d16s16, d0s16);
153   q15s32 = vmull_s16(d17s16, d0s16);
154
155   q2s32 = vmlal_s16(q2s32, d24s16, d0s16);
156   q3s32 = vmlal_s16(q3s32, d25s16, d0s16);
157   q13s32 = vmlsl_s16(q13s32, d24s16, d0s16);
158   q15s32 = vmlsl_s16(q15s32, d25s16, d0s16);
159
160   d0s16 = vdup_n_s16(cospi_24_64);
161   d1s16 = vdup_n_s16(cospi_8_64);
162
163   d18s16 = vqrshrn_n_s32(q2s32, 14);
164   d19s16 = vqrshrn_n_s32(q3s32, 14);
165   d22s16 = vqrshrn_n_s32(q13s32, 14);
166   d23s16 = vqrshrn_n_s32(q15s32, 14);
167   *q9s16 = vcombine_s16(d18s16, d19s16);
168   *q11s16 = vcombine_s16(d22s16, d23s16);
169
170   q2s32 = vmull_s16(d20s16, d0s16);
171   q3s32 = vmull_s16(d21s16, d0s16);
172   q8s32 = vmull_s16(d20s16, d1s16);
173   q12s32 = vmull_s16(d21s16, d1s16);
174
175   q2s32 = vmlsl_s16(q2s32, d28s16, d1s16);
176   q3s32 = vmlsl_s16(q3s32, d29s16, d1s16);
177   q8s32 = vmlal_s16(q8s32, d28s16, d0s16);
178   q12s32 = vmlal_s16(q12s32, d29s16, d0s16);
179
180   d26s16 = vqrshrn_n_s32(q2s32, 14);
181   d27s16 = vqrshrn_n_s32(q3s32, 14);
182   d30s16 = vqrshrn_n_s32(q8s32, 14);
183   d31s16 = vqrshrn_n_s32(q12s32, 14);
184   *q13s16 = vcombine_s16(d26s16, d27s16);
185   *q15s16 = vcombine_s16(d30s16, d31s16);
186
187   q0s16 = vaddq_s16(*q9s16, *q15s16);
188   q1s16 = vaddq_s16(*q11s16, *q13s16);
189   q2s16 = vsubq_s16(*q11s16, *q13s16);
190   q3s16 = vsubq_s16(*q9s16, *q15s16);
191
192   *q13s16 = vsubq_s16(q4s16, q5s16);
193   q4s16 = vaddq_s16(q4s16, q5s16);
194   *q14s16 = vsubq_s16(q7s16, q6s16);
195   q7s16 = vaddq_s16(q7s16, q6s16);
196   d26s16 = vget_low_s16(*q13s16);
197   d27s16 = vget_high_s16(*q13s16);
198   d28s16 = vget_low_s16(*q14s16);
199   d29s16 = vget_high_s16(*q14s16);
200
201   d16s16 = vdup_n_s16(cospi_16_64);
202
203   q9s32 = vmull_s16(d28s16, d16s16);
204   q10s32 = vmull_s16(d29s16, d16s16);
205   q11s32 = vmull_s16(d28s16, d16s16);
206   q12s32 = vmull_s16(d29s16, d16s16);
207
208   q9s32 = vmlsl_s16(q9s32, d26s16, d16s16);
209   q10s32 = vmlsl_s16(q10s32, d27s16, d16s16);
210   q11s32 = vmlal_s16(q11s32, d26s16, d16s16);
211   q12s32 = vmlal_s16(q12s32, d27s16, d16s16);
212
213   d10s16 = vqrshrn_n_s32(q9s32, 14);
214   d11s16 = vqrshrn_n_s32(q10s32, 14);
215   d12s16 = vqrshrn_n_s32(q11s32, 14);
216   d13s16 = vqrshrn_n_s32(q12s32, 14);
217   q5s16 = vcombine_s16(d10s16, d11s16);
218   q6s16 = vcombine_s16(d12s16, d13s16);
219
220   *q8s16 = vaddq_s16(q0s16, q7s16);
221   *q9s16 = vaddq_s16(q1s16, q6s16);
222   *q10s16 = vaddq_s16(q2s16, q5s16);
223   *q11s16 = vaddq_s16(q3s16, q4s16);
224   *q12s16 = vsubq_s16(q3s16, q4s16);
225   *q13s16 = vsubq_s16(q2s16, q5s16);
226   *q14s16 = vsubq_s16(q1s16, q6s16);
227   *q15s16 = vsubq_s16(q0s16, q7s16);
228   return;
229 }
230
231 void vpx_idct8x8_64_add_neon(int16_t *input, uint8_t *dest, int dest_stride) {
232   uint8_t *d1, *d2;
233   uint8x8_t d0u8, d1u8, d2u8, d3u8;
234   uint64x1_t d0u64, d1u64, d2u64, d3u64;
235   int16x8_t q8s16, q9s16, q10s16, q11s16, q12s16, q13s16, q14s16, q15s16;
236   uint16x8_t q8u16, q9u16, q10u16, q11u16;
237
238   q8s16 = vld1q_s16(input);
239   q9s16 = vld1q_s16(input + 8);
240   q10s16 = vld1q_s16(input + 16);
241   q11s16 = vld1q_s16(input + 24);
242   q12s16 = vld1q_s16(input + 32);
243   q13s16 = vld1q_s16(input + 40);
244   q14s16 = vld1q_s16(input + 48);
245   q15s16 = vld1q_s16(input + 56);
246
247   TRANSPOSE8X8(&q8s16, &q9s16, &q10s16, &q11s16, &q12s16, &q13s16, &q14s16,
248                &q15s16);
249
250   IDCT8x8_1D(&q8s16, &q9s16, &q10s16, &q11s16, &q12s16, &q13s16, &q14s16,
251              &q15s16);
252
253   TRANSPOSE8X8(&q8s16, &q9s16, &q10s16, &q11s16, &q12s16, &q13s16, &q14s16,
254                &q15s16);
255
256   IDCT8x8_1D(&q8s16, &q9s16, &q10s16, &q11s16, &q12s16, &q13s16, &q14s16,
257              &q15s16);
258
259   q8s16 = vrshrq_n_s16(q8s16, 5);
260   q9s16 = vrshrq_n_s16(q9s16, 5);
261   q10s16 = vrshrq_n_s16(q10s16, 5);
262   q11s16 = vrshrq_n_s16(q11s16, 5);
263   q12s16 = vrshrq_n_s16(q12s16, 5);
264   q13s16 = vrshrq_n_s16(q13s16, 5);
265   q14s16 = vrshrq_n_s16(q14s16, 5);
266   q15s16 = vrshrq_n_s16(q15s16, 5);
267
268   d1 = d2 = dest;
269
270   d0u64 = vld1_u64((uint64_t *)d1);
271   d1 += dest_stride;
272   d1u64 = vld1_u64((uint64_t *)d1);
273   d1 += dest_stride;
274   d2u64 = vld1_u64((uint64_t *)d1);
275   d1 += dest_stride;
276   d3u64 = vld1_u64((uint64_t *)d1);
277   d1 += dest_stride;
278
279   q8u16 = vaddw_u8(vreinterpretq_u16_s16(q8s16), vreinterpret_u8_u64(d0u64));
280   q9u16 = vaddw_u8(vreinterpretq_u16_s16(q9s16), vreinterpret_u8_u64(d1u64));
281   q10u16 = vaddw_u8(vreinterpretq_u16_s16(q10s16), vreinterpret_u8_u64(d2u64));
282   q11u16 = vaddw_u8(vreinterpretq_u16_s16(q11s16), vreinterpret_u8_u64(d3u64));
283
284   d0u8 = vqmovun_s16(vreinterpretq_s16_u16(q8u16));
285   d1u8 = vqmovun_s16(vreinterpretq_s16_u16(q9u16));
286   d2u8 = vqmovun_s16(vreinterpretq_s16_u16(q10u16));
287   d3u8 = vqmovun_s16(vreinterpretq_s16_u16(q11u16));
288
289   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d0u8));
290   d2 += dest_stride;
291   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d1u8));
292   d2 += dest_stride;
293   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d2u8));
294   d2 += dest_stride;
295   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d3u8));
296   d2 += dest_stride;
297
298   q8s16 = q12s16;
299   q9s16 = q13s16;
300   q10s16 = q14s16;
301   q11s16 = q15s16;
302
303   d0u64 = vld1_u64((uint64_t *)d1);
304   d1 += dest_stride;
305   d1u64 = vld1_u64((uint64_t *)d1);
306   d1 += dest_stride;
307   d2u64 = vld1_u64((uint64_t *)d1);
308   d1 += dest_stride;
309   d3u64 = vld1_u64((uint64_t *)d1);
310   d1 += dest_stride;
311
312   q8u16 = vaddw_u8(vreinterpretq_u16_s16(q8s16), vreinterpret_u8_u64(d0u64));
313   q9u16 = vaddw_u8(vreinterpretq_u16_s16(q9s16), vreinterpret_u8_u64(d1u64));
314   q10u16 = vaddw_u8(vreinterpretq_u16_s16(q10s16), vreinterpret_u8_u64(d2u64));
315   q11u16 = vaddw_u8(vreinterpretq_u16_s16(q11s16), vreinterpret_u8_u64(d3u64));
316
317   d0u8 = vqmovun_s16(vreinterpretq_s16_u16(q8u16));
318   d1u8 = vqmovun_s16(vreinterpretq_s16_u16(q9u16));
319   d2u8 = vqmovun_s16(vreinterpretq_s16_u16(q10u16));
320   d3u8 = vqmovun_s16(vreinterpretq_s16_u16(q11u16));
321
322   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d0u8));
323   d2 += dest_stride;
324   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d1u8));
325   d2 += dest_stride;
326   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d2u8));
327   d2 += dest_stride;
328   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d3u8));
329   d2 += dest_stride;
330   return;
331 }
332
333 void vpx_idct8x8_12_add_neon(int16_t *input, uint8_t *dest, int dest_stride) {
334   uint8_t *d1, *d2;
335   uint8x8_t d0u8, d1u8, d2u8, d3u8;
336   int16x4_t d10s16, d11s16, d12s16, d13s16, d16s16;
337   int16x4_t d26s16, d27s16, d28s16, d29s16;
338   uint64x1_t d0u64, d1u64, d2u64, d3u64;
339   int16x8_t q0s16, q1s16, q2s16, q3s16, q4s16, q5s16, q6s16, q7s16;
340   int16x8_t q8s16, q9s16, q10s16, q11s16, q12s16, q13s16, q14s16, q15s16;
341   uint16x8_t q8u16, q9u16, q10u16, q11u16;
342   int32x4_t q9s32, q10s32, q11s32, q12s32;
343
344   q8s16 = vld1q_s16(input);
345   q9s16 = vld1q_s16(input + 8);
346   q10s16 = vld1q_s16(input + 16);
347   q11s16 = vld1q_s16(input + 24);
348   q12s16 = vld1q_s16(input + 32);
349   q13s16 = vld1q_s16(input + 40);
350   q14s16 = vld1q_s16(input + 48);
351   q15s16 = vld1q_s16(input + 56);
352
353   TRANSPOSE8X8(&q8s16, &q9s16, &q10s16, &q11s16, &q12s16, &q13s16, &q14s16,
354                &q15s16);
355
356   // First transform rows
357   // stage 1
358   q0s16 = vdupq_n_s16(cospi_28_64 * 2);
359   q1s16 = vdupq_n_s16(cospi_4_64 * 2);
360
361   q4s16 = vqrdmulhq_s16(q9s16, q0s16);
362
363   q0s16 = vdupq_n_s16(-cospi_20_64 * 2);
364
365   q7s16 = vqrdmulhq_s16(q9s16, q1s16);
366
367   q1s16 = vdupq_n_s16(cospi_12_64 * 2);
368
369   q5s16 = vqrdmulhq_s16(q11s16, q0s16);
370
371   q0s16 = vdupq_n_s16(cospi_16_64 * 2);
372
373   q6s16 = vqrdmulhq_s16(q11s16, q1s16);
374
375   // stage 2 & stage 3 - even half
376   q1s16 = vdupq_n_s16(cospi_24_64 * 2);
377
378   q9s16 = vqrdmulhq_s16(q8s16, q0s16);
379
380   q0s16 = vdupq_n_s16(cospi_8_64 * 2);
381
382   q13s16 = vqrdmulhq_s16(q10s16, q1s16);
383
384   q15s16 = vqrdmulhq_s16(q10s16, q0s16);
385
386   // stage 3 -odd half
387   q0s16 = vaddq_s16(q9s16, q15s16);
388   q1s16 = vaddq_s16(q9s16, q13s16);
389   q2s16 = vsubq_s16(q9s16, q13s16);
390   q3s16 = vsubq_s16(q9s16, q15s16);
391
392   // stage 2 - odd half
393   q13s16 = vsubq_s16(q4s16, q5s16);
394   q4s16 = vaddq_s16(q4s16, q5s16);
395   q14s16 = vsubq_s16(q7s16, q6s16);
396   q7s16 = vaddq_s16(q7s16, q6s16);
397   d26s16 = vget_low_s16(q13s16);
398   d27s16 = vget_high_s16(q13s16);
399   d28s16 = vget_low_s16(q14s16);
400   d29s16 = vget_high_s16(q14s16);
401
402   d16s16 = vdup_n_s16(cospi_16_64);
403   q9s32 = vmull_s16(d28s16, d16s16);
404   q10s32 = vmull_s16(d29s16, d16s16);
405   q11s32 = vmull_s16(d28s16, d16s16);
406   q12s32 = vmull_s16(d29s16, d16s16);
407
408   q9s32 = vmlsl_s16(q9s32, d26s16, d16s16);
409   q10s32 = vmlsl_s16(q10s32, d27s16, d16s16);
410   q11s32 = vmlal_s16(q11s32, d26s16, d16s16);
411   q12s32 = vmlal_s16(q12s32, d27s16, d16s16);
412
413   d10s16 = vqrshrn_n_s32(q9s32, 14);
414   d11s16 = vqrshrn_n_s32(q10s32, 14);
415   d12s16 = vqrshrn_n_s32(q11s32, 14);
416   d13s16 = vqrshrn_n_s32(q12s32, 14);
417   q5s16 = vcombine_s16(d10s16, d11s16);
418   q6s16 = vcombine_s16(d12s16, d13s16);
419
420   // stage 4
421   q8s16 = vaddq_s16(q0s16, q7s16);
422   q9s16 = vaddq_s16(q1s16, q6s16);
423   q10s16 = vaddq_s16(q2s16, q5s16);
424   q11s16 = vaddq_s16(q3s16, q4s16);
425   q12s16 = vsubq_s16(q3s16, q4s16);
426   q13s16 = vsubq_s16(q2s16, q5s16);
427   q14s16 = vsubq_s16(q1s16, q6s16);
428   q15s16 = vsubq_s16(q0s16, q7s16);
429
430   TRANSPOSE8X8(&q8s16, &q9s16, &q10s16, &q11s16, &q12s16, &q13s16, &q14s16,
431                &q15s16);
432
433   IDCT8x8_1D(&q8s16, &q9s16, &q10s16, &q11s16, &q12s16, &q13s16, &q14s16,
434              &q15s16);
435
436   q8s16 = vrshrq_n_s16(q8s16, 5);
437   q9s16 = vrshrq_n_s16(q9s16, 5);
438   q10s16 = vrshrq_n_s16(q10s16, 5);
439   q11s16 = vrshrq_n_s16(q11s16, 5);
440   q12s16 = vrshrq_n_s16(q12s16, 5);
441   q13s16 = vrshrq_n_s16(q13s16, 5);
442   q14s16 = vrshrq_n_s16(q14s16, 5);
443   q15s16 = vrshrq_n_s16(q15s16, 5);
444
445   d1 = d2 = dest;
446
447   d0u64 = vld1_u64((uint64_t *)d1);
448   d1 += dest_stride;
449   d1u64 = vld1_u64((uint64_t *)d1);
450   d1 += dest_stride;
451   d2u64 = vld1_u64((uint64_t *)d1);
452   d1 += dest_stride;
453   d3u64 = vld1_u64((uint64_t *)d1);
454   d1 += dest_stride;
455
456   q8u16 = vaddw_u8(vreinterpretq_u16_s16(q8s16), vreinterpret_u8_u64(d0u64));
457   q9u16 = vaddw_u8(vreinterpretq_u16_s16(q9s16), vreinterpret_u8_u64(d1u64));
458   q10u16 = vaddw_u8(vreinterpretq_u16_s16(q10s16), vreinterpret_u8_u64(d2u64));
459   q11u16 = vaddw_u8(vreinterpretq_u16_s16(q11s16), vreinterpret_u8_u64(d3u64));
460
461   d0u8 = vqmovun_s16(vreinterpretq_s16_u16(q8u16));
462   d1u8 = vqmovun_s16(vreinterpretq_s16_u16(q9u16));
463   d2u8 = vqmovun_s16(vreinterpretq_s16_u16(q10u16));
464   d3u8 = vqmovun_s16(vreinterpretq_s16_u16(q11u16));
465
466   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d0u8));
467   d2 += dest_stride;
468   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d1u8));
469   d2 += dest_stride;
470   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d2u8));
471   d2 += dest_stride;
472   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d3u8));
473   d2 += dest_stride;
474
475   q8s16 = q12s16;
476   q9s16 = q13s16;
477   q10s16 = q14s16;
478   q11s16 = q15s16;
479
480   d0u64 = vld1_u64((uint64_t *)d1);
481   d1 += dest_stride;
482   d1u64 = vld1_u64((uint64_t *)d1);
483   d1 += dest_stride;
484   d2u64 = vld1_u64((uint64_t *)d1);
485   d1 += dest_stride;
486   d3u64 = vld1_u64((uint64_t *)d1);
487   d1 += dest_stride;
488
489   q8u16 = vaddw_u8(vreinterpretq_u16_s16(q8s16), vreinterpret_u8_u64(d0u64));
490   q9u16 = vaddw_u8(vreinterpretq_u16_s16(q9s16), vreinterpret_u8_u64(d1u64));
491   q10u16 = vaddw_u8(vreinterpretq_u16_s16(q10s16), vreinterpret_u8_u64(d2u64));
492   q11u16 = vaddw_u8(vreinterpretq_u16_s16(q11s16), vreinterpret_u8_u64(d3u64));
493
494   d0u8 = vqmovun_s16(vreinterpretq_s16_u16(q8u16));
495   d1u8 = vqmovun_s16(vreinterpretq_s16_u16(q9u16));
496   d2u8 = vqmovun_s16(vreinterpretq_s16_u16(q10u16));
497   d3u8 = vqmovun_s16(vreinterpretq_s16_u16(q11u16));
498
499   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d0u8));
500   d2 += dest_stride;
501   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d1u8));
502   d2 += dest_stride;
503   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d2u8));
504   d2 += dest_stride;
505   vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d3u8));
506   d2 += dest_stride;
507   return;
508 }