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