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 @ Same as mbutterfly0 above, but treating the input in in2 as zero,
86 @ writing the same output into both out1 and out2.
87 .macro mbutterfly0_h out1, out2, in1, in2, tmpd1, tmpd2, tmpq3, tmpq4
88 vmull.s32 \tmpq3, \in1, d0[0]
89 vrshrn.s64 \out1, \tmpq3, #14
90 vrshrn.s64 \out2, \tmpq3, #14
93 @ out1,out2 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14
94 @ out3,out4 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14
95 @ Same as mbutterfly0, but with input being 2 q registers, output
96 @ being 4 d registers.
97 @ This can do with either 4 or 6 temporary q registers.
98 .macro dmbutterfly0 out1, out2, out3, out4, in1, in2, tmpq1, tmpq2, tmpd11, tmpd12, tmpd21, tmpd22, tmpq3, tmpq4, tmpq5, tmpq6
99 vadd.s32 \tmpq1, \in1, \in2
100 vsub.s32 \tmpq2, \in1, \in2
101 vmull.s32 \tmpq3, \tmpd11, d0[0]
102 vmull.s32 \tmpq4, \tmpd12, d0[0]
104 vrshrn.s64 \out1, \tmpq3, #14
105 vrshrn.s64 \out2, \tmpq4, #14
106 vmull.s32 \tmpq3, \tmpd21, d0[0]
107 vmull.s32 \tmpq4, \tmpd22, d0[0]
108 vrshrn.s64 \out3, \tmpq3, #14
109 vrshrn.s64 \out4, \tmpq4, #14
111 vmull.s32 \tmpq5, \tmpd21, d0[0]
112 vmull.s32 \tmpq6, \tmpd22, d0[0]
113 vrshrn.s64 \out1, \tmpq3, #14
114 vrshrn.s64 \out2, \tmpq4, #14
115 vrshrn.s64 \out3, \tmpq5, #14
116 vrshrn.s64 \out4, \tmpq6, #14
120 @ out1 = in1 * coef1 - in2 * coef2
121 @ out2 = in1 * coef2 + in2 * coef1
122 @ out are 2 q registers, in are 2 d registers
123 .macro mbutterfly_l out1, out2, in1, in2, coef1, coef2, neg=0
124 vmull.s32 \out1, \in1, \coef1
125 vmlsl.s32 \out1, \in2, \coef2
128 vmlsl.s32 \out2, \in1, \coef2
129 vmlsl.s32 \out2, \in2, \coef1
131 vmull.s32 \out2, \in1, \coef2
132 vmlal.s32 \out2, \in2, \coef1
136 @ out1,out2 = in1,in2 * coef1 - in3,in4 * coef2
137 @ out3,out4 = in1,in2 * coef2 + in3,in4 * coef1
138 @ out are 4 q registers, in are 4 d registers
139 .macro dmbutterfly_l out1, out2, out3, out4, in1, in2, in3, in4, coef1, coef2
140 vmull.s32 \out1, \in1, \coef1
141 vmull.s32 \out2, \in2, \coef1
142 vmull.s32 \out3, \in1, \coef2
143 vmull.s32 \out4, \in2, \coef2
144 vmlsl.s32 \out1, \in3, \coef2
145 vmlsl.s32 \out2, \in4, \coef2
146 vmlal.s32 \out3, \in3, \coef1
147 vmlal.s32 \out4, \in4, \coef1
150 @ inout1 = (inout1 * coef1 - inout2 * coef2 + (1 << 13)) >> 14
151 @ inout2 = (inout1 * coef2 + inout2 * coef1 + (1 << 13)) >> 14
152 @ inout are 2 d registers, tmp are 2 q registers
153 .macro mbutterfly inout1, inout2, coef1, coef2, tmp1, tmp2, neg=0
154 mbutterfly_l \tmp1, \tmp2, \inout1, \inout2, \coef1, \coef2, \neg
155 vrshrn.s64 \inout1, \tmp1, #14
156 vrshrn.s64 \inout2, \tmp2, #14
159 @ Same as mbutterfly above, but treating the input in inout2 as zero
160 .macro mbutterfly_h1 inout1, inout2, coef1, coef2, tmp1, tmp2
161 vmull.s32 \tmp1, \inout1, \coef1
162 vmull.s32 \tmp2, \inout1, \coef2
163 vrshrn.s64 \inout1, \tmp1, #14
164 vrshrn.s64 \inout2, \tmp2, #14
167 @ Same as mbutterfly above, but treating the input in inout1 as zero
168 .macro mbutterfly_h2 inout1, inout2, coef1, coef2, tmp1, tmp2
170 vmull.s32 \tmp2, \inout2, \coef1
171 vmlsl.s32 \tmp1, \inout2, \coef2
172 vrshrn.s64 \inout2, \tmp2, #14
173 vrshrn.s64 \inout1, \tmp1, #14
176 @ inout1,inout2 = (inout1,inout2 * coef1 - inout3,inout4 * coef2 + (1 << 13)) >> 14
177 @ inout3,inout4 = (inout1,inout2 * coef2 + inout3,inout4 * coef1 + (1 << 13)) >> 14
178 @ inout are 4 d registers, tmp are 4 q registers
179 .macro dmbutterfly inout1, inout2, inout3, inout4, coef1, coef2, tmp1, tmp2, tmp3, tmp4
180 dmbutterfly_l \tmp1, \tmp2, \tmp3, \tmp4, \inout1, \inout2, \inout3, \inout4, \coef1, \coef2
181 vrshrn.s64 \inout1, \tmp1, #14
182 vrshrn.s64 \inout2, \tmp2, #14
183 vrshrn.s64 \inout3, \tmp3, #14
184 vrshrn.s64 \inout4, \tmp4, #14
189 .macro butterfly out1, out2, in1, in2
190 vadd.s32 \out1, \in1, \in2
191 vsub.s32 \out2, \in1, \in2
196 .macro butterfly_r out1, out2, in1, in2
197 vsub.s32 \out1, \in1, \in2
198 vadd.s32 \out2, \in1, \in2
201 @ out1 = (in1 + in2 + (1 << 13)) >> 14
202 @ out2 = (in1 - in2 + (1 << 13)) >> 14
203 @ out are 2 d registers, in are 2 q registers, tmp are 2 q registers
204 .macro butterfly_n out1, out2, in1, in2, tmp1, tmp2
205 vadd.s64 \tmp1, \in1, \in2
206 vsub.s64 \tmp2, \in1, \in2
207 vrshrn.s64 \out1, \tmp1, #14
208 vrshrn.s64 \out2, \tmp2, #14
211 @ out1,out2 = (in1,in2 + in3,in4 + (1 << 13)) >> 14
212 @ out3,out4 = (in1,in2 - in3,in4 + (1 << 13)) >> 14
213 @ out are 4 d registers, in are 4 q registers, tmp are 4 q registers
214 .macro dbutterfly_n out1, out2, out3, out4, in1, in2, in3, in4, tmp1, tmp2, tmp3, tmp4
215 vadd.s64 \tmp1, \in1, \in3
216 vadd.s64 \tmp2, \in2, \in4
217 vsub.s64 \tmp3, \in1, \in3
218 vsub.s64 \tmp4, \in2, \in4
219 vrshrn.s64 \out1, \tmp1, #14
220 vrshrn.s64 \out2, \tmp2, #14
221 vrshrn.s64 \out3, \tmp3, #14
222 vrshrn.s64 \out4, \tmp4, #14
226 .macro iwht4_10 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
227 vadd.i32 \c0, \c0, \c1
228 vsub.i32 q11, \c2, \c3
229 vsub.i32 q10, \c0, q11
230 vshr.s32 q10, q10, #1
231 vsub.i32 \c2, q10, \c1
232 vsub.i32 \c1, q10, \c3
233 vadd.i32 \c3, q11, \c2
234 vsub.i32 \c0, \c0, \c1
237 .macro iwht4_12 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
238 iwht4_10 \c0, \c1, \c2, \c3, \cd0, \cd1, \cd2, \cd3, \cd4, \cd5, \cd6, \cd7
241 @ c0 == cd0,cd1, c1 == cd2,cd3
242 .macro idct4_10 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
243 vmul.s32 q13, \c1, d1[1]
244 vmul.s32 q11, \c1, d1[0]
245 vadd.i32 q14, \c0, \c2
246 vsub.i32 q15, \c0, \c2
247 vmla.s32 q13, \c3, d1[0]
248 vmul.s32 q12, q14, d0[0]
249 vmul.s32 q10, q15, d0[0]
250 vmls.s32 q11, \c3, d1[1]
251 vrshr.s32 q13, q13, #14
252 vrshr.s32 q12, q12, #14
253 vrshr.s32 q10, q10, #14
254 vrshr.s32 q11, q11, #14
255 vadd.i32 \c0, q12, q13
256 vsub.i32 \c3, q12, q13
257 vadd.i32 \c1, q10, q11
258 vsub.i32 \c2, q10, q11
261 .macro idct4_12 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
262 vmull.s32 q13, \cd2, d1[1]
263 vmull.s32 q15, \cd3, d1[1]
264 vmull.s32 q11, \cd2, d1[0]
265 vmull.s32 q3, \cd3, d1[0]
266 vadd.i32 q14, \c0, \c2
267 vsub.i32 q2, \c0, \c2
268 vmlal.s32 q13, \cd6, d1[0]
269 vmlal.s32 q15, \cd7, d1[0]
270 vmull.s32 q12, d28, d0[0]
271 vmull.s32 q14, d29, d0[0]
272 vmull.s32 q10, d4, d0[0]
273 vmull.s32 q8, d5, d0[0]
274 vmlsl.s32 q11, \cd6, d1[1]
275 vmlsl.s32 q3, \cd7, d1[1]
276 vrshrn.s64 d26, q13, #14
277 vrshrn.s64 d27, q15, #14
278 vrshrn.s64 d24, q12, #14
279 vrshrn.s64 d25, q14, #14
280 vrshrn.s64 d20, q10, #14
281 vrshrn.s64 d21, q8, #14
282 vrshrn.s64 d22, q11, #14
283 vrshrn.s64 d23, q3, #14
284 vadd.i32 \c0, q12, q13
285 vsub.i32 \c3, q12, q13
286 vadd.i32 \c1, q10, q11
287 vsub.i32 \c2, q10, q11
290 .macro iadst4_10 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
291 vmul.s32 q10, \c0, d2[0]
292 vmla.s32 q10, \c2, d2[1]
293 vmla.s32 q10, \c3, d3[0]
294 vmul.s32 q11, \c0, d3[0]
295 vmls.s32 q11, \c2, d2[0]
296 vsub.s32 \c0, \c0, \c2
297 vmls.s32 q11, \c3, d2[1]
298 vadd.s32 \c0, \c0, \c3
299 vmul.s32 q13, \c1, d3[1]
300 vmul.s32 q12, \c0, d3[1]
301 vadd.s32 q14, q10, q13
302 vadd.s32 q15, q11, q13
303 vrshr.s32 \c0, q14, #14
304 vadd.s32 q10, q10, q11
305 vrshr.s32 \c1, q15, #14
306 vsub.s32 q10, q10, q13
307 vrshr.s32 \c2, q12, #14
308 vrshr.s32 \c3, q10, #14
311 .macro iadst4_12 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
312 vmull.s32 q10, \cd0, d2[0]
313 vmull.s32 q4, \cd1, d2[0]
314 vmlal.s32 q10, \cd4, d2[1]
315 vmlal.s32 q4, \cd5, d2[1]
316 vmlal.s32 q10, \cd6, d3[0]
317 vmlal.s32 q4, \cd7, d3[0]
318 vmull.s32 q11, \cd0, d3[0]
319 vmull.s32 q5, \cd1, d3[0]
320 vmlsl.s32 q11, \cd4, d2[0]
321 vmlsl.s32 q5, \cd5, d2[0]
322 vsub.s32 \c0, \c0, \c2
323 vmlsl.s32 q11, \cd6, d2[1]
324 vmlsl.s32 q5, \cd7, d2[1]
325 vadd.s32 \c0, \c0, \c3
326 vmull.s32 q13, \cd2, d3[1]
327 vmull.s32 q6, \cd3, d3[1]
328 vmull.s32 q12, \cd0, d3[1]
329 vmull.s32 q7, \cd1, d3[1]
330 vadd.s64 q14, q10, q13
332 vadd.s64 q15, q11, q13
334 vrshrn.s64 \cd1, q2, #14
335 vrshrn.s64 \cd0, q14, #14
336 vadd.s64 q10, q10, q11
338 vrshrn.s64 \cd3, q3, #14
339 vrshrn.s64 \cd2, q15, #14
340 vsub.s64 q10, q10, q13
342 vrshrn.s64 \cd4, q12, #14
343 vrshrn.s64 \cd5, q7, #14
344 vrshrn.s64 \cd6, q10, #14
345 vrshrn.s64 \cd7, q4, #14
348 @ The public functions in this file have got the following signature:
349 @ void itxfm_add(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
351 .macro itxfm_func4x4 txfm1, txfm2, bpp
352 function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_\bpp\()_neon, export=1
355 movrel r12, itxfm4_coeffs
356 vld1.16 {d0}, [r12,:64]
360 movrel r12, iadst4_coeffs
361 vld1.16 {d1}, [r12,:64]
365 movrel r12, itxfm4_coeffs
366 vld1.16 {q0}, [r12,:128]
371 .ifnc \txfm1\()_\txfm2,idct_idct
372 @ iadst4_12 needs q4-q7
379 .ifc \txfm1\()_\txfm2,idct_idct
382 @ DC-only for idct/idct
383 vld1.32 {d4[]}, [r2,:32]
384 vmull.s32 q2, d4, d0[0]
385 vrshrn.s64 d4, q2, #14
386 vmull.s32 q2, d4, d0[0]
387 vrshrn.s64 d4, q2, #14
388 vst1.32 {d30[0]}, [r2,:32]
397 vld1.32 {q2-q3}, [r2,:128]
398 vst1.32 {q14-q15}, [r2,:128]!
399 vld1.32 {q8-q9}, [r2,:128]
408 vst1.16 {q14-q15}, [r2,:128]!
409 \txfm1\()4_\bpp q2, q3, q8, q9, d4, d5, d6, d7, d16, d17, d18, d19
411 @ Transpose 4x4 with 32 bit elements
417 \txfm2\()4_\bpp q2, q3, q8, q9, d4, d5, d6, d7, d16, d17, d18, d19
419 vmvn.u16 q15, #((0xffff << \bpp) & 0xffff)
420 vld1.16 {d0}, [r0,:64], r1
421 vld1.16 {d1}, [r0,:64], r1
430 vld1.16 {d2}, [r0,:64], r1
431 vld1.16 {d3}, [r0,:64], r1
434 sub r0, r0, r1, lsl #2
439 vst1.16 {d0}, [r0,:64], r1
444 vst1.16 {d1}, [r0,:64], r1
445 vst1.16 {d2}, [r0,:64], r1
446 vst1.16 {d3}, [r0,:64], r1
449 .ifnc \txfm1\()_\txfm2,idct_idct
457 .macro itxfm_funcs4x4 bpp
458 itxfm_func4x4 idct, idct, \bpp
459 itxfm_func4x4 iadst, idct, \bpp
460 itxfm_func4x4 idct, iadst, \bpp
461 itxfm_func4x4 iadst, iadst, \bpp
462 itxfm_func4x4 iwht, iwht, \bpp
469 dmbutterfly0 d16, d17, d24, d25, q8, q12, q2, q4, d4, d5, d8, d9, q3, q2, q5, q4 @ q8 = t0a, q12 = t1a
470 dmbutterfly d20, d21, d28, d29, d1[0], d1[1], q2, q3, q4, q5 @ q10 = t2a, q14 = t3a
471 dmbutterfly d18, d19, d30, d31, d2[0], d2[1], q2, q3, q4, q5 @ q9 = t4a, q15 = t7a
472 dmbutterfly d26, d27, d22, d23, d3[0], d3[1], q2, q3, q4, q5 @ q13 = t5a, q11 = t6a
474 butterfly q2, q14, q8, q14 @ q2 = t0, q14 = t3
475 butterfly q3, q10, q12, q10 @ q3 = t1, q10 = t2
476 butterfly q4, q13, q9, q13 @ q4 = t4, q13 = t5a
477 butterfly q5, q11, q15, q11 @ q5 = t7, q11 = t6a
479 butterfly q8, q15, q2, q5 @ q8 = out[0], q15 = out[7]
481 dmbutterfly0 d4, d5, d10, d11, q11, q13, q9, q13, d18, d19, d26, d27, q2, q5, q11, q12 @ q2 = t6, q5 = t5
483 butterfly q11, q12, q14, q4 @ q11 = out[3], q12 = out[4]
484 butterfly q9, q14, q3, q2 @ q9 = out[1], q14 = out[6]
485 butterfly_r q13, q10, q10, q5 @ q13 = out[5], q10 = out[2]
489 movrel r12, iadst8_coeffs
490 vld1.16 {q1}, [r12,:128]!
494 dmbutterfly_l q4, q5, q2, q3, d30, d31, d16, d17, d0[1], d0[0] @ q4,q5 = t1a, q2,q3 = t0a
495 dmbutterfly_l q8, q15, q6, q7, d22, d23, d24, d25, d2[1], d2[0] @ q8,q15 = t5a, q6,q7 = t4a
497 dbutterfly_n d22, d23, d4, d5, q2, q3, q6, q7, q11, q12, q2, q3 @ q11 = t0, q2 = t4
499 dbutterfly_n d24, d25, d6, d7, q4, q5, q8, q15, q12, q3, q6, q7 @ q12 = t1, q3 = t5
501 dmbutterfly_l q6, q7, q4, q5, d26, d27, d20, d21, d1[1], d1[0] @ q6,q7 = t3a, q4,q5 = t2a
502 dmbutterfly_l q10, q13, q8, q15, d18, d19, d28, d29, d3[1], d3[0] @ q10,q13 = t7a, q8,q15 = t6a
504 dbutterfly_n d18, d19, d8, d9, q4, q5, q8, q15, q9, q14, q4, q5 @ q9 = t2, q4 = t6
505 dbutterfly_n d16, d17, d12, d13, q6, q7, q10, q13, q8, q15, q6, q7 @ q8 = t3, q6 = t7
507 movrel r12, idct_coeffs
508 vld1.16 {q0}, [r12,:128]
512 butterfly q15, q12, q12, q8 @ q15 = -out[7], q12 = t3
513 vneg.s32 q15, q15 @ q15 = out[7]
514 butterfly q8, q9, q11, q9 @ q8 = out[0], q9 = t2
516 dmbutterfly_l q10, q11, q5, q7, d4, d5, d6, d7, d1[0], d1[1] @ q10,q11 = t5a, q5,q7 = t4a
517 dmbutterfly_l q2, q3, q13, q14, d12, d13, d8, d9, d1[1], d1[0] @ q2,q3 = t6a, q13,q14 = t7a
519 dbutterfly_n d28, d29, d8, d9, q10, q11, q13, q14, q4, q6, q10, q11 @ q14 = out[6], q4 = t7
521 dmbutterfly0 d22, d23, d24, d25, q9, q12, q6, q13, d12, d13, d26, d27, q9, q10 @ q11 = -out[3], q12 = out[4]
522 vneg.s32 q11, q11 @ q11 = out[3]
524 dbutterfly_n d18, d19, d4, d5, q5, q7, q2, q3, q9, q10, q2, q3 @ q9 = -out[1], q2 = t6
525 vneg.s32 q9, q9 @ q9 = out[1]
527 dmbutterfly0 d20, d21, d26, d27, q2, q4, q3, q5, d6, d7, d10, d11, q6, q7 @ q10 = out[2], q13 = -out[5]
528 vneg.s32 q13, q13 @ q13 = out[5]
531 function idct8x8_dc_add_neon
532 movrel r12, idct_coeffs
533 vld1.16 {d0}, [r12,:64]
538 vld1.32 {d16[]}, [r2,:32]
539 vmull.s32 q8, d16, d0[0]
540 vrshrn.s64 d16, q8, #14
541 vmull.s32 q8, d16, d0[0]
542 vrshrn.s64 d16, q8, #14
544 vst1.32 {d4[0]}, [r2,:32]
552 @ Loop to add the constant from q8 into all 8x8 outputs
554 vld1.16 {q2}, [r0,:128], r1
555 vaddw.u16 q10, q8, d4
556 vld1.16 {q3}, [r0,:128], r1
557 vaddw.u16 q11, q8, d5
558 vaddw.u16 q12, q8, d6
559 vaddw.u16 q13, q8, d7
565 vst1.16 {q2}, [r3,:128], r1
567 vst1.16 {q3}, [r3,:128], r1
574 .macro itxfm8_1d_funcs txfm
575 @ Read a vertical 4x8 slice out of a 8x8 matrix, do a transform on it,
576 @ transpose into a horizontal 8x4 slice and store.
577 @ r0 = dst (temp buffer)
580 function \txfm\()8_1d_4x8_pass1_neon
583 .irp i, 8, 9, 10, 11, 12, 13, 14, 15
584 vld1.32 {q\i}, [r2,:128]
585 vst1.32 {q2}, [r2,:128], r12
590 @ Do two 4x4 transposes. Originally, q8-q15 contain the
591 @ 8 rows. Afterwards, q8-q11, q12-q15 contain the transposed
593 transpose32_q_2x_4x4 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
595 @ Store the transposed 4x4 blocks horizontally.
598 .irp i, 8, 12, 9, 13, 10, 14, 11, 15
599 vst1.32 {q\i}, [r0,:128]!
603 @ Special case: For the last input column (r1 == 4),
604 @ which would be stored as the last row in the temp buffer,
605 @ don't store the first 4x4 block, but keep it in registers
606 @ for the first slice of the second pass (where it is the
608 .irp i, 12, 13, 14, 15
610 vst1.32 {q\i}, [r0,:128]!
619 @ Read a vertical 4x8 slice out of a 8x8 matrix, do a transform on it,
620 @ load the destination pixels (from a similar 4x8 slice), add and store back.
623 @ r2 = src (temp buffer)
625 function \txfm\()8_1d_4x8_pass2_neon
628 vld1.32 {q\i}, [r2,:128], r12
632 .irp i, 12, 13, 14, 15
633 vld1.32 {q\i}, [r2,:128], r12
642 .macro load_add_store coef0, coef1, coef2, coef3
643 vld1.16 {d4}, [r0,:64], r1
644 vld1.16 {d5}, [r3,:64], r1
645 vld1.16 {d6}, [r0,:64], r1
646 vld1.16 {d7}, [r3,:64], r1
648 vrshr.s32 \coef0, \coef0, #5
649 vrshr.s32 \coef1, \coef1, #5
650 vrshr.s32 \coef2, \coef2, #5
651 vrshr.s32 \coef3, \coef3, #5
653 vaddw.u16 \coef0, \coef0, d4
654 vaddw.u16 \coef1, \coef1, d5
655 vaddw.u16 \coef2, \coef2, d6
656 vaddw.u16 \coef3, \coef3, d7
658 sub r0, r0, r1, lsl #1
659 sub r3, r3, r1, lsl #1
661 vqmovun.s32 d4, \coef0
662 vqmovun.s32 d5, \coef1
663 vqmovun.s32 d6, \coef2
664 vqmovun.s32 d7, \coef3
669 vst1.16 {d4}, [r0,:64], r1
670 vst1.16 {d5}, [r3,:64], r1
671 vst1.16 {d6}, [r0,:64], r1
672 vst1.16 {d7}, [r3,:64], r1
674 load_add_store q8, q9, q10, q11
675 load_add_store q12, q13, q14, q15
676 .purgem load_add_store
683 itxfm8_1d_funcs iadst
685 .macro itxfm_func8x8 txfm1, txfm2
686 function vp9_\txfm1\()_\txfm2\()_8x8_add_16_neon
687 .ifc \txfm1\()_\txfm2,idct_idct
689 beq idct8x8_dc_add_neon
691 .ifnc \txfm1\()_\txfm2,idct_idct
697 @ Align the stack, allocate a temp buffer
709 movrel r12, idct_coeffs
710 vld1.16 {q0}, [r12,:128]
717 .ifc \txfm1\()_\txfm2,idct_idct
725 bl \txfm1\()8_1d_4x8_pass1_neon
727 .ifc \txfm1\()_\txfm2,idct_idct
730 @ For all-zero slices in pass 1, set q12-q15 to zero, for the in-register
731 @ passthrough of coefficients to pass 2 and clear the end of the temp buffer
737 vst1.32 {q12-q13}, [r0,:128]!
741 .ifc \txfm1\()_\txfm2,iadst_idct
742 movrel r12, idct_coeffs
743 vld1.16 {q0}, [r12,:128]
752 bl \txfm2\()8_1d_4x8_pass2_neon
756 .ifnc \txfm1\()_\txfm2,idct_idct
764 function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_10_neon, export=1
767 b vp9_\txfm1\()_\txfm2\()_8x8_add_16_neon
770 function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_12_neon, export=1
773 b vp9_\txfm1\()_\txfm2\()_8x8_add_16_neon
777 itxfm_func8x8 idct, idct
778 itxfm_func8x8 iadst, idct
779 itxfm_func8x8 idct, iadst
780 itxfm_func8x8 iadst, iadst
782 function idct16x16_dc_add_neon
783 movrel r12, idct_coeffs
784 vld1.16 {d0}, [r12,:64]
789 vld1.32 {d16[]}, [r2,:32]
790 vmull.s32 q8, d16, d0[0]
791 vrshrn.s64 d16, q8, #14
792 vmull.s32 q8, d16, d0[0]
793 vrshrn.s64 d16, q8, #14
795 vst1.32 {d4[0]}, [r2,:32]
803 @ Loop to add the constant from q8 into all 16x16 outputs
805 vld1.16 {q0-q1}, [r0,:128], r1
807 vaddw.u16 q10, q8, d1
808 vld1.16 {q2-q3}, [r0,:128], r1
809 vaddw.u16 q11, q8, d2
810 vaddw.u16 q12, q8, d3
811 vaddw.u16 q13, q8, d4
812 vaddw.u16 q14, q8, d5
816 vaddw.u16 q10, q8, d7
825 vst1.16 {q0-q1}, [r3,:128], r1
828 vst1.16 {q2-q3}, [r3,:128], r1
836 butterfly d18, d11, d8, d11 @ d18 = t0a, d11 = t7a
837 butterfly d19, d22, d9, d22 @ d19 = t1a, d22 = t6
838 butterfly d8, d26, d20, d26 @ d8 = t2a, d26 = t5
839 butterfly d9, d10, d28, d10 @ d9 = t3a, d10 = t4
840 butterfly d20, d28, d16, d24 @ d20 = t8a, d28 = t11a
841 butterfly d24, d21, d23, d21 @ d24 = t9, d21 = t10
842 butterfly d23, d27, d25, d27 @ d23 = t14, d27 = t13
843 butterfly d25, d29, d29, d17 @ d25 = t15a, d29 = t12a
845 mbutterfly0 d27, d21, d27, d21, d16, d30, q8, q15 @ d27 = t13a, d21 = t10a
846 mbutterfly0 d29, d28, d29, d28, d16, d30, q8, q15 @ d29 = t12, d28 = t11
848 vswp d27, d29 @ d27 = t12, d29 = t13a
849 vswp d28, d27 @ d28 = t12, d27 = t11
850 butterfly d16, d31, d18, d25 @ d16 = out[0], d31 = out[15]
851 butterfly d17, d30, d19, d23 @ d17 = out[1], d30 = out[14]
852 butterfly_r d25, d22, d22, d24 @ d25 = out[9], d22 = out[6]
853 butterfly d23, d24, d11, d20 @ d23 = out[7], d24 = out[8]
854 butterfly d18, d29, d8, d29 @ d18 = out[2], d29 = out[13]
855 butterfly d19, d28, d9, d28 @ d19 = out[3], d28 = out[12]
856 vmov d8, d21 @ d8 = t10a
857 butterfly d20, d27, d10, d27 @ d20 = out[4], d27 = out[11]
858 butterfly d21, d26, d26, d8 @ d21 = out[5], d26 = out[10]
863 mbutterfly0 d16, d24, d16, d24, d8, d10, q4, q5 @ d16 = t0a, d24 = t1a
864 mbutterfly d20, d28, d1[0], d1[1], q4, q5 @ d20 = t2a, d28 = t3a
865 mbutterfly d18, d30, d2[0], d2[1], q4, q5 @ d18 = t4a, d30 = t7a
866 mbutterfly d26, d22, d3[0], d3[1], q4, q5 @ d26 = t5a, d22 = t6a
867 mbutterfly d17, d31, d4[0], d4[1], q4, q5 @ d17 = t8a, d31 = t15a
868 mbutterfly d25, d23, d5[0], d5[1], q4, q5 @ d25 = t9a, d23 = t14a
869 mbutterfly d21, d27, d6[0], d6[1], q4, q5 @ d21 = t10a, d27 = t13a
870 mbutterfly d29, d19, d7[0], d7[1], q4, q5 @ d29 = t11a, d19 = t12a
872 butterfly d8, d28, d16, d28 @ d8 = t0, d28 = t3
873 butterfly d9, d20, d24, d20 @ d9 = t1, d20 = t2
874 butterfly d10, d26, d18, d26 @ d10 = t4, d26 = t5
875 butterfly d11, d22, d30, d22 @ d11 = t7, d22 = t6
876 butterfly d16, d25, d17, d25 @ d16 = t8, d25 = t9
877 butterfly d24, d21, d29, d21 @ d24 = t11, d21 = t10
878 butterfly d17, d27, d19, d27 @ d17 = t12, d27 = t13
879 butterfly d29, d23, d31, d23 @ d29 = t15, d23 = t14
881 mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a
882 mbutterfly d23, d25, d1[0], d1[1], q9, q15 @ d23 = t9a, d25 = t14a
883 mbutterfly d27, d21, d1[0], d1[1], q9, q15, neg=1 @ d27 = t13a, d21 = t10a
888 mbutterfly0_h d16, d24, d16, d24, d8, d10, q4, q5 @ d16 = t0a, d24 = t1a
889 mbutterfly_h1 d20, d28, d1[0], d1[1], q4, q5 @ d20 = t2a, d28 = t3a
890 mbutterfly_h1 d18, d30, d2[0], d2[1], q4, q5 @ d18 = t4a, d30 = t7a
891 mbutterfly_h2 d26, d22, d3[0], d3[1], q4, q5 @ d26 = t5a, d22 = t6a
892 mbutterfly_h1 d17, d31, d4[0], d4[1], q4, q5 @ d17 = t8a, d31 = t15a
893 mbutterfly_h2 d25, d23, d5[0], d5[1], q4, q5 @ d25 = t9a, d23 = t14a
894 mbutterfly_h1 d21, d27, d6[0], d6[1], q4, q5 @ d21 = t10a, d27 = t13a
895 mbutterfly_h2 d29, d19, d7[0], d7[1], q4, q5 @ d29 = t11a, d19 = t12a
897 butterfly d8, d28, d16, d28 @ d8 = t0, d28 = t3
898 butterfly d9, d20, d24, d20 @ d9 = t1, d20 = t2
899 butterfly d10, d26, d18, d26 @ d10 = t4, d26 = t5
900 butterfly d11, d22, d30, d22 @ d11 = t7, d22 = t6
901 butterfly d16, d25, d17, d25 @ d16 = t8, d25 = t9
902 butterfly d24, d21, d29, d21 @ d24 = t11, d21 = t10
903 butterfly d17, d27, d19, d27 @ d17 = t12, d27 = t13
904 butterfly d29, d23, d31, d23 @ d29 = t15, d23 = t14
906 mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a
907 mbutterfly d23, d25, d1[0], d1[1], q9, q15 @ d23 = t9a, d25 = t14a
908 mbutterfly d27, d21, d1[0], d1[1], q9, q15, neg=1 @ d27 = t13a, d21 = t10a
912 function idct16_quarter
914 vmull.s32 q4, d17, d4[0]
915 vmull.s32 q5, d18, d2[1]
916 vmull.s32 q15, d18, d2[0]
917 vmlsl.s32 q12, d19, d7[1]
918 vmull.s32 q14, d17, d4[1]
919 vmull.s32 q13, d19, d7[0]
920 vmull.s32 q11, d16, d0[0]
921 vrshrn.s64 d16, q4, #14
922 vrshrn.s64 d11, q5, #14
923 vrshrn.s64 d10, q15, #14
924 vrshrn.s64 d24, q12, #14
925 vrshrn.s64 d29, q14, #14
926 vrshrn.s64 d17, q13, #14
927 vrshrn.s64 d28, q11, #14
929 mbutterfly_l q10, q11, d17, d24, d1[0], d1[1], neg=1
930 mbutterfly_l q9, q15, d29, d16, d1[0], d1[1]
931 vrshrn.s64 d27, q10, #14
932 vrshrn.s64 d21, q11, #14
933 vrshrn.s64 d23, q9, #14
934 vrshrn.s64 d25, q15, #14
937 mbutterfly0 d22, d26, d11, d10, d18, d30, q9, q15
943 movrel r12, iadst16_coeffs
944 vld1.16 {q0}, [r12,:128]!
948 mbutterfly_l q3, q2, d31, d16, d0[1], d0[0] @ q3 = t1, q2 = t0
949 mbutterfly_l q5, q4, d23, d24, d2[1], d2[0] @ q5 = t9, q4 = t8
950 butterfly_n d31, d24, q3, q5, q6, q5 @ d31 = t1a, d24 = t9a
951 mbutterfly_l q7, q6, d29, d18, d1[1], d1[0] @ q7 = t3, q6 = t2
952 butterfly_n d16, d23, q2, q4, q3, q4 @ d16 = t0a, d23 = t8a
953 mbutterfly_l q3, q2, d21, d26, d3[1], d3[0] @ q3 = t11, q2 = t10
955 vld1.16 {q0}, [r12,:128]!
956 butterfly_n d29, d26, q7, q3, q4, q3 @ d29 = t3a, d26 = t11a
959 mbutterfly_l q5, q4, d27, d20, d0[1], d0[0] @ q5 = t5, q4 = t4
960 butterfly_n d18, d21, q6, q2, q3, q2 @ d18 = t2a, d21 = t10a
962 mbutterfly_l q7, q6, d19, d28, d2[1], d2[0] @ q7 = t13, q6 = t12
963 butterfly_n d20, d28, q5, q7, q2, q7 @ d20 = t5a, d28 = t13a
964 mbutterfly_l q3, q2, d25, d22, d1[1], d1[0] @ q3 = t7, q2 = t6
965 butterfly_n d27, d19, q4, q6, q5, q6 @ d27 = t4a, d19 = t12a
967 mbutterfly_l q5, q4, d17, d30, d3[1], d3[0] @ q5 = t15, q4 = t14
968 movrel r12, idct_coeffs
969 vld1.16 {q0}, [r12,:128]
972 butterfly_n d22, d30, q3, q5, q6, q5 @ d22 = t7a, d30 = t15a
973 mbutterfly_l q7, q6, d23, d24, d2[0], d2[1] @ q7 = t9, q6 = t8
974 butterfly_n d25, d17, q2, q4, q3, q4 @ d25 = t6a, d17 = t14a
976 mbutterfly_l q2, q3, d28, d19, d2[1], d2[0] @ q2 = t12, q3 = t13
977 butterfly_n d23, d19, q6, q2, q4, q2 @ d23 = t8a, d19 = t12a
978 mbutterfly_l q5, q4, d21, d26, d3[0], d3[1] @ q5 = t11, q4 = t10
979 butterfly_r d4, d27, d16, d27 @ d4 = t4, d27 = t0
980 butterfly_n d24, d28, q7, q3, q6, q3 @ d24 = t9a, d28 = t13a
982 mbutterfly_l q6, q7, d30, d17, d3[1], d3[0] @ q6 = t14, q7 = t15
983 butterfly_r d5, d20, d31, d20 @ d5 = t5, d20 = t1
984 butterfly_n d21, d17, q4, q6, q3, q6 @ d21 = t10a, d17 = t14a
985 butterfly_n d26, d30, q5, q7, q4, q7 @ d26 = t11a, d30 = t15a
987 butterfly_r d6, d25, d18, d25 @ d6 = t6, d25 = t2
988 butterfly_r d7, d22, d29, d22 @ d7 = t7, d22 = t3
990 mbutterfly_l q5, q4, d19, d28, d1[0], d1[1] @ q5 = t13, q4 = t12
991 mbutterfly_l q6, q7, d30, d17, d1[1], d1[0] @ q6 = t14, q7 = t15
993 butterfly_n d18, d30, q4, q6, q8, q6 @ d18 = out[2], d30 = t14a
994 butterfly_n d29, d17, q5, q7, q6, q7 @ d29 = -out[13], d17 = t15a
995 vneg.s32 d29, d29 @ d29 = out[13]
997 mbutterfly_l q5, q4, d4, d5, d1[0], d1[1] @ q5 = t5a, q4 = t4a
998 mbutterfly_l q6, q7, d7, d6, d1[1], d1[0] @ q6 = t6a, q7 = t7a
1000 butterfly d2, d6, d27, d25 @ d2 = out[0], d6 = t2a
1001 butterfly d3, d7, d23, d21 @ d3 =-out[1], d7 = t10
1003 butterfly_n d19, d31, q4, q6, q2, q4 @ d19 = -out[3], d31 = t6
1004 vneg.s32 d19, d19 @ d19 = out[3]
1005 butterfly_n d28, d16, q5, q7, q2, q5 @ d28 = out[12], d16 = t7
1007 butterfly d5, d8, d20, d22 @ d5 =-out[15],d8 = t3a
1008 butterfly d4, d9, d24, d26 @ d4 = out[14],d9 = t11
1010 mbutterfly0 d23, d24, d6, d8, d10, d11, q6, q7, 1 @ d23 = out[7], d24 = out[8]
1011 mbutterfly0 d20, d27, d16, d31, d10, d11, q6, q7 @ d20 = out[4], d27 = out[11]
1012 mbutterfly0 d22, d25, d9, d7, d10, d11, q6, q7 @ d22 = out[6], d25 = out[9]
1013 mbutterfly0 d21, d26, d30, d17, d10, d11, q6, q7, 1 @ d21 = out[5], d26 = out[10]
1015 vneg.s32 d31, d5 @ d31 = out[15]
1016 vneg.s32 d17, d3 @ d17 = out[1]
1023 .macro itxfm16_1d_funcs txfm, suffix
1024 @ Read a vertical 2x16 slice out of a 16x16 matrix, do a transform on it,
1025 @ transpose into a horizontal 16x2 slice and store.
1026 @ r0 = dst (temp buffer)
1028 function \txfm\()16_1d_2x16_pass1\suffix\()_neon
1034 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1035 vld1.32 {d\i}, [r2,:64]
1036 vst1.32 {d8}, [r2,:64], r12
1039 .ifc \suffix,_quarter
1040 .irp i, 16, 17, 18, 19
1041 vld1.32 {d\i}, [r2,:64]
1042 vst1.32 {d8}, [r2,:64], r12
1046 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1047 vld1.32 {d\i}, [r2,:64]
1048 vst1.32 {d8}, [r2,:64], r12
1052 bl \txfm\()16\suffix
1054 @ Do eight 2x2 transposes. Originally, d16-d31 contain the
1055 @ 16 rows. Afterwards, d16-d17, d18-d19 etc contain the eight
1056 @ transposed 2x2 blocks.
1057 transpose32_8x_2x2 d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
1059 @ Store the transposed 2x2 blocks horizontally.
1060 .irp i, 16, 18, 20, 22, 24, 26, 28, 30, 17, 19, 21, 23, 25, 27, 29, 31
1061 vst1.32 {d\i}, [r0,:64]!
1066 @ Read a vertical 2x16 slice out of a 16x16 matrix, do a transform on it,
1067 @ load the destination pixels (from a similar 2x16 slice), add and store back.
1070 @ r2 = src (temp buffer)
1071 function \txfm\()16_1d_2x16_pass2\suffix\()_neon
1076 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1077 vld1.16 {d\i}, [r2,:64], r12
1080 .ifc \suffix,_quarter
1081 .irp i, 16, 17, 18, 19, 20
1082 vld1.16 {d\i}, [r2,:64], r12
1086 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1087 vld1.16 {d\i}, [r2,:64], r12
1093 bl \txfm\()16\suffix
1095 .macro load_add_store coef0, coef1, coef2, coef3
1096 vrshr.s32 \coef0, \coef0, #6
1097 vrshr.s32 \coef1, \coef1, #6
1099 vld1.32 {d8[]}, [r0,:32], r1
1100 vld1.32 {d8[1]}, [r3,:32], r1
1101 vrshr.s32 \coef2, \coef2, #6
1102 vrshr.s32 \coef3, \coef3, #6
1103 vld1.32 {d9[]}, [r0,:32], r1
1104 vld1.32 {d9[1]}, [r3,:32], r1
1105 vaddw.u16 \coef0, \coef0, d8
1106 vld1.32 {d10[]}, [r0,:32], r1
1107 vld1.32 {d10[1]}, [r3,:32], r1
1108 vaddw.u16 \coef1, \coef1, d9
1109 vld1.32 {d11[]}, [r0,:32], r1
1110 vld1.32 {d11[1]}, [r3,:32], r1
1112 vqmovun.s32 d8, \coef0
1114 vqmovun.s32 d9, \coef1
1115 sub r0, r0, r1, lsl #2
1116 sub r3, r3, r1, lsl #2
1117 vaddw.u16 \coef2, \coef2, d10
1118 vaddw.u16 \coef3, \coef3, d11
1120 vst1.32 {d8[0]}, [r0,:32], r1
1121 vst1.32 {d8[1]}, [r3,:32], r1
1122 vqmovun.s32 d10, \coef2
1123 vst1.32 {d9[0]}, [r0,:32], r1
1124 vst1.32 {d9[1]}, [r3,:32], r1
1125 vqmovun.s32 d11, \coef3
1128 vst1.32 {d10[0]}, [r0,:32], r1
1129 vst1.32 {d10[1]}, [r3,:32], r1
1130 vst1.32 {d11[0]}, [r0,:32], r1
1131 vst1.32 {d11[1]}, [r3,:32], r1
1133 load_add_store q8, q9, q10, q11
1134 load_add_store q12, q13, q14, q15
1135 .purgem load_add_store
1141 itxfm16_1d_funcs idct
1142 itxfm16_1d_funcs iadst
1143 itxfm16_1d_funcs idct, _quarter
1144 itxfm16_1d_funcs idct, _half
1147 @ This is the minimum eob value for each subpartition, in increments of 2
1148 const min_eob_idct_idct_16, align=4
1149 .short 0, 3, 10, 22, 38, 62, 89, 121
1152 .macro itxfm_func16x16 txfm1, txfm2
1153 function vp9_\txfm1\()_\txfm2\()_16x16_add_16_neon
1154 .ifc \txfm1\()_\txfm2,idct_idct
1156 beq idct16x16_dc_add_neon
1158 .ifnc \txfm1\()_\txfm2,idct_idct
1164 @ Align the stack, allocate a temp buffer
1176 movrel r12, idct_coeffs
1177 vld1.16 {q0-q1}, [r12,:128]
1184 .ifc \txfm1\()_\txfm2,idct_idct
1186 ble idct16x16_quarter_add_16_neon
1188 ble idct16x16_half_add_16_neon
1190 movrel r8, min_eob_idct_idct_16 + 2
1193 .irp i, 0, 2, 4, 6, 8, 10, 12, 14
1194 add r0, sp, #(\i*64)
1195 .ifc \txfm1\()_\txfm2,idct_idct
1197 ldrh_post r1, r8, #2
1200 movle r1, #(16 - \i)/2
1205 bl \txfm1\()16_1d_2x16_pass1_neon
1208 .ifc \txfm1\()_\txfm2,idct_idct
1215 @ Unroll for 2 lines
1217 @ Fill one line with zeros
1218 vst1.32 {q14-q15}, [r0,:128]!
1219 vst1.32 {q14-q15}, [r0,:128]!
1225 .ifc \txfm1\()_\txfm2,iadst_idct
1226 movrel r12, idct_coeffs
1227 vld1.16 {q0-q1}, [r12,:128]
1233 .irp i, 0, 2, 4, 6, 8, 10, 12, 14
1237 bl \txfm2\()16_1d_2x16_pass2_neon
1241 .ifnc \txfm1\()_\txfm2,idct_idct
1249 function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_10_neon, export=1
1252 b vp9_\txfm1\()_\txfm2\()_16x16_add_16_neon
1255 function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_12_neon, export=1
1258 b vp9_\txfm1\()_\txfm2\()_16x16_add_16_neon
1262 itxfm_func16x16 idct, idct
1263 itxfm_func16x16 iadst, idct
1264 itxfm_func16x16 idct, iadst
1265 itxfm_func16x16 iadst, iadst
1268 .macro idct16_partial size
1269 function idct16x16_\size\()_add_16_neon
1271 add r0, sp, #(\i*64)
1279 bl idct16_1d_2x16_pass1_\size\()_neon
1284 add r0, sp, #(\i*64)
1290 bl idct16_1d_2x16_pass1_\size\()_neon
1299 @ Unroll for 2 lines
1301 @ Fill one line with zeros
1302 vst1.32 {q14-q15}, [r0,:128]!
1303 vst1.32 {q14-q15}, [r0,:128]!
1308 .irp i, 0, 2, 4, 6, 8, 10, 12, 14
1312 bl idct16_1d_2x16_pass2_\size\()_neon
1321 idct16_partial quarter
1324 function idct32x32_dc_add_neon
1325 movrel r12, idct_coeffs
1326 vld1.16 {d0}, [r12,:64]
1331 vld1.32 {d16[]}, [r2,:32]
1332 vmull.s32 q8, d16, d0[0]
1333 vrshrn.s64 d16, q8, #14
1334 vmull.s32 q8, d16, d0[0]
1335 vrshrn.s64 d16, q8, #14
1337 vst1.32 {d4[0]}, [r2,:32]
1339 vrshr.s32 q8, q8, #6
1346 @ Loop to add the constant from q8 into all 32x32 outputs
1348 vld1.16 {q0-q1}, [r0,:128]!
1349 vaddw.u16 q9, q8, d0
1350 vaddw.u16 q10, q8, d1
1351 vld1.16 {q2-q3}, [r0,:128], r1
1352 vaddw.u16 q11, q8, d2
1353 vaddw.u16 q12, q8, d3
1354 vaddw.u16 q13, q8, d4
1355 vaddw.u16 q14, q8, d5
1357 vaddw.u16 q9, q8, d6
1359 vaddw.u16 q10, q8, d7
1364 vmin.u16 q0, q0, q15
1365 vmin.u16 q1, q1, q15
1368 vst1.16 {q0-q1}, [r3,:128]!
1369 vmin.u16 q2, q2, q15
1370 vmin.u16 q3, q3, q15
1371 vst1.16 {q2-q3}, [r3,:128], r1
1378 butterfly d16, d9, d8, d9 @ d16 = t16a, d9 = t19a
1379 butterfly d17, d20, d23, d20 @ d17 = t17, d20 = t18
1380 butterfly d18, d10, d11, d10 @ d18 = t23a, d10 = t20a
1381 butterfly d19, d21, d22, d21 @ d19 = t22, d21 = t21
1382 butterfly d8, d28, d28, d30 @ d8 = t24a, d28 = t27a
1383 butterfly d23, d26, d25, d26 @ d23 = t25, d26 = t26
1384 butterfly d11, d29, d29, d31 @ d11 = t31a, d29 = t28a
1385 butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29
1387 mbutterfly d27, d20, d1[0], d1[1], q12, q15 @ d27 = t18a, d20 = t29a
1388 mbutterfly d29, d9, d1[0], d1[1], q12, q15 @ d29 = t19, d9 = t28
1389 mbutterfly d28, d10, d1[0], d1[1], q12, q15, neg=1 @ d28 = t27, d10 = t20
1390 mbutterfly d26, d21, d1[0], d1[1], q12, q15, neg=1 @ d26 = t26a, d21 = t21a
1392 butterfly d31, d24, d11, d8 @ d31 = t31, d24 = t24
1393 butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a
1394 butterfly_r d23, d16, d16, d18 @ d23 = t23, d16 = t16
1395 butterfly_r d22, d17, d17, d19 @ d22 = t22a, d17 = t17a
1396 butterfly d18, d21, d27, d21 @ d18 = t18, d21 = t21
1397 butterfly_r d27, d28, d9, d28 @ d27 = t27a, d28 = t28a
1398 butterfly d8, d26, d20, d26 @ d8 = t29, d26 = t26
1399 butterfly d19, d20, d29, d10 @ d19 = t19a, d20 = t20
1400 vmov d29, d8 @ d29 = t29
1402 mbutterfly0 d27, d20, d27, d20, d8, d10, q4, q5 @ d27 = t27, d20 = t20
1403 mbutterfly0 d26, d21, d26, d21, d8, d10, q4, q5 @ d26 = t26a, d21 = t21a
1404 mbutterfly0 d25, d22, d25, d22, d8, d10, q4, q5 @ d25 = t25, d22 = t22
1405 mbutterfly0 d24, d23, d24, d23, d8, d10, q4, q5 @ d24 = t24a, d23 = t23a
1410 movrel r12, idct_coeffs
1412 @ Overwrite the idct16 coeffs with the stored ones for idct32
1418 mbutterfly d16, d31, d0[0], d0[1], q4, q5 @ d16 = t16a, d31 = t31a
1419 mbutterfly d24, d23, d1[0], d1[1], q4, q5 @ d24 = t17a, d23 = t30a
1420 mbutterfly d20, d27, d2[0], d2[1], q4, q5 @ d20 = t18a, d27 = t29a
1421 mbutterfly d28, d19, d3[0], d3[1], q4, q5 @ d28 = t19a, d19 = t28a
1422 mbutterfly d18, d29, d4[0], d4[1], q4, q5 @ d18 = t20a, d29 = t27a
1423 mbutterfly d26, d21, d5[0], d5[1], q4, q5 @ d26 = t21a, d21 = t26a
1424 mbutterfly d22, d25, d6[0], d6[1], q4, q5 @ d22 = t22a, d25 = t25a
1425 mbutterfly d30, d17, d7[0], d7[1], q4, q5 @ d30 = t23a, d17 = t24a
1427 @ Reload the idct16 coefficients. We could swap the coefficients between
1428 @ q0-q3 and q6-q7 by narrowing/lengthening, but that's slower than just
1429 @ loading and lengthening.
1430 vld1.16 {q0-q1}, [r12,:128]
1432 butterfly d8, d24, d16, d24 @ d8 = t16, d24 = t17
1433 butterfly d9, d20, d28, d20 @ d9 = t19, d20 = t18
1434 butterfly d10, d26, d18, d26 @ d10 = t20, d26 = t21
1435 butterfly d11, d22, d30, d22 @ d11 = t23, d22 = t22
1440 butterfly d28, d25, d17, d25 @ d28 = t24, d25 = t25
1441 butterfly d30, d21, d29, d21 @ d30 = t27, d21 = t26
1442 butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30
1443 butterfly d31, d27, d19, d27 @ d31 = t28, d27 = t29
1445 mbutterfly d23, d24, d2[0], d2[1], q8, q9 @ d23 = t17a, d24 = t30a
1446 mbutterfly d27, d20, d2[0], d2[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a
1447 mbutterfly d21, d26, d3[0], d3[1], q8, q9 @ d21 = t21a, d26 = t26a
1448 mbutterfly d25, d22, d3[0], d3[1], q8, q9, neg=1 @ d25 = t25a, d22 = t22a
1452 function idct32_odd_half
1453 movrel r12, idct_coeffs
1460 mbutterfly_h1 d16, d31, d0[0], d0[1], q4, q5 @ d16 = t16a, d31 = t31a
1461 mbutterfly_h2 d24, d23, d1[0], d1[1], q4, q5 @ d24 = t17a, d23 = t30a
1462 mbutterfly_h1 d20, d27, d2[0], d2[1], q4, q5 @ d20 = t18a, d27 = t29a
1463 mbutterfly_h2 d28, d19, d3[0], d3[1], q4, q5 @ d28 = t19a, d19 = t28a
1464 mbutterfly_h1 d18, d29, d4[0], d4[1], q4, q5 @ d18 = t20a, d29 = t27a
1465 mbutterfly_h2 d26, d21, d5[0], d5[1], q4, q5 @ d26 = t21a, d21 = t26a
1466 mbutterfly_h1 d22, d25, d6[0], d6[1], q4, q5 @ d22 = t22a, d25 = t25a
1467 mbutterfly_h2 d30, d17, d7[0], d7[1], q4, q5 @ d30 = t23a, d17 = t24a
1469 vld1.16 {q0-q1}, [r12,:128]
1471 butterfly d8, d24, d16, d24 @ d8 = t16, d24 = t17
1472 butterfly d9, d20, d28, d20 @ d9 = t19, d20 = t18
1473 butterfly d10, d26, d18, d26 @ d10 = t20, d26 = t21
1474 butterfly d11, d22, d30, d22 @ d11 = t23, d22 = t22
1479 butterfly d28, d25, d17, d25 @ d28 = t24, d25 = t25
1480 butterfly d30, d21, d29, d21 @ d30 = t27, d21 = t26
1481 butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30
1482 butterfly d31, d27, d19, d27 @ d31 = t28, d27 = t29
1484 mbutterfly d23, d24, d2[0], d2[1], q8, q9 @ d23 = t17a, d24 = t30a
1485 mbutterfly d27, d20, d2[0], d2[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a
1486 mbutterfly d21, d26, d3[0], d3[1], q8, q9 @ d21 = t21a, d26 = t26a
1487 mbutterfly d25, d22, d3[0], d3[1], q8, q9, neg=1 @ d25 = t25a, d22 = t22a
1491 function idct32_odd_quarter
1492 movrel r12, idct_coeffs
1502 vmull.s32 q4, d16, d0[0]
1503 vmlsl.s32 q14, d19, d3[1]
1504 vmull.s32 q15, d16, d0[1]
1505 vmull.s32 q11, d17, d7[0]
1506 vmlsl.s32 q5, d17, d7[1]
1507 vmull.s32 q13, d19, d3[0]
1508 vmull.s32 q10, d18, d4[0]
1509 vmull.s32 q12, d18, d4[1]
1511 vld1.16 {q0-q1}, [r12,:128]
1513 vrshrn.s64 d8, q4, #14
1514 vrshrn.s64 d9, q14, #14
1515 vrshrn.s64 d29, q15, #14
1516 vrshrn.s64 d28, q11, #14
1523 vrshrn.s64 d11, q5, #14
1524 vrshrn.s64 d31, q13, #14
1525 vrshrn.s64 d10, q10, #14
1526 vrshrn.s64 d30, q12, #14
1528 mbutterfly_l q8, q9, d29, d8, d2[0], d2[1]
1529 mbutterfly_l q13, q10, d31, d9, d2[0], d2[1], neg=1
1530 vrshrn.s64 d23, q8, #14
1531 vrshrn.s64 d24, q9, #14
1532 vrshrn.s64 d27, q13, #14
1533 vrshrn.s64 d20, q10, #14
1534 mbutterfly_l q8, q9, d30, d10, d3[0], d3[1]
1535 vrshrn.s64 d21, q8, #14
1536 vrshrn.s64 d26, q9, #14
1537 mbutterfly_l q8, q9, d28, d11, d3[0], d3[1], neg=1
1538 vrshrn.s64 d25, q8, #14
1539 vrshrn.s64 d22, q9, #14
1544 .macro idct32_funcs suffix
1545 @ Do an 32-point IDCT of a 2x32 slice out of a 32x32 matrix.
1546 @ We don't have register space to do a single pass IDCT of 2x32 though,
1547 @ but the 32-point IDCT can be decomposed into two 16-point IDCTs;
1548 @ a normal IDCT16 with every other input component (the even ones, with
1549 @ each output written twice), followed by a separate 16-point IDCT
1550 @ of the odd inputs, added/subtracted onto the outputs of the first idct16.
1551 @ r0 = dst (temp buffer)
1554 function idct32_1d_2x32_pass1\suffix\()_neon
1557 @ Double stride of the input, since we only read every other line
1561 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30)
1563 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1564 vld1.32 {d\i}, [r2,:64]
1565 vst1.32 {d8}, [r2,:64], r12
1568 .ifc \suffix,_quarter
1569 .irp i, 16, 17, 18, 19
1570 vld1.32 {d\i}, [r2,:64]
1571 vst1.32 {d8}, [r2,:64], r12
1575 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1576 vld1.32 {d\i}, [r2,:64]
1577 vst1.32 {d8}, [r2,:64], r12
1583 @ Do eight 2x2 transposes. Originally, d16-d31 contain the
1584 @ 16 rows. Afterwards, d16-d17, d18-d19 etc contain the eight
1585 @ transposed 2x2 blocks.
1586 transpose32_8x_2x2 d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
1588 @ Store the registers a, b, c, d, e, f, g, h horizontally, followed
1589 @ by the same registers h, g, f, e, d, c, b, a mirrored.
1590 .macro store_rev a, b, c, d, e, f, g, h
1591 .irp i, \a, \b, \c, \d, \e, \f, \g, \h
1592 vst1.32 {d\i}, [r0,:64]!
1595 .irp i, \h, \g, \f, \e, \d, \c, \b, \a
1596 vst1.32 {d\i}, [r0,:64]!
1599 store_rev 16, 18, 20, 22, 24, 26, 28, 30
1600 store_rev 17, 19, 21, 23, 25, 27, 29, 31
1604 @ Move r2 back to the start of the input, and move
1605 @ to the first odd row
1607 sub r2, r2, r12, lsl #4
1609 .ifc \suffix,_quarter
1610 sub r2, r2, r12, lsl #2
1613 sub r2, r2, r12, lsl #3
1618 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31)
1620 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1621 vld1.16 {d\i}, [r2,:64]
1622 vst1.16 {d8}, [r2,:64], r12
1625 .ifc \suffix,_quarter
1626 .irp i, 16, 17, 18, 19
1627 vld1.16 {d\i}, [r2,:64]
1628 vst1.16 {d8}, [r2,:64], r12
1632 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1633 vld1.16 {d\i}, [r2,:64]
1634 vst1.16 {d8}, [r2,:64], r12
1638 bl idct32_odd\suffix
1640 transpose32_8x_2x2 d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16
1642 @ Store the registers a, b, c, d, e, f, g, h horizontally,
1643 @ adding into the output first, and then mirrored, subtracted
1645 .macro store_rev a, b, c, d, e, f, g, h
1646 .irp i, \a, \b, \c, \d, \e, \f, \g, \h
1647 vld1.32 {d8}, [r0,:64]
1648 vadd.s32 d8, d8, d\i
1649 vst1.32 {d8}, [r0,:64]!
1652 .irp i, \h, \g, \f, \e, \d, \c, \b, \a
1653 vld1.32 {d8}, [r0,:64]
1654 vsub.s32 d8, d8, d\i
1655 vst1.32 {d8}, [r0,:64]!
1659 store_rev 31, 29, 27, 25, 23, 21, 19, 17
1660 store_rev 30, 28, 26, 24, 22, 20, 18, 16
1666 @ This is mostly the same as 2x32_pass1, but without the transpose,
1667 @ and use the source as temp buffer between the two idct passes, and
1668 @ add into the destination.
1671 @ r2 = src (temp buffer)
1672 function idct32_1d_2x32_pass2\suffix\()_neon
1676 @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30)
1678 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1679 vld1.32 {d\i}, [r2,:64], r12
1681 sub r2, r2, r12, lsl #4
1683 .ifc \suffix,_quarter
1684 .irp i, 16, 17, 18, 19
1685 vld1.32 {d\i}, [r2,:64], r12
1687 sub r2, r2, r12, lsl #2
1690 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1691 vld1.32 {d\i}, [r2,:64], r12
1693 sub r2, r2, r12, lsl #3
1698 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1699 vst1.32 {d\i}, [r2,:64], r12
1702 sub r2, r2, r12, lsl #4
1705 @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31)
1707 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
1708 vld1.32 {d\i}, [r2,:64], r12
1710 sub r2, r2, r12, lsl #4
1712 .ifc \suffix,_quarter
1713 .irp i, 16, 17, 18, 19
1714 vld1.32 {d\i}, [r2,:64], r12
1716 sub r2, r2, r12, lsl #2
1719 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
1720 vld1.32 {d\i}, [r2,:64], r12
1722 sub r2, r2, r12, lsl #3
1726 bl idct32_odd\suffix
1728 @ Narrow the ict16 coefficients in q0-q3 into q0-q1, to
1729 @ allow clobbering q2-q3 below.
1737 .macro load_acc_store a, b, c, d, neg=0
1738 vld1.32 {d4}, [r2,:64], r12
1739 vld1.32 {d5}, [r2,:64], r12
1741 vadd.s32 d4, d4, d\a
1742 vld1.32 {d6}, [r2,:64], r12
1743 vadd.s32 d5, d5, d\b
1744 vld1.32 {d7}, [r2,:64], r12
1745 vadd.s32 d6, d6, d\c
1746 vadd.s32 d7, d7, d\d
1748 vsub.s32 d4, d4, d\a
1749 vld1.32 {d6}, [r2,:64], r12
1750 vsub.s32 d5, d5, d\b
1751 vld1.32 {d7}, [r2,:64], r12
1752 vsub.s32 d6, d6, d\c
1753 vsub.s32 d7, d7, d\d
1755 vld1.32 {d10[]}, [r0,:32], r1
1756 vld1.32 {d10[1]}, [r0,:32], r1
1757 vrshr.s32 q2, q2, #6
1758 vld1.32 {d11[]}, [r0,:32], r1
1759 vrshr.s32 q3, q3, #6
1760 vld1.32 {d11[1]}, [r0,:32], r1
1761 sub r0, r0, r1, lsl #2
1762 vaddw.u16 q2, q2, d10
1763 vaddw.u16 q3, q3, d11
1767 vst1.32 {d4[0]}, [r0,:32], r1
1768 vst1.32 {d4[1]}, [r0,:32], r1
1769 vst1.32 {d5[0]}, [r0,:32], r1
1770 vst1.32 {d5[1]}, [r0,:32], r1
1772 load_acc_store 31, 30, 29, 28
1773 load_acc_store 27, 26, 25, 24
1774 load_acc_store 23, 22, 21, 20
1775 load_acc_store 19, 18, 17, 16
1778 load_acc_store 16, 17, 18, 19, 1
1779 load_acc_store 20, 21, 22, 23, 1
1780 load_acc_store 24, 25, 26, 27, 1
1781 load_acc_store 28, 29, 30, 31, 1
1782 .purgem load_acc_store
1783 @ Lengthen the idct16 coeffs back into 32 bit form
1793 idct32_funcs _quarter
1796 const min_eob_idct_idct_32, align=4
1797 .short 0, 3, 9, 21, 34, 51, 70, 98, 135, 176, 240, 258, 336, 357, 448, 472
1800 function vp9_idct_idct_32x32_add_16_neon
1802 beq idct32x32_dc_add_neon
1804 movrel r8, min_eob_idct_idct_32 + 2
1806 @ Align the stack, allocate a temp buffer
1817 movrel r12, idct_coeffs
1818 vld1.16 {q0-q1}, [r12,:128]!
1819 vld1.16 {q6-q7}, [r12,:128]
1826 ble idct32x32_quarter_add_16_neon
1828 ble idct32x32_half_add_16_neon
1830 .irp i, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
1831 add r0, sp, #(\i*128)
1833 ldrh_post r1, r8, #2
1836 movle r1, #(32 - \i)/2
1840 bl idct32_1d_2x32_pass1_neon
1845 @ Write zeros to the temp buffer for pass 2
1851 @ Fill one line with zeros
1852 vst1.16 {q14-q15}, [r0,:128]!
1853 vst1.16 {q14-q15}, [r0,:128]!
1854 vst1.16 {q14-q15}, [r0,:128]!
1855 vst1.16 {q14-q15}, [r0,:128]!
1859 .irp i, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
1863 bl idct32_1d_2x32_pass2_neon
1871 function ff_vp9_idct_idct_32x32_add_10_neon, export=1
1874 b vp9_idct_idct_32x32_add_16_neon
1877 function ff_vp9_idct_idct_32x32_add_12_neon, export=1
1880 b vp9_idct_idct_32x32_add_16_neon
1883 .macro idct32_partial size, rows
1884 function idct32x32_\size\()_add_16_neon
1886 add r0, sp, #(\i*128)
1889 ldrh_post r1, r8, #2
1892 movle r1, #(\rows - \i)/2
1897 bl idct32_1d_2x32_pass1_\size\()_neon
1901 .irp i, 8, 10, 12, 14
1902 add r0, sp, #(\i*128)
1904 ldrh_post r1, r8, #2
1907 movle r1, #(\rows - \i)/2
1911 bl idct32_1d_2x32_pass1_\size\()_neon
1917 @ Write zeros to the temp buffer for pass 2
1923 @ Fill one line with zeros
1924 vst1.16 {q14-q15}, [r0,:128]!
1925 vst1.16 {q14-q15}, [r0,:128]!
1926 vst1.16 {q14-q15}, [r0,:128]!
1927 vst1.16 {q14-q15}, [r0,:128]!
1931 .irp i, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
1935 bl idct32_1d_2x32_pass2_\size\()_neon
1944 idct32_partial quarter, 8
1945 idct32_partial half, 16