annotate libavcodec/arm/dsputil_vfp.S @ 6:55fb61482128

VSs working
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Wed, 06 Mar 2013 14:35:39 +0100
parents
children
rev   line source
nengel@2 1 /*
nengel@2 2 * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
nengel@2 3 *
nengel@2 4 * This file is part of FFmpeg.
nengel@2 5 *
nengel@2 6 * FFmpeg is free software; you can redistribute it and/or
nengel@2 7 * modify it under the terms of the GNU Lesser General Public
nengel@2 8 * License as published by the Free Software Foundation; either
nengel@2 9 * version 2.1 of the License, or (at your option) any later version.
nengel@2 10 *
nengel@2 11 * FFmpeg is distributed in the hope that it will be useful,
nengel@2 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nengel@2 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
nengel@2 14 * Lesser General Public License for more details.
nengel@2 15 *
nengel@2 16 * You should have received a copy of the GNU Lesser General Public
nengel@2 17 * License along with FFmpeg; if not, write to the Free Software
nengel@2 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
nengel@2 19 */
nengel@2 20
nengel@2 21 #include "config.h"
nengel@2 22 #include "asm.S"
nengel@2 23
nengel@2 24 .syntax unified
nengel@2 25 /*
nengel@2 26 * VFP is a floating point coprocessor used in some ARM cores. VFP11 has 1 cycle
nengel@2 27 * throughput for almost all the instructions (except for double precision
nengel@2 28 * arithmetics), but rather high latency. Latency is 4 cycles for loads and 8 cycles
nengel@2 29 * for arithmetic operations. Scheduling code to avoid pipeline stalls is very
nengel@2 30 * important for performance. One more interesting feature is that VFP has
nengel@2 31 * independent load/store and arithmetics pipelines, so it is possible to make
nengel@2 32 * them work simultaneously and get more than 1 operation per cycle. Load/store
nengel@2 33 * pipeline can process 2 single precision floating point values per cycle and
nengel@2 34 * supports bulk loads and stores for large sets of registers. Arithmetic operations
nengel@2 35 * can be done on vectors, which allows to keep the arithmetics pipeline busy,
nengel@2 36 * while the processor may issue and execute other instructions. Detailed
nengel@2 37 * optimization manuals can be found at http://www.arm.com
nengel@2 38 */
nengel@2 39
nengel@2 40 /**
nengel@2 41 * ARM VFP optimized implementation of 'vector_fmul_c' function.
nengel@2 42 * Assume that len is a positive number and is multiple of 8
nengel@2 43 */
nengel@2 44 @ void ff_vector_fmul_vfp(float *dst, const float *src, int len)
nengel@2 45 function ff_vector_fmul_vfp, export=1
nengel@2 46 vpush {d8-d15}
nengel@2 47 mov r3, r0
nengel@2 48 fmrx r12, fpscr
nengel@2 49 orr r12, r12, #(3 << 16) /* set vector size to 4 */
nengel@2 50 fmxr fpscr, r12
nengel@2 51
nengel@2 52 vldmia r3!, {s0-s3}
nengel@2 53 vldmia r1!, {s8-s11}
nengel@2 54 vldmia r3!, {s4-s7}
nengel@2 55 vldmia r1!, {s12-s15}
nengel@2 56 vmul.f32 s8, s0, s8
nengel@2 57 1:
nengel@2 58 subs r2, r2, #16
nengel@2 59 vmul.f32 s12, s4, s12
nengel@2 60 vldmiage r3!, {s16-s19}
nengel@2 61 vldmiage r1!, {s24-s27}
nengel@2 62 vldmiage r3!, {s20-s23}
nengel@2 63 vldmiage r1!, {s28-s31}
nengel@2 64 vmulge.f32 s24, s16, s24
nengel@2 65 vstmia r0!, {s8-s11}
nengel@2 66 vstmia r0!, {s12-s15}
nengel@2 67 vmulge.f32 s28, s20, s28
nengel@2 68 vldmiagt r3!, {s0-s3}
nengel@2 69 vldmiagt r1!, {s8-s11}
nengel@2 70 vldmiagt r3!, {s4-s7}
nengel@2 71 vldmiagt r1!, {s12-s15}
nengel@2 72 vmulge.f32 s8, s0, s8
nengel@2 73 vstmiage r0!, {s24-s27}
nengel@2 74 vstmiage r0!, {s28-s31}
nengel@2 75 bgt 1b
nengel@2 76
nengel@2 77 bic r12, r12, #(7 << 16) /* set vector size back to 1 */
nengel@2 78 fmxr fpscr, r12
nengel@2 79 vpop {d8-d15}
nengel@2 80 bx lr
nengel@2 81 endfunc
nengel@2 82
nengel@2 83 /**
nengel@2 84 * ARM VFP optimized implementation of 'vector_fmul_reverse_c' function.
nengel@2 85 * Assume that len is a positive number and is multiple of 8
nengel@2 86 */
nengel@2 87 @ void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
nengel@2 88 @ const float *src1, int len)
nengel@2 89 function ff_vector_fmul_reverse_vfp, export=1
nengel@2 90 vpush {d8-d15}
nengel@2 91 add r2, r2, r3, lsl #2
nengel@2 92 vldmdb r2!, {s0-s3}
nengel@2 93 vldmia r1!, {s8-s11}
nengel@2 94 vldmdb r2!, {s4-s7}
nengel@2 95 vldmia r1!, {s12-s15}
nengel@2 96 vmul.f32 s8, s3, s8
nengel@2 97 vmul.f32 s9, s2, s9
nengel@2 98 vmul.f32 s10, s1, s10
nengel@2 99 vmul.f32 s11, s0, s11
nengel@2 100 1:
nengel@2 101 subs r3, r3, #16
nengel@2 102 vldmdbge r2!, {s16-s19}
nengel@2 103 vmul.f32 s12, s7, s12
nengel@2 104 vldmiage r1!, {s24-s27}
nengel@2 105 vmul.f32 s13, s6, s13
nengel@2 106 vldmdbge r2!, {s20-s23}
nengel@2 107 vmul.f32 s14, s5, s14
nengel@2 108 vldmiage r1!, {s28-s31}
nengel@2 109 vmul.f32 s15, s4, s15
nengel@2 110 vmulge.f32 s24, s19, s24
nengel@2 111 vldmdbgt r2!, {s0-s3}
nengel@2 112 vmulge.f32 s25, s18, s25
nengel@2 113 vstmia r0!, {s8-s13}
nengel@2 114 vmulge.f32 s26, s17, s26
nengel@2 115 vldmiagt r1!, {s8-s11}
nengel@2 116 vmulge.f32 s27, s16, s27
nengel@2 117 vmulge.f32 s28, s23, s28
nengel@2 118 vldmdbgt r2!, {s4-s7}
nengel@2 119 vmulge.f32 s29, s22, s29
nengel@2 120 vstmia r0!, {s14-s15}
nengel@2 121 vmulge.f32 s30, s21, s30
nengel@2 122 vmulge.f32 s31, s20, s31
nengel@2 123 vmulge.f32 s8, s3, s8
nengel@2 124 vldmiagt r1!, {s12-s15}
nengel@2 125 vmulge.f32 s9, s2, s9
nengel@2 126 vmulge.f32 s10, s1, s10
nengel@2 127 vstmiage r0!, {s24-s27}
nengel@2 128 vmulge.f32 s11, s0, s11
nengel@2 129 vstmiage r0!, {s28-s31}
nengel@2 130 bgt 1b
nengel@2 131
nengel@2 132 vpop {d8-d15}
nengel@2 133 bx lr
nengel@2 134 endfunc
nengel@2 135
nengel@2 136 #if HAVE_ARMV6
nengel@2 137 /**
nengel@2 138 * ARM VFP optimized float to int16 conversion.
nengel@2 139 * Assume that len is a positive number and is multiple of 8, destination
nengel@2 140 * buffer is at least 4 bytes aligned (8 bytes alignment is better for
nengel@2 141 * performance), little endian byte sex
nengel@2 142 */
nengel@2 143 @ void ff_float_to_int16_vfp(int16_t *dst, const float *src, int len)
nengel@2 144 function ff_float_to_int16_vfp, export=1
nengel@2 145 push {r4-r8,lr}
nengel@2 146 vpush {d8-d11}
nengel@2 147 vldmia r1!, {s16-s23}
nengel@2 148 vcvt.s32.f32 s0, s16
nengel@2 149 vcvt.s32.f32 s1, s17
nengel@2 150 vcvt.s32.f32 s2, s18
nengel@2 151 vcvt.s32.f32 s3, s19
nengel@2 152 vcvt.s32.f32 s4, s20
nengel@2 153 vcvt.s32.f32 s5, s21
nengel@2 154 vcvt.s32.f32 s6, s22
nengel@2 155 vcvt.s32.f32 s7, s23
nengel@2 156 1:
nengel@2 157 subs r2, r2, #8
nengel@2 158 vmov r3, r4, s0, s1
nengel@2 159 vmov r5, r6, s2, s3
nengel@2 160 vmov r7, r8, s4, s5
nengel@2 161 vmov ip, lr, s6, s7
nengel@2 162 vldmiagt r1!, {s16-s23}
nengel@2 163 ssat r4, #16, r4
nengel@2 164 ssat r3, #16, r3
nengel@2 165 ssat r6, #16, r6
nengel@2 166 ssat r5, #16, r5
nengel@2 167 pkhbt r3, r3, r4, lsl #16
nengel@2 168 pkhbt r4, r5, r6, lsl #16
nengel@2 169 vcvtgt.s32.f32 s0, s16
nengel@2 170 vcvtgt.s32.f32 s1, s17
nengel@2 171 vcvtgt.s32.f32 s2, s18
nengel@2 172 vcvtgt.s32.f32 s3, s19
nengel@2 173 vcvtgt.s32.f32 s4, s20
nengel@2 174 vcvtgt.s32.f32 s5, s21
nengel@2 175 vcvtgt.s32.f32 s6, s22
nengel@2 176 vcvtgt.s32.f32 s7, s23
nengel@2 177 ssat r8, #16, r8
nengel@2 178 ssat r7, #16, r7
nengel@2 179 ssat lr, #16, lr
nengel@2 180 ssat ip, #16, ip
nengel@2 181 pkhbt r5, r7, r8, lsl #16
nengel@2 182 pkhbt r6, ip, lr, lsl #16
nengel@2 183 stmia r0!, {r3-r6}
nengel@2 184 bgt 1b
nengel@2 185
nengel@2 186 vpop {d8-d11}
nengel@2 187 pop {r4-r8,pc}
nengel@2 188 endfunc
nengel@2 189 #endif