Imported Debian version 2.4.3~trusty1
[deb_ffmpeg.git] / ffmpeg / libavcodec / arm / fft_neon.S
CommitLineData
2ba45a60
DM
1/*
2 * ARM NEON optimised FFT
3 *
4 * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
5 * Copyright (c) 2009 Naotoshi Nojiri
6 *
7 * This algorithm (though not any of the implementation details) is
8 * based on libdjbfft by D. J. Bernstein.
9 *
10 * This file is part of FFmpeg.
11 *
12 * FFmpeg is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * FFmpeg is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with FFmpeg; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27#include "libavutil/arm/asm.S"
28
29#define M_SQRT1_2 0.70710678118654752440
30
31
32function fft4_neon
33 vld1.32 {d0-d3}, [r0,:128]
34
35 vext.32 q8, q1, q1, #1 @ i2,r3 d3=i3,r2
36 vsub.f32 d6, d0, d1 @ r0-r1,i0-i1
37 vsub.f32 d7, d16, d17 @ r3-r2,i2-i3
38 vadd.f32 d4, d0, d1 @ r0+r1,i0+i1
39 vadd.f32 d5, d2, d3 @ i2+i3,r2+r3
40 vadd.f32 d1, d6, d7
41 vsub.f32 d3, d6, d7
42 vadd.f32 d0, d4, d5
43 vsub.f32 d2, d4, d5
44
45 vst1.32 {d0-d3}, [r0,:128]
46
47 bx lr
48endfunc
49
50function fft8_neon
51 mov r1, r0
52 vld1.32 {d0-d3}, [r1,:128]!
53 vld1.32 {d16-d19}, [r1,:128]
54
55 movw r2, #0x04f3 @ sqrt(1/2)
56 movt r2, #0x3f35
57 eor r3, r2, #1<<31
58 vdup.32 d31, r2
59
60 vext.32 q11, q1, q1, #1 @ i2,r3,i3,r2
61 vadd.f32 d4, d16, d17 @ r4+r5,i4+i5
62 vmov d28, r3, r2
63 vadd.f32 d5, d18, d19 @ r6+r7,i6+i7
64 vsub.f32 d17, d16, d17 @ r4-r5,i4-i5
65 vsub.f32 d19, d18, d19 @ r6-r7,i6-i7
66 vrev64.32 d29, d28
67 vadd.f32 d20, d0, d1 @ r0+r1,i0+i1
68 vadd.f32 d21, d2, d3 @ r2+r3,i2+i3
69 vmul.f32 d26, d17, d28 @ -a2r*w,a2i*w
70 vext.32 q3, q2, q2, #1
71 vmul.f32 d27, d19, d29 @ a3r*w,-a3i*w
72 vsub.f32 d23, d22, d23 @ i2-i3,r3-r2
73 vsub.f32 d22, d0, d1 @ r0-r1,i0-i1
74 vmul.f32 d24, d17, d31 @ a2r*w,a2i*w
75 vmul.f32 d25, d19, d31 @ a3r*w,a3i*w
76 vadd.f32 d0, d20, d21
77 vsub.f32 d2, d20, d21
78 vadd.f32 d1, d22, d23
79 vrev64.32 q13, q13
80 vsub.f32 d3, d22, d23
81 vsub.f32 d6, d6, d7
82 vadd.f32 d24, d24, d26 @ a2r+a2i,a2i-a2r t1,t2
83 vadd.f32 d25, d25, d27 @ a3r-a3i,a3i+a3r t5,t6
84 vadd.f32 d7, d4, d5
85 vsub.f32 d18, d2, d6
86 vext.32 q13, q12, q12, #1
87 vadd.f32 d2, d2, d6
88 vsub.f32 d16, d0, d7
89 vadd.f32 d5, d25, d24
90 vsub.f32 d4, d26, d27
91 vadd.f32 d0, d0, d7
92 vsub.f32 d17, d1, d5
93 vsub.f32 d19, d3, d4
94 vadd.f32 d3, d3, d4
95 vadd.f32 d1, d1, d5
96
97 vst1.32 {d16-d19}, [r1,:128]
98 vst1.32 {d0-d3}, [r0,:128]
99
100 bx lr
101endfunc
102
103function fft16_neon
104 movrel r1, mppm
105 vld1.32 {d16-d19}, [r0,:128]! @ q8{r0,i0,r1,i1} q9{r2,i2,r3,i3}
106 pld [r0, #32]
107 vld1.32 {d2-d3}, [r1,:128]
108 vext.32 q13, q9, q9, #1
109 vld1.32 {d22-d25}, [r0,:128]! @ q11{r4,i4,r5,i5} q12{r6,i5,r7,i7}
110 vadd.f32 d4, d16, d17
111 vsub.f32 d5, d16, d17
112 vadd.f32 d18, d18, d19
113 vsub.f32 d19, d26, d27
114
115 vadd.f32 d20, d22, d23
116 vsub.f32 d22, d22, d23
117 vsub.f32 d23, d24, d25
118 vadd.f32 q8, q2, q9 @ {r0,i0,r1,i1}
119 vadd.f32 d21, d24, d25
120 vmul.f32 d24, d22, d2
121 vsub.f32 q9, q2, q9 @ {r2,i2,r3,i3}
122 vmul.f32 d25, d23, d3
123 vuzp.32 d16, d17 @ {r0,r1,i0,i1}
124 vmul.f32 q1, q11, d2[1]
125 vuzp.32 d18, d19 @ {r2,r3,i2,i3}
126 vrev64.32 q12, q12
127 vadd.f32 q11, q12, q1 @ {t1a,t2a,t5,t6}
128 vld1.32 {d24-d27}, [r0,:128]! @ q12{r8,i8,r9,i9} q13{r10,i10,r11,i11}
129 vzip.32 q10, q11
130 vld1.32 {d28-d31}, [r0,:128] @ q14{r12,i12,r13,i13} q15{r14,i14,r15,i15}
131 vadd.f32 d0, d22, d20
132 vadd.f32 d1, d21, d23
133 vsub.f32 d2, d21, d23
134 vsub.f32 d3, d22, d20
135 sub r0, r0, #96
136 vext.32 q13, q13, q13, #1
137 vsub.f32 q10, q8, q0 @ {r4,r5,i4,i5}
138 vadd.f32 q8, q8, q0 @ {r0,r1,i0,i1}
139 vext.32 q15, q15, q15, #1
140 vsub.f32 q11, q9, q1 @ {r6,r7,i6,i7}
141 vswp d25, d26 @ q12{r8,i8,i10,r11} q13{r9,i9,i11,r10}
142 vadd.f32 q9, q9, q1 @ {r2,r3,i2,i3}
143 vswp d29, d30 @ q14{r12,i12,i14,r15} q15{r13,i13,i15,r14}
144 vadd.f32 q0, q12, q13 @ {t1,t2,t5,t6}
145 vadd.f32 q1, q14, q15 @ {t1a,t2a,t5a,t6a}
146 movrelx r2, X(ff_cos_16)
147 vsub.f32 q13, q12, q13 @ {t3,t4,t7,t8}
148 vrev64.32 d1, d1
149 vsub.f32 q15, q14, q15 @ {t3a,t4a,t7a,t8a}
150 vrev64.32 d3, d3
151 movrel r3, pmmp
152 vswp d1, d26 @ q0{t1,t2,t3,t4} q13{t6,t5,t7,t8}
153 vswp d3, d30 @ q1{t1a,t2a,t3a,t4a} q15{t6a,t5a,t7a,t8a}
154 vadd.f32 q12, q0, q13 @ {r8,i8,r9,i9}
155 vadd.f32 q14, q1, q15 @ {r12,i12,r13,i13}
156 vld1.32 {d4-d5}, [r2,:64]
157 vsub.f32 q13, q0, q13 @ {r10,i10,r11,i11}
158 vsub.f32 q15, q1, q15 @ {r14,i14,r15,i15}
159 vswp d25, d28 @ q12{r8,i8,r12,i12} q14{r9,i9,r13,i13}
160 vld1.32 {d6-d7}, [r3,:128]
161 vrev64.32 q1, q14
162 vmul.f32 q14, q14, d4[1]
163 vmul.f32 q1, q1, q3
164 vmla.f32 q14, q1, d5[1] @ {t1a,t2a,t5a,t6a}
165 vswp d27, d30 @ q13{r10,i10,r14,i14} q15{r11,i11,r15,i15}
166 vzip.32 q12, q14
167 vadd.f32 d0, d28, d24
168 vadd.f32 d1, d25, d29
169 vsub.f32 d2, d25, d29
170 vsub.f32 d3, d28, d24
171 vsub.f32 q12, q8, q0 @ {r8,r9,i8,i9}
172 vadd.f32 q8, q8, q0 @ {r0,r1,i0,i1}
173 vsub.f32 q14, q10, q1 @ {r12,r13,i12,i13}
174 mov r1, #32
175 vadd.f32 q10, q10, q1 @ {r4,r5,i4,i5}
176 vrev64.32 q0, q13
177 vmul.f32 q13, q13, d5[0]
178 vrev64.32 q1, q15
179 vmul.f32 q15, q15, d5[1]
180 vst2.32 {d16-d17},[r0,:128], r1
181 vmul.f32 q0, q0, q3
182 vst2.32 {d20-d21},[r0,:128], r1
183 vmul.f32 q1, q1, q3
184 vmla.f32 q13, q0, d5[0] @ {t1,t2,t5,t6}
185 vmla.f32 q15, q1, d4[1] @ {t1a,t2a,t5a,t6a}
186 vst2.32 {d24-d25},[r0,:128], r1
187 vst2.32 {d28-d29},[r0,:128]
188 vzip.32 q13, q15
189 sub r0, r0, #80
190 vadd.f32 d0, d30, d26
191 vadd.f32 d1, d27, d31
192 vsub.f32 d2, d27, d31
193 vsub.f32 d3, d30, d26
194 vsub.f32 q13, q9, q0 @ {r10,r11,i10,i11}
195 vadd.f32 q9, q9, q0 @ {r2,r3,i2,i3}
196 vsub.f32 q15, q11, q1 @ {r14,r15,i14,i15}
197 vadd.f32 q11, q11, q1 @ {r6,r7,i6,i7}
198 vst2.32 {d18-d19},[r0,:128], r1
199 vst2.32 {d22-d23},[r0,:128], r1
200 vst2.32 {d26-d27},[r0,:128], r1
201 vst2.32 {d30-d31},[r0,:128]
202 bx lr
203endfunc
204
205function fft_pass_neon
206 push {r4-r6,lr}
207 mov r6, r2 @ n
208 lsl r5, r2, #3 @ 2 * n * sizeof FFTSample
209 lsl r4, r2, #4 @ 2 * n * sizeof FFTComplex
210 lsl r2, r2, #5 @ 4 * n * sizeof FFTComplex
211 add r3, r2, r4
212 add r4, r4, r0 @ &z[o1]
213 add r2, r2, r0 @ &z[o2]
214 add r3, r3, r0 @ &z[o3]
215 vld1.32 {d20-d21},[r2,:128] @ {z[o2],z[o2+1]}
216 movrel r12, pmmp
217 vld1.32 {d22-d23},[r3,:128] @ {z[o3],z[o3+1]}
218 add r5, r5, r1 @ wim
219 vld1.32 {d6-d7}, [r12,:128] @ pmmp
220 vswp d21, d22
221 vld1.32 {d4}, [r1,:64]! @ {wre[0],wre[1]}
222 sub r5, r5, #4 @ wim--
223 vrev64.32 q1, q11
224 vmul.f32 q11, q11, d4[1]
225 vmul.f32 q1, q1, q3
226 vld1.32 {d5[0]}, [r5,:32] @ d5[0] = wim[-1]
227 vmla.f32 q11, q1, d5[0] @ {t1a,t2a,t5a,t6a}
228 vld2.32 {d16-d17},[r0,:128] @ {z[0],z[1]}
229 sub r6, r6, #1 @ n--
230 vld2.32 {d18-d19},[r4,:128] @ {z[o1],z[o1+1]}
231 vzip.32 q10, q11
232 vadd.f32 d0, d22, d20
233 vadd.f32 d1, d21, d23
234 vsub.f32 d2, d21, d23
235 vsub.f32 d3, d22, d20
236 vsub.f32 q10, q8, q0
237 vadd.f32 q8, q8, q0
238 vsub.f32 q11, q9, q1
239 vadd.f32 q9, q9, q1
240 vst2.32 {d20-d21},[r2,:128]! @ {z[o2],z[o2+1]}
241 vst2.32 {d16-d17},[r0,:128]! @ {z[0],z[1]}
242 vst2.32 {d22-d23},[r3,:128]! @ {z[o3],z[o3+1]}
243 vst2.32 {d18-d19},[r4,:128]! @ {z[o1],z[o1+1]}
244 sub r5, r5, #8 @ wim -= 2
2451:
246 vld1.32 {d20-d21},[r2,:128] @ {z[o2],z[o2+1]}
247 vld1.32 {d22-d23},[r3,:128] @ {z[o3],z[o3+1]}
248 vswp d21, d22
249 vld1.32 {d4}, [r1]! @ {wre[0],wre[1]}
250 vrev64.32 q0, q10
251 vmul.f32 q10, q10, d4[0]
252 vrev64.32 q1, q11
253 vmul.f32 q11, q11, d4[1]
254 vld1.32 {d5}, [r5] @ {wim[-1],wim[0]}
255 vmul.f32 q0, q0, q3
256 sub r5, r5, #8 @ wim -= 2
257 vmul.f32 q1, q1, q3
258 vmla.f32 q10, q0, d5[1] @ {t1,t2,t5,t6}
259 vmla.f32 q11, q1, d5[0] @ {t1a,t2a,t5a,t6a}
260 vld2.32 {d16-d17},[r0,:128] @ {z[0],z[1]}
261 subs r6, r6, #1 @ n--
262 vld2.32 {d18-d19},[r4,:128] @ {z[o1],z[o1+1]}
263 vzip.32 q10, q11
264 vadd.f32 d0, d22, d20
265 vadd.f32 d1, d21, d23
266 vsub.f32 d2, d21, d23
267 vsub.f32 d3, d22, d20
268 vsub.f32 q10, q8, q0
269 vadd.f32 q8, q8, q0
270 vsub.f32 q11, q9, q1
271 vadd.f32 q9, q9, q1
272 vst2.32 {d20-d21}, [r2,:128]! @ {z[o2],z[o2+1]}
273 vst2.32 {d16-d17}, [r0,:128]! @ {z[0],z[1]}
274 vst2.32 {d22-d23}, [r3,:128]! @ {z[o3],z[o3+1]}
275 vst2.32 {d18-d19}, [r4,:128]! @ {z[o1],z[o1+1]}
276 bne 1b
277
278 pop {r4-r6,pc}
279endfunc
280
281.macro def_fft n, n2, n4
282 .align 6
283function fft\n\()_neon
284 push {r4, lr}
285 mov r4, r0
286 bl fft\n2\()_neon
287 add r0, r4, #\n4*2*8
288 bl fft\n4\()_neon
289 add r0, r4, #\n4*3*8
290 bl fft\n4\()_neon
291 mov r0, r4
292 pop {r4, lr}
293 movrelx r1, X(ff_cos_\n)
294 mov r2, #\n4/2
295 b fft_pass_neon
296endfunc
297.endm
298
299 def_fft 32, 16, 8
300 def_fft 64, 32, 16
301 def_fft 128, 64, 32
302 def_fft 256, 128, 64
303 def_fft 512, 256, 128
304 def_fft 1024, 512, 256
305 def_fft 2048, 1024, 512
306 def_fft 4096, 2048, 1024
307 def_fft 8192, 4096, 2048
308 def_fft 16384, 8192, 4096
309 def_fft 32768, 16384, 8192
310 def_fft 65536, 32768, 16384
311
312function ff_fft_calc_neon, export=1
313 ldr r2, [r0]
314 sub r2, r2, #2
315 movrel r3, fft_tab_neon
316 ldr r3, [r3, r2, lsl #2]
317 mov r0, r1
318 bx r3
319endfunc
320
321function ff_fft_permute_neon, export=1
322 push {r4,lr}
323 mov r12, #1
324 ldr r2, [r0] @ nbits
325 ldr r3, [r0, #12] @ tmp_buf
326 ldr r0, [r0, #8] @ revtab
327 lsl r12, r12, r2
328 mov r2, r12
3291:
330 vld1.32 {d0-d1}, [r1,:128]!
331 ldr r4, [r0], #4
332 uxth lr, r4
333 uxth r4, r4, ror #16
334 add lr, r3, lr, lsl #3
335 add r4, r3, r4, lsl #3
336 vst1.32 {d0}, [lr,:64]
337 vst1.32 {d1}, [r4,:64]
338 subs r12, r12, #2
339 bgt 1b
340
341 sub r1, r1, r2, lsl #3
3421:
343 vld1.32 {d0-d3}, [r3,:128]!
344 vst1.32 {d0-d3}, [r1,:128]!
345 subs r2, r2, #4
346 bgt 1b
347
348 pop {r4,pc}
349endfunc
350
351const fft_tab_neon
352 .word fft4_neon
353 .word fft8_neon
354 .word fft16_neon
355 .word fft32_neon
356 .word fft64_neon
357 .word fft128_neon
358 .word fft256_neon
359 .word fft512_neon
360 .word fft1024_neon
361 .word fft2048_neon
362 .word fft4096_neon
363 .word fft8192_neon
364 .word fft16384_neon
365 .word fft32768_neon
366 .word fft65536_neon
367endconst
368
369const pmmp, align=4
370 .float +1.0, -1.0, -1.0, +1.0
371endconst
372
373const mppm, align=4
374 .float -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2
375endconst