diff libavcodec/arm/dsputil_vfp.S @ 2:897f711a7157

rearrange to work with autoconf
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Tue, 25 Sep 2012 15:55:33 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libavcodec/arm/dsputil_vfp.S	Tue Sep 25 15:55:33 2012 +0200
     1.3 @@ -0,0 +1,189 @@
     1.4 +/*
     1.5 + * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
     1.6 + *
     1.7 + * This file is part of FFmpeg.
     1.8 + *
     1.9 + * FFmpeg is free software; you can redistribute it and/or
    1.10 + * modify it under the terms of the GNU Lesser General Public
    1.11 + * License as published by the Free Software Foundation; either
    1.12 + * version 2.1 of the License, or (at your option) any later version.
    1.13 + *
    1.14 + * FFmpeg is distributed in the hope that it will be useful,
    1.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.17 + * Lesser General Public License for more details.
    1.18 + *
    1.19 + * You should have received a copy of the GNU Lesser General Public
    1.20 + * License along with FFmpeg; if not, write to the Free Software
    1.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
    1.22 + */
    1.23 +
    1.24 +#include "config.h"
    1.25 +#include "asm.S"
    1.26 +
    1.27 +        .syntax unified
    1.28 +/*
    1.29 + * VFP is a floating point coprocessor used in some ARM cores. VFP11 has 1 cycle
    1.30 + * throughput for almost all the instructions (except for double precision
    1.31 + * arithmetics), but rather high latency. Latency is 4 cycles for loads and 8 cycles
    1.32 + * for arithmetic operations. Scheduling code to avoid pipeline stalls is very
    1.33 + * important for performance. One more interesting feature is that VFP has
    1.34 + * independent load/store and arithmetics pipelines, so it is possible to make
    1.35 + * them work simultaneously and get more than 1 operation per cycle. Load/store
    1.36 + * pipeline can process 2 single precision floating point values per cycle and
    1.37 + * supports bulk loads and stores for large sets of registers. Arithmetic operations
    1.38 + * can be done on vectors, which allows to keep the arithmetics pipeline busy,
    1.39 + * while the processor may issue and execute other instructions. Detailed
    1.40 + * optimization manuals can be found at http://www.arm.com
    1.41 + */
    1.42 +
    1.43 +/**
    1.44 + * ARM VFP optimized implementation of 'vector_fmul_c' function.
    1.45 + * Assume that len is a positive number and is multiple of 8
    1.46 + */
    1.47 +@ void ff_vector_fmul_vfp(float *dst, const float *src, int len)
    1.48 +function ff_vector_fmul_vfp, export=1
    1.49 +        vpush           {d8-d15}
    1.50 +        mov             r3,  r0
    1.51 +        fmrx            r12, fpscr
    1.52 +        orr             r12, r12, #(3 << 16) /* set vector size to 4 */
    1.53 +        fmxr            fpscr, r12
    1.54 +
    1.55 +        vldmia          r3!, {s0-s3}
    1.56 +        vldmia          r1!, {s8-s11}
    1.57 +        vldmia          r3!, {s4-s7}
    1.58 +        vldmia          r1!, {s12-s15}
    1.59 +        vmul.f32        s8,  s0,  s8
    1.60 +1:
    1.61 +        subs            r2,  r2,  #16
    1.62 +        vmul.f32        s12, s4,  s12
    1.63 +        vldmiage        r3!, {s16-s19}
    1.64 +        vldmiage        r1!, {s24-s27}
    1.65 +        vldmiage        r3!, {s20-s23}
    1.66 +        vldmiage        r1!, {s28-s31}
    1.67 +        vmulge.f32      s24, s16, s24
    1.68 +        vstmia          r0!, {s8-s11}
    1.69 +        vstmia          r0!, {s12-s15}
    1.70 +        vmulge.f32      s28, s20, s28
    1.71 +        vldmiagt        r3!, {s0-s3}
    1.72 +        vldmiagt        r1!, {s8-s11}
    1.73 +        vldmiagt        r3!, {s4-s7}
    1.74 +        vldmiagt        r1!, {s12-s15}
    1.75 +        vmulge.f32      s8,  s0,  s8
    1.76 +        vstmiage        r0!, {s24-s27}
    1.77 +        vstmiage        r0!, {s28-s31}
    1.78 +        bgt             1b
    1.79 +
    1.80 +        bic             r12, r12, #(7 << 16) /* set vector size back to 1 */
    1.81 +        fmxr            fpscr, r12
    1.82 +        vpop            {d8-d15}
    1.83 +        bx              lr
    1.84 +endfunc
    1.85 +
    1.86 +/**
    1.87 + * ARM VFP optimized implementation of 'vector_fmul_reverse_c' function.
    1.88 + * Assume that len is a positive number and is multiple of 8
    1.89 + */
    1.90 +@ void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
    1.91 +@                                 const float *src1, int len)
    1.92 +function ff_vector_fmul_reverse_vfp, export=1
    1.93 +        vpush           {d8-d15}
    1.94 +        add             r2,  r2,  r3, lsl #2
    1.95 +        vldmdb          r2!, {s0-s3}
    1.96 +        vldmia          r1!, {s8-s11}
    1.97 +        vldmdb          r2!, {s4-s7}
    1.98 +        vldmia          r1!, {s12-s15}
    1.99 +        vmul.f32        s8,  s3,  s8
   1.100 +        vmul.f32        s9,  s2,  s9
   1.101 +        vmul.f32        s10, s1,  s10
   1.102 +        vmul.f32        s11, s0,  s11
   1.103 +1:
   1.104 +        subs            r3,  r3,  #16
   1.105 +        vldmdbge        r2!, {s16-s19}
   1.106 +        vmul.f32        s12, s7,  s12
   1.107 +        vldmiage        r1!, {s24-s27}
   1.108 +        vmul.f32        s13, s6,  s13
   1.109 +        vldmdbge        r2!, {s20-s23}
   1.110 +        vmul.f32        s14, s5,  s14
   1.111 +        vldmiage        r1!, {s28-s31}
   1.112 +        vmul.f32        s15, s4,  s15
   1.113 +        vmulge.f32      s24, s19, s24
   1.114 +        vldmdbgt        r2!, {s0-s3}
   1.115 +        vmulge.f32      s25, s18, s25
   1.116 +        vstmia          r0!, {s8-s13}
   1.117 +        vmulge.f32      s26, s17, s26
   1.118 +        vldmiagt        r1!, {s8-s11}
   1.119 +        vmulge.f32      s27, s16, s27
   1.120 +        vmulge.f32      s28, s23, s28
   1.121 +        vldmdbgt        r2!, {s4-s7}
   1.122 +        vmulge.f32      s29, s22, s29
   1.123 +        vstmia          r0!, {s14-s15}
   1.124 +        vmulge.f32      s30, s21, s30
   1.125 +        vmulge.f32      s31, s20, s31
   1.126 +        vmulge.f32      s8,  s3,  s8
   1.127 +        vldmiagt        r1!, {s12-s15}
   1.128 +        vmulge.f32      s9,  s2,  s9
   1.129 +        vmulge.f32      s10, s1,  s10
   1.130 +        vstmiage        r0!, {s24-s27}
   1.131 +        vmulge.f32      s11, s0,  s11
   1.132 +        vstmiage        r0!, {s28-s31}
   1.133 +        bgt             1b
   1.134 +
   1.135 +        vpop            {d8-d15}
   1.136 +        bx              lr
   1.137 +endfunc
   1.138 +
   1.139 +#if HAVE_ARMV6
   1.140 +/**
   1.141 + * ARM VFP optimized float to int16 conversion.
   1.142 + * Assume that len is a positive number and is multiple of 8, destination
   1.143 + * buffer is at least 4 bytes aligned (8 bytes alignment is better for
   1.144 + * performance), little endian byte sex
   1.145 + */
   1.146 +@ void ff_float_to_int16_vfp(int16_t *dst, const float *src, int len)
   1.147 +function ff_float_to_int16_vfp, export=1
   1.148 +        push            {r4-r8,lr}
   1.149 +        vpush           {d8-d11}
   1.150 +        vldmia          r1!, {s16-s23}
   1.151 +        vcvt.s32.f32    s0,  s16
   1.152 +        vcvt.s32.f32    s1,  s17
   1.153 +        vcvt.s32.f32    s2,  s18
   1.154 +        vcvt.s32.f32    s3,  s19
   1.155 +        vcvt.s32.f32    s4,  s20
   1.156 +        vcvt.s32.f32    s5,  s21
   1.157 +        vcvt.s32.f32    s6,  s22
   1.158 +        vcvt.s32.f32    s7,  s23
   1.159 +1:
   1.160 +        subs            r2,  r2,  #8
   1.161 +        vmov            r3,  r4,  s0, s1
   1.162 +        vmov            r5,  r6,  s2, s3
   1.163 +        vmov            r7,  r8,  s4, s5
   1.164 +        vmov            ip,  lr,  s6, s7
   1.165 +        vldmiagt        r1!, {s16-s23}
   1.166 +        ssat            r4,  #16, r4
   1.167 +        ssat            r3,  #16, r3
   1.168 +        ssat            r6,  #16, r6
   1.169 +        ssat            r5,  #16, r5
   1.170 +        pkhbt           r3,  r3,  r4, lsl #16
   1.171 +        pkhbt           r4,  r5,  r6, lsl #16
   1.172 +        vcvtgt.s32.f32  s0,  s16
   1.173 +        vcvtgt.s32.f32  s1,  s17
   1.174 +        vcvtgt.s32.f32  s2,  s18
   1.175 +        vcvtgt.s32.f32  s3,  s19
   1.176 +        vcvtgt.s32.f32  s4,  s20
   1.177 +        vcvtgt.s32.f32  s5,  s21
   1.178 +        vcvtgt.s32.f32  s6,  s22
   1.179 +        vcvtgt.s32.f32  s7,  s23
   1.180 +        ssat            r8,  #16, r8
   1.181 +        ssat            r7,  #16, r7
   1.182 +        ssat            lr,  #16, lr
   1.183 +        ssat            ip,  #16, ip
   1.184 +        pkhbt           r5,  r7,  r8, lsl #16
   1.185 +        pkhbt           r6,  ip,  lr, lsl #16
   1.186 +        stmia           r0!, {r3-r6}
   1.187 +        bgt             1b
   1.188 +
   1.189 +        vpop            {d8-d11}
   1.190 +        pop             {r4-r8,pc}
   1.191 +endfunc
   1.192 +#endif