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