lavc/htmlsubtitles: handle colors starting with many '#'
[ffmpeg.git] / libavcodec / arm / vp9itxfm_16bpp_neon.S
1 /*
2  * Copyright (c) 2017 Google Inc.
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 #include "libavutil/arm/asm.S"
22 #include "neon.S"
23
24 const itxfm4_coeffs, align=4
25         .short  11585, 0, 6270, 15137
26 iadst4_coeffs:
27         .short  5283, 15212, 9929, 13377
28 endconst
29
30 const iadst8_coeffs, align=4
31         .short  16305, 1606, 14449, 7723, 10394, 12665, 4756, 15679
32 idct_coeffs:
33         .short  11585, 0, 6270, 15137, 3196, 16069, 13623, 9102
34         .short  1606, 16305, 12665, 10394, 7723, 14449, 15679, 4756
35         .short  804, 16364, 12140, 11003, 7005, 14811, 15426, 5520
36         .short  3981, 15893, 14053, 8423, 9760, 13160, 16207, 2404
37 endconst
38
39 const iadst16_coeffs, align=4
40         .short  16364, 804, 15893, 3981, 11003, 12140, 8423, 14053
41         .short  14811, 7005, 13160, 9760, 5520, 15426, 2404, 16207
42 endconst
43
44 @ Do two 4x4 transposes, using q registers for the subtransposes that don't
45 @ need to address the individual d registers.
46 @ r0,r1 == rq1, r2,r3 == rq1, etc
47 .macro transpose32_q_2x_4x4 rq0, rq1, rq2, rq3, rq4, rq5, rq6, rq7, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15
48         vswp             \r1,  \r4  @ vtrn.64 \rq0, \rq2
49         vswp             \r3,  \r6  @ vtrn.64 \rq1, \rq3
50         vswp             \r9,  \r12 @ vtrn.64 \rq4, \rq6
51         vswp             \r11, \r14 @ vtrn.64 \rq5, \rq7
52         vtrn.32          \rq0, \rq1
53         vtrn.32          \rq2, \rq3
54         vtrn.32          \rq4, \rq5
55         vtrn.32          \rq6, \rq7
56 .endm
57
58 @ Do eight 2x2 transposes.
59 .macro transpose32_8x_2x2 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15
60         vtrn.32          \r0,  \r1
61         vtrn.32          \r2,  \r3
62         vtrn.32          \r4,  \r5
63         vtrn.32          \r6,  \r7
64         vtrn.32          \r8,  \r9
65         vtrn.32          \r10, \r11
66         vtrn.32          \r12, \r13
67         vtrn.32          \r14, \r15
68 .endm
69
70 @ out1 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14
71 @ out2 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14
72 @ in/out are d registers
73 .macro mbutterfly0 out1, out2, in1, in2, tmpd1, tmpd2, tmpq3, tmpq4, neg=0
74         vadd.s32        \tmpd1, \in1,  \in2
75         vsub.s32        \tmpd2, \in1,  \in2
76 .if \neg > 0
77         vneg.s32        \tmpd1, \tmpd1
78 .endif
79         vmull.s32       \tmpq3, \tmpd1, d0[0]
80         vmull.s32       \tmpq4, \tmpd2, d0[0]
81         vrshrn.s64      \out1, \tmpq3, #14
82         vrshrn.s64      \out2, \tmpq4, #14
83 .endm
84
85 @ Same as mbutterfly0 above, but treating the input in in2 as zero,
86 @ writing the same output into both out1 and out2.
87 .macro mbutterfly0_h out1, out2, in1, in2, tmpd1, tmpd2, tmpq3, tmpq4
88         vmull.s32       \tmpq3, \in1, d0[0]
89         vrshrn.s64      \out1, \tmpq3, #14
90         vrshrn.s64      \out2, \tmpq3, #14
91 .endm
92
93 @ out1,out2 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14
94 @ out3,out4 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14
95 @ Same as mbutterfly0, but with input being 2 q registers, output
96 @ being 4 d registers.
97 @ This can do with either 4 or 6 temporary q registers.
98 .macro dmbutterfly0 out1, out2, out3, out4, in1, in2, tmpq1, tmpq2, tmpd11, tmpd12, tmpd21, tmpd22, tmpq3, tmpq4, tmpq5, tmpq6
99         vadd.s32        \tmpq1, \in1,  \in2
100         vsub.s32        \tmpq2, \in1,  \in2
101         vmull.s32       \tmpq3, \tmpd11, d0[0]
102         vmull.s32       \tmpq4, \tmpd12, d0[0]
103 .ifb \tmpq5
104         vrshrn.s64      \out1, \tmpq3, #14
105         vrshrn.s64      \out2, \tmpq4, #14
106         vmull.s32       \tmpq3, \tmpd21, d0[0]
107         vmull.s32       \tmpq4, \tmpd22, d0[0]
108         vrshrn.s64      \out3, \tmpq3, #14
109         vrshrn.s64      \out4, \tmpq4, #14
110 .else
111         vmull.s32       \tmpq5, \tmpd21, d0[0]
112         vmull.s32       \tmpq6, \tmpd22, d0[0]
113         vrshrn.s64      \out1, \tmpq3, #14
114         vrshrn.s64      \out2, \tmpq4, #14
115         vrshrn.s64      \out3, \tmpq5, #14
116         vrshrn.s64      \out4, \tmpq6, #14
117 .endif
118 .endm
119
120 @ out1 = in1 * coef1 - in2 * coef2
121 @ out2 = in1 * coef2 + in2 * coef1
122 @ out are 2 q registers, in are 2 d registers
123 .macro mbutterfly_l out1, out2, in1, in2, coef1, coef2, neg=0
124         vmull.s32       \out1, \in1, \coef1
125         vmlsl.s32       \out1, \in2, \coef2
126 .if \neg
127         vmov.s64        \out2, #0
128         vmlsl.s32       \out2, \in1, \coef2
129         vmlsl.s32       \out2, \in2, \coef1
130 .else
131         vmull.s32       \out2, \in1, \coef2
132         vmlal.s32       \out2, \in2, \coef1
133 .endif
134 .endm
135
136 @ out1,out2 = in1,in2 * coef1 - in3,in4 * coef2
137 @ out3,out4 = in1,in2 * coef2 + in3,in4 * coef1
138 @ out are 4 q registers, in are 4 d registers
139 .macro dmbutterfly_l out1, out2, out3, out4, in1, in2, in3, in4, coef1, coef2
140         vmull.s32       \out1, \in1, \coef1
141         vmull.s32       \out2, \in2, \coef1
142         vmull.s32       \out3, \in1, \coef2
143         vmull.s32       \out4, \in2, \coef2
144         vmlsl.s32       \out1, \in3, \coef2
145         vmlsl.s32       \out2, \in4, \coef2
146         vmlal.s32       \out3, \in3, \coef1
147         vmlal.s32       \out4, \in4, \coef1
148 .endm
149
150 @ inout1 = (inout1 * coef1 - inout2 * coef2 + (1 << 13)) >> 14
151 @ inout2 = (inout1 * coef2 + inout2 * coef1 + (1 << 13)) >> 14
152 @ inout are 2 d registers, tmp are 2 q registers
153 .macro mbutterfly inout1, inout2, coef1, coef2, tmp1, tmp2, neg=0
154         mbutterfly_l    \tmp1, \tmp2, \inout1, \inout2, \coef1, \coef2, \neg
155         vrshrn.s64      \inout1, \tmp1,  #14
156         vrshrn.s64      \inout2, \tmp2,  #14
157 .endm
158
159 @ Same as mbutterfly above, but treating the input in inout2 as zero
160 .macro mbutterfly_h1 inout1, inout2, coef1, coef2, tmp1, tmp2
161         vmull.s32       \tmp1,   \inout1, \coef1
162         vmull.s32       \tmp2,   \inout1, \coef2
163         vrshrn.s64      \inout1, \tmp1,   #14
164         vrshrn.s64      \inout2, \tmp2,   #14
165 .endm
166
167 @ Same as mbutterfly above, but treating the input in inout1 as zero
168 .macro mbutterfly_h2 inout1, inout2, coef1, coef2, tmp1, tmp2
169         vmov.s64        \tmp1,   #0
170         vmull.s32       \tmp2,   \inout2, \coef1
171         vmlsl.s32       \tmp1,   \inout2, \coef2
172         vrshrn.s64      \inout2, \tmp2,   #14
173         vrshrn.s64      \inout1, \tmp1,   #14
174 .endm
175
176 @ inout1,inout2 = (inout1,inout2 * coef1 - inout3,inout4 * coef2 + (1 << 13)) >> 14
177 @ inout3,inout4 = (inout1,inout2 * coef2 + inout3,inout4 * coef1 + (1 << 13)) >> 14
178 @ inout are 4 d registers, tmp are 4 q registers
179 .macro dmbutterfly inout1, inout2, inout3, inout4, coef1, coef2, tmp1, tmp2, tmp3, tmp4
180         dmbutterfly_l   \tmp1, \tmp2, \tmp3, \tmp4, \inout1, \inout2, \inout3, \inout4, \coef1, \coef2
181         vrshrn.s64      \inout1, \tmp1,  #14
182         vrshrn.s64      \inout2, \tmp2,  #14
183         vrshrn.s64      \inout3, \tmp3,  #14
184         vrshrn.s64      \inout4, \tmp4,  #14
185 .endm
186
187 @ out1 = in1 + in2
188 @ out2 = in1 - in2
189 .macro butterfly out1, out2, in1, in2
190         vadd.s32        \out1, \in1, \in2
191         vsub.s32        \out2, \in1, \in2
192 .endm
193
194 @ out1 = in1 - in2
195 @ out2 = in1 + in2
196 .macro butterfly_r out1, out2, in1, in2
197         vsub.s32        \out1, \in1, \in2
198         vadd.s32        \out2, \in1, \in2
199 .endm
200
201 @ out1 = (in1 + in2 + (1 << 13)) >> 14
202 @ out2 = (in1 - in2 + (1 << 13)) >> 14
203 @ out are 2 d registers, in are 2 q registers, tmp are 2 q registers
204 .macro butterfly_n out1, out2, in1, in2, tmp1, tmp2
205         vadd.s64        \tmp1, \in1, \in2
206         vsub.s64        \tmp2, \in1, \in2
207         vrshrn.s64      \out1, \tmp1,  #14
208         vrshrn.s64      \out2, \tmp2,  #14
209 .endm
210
211 @ out1,out2 = (in1,in2 + in3,in4 + (1 << 13)) >> 14
212 @ out3,out4 = (in1,in2 - in3,in4 + (1 << 13)) >> 14
213 @ out are 4 d registers, in are 4 q registers, tmp are 4 q registers
214 .macro dbutterfly_n out1, out2, out3, out4, in1, in2, in3, in4, tmp1, tmp2, tmp3, tmp4
215         vadd.s64        \tmp1, \in1, \in3
216         vadd.s64        \tmp2, \in2, \in4
217         vsub.s64        \tmp3, \in1, \in3
218         vsub.s64        \tmp4, \in2, \in4
219         vrshrn.s64      \out1, \tmp1,  #14
220         vrshrn.s64      \out2, \tmp2,  #14
221         vrshrn.s64      \out3, \tmp3,  #14
222         vrshrn.s64      \out4, \tmp4,  #14
223 .endm
224
225
226 .macro iwht4_10 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
227         vadd.i32        \c0,  \c0,  \c1
228         vsub.i32        q11,  \c2,  \c3
229         vsub.i32        q10,  \c0,  q11
230         vshr.s32        q10,  q10,  #1
231         vsub.i32        \c2,  q10,  \c1
232         vsub.i32        \c1,  q10,  \c3
233         vadd.i32        \c3,  q11,  \c2
234         vsub.i32        \c0,  \c0,  \c1
235 .endm
236
237 .macro iwht4_12 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
238         iwht4_10        \c0, \c1, \c2, \c3, \cd0, \cd1, \cd2, \cd3, \cd4, \cd5, \cd6, \cd7
239 .endm
240
241 @ c0 == cd0,cd1, c1 == cd2,cd3
242 .macro idct4_10 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
243         vmul.s32        q13,  \c1,  d1[1]
244         vmul.s32        q11,  \c1,  d1[0]
245         vadd.i32        q14,  \c0,  \c2
246         vsub.i32        q15,  \c0,  \c2
247         vmla.s32        q13,  \c3,  d1[0]
248         vmul.s32        q12,  q14,  d0[0]
249         vmul.s32        q10,  q15,  d0[0]
250         vmls.s32        q11,  \c3,  d1[1]
251         vrshr.s32       q13,  q13,  #14
252         vrshr.s32       q12,  q12,  #14
253         vrshr.s32       q10,  q10,  #14
254         vrshr.s32       q11,  q11,  #14
255         vadd.i32        \c0,  q12,  q13
256         vsub.i32        \c3,  q12,  q13
257         vadd.i32        \c1,  q10,  q11
258         vsub.i32        \c2,  q10,  q11
259 .endm
260
261 .macro idct4_12 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
262         vmull.s32       q13,  \cd2, d1[1]
263         vmull.s32       q15,  \cd3, d1[1]
264         vmull.s32       q11,  \cd2, d1[0]
265         vmull.s32       q3,   \cd3, d1[0]
266         vadd.i32        q14,  \c0,  \c2
267         vsub.i32        q2,   \c0,  \c2
268         vmlal.s32       q13,  \cd6, d1[0]
269         vmlal.s32       q15,  \cd7, d1[0]
270         vmull.s32       q12,  d28,  d0[0]
271         vmull.s32       q14,  d29,  d0[0]
272         vmull.s32       q10,  d4,   d0[0]
273         vmull.s32       q8,   d5,   d0[0]
274         vmlsl.s32       q11,  \cd6, d1[1]
275         vmlsl.s32       q3,   \cd7, d1[1]
276         vrshrn.s64      d26,  q13,  #14
277         vrshrn.s64      d27,  q15,  #14
278         vrshrn.s64      d24,  q12,  #14
279         vrshrn.s64      d25,  q14,  #14
280         vrshrn.s64      d20,  q10,  #14
281         vrshrn.s64      d21,  q8,   #14
282         vrshrn.s64      d22,  q11,  #14
283         vrshrn.s64      d23,  q3,   #14
284         vadd.i32        \c0,  q12,  q13
285         vsub.i32        \c3,  q12,  q13
286         vadd.i32        \c1,  q10,  q11
287         vsub.i32        \c2,  q10,  q11
288 .endm
289
290 .macro iadst4_10 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
291         vmul.s32        q10,  \c0,  d2[0]
292         vmla.s32        q10,  \c2,  d2[1]
293         vmla.s32        q10,  \c3,  d3[0]
294         vmul.s32        q11,  \c0,  d3[0]
295         vmls.s32        q11,  \c2,  d2[0]
296         vsub.s32        \c0,  \c0,  \c2
297         vmls.s32        q11,  \c3,  d2[1]
298         vadd.s32        \c0,  \c0,  \c3
299         vmul.s32        q13,  \c1,  d3[1]
300         vmul.s32        q12,  \c0,  d3[1]
301         vadd.s32        q14,  q10,  q13
302         vadd.s32        q15,  q11,  q13
303         vrshr.s32       \c0,  q14,  #14
304         vadd.s32        q10,  q10,  q11
305         vrshr.s32       \c1,  q15,  #14
306         vsub.s32        q10,  q10,  q13
307         vrshr.s32       \c2,  q12,  #14
308         vrshr.s32       \c3,  q10,  #14
309 .endm
310
311 .macro iadst4_12 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
312         vmull.s32       q10,  \cd0, d2[0]
313         vmull.s32       q4,   \cd1, d2[0]
314         vmlal.s32       q10,  \cd4, d2[1]
315         vmlal.s32       q4,   \cd5, d2[1]
316         vmlal.s32       q10,  \cd6, d3[0]
317         vmlal.s32       q4,   \cd7, d3[0]
318         vmull.s32       q11,  \cd0, d3[0]
319         vmull.s32       q5,   \cd1, d3[0]
320         vmlsl.s32       q11,  \cd4, d2[0]
321         vmlsl.s32       q5,   \cd5, d2[0]
322         vsub.s32        \c0,  \c0,  \c2
323         vmlsl.s32       q11,  \cd6, d2[1]
324         vmlsl.s32       q5,   \cd7, d2[1]
325         vadd.s32        \c0,  \c0,  \c3
326         vmull.s32       q13,  \cd2, d3[1]
327         vmull.s32       q6,   \cd3, d3[1]
328         vmull.s32       q12,  \cd0, d3[1]
329         vmull.s32       q7,   \cd1, d3[1]
330         vadd.s64        q14,  q10,  q13
331         vadd.s64        q2,   q4,   q6
332         vadd.s64        q15,  q11,  q13
333         vadd.s64        q3,   q5,   q6
334         vrshrn.s64      \cd1, q2,   #14
335         vrshrn.s64      \cd0, q14,  #14
336         vadd.s64        q10,  q10,  q11
337         vadd.s64        q4,   q4,   q5
338         vrshrn.s64      \cd3, q3,   #14
339         vrshrn.s64      \cd2, q15,  #14
340         vsub.s64        q10,  q10,  q13
341         vsub.s64        q4,   q4,   q6
342         vrshrn.s64      \cd4, q12,  #14
343         vrshrn.s64      \cd5, q7,   #14
344         vrshrn.s64      \cd6, q10,  #14
345         vrshrn.s64      \cd7, q4,   #14
346 .endm
347
348 @ The public functions in this file have got the following signature:
349 @ void itxfm_add(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
350
351 .macro itxfm_func4x4 txfm1, txfm2, bpp
352 function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_\bpp\()_neon, export=1
353 .ifc \txfm1,\txfm2
354 .ifc \txfm1,idct
355         movrel          r12, itxfm4_coeffs
356         vld1.16         {d0}, [r12,:64]
357         vmovl.s16       q0,  d0
358 .endif
359 .ifc \txfm1,iadst
360         movrel          r12, iadst4_coeffs
361         vld1.16         {d1}, [r12,:64]
362         vmovl.s16       q1,  d1
363 .endif
364 .else
365         movrel          r12, itxfm4_coeffs
366         vld1.16         {q0}, [r12,:128]
367         vmovl.s16       q1,  d1
368         vmovl.s16       q0,  d0
369 .endif
370 .if \bpp > 10
371 .ifnc \txfm1\()_\txfm2,idct_idct
372         @ iadst4_12 needs q4-q7
373         vpush           {q4-q7}
374 .endif
375 .endif
376
377         vmov.i32        q14, #0
378         vmov.i32        q15, #0
379 .ifc \txfm1\()_\txfm2,idct_idct
380         cmp             r3,  #1
381         bne             1f
382         @ DC-only for idct/idct
383         vld1.32         {d4[]},   [r2,:32]
384         vmull.s32       q2,  d4,  d0[0]
385         vrshrn.s64      d4,  q2,  #14
386         vmull.s32       q2,  d4,  d0[0]
387         vrshrn.s64      d4,  q2,  #14
388         vst1.32         {d30[0]}, [r2,:32]
389         vdup.32         q2,  d4[0]
390         vmov            q3,  q2
391         vmov            q8,  q2
392         vmov            q9,  q2
393         b               2f
394 .endif
395
396 1:
397         vld1.32         {q2-q3},   [r2,:128]
398         vst1.32         {q14-q15}, [r2,:128]!
399         vld1.32         {q8-q9},   [r2,:128]
400
401 .ifc \txfm1,iwht
402         vshr.s32        q2,  q2,  #2
403         vshr.s32        q3,  q3,  #2
404         vshr.s32        q8,  q8,  #2
405         vshr.s32        q9,  q9,  #2
406 .endif
407
408         vst1.16         {q14-q15}, [r2,:128]!
409         \txfm1\()4_\bpp q2,  q3,  q8,  q9,  d4,  d5,  d6,  d7,  d16, d17, d18, d19
410
411         @ Transpose 4x4 with 32 bit elements
412         vtrn.32         q2,  q3
413         vtrn.32         q8,  q9
414         vswp            d5,  d16
415         vswp            d7,  d18
416
417         \txfm2\()4_\bpp q2,  q3,  q8,  q9,  d4,  d5,  d6,  d7,  d16, d17, d18, d19
418 2:
419         vmvn.u16        q15, #((0xffff << \bpp) & 0xffff)
420         vld1.16         {d0},  [r0,:64], r1
421         vld1.16         {d1},  [r0,:64], r1
422 .ifnc \txfm1,iwht
423         vrshr.s32       q2,  q2,  #4
424         vrshr.s32       q3,  q3,  #4
425         vrshr.s32       q8,  q8,  #4
426         vrshr.s32       q9,  q9,  #4
427 .endif
428         vaddw.u16       q2,  q2,  d0
429         vaddw.u16       q3,  q3,  d1
430         vld1.16         {d2},  [r0,:64], r1
431         vld1.16         {d3},  [r0,:64], r1
432         vqmovun.s32     d0,  q2
433         vqmovun.s32     d1,  q3
434         sub             r0,  r0,  r1, lsl #2
435
436         vaddw.u16       q8,  q8,  d2
437         vmin.u16        q0,  q0,  q15
438         vaddw.u16       q9,  q9,  d3
439         vst1.16         {d0},  [r0,:64], r1
440         vqmovun.s32     d2,  q8
441         vqmovun.s32     d3,  q9
442         vmin.u16        q1,  q1,  q15
443
444         vst1.16         {d1},  [r0,:64], r1
445         vst1.16         {d2},  [r0,:64], r1
446         vst1.16         {d3},  [r0,:64], r1
447
448 .if \bpp > 10
449 .ifnc \txfm1\()_\txfm2,idct_idct
450         vpop            {q4-q7}
451 .endif
452 .endif
453         bx              lr
454 endfunc
455 .endm
456
457 .macro itxfm_funcs4x4 bpp
458 itxfm_func4x4 idct,  idct,  \bpp
459 itxfm_func4x4 iadst, idct,  \bpp
460 itxfm_func4x4 idct,  iadst, \bpp
461 itxfm_func4x4 iadst, iadst, \bpp
462 itxfm_func4x4 iwht,  iwht,  \bpp
463 .endm
464
465 itxfm_funcs4x4 10
466 itxfm_funcs4x4 12
467
468 .macro idct8
469         dmbutterfly0    d16, d17, d24, d25, q8,  q12, q2, q4, d4, d5, d8, d9, q3, q2, q5, q4 @ q8 = t0a, q12 = t1a
470         dmbutterfly     d20, d21, d28, d29, d1[0], d1[1], q2,  q3,  q4,  q5 @ q10 = t2a, q14 = t3a
471         dmbutterfly     d18, d19, d30, d31, d2[0], d2[1], q2,  q3,  q4,  q5 @ q9  = t4a, q15 = t7a
472         dmbutterfly     d26, d27, d22, d23, d3[0], d3[1], q2,  q3,  q4,  q5 @ q13 = t5a, q11 = t6a
473
474         butterfly       q2,  q14, q8,  q14 @ q2 = t0, q14 = t3
475         butterfly       q3,  q10, q12, q10 @ q3 = t1, q10 = t2
476         butterfly       q4,  q13, q9,  q13 @ q4 = t4, q13 = t5a
477         butterfly       q5,  q11, q15, q11 @ q5 = t7, q11 = t6a
478
479         butterfly       q8,  q15, q2,  q5  @ q8 = out[0], q15 = out[7]
480
481         dmbutterfly0    d4,  d5,  d10, d11, q11, q13, q9,  q13, d18, d19, d26, d27, q2,  q5, q11, q12 @ q2 = t6, q5 = t5
482
483         butterfly       q11, q12, q14, q4  @ q11 = out[3], q12 = out[4]
484         butterfly       q9,  q14, q3,  q2  @ q9 = out[1],  q14 = out[6]
485         butterfly_r     q13, q10, q10, q5  @ q13 = out[5], q10 = out[2]
486 .endm
487
488 .macro iadst8
489         movrel          r12, iadst8_coeffs
490         vld1.16         {q1}, [r12,:128]!
491         vmovl.s16       q0,  d2
492         vmovl.s16       q1,  d3
493
494         dmbutterfly_l   q4,  q5,  q2,  q3,  d30, d31, d16, d17, d0[1], d0[0] @ q4,q5  = t1a, q2,q3 = t0a
495         dmbutterfly_l   q8,  q15, q6,  q7,  d22, d23, d24, d25, d2[1], d2[0] @ q8,q15 = t5a, q6,q7 = t4a
496
497         dbutterfly_n    d22, d23, d4,  d5,  q2,  q3,  q6,  q7,  q11, q12, q2,  q3 @ q11 = t0, q2 = t4
498
499         dbutterfly_n    d24, d25, d6,  d7,  q4,  q5,  q8,  q15, q12, q3,  q6,  q7 @ q12 = t1, q3 = t5
500
501         dmbutterfly_l   q6,  q7,  q4,  q5,  d26, d27, d20, d21, d1[1], d1[0] @ q6,q7 = t3a, q4,q5 = t2a
502         dmbutterfly_l   q10, q13, q8,  q15, d18, d19, d28, d29, d3[1], d3[0] @ q10,q13 = t7a, q8,q15 = t6a
503
504         dbutterfly_n    d18, d19, d8,  d9,  q4,  q5,  q8,  q15, q9,  q14, q4, q5 @ q9 = t2, q4 = t6
505         dbutterfly_n    d16, d17, d12, d13, q6,  q7,  q10, q13, q8,  q15, q6, q7 @ q8 = t3, q6 = t7
506
507         movrel          r12, idct_coeffs
508         vld1.16         {q0}, [r12,:128]
509         vmovl.s16       q1,  d1
510         vmovl.s16       q0,  d0
511
512         butterfly       q15, q12, q12, q8 @ q15 = -out[7], q12 = t3
513         vneg.s32        q15, q15          @ q15 = out[7]
514         butterfly       q8,  q9,  q11, q9 @ q8 = out[0], q9 = t2
515
516         dmbutterfly_l   q10, q11, q5,  q7,  d4,  d5,  d6,  d7,  d1[0], d1[1] @ q10,q11 = t5a, q5,q7 = t4a
517         dmbutterfly_l   q2,  q3,  q13, q14, d12, d13, d8,  d9,  d1[1], d1[0] @ q2,q3 = t6a, q13,q14 = t7a
518
519         dbutterfly_n    d28, d29, d8,  d9,  q10, q11, q13, q14, q4,  q6,  q10, q11 @ q14 = out[6], q4 = t7
520
521         dmbutterfly0    d22, d23, d24, d25, q9,  q12, q6, q13, d12, d13, d26, d27, q9, q10 @ q11 = -out[3], q12 = out[4]
522         vneg.s32        q11, q11      @ q11 = out[3]
523
524         dbutterfly_n    d18, d19, d4,  d5,  q5,  q7,  q2,  q3,  q9, q10, q2,  q3 @ q9 = -out[1], q2 = t6
525         vneg.s32        q9,  q9       @ q9 = out[1]
526
527         dmbutterfly0    d20, d21, d26, d27, q2,  q4,  q3, q5,  d6,  d7,  d10, d11, q6,  q7 @ q10 = out[2], q13 = -out[5]
528         vneg.s32        q13, q13      @ q13 = out[5]
529 .endm
530
531 function idct8x8_dc_add_neon
532         movrel          r12, idct_coeffs
533         vld1.16         {d0}, [r12,:64]
534
535         vmov.i32        q2,  #0
536         vmovl.s16       q0,  d0
537
538         vld1.32         {d16[]}, [r2,:32]
539         vmull.s32       q8,  d16, d0[0]
540         vrshrn.s64      d16, q8,  #14
541         vmull.s32       q8,  d16, d0[0]
542         vrshrn.s64      d16, q8,  #14
543         vdup.32         q8,  d16[0]
544         vst1.32         {d4[0]}, [r2,:32]
545
546         vrshr.s32       q8,  q8,  #5
547         vdup.s16        q15, r8
548
549         mov             r3,  r0
550         mov             r12, #8
551 1:
552         @ Loop to add the constant from q8 into all 8x8 outputs
553         subs            r12, r12, #2
554         vld1.16         {q2},  [r0,:128], r1
555         vaddw.u16       q10, q8,  d4
556         vld1.16         {q3},  [r0,:128], r1
557         vaddw.u16       q11, q8,  d5
558         vaddw.u16       q12, q8,  d6
559         vaddw.u16       q13, q8,  d7
560         vqmovun.s32     d4,  q10
561         vqmovun.s32     d5,  q11
562         vqmovun.s32     d6,  q12
563         vqmovun.s32     d7,  q13
564         vmin.u16        q2,  q2,  q15
565         vst1.16         {q2},  [r3,:128], r1
566         vmin.u16        q3,  q3,  q15
567         vst1.16         {q3},  [r3,:128], r1
568         bne             1b
569
570         pop             {r4-r8,pc}
571 endfunc
572 .ltorg
573
574 .macro itxfm8_1d_funcs txfm
575 @ Read a vertical 4x8 slice out of a 8x8 matrix, do a transform on it,
576 @ transpose into a horizontal 8x4 slice and store.
577 @ r0 = dst (temp buffer)
578 @ r1 = slice offset
579 @ r2 = src
580 function \txfm\()8_1d_4x8_pass1_neon
581         mov             r12, #32
582         vmov.s32        q2,  #0
583 .irp i, 8, 9, 10, 11, 12, 13, 14, 15
584         vld1.32         {q\i}, [r2,:128]
585         vst1.32         {q2},  [r2,:128], r12
586 .endr
587
588         \txfm\()8
589
590         @ Do two 4x4 transposes. Originally, q8-q15 contain the
591         @ 8 rows. Afterwards, q8-q11, q12-q15 contain the transposed
592         @ 4x4 blocks.
593         transpose32_q_2x_4x4 q8,  q9,  q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
594
595         @ Store the transposed 4x4 blocks horizontally.
596         cmp             r1,  #4
597         beq             1f
598 .irp i, 8, 12, 9, 13, 10, 14, 11, 15
599         vst1.32         {q\i}, [r0,:128]!
600 .endr
601         bx              lr
602 1:
603         @ Special case: For the last input column (r1 == 4),
604         @ which would be stored as the last row in the temp buffer,
605         @ don't store the first 4x4 block, but keep it in registers
606         @ for the first slice of the second pass (where it is the
607         @ last 4x4 block).
608 .irp i, 12, 13, 14, 15
609         add             r0,  r0,  #16
610         vst1.32         {q\i}, [r0,:128]!
611 .endr
612         vmov            q12, q8
613         vmov            q13, q9
614         vmov            q14, q10
615         vmov            q15, q11
616         bx              lr
617 endfunc
618
619 @ Read a vertical 4x8 slice out of a 8x8 matrix, do a transform on it,
620 @ load the destination pixels (from a similar 4x8 slice), add and store back.
621 @ r0 = dst
622 @ r1 = dst stride
623 @ r2 = src (temp buffer)
624 @ r3 = slice offset
625 function \txfm\()8_1d_4x8_pass2_neon
626         mov             r12, #32
627 .irp i, 8, 9, 10, 11
628         vld1.32         {q\i}, [r2,:128], r12
629 .endr
630         cmp             r3,  #0
631         beq             1f
632 .irp i, 12, 13, 14, 15
633         vld1.32         {q\i}, [r2,:128], r12
634 .endr
635 1:
636
637         add             r3,  r0,  r1
638         lsl             r1,  r1,  #1
639         \txfm\()8
640
641         vdup.s16        q4,  r8
642 .macro load_add_store coef0, coef1, coef2, coef3
643         vld1.16         {d4},   [r0,:64], r1
644         vld1.16         {d5},   [r3,:64], r1
645         vld1.16         {d6},   [r0,:64], r1
646         vld1.16         {d7},   [r3,:64], r1
647
648         vrshr.s32       \coef0, \coef0, #5
649         vrshr.s32       \coef1, \coef1, #5
650         vrshr.s32       \coef2, \coef2, #5
651         vrshr.s32       \coef3, \coef3, #5
652
653         vaddw.u16       \coef0, \coef0, d4
654         vaddw.u16       \coef1, \coef1, d5
655         vaddw.u16       \coef2, \coef2, d6
656         vaddw.u16       \coef3, \coef3, d7
657
658         sub             r0,  r0,  r1, lsl #1
659         sub             r3,  r3,  r1, lsl #1
660
661         vqmovun.s32     d4,  \coef0
662         vqmovun.s32     d5,  \coef1
663         vqmovun.s32     d6,  \coef2
664         vqmovun.s32     d7,  \coef3
665
666         vmin.u16        q2,  q2,  q4
667         vmin.u16        q3,  q3,  q4
668
669         vst1.16         {d4},  [r0,:64], r1
670         vst1.16         {d5},  [r3,:64], r1
671         vst1.16         {d6},  [r0,:64], r1
672         vst1.16         {d7},  [r3,:64], r1
673 .endm
674         load_add_store  q8,  q9,  q10, q11
675         load_add_store  q12, q13, q14, q15
676 .purgem load_add_store
677
678         bx              lr
679 endfunc
680 .endm
681
682 itxfm8_1d_funcs idct
683 itxfm8_1d_funcs iadst
684
685 .macro itxfm_func8x8 txfm1, txfm2
686 function vp9_\txfm1\()_\txfm2\()_8x8_add_16_neon
687 .ifc \txfm1\()_\txfm2,idct_idct
688         cmp             r3,  #1
689         beq             idct8x8_dc_add_neon
690 .endif
691 .ifnc \txfm1\()_\txfm2,idct_idct
692         vpush           {q4-q7}
693 .else
694         vpush           {q4-q5}
695 .endif
696
697         @ Align the stack, allocate a temp buffer
698 T       mov             r7,  sp
699 T       and             r7,  r7,  #15
700 A       and             r7,  sp,  #15
701         add             r7,  r7,  #256
702         sub             sp,  sp,  r7
703
704         mov             r4,  r0
705         mov             r5,  r1
706         mov             r6,  r2
707
708 .ifc \txfm1,idct
709         movrel          r12, idct_coeffs
710         vld1.16         {q0}, [r12,:128]
711         vmovl.s16       q1,  d1
712         vmovl.s16       q0,  d0
713 .endif
714
715 .irp i, 0, 4
716         add             r0,  sp,  #(\i*32)
717 .ifc \txfm1\()_\txfm2,idct_idct
718 .if \i == 4
719         cmp             r3,  #12
720         ble             1f
721 .endif
722 .endif
723         mov             r1,  #\i
724         add             r2,  r6,  #(\i*4)
725         bl              \txfm1\()8_1d_4x8_pass1_neon
726 .endr
727 .ifc \txfm1\()_\txfm2,idct_idct
728         b               3f
729 1:
730         @ For all-zero slices in pass 1, set q12-q15 to zero, for the in-register
731         @ passthrough of coefficients to pass 2 and clear the end of the temp buffer
732         vmov.i32        q12, #0
733         vmov.i32        q13, #0
734         vmov.i32        q14, #0
735         vmov.i32        q15, #0
736 .rept 4
737         vst1.32         {q12-q13}, [r0,:128]!
738 .endr
739 3:
740 .endif
741 .ifc \txfm1\()_\txfm2,iadst_idct
742         movrel          r12, idct_coeffs
743         vld1.16         {q0}, [r12,:128]
744         vmovl.s16       q1,  d1
745         vmovl.s16       q0,  d0
746 .endif
747 .irp i, 0, 4
748         add             r0,  r4,  #(\i*2)
749         mov             r1,  r5
750         add             r2,  sp,  #(\i*4)
751         mov             r3,  #\i
752         bl              \txfm2\()8_1d_4x8_pass2_neon
753 .endr
754
755         add             sp,  sp,  r7
756 .ifnc \txfm1\()_\txfm2,idct_idct
757         vpop            {q4-q7}
758 .else
759         vpop            {q4-q5}
760 .endif
761         pop             {r4-r8,pc}
762 endfunc
763
764 function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_10_neon, export=1
765         push            {r4-r8,lr}
766         movw            r8,  #0x03ff
767         b               vp9_\txfm1\()_\txfm2\()_8x8_add_16_neon
768 endfunc
769
770 function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_12_neon, export=1
771         push            {r4-r8,lr}
772         movw            r8,  #0x0fff
773         b               vp9_\txfm1\()_\txfm2\()_8x8_add_16_neon
774 endfunc
775 .endm
776
777 itxfm_func8x8 idct,  idct
778 itxfm_func8x8 iadst, idct
779 itxfm_func8x8 idct,  iadst
780 itxfm_func8x8 iadst, iadst
781
782 function idct16x16_dc_add_neon
783         movrel          r12, idct_coeffs
784         vld1.16         {d0}, [r12,:64]
785
786         vmov.i32        q2,  #0
787         vmovl.s16       q0,  d0
788
789         vld1.32         {d16[]}, [r2,:32]
790         vmull.s32       q8,  d16, d0[0]
791         vrshrn.s64      d16, q8,  #14
792         vmull.s32       q8,  d16, d0[0]
793         vrshrn.s64      d16, q8,  #14
794         vdup.32         q8,  d16[0]
795         vst1.32         {d4[0]}, [r2,:32]
796
797         vrshr.s32       q8,  q8,  #6
798         vdup.s16        q15, r9
799
800         mov             r3,  r0
801         mov             r12, #16
802 1:
803         @ Loop to add the constant from q8 into all 16x16 outputs
804         subs            r12, r12, #2
805         vld1.16         {q0-q1},  [r0,:128], r1
806         vaddw.u16       q9,  q8,  d0
807         vaddw.u16       q10, q8,  d1
808         vld1.16         {q2-q3},  [r0,:128], r1
809         vaddw.u16       q11, q8,  d2
810         vaddw.u16       q12, q8,  d3
811         vaddw.u16       q13, q8,  d4
812         vaddw.u16       q14, q8,  d5
813         vqmovun.s32     d0,  q9
814         vaddw.u16       q9,  q8,  d6
815         vqmovun.s32     d1,  q10
816         vaddw.u16       q10, q8,  d7
817         vqmovun.s32     d2,  q11
818         vqmovun.s32     d3,  q12
819         vqmovun.s32     d4,  q13
820         vqmovun.s32     d5,  q14
821         vmin.u16        q0,  q0,  q15
822         vmin.u16        q1,  q1,  q15
823         vqmovun.s32     d6,  q9
824         vqmovun.s32     d7,  q10
825         vst1.16         {q0-q1},  [r3,:128], r1
826         vmin.u16        q2,  q2,  q15
827         vmin.u16        q3,  q3,  q15
828         vst1.16         {q2-q3},  [r3,:128], r1
829         bne             1b
830
831         pop             {r4-r9,pc}
832 endfunc
833 .ltorg
834
835 .macro idct16_end
836         butterfly       d18, d11, d8,  d11               @ d18 = t0a,  d11 = t7a
837         butterfly       d19, d22, d9,  d22               @ d19 = t1a,  d22 = t6
838         butterfly       d8,  d26, d20, d26               @ d8  = t2a,  d26 = t5
839         butterfly       d9,  d10, d28, d10               @ d9  = t3a,  d10 = t4
840         butterfly       d20, d28, d16, d24               @ d20 = t8a,  d28 = t11a
841         butterfly       d24, d21, d23, d21               @ d24 = t9,   d21 = t10
842         butterfly       d23, d27, d25, d27               @ d23 = t14,  d27 = t13
843         butterfly       d25, d29, d29, d17               @ d25 = t15a, d29 = t12a
844
845         mbutterfly0     d27, d21, d27, d21, d16, d30, q8, q15 @ d27 = t13a, d21 = t10a
846         mbutterfly0     d29, d28, d29, d28, d16, d30, q8, q15 @ d29 = t12,  d28 = t11
847
848         vswp            d27, d29                         @ d27 = t12, d29 = t13a
849         vswp            d28, d27                         @ d28 = t12, d27 = t11
850         butterfly       d16, d31, d18, d25               @ d16 = out[0], d31 = out[15]
851         butterfly       d17, d30, d19, d23               @ d17 = out[1], d30 = out[14]
852         butterfly_r     d25, d22, d22, d24               @ d25 = out[9], d22 = out[6]
853         butterfly       d23, d24, d11, d20               @ d23 = out[7], d24 = out[8]
854         butterfly       d18, d29, d8,  d29               @ d18 = out[2], d29 = out[13]
855         butterfly       d19, d28, d9,  d28               @ d19 = out[3], d28 = out[12]
856         vmov            d8,  d21                         @ d8  = t10a
857         butterfly       d20, d27, d10, d27               @ d20 = out[4], d27 = out[11]
858         butterfly       d21, d26, d26, d8                @ d21 = out[5], d26 = out[10]
859         bx              lr
860 .endm
861
862 function idct16
863         mbutterfly0     d16, d24, d16, d24, d8, d10, q4,  q5 @ d16 = t0a,  d24 = t1a
864         mbutterfly      d20, d28, d1[0], d1[1], q4,  q5  @ d20 = t2a,  d28 = t3a
865         mbutterfly      d18, d30, d2[0], d2[1], q4,  q5  @ d18 = t4a,  d30 = t7a
866         mbutterfly      d26, d22, d3[0], d3[1], q4,  q5  @ d26 = t5a,  d22 = t6a
867         mbutterfly      d17, d31, d4[0], d4[1], q4,  q5  @ d17 = t8a,  d31 = t15a
868         mbutterfly      d25, d23, d5[0], d5[1], q4,  q5  @ d25 = t9a,  d23 = t14a
869         mbutterfly      d21, d27, d6[0], d6[1], q4,  q5  @ d21 = t10a, d27 = t13a
870         mbutterfly      d29, d19, d7[0], d7[1], q4,  q5  @ d29 = t11a, d19 = t12a
871
872         butterfly       d8,  d28, d16, d28               @ d8  = t0,   d28 = t3
873         butterfly       d9,  d20, d24, d20               @ d9  = t1,   d20 = t2
874         butterfly       d10, d26, d18, d26               @ d10 = t4,   d26 = t5
875         butterfly       d11, d22, d30, d22               @ d11 = t7,   d22 = t6
876         butterfly       d16, d25, d17, d25               @ d16 = t8,   d25 = t9
877         butterfly       d24, d21, d29, d21               @ d24 = t11,  d21 = t10
878         butterfly       d17, d27, d19, d27               @ d17 = t12,  d27 = t13
879         butterfly       d29, d23, d31, d23               @ d29 = t15,  d23 = t14
880
881         mbutterfly0     d22, d26, d22, d26, d18, d30, q9,  q15  @ d22 = t6a, d26 = t5a
882         mbutterfly      d23, d25, d1[0], d1[1], q9,  q15        @ d23 = t9a,  d25 = t14a
883         mbutterfly      d27, d21, d1[0], d1[1], q9,  q15, neg=1 @ d27 = t13a, d21 = t10a
884         idct16_end
885 endfunc
886
887 function idct16_half
888         mbutterfly0_h   d16, d24, d16, d24, d8, d10, q4,  q5 @ d16 = t0a,  d24 = t1a
889         mbutterfly_h1   d20, d28, d1[0], d1[1], q4,  q5  @ d20 = t2a,  d28 = t3a
890         mbutterfly_h1   d18, d30, d2[0], d2[1], q4,  q5  @ d18 = t4a,  d30 = t7a
891         mbutterfly_h2   d26, d22, d3[0], d3[1], q4,  q5  @ d26 = t5a,  d22 = t6a
892         mbutterfly_h1   d17, d31, d4[0], d4[1], q4,  q5  @ d17 = t8a,  d31 = t15a
893         mbutterfly_h2   d25, d23, d5[0], d5[1], q4,  q5  @ d25 = t9a,  d23 = t14a
894         mbutterfly_h1   d21, d27, d6[0], d6[1], q4,  q5  @ d21 = t10a, d27 = t13a
895         mbutterfly_h2   d29, d19, d7[0], d7[1], q4,  q5  @ d29 = t11a, d19 = t12a
896
897         butterfly       d8,  d28, d16, d28               @ d8  = t0,   d28 = t3
898         butterfly       d9,  d20, d24, d20               @ d9  = t1,   d20 = t2
899         butterfly       d10, d26, d18, d26               @ d10 = t4,   d26 = t5
900         butterfly       d11, d22, d30, d22               @ d11 = t7,   d22 = t6
901         butterfly       d16, d25, d17, d25               @ d16 = t8,   d25 = t9
902         butterfly       d24, d21, d29, d21               @ d24 = t11,  d21 = t10
903         butterfly       d17, d27, d19, d27               @ d17 = t12,  d27 = t13
904         butterfly       d29, d23, d31, d23               @ d29 = t15,  d23 = t14
905
906         mbutterfly0     d22, d26, d22, d26, d18, d30, q9,  q15  @ d22 = t6a, d26 = t5a
907         mbutterfly      d23, d25, d1[0], d1[1], q9,  q15        @ d23 = t9a,  d25 = t14a
908         mbutterfly      d27, d21, d1[0], d1[1], q9,  q15, neg=1 @ d27 = t13a, d21 = t10a
909         idct16_end
910 endfunc
911
912 function idct16_quarter
913         vmov.s64        q12, #0
914         vmull.s32       q4,  d17, d4[0]
915         vmull.s32       q5,  d18, d2[1]
916         vmull.s32       q15, d18, d2[0]
917         vmlsl.s32       q12, d19, d7[1]
918         vmull.s32       q14, d17, d4[1]
919         vmull.s32       q13, d19, d7[0]
920         vmull.s32       q11, d16, d0[0]
921         vrshrn.s64      d16, q4,  #14
922         vrshrn.s64      d11, q5,  #14
923         vrshrn.s64      d10, q15, #14
924         vrshrn.s64      d24, q12, #14
925         vrshrn.s64      d29, q14, #14
926         vrshrn.s64      d17, q13, #14
927         vrshrn.s64      d28, q11, #14
928
929         mbutterfly_l    q10, q11, d17, d24, d1[0], d1[1], neg=1
930         mbutterfly_l    q9,  q15, d29, d16, d1[0], d1[1]
931         vrshrn.s64      d27, q10, #14
932         vrshrn.s64      d21, q11, #14
933         vrshrn.s64      d23, q9,  #14
934         vrshrn.s64      d25, q15, #14
935         vmov            d8,  d28
936         vmov            d9,  d28
937         mbutterfly0     d22, d26, d11, d10, d18, d30, q9,  q15
938         vmov            d20, d28
939         idct16_end
940 endfunc
941
942 function iadst16
943         movrel          r12, iadst16_coeffs
944         vld1.16         {q0},  [r12,:128]!
945         vmovl.s16       q1,  d1
946         vmovl.s16       q0,  d0
947
948         mbutterfly_l    q3,  q2,  d31, d16, d0[1], d0[0] @ q3  = t1,   q2  = t0
949         mbutterfly_l    q5,  q4,  d23, d24, d2[1], d2[0] @ q5  = t9,   q4  = t8
950         butterfly_n     d31, d24, q3,  q5,  q6,  q5      @ d31 = t1a,  d24 = t9a
951         mbutterfly_l    q7,  q6,  d29, d18, d1[1], d1[0] @ q7  = t3,   q6  = t2
952         butterfly_n     d16, d23, q2,  q4,  q3,  q4      @ d16 = t0a,  d23 = t8a
953         mbutterfly_l    q3,  q2,  d21, d26, d3[1], d3[0] @ q3  = t11,  q2  = t10
954
955         vld1.16         {q0},  [r12,:128]!
956         butterfly_n     d29, d26, q7,  q3,  q4,  q3      @ d29 = t3a,  d26 = t11a
957         vmovl.s16       q1,  d1
958         vmovl.s16       q0,  d0
959         mbutterfly_l    q5,  q4,  d27, d20, d0[1], d0[0] @ q5  = t5,   q4  = t4
960         butterfly_n     d18, d21, q6,  q2,  q3,  q2      @ d18 = t2a,  d21 = t10a
961
962         mbutterfly_l    q7,  q6,  d19, d28, d2[1], d2[0] @ q7  = t13,  q6  = t12
963         butterfly_n     d20, d28, q5,  q7,  q2,  q7      @ d20 = t5a,  d28 = t13a
964         mbutterfly_l    q3,  q2,  d25, d22, d1[1], d1[0] @ q3  = t7,   q2  = t6
965         butterfly_n     d27, d19, q4,  q6,  q5,  q6      @ d27 = t4a,  d19 = t12a
966
967         mbutterfly_l    q5,  q4,  d17, d30, d3[1], d3[0] @ q5  = t15,  q4  = t14
968         movrel          r12, idct_coeffs
969         vld1.16         {q0}, [r12,:128]
970         vmovl.s16       q1,  d1
971         vmovl.s16       q0,  d0
972         butterfly_n     d22, d30, q3,  q5,  q6,  q5      @ d22 = t7a,  d30 = t15a
973         mbutterfly_l    q7,  q6,  d23, d24, d2[0], d2[1] @ q7  = t9,   q6  = t8
974         butterfly_n     d25, d17, q2,  q4,  q3,  q4      @ d25 = t6a,  d17 = t14a
975
976         mbutterfly_l    q2,  q3,  d28, d19, d2[1], d2[0] @ q2  = t12,  q3  = t13
977         butterfly_n     d23, d19, q6,  q2,  q4,  q2      @ d23 = t8a,  d19 = t12a
978         mbutterfly_l    q5,  q4,  d21, d26, d3[0], d3[1] @ q5  = t11,  q4  = t10
979         butterfly_r     d4,  d27, d16, d27               @ d4  = t4,   d27 = t0
980         butterfly_n     d24, d28, q7,  q3,  q6,  q3      @ d24 = t9a,  d28 = t13a
981
982         mbutterfly_l    q6,  q7,  d30, d17, d3[1], d3[0] @ q6  = t14,  q7  = t15
983         butterfly_r     d5,  d20, d31, d20               @ d5  = t5,   d20 = t1
984         butterfly_n     d21, d17, q4,  q6,  q3,  q6      @ d21 = t10a, d17 = t14a
985         butterfly_n     d26, d30, q5,  q7,  q4,  q7      @ d26 = t11a, d30 = t15a
986
987         butterfly_r     d6,  d25, d18, d25               @ d6  = t6,   d25 = t2
988         butterfly_r     d7,  d22, d29, d22               @ d7  = t7,   d22 = t3
989
990         mbutterfly_l    q5,  q4,  d19, d28, d1[0], d1[1] @ q5  = t13,  q4  = t12
991         mbutterfly_l    q6,  q7,  d30, d17, d1[1], d1[0] @ q6  = t14,  q7  = t15
992
993         butterfly_n     d18, d30, q4,  q6,  q8,  q6      @ d18 = out[2],   d30 = t14a
994         butterfly_n     d29, d17, q5,  q7,  q6,  q7      @ d29 = -out[13], d17 = t15a
995         vneg.s32        d29, d29                         @ d29 = out[13]
996
997         mbutterfly_l    q5,  q4,  d4,  d5,  d1[0], d1[1] @ q5  = t5a,  q4  = t4a
998         mbutterfly_l    q6,  q7,  d7,  d6,  d1[1], d1[0] @ q6  = t6a,  q7  = t7a
999
1000         butterfly       d2,  d6,  d27, d25               @ d2 = out[0], d6 = t2a
1001         butterfly       d3,  d7,  d23, d21               @ d3 =-out[1], d7 = t10
1002
1003         butterfly_n     d19, d31, q4,  q6,  q2,  q4      @ d19 = -out[3],  d31 = t6
1004         vneg.s32        d19, d19                         @ d19 = out[3]
1005         butterfly_n     d28, d16, q5,  q7,  q2,  q5      @ d28 = out[12],  d16 = t7
1006
1007         butterfly       d5,  d8,  d20, d22               @ d5 =-out[15],d8 = t3a
1008         butterfly       d4,  d9,  d24, d26               @ d4 = out[14],d9 = t11
1009
1010         mbutterfly0     d23, d24, d6,  d8,  d10, d11, q6,  q7, 1 @ d23 = out[7], d24 = out[8]
1011         mbutterfly0     d20, d27, d16, d31, d10, d11, q6,  q7    @ d20 = out[4], d27 = out[11]
1012         mbutterfly0     d22, d25, d9,  d7,  d10, d11, q6,  q7    @ d22 = out[6], d25 = out[9]
1013         mbutterfly0     d21, d26, d30, d17, d10, d11, q6,  q7, 1 @ d21 = out[5], d26 = out[10]
1014
1015         vneg.s32        d31, d5                          @ d31 = out[15]
1016         vneg.s32        d17, d3                          @ d17 = out[1]
1017
1018         vmov            d16, d2
1019         vmov            d30, d4
1020         bx              lr
1021 endfunc
1022
1023 .macro itxfm16_1d_funcs txfm, suffix
1024 @ Read a vertical 2x16 slice out of a 16x16 matrix, do a transform on it,
1025 @ transpose into a horizontal 16x2 slice and store.
1026 @ r0 = dst (temp buffer)
1027 @ r2 = src
1028 function \txfm\()16_1d_2x16_pass1\suffix\()_neon
1029         push            {lr}
1030
1031         mov             r12, #64
1032         vmov.s32        q4,  #0
1033 .ifb \suffix
1034 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1035         vld1.32         {d\i}, [r2,:64]
1036         vst1.32         {d8},  [r2,:64], r12
1037 .endr
1038 .endif
1039 .ifc \suffix,_quarter
1040 .irp i, 16, 17, 18, 19
1041         vld1.32         {d\i}, [r2,:64]
1042         vst1.32         {d8},  [r2,:64], r12
1043 .endr
1044 .endif
1045 .ifc \suffix,_half
1046 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1047         vld1.32         {d\i}, [r2,:64]
1048         vst1.32         {d8},  [r2,:64], r12
1049 .endr
1050 .endif
1051
1052         bl              \txfm\()16\suffix
1053
1054         @ Do eight 2x2 transposes. Originally, d16-d31 contain the
1055         @ 16 rows. Afterwards, d16-d17, d18-d19 etc contain the eight
1056         @ transposed 2x2 blocks.
1057         transpose32_8x_2x2 d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
1058
1059         @ Store the transposed 2x2 blocks horizontally.
1060 .irp i, 16, 18, 20, 22, 24, 26, 28, 30, 17, 19, 21, 23, 25, 27, 29, 31
1061         vst1.32         {d\i}, [r0,:64]!
1062 .endr
1063         pop             {pc}
1064 endfunc
1065
1066 @ Read a vertical 2x16 slice out of a 16x16 matrix, do a transform on it,
1067 @ load the destination pixels (from a similar 2x16 slice), add and store back.
1068 @ r0 = dst
1069 @ r1 = dst stride
1070 @ r2 = src (temp buffer)
1071 function \txfm\()16_1d_2x16_pass2\suffix\()_neon
1072         push            {lr}
1073
1074         mov             r12, #64
1075 .ifb \suffix
1076 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1077         vld1.16         {d\i}, [r2,:64], r12
1078 .endr
1079 .endif
1080 .ifc \suffix,_quarter
1081 .irp i, 16, 17, 18, 19, 20
1082         vld1.16         {d\i}, [r2,:64], r12
1083 .endr
1084 .endif
1085 .ifc \suffix,_half
1086 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1087         vld1.16         {d\i}, [r2,:64], r12
1088 .endr
1089 .endif
1090
1091         add             r3,  r0,  r1
1092         lsl             r1,  r1,  #1
1093         bl              \txfm\()16\suffix
1094
1095 .macro load_add_store coef0, coef1, coef2, coef3
1096         vrshr.s32       \coef0, \coef0, #6
1097         vrshr.s32       \coef1, \coef1, #6
1098
1099         vld1.32         {d8[]},   [r0,:32], r1
1100         vld1.32         {d8[1]},  [r3,:32], r1
1101         vrshr.s32       \coef2, \coef2, #6
1102         vrshr.s32       \coef3, \coef3, #6
1103         vld1.32         {d9[]},   [r0,:32], r1
1104         vld1.32         {d9[1]},  [r3,:32], r1
1105         vaddw.u16       \coef0, \coef0, d8
1106         vld1.32         {d10[]},  [r0,:32], r1
1107         vld1.32         {d10[1]}, [r3,:32], r1
1108         vaddw.u16       \coef1, \coef1, d9
1109         vld1.32         {d11[]},  [r0,:32], r1
1110         vld1.32         {d11[1]}, [r3,:32], r1
1111
1112         vqmovun.s32     d8,  \coef0
1113         vdup.s16        q8,  r9
1114         vqmovun.s32     d9,  \coef1
1115         sub             r0,  r0,  r1, lsl #2
1116         sub             r3,  r3,  r1, lsl #2
1117         vaddw.u16       \coef2, \coef2, d10
1118         vaddw.u16       \coef3, \coef3, d11
1119         vmin.u16        q4,  q4,  q8
1120         vst1.32         {d8[0]},  [r0,:32], r1
1121         vst1.32         {d8[1]},  [r3,:32], r1
1122         vqmovun.s32     d10, \coef2
1123         vst1.32         {d9[0]},  [r0,:32], r1
1124         vst1.32         {d9[1]},  [r3,:32], r1
1125         vqmovun.s32     d11, \coef3
1126         vmin.u16        q5,  q5,  q8
1127
1128         vst1.32         {d10[0]}, [r0,:32], r1
1129         vst1.32         {d10[1]}, [r3,:32], r1
1130         vst1.32         {d11[0]}, [r0,:32], r1
1131         vst1.32         {d11[1]}, [r3,:32], r1
1132 .endm
1133         load_add_store  q8,  q9,  q10, q11
1134         load_add_store  q12, q13, q14, q15
1135 .purgem load_add_store
1136
1137         pop             {pc}
1138 endfunc
1139 .endm
1140
1141 itxfm16_1d_funcs idct
1142 itxfm16_1d_funcs iadst
1143 itxfm16_1d_funcs idct, _quarter
1144 itxfm16_1d_funcs idct, _half
1145 .ltorg
1146
1147 @ This is the minimum eob value for each subpartition, in increments of 2
1148 const min_eob_idct_idct_16, align=4
1149         .short  0, 3, 10, 22, 38, 62, 89, 121
1150 endconst
1151
1152 .macro itxfm_func16x16 txfm1, txfm2
1153 function vp9_\txfm1\()_\txfm2\()_16x16_add_16_neon
1154 .ifc \txfm1\()_\txfm2,idct_idct
1155         cmp             r3,  #1
1156         beq             idct16x16_dc_add_neon
1157 .endif
1158 .ifnc \txfm1\()_\txfm2,idct_idct
1159         vpush           {q4-q7}
1160 .else
1161         vpush           {q4-q5}
1162 .endif
1163
1164         @ Align the stack, allocate a temp buffer
1165 T       mov             r7,  sp
1166 T       and             r7,  r7,  #15
1167 A       and             r7,  sp,  #15
1168         add             r7,  r7,  #1024
1169         sub             sp,  sp,  r7
1170
1171         mov             r4,  r0
1172         mov             r5,  r1
1173         mov             r6,  r2
1174
1175 .ifc \txfm1,idct
1176         movrel          r12, idct_coeffs
1177         vld1.16         {q0-q1}, [r12,:128]
1178         vmovl.s16       q2,  d2
1179         vmovl.s16       q3,  d3
1180         vmovl.s16       q1,  d1
1181         vmovl.s16       q0,  d0
1182 .endif
1183
1184 .ifc \txfm1\()_\txfm2,idct_idct
1185         cmp             r3,  #10
1186         ble             idct16x16_quarter_add_16_neon
1187         cmp             r3,  #38
1188         ble             idct16x16_half_add_16_neon
1189
1190         movrel          r8,  min_eob_idct_idct_16 + 2
1191 .endif
1192
1193 .irp i, 0, 2, 4, 6, 8, 10, 12, 14
1194         add             r0,  sp,  #(\i*64)
1195 .ifc \txfm1\()_\txfm2,idct_idct
1196 .if \i > 0
1197         ldrh_post       r1,  r8,  #2
1198         cmp             r3,  r1
1199         it              le
1200         movle           r1,  #(16 - \i)/2
1201         ble             1f
1202 .endif
1203 .endif
1204         add             r2,  r6,  #(\i*4)
1205         bl              \txfm1\()16_1d_2x16_pass1_neon
1206 .endr
1207
1208 .ifc \txfm1\()_\txfm2,idct_idct
1209         b               3f
1210 1:
1211         vmov.i32        q14, #0
1212         vmov.i32        q15, #0
1213 2:
1214         subs            r1,  r1,  #1
1215         @ Unroll for 2 lines
1216 .rept 2
1217         @ Fill one line with zeros
1218         vst1.32         {q14-q15}, [r0,:128]!
1219         vst1.32         {q14-q15}, [r0,:128]!
1220 .endr
1221         bne             2b
1222 3:
1223 .endif
1224
1225 .ifc \txfm1\()_\txfm2,iadst_idct
1226         movrel          r12, idct_coeffs
1227         vld1.16         {q0-q1}, [r12,:128]
1228         vmovl.s16       q2,  d2
1229         vmovl.s16       q3,  d3
1230         vmovl.s16       q1,  d1
1231         vmovl.s16       q0,  d0
1232 .endif
1233 .irp i, 0, 2, 4, 6, 8, 10, 12, 14
1234         add             r0,  r4,  #(\i*2)
1235         mov             r1,  r5
1236         add             r2,  sp,  #(\i*4)
1237         bl              \txfm2\()16_1d_2x16_pass2_neon
1238 .endr
1239
1240         add             sp,  sp,  r7
1241 .ifnc \txfm1\()_\txfm2,idct_idct
1242         vpop            {q4-q7}
1243 .else
1244         vpop            {q4-q5}
1245 .endif
1246         pop             {r4-r9,pc}
1247 endfunc
1248
1249 function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_10_neon, export=1
1250         push            {r4-r9,lr}
1251         movw            r9,  #0x03ff
1252         b               vp9_\txfm1\()_\txfm2\()_16x16_add_16_neon
1253 endfunc
1254
1255 function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_12_neon, export=1
1256         push            {r4-r9,lr}
1257         movw            r9,  #0x0fff
1258         b               vp9_\txfm1\()_\txfm2\()_16x16_add_16_neon
1259 endfunc
1260 .endm
1261
1262 itxfm_func16x16 idct,  idct
1263 itxfm_func16x16 iadst, idct
1264 itxfm_func16x16 idct,  iadst
1265 itxfm_func16x16 iadst, iadst
1266 .ltorg
1267
1268 .macro idct16_partial size
1269 function idct16x16_\size\()_add_16_neon
1270 .irp i, 0, 2
1271         add             r0,  sp,  #(\i*64)
1272 .ifc \size,quarter
1273 .if \i == 2
1274         cmp             r3,  #3
1275         ble             1f
1276 .endif
1277 .endif
1278         add             r2,  r6,  #(\i*4)
1279         bl              idct16_1d_2x16_pass1_\size\()_neon
1280 .endr
1281
1282 .ifc \size,half
1283 .irp i, 4, 6
1284         add             r0,  sp,  #(\i*64)
1285 .if \i == 6
1286         cmp             r3,  #22
1287         ble             1f
1288 .endif
1289         add             r2,  r6,  #(\i*4)
1290         bl              idct16_1d_2x16_pass1_\size\()_neon
1291 .endr
1292 .endif
1293
1294         b               3f
1295 1:
1296         vmov.i32        q14, #0
1297         vmov.i32        q15, #0
1298
1299         @ Unroll for 2 lines
1300 .rept 2
1301         @ Fill one line with zeros
1302         vst1.32         {q14-q15}, [r0,:128]!
1303         vst1.32         {q14-q15}, [r0,:128]!
1304 .endr
1305
1306 3:
1307
1308 .irp i, 0, 2, 4, 6, 8, 10, 12, 14
1309         add             r0,  r4,  #(\i*2)
1310         mov             r1,  r5
1311         add             r2,  sp,  #(\i*4)
1312         bl              idct16_1d_2x16_pass2_\size\()_neon
1313 .endr
1314
1315         add             sp,  sp,  r7
1316         vpop            {q4-q5}
1317         pop             {r4-r9,pc}
1318 endfunc
1319 .endm
1320
1321 idct16_partial quarter
1322 idct16_partial half
1323
1324 function idct32x32_dc_add_neon
1325         movrel          r12, idct_coeffs
1326         vld1.16         {d0}, [r12,:64]
1327
1328         vmov.i32        q2,  #0
1329         vmovl.s16       q0,  d0
1330
1331         vld1.32         {d16[]}, [r2,:32]
1332         vmull.s32       q8,  d16, d0[0]
1333         vrshrn.s64      d16, q8,  #14
1334         vmull.s32       q8,  d16, d0[0]
1335         vrshrn.s64      d16, q8,  #14
1336         vdup.32         q8,  d16[0]
1337         vst1.32         {d4[0]}, [r2,:32]
1338
1339         vrshr.s32       q8,  q8,  #6
1340         vdup.s16        q15, r9
1341
1342         mov             r3,  r0
1343         mov             r12, #32
1344         sub             r1,  r1,  #32
1345 1:
1346         @ Loop to add the constant from q8 into all 32x32 outputs
1347         subs            r12, r12, #1
1348         vld1.16         {q0-q1},  [r0,:128]!
1349         vaddw.u16       q9,  q8,  d0
1350         vaddw.u16       q10, q8,  d1
1351         vld1.16         {q2-q3},  [r0,:128], r1
1352         vaddw.u16       q11, q8,  d2
1353         vaddw.u16       q12, q8,  d3
1354         vaddw.u16       q13, q8,  d4
1355         vaddw.u16       q14, q8,  d5
1356         vqmovun.s32     d0,  q9
1357         vaddw.u16       q9,  q8,  d6
1358         vqmovun.s32     d1,  q10
1359         vaddw.u16       q10, q8,  d7
1360         vqmovun.s32     d2,  q11
1361         vqmovun.s32     d3,  q12
1362         vqmovun.s32     d4,  q13
1363         vqmovun.s32     d5,  q14
1364         vmin.u16        q0,  q0,  q15
1365         vmin.u16        q1,  q1,  q15
1366         vqmovun.s32     d6,  q9
1367         vqmovun.s32     d7,  q10
1368         vst1.16         {q0-q1},  [r3,:128]!
1369         vmin.u16        q2,  q2,  q15
1370         vmin.u16        q3,  q3,  q15
1371         vst1.16         {q2-q3},  [r3,:128], r1
1372         bne             1b
1373
1374         pop             {r4-r9,pc}
1375 endfunc
1376
1377 .macro idct32_end
1378         butterfly       d16, d9,  d8,  d9  @ d16 = t16a, d9  = t19a
1379         butterfly       d17, d20, d23, d20 @ d17 = t17,  d20 = t18
1380         butterfly       d18, d10, d11, d10 @ d18 = t23a, d10 = t20a
1381         butterfly       d19, d21, d22, d21 @ d19 = t22,  d21 = t21
1382         butterfly       d8,  d28, d28, d30 @ d8  = t24a, d28 = t27a
1383         butterfly       d23, d26, d25, d26 @ d23 = t25,  d26 = t26
1384         butterfly       d11, d29, d29, d31 @ d11 = t31a, d29 = t28a
1385         butterfly       d22, d27, d24, d27 @ d22 = t30,  d27 = t29
1386
1387         mbutterfly      d27, d20, d1[0], d1[1], q12, q15        @ d27 = t18a, d20 = t29a
1388         mbutterfly      d29, d9,  d1[0], d1[1], q12, q15        @ d29 = t19,  d9  = t28
1389         mbutterfly      d28, d10, d1[0], d1[1], q12, q15, neg=1 @ d28 = t27,  d10 = t20
1390         mbutterfly      d26, d21, d1[0], d1[1], q12, q15, neg=1 @ d26 = t26a, d21 = t21a
1391
1392         butterfly       d31, d24, d11, d8  @ d31 = t31,  d24 = t24
1393         butterfly       d30, d25, d22, d23 @ d30 = t30a, d25 = t25a
1394         butterfly_r     d23, d16, d16, d18 @ d23 = t23,  d16 = t16
1395         butterfly_r     d22, d17, d17, d19 @ d22 = t22a, d17 = t17a
1396         butterfly       d18, d21, d27, d21 @ d18 = t18,  d21 = t21
1397         butterfly_r     d27, d28, d9,  d28 @ d27 = t27a, d28 = t28a
1398         butterfly       d8,  d26, d20, d26 @ d8  = t29,  d26 = t26
1399         butterfly       d19, d20, d29, d10 @ d19 = t19a, d20 = t20
1400         vmov            d29, d8            @ d29 = t29
1401
1402         mbutterfly0     d27, d20, d27, d20, d8, d10, q4, q5 @ d27 = t27,  d20 = t20
1403         mbutterfly0     d26, d21, d26, d21, d8, d10, q4, q5 @ d26 = t26a, d21 = t21a
1404         mbutterfly0     d25, d22, d25, d22, d8, d10, q4, q5 @ d25 = t25,  d22 = t22
1405         mbutterfly0     d24, d23, d24, d23, d8, d10, q4, q5 @ d24 = t24a, d23 = t23a
1406         bx              lr
1407 .endm
1408
1409 function idct32_odd
1410         movrel          r12, idct_coeffs
1411
1412         @ Overwrite the idct16 coeffs with the stored ones for idct32
1413         vmovl.s16       q0,  d12
1414         vmovl.s16       q1,  d13
1415         vmovl.s16       q2,  d14
1416         vmovl.s16       q3,  d15
1417
1418         mbutterfly      d16, d31, d0[0], d0[1], q4, q5 @ d16 = t16a, d31 = t31a
1419         mbutterfly      d24, d23, d1[0], d1[1], q4, q5 @ d24 = t17a, d23 = t30a
1420         mbutterfly      d20, d27, d2[0], d2[1], q4, q5 @ d20 = t18a, d27 = t29a
1421         mbutterfly      d28, d19, d3[0], d3[1], q4, q5 @ d28 = t19a, d19 = t28a
1422         mbutterfly      d18, d29, d4[0], d4[1], q4, q5 @ d18 = t20a, d29 = t27a
1423         mbutterfly      d26, d21, d5[0], d5[1], q4, q5 @ d26 = t21a, d21 = t26a
1424         mbutterfly      d22, d25, d6[0], d6[1], q4, q5 @ d22 = t22a, d25 = t25a
1425         mbutterfly      d30, d17, d7[0], d7[1], q4, q5 @ d30 = t23a, d17 = t24a
1426
1427         @ Reload the idct16 coefficients. We could swap the coefficients between
1428         @ q0-q3 and q6-q7 by narrowing/lengthening, but that's slower than just
1429         @ loading and lengthening.
1430         vld1.16         {q0-q1}, [r12,:128]
1431
1432         butterfly       d8,  d24, d16, d24 @ d8  = t16, d24 = t17
1433         butterfly       d9,  d20, d28, d20 @ d9  = t19, d20 = t18
1434         butterfly       d10, d26, d18, d26 @ d10 = t20, d26 = t21
1435         butterfly       d11, d22, d30, d22 @ d11 = t23, d22 = t22
1436         vmovl.s16       q2,  d2
1437         vmovl.s16       q3,  d3
1438         vmovl.s16       q1,  d1
1439         vmovl.s16       q0,  d0
1440         butterfly       d28, d25, d17, d25 @ d28 = t24, d25 = t25
1441         butterfly       d30, d21, d29, d21 @ d30 = t27, d21 = t26
1442         butterfly       d29, d23, d31, d23 @ d29 = t31, d23 = t30
1443         butterfly       d31, d27, d19, d27 @ d31 = t28, d27 = t29
1444
1445         mbutterfly      d23, d24, d2[0], d2[1], q8, q9        @ d23 = t17a, d24 = t30a
1446         mbutterfly      d27, d20, d2[0], d2[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a
1447         mbutterfly      d21, d26, d3[0], d3[1], q8, q9        @ d21 = t21a, d26 = t26a
1448         mbutterfly      d25, d22, d3[0], d3[1], q8, q9, neg=1 @ d25 = t25a, d22 = t22a
1449         idct32_end
1450 endfunc
1451
1452 function idct32_odd_half
1453         movrel          r12, idct_coeffs
1454
1455         vmovl.s16       q0,  d12
1456         vmovl.s16       q1,  d13
1457         vmovl.s16       q2,  d14
1458         vmovl.s16       q3,  d15
1459
1460         mbutterfly_h1   d16, d31, d0[0], d0[1], q4, q5 @ d16 = t16a, d31 = t31a
1461         mbutterfly_h2   d24, d23, d1[0], d1[1], q4, q5 @ d24 = t17a, d23 = t30a
1462         mbutterfly_h1   d20, d27, d2[0], d2[1], q4, q5 @ d20 = t18a, d27 = t29a
1463         mbutterfly_h2   d28, d19, d3[0], d3[1], q4, q5 @ d28 = t19a, d19 = t28a
1464         mbutterfly_h1   d18, d29, d4[0], d4[1], q4, q5 @ d18 = t20a, d29 = t27a
1465         mbutterfly_h2   d26, d21, d5[0], d5[1], q4, q5 @ d26 = t21a, d21 = t26a
1466         mbutterfly_h1   d22, d25, d6[0], d6[1], q4, q5 @ d22 = t22a, d25 = t25a
1467         mbutterfly_h2   d30, d17, d7[0], d7[1], q4, q5 @ d30 = t23a, d17 = t24a
1468
1469         vld1.16         {q0-q1}, [r12,:128]
1470
1471         butterfly       d8,  d24, d16, d24 @ d8  = t16, d24 = t17
1472         butterfly       d9,  d20, d28, d20 @ d9  = t19, d20 = t18
1473         butterfly       d10, d26, d18, d26 @ d10 = t20, d26 = t21
1474         butterfly       d11, d22, d30, d22 @ d11 = t23, d22 = t22
1475         vmovl.s16       q2,  d2
1476         vmovl.s16       q3,  d3
1477         vmovl.s16       q1,  d1
1478         vmovl.s16       q0,  d0
1479         butterfly       d28, d25, d17, d25 @ d28 = t24, d25 = t25
1480         butterfly       d30, d21, d29, d21 @ d30 = t27, d21 = t26
1481         butterfly       d29, d23, d31, d23 @ d29 = t31, d23 = t30
1482         butterfly       d31, d27, d19, d27 @ d31 = t28, d27 = t29
1483
1484         mbutterfly      d23, d24, d2[0], d2[1], q8, q9        @ d23 = t17a, d24 = t30a
1485         mbutterfly      d27, d20, d2[0], d2[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a
1486         mbutterfly      d21, d26, d3[0], d3[1], q8, q9        @ d21 = t21a, d26 = t26a
1487         mbutterfly      d25, d22, d3[0], d3[1], q8, q9, neg=1 @ d25 = t25a, d22 = t22a
1488         idct32_end
1489 endfunc
1490
1491 function idct32_odd_quarter
1492         movrel          r12, idct_coeffs
1493
1494         vmovl.s16       q0,  d12
1495         vmovl.s16       q1,  d13
1496         vmovl.s16       q2,  d14
1497         vmovl.s16       q3,  d15
1498
1499         vmov.s64        q14, #0
1500         vmov.s64        q5,  #0
1501
1502         vmull.s32       q4,  d16, d0[0]
1503         vmlsl.s32       q14, d19, d3[1]
1504         vmull.s32       q15, d16, d0[1]
1505         vmull.s32       q11, d17, d7[0]
1506         vmlsl.s32       q5,  d17, d7[1]
1507         vmull.s32       q13, d19, d3[0]
1508         vmull.s32       q10, d18, d4[0]
1509         vmull.s32       q12, d18, d4[1]
1510
1511         vld1.16         {q0-q1}, [r12,:128]
1512
1513         vrshrn.s64      d8,  q4,  #14
1514         vrshrn.s64      d9,  q14, #14
1515         vrshrn.s64      d29, q15, #14
1516         vrshrn.s64      d28, q11, #14
1517
1518         vmovl.s16       q2,  d2
1519         vmovl.s16       q3,  d3
1520         vmovl.s16       q1,  d1
1521         vmovl.s16       q0,  d0
1522
1523         vrshrn.s64      d11, q5,  #14
1524         vrshrn.s64      d31, q13, #14
1525         vrshrn.s64      d10, q10, #14
1526         vrshrn.s64      d30, q12, #14
1527
1528         mbutterfly_l    q8,  q9,  d29, d8,  d2[0], d2[1]
1529         mbutterfly_l    q13, q10, d31, d9,  d2[0], d2[1], neg=1
1530         vrshrn.s64      d23, q8,  #14
1531         vrshrn.s64      d24, q9,  #14
1532         vrshrn.s64      d27, q13, #14
1533         vrshrn.s64      d20, q10, #14
1534         mbutterfly_l    q8,  q9,  d30, d10, d3[0], d3[1]
1535         vrshrn.s64      d21, q8,  #14
1536         vrshrn.s64      d26, q9,  #14
1537         mbutterfly_l    q8,  q9,  d28, d11, d3[0], d3[1], neg=1
1538         vrshrn.s64      d25, q8,  #14
1539         vrshrn.s64      d22, q9,  #14
1540
1541         idct32_end
1542 endfunc
1543
1544 .macro idct32_funcs suffix
1545 @ Do an 32-point IDCT of a 2x32 slice out of a 32x32 matrix.
1546 @ We don't have register space to do a single pass IDCT of 2x32 though,
1547 @ but the 32-point IDCT can be decomposed into two 16-point IDCTs;
1548 @ a normal IDCT16 with every other input component (the even ones, with
1549 @ each output written twice), followed by a separate 16-point IDCT
1550 @ of the odd inputs, added/subtracted onto the outputs of the first idct16.
1551 @ r0 = dst (temp buffer)
1552 @ r1 = unused
1553 @ r2 = src
1554 function idct32_1d_2x32_pass1\suffix\()_neon
1555         push            {lr}
1556
1557         @ Double stride of the input, since we only read every other line
1558         mov             r12, #256
1559         vmov.s32        d8,  #0
1560
1561         @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30)
1562 .ifb \suffix
1563 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1564         vld1.32         {d\i}, [r2,:64]
1565         vst1.32         {d8},  [r2,:64], r12
1566 .endr
1567 .endif
1568 .ifc \suffix,_quarter
1569 .irp i, 16, 17, 18, 19
1570         vld1.32         {d\i}, [r2,:64]
1571         vst1.32         {d8},  [r2,:64], r12
1572 .endr
1573 .endif
1574 .ifc \suffix,_half
1575 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1576         vld1.32         {d\i}, [r2,:64]
1577         vst1.32         {d8},  [r2,:64], r12
1578 .endr
1579 .endif
1580
1581         bl              idct16\suffix
1582
1583         @ Do eight 2x2 transposes. Originally, d16-d31 contain the
1584         @ 16 rows. Afterwards, d16-d17, d18-d19 etc contain the eight
1585         @ transposed 2x2 blocks.
1586         transpose32_8x_2x2 d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
1587
1588         @ Store the registers a, b, c, d, e, f, g, h horizontally, followed
1589         @ by the same registers h, g, f, e, d, c, b, a mirrored.
1590 .macro store_rev a, b, c, d, e, f, g, h
1591 .irp i, \a, \b, \c, \d, \e, \f, \g, \h
1592         vst1.32         {d\i}, [r0,:64]!
1593         vrev64.32       d\i, d\i
1594 .endr
1595 .irp i, \h, \g, \f, \e, \d, \c, \b, \a
1596         vst1.32         {d\i}, [r0,:64]!
1597 .endr
1598 .endm
1599         store_rev       16, 18, 20, 22, 24, 26, 28, 30
1600         store_rev       17, 19, 21, 23, 25, 27, 29, 31
1601         sub             r0,  r0,  #256
1602 .purgem store_rev
1603
1604         @ Move r2 back to the start of the input, and move
1605         @ to the first odd row
1606 .ifb \suffix
1607         sub             r2,  r2,  r12, lsl #4
1608 .endif
1609 .ifc \suffix,_quarter
1610         sub             r2,  r2,  r12, lsl #2
1611 .endif
1612 .ifc \suffix,_half
1613         sub             r2,  r2,  r12, lsl #3
1614 .endif
1615         add             r2,  r2,  #128
1616
1617         vmov.s32        d8,  #0
1618         @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31)
1619 .ifb \suffix
1620 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1621         vld1.16         {d\i}, [r2,:64]
1622         vst1.16         {d8},  [r2,:64], r12
1623 .endr
1624 .endif
1625 .ifc \suffix,_quarter
1626 .irp i, 16, 17, 18, 19
1627         vld1.16         {d\i}, [r2,:64]
1628         vst1.16         {d8},  [r2,:64], r12
1629 .endr
1630 .endif
1631 .ifc \suffix,_half
1632 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1633         vld1.16         {d\i}, [r2,:64]
1634         vst1.16         {d8},  [r2,:64], r12
1635 .endr
1636 .endif
1637
1638         bl              idct32_odd\suffix
1639
1640         transpose32_8x_2x2 d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16
1641
1642         @ Store the registers a, b, c, d, e, f, g, h horizontally,
1643         @ adding into the output first, and then mirrored, subtracted
1644         @ from the output.
1645 .macro store_rev a, b, c, d, e, f, g, h
1646 .irp i, \a, \b, \c, \d, \e, \f, \g, \h
1647         vld1.32         {d8},  [r0,:64]
1648         vadd.s32        d8, d8, d\i
1649         vst1.32         {d8},  [r0,:64]!
1650         vrev64.32       d\i, d\i
1651 .endr
1652 .irp i, \h, \g, \f, \e, \d, \c, \b, \a
1653         vld1.32         {d8},  [r0,:64]
1654         vsub.s32        d8, d8, d\i
1655         vst1.32         {d8},  [r0,:64]!
1656 .endr
1657 .endm
1658
1659         store_rev       31, 29, 27, 25, 23, 21, 19, 17
1660         store_rev       30, 28, 26, 24, 22, 20, 18, 16
1661 .purgem store_rev
1662         pop             {pc}
1663 endfunc
1664 .ltorg
1665
1666 @ This is mostly the same as 2x32_pass1, but without the transpose,
1667 @ and use the source as temp buffer between the two idct passes, and
1668 @ add into the destination.
1669 @ r0 = dst
1670 @ r1 = dst stride
1671 @ r2 = src (temp buffer)
1672 function idct32_1d_2x32_pass2\suffix\()_neon
1673         push            {lr}
1674
1675         mov             r12, #256
1676         @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30)
1677 .ifb \suffix
1678 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1679         vld1.32         {d\i}, [r2,:64], r12
1680 .endr
1681         sub             r2,  r2,  r12, lsl #4
1682 .endif
1683 .ifc \suffix,_quarter
1684 .irp i, 16, 17, 18, 19
1685         vld1.32         {d\i}, [r2,:64], r12
1686 .endr
1687         sub             r2,  r2,  r12, lsl #2
1688 .endif
1689 .ifc \suffix,_half
1690 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1691         vld1.32         {d\i}, [r2,:64], r12
1692 .endr
1693         sub             r2,  r2,  r12, lsl #3
1694 .endif
1695
1696         bl              idct16\suffix
1697
1698 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1699         vst1.32         {d\i}, [r2,:64], r12
1700 .endr
1701
1702         sub             r2,  r2,  r12, lsl #4
1703         add             r2,  r2,  #128
1704
1705         @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31)
1706 .ifb \suffix
1707 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1708         vld1.32         {d\i}, [r2,:64], r12
1709 .endr
1710         sub             r2,  r2,  r12, lsl #4
1711 .endif
1712 .ifc \suffix,_quarter
1713 .irp i, 16, 17, 18, 19
1714         vld1.32         {d\i}, [r2,:64], r12
1715 .endr
1716         sub             r2,  r2,  r12, lsl #2
1717 .endif
1718 .ifc \suffix,_half
1719 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1720         vld1.32         {d\i}, [r2,:64], r12
1721 .endr
1722         sub             r2,  r2,  r12, lsl #3
1723 .endif
1724         sub             r2,  r2,  #128
1725
1726         bl              idct32_odd\suffix
1727
1728         @ Narrow the ict16 coefficients in q0-q3 into q0-q1, to
1729         @ allow clobbering q2-q3 below.
1730         vmovn.s32       d0,  q0
1731         vmovn.s32       d1,  q1
1732         vmovn.s32       d2,  q2
1733         vmovn.s32       d3,  q3
1734
1735         mov             r12, #256
1736         vdup.s16        q4,  r9
1737 .macro load_acc_store a, b, c, d, neg=0
1738         vld1.32         {d4},  [r2,:64], r12
1739         vld1.32         {d5},  [r2,:64], r12
1740 .if \neg == 0
1741         vadd.s32        d4,  d4,  d\a
1742         vld1.32         {d6},  [r2,:64], r12
1743         vadd.s32        d5,  d5,  d\b
1744         vld1.32         {d7},  [r2,:64], r12
1745         vadd.s32        d6,  d6,  d\c
1746         vadd.s32        d7,  d7,  d\d
1747 .else
1748         vsub.s32        d4,  d4,  d\a
1749         vld1.32         {d6},  [r2,:64], r12
1750         vsub.s32        d5,  d5,  d\b
1751         vld1.32         {d7},  [r2,:64], r12
1752         vsub.s32        d6,  d6,  d\c
1753         vsub.s32        d7,  d7,  d\d
1754 .endif
1755         vld1.32         {d10[]},  [r0,:32], r1
1756         vld1.32         {d10[1]}, [r0,:32], r1
1757         vrshr.s32       q2,  q2,  #6
1758         vld1.32         {d11[]},  [r0,:32], r1
1759         vrshr.s32       q3,  q3,  #6
1760         vld1.32         {d11[1]}, [r0,:32], r1
1761         sub             r0,  r0,  r1, lsl #2
1762         vaddw.u16       q2,  q2,  d10
1763         vaddw.u16       q3,  q3,  d11
1764         vqmovun.s32     d4,  q2
1765         vqmovun.s32     d5,  q3
1766         vmin.u16        q2,  q2,  q4
1767         vst1.32         {d4[0]},  [r0,:32], r1
1768         vst1.32         {d4[1]},  [r0,:32], r1
1769         vst1.32         {d5[0]},  [r0,:32], r1
1770         vst1.32         {d5[1]},  [r0,:32], r1
1771 .endm
1772         load_acc_store  31, 30, 29, 28
1773         load_acc_store  27, 26, 25, 24
1774         load_acc_store  23, 22, 21, 20
1775         load_acc_store  19, 18, 17, 16
1776         sub             r2,  r2,  r12
1777         neg             r12, r12
1778         load_acc_store  16, 17, 18, 19, 1
1779         load_acc_store  20, 21, 22, 23, 1
1780         load_acc_store  24, 25, 26, 27, 1
1781         load_acc_store  28, 29, 30, 31, 1
1782 .purgem load_acc_store
1783         @ Lengthen the idct16 coeffs back into 32 bit form
1784         vmovl.s16       q2,  d2
1785         vmovl.s16       q3,  d3
1786         vmovl.s16       q1,  d1
1787         vmovl.s16       q0,  d0
1788         pop             {pc}
1789 endfunc
1790 .endm
1791
1792 idct32_funcs
1793 idct32_funcs _quarter
1794 idct32_funcs _half
1795
1796 const min_eob_idct_idct_32, align=4
1797         .short  0, 3, 9, 21, 34, 51, 70, 98, 135, 176, 240, 258, 336, 357, 448, 472
1798 endconst
1799
1800 function vp9_idct_idct_32x32_add_16_neon
1801         cmp             r3,  #1
1802         beq             idct32x32_dc_add_neon
1803         vpush           {q4-q7}
1804         movrel          r8,  min_eob_idct_idct_32 + 2
1805
1806         @ Align the stack, allocate a temp buffer
1807 T       mov             r7,  sp
1808 T       and             r7,  r7,  #15
1809 A       and             r7,  sp,  #15
1810         add             r7,  r7,  #4096
1811         sub             sp,  sp,  r7
1812
1813         mov             r4,  r0
1814         mov             r5,  r1
1815         mov             r6,  r2
1816
1817         movrel          r12, idct_coeffs
1818         vld1.16         {q0-q1}, [r12,:128]!
1819         vld1.16         {q6-q7}, [r12,:128]
1820         vmovl.s16       q2,  d2
1821         vmovl.s16       q3,  d3
1822         vmovl.s16       q1,  d1
1823         vmovl.s16       q0,  d0
1824
1825         cmp             r3,  #34
1826         ble             idct32x32_quarter_add_16_neon
1827         cmp             r3,  #135
1828         ble             idct32x32_half_add_16_neon
1829
1830 .irp i, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
1831         add             r0,  sp,  #(\i*128)
1832 .if \i > 0
1833         ldrh_post       r1,  r8,  #2
1834         cmp             r3,  r1
1835         it              le
1836         movle           r1,  #(32 - \i)/2
1837         ble             1f
1838 .endif
1839         add             r2,  r6,  #(\i*4)
1840         bl              idct32_1d_2x32_pass1_neon
1841 .endr
1842         b               3f
1843
1844 1:
1845         @ Write zeros to the temp buffer for pass 2
1846         vmov.i16        q14, #0
1847         vmov.i16        q15, #0
1848 2:
1849         subs            r1,  r1,  #1
1850 .rept 2
1851         @ Fill one line with zeros
1852         vst1.16         {q14-q15}, [r0,:128]!
1853         vst1.16         {q14-q15}, [r0,:128]!
1854         vst1.16         {q14-q15}, [r0,:128]!
1855         vst1.16         {q14-q15}, [r0,:128]!
1856 .endr
1857         bne             2b
1858 3:
1859 .irp i, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
1860         add             r0,  r4,  #(\i*2)
1861         mov             r1,  r5
1862         add             r2,  sp,  #(\i*4)
1863         bl              idct32_1d_2x32_pass2_neon
1864 .endr
1865
1866         add             sp,  sp,  r7
1867         vpop            {q4-q7}
1868         pop             {r4-r9,pc}
1869 endfunc
1870
1871 function ff_vp9_idct_idct_32x32_add_10_neon, export=1
1872         push            {r4-r9,lr}
1873         movw            r9,  #0x03ff
1874         b               vp9_idct_idct_32x32_add_16_neon
1875 endfunc
1876
1877 function ff_vp9_idct_idct_32x32_add_12_neon, export=1
1878         push            {r4-r9,lr}
1879         movw            r9,  #0x0fff
1880         b               vp9_idct_idct_32x32_add_16_neon
1881 endfunc
1882
1883 .macro idct32_partial size, rows
1884 function idct32x32_\size\()_add_16_neon
1885 .irp i, 0, 2, 4, 6
1886         add             r0,  sp,  #(\i*128)
1887 .ifc \size,quarter
1888 .if \i > 0
1889         ldrh_post       r1,  r8,  #2
1890         cmp             r3,  r1
1891         it              le
1892         movle           r1,  #(\rows - \i)/2
1893         ble             1f
1894 .endif
1895 .endif
1896         add             r2,  r6,  #(\i*4)
1897         bl              idct32_1d_2x32_pass1_\size\()_neon
1898 .endr
1899 .ifc \size,half
1900         add             r8,  r8,  #8
1901 .irp i, 8, 10, 12, 14
1902         add             r0,  sp,  #(\i*128)
1903 .if \i > 8
1904         ldrh_post       r1,  r8,  #2
1905         cmp             r3,  r1
1906         it              le
1907         movle           r1,  #(\rows - \i)/2
1908         ble             1f
1909 .endif
1910         add             r2,  r6,  #(\i*4)
1911         bl              idct32_1d_2x32_pass1_\size\()_neon
1912 .endr
1913 .endif
1914         b               3f
1915
1916 1:
1917         @ Write zeros to the temp buffer for pass 2
1918         vmov.i16        q14, #0
1919         vmov.i16        q15, #0
1920 2:
1921         subs            r1,  r1,  #1
1922 .rept 2
1923         @ Fill one line with zeros
1924         vst1.16         {q14-q15}, [r0,:128]!
1925         vst1.16         {q14-q15}, [r0,:128]!
1926         vst1.16         {q14-q15}, [r0,:128]!
1927         vst1.16         {q14-q15}, [r0,:128]!
1928 .endr
1929         bne             2b
1930 3:
1931 .irp i, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
1932         add             r0,  r4,  #(\i*2)
1933         mov             r1,  r5
1934         add             r2,  sp,  #(\i*4)
1935         bl              idct32_1d_2x32_pass2_\size\()_neon
1936 .endr
1937
1938         add             sp,  sp,  r7
1939         vpop            {q4-q7}
1940         pop             {r4-r9,pc}
1941 endfunc
1942 .endm
1943
1944 idct32_partial quarter, 8
1945 idct32_partial half, 16