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