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