Merge commit '358adef0305618219522858e471edf7e0cb4043e'
[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 function ff_hevc_idct_4x4_dc_8_neon, export=1
163         ldrsh           r1, [r0]
164         ldr             r2, =0x20
165         add             r1, #1
166         asr             r1, #1
167         add             r1, r2
168         asr             r1, #6
169         vdup.16         q0, r1
170         vdup.16         q1, r1
171         vst1.16         {q0, q1}, [r0, :128]
172         bx              lr
173 endfunc
174
175 function ff_hevc_idct_8x8_dc_8_neon, export=1
176         ldrsh           r1, [r0]
177         ldr             r2, =0x20
178         add             r1, #1
179         asr             r1, #1
180         add             r1, r2
181         asr             r1, #6
182         vdup.16         q8, r1
183         vdup.16         q9, r1
184         vmov.16         q10, q8
185         vmov.16         q11, q8
186         vmov.16         q12, q8
187         vmov.16         q13, q8
188         vmov.16         q14, q8
189         vmov.16         q15, q8
190         vstm            r0, {q8-q15}
191         bx              lr
192 endfunc
193
194 function ff_hevc_idct_16x16_dc_8_neon, export=1
195         ldrsh           r1, [r0]
196         ldr             r2, =0x20
197         add             r1, #1
198         asr             r1, #1
199         add             r1, r2
200         asr             r1, #6
201         vdup.16         q8, r1
202         vdup.16         q9, r1
203         vmov.16         q10, q8
204         vmov.16         q11, q8
205         vmov.16         q12, q8
206         vmov.16         q13, q8
207         vmov.16         q14, q8
208         vmov.16         q15, q8
209         vstm            r0!, {q8-q15}
210         vstm            r0!, {q8-q15}
211         vstm            r0!, {q8-q15}
212         vstm            r0, {q8-q15}
213         bx              lr
214 endfunc
215
216 function ff_hevc_idct_32x32_dc_8_neon, export=1
217         ldrsh           r1, [r0]
218         ldr             r2, =0x20
219         add             r1, #1
220         asr             r1, #1
221         add             r1, r2
222         asr             r1, #6
223         mov             r3, #16
224         vdup.16         q8, r1
225         vdup.16         q9, r1
226         vmov.16         q10, q8
227         vmov.16         q11, q8
228         vmov.16         q12, q8
229         vmov.16         q13, q8
230         vmov.16         q14, q8
231         vmov.16         q15, q8
232 1:      subs            r3, #1
233         vstm            r0!, {q8-q15}
234         bne             1b
235         bx              lr
236 endfunc
237
238 .macro sum_sub out, in, c, op
239   .ifc \op, +
240         vmlal.s16       \out, \in, \c
241   .else
242         vmlsl.s16       \out, \in, \c
243   .endif
244 .endm
245
246 .macro tr_4x4 in0, in1, in2, in3, out0, out1, out2, out3, shift, tmp0, tmp1, tmp2, tmp3, tmp4
247          vshll.s16      \tmp0, \in0, #6
248          vmull.s16      \tmp2, \in1, d4[1]
249          vmov           \tmp1, \tmp0
250          vmull.s16      \tmp3, \in1, d4[3]
251          vmlal.s16      \tmp0, \in2, d4[0] @e0
252          vmlsl.s16      \tmp1, \in2, d4[0] @e1
253          vmlal.s16      \tmp2, \in3, d4[3] @o0
254          vmlsl.s16      \tmp3, \in3, d4[1] @o1
255
256          vadd.s32       \tmp4, \tmp0, \tmp2
257          vsub.s32       \tmp0, \tmp0, \tmp2
258          vadd.s32       \tmp2, \tmp1, \tmp3
259          vsub.s32       \tmp1, \tmp1, \tmp3
260          vqrshrn.s32    \out0, \tmp4, #\shift
261          vqrshrn.s32    \out3, \tmp0, #\shift
262          vqrshrn.s32    \out1, \tmp2, #\shift
263          vqrshrn.s32    \out2, \tmp1, #\shift
264 .endm
265
266 .macro tr_4x4_8 in0, in1, in2, in3, out0, out1, out2, out3, tmp0, tmp1, tmp2, tmp3
267          vshll.s16      \tmp0, \in0, #6
268          vld1.s16       {\in0}, [r1, :64]!
269          vmov           \tmp1, \tmp0
270          vmull.s16      \tmp2, \in1, \in0[1]
271          vmull.s16      \tmp3, \in1, \in0[3]
272          vmlal.s16      \tmp0, \in2, \in0[0] @e0
273          vmlsl.s16      \tmp1, \in2, \in0[0] @e1
274          vmlal.s16      \tmp2, \in3, \in0[3] @o0
275          vmlsl.s16      \tmp3, \in3, \in0[1] @o1
276
277          vld1.s16       {\in0}, [r1, :64]
278
279          vadd.s32       \out0, \tmp0, \tmp2
280          vadd.s32       \out1, \tmp1, \tmp3
281          vsub.s32       \out2, \tmp1, \tmp3
282          vsub.s32       \out3, \tmp0, \tmp2
283
284          sub            r1,  r1,  #8
285 .endm
286
287 @ Do a 4x4 transpose, using q registers for the subtransposes that don't
288 @ need to address the indiviudal d registers.
289 @ r0,r1 == rq0, r2,r3 == rq1
290 .macro transpose_4x4 rq0, rq1, r0, r1, r2, r3
291         vtrn.32         \rq0, \rq1
292         vtrn.16         \r0,  \r1
293         vtrn.16         \r2,  \r3
294 .endm
295
296 .macro idct_4x4 bitdepth
297 function ff_hevc_idct_4x4_\bitdepth\()_neon, export=1
298 @r0 - coeffs
299         vld1.s16        {q0-q1}, [r0, :128]
300
301         movrel          r1, trans
302         vld1.s16        {d4}, [r1, :64]
303
304         tr_4x4          d0, d1, d2, d3, d16, d17, d18, d19, 7, q10, q11, q12, q13, q0
305         transpose_4x4   q8, q9, d16, d17, d18, d19
306
307         tr_4x4          d16, d17, d18, d19, d0, d1, d2, d3, 20 - \bitdepth, q10, q11, q12, q13, q0
308         transpose_4x4   q0, q1, d0, d1, d2, d3
309         vst1.s16        {d0-d3}, [r0, :128]
310         bx lr
311 endfunc
312 .endm
313
314 .macro transpose8_4x4 r0, r1, r2, r3
315         vtrn.16         \r0,  \r1
316         vtrn.16         \r2,  \r3
317         vtrn.32         \r0,  \r2
318         vtrn.32         \r1,  \r3
319 .endm
320
321 .macro transpose_8x8 r0, r1, r2, r3, r4, r5, r6, r7, l0, l1, l2, l3, l4, l5, l6, l7
322         transpose8_4x4  \r0, \r1, \r2, \r3
323         transpose8_4x4  \r4, \r5, \r6, \r7
324
325         transpose8_4x4  \l0, \l1, \l2, \l3
326         transpose8_4x4  \l4, \l5, \l6, \l7
327 .endm
328
329 .macro tr_8x4 shift, in0, in1, in2, in3, in4, in5, in6, in7
330         tr_4x4_8        \in0, \in2, \in4, \in6, q8, q9, q10, q11, q12, q13, q14, q15
331
332         vmull.s16       q14, \in1, \in0[2]
333         vmull.s16       q12, \in1, \in0[0]
334         vmull.s16       q13, \in1, \in0[1]
335         sum_sub         q14, \in3, \in0[0], -
336         sum_sub         q12, \in3, \in0[1], +
337         sum_sub         q13, \in3, \in0[3], -
338
339         sum_sub         q14, \in5, \in0[3], +
340         sum_sub         q12, \in5, \in0[2], +
341         sum_sub         q13, \in5, \in0[0], -
342
343         sum_sub         q14, \in7, \in0[1], +
344         sum_sub         q12, \in7, \in0[3], +
345         sum_sub         q13, \in7, \in0[2], -
346
347         vadd.s32        q15, q10, q14
348         vsub.s32        q10, q10, q14
349         vqrshrn.s32     \in2, q15, \shift
350
351         vmull.s16       q15, \in1, \in0[3]
352         sum_sub         q15, \in3, \in0[2], -
353         sum_sub         q15, \in5, \in0[1], +
354         sum_sub         q15, \in7, \in0[0], -
355
356         vqrshrn.s32     \in5, q10,  \shift
357
358         vadd.s32        q10, q8, q12
359         vsub.s32        q8,  q8, q12
360         vadd.s32        q12, q9, q13
361         vsub.s32        q9,  q9, q13
362         vadd.s32        q14, q11, q15
363         vsub.s32        q11, q11, q15
364
365         vqrshrn.s32     \in0, q10, \shift
366         vqrshrn.s32     \in7, q8,  \shift
367         vqrshrn.s32     \in1, q12, \shift
368         vqrshrn.s32     \in6, q9,  \shift
369         vqrshrn.s32     \in3, q14, \shift
370         vqrshrn.s32     \in4, q11, \shift
371 .endm
372
373 .macro idct_8x8 bitdepth
374 function ff_hevc_idct_8x8_\bitdepth\()_neon, export=1
375 @r0 - coeffs
376         vpush           {q4-q7}
377
378         mov             r1,  r0
379         mov             r2,  #64
380         add             r3,  r0,  #32
381         vld1.s16        {q0-q1}, [r1,:128], r2
382         vld1.s16        {q2-q3}, [r3,:128], r2
383         vld1.s16        {q4-q5}, [r1,:128], r2
384         vld1.s16        {q6-q7}, [r3,:128], r2
385
386         movrel          r1, trans
387
388         tr_8x4          7, d0, d2, d4, d6, d8, d10, d12, d14
389         tr_8x4          7, d1, d3, d5, d7, d9, d11, d13, d15
390
391         @ Transpose each 4x4 block, and swap how d4-d7 and d8-d11 are used.
392         @ Layout before:
393         @ d0  d1
394         @ d2  d3
395         @ d4  d5
396         @ d6  d7
397         @ d8  d9
398         @ d10 d11
399         @ d12 d13
400         @ d14 d15
401         transpose_8x8   d0, d2, d4, d6, d8, d10, d12, d14, d1, d3, d5, d7, d9, d11, d13, d15
402         @ Now the layout is:
403         @ d0  d8
404         @ d2  d10
405         @ d4  d12
406         @ d6  d14
407         @ d1  d9
408         @ d3  d11
409         @ d5  d13
410         @ d7  d15
411
412         tr_8x4          20 - \bitdepth, d0, d2, d4, d6, d1, d3, d5, d7
413         vswp            d0, d8
414         tr_8x4          20 - \bitdepth, d0, d10, d12, d14, d9, d11, d13, d15
415         vswp            d0, d8
416
417         transpose_8x8   d0, d2, d4, d6, d8, d10, d12, d14, d1, d3, d5, d7, d9, d11, d13, d15
418
419         mov             r1,  r0
420         mov             r2,  #64
421         add             r3,  r0,  #32
422         vst1.s16        {q0-q1}, [r1,:128], r2
423         vst1.s16        {q2-q3}, [r3,:128], r2
424         vst1.s16        {q4-q5}, [r1,:128], r2
425         vst1.s16        {q6-q7}, [r3,:128], r2
426
427         vpop            {q4-q7}
428         bx              lr
429 endfunc
430 .endm
431
432 .macro butterfly e, o, tmp_p, tmp_m
433         vadd.s32        \tmp_p, \e, \o
434         vsub.s32        \tmp_m, \e, \o
435 .endm
436
437 .macro tr16_8x4 in0, in1, in2, in3, in4, in5, in6, in7
438         tr_4x4_8        \in0, \in2, \in4, \in6, q8, q9, q10, q11, q12, q13, q14, q15
439
440         vmull.s16       q12, \in1, \in0[0]
441         vmull.s16       q13, \in1, \in0[1]
442         vmull.s16       q14, \in1, \in0[2]
443         vmull.s16       q15, \in1, \in0[3]
444         sum_sub         q12, \in3, \in0[1], +
445         sum_sub         q13, \in3, \in0[3], -
446         sum_sub         q14, \in3, \in0[0], -
447         sum_sub         q15, \in3, \in0[2], -
448
449         sum_sub         q12, \in5, \in0[2], +
450         sum_sub         q13, \in5, \in0[0], -
451         sum_sub         q14, \in5, \in0[3], +
452         sum_sub         q15, \in5, \in0[1], +
453
454         sum_sub         q12, \in7, \in0[3], +
455         sum_sub         q13, \in7, \in0[2], -
456         sum_sub         q14, \in7, \in0[1], +
457         sum_sub         q15, \in7, \in0[0], -
458
459         butterfly       q8,  q12, q0, q7
460         butterfly       q9,  q13, q1, q6
461         butterfly       q10, q14, q2, q5
462         butterfly       q11, q15, q3, q4
463         add             r4,  sp,  #512
464         vst1.s16        {q0-q1}, [r4, :128]!
465         vst1.s16        {q2-q3}, [r4, :128]!
466         vst1.s16        {q4-q5}, [r4, :128]!
467         vst1.s16        {q6-q7}, [r4, :128]
468 .endm
469
470 .macro load16 in0, in1, in2, in3, in4, in5, in6, in7
471         vld1.s16        {\in0}, [r1, :64], r2
472         vld1.s16        {\in1}, [r3, :64], r2
473         vld1.s16        {\in2}, [r1, :64], r2
474         vld1.s16        {\in3}, [r3, :64], r2
475         vld1.s16        {\in4}, [r1, :64], r2
476         vld1.s16        {\in5}, [r3, :64], r2
477         vld1.s16        {\in6}, [r1, :64], r2
478         vld1.s16        {\in7}, [r3, :64], r2
479 .endm
480
481 .macro add_member in, t0, t1, t2, t3, t4, t5, t6, t7, op0, op1, op2, op3, op4, op5, op6, op7
482         sum_sub q5,     \in, \t0, \op0
483         sum_sub q6,     \in, \t1, \op1
484         sum_sub q7,     \in, \t2, \op2
485         sum_sub q8,     \in, \t3, \op3
486         sum_sub q9,     \in, \t4, \op4
487         sum_sub q10,    \in, \t5, \op5
488         sum_sub q11,    \in, \t6, \op6
489         sum_sub q12,    \in, \t7, \op7
490 .endm
491
492 .macro butterfly16 in0, in1, in2, in3, in4, in5, in6, in7
493         vadd.s32        q4, \in0, \in1
494         vsub.s32        \in0, \in0, \in1
495         vadd.s32        \in1, \in2, \in3
496         vsub.s32        \in2, \in2, \in3
497         vadd.s32        \in3, \in4, \in5
498         vsub.s32        \in4, \in4, \in5
499         vadd.s32        \in5, \in6, \in7
500         vsub.s32        \in6, \in6, \in7
501 .endm
502
503 .macro store16 in0, in1, in2, in3, in4, in5, in6, in7
504         vst1.s16        \in0, [r1, :64], r2
505         vst1.s16        \in1, [r3, :64], r4
506         vst1.s16        \in2, [r1, :64], r2
507         vst1.s16        \in3, [r3, :64], r4
508         vst1.s16        \in4, [r1, :64], r2
509         vst1.s16        \in5, [r3, :64], r4
510         vst1.s16        \in6, [r1, :64], r2
511         vst1.s16        \in7, [r3, :64], r4
512 .endm
513
514 .macro scale out0, out1, out2, out3, out4, out5, out6, out7, in0, in1, in2, in3, in4, in5, in6, in7, shift
515         vqrshrn.s32     \out0, \in0, \shift
516         vqrshrn.s32     \out1, \in1, \shift
517         vqrshrn.s32     \out2, \in2, \shift
518         vqrshrn.s32     \out3, \in3, \shift
519         vqrshrn.s32     \out4, \in4, \shift
520         vqrshrn.s32     \out5, \in5, \shift
521         vqrshrn.s32     \out6, \in6, \shift
522         vqrshrn.s32     \out7, \in7, \shift
523 .endm
524
525 .macro tr_16x4 name, shift
526 function func_tr_16x4_\name
527         mov             r1,  r5
528         add             r3,  r5, #64
529         mov             r2,  #128
530         load16          d0, d1, d2, d3, d4, d5, d6, d7
531         movrel          r1, trans
532
533         tr16_8x4        d0, d1, d2, d3, d4, d5, d6, d7
534
535         add             r1,  r5, #32
536         add             r3,  r5, #(64 + 32)
537         mov             r2,  #128
538         load16          d8, d9, d2, d3, d4, d5, d6, d7
539         movrel          r1, trans + 16
540         vld1.s16        {q0}, [r1, :128]
541         vmull.s16       q5, d8, d0[0]
542         vmull.s16       q6, d8, d0[1]
543         vmull.s16       q7, d8, d0[2]
544         vmull.s16       q8, d8, d0[3]
545         vmull.s16       q9, d8, d1[0]
546         vmull.s16       q10, d8, d1[1]
547         vmull.s16       q11, d8, d1[2]
548         vmull.s16       q12, d8, d1[3]
549
550         add_member      d9, d0[1], d1[0], d1[3], d1[1], d0[2], d0[0], d0[3], d1[2], +, +, +, -, -, -, -, -
551         add_member      d2, d0[2], d1[3], d0[3], d0[1], d1[2], d1[0], d0[0], d1[1], +, +, -, -, -, +, +, +
552         add_member      d3, d0[3], d1[1], d0[1], d1[3], d0[0], d1[2], d0[2], d1[0], +, -, -, +, +, +, -, -
553         add_member      d4, d1[0], d0[2], d1[2], d0[0], d1[3], d0[1], d1[1], d0[3], +, -, -, +, -, -, +, +
554         add_member      d5, d1[1], d0[0], d1[0], d1[2], d0[1], d0[3], d1[3], d0[2], +, -, +, +, -, +, +, -
555         add_member      d6, d1[2], d0[3], d0[0], d0[2], d1[1], d1[3], d1[0], d0[1], +, -, +, -, +, +, -, +
556         add_member      d7, d1[3], d1[2], d1[1], d1[0], d0[3], d0[2], d0[1], d0[0], +, -, +, -, +, -, +, -
557
558         add             r4, sp, #512
559         vld1.s16        {q0-q1}, [r4, :128]!
560         vld1.s16        {q2-q3}, [r4, :128]!
561
562         butterfly16     q0, q5, q1, q6, q2, q7, q3, q8
563         scale           d26, d27, d28, d29, d30, d31, d16, d17, q4, q0, q5, q1, q6, q2, q7, q3, \shift
564         transpose8_4x4  d26, d28, d30, d16
565         transpose8_4x4  d17, d31, d29, d27
566         mov             r1, r6
567         add             r3, r6, #(24 +3*32)
568         mov             r2, #32
569         mov             r4, #-32
570         store16         d26, d27, d28, d29, d30, d31, d16, d17
571
572         add             r4, sp, #576
573         vld1.s16        {q0-q1}, [r4, :128]!
574         vld1.s16        {q2-q3}, [r4, :128]
575         butterfly16     q0, q9, q1, q10, q2, q11, q3, q12
576         scale           d26, d27, d28, d29, d30, d31, d8, d9, q4, q0, q9, q1, q10, q2, q11, q3, \shift
577         transpose8_4x4  d26, d28, d30, d8
578         transpose8_4x4  d9, d31, d29, d27
579
580         add             r1, r6, #8
581         add             r3, r6, #(16 + 3 * 32)
582         mov             r2, #32
583         mov             r4, #-32
584         store16         d26, d27, d28, d29, d30, d31, d8, d9
585
586         bx              lr
587 endfunc
588 .endm
589
590 .macro idct_16x16 bitdepth
591 function ff_hevc_idct_16x16_\bitdepth\()_neon, export=1
592 @r0 - coeffs
593         push            {r4-r7, lr}
594         vpush           {q4-q7}
595
596         @ Align the stack, allocate a temp buffer
597 T       mov             r7,  sp
598 T       and             r7,  r7,  #15
599 A       and             r7,  sp,  #15
600         add             r7,  r7,  #640
601         sub             sp,  sp,  r7
602
603 .irp i, 0, 1, 2, 3
604         add             r5, r0, #(8 * \i)
605         add             r6, sp, #(8 * \i * 16)
606         bl              func_tr_16x4_firstpass
607 .endr
608
609 .irp i, 0, 1, 2, 3
610         add             r5, sp, #(8 * \i)
611         add             r6, r0, #(8 * \i * 16)
612         bl              func_tr_16x4_secondpass_\bitdepth
613 .endr
614
615         add             sp,  sp,  r7
616
617         vpop            {q4-q7}
618         pop             {r4-r7, pc}
619 endfunc
620 .endm
621
622 tr_16x4 firstpass, 7
623 tr_16x4 secondpass_8, 20 - 8
624 tr_16x4 secondpass_10, 20 - 10
625 .ltorg
626
627 idct_4x4 8
628 idct_4x4 10
629 idct_8x8 8
630 idct_8x8 10
631 idct_16x16 8
632 idct_16x16 10