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