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