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