57e16196f7c7d513f7746a006de7a8ae6db0f297
[ffmpeg.git] / libavcodec / arm / dcadsp_vfp.S
1 /*
2  * Copyright (c) 2013 RISC OS Open Ltd
3  * Author: Ben Avison <bavison@riscosopen.org>
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; 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
24 POUT          .req    a1
25 PIN           .req    a2
26 PCOEF         .req    a3
27 DECIFACTOR    .req    a4
28 OLDFPSCR      .req    a4
29 COUNTER       .req    ip
30
31 SCALE32       .req    s28  @ use vector of 4 in place of 9th scalar when decifactor=32 / JMAX=8
32 SCALE64       .req    s0   @ spare register in scalar bank when decifactor=64 / JMAX=4
33 IN0           .req    s4
34 IN1           .req    s5
35 IN2           .req    s6
36 IN3           .req    s7
37 IN4           .req    s0
38 IN5           .req    s1
39 IN6           .req    s2
40 IN7           .req    s3
41 COEF0         .req    s8   @ coefficient elements
42 COEF1         .req    s9
43 COEF2         .req    s10
44 COEF3         .req    s11
45 COEF4         .req    s12
46 COEF5         .req    s13
47 COEF6         .req    s14
48 COEF7         .req    s15
49 ACCUM0        .req    s16  @ double-buffered multiply-accumulate results
50 ACCUM4        .req    s20
51 POST0         .req    s24  @ do long-latency post-multiply in this vector in parallel
52 POST1         .req    s25
53 POST2         .req    s26
54 POST3         .req    s27
55
56
57 .macro inner_loop  decifactor, dir, tail, head
58  .ifc "\dir","up"
59   .set X, 0
60   .set Y, 4
61  .else
62   .set X, 4*JMAX*4 - 4
63   .set Y, -4
64  .endif
65  .ifnc "\head",""
66         vldr    COEF0, [PCOEF, #X + (0*JMAX + 0) * Y]
67         vldr    COEF1, [PCOEF, #X + (1*JMAX + 0) * Y]
68         vldr    COEF2, [PCOEF, #X + (2*JMAX + 0) * Y]
69         vldr    COEF3, [PCOEF, #X + (3*JMAX + 0) * Y]
70  .endif
71  .ifnc "\tail",""
72         vadd.f  POST0, ACCUM0, ACCUM4   @ vector operation
73  .endif
74  .ifnc "\head",""
75         vmul.f  ACCUM0, COEF0, IN0      @ vector = vector * scalar
76         vldr    COEF4, [PCOEF, #X + (0*JMAX + 1) * Y]
77         vldr    COEF5, [PCOEF, #X + (1*JMAX + 1) * Y]
78         vldr    COEF6, [PCOEF, #X + (2*JMAX + 1) * Y]
79  .endif
80  .ifnc "\tail",""
81         vmul.f  POST0, POST0, SCALE\decifactor  @ vector operation (SCALE may be scalar)
82  .endif
83  .ifnc "\head",""
84         vldr    COEF7, [PCOEF, #X + (3*JMAX + 1) * Y]
85    .ifc "\tail",""
86         vmul.f  ACCUM4, COEF4, IN1      @ vector operation
87    .endif
88         vldr    COEF0, [PCOEF, #X + (0*JMAX + 2) * Y]
89         vldr    COEF1, [PCOEF, #X + (1*JMAX + 2) * Y]
90    .ifnc "\tail",""
91         vmul.f  ACCUM4, COEF4, IN1      @ vector operation
92    .endif
93         vldr    COEF2, [PCOEF, #X + (2*JMAX + 2) * Y]
94         vldr    COEF3, [PCOEF, #X + (3*JMAX + 2) * Y]
95  .endif
96  .ifnc "\tail",""
97         vstmia  POUT!, {POST0-POST3}
98  .endif
99  .ifnc "\head",""
100         vmla.f  ACCUM0, COEF0, IN2      @ vector = vector * scalar
101         vldr    COEF4, [PCOEF, #X + (0*JMAX + 3) * Y]
102         vldr    COEF5, [PCOEF, #X + (1*JMAX + 3) * Y]
103         vldr    COEF6, [PCOEF, #X + (2*JMAX + 3) * Y]
104         vldr    COEF7, [PCOEF, #X + (3*JMAX + 3) * Y]
105         vmla.f  ACCUM4, COEF4, IN3      @ vector = vector * scalar
106   .if \decifactor == 32
107         vldr    COEF0, [PCOEF, #X + (0*JMAX + 4) * Y]
108         vldr    COEF1, [PCOEF, #X + (1*JMAX + 4) * Y]
109         vldr    COEF2, [PCOEF, #X + (2*JMAX + 4) * Y]
110         vldr    COEF3, [PCOEF, #X + (3*JMAX + 4) * Y]
111         vmla.f  ACCUM0, COEF0, IN4      @ vector = vector * scalar
112         vldr    COEF4, [PCOEF, #X + (0*JMAX + 5) * Y]
113         vldr    COEF5, [PCOEF, #X + (1*JMAX + 5) * Y]
114         vldr    COEF6, [PCOEF, #X + (2*JMAX + 5) * Y]
115         vldr    COEF7, [PCOEF, #X + (3*JMAX + 5) * Y]
116         vmla.f  ACCUM4, COEF4, IN5      @ vector = vector * scalar
117         vldr    COEF0, [PCOEF, #X + (0*JMAX + 6) * Y]
118         vldr    COEF1, [PCOEF, #X + (1*JMAX + 6) * Y]
119         vldr    COEF2, [PCOEF, #X + (2*JMAX + 6) * Y]
120         vldr    COEF3, [PCOEF, #X + (3*JMAX + 6) * Y]
121         vmla.f  ACCUM0, COEF0, IN6      @ vector = vector * scalar
122         vldr    COEF4, [PCOEF, #X + (0*JMAX + 7) * Y]
123         vldr    COEF5, [PCOEF, #X + (1*JMAX + 7) * Y]
124         vldr    COEF6, [PCOEF, #X + (2*JMAX + 7) * Y]
125         vldr    COEF7, [PCOEF, #X + (3*JMAX + 7) * Y]
126         vmla.f  ACCUM4, COEF4, IN7      @ vector = vector * scalar
127   .endif
128  .endif
129 .endm
130
131 .macro dca_lfe_fir  decifactor
132  .if \decifactor == 32
133   .set JMAX, 8
134         vpush   {s16-s31}
135         vmov    SCALE32, s0             @ duplicate scalar across vector
136         vldr    IN4, [PIN, #-4*4]
137         vldr    IN5, [PIN, #-5*4]
138         vldr    IN6, [PIN, #-6*4]
139         vldr    IN7, [PIN, #-7*4]
140  .else
141   .set JMAX, 4
142         vpush   {s16-s27}
143  .endif
144
145         mov     COUNTER, #\decifactor/4 - 1
146         inner_loop  \decifactor, up,, head
147 1:      add     PCOEF, PCOEF, #4*JMAX*4
148         subs    COUNTER, COUNTER, #1
149         inner_loop  \decifactor, up, tail, head
150         bne     1b
151         inner_loop  \decifactor, up, tail
152
153         mov     COUNTER, #\decifactor/4 - 1
154         inner_loop  \decifactor, down,, head
155 1:      sub     PCOEF, PCOEF, #4*JMAX*4
156         subs    COUNTER, COUNTER, #1
157         inner_loop  \decifactor, down, tail, head
158         bne     1b
159         inner_loop  \decifactor, down, tail
160
161  .if \decifactor == 32
162         vpop    {s16-s31}
163  .else
164         vpop    {s16-s27}
165  .endif
166         fmxr    FPSCR, OLDFPSCR
167         bx      lr
168 .endm
169
170
171 /* void ff_dca_lfe_fir_vfp(float *out, const float *in, const float *coefs,
172  *                         int decifactor, float scale)
173  */
174 function ff_dca_lfe_fir_vfp, export=1
175         teq     DECIFACTOR, #32
176         fmrx    OLDFPSCR, FPSCR
177         ldr     ip, =0x03030000         @ RunFast mode, short vectors of length 4, stride 1
178         fmxr    FPSCR, ip
179 NOVFP   vldr    s0, [sp]
180         vldr    IN0, [PIN, #-0*4]
181         vldr    IN1, [PIN, #-1*4]
182         vldr    IN2, [PIN, #-2*4]
183         vldr    IN3, [PIN, #-3*4]
184         beq     32f
185 64:     dca_lfe_fir  64
186  .ltorg
187 32:     dca_lfe_fir  32
188 endfunc
189
190         .unreq  POUT
191         .unreq  PIN
192         .unreq  PCOEF
193         .unreq  DECIFACTOR
194         .unreq  OLDFPSCR
195         .unreq  COUNTER
196
197         .unreq  SCALE32
198         .unreq  SCALE64
199         .unreq  IN0
200         .unreq  IN1
201         .unreq  IN2
202         .unreq  IN3
203         .unreq  IN4
204         .unreq  IN5
205         .unreq  IN6
206         .unreq  IN7
207         .unreq  COEF0
208         .unreq  COEF1
209         .unreq  COEF2
210         .unreq  COEF3
211         .unreq  COEF4
212         .unreq  COEF5
213         .unreq  COEF6
214         .unreq  COEF7
215         .unreq  ACCUM0
216         .unreq  ACCUM4
217         .unreq  POST0
218         .unreq  POST1
219         .unreq  POST2
220         .unreq  POST3