arm/aarch64: vp9: Fix vertical alignment
[ffmpeg.git] / libavcodec / arm / vp9itxfm_neon.S
1 /*
2  * Copyright (c) 2016 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 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[3]
228         vmull.s16       q11,  \c1,  d0[2]
229         vadd.i16        d16,  \c0,  \c2
230         vsub.i16        d17,  \c0,  \c2
231         vmlal.s16       q13,  \c3,  d0[2]
232         vmull.s16       q9,   d16,  d0[0]
233         vmull.s16       q10,  d17,  d0[0]
234         vmlsl.s16       q11,  \c3,  d0[3]
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[2], d0[3], q2,  q3,  q4,  q5 @ q10 = t2a, q14 = t3a
354         dmbutterfly     d18, d19, d30, d31, d1[0], d1[1], q2,  q3,  q4,  q5 @ q9  = t4a, q15 = t7a
355         dmbutterfly     d26, d27, d22, d23, d1[2], d1[3], 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[2], d0[3] @ q10,q11 = t5a, q5,q7 = t4a
390         dmbutterfly_l   q2,  q3,  q13, q14, d12, d13, d8,  d9,  d0[3], d0[2] @ 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[2], d0[3], q2,  q3  @ d20 = t2a,  d28 = t3a
598         mbutterfly      d18, d30, d1[0], d1[1], q2,  q3  @ d18 = t4a,  d30 = t7a
599         mbutterfly      d26, d22, d1[2], d1[3], q2,  q3  @ d26 = t5a,  d22 = t6a
600         mbutterfly      d17, d31, d2[0], d2[1], q2,  q3  @ d17 = t8a,  d31 = t15a
601         mbutterfly      d25, d23, d2[2], d2[3], q2,  q3  @ d25 = t9a,  d23 = t14a
602         mbutterfly      d21, d27, d3[0], d3[1], q2,  q3  @ d21 = t10a, d27 = t13a
603         mbutterfly      d29, d19, d3[2], d3[3], 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[2], d0[3], q9,  q15        @ d23 = t9a,  d25 = t14a
616         mbutterfly      d27, d21, d0[2], d0[3], 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[2], d0[3], q2,  q3  @ d20 = t2a,  d28 = t3a
623         mbutterfly_h1   d18, d30, d1[0], d1[1], q2,  q3  @ d18 = t4a,  d30 = t7a
624         mbutterfly_h2   d26, d22, d1[2], d1[3], q2,  q3  @ d26 = t5a,  d22 = t6a
625         mbutterfly_h1   d17, d31, d2[0], d2[1], q2,  q3  @ d17 = t8a,  d31 = t15a
626         mbutterfly_h2   d25, d23, d2[2], d2[3], q2,  q3  @ d25 = t9a,  d23 = t14a
627         mbutterfly_h1   d21, d27, d3[0], d3[1], q2,  q3  @ d21 = t10a, d27 = t13a
628         mbutterfly_h2   d29, d19, d3[2], d3[3], 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[2], d0[3], q9,  q15        @ d23 = t9a,  d25 = t14a
641         mbutterfly      d27, d21, d0[2], d0[3], q9,  q15, neg=1 @ d27 = t13a, d21 = t10a
642         idct16_end
643 endfunc
644
645 function idct16_quarter
646         vmull.s16       q12, d19, d3[3]
647         vmull.s16       q2,  d17, d2[0]
648         vmull.s16       q3,  d18, d1[1]
649         vmull.s16       q15, d18, d1[0]
650         vneg.s32        q12, q12
651         vmull.s16       q14, d17, d2[1]
652         vmull.s16       q13, d19, d3[2]
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[2], d0[3]
663         mbutterfly_l    q9,  q15, d29, d16, d0[2], d0[3]
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, d1[1], d1[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, d1[3], d1[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, d2[1], d2[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, d2[3], d2[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, d1[0], d1[1] @ 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[1], d1[0] @ 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[2], d1[3] @ 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[3], d1[2] @ 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[2], d0[3] @ q5  = t13,  q4  = t12
718         mbutterfly_l    q6,  q7,  d30, d17, d0[3], d0[2] @ 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[2], d0[3] @ q5  = t5a,  q4  = t4a
725         mbutterfly_l    q6,  q7,  d7,  d6,  d0[3], d0[2] @ 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 .endif
893
894         @ Align the stack, allocate a temp buffer
895 T       mov             r7,  sp
896 T       and             r7,  r7,  #15
897 A       and             r7,  sp,  #15
898         add             r7,  r7,  #512
899         sub             sp,  sp,  r7
900
901         mov             r4,  r0
902         mov             r5,  r1
903         mov             r6,  r2
904
905 .ifc \txfm1,idct
906         movrel          r12, idct_coeffs
907         vld1.16         {q0-q1}, [r12,:128]
908 .endif
909
910 .ifc \txfm1\()_\txfm2,idct_idct
911         cmp             r3,  #10
912         ble             idct16x16_quarter_add_neon
913         cmp             r3,  #38
914         ble             idct16x16_half_add_neon
915
916         movrel          r8,  min_eob_idct_idct_16 + 2
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, d9,  d8,  d9  @ d16 = t16a, d9  = t19a
1189         butterfly       d17, d20, d23, d20 @ d17 = t17,  d20 = t18
1190         butterfly       d18, d10, d11, d10 @ d18 = t23a, d10 = t20a
1191         butterfly       d19, d21, d22, d21 @ d19 = t22,  d21 = t21
1192         butterfly       d8,  d28, d28, d30 @ d8  = t24a, d28 = t27a
1193         butterfly       d23, d26, d25, d26 @ d23 = t25,  d26 = t26
1194         butterfly       d11, d29, d29, d31 @ d11 = t31a, d29 = t28a
1195         butterfly       d22, d27, d24, d27 @ d22 = t30,  d27 = t29
1196
1197         mbutterfly      d27, d20, d0[2], d0[3], q12, q15        @ d27 = t18a, d20 = t29a
1198         mbutterfly      d29, d9,  d0[2], d0[3], q12, q15        @ d29 = t19,  d5  = t28
1199         mbutterfly      d28, d10, d0[2], d0[3], q12, q15, neg=1 @ d28 = t27,  d6  = t20
1200         mbutterfly      d26, d21, d0[2], d0[3], q12, q15, neg=1 @ d26 = t26a, d21 = t21a
1201
1202         butterfly       d31, d24, d11, d8  @ 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, d9,  d28 @ d27 = t27a, d28 = t28a
1208         butterfly       d8,  d26, d20, d26 @ d8  = t29,  d26 = t26
1209         butterfly       d19, d20, d29, d10 @ d19 = t19a, d20 = t20
1210         vmov            d29, d8            @ d29 = t29
1211
1212         mbutterfly0     d27, d20, d27, d20, d8, d10, q4, q5 @ d27 = t27,  d20 = t20
1213         mbutterfly0     d26, d21, d26, d21, d8, d10, q4, q5 @ d26 = t26a, d21 = t21a
1214         mbutterfly0     d25, d22, d25, d22, d8, d10, q4, q5 @ d25 = t25,  d22 = t22
1215         mbutterfly0     d24, d23, d24, d23, d8, d10, q4, q5 @ d24 = t24a, d23 = t23a
1216         bx              lr
1217 .endm
1218
1219 function idct32_odd
1220         mbutterfly      d16, d31, d4[0], d4[1], q4, q5 @ d16 = t16a, d31 = t31a
1221         mbutterfly      d24, d23, d4[2], d4[3], q4, q5 @ d24 = t17a, d23 = t30a
1222         mbutterfly      d20, d27, d5[0], d5[1], q4, q5 @ d20 = t18a, d27 = t29a
1223         mbutterfly      d28, d19, d5[2], d5[3], q4, q5 @ d28 = t19a, d19 = t28a
1224         mbutterfly      d18, d29, d6[0], d6[1], q4, q5 @ d18 = t20a, d29 = t27a
1225         mbutterfly      d26, d21, d6[2], d6[3], q4, q5 @ d26 = t21a, d21 = t26a
1226         mbutterfly      d22, d25, d7[0], d7[1], q4, q5 @ d22 = t22a, d25 = t25a
1227         mbutterfly      d30, d17, d7[2], d7[3], q4, q5 @ d30 = t23a, d17 = t24a
1228
1229         butterfly       d8,  d24, d16, d24 @ d8  = t16, d24 = t17
1230         butterfly       d9,  d20, d28, d20 @ d9  = t19, d20 = t18
1231         butterfly       d10, d26, d18, d26 @ d10 = t20, d26 = t21
1232         butterfly       d11, d22, d30, d22 @ d11 = t23, d22 = t22
1233         butterfly       d28, d25, d17, d25 @ d28 = t24, d25 = t25
1234         butterfly       d30, d21, d29, d21 @ d30 = t27, d21 = t26
1235         butterfly       d29, d23, d31, d23 @ d29 = t31, d23 = t30
1236         butterfly       d31, d27, d19, d27 @ d31 = t28, d27 = t29
1237
1238         mbutterfly      d23, d24, d1[0], d1[1], q8, q9        @ d23 = t17a, d24 = t30a
1239         mbutterfly      d27, d20, d1[0], d1[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a
1240         mbutterfly      d21, d26, d1[2], d1[3], q8, q9        @ d21 = t21a, d26 = t26a
1241         mbutterfly      d25, d22, d1[2], d1[3], q8, q9, neg=1 @ d25 = t25a, d22 = t22a
1242         idct32_end
1243 endfunc
1244
1245 function idct32_odd_half
1246         mbutterfly_h1   d16, d31, d4[0], d4[1], q4, q5 @ d16 = t16a, d31 = t31a
1247         mbutterfly_h2   d24, d23, d4[2], d4[3], q4, q5 @ d24 = t17a, d23 = t30a
1248         mbutterfly_h1   d20, d27, d5[0], d5[1], q4, q5 @ d20 = t18a, d27 = t29a
1249         mbutterfly_h2   d28, d19, d5[2], d5[3], q4, q5 @ d28 = t19a, d19 = t28a
1250         mbutterfly_h1   d18, d29, d6[0], d6[1], q4, q5 @ d18 = t20a, d29 = t27a
1251         mbutterfly_h2   d26, d21, d6[2], d6[3], q4, q5 @ d26 = t21a, d21 = t26a
1252         mbutterfly_h1   d22, d25, d7[0], d7[1], q4, q5 @ d22 = t22a, d25 = t25a
1253         mbutterfly_h2   d30, d17, d7[2], d7[3], q4, q5 @ d30 = t23a, d17 = t24a
1254
1255         butterfly       d8,  d24, d16, d24 @ d8  = t16, d24 = t17
1256         butterfly       d9,  d20, d28, d20 @ d9  = t19, d20 = t18
1257         butterfly       d10, d26, d18, d26 @ d10 = t20, d26 = t21
1258         butterfly       d11, d22, d30, d22 @ d11 = t23, d22 = t22
1259         butterfly       d28, d25, d17, d25 @ d28 = t24, d25 = t25
1260         butterfly       d30, d21, d29, d21 @ d30 = t27, d21 = t26
1261         butterfly       d29, d23, d31, d23 @ d29 = t31, d23 = t30
1262         butterfly       d31, d27, d19, d27 @ d31 = t28, d27 = t29
1263
1264         mbutterfly      d23, d24, d1[0], d1[1], q8, q9        @ d23 = t17a, d24 = t30a
1265         mbutterfly      d27, d20, d1[0], d1[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a
1266         mbutterfly      d21, d26, d1[2], d1[3], q8, q9        @ d21 = t21a, d26 = t26a
1267         mbutterfly      d25, d22, d1[2], d1[3], q8, q9, neg=1 @ d25 = t25a, d22 = t22a
1268
1269         idct32_end
1270 endfunc
1271
1272 function idct32_odd_quarter
1273         vmull.s16       q4,  d16, d4[0]
1274         vmull.s16       q14, d19, d5[3]
1275         vmull.s16       q15, d16, d4[1]
1276         vmull.s16       q11, d17, d7[2]
1277         vmull.s16       q5,  d17, d7[3]
1278         vmull.s16       q13, d19, d5[2]
1279         vmull.s16       q10, d18, d6[0]
1280         vmull.s16       q12, d18, d6[1]
1281
1282         vneg.s32        q14, q14
1283         vneg.s32        q5,  q5
1284
1285         vrshrn.s32      d8,  q4,  #14
1286         vrshrn.s32      d9,  q14, #14
1287         vrshrn.s32      d29, q15, #14
1288         vrshrn.s32      d28, q11, #14
1289         vrshrn.s32      d11, q5,  #14
1290         vrshrn.s32      d31, q13, #14
1291         vrshrn.s32      d10, q10, #14
1292         vrshrn.s32      d30, q12, #14
1293
1294         mbutterfly_l    q8,  q9,  d29, d8,  d1[0], d1[1]
1295         mbutterfly_l    q13, q10, d31, d9,  d1[0], d1[1]
1296         vrshrn.s32      d23, q8,  #14
1297         vrshrn.s32      d24, q9,  #14
1298         vneg.s32        q10, q10
1299         vrshrn.s32      d27, q13, #14
1300         vrshrn.s32      d20, q10, #14
1301         mbutterfly_l    q8,  q9,  d30, d10, d1[2], d1[3]
1302         vrshrn.s32      d21, q8,  #14
1303         vrshrn.s32      d26, q9,  #14
1304         mbutterfly_l    q8,  q9,  d28, d11, d1[2], d1[3]
1305         vrshrn.s32      d25, q8,  #14
1306         vneg.s32        q9,  q9
1307         vrshrn.s32      d22, q9,  #14
1308
1309         idct32_end
1310 endfunc
1311
1312 .macro idct32_funcs suffix
1313 @ Do an 32-point IDCT of a 4x32 slice out of a 32x32 matrix.
1314 @ We don't have register space to do a single pass IDCT of 4x32 though,
1315 @ but the 32-point IDCT can be decomposed into two 16-point IDCTs;
1316 @ a normal IDCT16 with every other input component (the even ones, with
1317 @ each output written twice), followed by a separate 16-point IDCT
1318 @ of the odd inputs, added/subtracted onto the outputs of the first idct16.
1319 @ r0 = dst (temp buffer)
1320 @ r1 = unused
1321 @ r2 = src
1322 function idct32_1d_4x32_pass1\suffix\()_neon
1323         push            {lr}
1324
1325         @ idct16 clobbers q2-q3 (since it doesn't clobber q4-q7 at all
1326         @ when doing the normal 16x16 idct), so move the idct32_odd coeffs
1327         @ to q4-q5
1328         vmov            q4,  q2
1329         vmov            q5,  q3
1330
1331         @ Double stride of the input, since we only read every other line
1332         mov             r12, #128
1333         vmov.s16        d4,  #0
1334
1335         @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30)
1336 .ifb \suffix
1337 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1338         vld1.16         {d\i}, [r2,:64]
1339         vst1.16         {d4},  [r2,:64], r12
1340 .endr
1341 .endif
1342 .ifc \suffix,_quarter
1343 .irp i, 16, 17, 18, 19
1344         vld1.16         {d\i}, [r2,:64]
1345         vst1.16         {d4},  [r2,:64], r12
1346 .endr
1347 .endif
1348 .ifc \suffix,_half
1349 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1350         vld1.16         {d\i}, [r2,:64]
1351         vst1.16         {d4},  [r2,:64], r12
1352 .endr
1353 .endif
1354
1355         bl              idct16\suffix
1356
1357         @ Move the idct32_odd coeffs back into q2-q3 for idct32_odd;
1358         @ the constants for a vmul with a lane must be in q0-q3.
1359         vmov            q2,  q4
1360         vmov            q3,  q5
1361
1362         @ Do four 4x4 transposes. Originally, d16-d31 contain the
1363         @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31
1364         @ contain the transposed 4x4 blocks.
1365         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
1366         @ Store the registers a, b, c, d horizontally, followed
1367         @ by the same registers d, c, b, a mirrored.
1368 .macro store_rev a, b, c, d
1369 .irp i, \a, \b, \c, \d
1370         vst1.16         {d\i}, [r0,:64]!
1371         vrev64.16       d\i, d\i
1372 .endr
1373 .irp i, \d, \c, \b, \a
1374         vst1.16         {d\i}, [r0,:64]!
1375 .endr
1376 .endm
1377         store_rev       16, 20, 24, 28
1378         store_rev       17, 21, 25, 29
1379         store_rev       18, 22, 26, 30
1380         store_rev       19, 23, 27, 31
1381         sub             r0,  r0,  #256
1382 .purgem store_rev
1383
1384         @ Move r2 back to the start of the input, and move
1385         @ to the first odd row
1386 .ifb \suffix
1387         sub             r2,  r2,  r12, lsl #4
1388 .endif
1389 .ifc \suffix,_quarter
1390         sub             r2,  r2,  r12, lsl #2
1391 .endif
1392 .ifc \suffix,_half
1393         sub             r2,  r2,  r12, lsl #3
1394 .endif
1395         add             r2,  r2,  #64
1396
1397         vmov.s16        d8,  #0
1398         @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31)
1399 .ifb \suffix
1400 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1401         vld1.16         {d\i}, [r2,:64]
1402         vst1.16         {d8},  [r2,:64], r12
1403 .endr
1404 .endif
1405 .ifc \suffix,_quarter
1406 .irp i, 16, 17, 18, 19
1407         vld1.16         {d\i}, [r2,:64]
1408         vst1.16         {d8},  [r2,:64], r12
1409 .endr
1410 .endif
1411 .ifc \suffix,_half
1412 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1413         vld1.16         {d\i}, [r2,:64]
1414         vst1.16         {d8},  [r2,:64], r12
1415 .endr
1416 .endif
1417
1418         bl              idct32_odd\suffix
1419
1420         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
1421
1422         @ Store the registers a, b, c, d horizontally,
1423         @ adding into the output first, and then mirrored, subtracted
1424         @ from the output.
1425 .macro store_rev a, b, c, d
1426 .irp i, \a, \b, \c, \d
1427         vld1.16         {d8},  [r0,:64]
1428         vadd.s16        d8,  d8,  d\i
1429         vst1.16         {d8},  [r0,:64]!
1430         vrev64.16       d\i, d\i
1431 .endr
1432 .irp i, \d, \c, \b, \a
1433         vld1.16         {d8},  [r0,:64]
1434         vsub.s16        d8,  d8,  d\i
1435         vst1.16         {d8},  [r0,:64]!
1436 .endr
1437 .endm
1438
1439         store_rev       31, 27, 23, 19
1440         store_rev       30, 26, 22, 18
1441         store_rev       29, 25, 21, 17
1442         store_rev       28, 24, 20, 16
1443 .purgem store_rev
1444         pop             {pc}
1445 endfunc
1446 .ltorg
1447
1448 @ This is mostly the same as 4x32_pass1, but without the transpose,
1449 @ and use the source as temp buffer between the two idct passes, and
1450 @ add into the destination.
1451 @ r0 = dst
1452 @ r1 = dst stride
1453 @ r2 = src (temp buffer)
1454 function idct32_1d_4x32_pass2\suffix\()_neon
1455         push            {lr}
1456         vmov            q4,  q2
1457         vmov            q5,  q3
1458
1459         mov             r12, #128
1460         @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30)
1461 .ifb \suffix
1462 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1463         vld1.16         {d\i}, [r2,:64], r12
1464 .endr
1465         sub             r2,  r2,  r12, lsl #4
1466 .endif
1467 .ifc \suffix,_quarter
1468 .irp i, 16, 17, 18, 19
1469         vld1.16         {d\i}, [r2,:64], r12
1470 .endr
1471         sub             r2,  r2,  r12, lsl #2
1472 .endif
1473 .ifc \suffix,_half
1474 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1475         vld1.16         {d\i}, [r2,:64], r12
1476 .endr
1477         sub             r2,  r2,  r12, lsl #3
1478 .endif
1479
1480         bl              idct16\suffix
1481
1482         vmov            q2,  q4
1483         vmov            q3,  q5
1484
1485 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1486         vst1.16         {d\i}, [r2,:64], r12
1487 .endr
1488
1489         sub             r2,  r2,  r12, lsl #4
1490         add             r2,  r2,  #64
1491
1492         @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31)
1493 .ifb \suffix
1494 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1495         vld1.16         {d\i}, [r2,:64], r12
1496 .endr
1497         sub             r2,  r2,  r12, lsl #4
1498 .endif
1499 .ifc \suffix,_quarter
1500 .irp i, 16, 17, 18, 19
1501         vld1.16         {d\i}, [r2,:64], r12
1502 .endr
1503         sub             r2,  r2,  r12, lsl #2
1504 .endif
1505 .ifc \suffix,_half
1506 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1507         vld1.16         {d\i}, [r2,:64], r12
1508 .endr
1509         sub             r2,  r2,  r12, lsl #3
1510 .endif
1511         sub             r2,  r2,  #64
1512
1513         bl              idct32_odd\suffix
1514
1515         mov             r12, #128
1516 .macro load_acc_store a, b, c, d, neg=0
1517         vld1.16         {d8},  [r2,:64], r12
1518         vld1.16         {d9},  [r2,:64], r12
1519 .if \neg == 0
1520         vadd.s16        d8,  d8,  d\a
1521         vld1.16         {d10}, [r2,:64], r12
1522         vadd.s16        d9,  d9,  d\b
1523         vld1.16         {d11}, [r2,:64], r12
1524         vadd.s16        d10, d10, d\c
1525         vadd.s16        d11, d11, d\d
1526 .else
1527         vsub.s16        d8,  d8,  d\a
1528         vld1.16         {d10}, [r2,:64], r12
1529         vsub.s16        d9,  d9,  d\b
1530         vld1.16         {d11}, [r2,:64], r12
1531         vsub.s16        d10, d10, d\c
1532         vsub.s16        d11, d11, d\d
1533 .endif
1534         vld1.32         {d12[]},  [r0,:32], r1
1535         vld1.32         {d12[1]}, [r0,:32], r1
1536         vrshr.s16       q4,  q4,  #6
1537         vld1.32         {d13[]},  [r0,:32], r1
1538         vrshr.s16       q5,  q5,  #6
1539         vld1.32         {d13[1]}, [r0,:32], r1
1540         sub             r0,  r0,  r1, lsl #2
1541         vaddw.u8        q4,  q4,  d12
1542         vaddw.u8        q5,  q5,  d13
1543         vqmovun.s16     d8,  q4
1544         vqmovun.s16     d9,  q5
1545         vst1.32         {d8[0]},  [r0,:32], r1
1546         vst1.32         {d8[1]},  [r0,:32], r1
1547         vst1.32         {d9[0]},  [r0,:32], r1
1548         vst1.32         {d9[1]},  [r0,:32], r1
1549 .endm
1550         load_acc_store  31, 30, 29, 28
1551         load_acc_store  27, 26, 25, 24
1552         load_acc_store  23, 22, 21, 20
1553         load_acc_store  19, 18, 17, 16
1554         sub             r2,  r2,  r12
1555         neg             r12, r12
1556         load_acc_store  16, 17, 18, 19, 1
1557         load_acc_store  20, 21, 22, 23, 1
1558         load_acc_store  24, 25, 26, 27, 1
1559         load_acc_store  28, 29, 30, 31, 1
1560 .purgem load_acc_store
1561         pop             {pc}
1562 endfunc
1563 .endm
1564
1565 idct32_funcs
1566 idct32_funcs _quarter
1567 idct32_funcs _half
1568
1569 const min_eob_idct_idct_32, align=4
1570         .short  0, 9, 34, 70, 135, 240, 336, 448
1571 endconst
1572
1573 function ff_vp9_idct_idct_32x32_add_neon, export=1
1574         cmp             r3,  #1
1575         beq             idct32x32_dc_add_neon
1576         push            {r4-r8,lr}
1577         vpush           {q4-q6}
1578
1579         @ Align the stack, allocate a temp buffer
1580 T       mov             r7,  sp
1581 T       and             r7,  r7,  #15
1582 A       and             r7,  sp,  #15
1583         add             r7,  r7,  #2048
1584         sub             sp,  sp,  r7
1585
1586         mov             r4,  r0
1587         mov             r5,  r1
1588         mov             r6,  r2
1589
1590         movrel          r12, idct_coeffs
1591         vld1.16         {q0-q1}, [r12,:128]!
1592         vld1.16         {q2-q3}, [r12,:128]
1593
1594         cmp             r3,  #34
1595         ble             idct32x32_quarter_add_neon
1596         cmp             r3,  #135
1597         ble             idct32x32_half_add_neon
1598
1599         movrel          r8,  min_eob_idct_idct_32 + 2
1600
1601 .irp i, 0, 4, 8, 12, 16, 20, 24, 28
1602         add             r0,  sp,  #(\i*64)
1603 .if \i > 0
1604         ldrh_post       r1,  r8,  #2
1605         cmp             r3,  r1
1606         it              le
1607         movle           r1,  #(32 - \i)/2
1608         ble             1f
1609 .endif
1610         add             r2,  r6,  #(\i*2)
1611         bl              idct32_1d_4x32_pass1_neon
1612 .endr
1613         b               3f
1614
1615 1:
1616         @ Write zeros to the temp buffer for pass 2
1617         vmov.i16        q14, #0
1618         vmov.i16        q15, #0
1619 2:
1620         subs            r1,  r1,  #1
1621 .rept 4
1622         vst1.16         {q14-q15}, [r0,:128]!
1623 .endr
1624         bne             2b
1625 3:
1626 .irp i, 0, 4, 8, 12, 16, 20, 24, 28
1627         add             r0,  r4,  #(\i)
1628         mov             r1,  r5
1629         add             r2,  sp,  #(\i*2)
1630         bl              idct32_1d_4x32_pass2_neon
1631 .endr
1632
1633         add             sp,  sp,  r7
1634         vpop            {q4-q6}
1635         pop             {r4-r8,pc}
1636 endfunc
1637
1638 .macro idct32_partial size
1639 function idct32x32_\size\()_add_neon
1640 .irp i, 0, 4
1641         add             r0,  sp,  #(\i*64)
1642 .ifc \size,quarter
1643 .if \i == 4
1644         cmp             r3,  #9
1645         ble             1f
1646 .endif
1647 .endif
1648         add             r2,  r6,  #(\i*2)
1649         bl              idct32_1d_4x32_pass1_\size\()_neon
1650 .endr
1651
1652 .ifc \size,half
1653 .irp i, 8, 12
1654         add             r0,  sp,  #(\i*64)
1655 .if \i == 12
1656         cmp             r3,  #70
1657         ble             1f
1658 .endif
1659         add             r2,  r6,  #(\i*2)
1660         bl              idct32_1d_4x32_pass1_\size\()_neon
1661 .endr
1662 .endif
1663         b               3f
1664
1665 1:
1666         @ Write zeros to the temp buffer for pass 2
1667         vmov.i16        q14, #0
1668         vmov.i16        q15, #0
1669 .rept 8
1670         vst1.16         {q14-q15}, [r0,:128]!
1671 .endr
1672
1673 3:
1674 .irp i, 0, 4, 8, 12, 16, 20, 24, 28
1675         add             r0,  r4,  #(\i)
1676         mov             r1,  r5
1677         add             r2,  sp,  #(\i*2)
1678         bl              idct32_1d_4x32_pass2_\size\()_neon
1679 .endr
1680
1681         add             sp,  sp,  r7
1682         vpop            {q4-q6}
1683         pop             {r4-r8,pc}
1684 endfunc
1685 .endm
1686
1687 idct32_partial quarter
1688 idct32_partial half