4 * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
7 * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at>
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 #define W1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
29 #define W2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
30 #define W3 19266 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
31 #define W4 16383 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
32 #define W5 12873 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
33 #define W6 8867 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
34 #define W7 4520 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
35 #define W4c ((1<<(COL_SHIFT-1))/W4)
51 vmull.s16 q7, d6, w2 /* q9 = W2 * col[2] */
52 vmull.s16 q8, d6, w6 /* q10 = W6 * col[2] */
53 vmull.s16 q9, d4, w1 /* q9 = W1 * col[1] */
55 vmull.s16 q10, d4, w3 /* q10 = W3 * col[1] */
57 vmull.s16 q5, d4, w5 /* q5 = W5 * col[1] */
59 vmull.s16 q6, d4, w7 /* q6 = W7 * col[1] */
62 vmlal.s16 q9, d8, w3 /* q9 += W3 * col[3] */
63 vmlsl.s16 q10, d8, w7 /* q10 -= W7 * col[3] */
64 vmlsl.s16 q5, d8, w1 /* q5 -= W1 * col[3] */
65 vmlsl.s16 q6, d8, w5 /* q6 -= W5 * col[3] */
71 function idct_row4_neon
72 vmov.i32 q15, #(1<<(ROW_SHIFT-1))
73 vld1.64 {d2-d5}, [r2,:128]!
74 vmlal.s16 q15, d2, w4 /* q15 += W4 * col[0] */
75 vld1.64 {d6,d7}, [r2,:128]!
77 vld1.64 {d8,d9}, [r2,:128]!
89 vmull.s16 q7, d3, w4 /* q7 = W4 * col[4] */
90 vmlal.s16 q9, d5, w5 /* q9 += W5 * col[5] */
91 vmlsl.s16 q10, d5, w1 /* q10 -= W1 * col[5] */
92 vmull.s16 q8, d7, w2 /* q8 = W2 * col[6] */
93 vmlal.s16 q5, d5, w7 /* q5 += W7 * col[5] */
98 vmlal.s16 q6, d5, w3 /* q6 += W3 * col[5] */
99 vmull.s16 q7, d7, w6 /* q7 = W6 * col[6] */
101 vmlsl.s16 q10, d9, w5
104 vadd.i32 q11, q11, q7
105 vsub.i32 q12, q12, q8
106 vadd.i32 q13, q13, q8
107 vsub.i32 q14, q14, q7
109 1: vadd.i32 q3, q11, q9
110 vadd.i32 q4, q12, q10
111 vshrn.i32 d2, q3, #ROW_SHIFT
112 vshrn.i32 d4, q4, #ROW_SHIFT
116 vshrn.i32 d6, q7, #ROW_SHIFT
117 vshrn.i32 d8, q8, #ROW_SHIFT
118 vsub.i32 q14, q14, q6
119 vsub.i32 q11, q11, q9
121 vsub.i32 q13, q13, q5
122 vshrn.i32 d3, q14, #ROW_SHIFT
124 vsub.i32 q12, q12, q10
126 vshrn.i32 d5, q13, #ROW_SHIFT
127 vshrn.i32 d7, q12, #ROW_SHIFT
128 vshrn.i32 d9, q11, #ROW_SHIFT
135 vst1.64 {d2-d5}, [r2,:128]!
136 vst1.64 {d6-d9}, [r2,:128]!
141 function idct_col4_neon
143 vld1.64 {d2}, [r2,:64], ip /* d2 = col[0] */
145 vld1.64 {d4}, [r2,:64], ip /* d3 = col[1] */
146 vadd.i16 d30, d30, d2
147 vld1.64 {d6}, [r2,:64], ip /* d4 = col[2] */
148 vmull.s16 q15, d30, w4 /* q15 = W4*(col[0]+(1<<COL_SHIFT-1)/W4)*/
149 vld1.64 {d8}, [r2,:64], ip /* d5 = col[3] */
159 vld1.64 {d3}, [r2,:64], ip /* d6 = col[4] */
160 vmull.s16 q7, d3, w4 /* q7 = W4 * col[4] */
161 vadd.i32 q11, q11, q7
162 vsub.i32 q12, q12, q7
163 vsub.i32 q13, q13, q7
164 vadd.i32 q14, q14, q7
171 vld1.64 {d5}, [r2,:64], ip /* d7 = col[5] */
172 vmlal.s16 q9, d5, w5 /* q9 += W5 * col[5] */
173 vmlsl.s16 q10, d5, w1 /* q10 -= W1 * col[5] */
174 vmlal.s16 q5, d5, w7 /* q5 += W7 * col[5] */
175 vmlal.s16 q6, d5, w3 /* q6 += W3 * col[5] */
182 vld1.64 {d7}, [r2,:64], ip /* d8 = col[6] */
183 vmull.s16 q7, d7, w6 /* q7 = W6 * col[6] */
184 vmull.s16 q8, d7, w2 /* q8 = W2 * col[6] */
185 vadd.i32 q11, q11, q7
186 vsub.i32 q14, q14, q7
187 vsub.i32 q12, q12, q8
188 vadd.i32 q13, q13, q8
194 vld1.64 {d9}, [r2,:64], ip /* d9 = col[7] */
196 vmlsl.s16 q10, d9, w5
200 4: vaddhn.i32 d2, q11, q9
201 vaddhn.i32 d3, q12, q10
202 vaddhn.i32 d4, q13, q5
203 vaddhn.i32 d5, q14, q6
204 vsubhn.i32 d9, q11, q9
205 vsubhn.i32 d8, q12, q10
206 vsubhn.i32 d7, q13, q5
207 vsubhn.i32 d6, q14, q6
214 function idct_col4_st8_neon
215 vqshrun.s16 d2, q1, #COL_SHIFT-16
216 vqshrun.s16 d3, q2, #COL_SHIFT-16
217 vqshrun.s16 d4, q3, #COL_SHIFT-16
218 vqshrun.s16 d5, q4, #COL_SHIFT-16
219 vst1.32 {d2[0]}, [r0,:32], r1
220 vst1.32 {d2[1]}, [r0,:32], r1
221 vst1.32 {d3[0]}, [r0,:32], r1
222 vst1.32 {d3[1]}, [r0,:32], r1
223 vst1.32 {d4[0]}, [r0,:32], r1
224 vst1.32 {d4[1]}, [r0,:32], r1
225 vst1.32 {d5[0]}, [r0,:32], r1
226 vst1.32 {d5[1]}, [r0,:32], r1
234 .short W1, W2, W3, W4, W5, W6, W7, W4c
237 .macro idct_start data
242 movrel r3, idct_coeff_neon
243 vld1.64 {d0,d1}, [r3,:128]
251 /* void ff_simple_idct_put_neon(uint8_t *dst, int line_size, DCTELEM *data); */
252 function ff_simple_idct_put_neon, export=1
259 bl idct_col4_st8_neon
260 sub r0, r0, r1, lsl #3
264 bl idct_col4_st8_neon
271 function idct_col4_add8_neon
274 vld1.32 {d10[0]}, [r0,:32], r1
275 vshr.s16 q1, q1, #COL_SHIFT-16
276 vld1.32 {d10[1]}, [r0,:32], r1
277 vshr.s16 q2, q2, #COL_SHIFT-16
278 vld1.32 {d11[0]}, [r0,:32], r1
279 vshr.s16 q3, q3, #COL_SHIFT-16
280 vld1.32 {d11[1]}, [r0,:32], r1
281 vshr.s16 q4, q4, #COL_SHIFT-16
282 vld1.32 {d12[0]}, [r0,:32], r1
284 vld1.32 {d12[1]}, [r0,:32], r1
286 vld1.32 {d13[0]}, [r0,:32], r1
288 vld1.32 {d13[1]}, [r0,:32], r1
290 vst1.32 {d2[0]}, [ip,:32], r1
292 vst1.32 {d2[1]}, [ip,:32], r1
294 vst1.32 {d3[0]}, [ip,:32], r1
296 vst1.32 {d3[1]}, [ip,:32], r1
298 vst1.32 {d4[0]}, [ip,:32], r1
299 vst1.32 {d4[1]}, [ip,:32], r1
300 vst1.32 {d5[0]}, [ip,:32], r1
301 vst1.32 {d5[1]}, [ip,:32], r1
306 /* void ff_simple_idct_add_neon(uint8_t *dst, int line_size, DCTELEM *data); */
307 function ff_simple_idct_add_neon, export=1
314 bl idct_col4_add8_neon
315 sub r0, r0, r1, lsl #3
319 bl idct_col4_add8_neon
326 function idct_col4_st16_neon
329 vshr.s16 q1, q1, #COL_SHIFT-16
330 vshr.s16 q2, q2, #COL_SHIFT-16
331 vst1.64 {d2}, [r2,:64], ip
332 vshr.s16 q3, q3, #COL_SHIFT-16
333 vst1.64 {d3}, [r2,:64], ip
334 vshr.s16 q4, q4, #COL_SHIFT-16
335 vst1.64 {d4}, [r2,:64], ip
336 vst1.64 {d5}, [r2,:64], ip
337 vst1.64 {d6}, [r2,:64], ip
338 vst1.64 {d7}, [r2,:64], ip
339 vst1.64 {d8}, [r2,:64], ip
340 vst1.64 {d9}, [r2,:64], ip
345 /* void ff_simple_idct_neon(DCTELEM *data); */
346 function ff_simple_idct_neon, export=1
355 bl idct_col4_st16_neon
359 bl idct_col4_st16_neon