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
25function 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
341:      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
522:      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
633:      vshrn.s32       d4,  q8,  #16
64        vshrn.s32       d5,  q9,  #16
65        vst1.64         {d4-d5},  [r0,:128]!
66        bx              lr
67endfunc
68
69function ff_float_to_int16_interleave_neon, export=1
70        cmp             r3, #2
71        itt             lt
72        ldrlt           r1, [r1]
73        blt             X(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
911:      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
1192:      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
1353:      vsri.32         q10, q8,  #16
136        vsri.32         q11, q9,  #16
137        vst1.64         {d20-d23},[r0,:128]!
138        bx              lr
139
1404:      push            {r4-r8,lr}
141        cmp             r3,  #4
142        lsl             ip,  r3,  #1
143        blt             4f
144
145        @ 4 channels
1465:      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
1576:      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
1927:      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
2044:      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
2416:      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
2846:      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
2937:      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
3058:      subs            r3,  r3,  #2
306        add             r0,  r0,  #4
307        it              eq
308        popeq           {r4-r8,pc}
309
310        @ 1 channel
3114:      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
3206:      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
3387:      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}
3488:      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
364endfunc
365
366function ff_int32_to_float_fmul_scalar_neon, export=1
367VFP     vdup.32         q0,  d0[0]
368VFP     len     .req    r2
369NOVFP   vdup.32         q0,  r2
370NOVFP   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
3761:      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
3882:      vst1.32         {q9}, [r0,:128]!
389        vst1.32         {q10},[r0,:128]!
390        bx              lr
391        .unreq  len
392endfunc
393