]> git.sesse.net Git - ffmpeg/blob - libavcodec/arm/hevcdsp_idct_neon.S
avcodec: Remove redundant freeing of extradata of encoders
[ffmpeg] / 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         .short 90, 90, 88, 85
31         .short 82, 78, 73, 67
32         .short 61, 54, 46, 38
33         .short 31, 22, 13, 4
34 endconst
35
36 .macro clip10 in1, in2, c1, c2
37         vmax.s16        \in1, \in1, \c1
38         vmax.s16        \in2, \in2, \c1
39         vmin.s16        \in1, \in1, \c2
40         vmin.s16        \in2, \in2, \c2
41 .endm
42
43 function ff_hevc_add_residual_4x4_8_neon, export=1
44         vld1.16         {q0-q1}, [r1, :128]
45         vld1.32         d4[0], [r0, :32], r2
46         vld1.32         d4[1], [r0, :32], r2
47         vld1.32         d5[0], [r0, :32], r2
48         vld1.32         d5[1], [r0, :32], r2
49         sub             r0, r0, r2, lsl #2
50         vmovl.u8        q8, d4
51         vmovl.u8        q9, d5
52         vqadd.s16       q0, q0, q8
53         vqadd.s16       q1, q1, q9
54         vqmovun.s16     d0, q0
55         vqmovun.s16     d1, q1
56         vst1.32         d0[0], [r0, :32], r2
57         vst1.32         d0[1], [r0, :32], r2
58         vst1.32         d1[0], [r0, :32], r2
59         vst1.32         d1[1], [r0, :32], r2
60         bx              lr
61 endfunc
62
63 function ff_hevc_add_residual_4x4_10_neon, export=1
64         mov             r12, r0
65         vld1.16         {q0-q1}, [r1, :128]
66         vld1.16         d4, [r12, :64], r2
67         vld1.16         d5, [r12, :64], r2
68         vld1.16         d6, [r12, :64], r2
69         vqadd.s16       q0, q2
70         vld1.16         d7, [r12, :64], r2
71         vmov.s16        q12, #0
72         vqadd.s16       q1, q3
73         vmvn.s16        q13, #0xFC00 @ vmov.s16 #0x3FF
74         clip10          q0, q1, q12, q13
75         vst1.16         d0, [r0, :64], r2
76         vst1.16         d1, [r0, :64], r2
77         vst1.16         d2, [r0, :64], r2
78         vst1.16         d3, [r0, :64], r2
79         bx              lr
80 endfunc
81
82 function ff_hevc_add_residual_8x8_8_neon, export=1
83         add             r12, r0, r2
84         add             r2,  r2, r2
85         mov             r3,   #8
86 1:      subs            r3,   #2
87         vld1.8          {d16},   [r0,  :64]
88         vld1.8          {d17},   [r12, :64]
89         vmovl.u8        q9,   d16
90         vld1.16         {q0-q1}, [r1,  :128]!
91         vmovl.u8        q8,   d17
92         vqadd.s16       q0,   q9
93         vqadd.s16       q1,   q8
94         vqmovun.s16     d0,   q0
95         vqmovun.s16     d1,   q1
96         vst1.8          d0,   [r0,  :64], r2
97         vst1.8          d1,   [r12, :64], r2
98         bne             1b
99         bx              lr
100 endfunc
101
102 function ff_hevc_add_residual_8x8_10_neon, export=1
103         add             r12, r0, r2
104         add             r2,  r2, r2
105         mov             r3,  #8
106         vmov.s16        q12, #0
107         vmvn.s16        q13, #0xFC00 @ vmov.s16 #0x3FF
108 1:      subs            r3,  #2
109         vld1.16         {q0-q1}, [r1, :128]!
110         vld1.16         {q8},    [r0, :128]
111         vqadd.s16       q0, q8
112         vld1.16         {q9},    [r12, :128]
113         vqadd.s16       q1, q9
114         clip10          q0, q1, q12, q13
115         vst1.16         {q0}, [r0, :128], r2
116         vst1.16         {q1}, [r12, :128], r2
117         bne             1b
118         bx              lr
119 endfunc
120
121 function ff_hevc_add_residual_16x16_8_neon, export=1
122         mov             r3,  #16
123         add             r12, r0, r2
124         add             r2,  r2, r2
125 1:      subs            r3,  #2
126         vld1.8          {q8},     [r0, :128]
127         vld1.16         {q0, q1}, [r1, :128]!
128         vld1.8          {q11},    [r12, :128]
129         vld1.16         {q2, q3}, [r1, :128]!
130         vmovl.u8        q9,  d16
131         vmovl.u8        q10, d17
132         vmovl.u8        q12, d22
133         vmovl.u8        q13, d23
134         vqadd.s16       q0,  q9
135         vqadd.s16       q1,  q10
136         vqadd.s16       q2,  q12
137         vqadd.s16       q3,  q13
138         vqmovun.s16     d0,  q0
139         vqmovun.s16     d1,  q1
140         vqmovun.s16     d2,  q2
141         vqmovun.s16     d3,  q3
142         vst1.8          {q0},     [r0, :128], r2
143         vst1.8          {q1},     [r12, :128], r2
144         bne             1b
145         bx              lr
146 endfunc
147
148 function ff_hevc_add_residual_16x16_10_neon, export=1
149         mov             r3,  #16
150         vmov.s16        q12, #0
151         vmvn.s16        q13, #0xFC00 @ vmov.s16 #0x3FF
152         add             r12, r0, r2
153         add             r2,  r2, r2
154 1:      subs            r3,  #2
155         vld1.16         {q8-q9},   [r0, :128]
156         vld1.16         {q0, q1},  [r1, :128]!
157         vqadd.s16       q0, q8
158         vld1.16         {q10-q11}, [r12, :128]
159         vqadd.s16       q1, q9
160         vld1.16         {q2, q3},  [r1, :128]!
161         vqadd.s16       q2, q10
162         vqadd.s16       q3, q11
163         clip10          q0, q1, q12, q13
164         clip10          q2, q3, q12, q13
165         vst1.16         {q0-q1},   [r0, :128], r2
166         vst1.16         {q2-q3},   [r12, :128], r2
167         bne             1b
168         bx              lr
169 endfunc
170
171 function ff_hevc_add_residual_32x32_8_neon, export=1
172         vpush           {q4-q7}
173         add             r12, r0, r2
174         add             r2,  r2, r2
175         mov             r3,  #32
176 1:      subs            r3,  #2
177         vld1.8          {q12, q13}, [r0,  :128]
178         vmovl.u8        q8,  d24
179         vmovl.u8        q9,  d25
180         vld1.8          {q14, q15}, [r12, :128]
181         vmovl.u8        q10, d26
182         vmovl.u8        q11, d27
183         vmovl.u8        q12, d28
184         vldm            r1!, {q0-q7}
185         vmovl.u8        q13, d29
186         vmovl.u8        q14, d30
187         vmovl.u8        q15, d31
188         vqadd.s16       q0,  q8
189         vqadd.s16       q1,  q9
190         vqadd.s16       q2,  q10
191         vqadd.s16       q3,  q11
192         vqadd.s16       q4,  q12
193         vqadd.s16       q5,  q13
194         vqadd.s16       q6,  q14
195         vqadd.s16       q7,  q15
196         vqmovun.s16     d0,  q0
197         vqmovun.s16     d1,  q1
198         vqmovun.s16     d2,  q2
199         vqmovun.s16     d3,  q3
200         vqmovun.s16     d4,  q4
201         vqmovun.s16     d5,  q5
202         vst1.8          {q0, q1}, [r0, :128], r2
203         vqmovun.s16     d6,  q6
204         vqmovun.s16     d7,  q7
205         vst1.8          {q2, q3}, [r12, :128], r2
206         bne             1b
207         vpop            {q4-q7}
208         bx              lr
209 endfunc
210
211 function ff_hevc_add_residual_32x32_10_neon, export=1
212         mov             r3,  #32
213         add             r12, r0, #32
214         vmov.s16        q12, #0
215         vmvn.s16        q13, #0xFC00 @ vmov.s16 #0x3FF
216 1:      subs            r3,  #1
217         vldm            r1!, {q0-q3}
218         vld1.16         {q8, q9},   [r0, :128]
219         vld1.16         {q10, q11}, [r12, :128]
220         vqadd.s16       q0, q8
221         vqadd.s16       q1, q9
222         vqadd.s16       q2, q10
223         vqadd.s16       q3, q11
224         clip10          q0, q1, q12, q13
225         clip10          q2, q3, q12, q13
226         vst1.16         {q0-q1},   [r0, :128], r2
227         vst1.16         {q2-q3},   [r12, :128], r2
228         bne             1b
229         bx              lr
230 endfunc
231
232 .macro idct_4x4_dc bitdepth
233 function ff_hevc_idct_4x4_dc_\bitdepth\()_neon, export=1
234         ldrsh           r1, [r0]
235         ldr             r2, =(1 << (13 - \bitdepth))
236         add             r1, #1
237         asr             r1, #1
238         add             r1, r2
239         asr             r1, #(14 - \bitdepth)
240         vdup.16         q0, r1
241         vdup.16         q1, r1
242         vst1.16         {q0, q1}, [r0, :128]
243         bx              lr
244 endfunc
245 .endm
246
247 .macro idct_8x8_dc bitdepth
248 function ff_hevc_idct_8x8_dc_\bitdepth\()_neon, export=1
249         ldrsh           r1, [r0]
250         ldr             r2, =(1 << (13 - \bitdepth))
251         add             r1, #1
252         asr             r1, #1
253         add             r1, r2
254         asr             r1, #(14 - \bitdepth)
255         vdup.16         q8, r1
256         vdup.16         q9, r1
257         vmov.16         q10, q8
258         vmov.16         q11, q8
259         vmov.16         q12, q8
260         vmov.16         q13, q8
261         vmov.16         q14, q8
262         vmov.16         q15, q8
263         vstm            r0, {q8-q15}
264         bx              lr
265 endfunc
266 .endm
267
268 .macro idct_16x16_dc bitdepth
269 function ff_hevc_idct_16x16_dc_\bitdepth\()_neon, export=1
270         ldrsh           r1, [r0]
271         ldr             r2, =(1 << (13 - \bitdepth))
272         add             r1, #1
273         asr             r1, #1
274         add             r1, r2
275         asr             r1, #(14 - \bitdepth)
276         vdup.16         q8, r1
277         vdup.16         q9, r1
278         vmov.16         q10, q8
279         vmov.16         q11, q8
280         vmov.16         q12, q8
281         vmov.16         q13, q8
282         vmov.16         q14, q8
283         vmov.16         q15, q8
284         vstm            r0!, {q8-q15}
285         vstm            r0!, {q8-q15}
286         vstm            r0!, {q8-q15}
287         vstm            r0, {q8-q15}
288         bx              lr
289 endfunc
290 .endm
291
292 .macro idct_32x32_dc bitdepth
293 function ff_hevc_idct_32x32_dc_\bitdepth\()_neon, export=1
294         ldrsh           r1, [r0]
295         ldr             r2, =(1 << (13 - \bitdepth))
296         add             r1, #1
297         asr             r1, #1
298         add             r1, r2
299         asr             r1, #(14 - \bitdepth)
300         mov             r3, #16
301         vdup.16         q8, r1
302         vdup.16         q9, r1
303         vmov.16         q10, q8
304         vmov.16         q11, q8
305         vmov.16         q12, q8
306         vmov.16         q13, q8
307         vmov.16         q14, q8
308         vmov.16         q15, q8
309 1:      subs            r3, #1
310         vstm            r0!, {q8-q15}
311         bne             1b
312         bx              lr
313 endfunc
314 .endm
315
316 .macro sum_sub out, in, c, op
317   .ifc \op, +
318         vmlal.s16       \out, \in, \c
319   .else
320         vmlsl.s16       \out, \in, \c
321   .endif
322 .endm
323
324 .macro tr_4x4 in0, in1, in2, in3, out0, out1, out2, out3, shift, tmp0, tmp1, tmp2, tmp3, tmp4
325          vshll.s16      \tmp0, \in0, #6
326          vmull.s16      \tmp2, \in1, d4[1]
327          vmov           \tmp1, \tmp0
328          vmull.s16      \tmp3, \in1, d4[3]
329          vmlal.s16      \tmp0, \in2, d4[0] @e0
330          vmlsl.s16      \tmp1, \in2, d4[0] @e1
331          vmlal.s16      \tmp2, \in3, d4[3] @o0
332          vmlsl.s16      \tmp3, \in3, d4[1] @o1
333
334          vadd.s32       \tmp4, \tmp0, \tmp2
335          vsub.s32       \tmp0, \tmp0, \tmp2
336          vadd.s32       \tmp2, \tmp1, \tmp3
337          vsub.s32       \tmp1, \tmp1, \tmp3
338          vqrshrn.s32    \out0, \tmp4, #\shift
339          vqrshrn.s32    \out3, \tmp0, #\shift
340          vqrshrn.s32    \out1, \tmp2, #\shift
341          vqrshrn.s32    \out2, \tmp1, #\shift
342 .endm
343
344 .macro tr_4x4_8 in0, in1, in2, in3, out0, out1, out2, out3, tmp0, tmp1, tmp2, tmp3
345          vshll.s16      \tmp0, \in0, #6
346          vld1.s16       {\in0}, [r1, :64]!
347          vmov           \tmp1, \tmp0
348          vmull.s16      \tmp2, \in1, \in0[1]
349          vmull.s16      \tmp3, \in1, \in0[3]
350          vmlal.s16      \tmp0, \in2, \in0[0] @e0
351          vmlsl.s16      \tmp1, \in2, \in0[0] @e1
352          vmlal.s16      \tmp2, \in3, \in0[3] @o0
353          vmlsl.s16      \tmp3, \in3, \in0[1] @o1
354
355          vld1.s16       {\in0}, [r1, :64]
356
357          vadd.s32       \out0, \tmp0, \tmp2
358          vadd.s32       \out1, \tmp1, \tmp3
359          vsub.s32       \out2, \tmp1, \tmp3
360          vsub.s32       \out3, \tmp0, \tmp2
361
362          sub            r1,  r1,  #8
363 .endm
364
365 @ Do a 4x4 transpose, using q registers for the subtransposes that don't
366 @ need to address the indiviudal d registers.
367 @ r0,r1 == rq0, r2,r3 == rq1
368 .macro transpose_4x4 rq0, rq1, r0, r1, r2, r3
369         vtrn.32         \rq0, \rq1
370         vtrn.16         \r0,  \r1
371         vtrn.16         \r2,  \r3
372 .endm
373
374 .macro idct_4x4 bitdepth
375 function ff_hevc_idct_4x4_\bitdepth\()_neon, export=1
376 @r0 - coeffs
377         vld1.s16        {q0-q1}, [r0, :128]
378
379         movrel          r1, trans
380         vld1.s16        {d4}, [r1, :64]
381
382         tr_4x4          d0, d1, d2, d3, d16, d17, d18, d19, 7, q10, q11, q12, q13, q0
383         transpose_4x4   q8, q9, d16, d17, d18, d19
384
385         tr_4x4          d16, d17, d18, d19, d0, d1, d2, d3, 20 - \bitdepth, q10, q11, q12, q13, q0
386         transpose_4x4   q0, q1, d0, d1, d2, d3
387         vst1.s16        {d0-d3}, [r0, :128]
388         bx lr
389 endfunc
390 .endm
391
392 .macro transpose8_4x4 r0, r1, r2, r3
393         vtrn.16         \r0,  \r1
394         vtrn.16         \r2,  \r3
395         vtrn.32         \r0,  \r2
396         vtrn.32         \r1,  \r3
397 .endm
398
399 .macro transpose_8x8 r0, r1, r2, r3, r4, r5, r6, r7, l0, l1, l2, l3, l4, l5, l6, l7
400         transpose8_4x4  \r0, \r1, \r2, \r3
401         transpose8_4x4  \r4, \r5, \r6, \r7
402
403         transpose8_4x4  \l0, \l1, \l2, \l3
404         transpose8_4x4  \l4, \l5, \l6, \l7
405 .endm
406
407 .macro tr_8x4 shift, in0, in1, in2, in3, in4, in5, in6, in7
408         tr_4x4_8        \in0, \in2, \in4, \in6, q8, q9, q10, q11, q12, q13, q14, q15
409
410         vmull.s16       q14, \in1, \in0[2]
411         vmull.s16       q12, \in1, \in0[0]
412         vmull.s16       q13, \in1, \in0[1]
413         sum_sub         q14, \in3, \in0[0], -
414         sum_sub         q12, \in3, \in0[1], +
415         sum_sub         q13, \in3, \in0[3], -
416
417         sum_sub         q14, \in5, \in0[3], +
418         sum_sub         q12, \in5, \in0[2], +
419         sum_sub         q13, \in5, \in0[0], -
420
421         sum_sub         q14, \in7, \in0[1], +
422         sum_sub         q12, \in7, \in0[3], +
423         sum_sub         q13, \in7, \in0[2], -
424
425         vadd.s32        q15, q10, q14
426         vsub.s32        q10, q10, q14
427         vqrshrn.s32     \in2, q15, \shift
428
429         vmull.s16       q15, \in1, \in0[3]
430         sum_sub         q15, \in3, \in0[2], -
431         sum_sub         q15, \in5, \in0[1], +
432         sum_sub         q15, \in7, \in0[0], -
433
434         vqrshrn.s32     \in5, q10,  \shift
435
436         vadd.s32        q10, q8, q12
437         vsub.s32        q8,  q8, q12
438         vadd.s32        q12, q9, q13
439         vsub.s32        q9,  q9, q13
440         vadd.s32        q14, q11, q15
441         vsub.s32        q11, q11, q15
442
443         vqrshrn.s32     \in0, q10, \shift
444         vqrshrn.s32     \in7, q8,  \shift
445         vqrshrn.s32     \in1, q12, \shift
446         vqrshrn.s32     \in6, q9,  \shift
447         vqrshrn.s32     \in3, q14, \shift
448         vqrshrn.s32     \in4, q11, \shift
449 .endm
450
451 .macro idct_8x8 bitdepth
452 function ff_hevc_idct_8x8_\bitdepth\()_neon, export=1
453 @r0 - coeffs
454         vpush           {q4-q7}
455
456         mov             r1,  r0
457         mov             r2,  #64
458         add             r3,  r0,  #32
459         vld1.s16        {q0-q1}, [r1,:128], r2
460         vld1.s16        {q2-q3}, [r3,:128], r2
461         vld1.s16        {q4-q5}, [r1,:128], r2
462         vld1.s16        {q6-q7}, [r3,:128], r2
463
464         movrel          r1, trans
465
466         tr_8x4          7, d0, d2, d4, d6, d8, d10, d12, d14
467         tr_8x4          7, d1, d3, d5, d7, d9, d11, d13, d15
468
469         @ Transpose each 4x4 block, and swap how d4-d7 and d8-d11 are used.
470         @ Layout before:
471         @ d0  d1
472         @ d2  d3
473         @ d4  d5
474         @ d6  d7
475         @ d8  d9
476         @ d10 d11
477         @ d12 d13
478         @ d14 d15
479         transpose_8x8   d0, d2, d4, d6, d8, d10, d12, d14, d1, d3, d5, d7, d9, d11, d13, d15
480         @ Now the layout is:
481         @ d0  d8
482         @ d2  d10
483         @ d4  d12
484         @ d6  d14
485         @ d1  d9
486         @ d3  d11
487         @ d5  d13
488         @ d7  d15
489
490         tr_8x4          20 - \bitdepth, d0, d2, d4, d6, d1, d3, d5, d7
491         vswp            d0, d8
492         tr_8x4          20 - \bitdepth, d0, d10, d12, d14, d9, d11, d13, d15
493         vswp            d0, d8
494
495         transpose_8x8   d0, d2, d4, d6, d8, d10, d12, d14, d1, d3, d5, d7, d9, d11, d13, d15
496
497         mov             r1,  r0
498         mov             r2,  #64
499         add             r3,  r0,  #32
500         vst1.s16        {q0-q1}, [r1,:128], r2
501         vst1.s16        {q2-q3}, [r3,:128], r2
502         vst1.s16        {q4-q5}, [r1,:128], r2
503         vst1.s16        {q6-q7}, [r3,:128], r2
504
505         vpop            {q4-q7}
506         bx              lr
507 endfunc
508 .endm
509
510 .macro butterfly e, o, tmp_p, tmp_m
511         vadd.s32        \tmp_p, \e, \o
512         vsub.s32        \tmp_m, \e, \o
513 .endm
514
515 .macro tr16_8x4 in0, in1, in2, in3, in4, in5, in6, in7, offset
516         tr_4x4_8        \in0, \in2, \in4, \in6, q8, q9, q10, q11, q12, q13, q14, q15
517
518         vmull.s16       q12, \in1, \in0[0]
519         vmull.s16       q13, \in1, \in0[1]
520         vmull.s16       q14, \in1, \in0[2]
521         vmull.s16       q15, \in1, \in0[3]
522         sum_sub         q12, \in3, \in0[1], +
523         sum_sub         q13, \in3, \in0[3], -
524         sum_sub         q14, \in3, \in0[0], -
525         sum_sub         q15, \in3, \in0[2], -
526
527         sum_sub         q12, \in5, \in0[2], +
528         sum_sub         q13, \in5, \in0[0], -
529         sum_sub         q14, \in5, \in0[3], +
530         sum_sub         q15, \in5, \in0[1], +
531
532         sum_sub         q12, \in7, \in0[3], +
533         sum_sub         q13, \in7, \in0[2], -
534         sum_sub         q14, \in7, \in0[1], +
535         sum_sub         q15, \in7, \in0[0], -
536
537         butterfly       q8,  q12, q0, q7
538         butterfly       q9,  q13, q1, q6
539         butterfly       q10, q14, q2, q5
540         butterfly       q11, q15, q3, q4
541         add             r4,  sp,  #\offset
542         vst1.s32        {q0-q1}, [r4, :128]!
543         vst1.s32        {q2-q3}, [r4, :128]!
544         vst1.s32        {q4-q5}, [r4, :128]!
545         vst1.s32        {q6-q7}, [r4, :128]
546 .endm
547
548 .macro load16 in0, in1, in2, in3, in4, in5, in6, in7
549         vld1.s16        {\in0}, [r1, :64], r2
550         vld1.s16        {\in1}, [r3, :64], r2
551         vld1.s16        {\in2}, [r1, :64], r2
552         vld1.s16        {\in3}, [r3, :64], r2
553         vld1.s16        {\in4}, [r1, :64], r2
554         vld1.s16        {\in5}, [r3, :64], r2
555         vld1.s16        {\in6}, [r1, :64], r2
556         vld1.s16        {\in7}, [r3, :64], r2
557 .endm
558
559 .macro add_member in, t0, t1, t2, t3, t4, t5, t6, t7, op0, op1, op2, op3, op4, op5, op6, op7
560         sum_sub q5,     \in, \t0, \op0
561         sum_sub q6,     \in, \t1, \op1
562         sum_sub q7,     \in, \t2, \op2
563         sum_sub q8,     \in, \t3, \op3
564         sum_sub q9,     \in, \t4, \op4
565         sum_sub q10,    \in, \t5, \op5
566         sum_sub q11,    \in, \t6, \op6
567         sum_sub q12,    \in, \t7, \op7
568 .endm
569
570 .macro butterfly16 in0, in1, in2, in3, in4, in5, in6, in7
571         vadd.s32        q4, \in0, \in1
572         vsub.s32        \in0, \in0, \in1
573         vadd.s32        \in1, \in2, \in3
574         vsub.s32        \in2, \in2, \in3
575         vadd.s32        \in3, \in4, \in5
576         vsub.s32        \in4, \in4, \in5
577         vadd.s32        \in5, \in6, \in7
578         vsub.s32        \in6, \in6, \in7
579 .endm
580
581 .macro store16 in0, in1, in2, in3, in4, in5, in6, in7, rx
582         vst1.s16        \in0, [r1, :64], r2
583         vst1.s16        \in1, [r3, :64], \rx
584         vst1.s16        \in2, [r1, :64], r2
585         vst1.s16        \in3, [r3, :64], \rx
586         vst1.s16        \in4, [r1, :64], r2
587         vst1.s16        \in5, [r3, :64], \rx
588         vst1.s16        \in6, [r1, :64], r2
589         vst1.s16        \in7, [r3, :64], \rx
590 .endm
591
592 .macro scale out0, out1, out2, out3, out4, out5, out6, out7, in0, in1, in2, in3, in4, in5, in6, in7, shift
593         vqrshrn.s32     \out0, \in0, \shift
594         vqrshrn.s32     \out1, \in1, \shift
595         vqrshrn.s32     \out2, \in2, \shift
596         vqrshrn.s32     \out3, \in3, \shift
597         vqrshrn.s32     \out4, \in4, \shift
598         vqrshrn.s32     \out5, \in5, \shift
599         vqrshrn.s32     \out6, \in6, \shift
600         vqrshrn.s32     \out7, \in7, \shift
601 .endm
602
603 @stores in1, in2, in4, in6 ascending from off1 and
604 @stores in1, in3, in5, in7 descending from off2
605 .macro store_to_stack off1, off2, in0, in2, in4, in6, in7, in5, in3, in1
606         add             r1, sp, #\off1
607         add             r3, sp, #\off2
608         mov             r2, #-16
609         vst1.s32        {\in0}, [r1, :128]!
610         vst1.s32        {\in1}, [r3, :128], r2
611         vst1.s32        {\in2}, [r1, :128]!
612         vst1.s32        {\in3}, [r3, :128], r2
613         vst1.s32        {\in4}, [r1, :128]!
614         vst1.s32        {\in5}, [r3, :128], r2
615         vst1.s32        {\in6}, [r1, :128]
616         vst1.s32        {\in7}, [r3, :128]
617 .endm
618
619 .macro tr_16x4 name, shift, offset, step
620 function func_tr_16x4_\name
621         mov             r1,  r5
622         add             r3, r5, #(\step * 64)
623         mov             r2, #(\step * 128)
624         load16          d0, d1, d2, d3, d4, d5, d6, d7
625         movrel          r1, trans
626
627         tr16_8x4        d0, d1, d2, d3, d4, d5, d6, d7, \offset
628
629         add             r1,  r5, #(\step * 32)
630         add             r3,  r5, #(\step * 3 *32)
631         mov             r2,  #(\step * 128)
632         load16          d8, d9, d2, d3, d4, d5, d6, d7
633         movrel          r1, trans + 16
634         vld1.s16        {q0}, [r1, :128]
635         vmull.s16       q5, d8, d0[0]
636         vmull.s16       q6, d8, d0[1]
637         vmull.s16       q7, d8, d0[2]
638         vmull.s16       q8, d8, d0[3]
639         vmull.s16       q9, d8, d1[0]
640         vmull.s16       q10, d8, d1[1]
641         vmull.s16       q11, d8, d1[2]
642         vmull.s16       q12, d8, d1[3]
643
644         add_member      d9, d0[1], d1[0], d1[3], d1[1], d0[2], d0[0], d0[3], d1[2], +, +, +, -, -, -, -, -
645         add_member      d2, d0[2], d1[3], d0[3], d0[1], d1[2], d1[0], d0[0], d1[1], +, +, -, -, -, +, +, +
646         add_member      d3, d0[3], d1[1], d0[1], d1[3], d0[0], d1[2], d0[2], d1[0], +, -, -, +, +, +, -, -
647         add_member      d4, d1[0], d0[2], d1[2], d0[0], d1[3], d0[1], d1[1], d0[3], +, -, -, +, -, -, +, +
648         add_member      d5, d1[1], d0[0], d1[0], d1[2], d0[1], d0[3], d1[3], d0[2], +, -, +, +, -, +, +, -
649         add_member      d6, d1[2], d0[3], d0[0], d0[2], d1[1], d1[3], d1[0], d0[1], +, -, +, -, +, +, -, +
650         add_member      d7, d1[3], d1[2], d1[1], d1[0], d0[3], d0[2], d0[1], d0[0], +, -, +, -, +, -, +, -
651
652         add             r4, sp, #\offset
653         vld1.s32        {q0-q1}, [r4, :128]!
654         vld1.s32        {q2-q3}, [r4, :128]!
655
656         butterfly16     q0, q5, q1, q6, q2, q7, q3, q8
657     .if \shift > 0
658         scale           d26, d27, d28, d29, d30, d31, d16, d17, q4, q0, q5, q1, q6, q2, q7, q3, \shift
659         transpose8_4x4  d26, d28, d30, d16
660         transpose8_4x4  d17, d31, d29, d27
661         mov             r1, r6
662         add             r3, r6, #(24 +3*32)
663         mov             r2, #32
664         mov             r4, #-32
665         store16         d26, d27, d28, d29, d30, d31, d16, d17, r4
666     .else
667         store_to_stack  \offset, (\offset + 240), q4, q5, q6, q7, q3, q2, q1, q0
668     .endif
669
670         add             r4, sp, #(\offset + 64)
671         vld1.s32        {q0-q1}, [r4, :128]!
672         vld1.s32        {q2-q3}, [r4, :128]
673         butterfly16     q0, q9, q1, q10, q2, q11, q3, q12
674     .if \shift > 0
675         scale           d26, d27, d28, d29, d30, d31, d8, d9, q4, q0, q9, q1, q10, q2, q11, q3, \shift
676         transpose8_4x4  d26, d28, d30, d8
677         transpose8_4x4  d9, d31, d29, d27
678
679         add             r1, r6, #8
680         add             r3, r6, #(16 + 3 * 32)
681         mov             r2, #32
682         mov             r4, #-32
683         store16         d26, d27, d28, d29, d30, d31, d8, d9, r4
684     .else
685         store_to_stack (\offset + 64), (\offset + 176), q4, q9, q10, q11, q3, q2, q1, q0
686     .endif
687
688         bx              lr
689 endfunc
690 .endm
691
692 .macro idct_16x16 bitdepth
693 function ff_hevc_idct_16x16_\bitdepth\()_neon, export=1
694 @r0 - coeffs
695         push            {r4-r7, lr}
696         vpush           {q4-q7}
697
698         @ Align the stack, allocate a temp buffer
699 T       mov             r7,  sp
700 T       and             r7,  r7,  #15
701 A       and             r7,  sp,  #15
702         add             r7,  r7,  #640
703         sub             sp,  sp,  r7
704
705 .irp i, 0, 1, 2, 3
706         add             r5, r0, #(8 * \i)
707         add             r6, sp, #(8 * \i * 16)
708         bl              func_tr_16x4_firstpass
709 .endr
710
711 .irp i, 0, 1, 2, 3
712         add             r5, sp, #(8 * \i)
713         add             r6, r0, #(8 * \i * 16)
714         bl              func_tr_16x4_secondpass_\bitdepth
715 .endr
716
717         add             sp,  sp,  r7
718
719         vpop            {q4-q7}
720         pop             {r4-r7, pc}
721 endfunc
722 .endm
723
724 .macro load32
725         add             r1,  r5, #64
726         add             r3,  r1, #128
727         mov             r2,  #256
728         vld1.s16        {d4}, [r1, :64], r2
729         vld1.s16        {d5}, [r3, :64], r2
730         vld1.s16        {d6}, [r1, :64], r2
731         vld1.s16        {d7}, [r3, :64], r2
732         vld1.s16        {d8}, [r1, :64], r2
733         vld1.s16        {d9}, [r3, :64], r2
734         vld1.s16        {d10}, [r1, :64], r2
735         vld1.s16        {d11}, [r3, :64], r2
736         vld1.s16        {d12}, [r1, :64], r2
737         vld1.s16        {d13}, [r3, :64], r2
738         vld1.s16        {d14}, [r1, :64], r2
739         vld1.s16        {d15}, [r3, :64], r2
740         vld1.s16        {d16}, [r1, :64], r2
741         vld1.s16        {d17}, [r3, :64], r2
742         vld1.s16        {d18}, [r1, :64], r2
743         vld1.s16        {d19}, [r3, :64], r2
744 .endm
745
746 .macro add_member32 in, t0, t1, t2, t3, op0, op1, op2, op3
747         sum_sub q10,     \in, \t0, \op0
748         sum_sub q11,     \in, \t1, \op1
749         sum_sub q12,     \in, \t2, \op2
750         sum_sub q13,     \in, \t3, \op3
751 .endm
752
753 .macro butterfly32 in0, in1, in2, in3
754         vadd.s32        q1, \in0, \in1
755         vsub.s32        \in0, \in0, \in1
756         vadd.s32        \in1, \in2, \in3
757         vsub.s32        \in2, \in2, \in3
758 .endm
759
760 .macro scale32 out0, out1, out2, out3, in0, in1, in2, in3, shift
761         vqrshrn.s32     \out0, \in0, \shift
762         vqrshrn.s32     \out1, \in1, \shift
763         vqrshrn.s32     \out2, \in2, \shift
764         vqrshrn.s32     \out3, \in3, \shift
765 .endm
766
767 .macro multiply in
768         vmull.s16       q10, d4, \in[0]
769         vmull.s16       q11, d4, \in[1]
770         vmull.s16       q12, d4, \in[2]
771         vmull.s16       q13, d4, \in[3]
772 .endm
773
774 .macro scale_store shift
775         vld1.s16        {q14-q15}, [r4, :128]!
776         butterfly32     q14, q10, q15, q11
777         scale32         d22, d23, d20, d21, q1, q14, q10, q15, \shift
778
779         vld1.s16        {q14-q15}, [r4, :128]!
780         butterfly32     q14, q12, q15, q13
781         scale32         d2, d3, d28, d29, q1, q14, q12, q15, \shift
782         transpose8_4x4  d22, d20, d2, d28
783         transpose8_4x4  d29, d3, d21, d23
784         store16         d22, d23, d20, d21, d2, d3, d28, d29, r8
785
786         @ reload multiplication coefficiens to q1
787         vld1.s16        {q1}, [r9, :128]
788 .endm
789
790 function tr_block1
791         multiply        d0
792         add_member32    d5,  d0[1], d1[0], d1[3], d2[2], +, +, +, +
793         add_member32    d6,  d0[2], d1[3], d3[0], d3[2], +, +, +, -
794         add_member32    d7,  d0[3], d2[2], d3[2], d1[3], +, +, -, -
795         add_member32    d8,  d1[0], d3[1], d2[1], d0[0], +, +, -, -
796         add_member32    d9,  d1[1], d3[3], d1[0], d1[2], +, -, -, -
797         add_member32    d10, d1[2], d3[0], d0[0], d3[1], +, -, -, -
798         add_member32    d11, d1[3], d2[1], d1[1], d2[3], +, -, -, +
799         add_member32    d12, d2[0], d1[2], d2[2], d1[0], +, -, -, +
800         add_member32    d13, d2[1], d0[3], d3[3], d0[2], +, -, -, +
801         add_member32    d14, d2[2], d0[1], d2[3], d2[1], +, -, +, +
802         add_member32    d15, d2[3], d0[2], d1[2], d3[3], +, -, +, -
803         add_member32    d16, d3[0], d1[1], d0[1], d2[0], +, -, +, -
804         add_member32    d17, d3[1], d2[0], d0[3], d0[1], +, -, +, -
805         add_member32    d18, d3[2], d2[3], d2[0], d1[1], +, -, +, -
806         add_member32    d19, d3[3], d3[2], d3[1], d3[0], +, -, +, -
807         bx              lr
808 endfunc
809
810 function tr_block2
811         multiply        d1
812         add_member32    d5,  d3[1], d3[3], d3[0], d2[1], +, -, -, -
813         add_member32    d6,  d2[1], d1[0], d0[0], d1[1], -, -, -, -
814         add_member32    d7,  d0[0], d1[2], d3[1], d2[3], -, -, -, +
815         add_member32    d8,  d2[0], d3[2], d1[1], d0[3], -, +, +, +
816         add_member32    d9,  d3[2], d0[3], d1[3], d3[1], +, +, +, -
817         add_member32    d10, d1[1], d1[3], d2[3], d0[0], +, +, -, -
818         add_member32    d11, d0[3], d3[1], d0[1], d3[3], +, -, -, +
819         add_member32    d12, d3[0], d0[2], d3[2], d0[1], +, -, -, +
820         add_member32    d13, d2[2], d2[0], d1[0], d3[2], -, -, +, +
821         add_member32    d14, d0[1], d3[0], d2[0], d0[2], -, +, +, -
822         add_member32    d15, d1[3], d0[1], d2[2], d3[0], -, +, -, -
823         add_member32    d16, d3[3], d2[1], d0[2], d1[0], +, +, -, +
824         add_member32    d17, d1[2], d2[3], d3[3], d2[2], +, -, -, +
825         add_member32    d18, d0[2], d0[1], d0[3], d1[2], +, -, +, -
826         add_member32    d19, d2[3], d2[2], d2[1], d2[0], +, -, +, -
827         bx              lr
828 endfunc
829
830 function tr_block3
831         multiply        d2
832         add_member32    d5,  d1[2], d0[3], d0[0], d0[2], -, -, -, -
833         add_member32    d6,  d2[2], d3[3], d2[3], d1[2], -, -, +, +
834         add_member32    d7,  d1[0], d0[2], d2[1], d3[3], +, +, +, -
835         add_member32    d8,  d3[0], d2[2], d0[1], d1[3], +, -, -, -
836         add_member32    d9,  d0[2], d2[0], d3[0], d0[0], -, -, +, +
837         add_member32    d10, d3[2], d1[0], d2[0], d2[2], -, +, +, -
838         add_member32    d11, d0[0], d3[2], d0[2], d3[0], +, +, -, -
839         add_member32    d12, d3[3], d0[1], d3[1], d0[3], -, -, +, +
840         add_member32    d13, d0[1], d2[3], d1[3], d1[1], -, +, +, -
841         add_member32    d14, d3[1], d1[3], d0[3], d3[2], +, +, -, +
842         add_member32    d15, d0[3], d1[1], d3[2], d2[0], +, -, +, +
843         add_member32    d16, d2[3], d3[1], d1[2], d0[1], -, -, +, -
844         add_member32    d17, d1[1], d0[0], d1[0], d2[1], -, +, -, +
845         add_member32    d18, d2[1], d3[0], d3[3], d3[1], +, -, +, +
846         add_member32    d19, d1[3], d1[2], d1[1], d1[0], +, -, +, -
847         bx              lr
848 endfunc
849
850 function tr_block4
851         multiply        d3
852         add_member32    d5,  d1[1], d2[0], d2[3], d3[2], -, -, -, -
853         add_member32    d6,  d0[0], d0[3], d2[0], d3[1], +, +, +, +
854         add_member32    d7,  d2[0], d0[0], d1[1], d3[0], -, -, -, -
855         add_member32    d8,  d3[3], d1[2], d0[2], d2[3], +, +, +, +
856         add_member32    d9,  d2[1], d2[3], d0[0], d2[2], +, -, -, -
857         add_member32    d10, d0[2], d3[3], d0[3], d2[1], -, -, +, +
858         add_member32    d11, d1[0], d2[2], d1[2], d2[0], +, +, -, -
859         add_member32    d12, d2[3], d1[1], d2[1], d1[3], -, -, +, +
860         add_member32    d13, d3[1], d0[1], d3[0], d1[2], -, +, -, -
861         add_member32    d14, d1[2], d1[0], d3[3], d1[1], +, -, +, +
862         add_member32    d15, d0[1], d2[1], d3[1], d1[0], -, +, +, -
863         add_member32    d16, d1[3], d3[2], d2[2], d0[3], +, -, -, +
864         add_member32    d17, d3[2], d3[0], d1[3], d0[2], -, -, +, -
865         add_member32    d18, d2[2], d1[3], d1[0], d0[1], -, +, -, +
866         add_member32    d19, d0[3], d0[2], d0[1], d0[0], +, -, +, -
867         bx              lr
868 endfunc
869
870 .macro tr_32x4 name, shift
871 function func_tr_32x4_\name
872         mov             r10, lr
873         bl              func_tr_16x4_noscale
874
875         load32
876         movrel          r9, trans + 32
877         vld1.s16        {q0}, [r9, :128]!
878         vld1.s16        {q1}, [r9, :128]
879
880         bl              tr_block1
881
882         add             r4, sp, #2048
883         vld1.s16        {q14-q15}, [r4, :128]!
884         butterfly32     q14, q10, q15, q11
885         scale32         d22, d23, d20, d21, q1, q14, q10, q15, \shift
886
887         vld1.s16        {q14-q15}, [r4, :128]!
888         butterfly32     q14, q12, q15, q13
889         scale32         d2, d3, d28, d29, q1, q14, q12, q15, \shift
890
891         transpose8_4x4  d22, d20, d2, d28
892         transpose8_4x4  d29, d3, d21, d23
893         mov             r1, r11
894         mov             r2, #64
895         mov             r8, #-64
896         add             r3, r11, #(56 + 3 * 64)
897         store16         d22, d23, d20, d21, d2, d3, d28, d29, r8
898
899         @ reload multiplication coefficiens to q1
900         vld1.s16        {q1}, [r9, :128]
901
902         bl              tr_block2
903         add             r1, r11, #8
904         add             r3, r11, #(48 + 3 * 64)
905         mov             r2, #64
906         mov             r8, #-64
907         scale_store     \shift
908
909         bl              tr_block3
910         add             r1, r11, #16
911         add             r3, r11, #(40 + 3 * 64)
912         mov             r2, #64
913         mov             r8, #-64
914         scale_store     \shift
915
916         bl              tr_block4
917         add             r1, r11, #24
918         add             r3, r11, #(32 + 3 * 64)
919         mov             r2, #64
920         mov             r8, #-64
921         scale_store     \shift
922
923         bx               r10
924 endfunc
925 .endm
926
927 .macro idct_32x32 bitdepth
928 function ff_hevc_idct_32x32_\bitdepth\()_neon, export=1
929 @r0 - coeffs
930         push            {r4-r11, lr}
931         vpush           {q4-q7}
932
933         @ Align the stack, allocate a temp buffer
934 T       mov             r7,  sp
935 T       and             r7,  r7,  #15
936 A       and             r7,  sp,  #15
937         add             r7,  r7,  #2432
938         sub             sp,  sp,  r7
939
940 .irp i, 0, 1, 2, 3, 4, 5, 6, 7
941         add             r5, r0, #(8 * \i)
942         add             r11, sp, #(8 * \i * 32)
943         bl              func_tr_32x4_firstpass
944 .endr
945
946 .irp i, 0, 1, 2, 3, 4, 5, 6, 7
947         add             r5, sp, #(8 * \i)
948         add             r11, r0, #(8 * \i * 32)
949         bl              func_tr_32x4_secondpass_\bitdepth
950 .endr
951
952         add             sp,  sp,  r7
953         vpop            {q4-q7}
954         pop             {r4-r11, pc}
955 endfunc
956 .endm
957
958 tr_16x4 firstpass, 7, 512, 1
959 tr_16x4 secondpass_8, 20 - 8, 512, 1
960 tr_16x4 secondpass_10, 20 - 10, 512, 1
961 tr_16x4 noscale, 0, 2048, 4
962 .ltorg
963 tr_32x4 firstpass, 7
964 tr_32x4 secondpass_8, 20 - 8
965 tr_32x4 secondpass_10, 20 - 10
966 .ltorg
967
968 idct_4x4 8
969 idct_4x4_dc 8
970 idct_4x4 10
971 idct_4x4_dc 10
972 idct_8x8 8
973 idct_8x8_dc 8
974 idct_8x8 10
975 idct_8x8_dc 10
976 idct_16x16 8
977 idct_16x16_dc 8
978 idct_16x16 10
979 idct_16x16_dc 10
980 idct_32x32 8
981 idct_32x32_dc 8
982 idct_32x32 10
983 idct_32x32_dc 10
984
985 /* uses registers q2 - q9 for temp values */
986 /* TODO: reorder */
987 .macro tr4_luma_shift r0, r1, r2, r3, shift
988         vaddl.s16   q5, \r0, \r2    // c0 = src0 + src2
989         vaddl.s16   q2, \r2, \r3    // c1 = src2 + src3
990         vsubl.s16   q4, \r0, \r3    // c2 = src0 - src3
991         vmull.s16   q6, \r1, d0[0]  // c3 = 74 * src1
992
993         vaddl.s16   q7, \r0, \r3    // src0 + src3
994         vsubw.s16   q7, q7, \r2     // src0 - src2 + src3
995         vmul.s32    q7, q7, d0[0]   // dst2 = 74 * (src0 - src2 + src3)
996
997         vmul.s32    q8, q5, d0[1]   // 29 * c0
998         vmul.s32    q9, q2, d1[0]   // 55 * c1
999         vadd.s32    q8, q9          // 29 * c0 + 55 * c1
1000         vadd.s32    q8, q6          // dst0 = 29 * c0 + 55 * c1 + c3
1001
1002         vmul.s32    q2, q2, d0[1]   // 29 * c1
1003         vmul.s32    q9, q4, d1[0]   // 55 * c2
1004         vsub.s32    q9, q2          // 55 * c2 - 29 * c1
1005         vadd.s32    q9, q6          // dst1 = 55 * c2 - 29 * c1 + c3
1006
1007         vmul.s32    q5, q5, d1[0]   // 55 * c0
1008         vmul.s32    q4, q4, d0[1]   // 29 * c2
1009         vadd.s32    q5, q4          // 55 * c0 + 29 * c2
1010         vsub.s32    q5, q6          // dst3 = 55 * c0 + 29 * c2 - c3
1011
1012         vqrshrn.s32   \r0, q8, \shift
1013         vqrshrn.s32   \r1, q9, \shift
1014         vqrshrn.s32   \r2, q7, \shift
1015         vqrshrn.s32   \r3, q5, \shift
1016 .endm
1017
1018 .ltorg
1019 function ff_hevc_transform_luma_4x4_neon_8, export=1
1020         vpush       {d8-d15}
1021         vld1.16     {q14, q15}, [r0]  // coeffs
1022         ldr         r3, =0x4a  // 74
1023         vmov.32     d0[0], r3
1024         ldr         r3, =0x1d  // 29
1025         vmov.32     d0[1], r3
1026         ldr         r3, =0x37  // 55
1027         vmov.32     d1[0], r3
1028
1029         tr4_luma_shift d28, d29, d30, d31, #7
1030
1031         vtrn.16     d28, d29
1032         vtrn.16     d30, d31
1033         vtrn.32     q14, q15
1034
1035         tr4_luma_shift d28, d29, d30, d31, #12
1036
1037         vtrn.16     d28, d29
1038         vtrn.16     d30, d31
1039         vtrn.32     q14, q15
1040         vst1.16     {q14, q15}, [r0]
1041         vpop        {d8-d15}
1042         bx lr
1043 endfunc