Statistics
| Branch: | Revision:

ffmpeg / libavcodec / arm / fft_neon.S @ 2912e87a

History | View | Annotate | Download (15 KB)

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 Libav.
11
 *
12
 * Libav 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
 * Libav 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 Libav; if not, write to the Free Software
24
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25
 */
26

    
27
#include "asm.S"
28

    
29
#define M_SQRT1_2 0.70710678118654752440
30

    
31
        .text
32

    
33
function fft4_neon
34
        vld1.32         {d0-d3}, [r0,:128]
35

    
36
        vext.32         q8,  q1,  q1,  #1       @ i2,r3 d3=i3,r2
37
        vsub.f32        d6,  d0,  d1            @ r0-r1,i0-i1
38
        vsub.f32        d7,  d16, d17           @ r3-r2,i2-i3
39
        vadd.f32        d4,  d0,  d1            @ r0+r1,i0+i1
40
        vadd.f32        d5,  d2,  d3            @ i2+i3,r2+r3
41
        vadd.f32        d1,  d6,  d7
42
        vsub.f32        d3,  d6,  d7
43
        vadd.f32        d0,  d4,  d5
44
        vsub.f32        d2,  d4,  d5
45

    
46
        vst1.32         {d0-d3}, [r0,:128]
47

    
48
        bx              lr
49
endfunc
50

    
51
function fft8_neon
52
        mov             r1,  r0
53
        vld1.32         {d0-d3},   [r1,:128]!
54
        vld1.32         {d16-d19}, [r1,:128]
55

    
56
        movw            r2,  #0x04f3            @ sqrt(1/2)
57
        movt            r2,  #0x3f35
58
        eor             r3,  r2,  #1<<31
59
        vdup.32         d31, r2
60

    
61
        vext.32         q11, q1,  q1,  #1       @ i2,r3,i3,r2
62
        vadd.f32        d4,  d16, d17           @ r4+r5,i4+i5
63
        vmov            d28, r3,  r2
64
        vadd.f32        d5,  d18, d19           @ r6+r7,i6+i7
65
        vsub.f32        d17, d16, d17           @ r4-r5,i4-i5
66
        vsub.f32        d19, d18, d19           @ r6-r7,i6-i7
67
        vrev64.32       d29, d28
68
        vadd.f32        d20, d0,  d1            @ r0+r1,i0+i1
69
        vadd.f32        d21, d2,  d3            @ r2+r3,i2+i3
70
        vmul.f32        d26, d17, d28           @ -a2r*w,a2i*w
71
        vext.32         q3,  q2,  q2,  #1
72
        vmul.f32        d27, d19, d29           @ a3r*w,-a3i*w
73
        vsub.f32        d23, d22, d23           @ i2-i3,r3-r2
74
        vsub.f32        d22, d0,  d1            @ r0-r1,i0-i1
75
        vmul.f32        d24, d17, d31           @ a2r*w,a2i*w
76
        vmul.f32        d25, d19, d31           @ a3r*w,a3i*w
77
        vadd.f32        d0,  d20, d21
78
        vsub.f32        d2,  d20, d21
79
        vadd.f32        d1,  d22, d23
80
        vrev64.32       q13, q13
81
        vsub.f32        d3,  d22, d23
82
        vsub.f32        d6,  d6,  d7
83
        vadd.f32        d24, d24, d26           @ a2r+a2i,a2i-a2r   t1,t2
84
        vadd.f32        d25, d25, d27           @ a3r-a3i,a3i+a3r   t5,t6
85
        vadd.f32        d7,  d4,  d5
86
        vsub.f32        d18, d2,  d6
87
        vext.32         q13, q12, q12, #1
88
        vadd.f32        d2,  d2,  d6
89
        vsub.f32        d16, d0,  d7
90
        vadd.f32        d5,  d25, d24
91
        vsub.f32        d4,  d26, d27
92
        vadd.f32        d0,  d0,  d7
93
        vsub.f32        d17, d1,  d5
94
        vsub.f32        d19, d3,  d4
95
        vadd.f32        d3,  d3,  d4
96
        vadd.f32        d1,  d1,  d5
97

    
98
        vst1.32         {d16-d19}, [r1,:128]
99
        vst1.32         {d0-d3},   [r0,:128]
100

    
101
        bx              lr
102
endfunc
103

    
104
function fft16_neon
105
        movrel          r1, mppm
106
        vld1.32         {d16-d19}, [r0,:128]!   @ q8{r0,i0,r1,i1} q9{r2,i2,r3,i3}
107
        pld             [r0, #32]
108
        vld1.32         {d2-d3}, [r1,:128]
109
        vext.32         q13, q9,  q9,  #1
110
        vld1.32         {d22-d25}, [r0,:128]!   @ q11{r4,i4,r5,i5} q12{r6,i5,r7,i7}
111
        vadd.f32        d4,  d16, d17
112
        vsub.f32        d5,  d16, d17
113
        vadd.f32        d18, d18, d19
114
        vsub.f32        d19, d26, d27
115

    
116
        vadd.f32        d20, d22, d23
117
        vsub.f32        d22, d22, d23
118
        vsub.f32        d23, d24, d25
119
        vadd.f32        q8,  q2,  q9            @ {r0,i0,r1,i1}
120
        vadd.f32        d21, d24, d25
121
        vmul.f32        d24, d22, d2
122
        vsub.f32        q9,  q2,  q9            @ {r2,i2,r3,i3}
123
        vmul.f32        d25, d23, d3
124
        vuzp.32         d16, d17                @ {r0,r1,i0,i1}
125
        vmul.f32        q1,  q11, d2[1]
126
        vuzp.32         d18, d19                @ {r2,r3,i2,i3}
127
        vrev64.32       q12, q12
128
        vadd.f32        q11, q12, q1            @ {t1a,t2a,t5,t6}
129
        vld1.32         {d24-d27}, [r0,:128]!   @ q12{r8,i8,r9,i9} q13{r10,i10,r11,i11}
130
        vzip.32         q10, q11
131
        vld1.32         {d28-d31}, [r0,:128]    @ q14{r12,i12,r13,i13} q15{r14,i14,r15,i15}
132
        vadd.f32        d0,  d22, d20
133
        vadd.f32        d1,  d21, d23
134
        vsub.f32        d2,  d21, d23
135
        vsub.f32        d3,  d22, d20
136
        sub             r0,  r0,  #96
137
        vext.32         q13, q13, q13, #1
138
        vsub.f32        q10, q8,  q0            @ {r4,r5,i4,i5}
139
        vadd.f32        q8,  q8,  q0            @ {r0,r1,i0,i1}
140
        vext.32         q15, q15, q15, #1
141
        vsub.f32        q11, q9,  q1            @ {r6,r7,i6,i7}
142
        vswp            d25, d26                @ q12{r8,i8,i10,r11} q13{r9,i9,i11,r10}
143
        vadd.f32        q9,  q9,  q1            @ {r2,r3,i2,i3}
144
        vswp            d29, d30                @ q14{r12,i12,i14,r15} q15{r13,i13,i15,r14}
145
        vadd.f32        q0,  q12, q13           @ {t1,t2,t5,t6}
146
        vadd.f32        q1,  q14, q15           @ {t1a,t2a,t5a,t6a}
147
        movrel          r2,  X(ff_cos_16)
148
        vsub.f32        q13, q12, q13           @ {t3,t4,t7,t8}
149
        vrev64.32       d1,  d1
150
        vsub.f32        q15, q14, q15           @ {t3a,t4a,t7a,t8a}
151
        vrev64.32       d3,  d3
152
        movrel          r3,  pmmp
153
        vswp            d1,  d26                @ q0{t1,t2,t3,t4} q13{t6,t5,t7,t8}
154
        vswp            d3,  d30                @ q1{t1a,t2a,t3a,t4a} q15{t6a,t5a,t7a,t8a}
155
        vadd.f32        q12, q0,  q13           @ {r8,i8,r9,i9}
156
        vadd.f32        q14, q1,  q15           @ {r12,i12,r13,i13}
157
        vld1.32         {d4-d5},  [r2,:64]
158
        vsub.f32        q13, q0,  q13           @ {r10,i10,r11,i11}
159
        vsub.f32        q15, q1,  q15           @ {r14,i14,r15,i15}
160
        vswp            d25, d28                @ q12{r8,i8,r12,i12} q14{r9,i9,r13,i13}
161
        vld1.32         {d6-d7},  [r3,:128]
162
        vrev64.32       q1,  q14
163
        vmul.f32        q14, q14, d4[1]
164
        vmul.f32        q1,  q1,  q3
165
        vmla.f32        q14, q1,  d5[1]         @ {t1a,t2a,t5a,t6a}
166
        vswp            d27, d30                @ q13{r10,i10,r14,i14} q15{r11,i11,r15,i15}
167
        vzip.32         q12, q14
168
        vadd.f32        d0,  d28, d24
169
        vadd.f32        d1,  d25, d29
170
        vsub.f32        d2,  d25, d29
171
        vsub.f32        d3,  d28, d24
172
        vsub.f32        q12, q8,  q0            @ {r8,r9,i8,i9}
173
        vadd.f32        q8,  q8,  q0            @ {r0,r1,i0,i1}
174
        vsub.f32        q14, q10, q1            @ {r12,r13,i12,i13}
175
        mov             r1,  #32
176
        vadd.f32        q10, q10, q1            @ {r4,r5,i4,i5}
177
        vrev64.32       q0,  q13
178
        vmul.f32        q13, q13, d5[0]
179
        vrev64.32       q1,  q15
180
        vmul.f32        q15, q15, d5[1]
181
        vst2.32         {d16-d17},[r0,:128], r1
182
        vmul.f32        q0,  q0,  q3
183
        vst2.32         {d20-d21},[r0,:128], r1
184
        vmul.f32        q1,  q1,  q3
185
        vmla.f32        q13, q0,  d5[0]         @ {t1,t2,t5,t6}
186
        vmla.f32        q15, q1,  d4[1]         @ {t1a,t2a,t5a,t6a}
187
        vst2.32         {d24-d25},[r0,:128], r1
188
        vst2.32         {d28-d29},[r0,:128]
189
        vzip.32         q13, q15
190
        sub             r0, r0, #80
191
        vadd.f32        d0,  d30, d26
192
        vadd.f32        d1,  d27, d31
193
        vsub.f32        d2,  d27, d31
194
        vsub.f32        d3,  d30, d26
195
        vsub.f32        q13, q9,  q0            @ {r10,r11,i10,i11}
196
        vadd.f32        q9,  q9,  q0            @ {r2,r3,i2,i3}
197
        vsub.f32        q15, q11, q1            @ {r14,r15,i14,i15}
198
        vadd.f32        q11, q11, q1            @ {r6,r7,i6,i7}
199
        vst2.32         {d18-d19},[r0,:128], r1
200
        vst2.32         {d22-d23},[r0,:128], r1
201
        vst2.32         {d26-d27},[r0,:128], r1
202
        vst2.32         {d30-d31},[r0,:128]
203
        bx              lr
204
endfunc
205

    
206
function fft_pass_neon
207
        push            {r4-r6,lr}
208
        mov             r6,  r2                 @ n
209
        lsl             r5,  r2,  #3            @ 2 * n * sizeof FFTSample
210
        lsl             r4,  r2,  #4            @ 2 * n * sizeof FFTComplex
211
        lsl             r2,  r2,  #5            @ 4 * n * sizeof FFTComplex
212
        add             r3,  r2,  r4
213
        add             r4,  r4,  r0            @ &z[o1]
214
        add             r2,  r2,  r0            @ &z[o2]
215
        add             r3,  r3,  r0            @ &z[o3]
216
        vld1.32         {d20-d21},[r2,:128]     @ {z[o2],z[o2+1]}
217
        movrel          r12, pmmp
218
        vld1.32         {d22-d23},[r3,:128]     @ {z[o3],z[o3+1]}
219
        add             r5,  r5,  r1            @ wim
220
        vld1.32         {d6-d7},  [r12,:128]    @ pmmp
221
        vswp            d21, d22
222
        vld1.32         {d4},     [r1,:64]!     @ {wre[0],wre[1]}
223
        sub             r5,  r5,  #4            @ wim--
224
        vrev64.32       q1,  q11
225
        vmul.f32        q11, q11, d4[1]
226
        vmul.f32        q1,  q1,  q3
227
        vld1.32         {d5[0]},  [r5,:32]      @ d5[0] = wim[-1]
228
        vmla.f32        q11, q1,  d5[0]         @ {t1a,t2a,t5a,t6a}
229
        vld2.32         {d16-d17},[r0,:128]     @ {z[0],z[1]}
230
        sub             r6, r6, #1              @ n--
231
        vld2.32         {d18-d19},[r4,:128]     @ {z[o1],z[o1+1]}
232
        vzip.32         q10, q11
233
        vadd.f32        d0,  d22, d20
234
        vadd.f32        d1,  d21, d23
235
        vsub.f32        d2,  d21, d23
236
        vsub.f32        d3,  d22, d20
237
        vsub.f32        q10, q8,  q0
238
        vadd.f32        q8,  q8,  q0
239
        vsub.f32        q11, q9,  q1
240
        vadd.f32        q9,  q9,  q1
241
        vst2.32         {d20-d21},[r2,:128]!    @ {z[o2],z[o2+1]}
242
        vst2.32         {d16-d17},[r0,:128]!    @ {z[0],z[1]}
243
        vst2.32         {d22-d23},[r3,:128]!    @ {z[o3],z[o3+1]}
244
        vst2.32         {d18-d19},[r4,:128]!    @ {z[o1],z[o1+1]}
245
        sub             r5,  r5,  #8            @ wim -= 2
246
1:
247
        vld1.32         {d20-d21},[r2,:128]     @ {z[o2],z[o2+1]}
248
        vld1.32         {d22-d23},[r3,:128]     @ {z[o3],z[o3+1]}
249
        vswp            d21, d22
250
        vld1.32         {d4}, [r1]!             @ {wre[0],wre[1]}
251
        vrev64.32       q0,  q10
252
        vmul.f32        q10, q10, d4[0]
253
        vrev64.32       q1,  q11
254
        vmul.f32        q11, q11, d4[1]
255
        vld1.32         {d5}, [r5]              @ {wim[-1],wim[0]}
256
        vmul.f32        q0,  q0,  q3
257
        sub             r5,  r5,  #8            @ wim -= 2
258
        vmul.f32        q1,  q1,  q3
259
        vmla.f32        q10, q0,  d5[1]         @ {t1,t2,t5,t6}
260
        vmla.f32        q11, q1,  d5[0]         @ {t1a,t2a,t5a,t6a}
261
        vld2.32         {d16-d17},[r0,:128]     @ {z[0],z[1]}
262
        subs            r6,  r6,  #1            @ n--
263
        vld2.32         {d18-d19},[r4,:128]     @ {z[o1],z[o1+1]}
264
        vzip.32         q10, q11
265
        vadd.f32        d0,  d22, d20
266
        vadd.f32        d1,  d21, d23
267
        vsub.f32        d2,  d21, d23
268
        vsub.f32        d3,  d22, d20
269
        vsub.f32        q10, q8,  q0
270
        vadd.f32        q8,  q8,  q0
271
        vsub.f32        q11, q9,  q1
272
        vadd.f32        q9,  q9,  q1
273
        vst2.32         {d20-d21}, [r2,:128]!   @ {z[o2],z[o2+1]}
274
        vst2.32         {d16-d17}, [r0,:128]!   @ {z[0],z[1]}
275
        vst2.32         {d22-d23}, [r3,:128]!   @ {z[o3],z[o3+1]}
276
        vst2.32         {d18-d19}, [r4,:128]!   @ {z[o1],z[o1+1]}
277
        bne             1b
278

    
279
        pop             {r4-r6,pc}
280
endfunc
281

    
282
.macro  def_fft n, n2, n4
283
        .align 6
284
function fft\n\()_neon
285
        push            {r4, lr}
286
        mov             r4,  r0
287
        bl              fft\n2\()_neon
288
        add             r0,  r4,  #\n4*2*8
289
        bl              fft\n4\()_neon
290
        add             r0,  r4,  #\n4*3*8
291
        bl              fft\n4\()_neon
292
        mov             r0,  r4
293
        pop             {r4, lr}
294
        movrel          r1,  X(ff_cos_\n)
295
        mov             r2,  #\n4/2
296
        b               fft_pass_neon
297
endfunc
298
.endm
299

    
300
        def_fft    32,    16,     8
301
        def_fft    64,    32,    16
302
        def_fft   128,    64,    32
303
        def_fft   256,   128,    64
304
        def_fft   512,   256,   128
305
        def_fft  1024,   512,   256
306
        def_fft  2048,  1024,   512
307
        def_fft  4096,  2048,  1024
308
        def_fft  8192,  4096,  2048
309
        def_fft 16384,  8192,  4096
310
        def_fft 32768, 16384,  8192
311
        def_fft 65536, 32768, 16384
312

    
313
function ff_fft_calc_neon, export=1
314
        ldr             r2,  [r0]
315
        sub             r2,  r2,  #2
316
        movrel          r3,  fft_tab_neon
317
        ldr             r3,  [r3, r2, lsl #2]
318
        mov             r0,  r1
319
        bx              r3
320
endfunc
321

    
322
function ff_fft_permute_neon, export=1
323
        push            {r4,lr}
324
        mov             r12, #1
325
        ldr             r2,  [r0]       @ nbits
326
        ldr             r3,  [r0, #12]  @ tmp_buf
327
        ldr             r0,  [r0, #8]   @ revtab
328
        lsl             r12, r12, r2
329
        mov             r2,  r12
330
1:
331
        vld1.32         {d0-d1}, [r1,:128]!
332
        ldr             r4,  [r0], #4
333
        uxth            lr,  r4
334
        uxth            r4,  r4,  ror #16
335
        add             lr,  r3,  lr,  lsl #3
336
        add             r4,  r3,  r4,  lsl #3
337
        vst1.32         {d0}, [lr,:64]
338
        vst1.32         {d1}, [r4,:64]
339
        subs            r12, r12, #2
340
        bgt             1b
341

    
342
        sub             r1,  r1,  r2,  lsl #3
343
1:
344
        vld1.32         {d0-d3}, [r3,:128]!
345
        vst1.32         {d0-d3}, [r1,:128]!
346
        subs            r2,  r2,  #4
347
        bgt             1b
348

    
349
        pop             {r4,pc}
350
endfunc
351

    
352
        .section .rodata
353
        .align 4
354
fft_tab_neon:
355
        .word fft4_neon
356
        .word fft8_neon
357
        .word fft16_neon
358
        .word fft32_neon
359
        .word fft64_neon
360
        .word fft128_neon
361
        .word fft256_neon
362
        .word fft512_neon
363
        .word fft1024_neon
364
        .word fft2048_neon
365
        .word fft4096_neon
366
        .word fft8192_neon
367
        .word fft16384_neon
368
        .word fft32768_neon
369
        .word fft65536_neon
370
ELF     .size fft_tab_neon, . - fft_tab_neon
371

    
372
        .align 4
373
pmmp:   .float  +1.0, -1.0, -1.0, +1.0
374
mppm:   .float  -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2