1/*
2 * ARM NEON optimised RDFT
3 * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include "libavutil/arm/asm.S"
23
24function ff_rdft_calc_neon, export=1
25        push            {r4-r8,lr}
26
27        ldr             r6,  [r0, #4]           @ inverse
28        mov             r4,  r0
29        mov             r5,  r1
30
31        lsls            r6,  r6,  #31
32        bne             1f
33        add             r0,  r4,  #20
34        bl              X(ff_fft_permute_neon)
35        add             r0,  r4,  #20
36        mov             r1,  r5
37        bl              X(ff_fft_calc_neon)
381:
39        ldr             r12, [r4, #0]           @ nbits
40        mov             r2,  #1
41        lsl             r12, r2,  r12
42        add             r0,  r5,  #8
43        add             r1,  r5,  r12, lsl #2
44        lsr             r12, r12, #2
45        ldr             r2,  [r4, #12]          @ tcos
46        sub             r12, r12, #2
47        ldr             r3,  [r4, #16]          @ tsin
48        mov             r7,  r0
49        sub             r1,  r1,  #8
50        mov             lr,  r1
51        mov             r8,  #-8
52        vld1.32         {d0},     [r0,:64]!     @ d1[0,1]
53        vld1.32         {d1},     [r1,:64], r8  @ d2[0,1]
54        vld1.32         {d4},     [r2,:64]!     @ tcos[i]
55        vld1.32         {d5},     [r3,:64]!     @ tsin[i]
56        vmov.f32        d18, #0.5               @ k1
57        vdup.32         d19, r6
58        pld             [r0, #32]
59        veor            d19, d18, d19           @ k2
60        vmov.i32        d16, #0
61        vmov.i32        d17, #1<<31
62        pld             [r1, #-32]
63        vtrn.32         d16, d17
64        pld             [r2, #32]
65        vrev64.32       d16, d16                @ d16=1,0 d17=0,1
66        pld             [r3, #32]
672:
68        veor            q1,  q0,  q8            @ -d1[0],d1[1], d2[0],-d2[1]
69        vld1.32         {d24},    [r0,:64]!     @  d1[0,1]
70        vadd.f32        d0,  d0,  d3            @  d1[0]+d2[0], d1[1]-d2[1]
71        vld1.32         {d25},    [r1,:64], r8  @  d2[0,1]
72        vadd.f32        d1,  d2,  d1            @ -d1[0]+d2[0], d1[1]+d2[1]
73        veor            q3,  q12, q8            @ -d1[0],d1[1], d2[0],-d2[1]
74        pld             [r0, #32]
75        vmul.f32        q10, q0,  q9            @  ev.re, ev.im, od.im, od.re
76        pld             [r1, #-32]
77        vadd.f32        d0,  d24, d7            @  d1[0]+d2[0], d1[1]-d2[1]
78        vadd.f32        d1,  d6,  d25           @ -d1[0]+d2[0], d1[1]+d2[1]
79        vmul.f32        q11, q0,  q9            @  ev.re, ev.im, od.im, od.re
80        veor            d7,  d21, d16           @ -od.im, od.re
81        vrev64.32       d3,  d21                @  od.re, od.im
82        veor            d6,  d20, d17           @  ev.re,-ev.im
83        veor            d2,  d3,  d16           @ -od.re, od.im
84        vmla.f32        d20, d3,  d4[1]
85        vmla.f32        d20, d7,  d5[1]
86        vmla.f32        d6,  d2,  d4[1]
87        vmla.f32        d6,  d21, d5[1]
88        vld1.32         {d4},     [r2,:64]!     @  tcos[i]
89        veor            d7,  d23, d16           @ -od.im, od.re
90        vld1.32         {d5},     [r3,:64]!     @  tsin[i]
91        veor            d24, d22, d17           @  ev.re,-ev.im
92        vrev64.32       d3,  d23                @  od.re, od.im
93        pld             [r2, #32]
94        veor            d2,  d3,  d16           @ -od.re, od.im
95        pld             [r3, #32]
96        vmla.f32        d22, d3,  d4[0]
97        vmla.f32        d22, d7,  d5[0]
98        vmla.f32        d24, d2,  d4[0]
99        vmla.f32        d24, d23, d5[0]
100        vld1.32         {d0},     [r0,:64]!     @  d1[0,1]
101        vld1.32         {d1},     [r1,:64], r8  @  d2[0,1]
102        vst1.32         {d20},    [r7,:64]!
103        vst1.32         {d6},     [lr,:64], r8
104        vst1.32         {d22},    [r7,:64]!
105        vst1.32         {d24},    [lr,:64], r8
106        subs            r12, r12, #2
107        bgt             2b
108
109        veor            q1,  q0,  q8            @ -d1[0],d1[1], d2[0],-d2[1]
110        vadd.f32        d0,  d0,  d3            @  d1[0]+d2[0], d1[1]-d2[1]
111        vadd.f32        d1,  d2,  d1            @ -d1[0]+d2[0], d1[1]+d2[1]
112        ldr             r2,  [r4, #8]           @  sign_convention
113        vmul.f32        q10, q0,  q9            @  ev.re, ev.im, od.im, od.re
114        add             r0,  r0,  #4
115        bfc             r2,  #0,  #31
116        vld1.32         {d0[0]},  [r0,:32]
117        veor            d7,  d21, d16           @ -od.im, od.re
118        vrev64.32       d3,  d21                @  od.re, od.im
119        veor            d6,  d20, d17           @  ev.re,-ev.im
120        vld1.32         {d22},    [r5,:64]
121        vdup.32         d1,  r2
122        vmov            d23, d22
123        veor            d2,  d3,  d16           @ -od.re, od.im
124        vtrn.32         d22, d23
125        veor            d0,  d0,  d1
126        veor            d23, d23, d17
127        vmla.f32        d20, d3,  d4[1]
128        vmla.f32        d20, d7,  d5[1]
129        vmla.f32        d6,  d2,  d4[1]
130        vmla.f32        d6,  d21, d5[1]
131        vadd.f32        d22, d22, d23
132        vst1.32         {d20},    [r7,:64]
133        vst1.32         {d6},     [lr,:64]
134        vst1.32         {d0[0]},  [r0,:32]
135        vst1.32         {d22},    [r5,:64]
136
137        cmp             r6,  #0
138        it              eq
139        popeq           {r4-r8,pc}
140
141        vmul.f32        d22, d22, d18
142        vst1.32         {d22},    [r5,:64]
143        add             r0,  r4,  #20
144        mov             r1,  r5
145        bl              X(ff_fft_permute_neon)
146        add             r0,  r4,  #20
147        mov             r1,  r5
148        pop             {r4-r8,lr}
149        b               X(ff_fft_calc_neon)
150endfunc
151