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