Imported Debian version 2.4.3~trusty1
[deb_ffmpeg.git] / ffmpeg / libavcodec / arm / vp3dsp_neon.S
CommitLineData
2ba45a60
DM
1/*
2 * Copyright (c) 2009 David Conrad
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
23const vp3_idct_constants, align=4
24.short 64277, 60547, 54491, 46341, 36410, 25080, 12785
25endconst
26
27#define xC1S7 d0[0]
28#define xC2S6 d0[1]
29#define xC3S5 d0[2]
30#define xC4S4 d0[3]
31#define xC5S3 d1[0]
32#define xC6S2 d1[1]
33#define xC7S1 d1[2]
34
35.macro vp3_loop_filter
36 vsubl.u8 q3, d18, d17
37 vsubl.u8 q2, d16, d19
38 vadd.i16 q1, q3, q3
39 vadd.i16 q2, q2, q3
40 vadd.i16 q0, q1, q2
41 vrshr.s16 q0, q0, #3
42 vmovl.u8 q9, d18
43 vdup.u16 q15, r2
44
45 vabs.s16 q1, q0
46 vshr.s16 q0, q0, #15
47 vqsub.u16 q2, q15, q1
48 vqsub.u16 q3, q2, q1
49 vsub.i16 q1, q2, q3
50 veor q1, q1, q0
51 vsub.i16 q0, q1, q0
52
53 vaddw.u8 q2, q0, d17
54 vsub.i16 q3, q9, q0
55 vqmovun.s16 d0, q2
56 vqmovun.s16 d1, q3
57.endm
58
59function ff_vp3_v_loop_filter_neon, export=1
60 sub ip, r0, r1
61 sub r0, r0, r1, lsl #1
62 vld1.64 {d16}, [r0,:64], r1
63 vld1.64 {d17}, [r0,:64], r1
64 vld1.64 {d18}, [r0,:64], r1
65 vld1.64 {d19}, [r0,:64], r1
66 ldrb r2, [r2, #129*4]
67
68 vp3_loop_filter
69
70 vst1.64 {d0}, [ip,:64], r1
71 vst1.64 {d1}, [ip,:64], r1
72 bx lr
73endfunc
74
75function ff_vp3_h_loop_filter_neon, export=1
76 sub ip, r0, #1
77 sub r0, r0, #2
78 vld1.32 {d16[]}, [r0], r1
79 vld1.32 {d17[]}, [r0], r1
80 vld1.32 {d18[]}, [r0], r1
81 vld1.32 {d19[]}, [r0], r1
82 vld1.32 {d16[1]}, [r0], r1
83 vld1.32 {d17[1]}, [r0], r1
84 vld1.32 {d18[1]}, [r0], r1
85 vld1.32 {d19[1]}, [r0], r1
86 ldrb r2, [r2, #129*4]
87
88 vtrn.8 d16, d17
89 vtrn.8 d18, d19
90 vtrn.16 d16, d18
91 vtrn.16 d17, d19
92
93 vp3_loop_filter
94
95 vtrn.8 d0, d1
96
97 vst1.16 {d0[0]}, [ip], r1
98 vst1.16 {d1[0]}, [ip], r1
99 vst1.16 {d0[1]}, [ip], r1
100 vst1.16 {d1[1]}, [ip], r1
101 vst1.16 {d0[2]}, [ip], r1
102 vst1.16 {d1[2]}, [ip], r1
103 vst1.16 {d0[3]}, [ip], r1
104 vst1.16 {d1[3]}, [ip], r1
105 bx lr
106endfunc
107
108
109function vp3_idct_start_neon
110 vpush {d8-d15}
111 vmov.i16 q4, #0
112 vmov.i16 q5, #0
113 movrel r3, vp3_idct_constants
114 vld1.64 {d0-d1}, [r3,:128]
115 vld1.64 {d16-d19}, [r2,:128]
116 vst1.64 {q4-q5}, [r2,:128]!
117 vld1.64 {d20-d23}, [r2,:128]
118 vst1.64 {q4-q5}, [r2,:128]!
119 vld1.64 {d24-d27}, [r2,:128]
120 vst1.64 {q4-q5}, [r2,:128]!
121 vadd.s16 q1, q8, q12
122 vsub.s16 q8, q8, q12
123 vld1.64 {d28-d31}, [r2,:128]
124 vst1.64 {q4-q5}, [r2,:128]!
125
126vp3_idct_core_neon:
127 vmull.s16 q2, d18, xC1S7 // (ip[1] * C1) << 16
128 vmull.s16 q3, d19, xC1S7
129 vmull.s16 q4, d2, xC4S4 // ((ip[0] + ip[4]) * C4) << 16
130 vmull.s16 q5, d3, xC4S4
131 vmull.s16 q6, d16, xC4S4 // ((ip[0] - ip[4]) * C4) << 16
132 vmull.s16 q7, d17, xC4S4
133 vshrn.s32 d4, q2, #16
134 vshrn.s32 d5, q3, #16
135 vshrn.s32 d6, q4, #16
136 vshrn.s32 d7, q5, #16
137 vshrn.s32 d8, q6, #16
138 vshrn.s32 d9, q7, #16
139 vadd.s16 q12, q1, q3 // E = (ip[0] + ip[4]) * C4
140 vadd.s16 q8, q8, q4 // F = (ip[0] - ip[4]) * C4
141 vadd.s16 q1, q2, q9 // ip[1] * C1
142
143 vmull.s16 q2, d30, xC1S7 // (ip[7] * C1) << 16
144 vmull.s16 q3, d31, xC1S7
145 vmull.s16 q4, d30, xC7S1 // (ip[7] * C7) << 16
146 vmull.s16 q5, d31, xC7S1
147 vmull.s16 q6, d18, xC7S1 // (ip[1] * C7) << 16
148 vmull.s16 q7, d19, xC7S1
149 vshrn.s32 d4, q2, #16
150 vshrn.s32 d5, q3, #16
151 vshrn.s32 d6, q4, #16 // ip[7] * C7
152 vshrn.s32 d7, q5, #16
153 vshrn.s32 d8, q6, #16 // ip[1] * C7
154 vshrn.s32 d9, q7, #16
155 vadd.s16 q2, q2, q15 // ip[7] * C1
156 vadd.s16 q9, q1, q3 // A = ip[1] * C1 + ip[7] * C7
157 vsub.s16 q15, q4, q2 // B = ip[1] * C7 - ip[7] * C1
158
159 vmull.s16 q2, d22, xC5S3 // (ip[3] * C5) << 16
160 vmull.s16 q3, d23, xC5S3
161 vmull.s16 q4, d22, xC3S5 // (ip[3] * C3) << 16
162 vmull.s16 q5, d23, xC3S5
163 vmull.s16 q6, d26, xC5S3 // (ip[5] * C5) << 16
164 vmull.s16 q7, d27, xC5S3
165 vshrn.s32 d4, q2, #16
166 vshrn.s32 d5, q3, #16
167 vshrn.s32 d6, q4, #16
168 vshrn.s32 d7, q5, #16
169 vshrn.s32 d8, q6, #16
170 vshrn.s32 d9, q7, #16
171 vadd.s16 q3, q3, q11 // ip[3] * C3
172 vadd.s16 q4, q4, q13 // ip[5] * C5
173 vadd.s16 q1, q2, q11 // ip[3] * C5
174 vadd.s16 q11, q3, q4 // C = ip[3] * C3 + ip[5] * C5
175
176 vmull.s16 q2, d26, xC3S5 // (ip[5] * C3) << 16
177 vmull.s16 q3, d27, xC3S5
178 vmull.s16 q4, d20, xC2S6 // (ip[2] * C2) << 16
179 vmull.s16 q5, d21, xC2S6
180 vmull.s16 q6, d28, xC6S2 // (ip[6] * C6) << 16
181 vmull.s16 q7, d29, xC6S2
182 vshrn.s32 d4, q2, #16
183 vshrn.s32 d5, q3, #16
184 vshrn.s32 d6, q4, #16
185 vshrn.s32 d7, q5, #16
186 vshrn.s32 d8, q6, #16 // ip[6] * C6
187 vshrn.s32 d9, q7, #16
188 vadd.s16 q2, q2, q13 // ip[5] * C3
189 vadd.s16 q3, q3, q10 // ip[2] * C2
190 vsub.s16 q13, q2, q1 // D = ip[5] * C3 - ip[3] * C5
191 vsub.s16 q1, q9, q11 // (A - C)
192 vadd.s16 q11, q9, q11 // Cd = A + C
193 vsub.s16 q9, q15, q13 // (B - D)
194 vadd.s16 q13, q15, q13 // Dd = B + D
195 vadd.s16 q15, q3, q4 // G = ip[2] * C2 + ip[6] * C6
196
197 vmull.s16 q2, d2, xC4S4 // ((A - C) * C4) << 16
198 vmull.s16 q3, d3, xC4S4
199 vmull.s16 q4, d28, xC2S6 // (ip[6] * C2) << 16
200 vmull.s16 q5, d29, xC2S6
201 vmull.s16 q6, d20, xC6S2 // (ip[2] * C6) << 16
202 vmull.s16 q7, d21, xC6S2
203 vshrn.s32 d4, q2, #16
204 vshrn.s32 d5, q3, #16
205 vshrn.s32 d6, q4, #16
206 vshrn.s32 d7, q5, #16
207 vshrn.s32 d8, q6, #16 // ip[2] * C6
208 vmull.s16 q5, d18, xC4S4 // ((B - D) * C4) << 16
209 vmull.s16 q6, d19, xC4S4
210 vshrn.s32 d9, q7, #16
211 vadd.s16 q3, q3, q14 // ip[6] * C2
212 vadd.s16 q10, q1, q2 // Ad = (A - C) * C4
213 vsub.s16 q14, q4, q3 // H = ip[2] * C6 - ip[6] * C2
214 bx lr
215endfunc
216
217.macro VP3_IDCT_END type
218function vp3_idct_end_\type\()_neon
219.ifc \type, col
220 vdup.16 q0, r3
221 vadd.s16 q12, q12, q0
222 vadd.s16 q8, q8, q0
223.endif
224
225 vshrn.s32 d2, q5, #16
226 vshrn.s32 d3, q6, #16
227 vadd.s16 q2, q12, q15 // Gd = E + G
228 vadd.s16 q9, q1, q9 // (B - D) * C4
229 vsub.s16 q12, q12, q15 // Ed = E - G
230 vsub.s16 q3, q8, q10 // Fd = F - Ad
231 vadd.s16 q10, q8, q10 // Add = F + Ad
232 vadd.s16 q4, q9, q14 // Hd = Bd + H
233 vsub.s16 q14, q9, q14 // Bdd = Bd - H
234 vadd.s16 q8, q2, q11 // [0] = Gd + Cd
235 vsub.s16 q15, q2, q11 // [7] = Gd - Cd
236 vadd.s16 q9, q10, q4 // [1] = Add + Hd
237 vsub.s16 q10, q10, q4 // [2] = Add - Hd
238 vadd.s16 q11, q12, q13 // [3] = Ed + Dd
239 vsub.s16 q12, q12, q13 // [4] = Ed - Dd
240.ifc \type, row
241 vtrn.16 q8, q9
242.endif
243 vadd.s16 q13, q3, q14 // [5] = Fd + Bdd
244 vsub.s16 q14, q3, q14 // [6] = Fd - Bdd
245
246.ifc \type, row
247 // 8x8 transpose
248 vtrn.16 q10, q11
249 vtrn.16 q12, q13
250 vtrn.16 q14, q15
251 vtrn.32 q8, q10
252 vtrn.32 q9, q11
253 vtrn.32 q12, q14
254 vtrn.32 q13, q15
255 vswp d17, d24
256 vswp d19, d26
257 vadd.s16 q1, q8, q12
258 vswp d21, d28
259 vsub.s16 q8, q8, q12
260 vswp d23, d30
261.endif
262 bx lr
263endfunc
264.endm
265
266VP3_IDCT_END row
267VP3_IDCT_END col
268
269function ff_vp3_idct_put_neon, export=1
270 mov ip, lr
271 bl vp3_idct_start_neon
272 bl vp3_idct_end_row_neon
273 mov r3, #8
274 add r3, r3, #2048 // convert signed pixel to unsigned
275 bl vp3_idct_core_neon
276 bl vp3_idct_end_col_neon
277 mov lr, ip
278 vpop {d8-d15}
279
280 vqshrun.s16 d0, q8, #4
281 vqshrun.s16 d1, q9, #4
282 vqshrun.s16 d2, q10, #4
283 vqshrun.s16 d3, q11, #4
284 vst1.64 {d0}, [r0,:64], r1
285 vqshrun.s16 d4, q12, #4
286 vst1.64 {d1}, [r0,:64], r1
287 vqshrun.s16 d5, q13, #4
288 vst1.64 {d2}, [r0,:64], r1
289 vqshrun.s16 d6, q14, #4
290 vst1.64 {d3}, [r0,:64], r1
291 vqshrun.s16 d7, q15, #4
292 vst1.64 {d4}, [r0,:64], r1
293 vst1.64 {d5}, [r0,:64], r1
294 vst1.64 {d6}, [r0,:64], r1
295 vst1.64 {d7}, [r0,:64], r1
296 bx lr
297endfunc
298
299function ff_vp3_idct_add_neon, export=1
300 mov ip, lr
301 bl vp3_idct_start_neon
302 bl vp3_idct_end_row_neon
303 mov r3, #8
304 bl vp3_idct_core_neon
305 bl vp3_idct_end_col_neon
306 mov lr, ip
307 vpop {d8-d15}
308 mov r2, r0
309
310 vld1.64 {d0}, [r0,:64], r1
311 vshr.s16 q8, q8, #4
312 vld1.64 {d1}, [r0,:64], r1
313 vshr.s16 q9, q9, #4
314 vld1.64 {d2}, [r0,:64], r1
315 vaddw.u8 q8, q8, d0
316 vld1.64 {d3}, [r0,:64], r1
317 vaddw.u8 q9, q9, d1
318 vld1.64 {d4}, [r0,:64], r1
319 vshr.s16 q10, q10, #4
320 vld1.64 {d5}, [r0,:64], r1
321 vshr.s16 q11, q11, #4
322 vld1.64 {d6}, [r0,:64], r1
323 vqmovun.s16 d0, q8
324 vld1.64 {d7}, [r0,:64], r1
325 vqmovun.s16 d1, q9
326 vaddw.u8 q10, q10, d2
327 vaddw.u8 q11, q11, d3
328 vshr.s16 q12, q12, #4
329 vshr.s16 q13, q13, #4
330 vqmovun.s16 d2, q10
331 vqmovun.s16 d3, q11
332 vaddw.u8 q12, q12, d4
333 vaddw.u8 q13, q13, d5
334 vshr.s16 q14, q14, #4
335 vshr.s16 q15, q15, #4
336 vst1.64 {d0}, [r2,:64], r1
337 vqmovun.s16 d4, q12
338 vst1.64 {d1}, [r2,:64], r1
339 vqmovun.s16 d5, q13
340 vst1.64 {d2}, [r2,:64], r1
341 vaddw.u8 q14, q14, d6
342 vst1.64 {d3}, [r2,:64], r1
343 vaddw.u8 q15, q15, d7
344 vst1.64 {d4}, [r2,:64], r1
345 vqmovun.s16 d6, q14
346 vst1.64 {d5}, [r2,:64], r1
347 vqmovun.s16 d7, q15
348 vst1.64 {d6}, [r2,:64], r1
349 vst1.64 {d7}, [r2,:64], r1
350 bx lr
351endfunc
352
353function ff_vp3_idct_dc_add_neon, export=1
354 ldrsh r12, [r2]
355 mov r3, r0
356 add r12, r12, #15
357 vdup.16 q15, r12
358 mov r12, #0
359 strh r12, [r2]
360 vshr.s16 q15, q15, #5
361
362 vld1.8 {d0}, [r0,:64], r1
363 vld1.8 {d1}, [r0,:64], r1
364 vld1.8 {d2}, [r0,:64], r1
365 vaddw.u8 q8, q15, d0
366 vld1.8 {d3}, [r0,:64], r1
367 vaddw.u8 q9, q15, d1
368 vld1.8 {d4}, [r0,:64], r1
369 vaddw.u8 q10, q15, d2
370 vld1.8 {d5}, [r0,:64], r1
371 vaddw.u8 q11, q15, d3
372 vld1.8 {d6}, [r0,:64], r1
373 vaddw.u8 q12, q15, d4
374 vld1.8 {d7}, [r0,:64], r1
375 vaddw.u8 q13, q15, d5
376 vqmovun.s16 d0, q8
377 vaddw.u8 q14, q15, d6
378 vqmovun.s16 d1, q9
379 vaddw.u8 q15, q15, d7
380 vqmovun.s16 d2, q10
381 vst1.8 {d0}, [r3,:64], r1
382 vqmovun.s16 d3, q11
383 vst1.8 {d1}, [r3,:64], r1
384 vqmovun.s16 d4, q12
385 vst1.8 {d2}, [r3,:64], r1
386 vqmovun.s16 d5, q13
387 vst1.8 {d3}, [r3,:64], r1
388 vqmovun.s16 d6, q14
389 vst1.8 {d4}, [r3,:64], r1
390 vqmovun.s16 d7, q15
391 vst1.8 {d5}, [r3,:64], r1
392 vst1.8 {d6}, [r3,:64], r1
393 vst1.8 {d7}, [r3,:64], r1
394 bx lr
395endfunc