2 * Copyright (c) 2017 Google Inc.
4 * This file is part of FFmpeg.
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.
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.
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
21 #include "libavutil/arm/asm.S"
24 const itxfm4_coeffs, align=4
25 .short 11585, 0, 6270, 15137
27 .short 5283, 15212, 9929, 13377
30 const iadst8_coeffs, align=4
31 .short 16305, 1606, 14449, 7723, 10394, 12665, 4756, 15679
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
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
44 @ Do two 4x4 transposes, using q registers for the subtransposes that don't
45 @ need to address the individual d registers.
46 @ r0,r1 == rq1, r2,r3 == rq1, etc
47 .macro transpose32_q_2x_4x4 rq0, rq1, rq2, rq3, rq4, rq5, rq6, rq7, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15
48 vswp \r1, \r4 @ vtrn.64 \rq0, \rq2
49 vswp \r3, \r6 @ vtrn.64 \rq1, \rq3
50 vswp \r9, \r12 @ vtrn.64 \rq4, \rq6
51 vswp \r11, \r14 @ vtrn.64 \rq5, \rq7
58 @ Do eight 2x2 transposes.
59 .macro transpose32_8x_2x2 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15
70 @ out1 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14
71 @ out2 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14
72 @ in/out are d registers
73 .macro mbutterfly0 out1, out2, in1, in2, tmpd1, tmpd2, tmpq3, tmpq4, neg=0
74 vadd.s32 \tmpd1, \in1, \in2
75 vsub.s32 \tmpd2, \in1, \in2
77 vneg.s32 \tmpd1, \tmpd1
79 vmull.s32 \tmpq3, \tmpd1, d0[0]
80 vmull.s32 \tmpq4, \tmpd2, d0[0]
81 vrshrn.s64 \out1, \tmpq3, #14
82 vrshrn.s64 \out2, \tmpq4, #14
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.s32 \tmpq1, \in1, \in2
92 vsub.s32 \tmpq2, \in1, \in2
93 vmull.s32 \tmpq3, \tmpd11, d0[0]
94 vmull.s32 \tmpq4, \tmpd12, d0[0]
96 vrshrn.s64 \out1, \tmpq3, #14
97 vrshrn.s64 \out2, \tmpq4, #14
98 vmull.s32 \tmpq3, \tmpd21, d0[0]
99 vmull.s32 \tmpq4, \tmpd22, d0[0]
100 vrshrn.s64 \out3, \tmpq3, #14
101 vrshrn.s64 \out4, \tmpq4, #14
103 vmull.s32 \tmpq5, \tmpd21, d0[0]
104 vmull.s32 \tmpq6, \tmpd22, d0[0]
105 vrshrn.s64 \out1, \tmpq3, #14
106 vrshrn.s64 \out2, \tmpq4, #14
107 vrshrn.s64 \out3, \tmpq5, #14
108 vrshrn.s64 \out4, \tmpq6, #14
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, neg=0
116 vmull.s32 \out1, \in1, \coef1
117 vmlsl.s32 \out1, \in2, \coef2
120 vmlsl.s32 \out2, \in1, \coef2
121 vmlsl.s32 \out2, \in2, \coef1
123 vmull.s32 \out2, \in1, \coef2
124 vmlal.s32 \out2, \in2, \coef1
128 @ out1,out2 = in1,in2 * coef1 - in3,in4 * coef2
129 @ out3,out4 = in1,in2 * coef2 + in3,in4 * coef1
130 @ out are 4 q registers, in are 4 d registers
131 .macro dmbutterfly_l out1, out2, out3, out4, in1, in2, in3, in4, coef1, coef2
132 vmull.s32 \out1, \in1, \coef1
133 vmull.s32 \out2, \in2, \coef1
134 vmull.s32 \out3, \in1, \coef2
135 vmull.s32 \out4, \in2, \coef2
136 vmlsl.s32 \out1, \in3, \coef2
137 vmlsl.s32 \out2, \in4, \coef2
138 vmlal.s32 \out3, \in3, \coef1
139 vmlal.s32 \out4, \in4, \coef1
142 @ inout1 = (inout1 * coef1 - inout2 * coef2 + (1 << 13)) >> 14
143 @ inout2 = (inout1 * coef2 + inout2 * coef1 + (1 << 13)) >> 14
144 @ inout are 2 d registers, tmp are 2 q registers
145 .macro mbutterfly inout1, inout2, coef1, coef2, tmp1, tmp2, neg=0
146 mbutterfly_l \tmp1, \tmp2, \inout1, \inout2, \coef1, \coef2, \neg
147 vrshrn.s64 \inout1, \tmp1, #14
148 vrshrn.s64 \inout2, \tmp2, #14
151 @ inout1,inout2 = (inout1,inout2 * coef1 - inout3,inout4 * coef2 + (1 << 13)) >> 14
152 @ inout3,inout4 = (inout1,inout2 * coef2 + inout3,inout4 * coef1 + (1 << 13)) >> 14
153 @ inout are 4 d registers, tmp are 4 q registers
154 .macro dmbutterfly inout1, inout2, inout3, inout4, coef1, coef2, tmp1, tmp2, tmp3, tmp4
155 dmbutterfly_l \tmp1, \tmp2, \tmp3, \tmp4, \inout1, \inout2, \inout3, \inout4, \coef1, \coef2
156 vrshrn.s64 \inout1, \tmp1, #14
157 vrshrn.s64 \inout2, \tmp2, #14
158 vrshrn.s64 \inout3, \tmp3, #14
159 vrshrn.s64 \inout4, \tmp4, #14
164 .macro butterfly out1, out2, in1, in2
165 vadd.s32 \out1, \in1, \in2
166 vsub.s32 \out2, \in1, \in2
171 .macro butterfly_r out1, out2, in1, in2
172 vsub.s32 \out1, \in1, \in2
173 vadd.s32 \out2, \in1, \in2
176 @ out1 = (in1 + in2 + (1 << 13)) >> 14
177 @ out2 = (in1 - in2 + (1 << 13)) >> 14
178 @ out are 2 d registers, in are 2 q registers, tmp are 2 q registers
179 .macro butterfly_n out1, out2, in1, in2, tmp1, tmp2
180 vadd.s64 \tmp1, \in1, \in2
181 vsub.s64 \tmp2, \in1, \in2
182 vrshrn.s64 \out1, \tmp1, #14
183 vrshrn.s64 \out2, \tmp2, #14
186 @ out1,out2 = (in1,in2 + in3,in4 + (1 << 13)) >> 14
187 @ out3,out4 = (in1,in2 - in3,in4 + (1 << 13)) >> 14
188 @ out are 4 d registers, in are 4 q registers, tmp are 4 q registers
189 .macro dbutterfly_n out1, out2, out3, out4, in1, in2, in3, in4, tmp1, tmp2, tmp3, tmp4
190 vadd.s64 \tmp1, \in1, \in3
191 vadd.s64 \tmp2, \in2, \in4
192 vsub.s64 \tmp3, \in1, \in3
193 vsub.s64 \tmp4, \in2, \in4
194 vrshrn.s64 \out1, \tmp1, #14
195 vrshrn.s64 \out2, \tmp2, #14
196 vrshrn.s64 \out3, \tmp3, #14
197 vrshrn.s64 \out4, \tmp4, #14
201 .macro iwht4_10 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
202 vadd.i32 \c0, \c0, \c1
203 vsub.i32 q11, \c2, \c3
204 vsub.i32 q10, \c0, q11
205 vshr.s32 q10, q10, #1
206 vsub.i32 \c2, q10, \c1
207 vsub.i32 \c1, q10, \c3
208 vadd.i32 \c3, q11, \c2
209 vsub.i32 \c0, \c0, \c1
212 .macro iwht4_12 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
213 iwht4_10 \c0, \c1, \c2, \c3, \cd0, \cd1, \cd2, \cd3, \cd4, \cd5, \cd6, \cd7
216 @ c0 == cd0,cd1, c1 == cd2,cd3
217 .macro idct4_10 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
218 vmul.s32 q13, \c1, d1[1]
219 vmul.s32 q11, \c1, d1[0]
220 vadd.i32 q14, \c0, \c2
221 vsub.i32 q15, \c0, \c2
222 vmla.s32 q13, \c3, d1[0]
223 vmul.s32 q12, q14, d0[0]
224 vmul.s32 q10, q15, d0[0]
225 vmls.s32 q11, \c3, d1[1]
226 vrshr.s32 q13, q13, #14
227 vrshr.s32 q12, q12, #14
228 vrshr.s32 q10, q10, #14
229 vrshr.s32 q11, q11, #14
230 vadd.i32 \c0, q12, q13
231 vsub.i32 \c3, q12, q13
232 vadd.i32 \c1, q10, q11
233 vsub.i32 \c2, q10, q11
236 .macro idct4_12 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
237 vmull.s32 q13, \cd2, d1[1]
238 vmull.s32 q15, \cd3, d1[1]
239 vmull.s32 q11, \cd2, d1[0]
240 vmull.s32 q3, \cd3, d1[0]
241 vadd.i32 q14, \c0, \c2
242 vsub.i32 q2, \c0, \c2
243 vmlal.s32 q13, \cd6, d1[0]
244 vmlal.s32 q15, \cd7, d1[0]
245 vmull.s32 q12, d28, d0[0]
246 vmull.s32 q14, d29, d0[0]
247 vmull.s32 q10, d4, d0[0]
248 vmull.s32 q8, d5, d0[0]
249 vmlsl.s32 q11, \cd6, d1[1]
250 vmlsl.s32 q3, \cd7, d1[1]
251 vrshrn.s64 d26, q13, #14
252 vrshrn.s64 d27, q15, #14
253 vrshrn.s64 d24, q12, #14
254 vrshrn.s64 d25, q14, #14
255 vrshrn.s64 d20, q10, #14
256 vrshrn.s64 d21, q8, #14
257 vrshrn.s64 d22, q11, #14
258 vrshrn.s64 d23, q3, #14
259 vadd.i32 \c0, q12, q13
260 vsub.i32 \c3, q12, q13
261 vadd.i32 \c1, q10, q11
262 vsub.i32 \c2, q10, q11
265 .macro iadst4_10 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
266 vmul.s32 q10, \c0, d2[0]
267 vmla.s32 q10, \c2, d2[1]
268 vmla.s32 q10, \c3, d3[0]
269 vmul.s32 q11, \c0, d3[0]
270 vmls.s32 q11, \c2, d2[0]
271 vsub.s32 \c0, \c0, \c2
272 vmls.s32 q11, \c3, d2[1]
273 vadd.s32 \c0, \c0, \c3
274 vmul.s32 q13, \c1, d3[1]
275 vmul.s32 q12, \c0, d3[1]
276 vadd.s32 q14, q10, q13
277 vadd.s32 q15, q11, q13
278 vrshr.s32 \c0, q14, #14
279 vadd.s32 q10, q10, q11
280 vrshr.s32 \c1, q15, #14
281 vsub.s32 q10, q10, q13
282 vrshr.s32 \c2, q12, #14
283 vrshr.s32 \c3, q10, #14
286 .macro iadst4_12 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
287 vmull.s32 q10, \cd0, d2[0]
288 vmull.s32 q4, \cd1, d2[0]
289 vmlal.s32 q10, \cd4, d2[1]
290 vmlal.s32 q4, \cd5, d2[1]
291 vmlal.s32 q10, \cd6, d3[0]
292 vmlal.s32 q4, \cd7, d3[0]
293 vmull.s32 q11, \cd0, d3[0]
294 vmull.s32 q5, \cd1, d3[0]
295 vmlsl.s32 q11, \cd4, d2[0]
296 vmlsl.s32 q5, \cd5, d2[0]
297 vsub.s32 \c0, \c0, \c2
298 vmlsl.s32 q11, \cd6, d2[1]
299 vmlsl.s32 q5, \cd7, d2[1]
300 vadd.s32 \c0, \c0, \c3
301 vmull.s32 q13, \cd2, d3[1]
302 vmull.s32 q6, \cd3, d3[1]
303 vmull.s32 q12, \cd0, d3[1]
304 vmull.s32 q7, \cd1, d3[1]
305 vadd.s64 q14, q10, q13
307 vadd.s64 q15, q11, q13
309 vrshrn.s64 \cd1, q2, #14
310 vrshrn.s64 \cd0, q14, #14
311 vadd.s64 q10, q10, q11
313 vrshrn.s64 \cd3, q3, #14
314 vrshrn.s64 \cd2, q15, #14
315 vsub.s64 q10, q10, q13
317 vrshrn.s64 \cd4, q12, #14
318 vrshrn.s64 \cd5, q7, #14
319 vrshrn.s64 \cd6, q10, #14
320 vrshrn.s64 \cd7, q4, #14
323 @ The public functions in this file have got the following signature:
324 @ void itxfm_add(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
326 .macro itxfm_func4x4 txfm1, txfm2, bpp
327 function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_\bpp\()_neon, export=1
330 movrel r12, itxfm4_coeffs
331 vld1.16 {d0}, [r12,:64]
335 movrel r12, iadst4_coeffs
336 vld1.16 {d1}, [r12,:64]
340 movrel r12, itxfm4_coeffs
341 vld1.16 {q0}, [r12,:128]
346 .ifnc \txfm1\()_\txfm2,idct_idct
347 @ iadst4_12 needs q4-q7
354 .ifc \txfm1\()_\txfm2,idct_idct
357 @ DC-only for idct/idct
358 vld1.32 {d4[]}, [r2,:32]
359 vmull.s32 q2, d4, d0[0]
360 vrshrn.s64 d4, q2, #14
361 vmull.s32 q2, d4, d0[0]
362 vrshrn.s64 d4, q2, #14
363 vst1.32 {d30[0]}, [r2,:32]
372 vld1.32 {q2-q3}, [r2,:128]
373 vst1.32 {q14-q15}, [r2,:128]!
374 vld1.32 {q8-q9}, [r2,:128]
383 vst1.16 {q14-q15}, [r2,:128]!
384 \txfm1\()4_\bpp q2, q3, q8, q9, d4, d5, d6, d7, d16, d17, d18, d19
386 @ Transpose 4x4 with 32 bit elements
392 \txfm2\()4_\bpp q2, q3, q8, q9, d4, d5, d6, d7, d16, d17, d18, d19
394 vmvn.u16 q15, #((0xffff << \bpp) & 0xffff)
395 vld1.16 {d0}, [r0,:64], r1
396 vld1.16 {d1}, [r0,:64], r1
405 vld1.16 {d2}, [r0,:64], r1
406 vld1.16 {d3}, [r0,:64], r1
409 sub r0, r0, r1, lsl #2
414 vst1.16 {d0}, [r0,:64], r1
419 vst1.16 {d1}, [r0,:64], r1
420 vst1.16 {d2}, [r0,:64], r1
421 vst1.16 {d3}, [r0,:64], r1
424 .ifnc \txfm1\()_\txfm2,idct_idct
432 .macro itxfm_funcs4x4 bpp
433 itxfm_func4x4 idct, idct, \bpp
434 itxfm_func4x4 iadst, idct, \bpp
435 itxfm_func4x4 idct, iadst, \bpp
436 itxfm_func4x4 iadst, iadst, \bpp
437 itxfm_func4x4 iwht, iwht, \bpp
444 dmbutterfly0 d16, d17, d24, d25, q8, q12, q2, q4, d4, d5, d8, d9, q3, q2, q5, q4 @ q8 = t0a, q12 = t1a
445 dmbutterfly d20, d21, d28, d29, d1[0], d1[1], q2, q3, q4, q5 @ q10 = t2a, q14 = t3a
446 dmbutterfly d18, d19, d30, d31, d2[0], d2[1], q2, q3, q4, q5 @ q9 = t4a, q15 = t7a
447 dmbutterfly d26, d27, d22, d23, d3[0], d3[1], q2, q3, q4, q5 @ q13 = t5a, q11 = t6a
449 butterfly q2, q14, q8, q14 @ q2 = t0, q14 = t3
450 butterfly q3, q10, q12, q10 @ q3 = t1, q10 = t2
451 butterfly q4, q13, q9, q13 @ q4 = t4, q13 = t5a
452 butterfly q5, q11, q15, q11 @ q5 = t7, q11 = t6a
454 butterfly q8, q15, q2, q5 @ q8 = out[0], q15 = out[7]
456 dmbutterfly0 d4, d5, d10, d11, q11, q13, q9, q13, d18, d19, d26, d27, q2, q5, q11, q12 @ q2 = t6, q5 = t5
458 butterfly q11, q12, q14, q4 @ q11 = out[3], q12 = out[4]
459 butterfly q9, q14, q3, q2 @ q9 = out[1], q14 = out[6]
460 butterfly_r q13, q10, q10, q5 @ q13 = out[5], q10 = out[2]
464 movrel r12, iadst8_coeffs
465 vld1.16 {q1}, [r12,:128]!
469 dmbutterfly_l q4, q5, q2, q3, d30, d31, d16, d17, d0[1], d0[0] @ q4,q5 = t1a, q2,q3 = t0a
470 dmbutterfly_l q8, q15, q6, q7, d22, d23, d24, d25, d2[1], d2[0] @ q8,q15 = t5a, q6,q7 = t4a
472 dbutterfly_n d22, d23, d4, d5, q2, q3, q6, q7, q11, q12, q2, q3 @ q11 = t0, q2 = t4
474 dbutterfly_n d24, d25, d6, d7, q4, q5, q8, q15, q12, q3, q6, q7 @ q12 = t1, q3 = t5
476 dmbutterfly_l q6, q7, q4, q5, d26, d27, d20, d21, d1[1], d1[0] @ q6,q7 = t3a, q4,q5 = t2a
477 dmbutterfly_l q10, q13, q8, q15, d18, d19, d28, d29, d3[1], d3[0] @ q10,q13 = t7a, q8,q15 = t6a
479 dbutterfly_n d18, d19, d8, d9, q4, q5, q8, q15, q9, q14, q4, q5 @ q9 = t2, q4 = t6
480 dbutterfly_n d16, d17, d12, d13, q6, q7, q10, q13, q8, q15, q6, q7 @ q8 = t3, q6 = t7
482 movrel r12, idct_coeffs
483 vld1.16 {q0}, [r12,:128]
487 butterfly q15, q12, q12, q8 @ q15 = -out[7], q12 = t3
488 vneg.s32 q15, q15 @ q15 = out[7]
489 butterfly q8, q9, q11, q9 @ q8 = out[0], q9 = t2
491 dmbutterfly_l q10, q11, q5, q7, d4, d5, d6, d7, d1[0], d1[1] @ q10,q11 = t5a, q5,q7 = t4a
492 dmbutterfly_l q2, q3, q13, q14, d12, d13, d8, d9, d1[1], d1[0] @ q2,q3 = t6a, q13,q14 = t7a
494 dbutterfly_n d28, d29, d8, d9, q10, q11, q13, q14, q4, q6, q10, q11 @ q14 = out[6], q4 = t7
496 dmbutterfly0 d22, d23, d24, d25, q9, q12, q6, q13, d12, d13, d26, d27, q9, q10 @ q11 = -out[3], q12 = out[4]
497 vneg.s32 q11, q11 @ q11 = out[3]
499 dbutterfly_n d18, d19, d4, d5, q5, q7, q2, q3, q9, q10, q2, q3 @ q9 = -out[1], q2 = t6
500 vneg.s32 q9, q9 @ q9 = out[1]
502 dmbutterfly0 d20, d21, d26, d27, q2, q4, q3, q5, d6, d7, d10, d11, q6, q7 @ q10 = out[2], q13 = -out[5]
503 vneg.s32 q13, q13 @ q13 = out[5]
506 function idct8x8_dc_add_neon
507 movrel r12, idct_coeffs
508 vld1.16 {d0}, [r12,:64]
513 vld1.32 {d16[]}, [r2,:32]
514 vmull.s32 q8, d16, d0[0]
515 vrshrn.s64 d16, q8, #14
516 vmull.s32 q8, d16, d0[0]
517 vrshrn.s64 d16, q8, #14
519 vst1.32 {d4[0]}, [r2,:32]
527 @ Loop to add the constant from q8 into all 8x8 outputs
529 vld1.16 {q2}, [r0,:128], r1
530 vaddw.u16 q10, q8, d4
531 vld1.16 {q3}, [r0,:128], r1
532 vaddw.u16 q11, q8, d5
533 vaddw.u16 q12, q8, d6
534 vaddw.u16 q13, q8, d7
540 vst1.16 {q2}, [r3,:128], r1
542 vst1.16 {q3}, [r3,:128], r1
549 .macro itxfm8_1d_funcs txfm
550 @ Read a vertical 4x8 slice out of a 8x8 matrix, do a transform on it,
551 @ transpose into a horizontal 8x4 slice and store.
552 @ r0 = dst (temp buffer)
555 function \txfm\()8_1d_4x8_pass1_neon
558 .irp i, 8, 9, 10, 11, 12, 13, 14, 15
559 vld1.32 {q\i}, [r2,:128]
560 vst1.32 {q2}, [r2,:128], r12
565 @ Do two 4x4 transposes. Originally, q8-q15 contain the
566 @ 8 rows. Afterwards, q8-q11, q12-q15 contain the transposed
568 transpose32_q_2x_4x4 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
570 @ Store the transposed 4x4 blocks horizontally.
573 .irp i, 8, 12, 9, 13, 10, 14, 11, 15
574 vst1.32 {q\i}, [r0,:128]!
578 @ Special case: For the last input column (r1 == 4),
579 @ which would be stored as the last row in the temp buffer,
580 @ don't store the first 4x4 block, but keep it in registers
581 @ for the first slice of the second pass (where it is the
583 .irp i, 12, 13, 14, 15
585 vst1.32 {q\i}, [r0,:128]!
594 @ Read a vertical 4x8 slice out of a 8x8 matrix, do a transform on it,
595 @ load the destination pixels (from a similar 4x8 slice), add and store back.
598 @ r2 = src (temp buffer)
600 function \txfm\()8_1d_4x8_pass2_neon
603 vld1.32 {q\i}, [r2,:128], r12
607 .irp i, 12, 13, 14, 15
608 vld1.32 {q\i}, [r2,:128], r12
617 .macro load_add_store coef0, coef1, coef2, coef3
618 vld1.16 {d4}, [r0,:64], r1
619 vld1.16 {d5}, [r3,:64], r1
620 vld1.16 {d6}, [r0,:64], r1
621 vld1.16 {d7}, [r3,:64], r1
623 vrshr.s32 \coef0, \coef0, #5
624 vrshr.s32 \coef1, \coef1, #5
625 vrshr.s32 \coef2, \coef2, #5
626 vrshr.s32 \coef3, \coef3, #5
628 vaddw.u16 \coef0, \coef0, d4
629 vaddw.u16 \coef1, \coef1, d5
630 vaddw.u16 \coef2, \coef2, d6
631 vaddw.u16 \coef3, \coef3, d7
633 sub r0, r0, r1, lsl #1
634 sub r3, r3, r1, lsl #1
636 vqmovun.s32 d4, \coef0
637 vqmovun.s32 d5, \coef1
638 vqmovun.s32 d6, \coef2
639 vqmovun.s32 d7, \coef3
644 vst1.16 {d4}, [r0,:64], r1
645 vst1.16 {d5}, [r3,:64], r1
646 vst1.16 {d6}, [r0,:64], r1
647 vst1.16 {d7}, [r3,:64], r1
649 load_add_store q8, q9, q10, q11
650 load_add_store q12, q13, q14, q15
651 .purgem load_add_store
658 itxfm8_1d_funcs iadst
660 .macro itxfm_func8x8 txfm1, txfm2
661 function vp9_\txfm1\()_\txfm2\()_8x8_add_16_neon
662 .ifc \txfm1\()_\txfm2,idct_idct
664 beq idct8x8_dc_add_neon
666 .ifnc \txfm1\()_\txfm2,idct_idct
672 @ Align the stack, allocate a temp buffer
684 movrel r12, idct_coeffs
685 vld1.16 {q0}, [r12,:128]
692 .ifc \txfm1\()_\txfm2,idct_idct
700 bl \txfm1\()8_1d_4x8_pass1_neon
702 .ifc \txfm1\()_\txfm2,idct_idct
705 @ For all-zero slices in pass 1, set q12-q15 to zero, for the in-register
706 @ passthrough of coefficients to pass 2 and clear the end of the temp buffer
712 vst1.32 {q12-q13}, [r0,:128]!
716 .ifc \txfm1\()_\txfm2,iadst_idct
717 movrel r12, idct_coeffs
718 vld1.16 {q0}, [r12,:128]
727 bl \txfm2\()8_1d_4x8_pass2_neon
731 .ifnc \txfm1\()_\txfm2,idct_idct
739 function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_10_neon, export=1
742 b vp9_\txfm1\()_\txfm2\()_8x8_add_16_neon
745 function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_12_neon, export=1
748 b vp9_\txfm1\()_\txfm2\()_8x8_add_16_neon
752 itxfm_func8x8 idct, idct
753 itxfm_func8x8 iadst, idct
754 itxfm_func8x8 idct, iadst
755 itxfm_func8x8 iadst, iadst
757 function idct16x16_dc_add_neon
758 movrel r12, idct_coeffs
759 vld1.16 {d0}, [r12,:64]
764 vld1.32 {d16[]}, [r2,:32]
765 vmull.s32 q8, d16, d0[0]
766 vrshrn.s64 d16, q8, #14
767 vmull.s32 q8, d16, d0[0]
768 vrshrn.s64 d16, q8, #14
770 vst1.32 {d4[0]}, [r2,:32]
778 @ Loop to add the constant from q8 into all 16x16 outputs
780 vld1.16 {q0-q1}, [r0,:128], r1
782 vaddw.u16 q10, q8, d1
783 vld1.16 {q2-q3}, [r0,:128], r1
784 vaddw.u16 q11, q8, d2
785 vaddw.u16 q12, q8, d3
786 vaddw.u16 q13, q8, d4
787 vaddw.u16 q14, q8, d5
791 vaddw.u16 q10, q8, d7
800 vst1.16 {q0-q1}, [r3,:128], r1
803 vst1.16 {q2-q3}, [r3,:128], r1
811 mbutterfly0 d16, d24, d16, d24, d8, d10, q4, q5 @ d16 = t0a, d24 = t1a
812 mbutterfly d20, d28, d1[0], d1[1], q4, q5 @ d20 = t2a, d28 = t3a
813 mbutterfly d18, d30, d2[0], d2[1], q4, q5 @ d18 = t4a, d30 = t7a
814 mbutterfly d26, d22, d3[0], d3[1], q4, q5 @ d26 = t5a, d22 = t6a
815 mbutterfly d17, d31, d4[0], d4[1], q4, q5 @ d17 = t8a, d31 = t15a
816 mbutterfly d25, d23, d5[0], d5[1], q4, q5 @ d25 = t9a, d23 = t14a
817 mbutterfly d21, d27, d6[0], d6[1], q4, q5 @ d21 = t10a, d27 = t13a
818 mbutterfly d29, d19, d7[0], d7[1], q4, q5 @ d29 = t11a, d19 = t12a
820 butterfly d8, d28, d16, d28 @ d8 = t0, d28 = t3
821 butterfly d9, d20, d24, d20 @ d9 = t1, d20 = t2
822 butterfly d10, d26, d18, d26 @ d10 = t4, d26 = t5
823 butterfly d11, d22, d30, d22 @ d11 = t7, d22 = t6
824 butterfly d16, d25, d17, d25 @ d16 = t8, d25 = t9
825 butterfly d24, d21, d29, d21 @ d24 = t11, d21 = t10
826 butterfly d17, d27, d19, d27 @ d17 = t12, d27 = t13
827 butterfly d29, d23, d31, d23 @ d29 = t15, d23 = t14
829 mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a
830 mbutterfly d23, d25, d1[0], d1[1], q9, q15 @ d23 = t9a, d25 = t14a
831 mbutterfly d27, d21, d1[0], d1[1], q9, q15, neg=1 @ d27 = t13a, d21 = t10a
833 butterfly d18, d11, d8, d11 @ d18 = t0a, d11 = t7a
834 butterfly d19, d22, d9, d22 @ d19 = t1a, d22 = t6
835 butterfly d8, d26, d20, d26 @ d8 = t2a, d26 = t5
836 butterfly d9, d10, d28, d10 @ d9 = t3a, d10 = t4
837 butterfly d20, d28, d16, d24 @ d20 = t8a, d28 = t11a
838 butterfly d24, d21, d23, d21 @ d24 = t9, d21 = t10
839 butterfly d23, d27, d25, d27 @ d23 = t14, d27 = t13
840 butterfly d25, d29, d29, d17 @ d25 = t15a, d29 = t12a
842 mbutterfly0 d27, d21, d27, d21, d16, d30, q8, q15 @ d27 = t13a, d21 = t10a
843 mbutterfly0 d29, d28, d29, d28, d16, d30, q8, q15 @ d29 = t12, d28 = t11
845 vswp d27, d29 @ d27 = t12, d29 = t13a
846 vswp d28, d27 @ d28 = t12, d27 = t11
847 butterfly d16, d31, d18, d25 @ d16 = out[0], d31 = out[15]
848 butterfly d17, d30, d19, d23 @ d17 = out[1], d30 = out[14]
849 butterfly_r d25, d22, d22, d24 @ d25 = out[9], d22 = out[6]
850 butterfly d23, d24, d11, d20 @ d23 = out[7], d24 = out[8]
851 butterfly d18, d29, d8, d29 @ d18 = out[2], d29 = out[13]
852 butterfly d19, d28, d9, d28 @ d19 = out[3], d28 = out[12]
853 vmov d8, d21 @ d8 = t10a
854 butterfly d20, d27, d10, d27 @ d20 = out[4], d27 = out[11]
855 butterfly d21, d26, d26, d8 @ d21 = out[5], d26 = out[10]
859 movrel r12, iadst16_coeffs
860 vld1.16 {q0}, [r12,:128]!
864 mbutterfly_l q3, q2, d31, d16, d0[1], d0[0] @ q3 = t1, q2 = t0
865 mbutterfly_l q5, q4, d23, d24, d2[1], d2[0] @ q5 = t9, q4 = t8
866 butterfly_n d31, d24, q3, q5, q6, q5 @ d31 = t1a, d24 = t9a
867 mbutterfly_l q7, q6, d29, d18, d1[1], d1[0] @ q7 = t3, q6 = t2
868 butterfly_n d16, d23, q2, q4, q3, q4 @ d16 = t0a, d23 = t8a
869 mbutterfly_l q3, q2, d21, d26, d3[1], d3[0] @ q3 = t11, q2 = t10
871 vld1.16 {q0}, [r12,:128]!
872 butterfly_n d29, d26, q7, q3, q4, q3 @ d29 = t3a, d26 = t11a
875 mbutterfly_l q5, q4, d27, d20, d0[1], d0[0] @ q5 = t5, q4 = t4
876 butterfly_n d18, d21, q6, q2, q3, q2 @ d18 = t2a, d21 = t10a
878 mbutterfly_l q7, q6, d19, d28, d2[1], d2[0] @ q7 = t13, q6 = t12
879 butterfly_n d20, d28, q5, q7, q2, q7 @ d20 = t5a, d28 = t13a
880 mbutterfly_l q3, q2, d25, d22, d1[1], d1[0] @ q3 = t7, q2 = t6
881 butterfly_n d27, d19, q4, q6, q5, q6 @ d27 = t4a, d19 = t12a
883 mbutterfly_l q5, q4, d17, d30, d3[1], d3[0] @ q5 = t15, q4 = t14
884 movrel r12, idct_coeffs
885 vld1.16 {q0}, [r12,:128]
888 butterfly_n d22, d30, q3, q5, q6, q5 @ d22 = t7a, d30 = t15a
889 mbutterfly_l q7, q6, d23, d24, d2[0], d2[1] @ q7 = t9, q6 = t8
890 butterfly_n d25, d17, q2, q4, q3, q4 @ d25 = t6a, d17 = t14a
892 mbutterfly_l q2, q3, d28, d19, d2[1], d2[0] @ q2 = t12, q3 = t13
893 butterfly_n d23, d19, q6, q2, q4, q2 @ d23 = t8a, d19 = t12a
894 mbutterfly_l q5, q4, d21, d26, d3[0], d3[1] @ q5 = t11, q4 = t10
895 butterfly_r d4, d27, d16, d27 @ d4 = t4, d27 = t0
896 butterfly_n d24, d28, q7, q3, q6, q3 @ d24 = t9a, d28 = t13a
898 mbutterfly_l q6, q7, d30, d17, d3[1], d3[0] @ q6 = t14, q7 = t15
899 butterfly_r d5, d20, d31, d20 @ d5 = t5, d20 = t1
900 butterfly_n d21, d17, q4, q6, q3, q6 @ d21 = t10a, d17 = t14a
901 butterfly_n d26, d30, q5, q7, q4, q7 @ d26 = t11a, d30 = t15a
903 butterfly_r d6, d25, d18, d25 @ d6 = t6, d25 = t2
904 butterfly_r d7, d22, d29, d22 @ d7 = t7, d22 = t3
906 mbutterfly_l q5, q4, d19, d28, d1[0], d1[1] @ q5 = t13, q4 = t12
907 mbutterfly_l q6, q7, d30, d17, d1[1], d1[0] @ q6 = t14, q7 = t15
909 butterfly_n d18, d30, q4, q6, q8, q6 @ d18 = out[2], d30 = t14a
910 butterfly_n d29, d17, q5, q7, q6, q7 @ d29 = -out[13], d17 = t15a
911 vneg.s32 d29, d29 @ d29 = out[13]
913 mbutterfly_l q5, q4, d4, d5, d1[0], d1[1] @ q5 = t5a, q4 = t4a
914 mbutterfly_l q6, q7, d7, d6, d1[1], d1[0] @ q6 = t6a, q7 = t7a
916 butterfly d2, d6, d27, d25 @ d2 = out[0], d6 = t2a
917 butterfly d3, d7, d23, d21 @ d3 =-out[1], d7 = t10
919 butterfly_n d19, d31, q4, q6, q2, q4 @ d19 = -out[3], d31 = t6
920 vneg.s32 d19, d19 @ d19 = out[3]
921 butterfly_n d28, d16, q5, q7, q2, q5 @ d28 = out[12], d16 = t7
923 butterfly d5, d8, d20, d22 @ d5 =-out[15],d8 = t3a
924 butterfly d4, d9, d24, d26 @ d4 = out[14],d9 = t11
926 mbutterfly0 d23, d24, d6, d8, d10, d11, q6, q7, 1 @ d23 = out[7], d24 = out[8]
927 mbutterfly0 d20, d27, d16, d31, d10, d11, q6, q7 @ d20 = out[4], d27 = out[11]
928 mbutterfly0 d22, d25, d9, d7, d10, d11, q6, q7 @ d22 = out[6], d25 = out[9]
929 mbutterfly0 d21, d26, d30, d17, d10, d11, q6, q7, 1 @ d21 = out[5], d26 = out[10]
931 vneg.s32 d31, d5 @ d31 = out[15]
932 vneg.s32 d17, d3 @ d17 = out[1]
938 .macro itxfm16_1d_funcs txfm
939 @ Read a vertical 2x16 slice out of a 16x16 matrix, do a transform on it,
940 @ transpose into a horizontal 16x2 slice and store.
941 @ r0 = dst (temp buffer)
943 function \txfm\()16_1d_2x16_pass1_neon
946 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
947 vld1.32 {d\i}, [r2,:64]
948 vst1.32 {d8}, [r2,:64], r12
953 @ Do eight 2x2 transposes. Originally, d16-d31 contain the
954 @ 16 rows. Afterwards, d16-d17, d18-d19 etc contain the eight
955 @ transposed 2x2 blocks.
956 transpose32_8x_2x2 d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
958 @ Store the transposed 2x2 blocks horizontally.
959 .irp i, 16, 18, 20, 22, 24, 26, 28, 30, 17, 19, 21, 23, 25, 27, 29, 31
960 vst1.32 {d\i}, [r0,:64]!
965 @ Read a vertical 2x16 slice out of a 16x16 matrix, do a transform on it,
966 @ load the destination pixels (from a similar 2x16 slice), add and store back.
969 @ r2 = src (temp buffer)
970 function \txfm\()16_1d_2x16_pass2_neon
972 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
973 vld1.16 {d\i}, [r2,:64], r12
980 .macro load_add_store coef0, coef1, coef2, coef3
981 vrshr.s32 \coef0, \coef0, #6
982 vrshr.s32 \coef1, \coef1, #6
984 vld1.32 {d8[]}, [r0,:32], r1
985 vld1.32 {d8[1]}, [r3,:32], r1
986 vrshr.s32 \coef2, \coef2, #6
987 vrshr.s32 \coef3, \coef3, #6
988 vld1.32 {d9[]}, [r0,:32], r1
989 vld1.32 {d9[1]}, [r3,:32], r1
990 vaddw.u16 \coef0, \coef0, d8
991 vld1.32 {d10[]}, [r0,:32], r1
992 vld1.32 {d10[1]}, [r3,:32], r1
993 vaddw.u16 \coef1, \coef1, d9
994 vld1.32 {d11[]}, [r0,:32], r1
995 vld1.32 {d11[1]}, [r3,:32], r1
997 vqmovun.s32 d8, \coef0
999 vqmovun.s32 d9, \coef1
1000 sub r0, r0, r1, lsl #2
1001 sub r3, r3, r1, lsl #2
1002 vaddw.u16 \coef2, \coef2, d10
1003 vaddw.u16 \coef3, \coef3, d11
1005 vst1.32 {d8[0]}, [r0,:32], r1
1006 vst1.32 {d8[1]}, [r3,:32], r1
1007 vqmovun.s32 d10, \coef2
1008 vst1.32 {d9[0]}, [r0,:32], r1
1009 vst1.32 {d9[1]}, [r3,:32], r1
1010 vqmovun.s32 d11, \coef3
1013 vst1.32 {d10[0]}, [r0,:32], r1
1014 vst1.32 {d10[1]}, [r3,:32], r1
1015 vst1.32 {d11[0]}, [r0,:32], r1
1016 vst1.32 {d11[1]}, [r3,:32], r1
1018 load_add_store q8, q9, q10, q11
1019 load_add_store q12, q13, q14, q15
1020 .purgem load_add_store
1026 itxfm16_1d_funcs idct
1027 itxfm16_1d_funcs iadst
1029 @ This is the minimum eob value for each subpartition, in increments of 2
1030 const min_eob_idct_idct_16, align=4
1031 .short 0, 3, 10, 22, 38, 62, 89, 121
1034 .macro itxfm_func16x16 txfm1, txfm2
1035 function vp9_\txfm1\()_\txfm2\()_16x16_add_16_neon
1036 .ifc \txfm1\()_\txfm2,idct_idct
1038 beq idct16x16_dc_add_neon
1040 .ifnc \txfm1\()_\txfm2,idct_idct
1044 movrel r8, min_eob_idct_idct_16 + 2
1047 @ Align the stack, allocate a temp buffer
1059 movrel r12, idct_coeffs
1060 vld1.16 {q0-q1}, [r12,:128]
1067 .irp i, 0, 2, 4, 6, 8, 10, 12, 14
1068 add r0, sp, #(\i*64)
1069 .ifc \txfm1\()_\txfm2,idct_idct
1071 ldrh_post r1, r8, #2
1074 movle r1, #(16 - \i)/2
1079 bl \txfm1\()16_1d_2x16_pass1_neon
1082 .ifc \txfm1\()_\txfm2,idct_idct
1089 @ Unroll for 2 lines
1091 @ Fill one line with zeros
1092 vst1.32 {q14-q15}, [r0,:128]!
1093 vst1.32 {q14-q15}, [r0,:128]!
1099 .ifc \txfm1\()_\txfm2,iadst_idct
1100 movrel r12, idct_coeffs
1101 vld1.16 {q0-q1}, [r12,:128]
1107 .irp i, 0, 2, 4, 6, 8, 10, 12, 14
1111 bl \txfm2\()16_1d_2x16_pass2_neon
1115 .ifnc \txfm1\()_\txfm2,idct_idct
1123 function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_10_neon, export=1
1126 b vp9_\txfm1\()_\txfm2\()_16x16_add_16_neon
1129 function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_12_neon, export=1
1132 b vp9_\txfm1\()_\txfm2\()_16x16_add_16_neon
1136 itxfm_func16x16 idct, idct
1137 itxfm_func16x16 iadst, idct
1138 itxfm_func16x16 idct, iadst
1139 itxfm_func16x16 iadst, iadst
1143 function idct32x32_dc_add_neon
1144 movrel r12, idct_coeffs
1145 vld1.16 {d0}, [r12,:64]
1150 vld1.32 {d16[]}, [r2,:32]
1151 vmull.s32 q8, d16, d0[0]
1152 vrshrn.s64 d16, q8, #14
1153 vmull.s32 q8, d16, d0[0]
1154 vrshrn.s64 d16, q8, #14
1156 vst1.32 {d4[0]}, [r2,:32]
1158 vrshr.s32 q8, q8, #6
1165 @ Loop to add the constant from q8 into all 32x32 outputs
1167 vld1.16 {q0-q1}, [r0,:128]!
1168 vaddw.u16 q9, q8, d0
1169 vaddw.u16 q10, q8, d1
1170 vld1.16 {q2-q3}, [r0,:128], r1
1171 vaddw.u16 q11, q8, d2
1172 vaddw.u16 q12, q8, d3
1173 vaddw.u16 q13, q8, d4
1174 vaddw.u16 q14, q8, d5
1176 vaddw.u16 q9, q8, d6
1178 vaddw.u16 q10, q8, d7
1183 vmin.u16 q0, q0, q15
1184 vmin.u16 q1, q1, q15
1187 vst1.16 {q0-q1}, [r3,:128]!
1188 vmin.u16 q2, q2, q15
1189 vmin.u16 q3, q3, q15
1190 vst1.16 {q2-q3}, [r3,:128], r1
1197 movrel r12, idct_coeffs
1199 vld1.16 {q0-q1}, [r12,:128]
1205 mbutterfly d16, d31, d0[0], d0[1], q4, q5 @ d16 = t16a, d31 = t31a
1206 mbutterfly d24, d23, d1[0], d1[1], q4, q5 @ d24 = t17a, d23 = t30a
1207 mbutterfly d20, d27, d2[0], d2[1], q4, q5 @ d20 = t18a, d27 = t29a
1208 mbutterfly d28, d19, d3[0], d3[1], q4, q5 @ d28 = t19a, d19 = t28a
1209 mbutterfly d18, d29, d4[0], d4[1], q4, q5 @ d18 = t20a, d29 = t27a
1210 mbutterfly d26, d21, d5[0], d5[1], q4, q5 @ d26 = t21a, d21 = t26a
1211 mbutterfly d22, d25, d6[0], d6[1], q4, q5 @ d22 = t22a, d25 = t25a
1212 mbutterfly d30, d17, d7[0], d7[1], q4, q5 @ d30 = t23a, d17 = t24a
1215 vld1.16 {q0}, [r12,:128]
1219 butterfly d4, d24, d16, d24 @ d4 = t16, d24 = t17
1220 butterfly d5, d20, d28, d20 @ d5 = t19, d20 = t18
1221 butterfly d6, d26, d18, d26 @ d6 = t20, d26 = t21
1222 butterfly d7, d22, d30, d22 @ d7 = t23, d22 = t22
1223 butterfly d28, d25, d17, d25 @ d28 = t24, d25 = t25
1224 butterfly d30, d21, d29, d21 @ d30 = t27, d21 = t26
1225 butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30
1226 butterfly d31, d27, d19, d27 @ d31 = t28, d27 = t29
1228 mbutterfly d23, d24, d2[0], d2[1], q8, q9 @ d23 = t17a, d24 = t30a
1229 mbutterfly d27, d20, d2[0], d2[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a
1230 mbutterfly d21, d26, d3[0], d3[1], q8, q9 @ d21 = t21a, d26 = t26a
1231 mbutterfly d25, d22, d3[0], d3[1], q8, q9, neg=1 @ d25 = t25a, d22 = t22a
1233 butterfly d16, d5, d4, d5 @ d16 = t16a, d5 = t19a
1234 butterfly d17, d20, d23, d20 @ d17 = t17, d20 = t18
1235 butterfly d18, d6, d7, d6 @ d18 = t23a, d6 = t20a
1236 butterfly d19, d21, d22, d21 @ d19 = t22, d21 = t21
1237 butterfly d4, d28, d28, d30 @ d4 = t24a, d28 = t27a
1238 butterfly d23, d26, d25, d26 @ d23 = t25, d26 = t26
1239 butterfly d7, d29, d29, d31 @ d7 = t31a, d29 = t28a
1240 butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29
1242 mbutterfly d27, d20, d1[0], d1[1], q12, q15 @ d27 = t18a, d20 = t29a
1243 mbutterfly d29, d5, d1[0], d1[1], q12, q15 @ d29 = t19, d5 = t28
1244 mbutterfly d28, d6, d1[0], d1[1], q12, q15, neg=1 @ d28 = t27, d6 = t20
1245 mbutterfly d26, d21, d1[0], d1[1], q12, q15, neg=1 @ d26 = t26a, d21 = t21a
1247 butterfly d31, d24, d7, d4 @ d31 = t31, d24 = t24
1248 butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a
1249 butterfly_r d23, d16, d16, d18 @ d23 = t23, d16 = t16
1250 butterfly_r d22, d17, d17, d19 @ d22 = t22a, d17 = t17a
1251 butterfly d18, d21, d27, d21 @ d18 = t18, d21 = t21
1252 butterfly_r d27, d28, d5, d28 @ d27 = t27a, d28 = t28a
1253 butterfly d4, d26, d20, d26 @ d4 = t29, d26 = t26
1254 butterfly d19, d20, d29, d6 @ d19 = t19a, d20 = t20
1255 vmov d29, d4 @ d29 = t29
1257 mbutterfly0 d27, d20, d27, d20, d4, d6, q2, q3 @ d27 = t27, d20 = t20
1258 mbutterfly0 d26, d21, d26, d21, d4, d6, q2, q3 @ d26 = t26a, d21 = t21a
1259 mbutterfly0 d25, d22, d25, d22, d4, d6, q2, q3 @ d25 = t25, d22 = t22
1260 mbutterfly0 d24, d23, d24, d23, d4, d6, q2, q3 @ d24 = t24a, d23 = t23a
1263 @ Do an 32-point IDCT of a 2x32 slice out of a 32x32 matrix.
1264 @ We don't have register space to do a single pass IDCT of 2x32 though,
1265 @ but the 32-point IDCT can be decomposed into two 16-point IDCTs;
1266 @ a normal IDCT16 with every other input component (the even ones, with
1267 @ each output written twice), followed by a separate 16-point IDCT
1268 @ of the odd inputs, added/subtracted onto the outputs of the first idct16.
1269 @ r0 = dst (temp buffer)
1272 function idct32_1d_2x32_pass1_neon
1273 movrel r12, idct_coeffs
1274 vld1.16 {q0-q1}, [r12,:128]
1280 @ Double stride of the input, since we only read every other line
1284 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30)
1285 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1286 vld1.32 {d\i}, [r2,:64]
1287 vst1.32 {d8}, [r2,:64], r12
1292 @ Do eight 2x2 transposes. Originally, d16-d31 contain the
1293 @ 16 rows. Afterwards, d16-d17, d18-d19 etc contain the eight
1294 @ transposed 2x2 blocks.
1295 transpose32_8x_2x2 d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
1297 @ Store the registers a, b, c, d, e, f, g, h horizontally, followed
1298 @ by the same registers h, g, f, e, d, c, b, a mirrored.
1299 .macro store_rev a, b, c, d, e, f, g, h
1300 .irp i, \a, \b, \c, \d, \e, \f, \g, \h
1301 vst1.32 {d\i}, [r0,:64]!
1304 .irp i, \h, \g, \f, \e, \d, \c, \b, \a
1305 vst1.32 {d\i}, [r0,:64]!
1308 store_rev 16, 18, 20, 22, 24, 26, 28, 30
1309 store_rev 17, 19, 21, 23, 25, 27, 29, 31
1313 @ Move r2 back to the start of the input, and move
1314 @ to the first odd row
1315 sub r2, r2, r12, lsl #4
1319 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31)
1320 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1321 vld1.16 {d\i}, [r2,:64]
1322 vst1.16 {d4}, [r2,:64], r12
1327 transpose32_8x_2x2 d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16
1329 @ Store the registers a, b, c, d, e, f, g, h horizontally,
1330 @ adding into the output first, and then mirrored, subtracted
1332 .macro store_rev a, b, c, d, e, f, g, h
1333 .irp i, \a, \b, \c, \d, \e, \f, \g, \h
1334 vld1.32 {d4}, [r0,:64]
1335 vadd.s32 d4, d4, d\i
1336 vst1.32 {d4}, [r0,:64]!
1339 .irp i, \h, \g, \f, \e, \d, \c, \b, \a
1340 vld1.32 {d4}, [r0,:64]
1341 vsub.s32 d4, d4, d\i
1342 vst1.32 {d4}, [r0,:64]!
1346 store_rev 31, 29, 27, 25, 23, 21, 19, 17
1347 store_rev 30, 28, 26, 24, 22, 20, 18, 16
1353 @ This is mostly the same as 2x32_pass1, but without the transpose,
1354 @ and use the source as temp buffer between the two idct passes, and
1355 @ add into the destination.
1358 @ r2 = src (temp buffer)
1359 function idct32_1d_2x32_pass2_neon
1360 movrel r12, idct_coeffs
1361 vld1.16 {q0-q1}, [r12,:128]
1368 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30)
1369 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1370 vld1.32 {d\i}, [r2,:64], r12
1372 sub r2, r2, r12, lsl #4
1376 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1377 vst1.32 {d\i}, [r2,:64], r12
1380 sub r2, r2, r12, lsl #4
1383 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31)
1384 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1385 vld1.32 {d\i}, [r2,:64], r12
1387 sub r2, r2, r12, lsl #4
1394 .macro load_acc_store a, b, c, d, neg=0
1395 vld1.32 {d4}, [r2,:64], r12
1396 vld1.32 {d5}, [r2,:64], r12
1398 vadd.s32 d4, d4, d\a
1399 vld1.32 {d6}, [r2,:64], r12
1400 vadd.s32 d5, d5, d\b
1401 vld1.32 {d7}, [r2,:64], r12
1402 vadd.s32 d6, d6, d\c
1403 vadd.s32 d7, d7, d\d
1405 vsub.s32 d4, d4, d\a
1406 vld1.32 {d6}, [r2,:64], r12
1407 vsub.s32 d5, d5, d\b
1408 vld1.32 {d7}, [r2,:64], r12
1409 vsub.s32 d6, d6, d\c
1410 vsub.s32 d7, d7, d\d
1412 vld1.32 {d2[]}, [r0,:32], r1
1413 vld1.32 {d2[1]}, [r0,:32], r1
1414 vrshr.s32 q2, q2, #6
1415 vld1.32 {d3[]}, [r0,:32], r1
1416 vrshr.s32 q3, q3, #6
1417 vld1.32 {d3[1]}, [r0,:32], r1
1418 sub r0, r0, r1, lsl #2
1419 vaddw.u16 q2, q2, d2
1420 vaddw.u16 q3, q3, d3
1424 vst1.32 {d4[0]}, [r0,:32], r1
1425 vst1.32 {d4[1]}, [r0,:32], r1
1426 vst1.32 {d5[0]}, [r0,:32], r1
1427 vst1.32 {d5[1]}, [r0,:32], r1
1429 load_acc_store 31, 30, 29, 28
1430 load_acc_store 27, 26, 25, 24
1431 load_acc_store 23, 22, 21, 20
1432 load_acc_store 19, 18, 17, 16
1435 load_acc_store 16, 17, 18, 19, 1
1436 load_acc_store 20, 21, 22, 23, 1
1437 load_acc_store 24, 25, 26, 27, 1
1438 load_acc_store 28, 29, 30, 31, 1
1439 .purgem load_acc_store
1443 const min_eob_idct_idct_32, align=4
1444 .short 0, 3, 9, 21, 34, 51, 70, 98, 135, 176, 240, 258, 336, 357, 448, 472
1447 function vp9_idct_idct_32x32_add_16_neon
1449 beq idct32x32_dc_add_neon
1451 movrel r8, min_eob_idct_idct_32 + 2
1453 @ Align the stack, allocate a temp buffer
1464 .irp i, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
1465 add r0, sp, #(\i*128)
1467 ldrh_post r1, r8, #2
1470 movle r1, #(32 - \i)/2
1474 bl idct32_1d_2x32_pass1_neon
1479 @ Write zeros to the temp buffer for pass 2
1485 @ Fill one line with zeros
1486 vst1.16 {q14-q15}, [r0,:128]!
1487 vst1.16 {q14-q15}, [r0,:128]!
1488 vst1.16 {q14-q15}, [r0,:128]!
1489 vst1.16 {q14-q15}, [r0,:128]!
1493 .irp i, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
1497 bl idct32_1d_2x32_pass2_neon
1505 function ff_vp9_idct_idct_32x32_add_10_neon, export=1
1508 b vp9_idct_idct_32x32_add_16_neon
1511 function ff_vp9_idct_idct_32x32_add_12_neon, export=1
1514 b vp9_idct_idct_32x32_add_16_neon