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