Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/*
2
 * ARM NEON optimised FFT
3
 *
4
 * Copyright (c) 2009 Mans Rullgard 
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
 
32
function 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
48
endfunc
49
 
50
function 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
101
endfunc
102
 
103
function 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
203
endfunc
204
 
205
function 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
245
1:
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}
279
endfunc
280
 
281
.macro  def_fft n, n2, n4
282
        .align 6
283
function 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
296
endfunc
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
 
312
function 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
319
endfunc
320
 
321
function 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
329
1:
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
342
1:
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}
349
endfunc
350
 
351
const   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
endconst
368
 
369
const   pmmp, align=4
370
        .float          +1.0, -1.0, -1.0, +1.0
371
endconst
372
 
373
const   mppm, align=4
374
        .float          -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2
375
endconst