Merge commit 'd0ce0634e09403eecaea4283cf82a2c5cea7d1e1'
[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_idct_4x4_dc_neon_8, export=1
33         ldrsh       r1, [r0]
34         ldr         r2, =0x20
35         add         r1, #1
36         asr         r1, #1
37         add         r1, r2
38         asr         r1, #6
39         vdup.16     q0, r1
40         vdup.16     q1, r1
41         vst1.16     {q0, q1}, [r0]
42         bx lr
43 endfunc
44
45 function ff_hevc_idct_8x8_dc_neon_8, export=1
46         ldrsh       r1, [r0]
47         ldr         r2, =0x20
48         add         r1, #1
49         asr         r1, #1
50         add         r1, r2
51         asr         r1, #6
52         vdup.16     q8, r1
53         vdup.16     q9, r1
54         vmov.16     q10, q8
55         vmov.16     q11, q8
56         vmov.16     q12, q8
57         vmov.16     q13, q8
58         vmov.16     q14, q8
59         vmov.16     q15, q8
60         vstm        r0, {q8-q15}
61         bx lr
62 endfunc
63
64 function ff_hevc_idct_16x16_dc_neon_8, export=1
65         ldrsh       r1, [r0]
66         ldr         r2, =0x20
67         add         r1, #1
68         asr         r1, #1
69         add         r1, r2
70         asr         r1, #6
71         vdup.16     q8, r1
72         vdup.16     q9, r1
73         vmov.16     q10, q8
74         vmov.16     q11, q8
75         vmov.16     q12, q8
76         vmov.16     q13, q8
77         vmov.16     q14, q8
78         vmov.16     q15, q8
79         vstm        r0!, {q8-q15}
80         vstm        r0!, {q8-q15}
81         vstm        r0!, {q8-q15}
82         vstm        r0, {q8-q15}
83         bx lr
84 endfunc
85
86 function ff_hevc_idct_32x32_dc_neon_8, export=1
87         ldrsh       r1, [r0]
88         ldr         r2, =0x20
89         add         r1, #1
90         asr         r1, #1
91         add         r1, r2
92         asr         r1, #6
93         mov         r3, #16
94         vdup.16     q8, r1
95         vdup.16     q9, r1
96         vmov.16     q10, q8
97         vmov.16     q11, q8
98         vmov.16     q12, q8
99         vmov.16     q13, q8
100         vmov.16     q14, q8
101         vmov.16     q15, q8
102 1:      subs        r3, #1
103         vstm        r0!, {q8-q15}
104         bne         1b
105         bx lr
106 endfunc
107
108 function ff_hevc_add_residual_4x4_neon_8, export=1
109         vldm        r1, {q0-q1}
110         vld1.32     d4[0], [r0], r2
111         vld1.32     d4[1], [r0], r2
112         vld1.32     d5[0], [r0], r2
113         vld1.32     d5[1], [r0], r2
114         sub         r0, r0, r2, lsl #2
115         vmovl.u8    q8, d4
116         vmovl.u8    q9, d5
117         vqadd.s16   q0, q0, q8
118         vqadd.s16   q1, q1, q9
119         vqmovun.s16 d0, q0
120         vqmovun.s16 d1, q1
121         vst1.32     d0[0], [r0], r2
122         vst1.32     d0[1], [r0], r2
123         vst1.32     d1[0], [r0], r2
124         vst1.32     d1[1], [r0], r2
125         bx          lr
126 endfunc
127
128 function ff_hevc_add_residual_8x8_neon_8, export=1
129         mov         r3,   #8
130 1:      subs        r3,   #1
131         vld1.16     {q0}, [r1]!
132         vld1.8      d16,  [r0]
133         vmovl.u8    q8,   d16
134         vqadd.s16   q0,   q8
135         vqmovun.s16 d0,   q0
136         vst1.32     d0,   [r0], r2
137         bne         1b
138         bx          lr
139 endfunc
140
141 function ff_hevc_add_residual_16x16_neon_8, export=1
142         mov         r3,   #16
143 1:      subs        r3,   #1
144         vld1.16     {q0, q1}, [r1]!
145         vld1.8      {q8},  [r0]
146         vmovl.u8    q9,  d16
147         vmovl.u8    q10, d17
148         vqadd.s16   q0,  q9
149         vqadd.s16   q1,  q10
150         vqmovun.s16 d0,  q0
151         vqmovun.s16 d1,  q1
152         vst1.8      {q0},   [r0], r2
153         bne         1b
154         bx          lr
155 endfunc
156
157 function ff_hevc_add_residual_32x32_neon_8, export=1
158         mov         r3,   #32
159 1:      subs        r3,   #1
160         vldm        r1!, {q0-q3}
161         vld1.8      {q8, q9},  [r0]
162         vmovl.u8    q10, d16
163         vmovl.u8    q11, d17
164         vmovl.u8    q12, d18
165         vmovl.u8    q13, d19
166         vqadd.s16   q0,  q10
167         vqadd.s16   q1,  q11
168         vqadd.s16   q2,  q12
169         vqadd.s16   q3,  q13
170         vqmovun.s16 d0,  q0
171         vqmovun.s16 d1,  q1
172         vqmovun.s16 d2,  q2
173         vqmovun.s16 d3,  q3
174         vst1.8     {q0, q1},   [r0], r2
175         bne         1b
176         bx          lr
177 endfunc
178
179 /* uses registers q2 - q9 for temp values */
180 /* TODO: reorder */
181 .macro tr4_luma_shift r0, r1, r2, r3, shift
182         vaddl.s16   q5, \r0, \r2    // c0 = src0 + src2
183         vaddl.s16   q2, \r2, \r3    // c1 = src2 + src3
184         vsubl.s16   q4, \r0, \r3    // c2 = src0 - src3
185         vmull.s16   q6, \r1, d0[0]  // c3 = 74 * src1
186
187         vaddl.s16   q7, \r0, \r3    // src0 + src3
188         vsubw.s16   q7, q7, \r2     // src0 - src2 + src3
189         vmul.s32    q7, q7, d0[0]   // dst2 = 74 * (src0 - src2 + src3)
190
191         vmul.s32    q8, q5, d0[1]   // 29 * c0
192         vmul.s32    q9, q2, d1[0]   // 55 * c1
193         vadd.s32    q8, q9          // 29 * c0 + 55 * c1
194         vadd.s32    q8, q6          // dst0 = 29 * c0 + 55 * c1 + c3
195
196         vmul.s32    q2, q2, d0[1]   // 29 * c1
197         vmul.s32    q9, q4, d1[0]   // 55 * c2
198         vsub.s32    q9, q2          // 55 * c2 - 29 * c1
199         vadd.s32    q9, q6          // dst1 = 55 * c2 - 29 * c1 + c3
200
201         vmul.s32    q5, q5, d1[0]   // 55 * c0
202         vmul.s32    q4, q4, d0[1]   // 29 * c2
203         vadd.s32    q5, q4          // 55 * c0 + 29 * c2
204         vsub.s32    q5, q6          // dst3 = 55 * c0 + 29 * c2 - c3
205
206         vqrshrn.s32   \r0, q8, \shift
207         vqrshrn.s32   \r1, q9, \shift
208         vqrshrn.s32   \r2, q7, \shift
209         vqrshrn.s32   \r3, q5, \shift
210 .endm
211
212 function ff_hevc_transform_luma_4x4_neon_8, export=1
213         vpush       {d8-d15}
214         vld1.16     {q14, q15}, [r0]  // coeffs
215         ldr         r3, =0x4a  // 74
216         vmov.32     d0[0], r3
217         ldr         r3, =0x1d  // 29
218         vmov.32     d0[1], r3
219         ldr         r3, =0x37  // 55
220         vmov.32     d1[0], r3
221
222         tr4_luma_shift d28, d29, d30, d31, #7
223
224         vtrn.16     d28, d29
225         vtrn.16     d30, d31
226         vtrn.32     q14, q15
227
228         tr4_luma_shift d28, d29, d30, d31, #12
229
230         vtrn.16     d28, d29
231         vtrn.16     d30, d31
232         vtrn.32     q14, q15
233         vst1.16     {q14, q15}, [r0]
234         vpop        {d8-d15}
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