Merge commit '81a4cb8e58636d4efd200c2b4fec786a7e948d8b'
[ffmpeg.git] / libavcodec / arm / hevcdsp_idct_neon.S
1 /*
2  * ARM NEON optimised IDCT functions for HEVC decoding
3  * Copyright (c) 2014 Seppo Tomperi <seppo.tomperi@vtt.fi>
4  * Copyright (c) 2017 Alexandra Hájková
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 #include "libavutil/arm/asm.S"
24
25 const trans, align=4
26         .short 64, 83, 64, 36
27         .short 89, 75, 50, 18
28         .short 90, 87, 80, 70
29         .short 57, 43, 25, 9
30 endconst
31
32 function ff_hevc_add_residual_4x4_8_neon, export=1
33         vld1.16         {q0-q1}, [r1, :128]
34         vld1.32         d4[0], [r0, :32], r2
35         vld1.32         d4[1], [r0, :32], r2
36         vld1.32         d5[0], [r0, :32], r2
37         vld1.32         d5[1], [r0, :32], r2
38         sub             r0, r0, r2, lsl #2
39         vmovl.u8        q8, d4
40         vmovl.u8        q9, d5
41         vqadd.s16       q0, q0, q8
42         vqadd.s16       q1, q1, q9
43         vqmovun.s16     d0, q0
44         vqmovun.s16     d1, q1
45         vst1.32         d0[0], [r0, :32], r2
46         vst1.32         d0[1], [r0, :32], r2
47         vst1.32         d1[0], [r0, :32], r2
48         vst1.32         d1[1], [r0, :32], r2
49         bx              lr
50 endfunc
51
52 function ff_hevc_add_residual_8x8_8_neon, export=1
53         add             r12, r0, r2
54         add             r2,  r2, r2
55         mov             r3,   #8
56 1:      subs            r3,   #2
57         vld1.8          {d16},   [r0,  :64]
58         vld1.8          {d17},   [r12, :64]
59         vmovl.u8        q9,   d16
60         vld1.16         {q0-q1}, [r1,  :128]!
61         vmovl.u8        q8,   d17
62         vqadd.s16       q0,   q9
63         vqadd.s16       q1,   q8
64         vqmovun.s16     d0,   q0
65         vqmovun.s16     d1,   q1
66         vst1.8          d0,   [r0,  :64], r2
67         vst1.8          d1,   [r12, :64], r2
68         bne             1b
69         bx              lr
70 endfunc
71
72 function ff_hevc_add_residual_16x16_8_neon, export=1
73         mov             r3,  #16
74         add             r12, r0, r2
75         add             r2,  r2, r2
76 1:      subs            r3,  #2
77         vld1.8          {q8},     [r0, :128]
78         vld1.16         {q0, q1}, [r1, :128]!
79         vld1.8          {q11},    [r12, :128]
80         vld1.16         {q2, q3}, [r1, :128]!
81         vmovl.u8        q9,  d16
82         vmovl.u8        q10, d17
83         vmovl.u8        q12, d22
84         vmovl.u8        q13, d23
85         vqadd.s16       q0,  q9
86         vqadd.s16       q1,  q10
87         vqadd.s16       q2,  q12
88         vqadd.s16       q3,  q13
89         vqmovun.s16     d0,  q0
90         vqmovun.s16     d1,  q1
91         vqmovun.s16     d2,  q2
92         vqmovun.s16     d3,  q3
93         vst1.8          {q0},     [r0, :128], r2
94         vst1.8          {q1},     [r12, :128], r2
95         bne             1b
96         bx              lr
97 endfunc
98
99 function ff_hevc_add_residual_32x32_8_neon, export=1
100         vpush           {q4-q7}
101         add             r12, r0, r2
102         add             r2,  r2, r2
103         mov             r3,  #32
104 1:      subs            r3,  #2
105         vld1.8          {q12, q13}, [r0,  :128]
106         vmovl.u8        q8,  d24
107         vmovl.u8        q9,  d25
108         vld1.8          {q14, q15}, [r12, :128]
109         vmovl.u8        q10, d26
110         vmovl.u8        q11, d27
111         vmovl.u8        q12, d28
112         vldm            r1!, {q0-q7}
113         vmovl.u8        q13, d29
114         vmovl.u8        q14, d30
115         vmovl.u8        q15, d31
116         vqadd.s16       q0,  q8
117         vqadd.s16       q1,  q9
118         vqadd.s16       q2,  q10
119         vqadd.s16       q3,  q11
120         vqadd.s16       q4,  q12
121         vqadd.s16       q5,  q13
122         vqadd.s16       q6,  q14
123         vqadd.s16       q7,  q15
124         vqmovun.s16     d0,  q0
125         vqmovun.s16     d1,  q1
126         vqmovun.s16     d2,  q2
127         vqmovun.s16     d3,  q3
128         vqmovun.s16     d4,  q4
129         vqmovun.s16     d5,  q5
130         vst1.8          {q0, q1}, [r0, :128], r2
131         vqmovun.s16     d6,  q6
132         vqmovun.s16     d7,  q7
133         vst1.8          {q2, q3}, [r12, :128], r2
134         bne             1b
135         vpop            {q4-q7}
136         bx              lr
137 endfunc
138
139 /* uses registers q2 - q9 for temp values */
140 /* TODO: reorder */
141 .macro tr4_luma_shift r0, r1, r2, r3, shift
142         vaddl.s16   q5, \r0, \r2    // c0 = src0 + src2
143         vaddl.s16   q2, \r2, \r3    // c1 = src2 + src3
144         vsubl.s16   q4, \r0, \r3    // c2 = src0 - src3
145         vmull.s16   q6, \r1, d0[0]  // c3 = 74 * src1
146
147         vaddl.s16   q7, \r0, \r3    // src0 + src3
148         vsubw.s16   q7, q7, \r2     // src0 - src2 + src3
149         vmul.s32    q7, q7, d0[0]   // dst2 = 74 * (src0 - src2 + src3)
150
151         vmul.s32    q8, q5, d0[1]   // 29 * c0
152         vmul.s32    q9, q2, d1[0]   // 55 * c1
153         vadd.s32    q8, q9          // 29 * c0 + 55 * c1
154         vadd.s32    q8, q6          // dst0 = 29 * c0 + 55 * c1 + c3
155
156         vmul.s32    q2, q2, d0[1]   // 29 * c1
157         vmul.s32    q9, q4, d1[0]   // 55 * c2
158         vsub.s32    q9, q2          // 55 * c2 - 29 * c1
159         vadd.s32    q9, q6          // dst1 = 55 * c2 - 29 * c1 + c3
160
161         vmul.s32    q5, q5, d1[0]   // 55 * c0
162         vmul.s32    q4, q4, d0[1]   // 29 * c2
163         vadd.s32    q5, q4          // 55 * c0 + 29 * c2
164         vsub.s32    q5, q6          // dst3 = 55 * c0 + 29 * c2 - c3
165
166         vqrshrn.s32   \r0, q8, \shift
167         vqrshrn.s32   \r1, q9, \shift
168         vqrshrn.s32   \r2, q7, \shift
169         vqrshrn.s32   \r3, q5, \shift
170 .endm
171
172 function ff_hevc_transform_luma_4x4_neon_8, export=1
173         vpush       {d8-d15}
174         vld1.16     {q14, q15}, [r0]  // coeffs
175         ldr         r3, =0x4a  // 74
176         vmov.32     d0[0], r3
177         ldr         r3, =0x1d  // 29
178         vmov.32     d0[1], r3
179         ldr         r3, =0x37  // 55
180         vmov.32     d1[0], r3
181
182         tr4_luma_shift d28, d29, d30, d31, #7
183
184         vtrn.16     d28, d29
185         vtrn.16     d30, d31
186         vtrn.32     q14, q15
187
188         tr4_luma_shift d28, d29, d30, d31, #12
189
190         vtrn.16     d28, d29
191         vtrn.16     d30, d31
192         vtrn.32     q14, q15
193         vst1.16     {q14, q15}, [r0]
194         vpop        {d8-d15}
195         bx lr
196 endfunc
197
198 .macro idct_4x4_dc bitdepth
199 function ff_hevc_idct_4x4_dc_\bitdepth\()_neon, export=1
200         ldrsh           r1, [r0]
201         ldr             r2, =(1 << (13 - \bitdepth))
202         add             r1, #1
203         asr             r1, #1
204         add             r1, r2
205         asr             r1, #(14 - \bitdepth)
206         vdup.16         q0, r1
207         vdup.16         q1, r1
208         vst1.16         {q0, q1}, [r0, :128]
209         bx              lr
210 endfunc
211 .endm
212
213 .macro idct_8x8_dc bitdepth
214 function ff_hevc_idct_8x8_dc_\bitdepth\()_neon, export=1
215         ldrsh           r1, [r0]
216         ldr             r2, =(1 << (13 - \bitdepth))
217         add             r1, #1
218         asr             r1, #1
219         add             r1, r2
220         asr             r1, #(14 - \bitdepth)
221         vdup.16         q8, r1
222         vdup.16         q9, r1
223         vmov.16         q10, q8
224         vmov.16         q11, q8
225         vmov.16         q12, q8
226         vmov.16         q13, q8
227         vmov.16         q14, q8
228         vmov.16         q15, q8
229         vstm            r0, {q8-q15}
230         bx              lr
231 endfunc
232 .endm
233
234 .macro idct_16x16_dc bitdepth
235 function ff_hevc_idct_16x16_dc_\bitdepth\()_neon, export=1
236         ldrsh           r1, [r0]
237         ldr             r2, =(1 << (13 - \bitdepth))
238         add             r1, #1
239         asr             r1, #1
240         add             r1, r2
241         asr             r1, #(14 - \bitdepth)
242         vdup.16         q8, r1
243         vdup.16         q9, r1
244         vmov.16         q10, q8
245         vmov.16         q11, q8
246         vmov.16         q12, q8
247         vmov.16         q13, q8
248         vmov.16         q14, q8
249         vmov.16         q15, q8
250         vstm            r0!, {q8-q15}
251         vstm            r0!, {q8-q15}
252         vstm            r0!, {q8-q15}
253         vstm            r0, {q8-q15}
254         bx              lr
255 endfunc
256 .endm
257
258 .macro idct_32x32_dc bitdepth
259 function ff_hevc_idct_32x32_dc_\bitdepth\()_neon, export=1
260         ldrsh           r1, [r0]
261         ldr             r2, =(1 << (13 - \bitdepth))
262         add             r1, #1
263         asr             r1, #1
264         add             r1, r2
265         asr             r1, #(14 - \bitdepth)
266         mov             r3, #16
267         vdup.16         q8, r1
268         vdup.16         q9, r1
269         vmov.16         q10, q8
270         vmov.16         q11, q8
271         vmov.16         q12, q8
272         vmov.16         q13, q8
273         vmov.16         q14, q8
274         vmov.16         q15, q8
275 1:      subs            r3, #1
276         vstm            r0!, {q8-q15}
277         bne             1b
278         bx              lr
279 endfunc
280 .endm
281
282 .macro sum_sub out, in, c, op
283   .ifc \op, +
284         vmlal.s16       \out, \in, \c
285   .else
286         vmlsl.s16       \out, \in, \c
287   .endif
288 .endm
289
290 .macro tr_4x4 in0, in1, in2, in3, out0, out1, out2, out3, shift, tmp0, tmp1, tmp2, tmp3, tmp4
291          vshll.s16      \tmp0, \in0, #6
292          vmull.s16      \tmp2, \in1, d4[1]
293          vmov           \tmp1, \tmp0
294          vmull.s16      \tmp3, \in1, d4[3]
295          vmlal.s16      \tmp0, \in2, d4[0] @e0
296          vmlsl.s16      \tmp1, \in2, d4[0] @e1
297          vmlal.s16      \tmp2, \in3, d4[3] @o0
298          vmlsl.s16      \tmp3, \in3, d4[1] @o1
299
300          vadd.s32       \tmp4, \tmp0, \tmp2
301          vsub.s32       \tmp0, \tmp0, \tmp2
302          vadd.s32       \tmp2, \tmp1, \tmp3
303          vsub.s32       \tmp1, \tmp1, \tmp3
304          vqrshrn.s32    \out0, \tmp4, #\shift
305          vqrshrn.s32    \out3, \tmp0, #\shift
306          vqrshrn.s32    \out1, \tmp2, #\shift
307          vqrshrn.s32    \out2, \tmp1, #\shift
308 .endm
309
310 .macro tr_4x4_8 in0, in1, in2, in3, out0, out1, out2, out3, tmp0, tmp1, tmp2, tmp3
311          vshll.s16      \tmp0, \in0, #6
312          vld1.s16       {\in0}, [r1, :64]!
313          vmov           \tmp1, \tmp0
314          vmull.s16      \tmp2, \in1, \in0[1]
315          vmull.s16      \tmp3, \in1, \in0[3]
316          vmlal.s16      \tmp0, \in2, \in0[0] @e0
317          vmlsl.s16      \tmp1, \in2, \in0[0] @e1
318          vmlal.s16      \tmp2, \in3, \in0[3] @o0
319          vmlsl.s16      \tmp3, \in3, \in0[1] @o1
320
321          vld1.s16       {\in0}, [r1, :64]
322
323          vadd.s32       \out0, \tmp0, \tmp2
324          vadd.s32       \out1, \tmp1, \tmp3
325          vsub.s32       \out2, \tmp1, \tmp3
326          vsub.s32       \out3, \tmp0, \tmp2
327
328          sub            r1,  r1,  #8
329 .endm
330
331 @ Do a 4x4 transpose, using q registers for the subtransposes that don't
332 @ need to address the indiviudal d registers.
333 @ r0,r1 == rq0, r2,r3 == rq1
334 .macro transpose_4x4 rq0, rq1, r0, r1, r2, r3
335         vtrn.32         \rq0, \rq1
336         vtrn.16         \r0,  \r1
337         vtrn.16         \r2,  \r3
338 .endm
339
340 .macro idct_4x4 bitdepth
341 function ff_hevc_idct_4x4_\bitdepth\()_neon, export=1
342 @r0 - coeffs
343         vld1.s16        {q0-q1}, [r0, :128]
344
345         movrel          r1, trans
346         vld1.s16        {d4}, [r1, :64]
347
348         tr_4x4          d0, d1, d2, d3, d16, d17, d18, d19, 7, q10, q11, q12, q13, q0
349         transpose_4x4   q8, q9, d16, d17, d18, d19
350
351         tr_4x4          d16, d17, d18, d19, d0, d1, d2, d3, 20 - \bitdepth, q10, q11, q12, q13, q0
352         transpose_4x4   q0, q1, d0, d1, d2, d3
353         vst1.s16        {d0-d3}, [r0, :128]
354         bx lr
355 endfunc
356 .endm
357
358 .macro transpose8_4x4 r0, r1, r2, r3
359         vtrn.16         \r0,  \r1
360         vtrn.16         \r2,  \r3
361         vtrn.32         \r0,  \r2
362         vtrn.32         \r1,  \r3
363 .endm
364
365 .macro transpose_8x8 r0, r1, r2, r3, r4, r5, r6, r7, l0, l1, l2, l3, l4, l5, l6, l7
366         transpose8_4x4  \r0, \r1, \r2, \r3
367         transpose8_4x4  \r4, \r5, \r6, \r7
368
369         transpose8_4x4  \l0, \l1, \l2, \l3
370         transpose8_4x4  \l4, \l5, \l6, \l7
371 .endm
372
373 .macro tr_8x4 shift, in0, in1, in2, in3, in4, in5, in6, in7
374         tr_4x4_8        \in0, \in2, \in4, \in6, q8, q9, q10, q11, q12, q13, q14, q15
375
376         vmull.s16       q14, \in1, \in0[2]
377         vmull.s16       q12, \in1, \in0[0]
378         vmull.s16       q13, \in1, \in0[1]
379         sum_sub         q14, \in3, \in0[0], -
380         sum_sub         q12, \in3, \in0[1], +
381         sum_sub         q13, \in3, \in0[3], -
382
383         sum_sub         q14, \in5, \in0[3], +
384         sum_sub         q12, \in5, \in0[2], +
385         sum_sub         q13, \in5, \in0[0], -
386
387         sum_sub         q14, \in7, \in0[1], +
388         sum_sub         q12, \in7, \in0[3], +
389         sum_sub         q13, \in7, \in0[2], -
390
391         vadd.s32        q15, q10, q14
392         vsub.s32        q10, q10, q14
393         vqrshrn.s32     \in2, q15, \shift
394
395         vmull.s16       q15, \in1, \in0[3]
396         sum_sub         q15, \in3, \in0[2], -
397         sum_sub         q15, \in5, \in0[1], +
398         sum_sub         q15, \in7, \in0[0], -
399
400         vqrshrn.s32     \in5, q10,  \shift
401
402         vadd.s32        q10, q8, q12
403         vsub.s32        q8,  q8, q12
404         vadd.s32        q12, q9, q13
405         vsub.s32        q9,  q9, q13
406         vadd.s32        q14, q11, q15
407         vsub.s32        q11, q11, q15
408
409         vqrshrn.s32     \in0, q10, \shift
410         vqrshrn.s32     \in7, q8,  \shift
411         vqrshrn.s32     \in1, q12, \shift
412         vqrshrn.s32     \in6, q9,  \shift
413         vqrshrn.s32     \in3, q14, \shift
414         vqrshrn.s32     \in4, q11, \shift
415 .endm
416
417 .macro idct_8x8 bitdepth
418 function ff_hevc_idct_8x8_\bitdepth\()_neon, export=1
419 @r0 - coeffs
420         vpush           {q4-q7}
421
422         mov             r1,  r0
423         mov             r2,  #64
424         add             r3,  r0,  #32
425         vld1.s16        {q0-q1}, [r1,:128], r2
426         vld1.s16        {q2-q3}, [r3,:128], r2
427         vld1.s16        {q4-q5}, [r1,:128], r2
428         vld1.s16        {q6-q7}, [r3,:128], r2
429
430         movrel          r1, trans
431
432         tr_8x4          7, d0, d2, d4, d6, d8, d10, d12, d14
433         tr_8x4          7, d1, d3, d5, d7, d9, d11, d13, d15
434
435         @ Transpose each 4x4 block, and swap how d4-d7 and d8-d11 are used.
436         @ Layout before:
437         @ d0  d1
438         @ d2  d3
439         @ d4  d5
440         @ d6  d7
441         @ d8  d9
442         @ d10 d11
443         @ d12 d13
444         @ d14 d15
445         transpose_8x8   d0, d2, d4, d6, d8, d10, d12, d14, d1, d3, d5, d7, d9, d11, d13, d15
446         @ Now the layout is:
447         @ d0  d8
448         @ d2  d10
449         @ d4  d12
450         @ d6  d14
451         @ d1  d9
452         @ d3  d11
453         @ d5  d13
454         @ d7  d15
455
456         tr_8x4          20 - \bitdepth, d0, d2, d4, d6, d1, d3, d5, d7
457         vswp            d0, d8
458         tr_8x4          20 - \bitdepth, d0, d10, d12, d14, d9, d11, d13, d15
459         vswp            d0, d8
460
461         transpose_8x8   d0, d2, d4, d6, d8, d10, d12, d14, d1, d3, d5, d7, d9, d11, d13, d15
462
463         mov             r1,  r0
464         mov             r2,  #64
465         add             r3,  r0,  #32
466         vst1.s16        {q0-q1}, [r1,:128], r2
467         vst1.s16        {q2-q3}, [r3,:128], r2
468         vst1.s16        {q4-q5}, [r1,:128], r2
469         vst1.s16        {q6-q7}, [r3,:128], r2
470
471         vpop            {q4-q7}
472         bx              lr
473 endfunc
474 .endm
475
476 .macro butterfly e, o, tmp_p, tmp_m
477         vadd.s32        \tmp_p, \e, \o
478         vsub.s32        \tmp_m, \e, \o
479 .endm
480
481 .macro tr16_8x4 in0, in1, in2, in3, in4, in5, in6, in7
482         tr_4x4_8        \in0, \in2, \in4, \in6, q8, q9, q10, q11, q12, q13, q14, q15
483
484         vmull.s16       q12, \in1, \in0[0]
485         vmull.s16       q13, \in1, \in0[1]
486         vmull.s16       q14, \in1, \in0[2]
487         vmull.s16       q15, \in1, \in0[3]
488         sum_sub         q12, \in3, \in0[1], +
489         sum_sub         q13, \in3, \in0[3], -
490         sum_sub         q14, \in3, \in0[0], -
491         sum_sub         q15, \in3, \in0[2], -
492
493         sum_sub         q12, \in5, \in0[2], +
494         sum_sub         q13, \in5, \in0[0], -
495         sum_sub         q14, \in5, \in0[3], +
496         sum_sub         q15, \in5, \in0[1], +
497
498         sum_sub         q12, \in7, \in0[3], +
499         sum_sub         q13, \in7, \in0[2], -
500         sum_sub         q14, \in7, \in0[1], +
501         sum_sub         q15, \in7, \in0[0], -
502
503         butterfly       q8,  q12, q0, q7
504         butterfly       q9,  q13, q1, q6
505         butterfly       q10, q14, q2, q5
506         butterfly       q11, q15, q3, q4
507         add             r4,  sp,  #512
508         vst1.s16        {q0-q1}, [r4, :128]!
509         vst1.s16        {q2-q3}, [r4, :128]!
510         vst1.s16        {q4-q5}, [r4, :128]!
511         vst1.s16        {q6-q7}, [r4, :128]
512 .endm
513
514 .macro load16 in0, in1, in2, in3, in4, in5, in6, in7
515         vld1.s16        {\in0}, [r1, :64], r2
516         vld1.s16        {\in1}, [r3, :64], r2
517         vld1.s16        {\in2}, [r1, :64], r2
518         vld1.s16        {\in3}, [r3, :64], r2
519         vld1.s16        {\in4}, [r1, :64], r2
520         vld1.s16        {\in5}, [r3, :64], r2
521         vld1.s16        {\in6}, [r1, :64], r2
522         vld1.s16        {\in7}, [r3, :64], r2
523 .endm
524
525 .macro add_member in, t0, t1, t2, t3, t4, t5, t6, t7, op0, op1, op2, op3, op4, op5, op6, op7
526         sum_sub q5,     \in, \t0, \op0
527         sum_sub q6,     \in, \t1, \op1
528         sum_sub q7,     \in, \t2, \op2
529         sum_sub q8,     \in, \t3, \op3
530         sum_sub q9,     \in, \t4, \op4
531         sum_sub q10,    \in, \t5, \op5
532         sum_sub q11,    \in, \t6, \op6
533         sum_sub q12,    \in, \t7, \op7
534 .endm
535
536 .macro butterfly16 in0, in1, in2, in3, in4, in5, in6, in7
537         vadd.s32        q4, \in0, \in1
538         vsub.s32        \in0, \in0, \in1
539         vadd.s32        \in1, \in2, \in3
540         vsub.s32        \in2, \in2, \in3
541         vadd.s32        \in3, \in4, \in5
542         vsub.s32        \in4, \in4, \in5
543         vadd.s32        \in5, \in6, \in7
544         vsub.s32        \in6, \in6, \in7
545 .endm
546
547 .macro store16 in0, in1, in2, in3, in4, in5, in6, in7
548         vst1.s16        \in0, [r1, :64], r2
549         vst1.s16        \in1, [r3, :64], r4
550         vst1.s16        \in2, [r1, :64], r2
551         vst1.s16        \in3, [r3, :64], r4
552         vst1.s16        \in4, [r1, :64], r2
553         vst1.s16        \in5, [r3, :64], r4
554         vst1.s16        \in6, [r1, :64], r2
555         vst1.s16        \in7, [r3, :64], r4
556 .endm
557
558 .macro scale out0, out1, out2, out3, out4, out5, out6, out7, in0, in1, in2, in3, in4, in5, in6, in7, shift
559         vqrshrn.s32     \out0, \in0, \shift
560         vqrshrn.s32     \out1, \in1, \shift
561         vqrshrn.s32     \out2, \in2, \shift
562         vqrshrn.s32     \out3, \in3, \shift
563         vqrshrn.s32     \out4, \in4, \shift
564         vqrshrn.s32     \out5, \in5, \shift
565         vqrshrn.s32     \out6, \in6, \shift
566         vqrshrn.s32     \out7, \in7, \shift
567 .endm
568
569 .macro tr_16x4 name, shift
570 function func_tr_16x4_\name
571         mov             r1,  r5
572         add             r3,  r5, #64
573         mov             r2,  #128
574         load16          d0, d1, d2, d3, d4, d5, d6, d7
575         movrel          r1, trans
576
577         tr16_8x4        d0, d1, d2, d3, d4, d5, d6, d7
578
579         add             r1,  r5, #32
580         add             r3,  r5, #(64 + 32)
581         mov             r2,  #128
582         load16          d8, d9, d2, d3, d4, d5, d6, d7
583         movrel          r1, trans + 16
584         vld1.s16        {q0}, [r1, :128]
585         vmull.s16       q5, d8, d0[0]
586         vmull.s16       q6, d8, d0[1]
587         vmull.s16       q7, d8, d0[2]
588         vmull.s16       q8, d8, d0[3]
589         vmull.s16       q9, d8, d1[0]
590         vmull.s16       q10, d8, d1[1]
591         vmull.s16       q11, d8, d1[2]
592         vmull.s16       q12, d8, d1[3]
593
594         add_member      d9, d0[1], d1[0], d1[3], d1[1], d0[2], d0[0], d0[3], d1[2], +, +, +, -, -, -, -, -
595         add_member      d2, d0[2], d1[3], d0[3], d0[1], d1[2], d1[0], d0[0], d1[1], +, +, -, -, -, +, +, +
596         add_member      d3, d0[3], d1[1], d0[1], d1[3], d0[0], d1[2], d0[2], d1[0], +, -, -, +, +, +, -, -
597         add_member      d4, d1[0], d0[2], d1[2], d0[0], d1[3], d0[1], d1[1], d0[3], +, -, -, +, -, -, +, +
598         add_member      d5, d1[1], d0[0], d1[0], d1[2], d0[1], d0[3], d1[3], d0[2], +, -, +, +, -, +, +, -
599         add_member      d6, d1[2], d0[3], d0[0], d0[2], d1[1], d1[3], d1[0], d0[1], +, -, +, -, +, +, -, +
600         add_member      d7, d1[3], d1[2], d1[1], d1[0], d0[3], d0[2], d0[1], d0[0], +, -, +, -, +, -, +, -
601
602         add             r4, sp, #512
603         vld1.s16        {q0-q1}, [r4, :128]!
604         vld1.s16        {q2-q3}, [r4, :128]!
605
606         butterfly16     q0, q5, q1, q6, q2, q7, q3, q8
607         scale           d26, d27, d28, d29, d30, d31, d16, d17, q4, q0, q5, q1, q6, q2, q7, q3, \shift
608         transpose8_4x4  d26, d28, d30, d16
609         transpose8_4x4  d17, d31, d29, d27
610         mov             r1, r6
611         add             r3, r6, #(24 +3*32)
612         mov             r2, #32
613         mov             r4, #-32
614         store16         d26, d27, d28, d29, d30, d31, d16, d17
615
616         add             r4, sp, #576
617         vld1.s16        {q0-q1}, [r4, :128]!
618         vld1.s16        {q2-q3}, [r4, :128]
619         butterfly16     q0, q9, q1, q10, q2, q11, q3, q12
620         scale           d26, d27, d28, d29, d30, d31, d8, d9, q4, q0, q9, q1, q10, q2, q11, q3, \shift
621         transpose8_4x4  d26, d28, d30, d8
622         transpose8_4x4  d9, d31, d29, d27
623
624         add             r1, r6, #8
625         add             r3, r6, #(16 + 3 * 32)
626         mov             r2, #32
627         mov             r4, #-32
628         store16         d26, d27, d28, d29, d30, d31, d8, d9
629
630         bx              lr
631 endfunc
632 .endm
633
634 .macro idct_16x16 bitdepth
635 function ff_hevc_idct_16x16_\bitdepth\()_neon, export=1
636 @r0 - coeffs
637         push            {r4-r7, lr}
638         vpush           {q4-q7}
639
640         @ Align the stack, allocate a temp buffer
641 T       mov             r7,  sp
642 T       and             r7,  r7,  #15
643 A       and             r7,  sp,  #15
644         add             r7,  r7,  #640
645         sub             sp,  sp,  r7
646
647 .irp i, 0, 1, 2, 3
648         add             r5, r0, #(8 * \i)
649         add             r6, sp, #(8 * \i * 16)
650         bl              func_tr_16x4_firstpass
651 .endr
652
653 .irp i, 0, 1, 2, 3
654         add             r5, sp, #(8 * \i)
655         add             r6, r0, #(8 * \i * 16)
656         bl              func_tr_16x4_secondpass_\bitdepth
657 .endr
658
659         add             sp,  sp,  r7
660
661         vpop            {q4-q7}
662         pop             {r4-r7, pc}
663 endfunc
664 .endm
665
666 tr_16x4 firstpass, 7
667 tr_16x4 secondpass_8, 20 - 8
668 tr_16x4 secondpass_10, 20 - 10
669 .ltorg
670
671 idct_4x4 8
672 idct_4x4_dc 8
673 idct_4x4 10
674 idct_4x4_dc 10
675 idct_8x8 8
676 idct_8x8_dc 8
677 idct_8x8 10
678 idct_8x8_dc 10
679 idct_16x16 8
680 idct_16x16_dc 8
681 idct_16x16 10
682 idct_16x16_dc 10
683 idct_32x32_dc 8
684 idct_32x32_dc 10