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