arm: Add VFP-accelerated version of int32_to_float_fmul_scalar
[ffmpeg.git] / libavcodec / arm / fmtconvert_vfp.S
1 /*
2  * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
3  * Copyright (c) 2013 RISC OS Open Ltd <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 "config.h"
23 #include "libavutil/arm/asm.S"
24
25 /**
26  * ARM VFP optimized float to int16 conversion.
27  * Assume that len is a positive number and is multiple of 8, destination
28  * buffer is at least 4 bytes aligned (8 bytes alignment is better for
29  * performance), little-endian byte sex.
30  */
31 @ void ff_float_to_int16_vfp(int16_t *dst, const float *src, int len)
32 function ff_float_to_int16_vfp, export=1
33         push            {r4-r8,lr}
34         vpush           {d8-d11}
35         vldmia          r1!, {s16-s23}
36         vcvt.s32.f32    s0,  s16
37         vcvt.s32.f32    s1,  s17
38         vcvt.s32.f32    s2,  s18
39         vcvt.s32.f32    s3,  s19
40         vcvt.s32.f32    s4,  s20
41         vcvt.s32.f32    s5,  s21
42         vcvt.s32.f32    s6,  s22
43         vcvt.s32.f32    s7,  s23
44 1:
45         subs            r2,  r2,  #8
46         vmov            r3,  r4,  s0, s1
47         vmov            r5,  r6,  s2, s3
48         vmov            r7,  r8,  s4, s5
49         vmov            ip,  lr,  s6, s7
50         it              gt
51         vldmiagt        r1!, {s16-s23}
52         ssat            r4,  #16, r4
53         ssat            r3,  #16, r3
54         ssat            r6,  #16, r6
55         ssat            r5,  #16, r5
56         pkhbt           r3,  r3,  r4, lsl #16
57         pkhbt           r4,  r5,  r6, lsl #16
58         itttt           gt
59         vcvtgt.s32.f32  s0,  s16
60         vcvtgt.s32.f32  s1,  s17
61         vcvtgt.s32.f32  s2,  s18
62         vcvtgt.s32.f32  s3,  s19
63         itttt           gt
64         vcvtgt.s32.f32  s4,  s20
65         vcvtgt.s32.f32  s5,  s21
66         vcvtgt.s32.f32  s6,  s22
67         vcvtgt.s32.f32  s7,  s23
68         ssat            r8,  #16, r8
69         ssat            r7,  #16, r7
70         ssat            lr,  #16, lr
71         ssat            ip,  #16, ip
72         pkhbt           r5,  r7,  r8, lsl #16
73         pkhbt           r6,  ip,  lr, lsl #16
74         stmia           r0!, {r3-r6}
75         bgt             1b
76
77         vpop            {d8-d11}
78         pop             {r4-r8,pc}
79 endfunc
80
81 /**
82  * ARM VFP optimised int32 to float conversion.
83  * Assume len is a multiple of 8, destination buffer is at least 4 bytes aligned
84  * (16 bytes alignment is best for BCM2835), little-endian.
85  */
86 @ void ff_int32_to_float_fmul_scalar_vfp(float *dst, const int32_t *src, float mul, int len)
87 function ff_int32_to_float_fmul_scalar_vfp, export=1
88 VFP     tmp     .req    a4
89 VFP     len     .req    a3
90 NOVFP   tmp     .req    a3
91 NOVFP   len     .req    a4
92 NOVFP   vmov    s0, a3
93         ldr     tmp, =0x03070000           @ RunFast mode, short vectors of length 8, stride 1
94         fmrx    ip, FPSCR
95         fmxr    FPSCR, tmp
96 1:
97         vldmia          a2!, {s8-s15}
98         vcvt.f32.s32    s8, s8
99         vcvt.f32.s32    s9, s9
100         vcvt.f32.s32    s10, s10
101         vcvt.f32.s32    s11, s11
102         vcvt.f32.s32    s12, s12
103         vcvt.f32.s32    s13, s13
104         vcvt.f32.s32    s14, s14
105         vcvt.f32.s32    s15, s15
106         vmul.f32        s8, s8, s0
107         subs            len, len, #8
108         vstmia          a1!, {s8-s11}
109         vstmia          a1!, {s12-s15}
110         bne             1b
111
112         fmxr    FPSCR, ip
113         bx      lr
114 endfunc
115         .unreq  tmp
116         .unreq  len