Git init
[framework/multimedia/ffmpeg.git] / libavcodec / arm / fmtconvert_neon.S
1 /*
2  * ARM NEON optimised Format Conversion Utils
3  * Copyright (c) 2008 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 "config.h"
23 #include "asm.S"
24
25         preserve8
26         .text
27
28 function ff_float_to_int16_neon, export=1
29         subs            r2,  r2,  #8
30         vld1.64         {d0-d1},  [r1,:128]!
31         vcvt.s32.f32    q8,  q0,  #16
32         vld1.64         {d2-d3},  [r1,:128]!
33         vcvt.s32.f32    q9,  q1,  #16
34         beq             3f
35         bics            ip,  r2,  #15
36         beq             2f
37 1:      subs            ip,  ip,  #16
38         vshrn.s32       d4,  q8,  #16
39         vld1.64         {d0-d1},  [r1,:128]!
40         vcvt.s32.f32    q0,  q0,  #16
41         vshrn.s32       d5,  q9,  #16
42         vld1.64         {d2-d3},  [r1,:128]!
43         vcvt.s32.f32    q1,  q1,  #16
44         vshrn.s32       d6,  q0,  #16
45         vst1.64         {d4-d5},  [r0,:128]!
46         vshrn.s32       d7,  q1,  #16
47         vld1.64         {d16-d17},[r1,:128]!
48         vcvt.s32.f32    q8,  q8,  #16
49         vld1.64         {d18-d19},[r1,:128]!
50         vcvt.s32.f32    q9,  q9,  #16
51         vst1.64         {d6-d7},  [r0,:128]!
52         bne             1b
53         ands            r2,  r2,  #15
54         beq             3f
55 2:      vld1.64         {d0-d1},  [r1,:128]!
56         vshrn.s32       d4,  q8,  #16
57         vcvt.s32.f32    q0,  q0,  #16
58         vld1.64         {d2-d3},  [r1,:128]!
59         vshrn.s32       d5,  q9,  #16
60         vcvt.s32.f32    q1,  q1,  #16
61         vshrn.s32       d6,  q0,  #16
62         vst1.64         {d4-d5},  [r0,:128]!
63         vshrn.s32       d7,  q1,  #16
64         vst1.64         {d6-d7},  [r0,:128]!
65         bx              lr
66 3:      vshrn.s32       d4,  q8,  #16
67         vshrn.s32       d5,  q9,  #16
68         vst1.64         {d4-d5},  [r0,:128]!
69         bx              lr
70 endfunc
71
72 function ff_float_to_int16_interleave_neon, export=1
73         cmp             r3, #2
74         ldrlt           r1, [r1]
75         blt             ff_float_to_int16_neon
76         bne             4f
77
78         ldr             r3, [r1]
79         ldr             r1, [r1, #4]
80
81         subs            r2,  r2,  #8
82         vld1.64         {d0-d1},  [r3,:128]!
83         vcvt.s32.f32    q8,  q0,  #16
84         vld1.64         {d2-d3},  [r3,:128]!
85         vcvt.s32.f32    q9,  q1,  #16
86         vld1.64         {d20-d21},[r1,:128]!
87         vcvt.s32.f32    q10, q10, #16
88         vld1.64         {d22-d23},[r1,:128]!
89         vcvt.s32.f32    q11, q11, #16
90         beq             3f
91         bics            ip,  r2,  #15
92         beq             2f
93 1:      subs            ip,  ip,  #16
94         vld1.64         {d0-d1},  [r3,:128]!
95         vcvt.s32.f32    q0,  q0,  #16
96         vsri.32         q10, q8,  #16
97         vld1.64         {d2-d3},  [r3,:128]!
98         vcvt.s32.f32    q1,  q1,  #16
99         vld1.64         {d24-d25},[r1,:128]!
100         vcvt.s32.f32    q12, q12, #16
101         vld1.64         {d26-d27},[r1,:128]!
102         vsri.32         q11, q9,  #16
103         vst1.64         {d20-d21},[r0,:128]!
104         vcvt.s32.f32    q13, q13, #16
105         vst1.64         {d22-d23},[r0,:128]!
106         vsri.32         q12, q0,  #16
107         vld1.64         {d16-d17},[r3,:128]!
108         vsri.32         q13, q1,  #16
109         vst1.64         {d24-d25},[r0,:128]!
110         vcvt.s32.f32    q8,  q8,  #16
111         vld1.64         {d18-d19},[r3,:128]!
112         vcvt.s32.f32    q9,  q9,  #16
113         vld1.64         {d20-d21},[r1,:128]!
114         vcvt.s32.f32    q10, q10, #16
115         vld1.64         {d22-d23},[r1,:128]!
116         vcvt.s32.f32    q11, q11, #16
117         vst1.64         {d26-d27},[r0,:128]!
118         bne             1b
119         ands            r2,  r2,  #15
120         beq             3f
121 2:      vsri.32         q10, q8,  #16
122         vld1.64         {d0-d1},  [r3,:128]!
123         vcvt.s32.f32    q0,  q0,  #16
124         vld1.64         {d2-d3},  [r3,:128]!
125         vcvt.s32.f32    q1,  q1,  #16
126         vld1.64         {d24-d25},[r1,:128]!
127         vcvt.s32.f32    q12, q12, #16
128         vsri.32         q11, q9,  #16
129         vld1.64         {d26-d27},[r1,:128]!
130         vcvt.s32.f32    q13, q13, #16
131         vst1.64         {d20-d21},[r0,:128]!
132         vsri.32         q12, q0,  #16
133         vst1.64         {d22-d23},[r0,:128]!
134         vsri.32         q13, q1,  #16
135         vst1.64         {d24-d27},[r0,:128]!
136         bx              lr
137 3:      vsri.32         q10, q8,  #16
138         vsri.32         q11, q9,  #16
139         vst1.64         {d20-d23},[r0,:128]!
140         bx              lr
141
142 4:      push            {r4-r8,lr}
143         cmp             r3,  #4
144         lsl             ip,  r3,  #1
145         blt             4f
146
147         @ 4 channels
148 5:      ldmia           r1!, {r4-r7}
149         mov             lr,  r2
150         mov             r8,  r0
151         vld1.64         {d16-d17},[r4,:128]!
152         vcvt.s32.f32    q8,  q8,  #16
153         vld1.64         {d18-d19},[r5,:128]!
154         vcvt.s32.f32    q9,  q9,  #16
155         vld1.64         {d20-d21},[r6,:128]!
156         vcvt.s32.f32    q10, q10, #16
157         vld1.64         {d22-d23},[r7,:128]!
158         vcvt.s32.f32    q11, q11, #16
159 6:      subs            lr,  lr,  #8
160         vld1.64         {d0-d1},  [r4,:128]!
161         vcvt.s32.f32    q0,  q0,  #16
162         vsri.32         q9,  q8,  #16
163         vld1.64         {d2-d3},  [r5,:128]!
164         vcvt.s32.f32    q1,  q1,  #16
165         vsri.32         q11, q10, #16
166         vld1.64         {d4-d5},  [r6,:128]!
167         vcvt.s32.f32    q2,  q2,  #16
168         vzip.32         d18, d22
169         vld1.64         {d6-d7},  [r7,:128]!
170         vcvt.s32.f32    q3,  q3,  #16
171         vzip.32         d19, d23
172         vst1.64         {d18},    [r8], ip
173         vsri.32         q1,  q0,  #16
174         vst1.64         {d22},    [r8], ip
175         vsri.32         q3,  q2,  #16
176         vst1.64         {d19},    [r8], ip
177         vzip.32         d2,  d6
178         vst1.64         {d23},    [r8], ip
179         vzip.32         d3,  d7
180         beq             7f
181         vld1.64         {d16-d17},[r4,:128]!
182         vcvt.s32.f32    q8,  q8,  #16
183         vst1.64         {d2},     [r8], ip
184         vld1.64         {d18-d19},[r5,:128]!
185         vcvt.s32.f32    q9,  q9,  #16
186         vst1.64         {d6},     [r8], ip
187         vld1.64         {d20-d21},[r6,:128]!
188         vcvt.s32.f32    q10, q10, #16
189         vst1.64         {d3},     [r8], ip
190         vld1.64         {d22-d23},[r7,:128]!
191         vcvt.s32.f32    q11, q11, #16
192         vst1.64         {d7},     [r8], ip
193         b               6b
194 7:      vst1.64         {d2},     [r8], ip
195         vst1.64         {d6},     [r8], ip
196         vst1.64         {d3},     [r8], ip
197         vst1.64         {d7},     [r8], ip
198         subs            r3,  r3,  #4
199         popeq           {r4-r8,pc}
200         cmp             r3,  #4
201         add             r0,  r0,  #8
202         bge             5b
203
204         @ 2 channels
205 4:      cmp             r3,  #2
206         blt             4f
207         ldmia           r1!, {r4-r5}
208         mov             lr,  r2
209         mov             r8,  r0
210         tst             lr,  #8
211         vld1.64         {d16-d17},[r4,:128]!
212         vcvt.s32.f32    q8,  q8,  #16
213         vld1.64         {d18-d19},[r5,:128]!
214         vcvt.s32.f32    q9,  q9,  #16
215         vld1.64         {d20-d21},[r4,:128]!
216         vcvt.s32.f32    q10, q10, #16
217         vld1.64         {d22-d23},[r5,:128]!
218         vcvt.s32.f32    q11, q11, #16
219         beq             6f
220         subs            lr,  lr,  #8
221         beq             7f
222         vsri.32         d18, d16, #16
223         vsri.32         d19, d17, #16
224         vld1.64         {d16-d17},[r4,:128]!
225         vcvt.s32.f32    q8,  q8,  #16
226         vst1.32         {d18[0]}, [r8], ip
227         vsri.32         d22, d20, #16
228         vst1.32         {d18[1]}, [r8], ip
229         vsri.32         d23, d21, #16
230         vst1.32         {d19[0]}, [r8], ip
231         vst1.32         {d19[1]}, [r8], ip
232         vld1.64         {d18-d19},[r5,:128]!
233         vcvt.s32.f32    q9,  q9,  #16
234         vst1.32         {d22[0]}, [r8], ip
235         vst1.32         {d22[1]}, [r8], ip
236         vld1.64         {d20-d21},[r4,:128]!
237         vcvt.s32.f32    q10, q10, #16
238         vst1.32         {d23[0]}, [r8], ip
239         vst1.32         {d23[1]}, [r8], ip
240         vld1.64         {d22-d23},[r5,:128]!
241         vcvt.s32.f32    q11, q11, #16
242 6:      subs            lr,  lr,  #16
243         vld1.64         {d0-d1},  [r4,:128]!
244         vcvt.s32.f32    q0,  q0,  #16
245         vsri.32         d18, d16, #16
246         vld1.64         {d2-d3},  [r5,:128]!
247         vcvt.s32.f32    q1,  q1,  #16
248         vsri.32         d19, d17, #16
249         vld1.64         {d4-d5},  [r4,:128]!
250         vcvt.s32.f32    q2,  q2,  #16
251         vld1.64         {d6-d7},  [r5,:128]!
252         vcvt.s32.f32    q3,  q3,  #16
253         vst1.32         {d18[0]}, [r8], ip
254         vsri.32         d22, d20, #16
255         vst1.32         {d18[1]}, [r8], ip
256         vsri.32         d23, d21, #16
257         vst1.32         {d19[0]}, [r8], ip
258         vsri.32         d2,  d0,  #16
259         vst1.32         {d19[1]}, [r8], ip
260         vsri.32         d3,  d1,  #16
261         vst1.32         {d22[0]}, [r8], ip
262         vsri.32         d6,  d4,  #16
263         vst1.32         {d22[1]}, [r8], ip
264         vsri.32         d7,  d5,  #16
265         vst1.32         {d23[0]}, [r8], ip
266         vst1.32         {d23[1]}, [r8], ip
267         beq             6f
268         vld1.64         {d16-d17},[r4,:128]!
269         vcvt.s32.f32    q8,  q8,  #16
270         vst1.32         {d2[0]},  [r8], ip
271         vst1.32         {d2[1]},  [r8], ip
272         vld1.64         {d18-d19},[r5,:128]!
273         vcvt.s32.f32    q9,  q9,  #16
274         vst1.32         {d3[0]},  [r8], ip
275         vst1.32         {d3[1]},  [r8], ip
276         vld1.64         {d20-d21},[r4,:128]!
277         vcvt.s32.f32    q10, q10, #16
278         vst1.32         {d6[0]},  [r8], ip
279         vst1.32         {d6[1]},  [r8], ip
280         vld1.64         {d22-d23},[r5,:128]!
281         vcvt.s32.f32    q11, q11, #16
282         vst1.32         {d7[0]},  [r8], ip
283         vst1.32         {d7[1]},  [r8], ip
284         bgt             6b
285 6:      vst1.32         {d2[0]},  [r8], ip
286         vst1.32         {d2[1]},  [r8], ip
287         vst1.32         {d3[0]},  [r8], ip
288         vst1.32         {d3[1]},  [r8], ip
289         vst1.32         {d6[0]},  [r8], ip
290         vst1.32         {d6[1]},  [r8], ip
291         vst1.32         {d7[0]},  [r8], ip
292         vst1.32         {d7[1]},  [r8], ip
293         b               8f
294 7:      vsri.32         d18, d16, #16
295         vsri.32         d19, d17, #16
296         vst1.32         {d18[0]}, [r8], ip
297         vsri.32         d22, d20, #16
298         vst1.32         {d18[1]}, [r8], ip
299         vsri.32         d23, d21, #16
300         vst1.32         {d19[0]}, [r8], ip
301         vst1.32         {d19[1]}, [r8], ip
302         vst1.32         {d22[0]}, [r8], ip
303         vst1.32         {d22[1]}, [r8], ip
304         vst1.32         {d23[0]}, [r8], ip
305         vst1.32         {d23[1]}, [r8], ip
306 8:      subs            r3,  r3,  #2
307         add             r0,  r0,  #4
308         popeq           {r4-r8,pc}
309
310         @ 1 channel
311 4:      ldr             r4,  [r1],#4
312         tst             r2,  #8
313         mov             lr,  r2
314         mov             r5,  r0
315         vld1.64         {d0-d1},  [r4,:128]!
316         vcvt.s32.f32    q0,  q0,  #16
317         vld1.64         {d2-d3},  [r4,:128]!
318         vcvt.s32.f32    q1,  q1,  #16
319         bne             8f
320 6:      subs            lr,  lr,  #16
321         vld1.64         {d4-d5},  [r4,:128]!
322         vcvt.s32.f32    q2,  q2,  #16
323         vld1.64         {d6-d7},  [r4,:128]!
324         vcvt.s32.f32    q3,  q3,  #16
325         vst1.16         {d0[1]},  [r5,:16], ip
326         vst1.16         {d0[3]},  [r5,:16], ip
327         vst1.16         {d1[1]},  [r5,:16], ip
328         vst1.16         {d1[3]},  [r5,:16], ip
329         vst1.16         {d2[1]},  [r5,:16], ip
330         vst1.16         {d2[3]},  [r5,:16], ip
331         vst1.16         {d3[1]},  [r5,:16], ip
332         vst1.16         {d3[3]},  [r5,:16], ip
333         beq             7f
334         vld1.64         {d0-d1},  [r4,:128]!
335         vcvt.s32.f32    q0,  q0,  #16
336         vld1.64         {d2-d3},  [r4,:128]!
337         vcvt.s32.f32    q1,  q1,  #16
338 7:      vst1.16         {d4[1]},  [r5,:16], ip
339         vst1.16         {d4[3]},  [r5,:16], ip
340         vst1.16         {d5[1]},  [r5,:16], ip
341         vst1.16         {d5[3]},  [r5,:16], ip
342         vst1.16         {d6[1]},  [r5,:16], ip
343         vst1.16         {d6[3]},  [r5,:16], ip
344         vst1.16         {d7[1]},  [r5,:16], ip
345         vst1.16         {d7[3]},  [r5,:16], ip
346         bgt             6b
347         pop             {r4-r8,pc}
348 8:      subs            lr,  lr,  #8
349         vst1.16         {d0[1]},  [r5,:16], ip
350         vst1.16         {d0[3]},  [r5,:16], ip
351         vst1.16         {d1[1]},  [r5,:16], ip
352         vst1.16         {d1[3]},  [r5,:16], ip
353         vst1.16         {d2[1]},  [r5,:16], ip
354         vst1.16         {d2[3]},  [r5,:16], ip
355         vst1.16         {d3[1]},  [r5,:16], ip
356         vst1.16         {d3[3]},  [r5,:16], ip
357         popeq           {r4-r8,pc}
358         vld1.64         {d0-d1},  [r4,:128]!
359         vcvt.s32.f32    q0,  q0,  #16
360         vld1.64         {d2-d3},  [r4,:128]!
361         vcvt.s32.f32    q1,  q1,  #16
362         b               6b
363 endfunc
364
365 function ff_int32_to_float_fmul_scalar_neon, export=1
366 VFP     vdup.32         q0,  d0[0]
367 VFP     len     .req    r2
368 NOVFP   vdup.32         q0,  r2
369 NOVFP   len     .req    r3
370
371         vld1.32         {q1},[r1,:128]!
372         vcvt.f32.s32    q3,  q1
373         vld1.32         {q2},[r1,:128]!
374         vcvt.f32.s32    q8,  q2
375 1:      subs            len, len, #8
376         pld             [r1, #16]
377         vmul.f32        q9,  q3,  q0
378         vmul.f32        q10, q8,  q0
379         beq             2f
380         vld1.32         {q1},[r1,:128]!
381         vcvt.f32.s32    q3,  q1
382         vld1.32         {q2},[r1,:128]!
383         vcvt.f32.s32    q8,  q2
384         vst1.32         {q9}, [r0,:128]!
385         vst1.32         {q10},[r0,:128]!
386         b               1b
387 2:      vst1.32         {q9}, [r0,:128]!
388         vst1.32         {q10},[r0,:128]!
389         bx              lr
390         .unreq  len
391 endfunc